Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2021-09-01 08:23:58 +0300
committerCampbell Barton <ideasman42@gmail.com>2021-09-01 08:23:58 +0300
commitf1cdd49a4e7fb2883d574691eab16b2ffc1f52a3 (patch)
tree1d3af334b7ef5f70c1fdfb051cc28ece7eb1bdd0
parent90dac47717b12f33d5dd738da12a337cfe4f2f14 (diff)
BLI_string: add BLI_str_quoted_substr_range
This is a similar funciton to BLI_str_quoted_substrN that extracts the range of the quoted string instead of allocating a new string un-escaped string.
-rw-r--r--source/blender/blenlib/BLI_string.h5
-rw-r--r--source/blender/blenlib/intern/string.c77
2 files changed, 62 insertions, 20 deletions
diff --git a/source/blender/blenlib/BLI_string.h b/source/blender/blenlib/BLI_string.h
index 0c51d38e813..c20376c42b9 100644
--- a/source/blender/blenlib/BLI_string.h
+++ b/source/blender/blenlib/BLI_string.h
@@ -57,6 +57,11 @@ size_t BLI_strncpy_rlen(char *__restrict dst,
size_t BLI_strcpy_rlen(char *__restrict dst, const char *__restrict src) ATTR_WARN_UNUSED_RESULT
ATTR_NONNULL();
+bool BLI_str_quoted_substr_range(const char *__restrict str,
+ const char *__restrict prefix,
+ int *__restrict r_start,
+ int *__restrict r_end) ATTR_WARN_UNUSED_RESULT
+ ATTR_NONNULL(1, 2, 3, 4);
char *BLI_str_quoted_substrN(const char *__restrict str,
const char *__restrict prefix) ATTR_WARN_UNUSED_RESULT
ATTR_NONNULL() ATTR_MALLOC;
diff --git a/source/blender/blenlib/intern/string.c b/source/blender/blenlib/intern/string.c
index 5541d75bc73..0be8700810e 100644
--- a/source/blender/blenlib/intern/string.c
+++ b/source/blender/blenlib/intern/string.c
@@ -420,6 +420,53 @@ const char *BLI_str_escape_find_quote(const char *str)
}
/**
+ * Return the range of the quoted string (excluding quotes) `str` after `prefix`.
+ *
+ * A version of #BLI_str_quoted_substrN that calculates the range
+ * instead of un-escaping and allocating the result.
+ *
+ * \param str: String potentially including `prefix`.
+ * \param prefix: Quoted string prefix.
+ * \param r_start: The start of the quoted string (after the first quote).
+ * \param r_end: The end of the quoted string (before the last quote).
+ * \return True when a quoted string range could be found after `prefix`.
+ */
+bool BLI_str_quoted_substr_range(const char *__restrict str,
+ const char *__restrict prefix,
+ int *__restrict r_start,
+ int *__restrict r_end)
+{
+ const char *str_start = strstr(str, prefix);
+ if (str_start == NULL) {
+ return false;
+ }
+ const size_t prefix_len = strlen(prefix);
+ if (UNLIKELY(prefix_len == 0)) {
+ BLI_assert_msg(0,
+ "Zero length prefix passed in, "
+ "caller must prevent this from happening!");
+ return false;
+ }
+ BLI_assert_msg(prefix[prefix_len - 1] != '"',
+ "Prefix includes trailing quote, "
+ "caller must prevent this from happening!");
+
+ str_start += prefix_len;
+ if (UNLIKELY(*str_start != '\"')) {
+ return false;
+ }
+ str_start += 1;
+ const char *str_end = BLI_str_escape_find_quote(str_start);
+ if (UNLIKELY(str_end == NULL)) {
+ return false;
+ }
+
+ *r_start = (int)(str_start - str);
+ *r_end = (int)(str_end - str);
+ return true;
+}
+
+/**
* Makes a copy of the text within the "" that appear after some text `blahblah`.
* i.e. for string `pose["apples"]` with prefix `pose[`, it will return `apples`.
*
@@ -431,27 +478,17 @@ const char *BLI_str_escape_find_quote(const char *str)
*/
char *BLI_str_quoted_substrN(const char *__restrict str, const char *__restrict prefix)
{
- const char *start_match, *end_match;
-
- /* get the starting point (i.e. where prefix starts, and add prefix_len+1
- * to it to get be after the first " */
- start_match = strstr(str, prefix);
- if (start_match) {
- const size_t prefix_len = strlen(prefix);
- start_match += prefix_len + 1;
- /* get the end point (i.e. where the next occurrence of " is after the starting point) */
- end_match = BLI_str_escape_find_quote(start_match);
- if (end_match) {
- const size_t escaped_len = (size_t)(end_match - start_match);
- char *result = MEM_mallocN(sizeof(char) * (escaped_len + 1), __func__);
- const size_t unescaped_len = BLI_str_unescape(result, start_match, escaped_len);
- if (unescaped_len != escaped_len) {
- result = MEM_reallocN(result, sizeof(char) * (unescaped_len + 1));
- }
- return result;
- }
+ int start_match_ofs, end_match_ofs;
+ if (!BLI_str_quoted_substr_range(str, prefix, &start_match_ofs, &end_match_ofs)) {
+ return NULL;
+ }
+ const size_t escaped_len = (size_t)(end_match_ofs - start_match_ofs);
+ char *result = MEM_mallocN(sizeof(char) * (escaped_len + 1), __func__);
+ const size_t unescaped_len = BLI_str_unescape(result, str + start_match_ofs, escaped_len);
+ if (unescaped_len != escaped_len) {
+ result = MEM_reallocN(result, sizeof(char) * (unescaped_len + 1));
}
- return NULL;
+ return result;
}
/**