Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- diff --git a/options/m_property.c b/options/m_property.c
- index 9dad34f..c7c92b2 100644
- --- a/options/m_property.c
- +++ b/options/m_property.c
- @@ -255,6 +255,21 @@ static int expand_property(const struct m_property *prop_list, char **ret,
- return skip;
- }
- +// This is not really a functional/generic macro but rather a sequence which
- +// can only execute inside m_properties_expand_string. The arguments are there
- +// only to make its usage semantic clearer.
- +// Effectively it's: ret = ret[0 .. from] + expand( ret[from .. ret_len] )
- +// while keeping ret_len up to date, and managing memory transparently.
- +#define EXPAND_INPLACE(ret, from, ret_len) do { \
- + MP_TARRAY_APPEND(NULL, ret, ret_len, '\0'); \
- + char *out0 = m_properties_expand_string(prop_list, ret + from, ctx); \
- + int out_len = strlen(out0); \
- + ret = talloc_realloc(NULL, ret, char, from + out_len); \
- + memcpy(ret + from, out0, out_len); \
- + ret_len = from + out_len; \
- + talloc_free(out0); \
- +} while (0)
- +
- char *m_properties_expand_string(const struct m_property *prop_list,
- const char *str0, void *ctx)
- {
- @@ -264,15 +279,34 @@ char *m_properties_expand_string(const struct m_property *prop_list,
- int level = 0, skip_level = 0;
- bstr str = bstr0(str0);
- + // Stack where at index i we store -1 if level i+1 doesn't need re-expand
- + // once it's done, or the output position from which we should re-expand.
- + // E.g. for the string "${X}${+Y:abc${Z}}", the array will be [-1] while
- + // expanding X, [N] while expanding Y, and [N, -1] while (if) expanding Z,
- + // where N is the output size after expanding ${X}.
- + int *reexpand_stack = NULL;
- + int reexpand_len = 0; // identical to level, kept separate for readability.
- +
- while (str.len) {
- if (level > 0 && bstr_eatstart0(&str, "}")) {
- if (skip && level <= skip_level)
- skip = false;
- level--;
- +
- + int from = reexpand_stack[level]; // pop
- + MP_TARRAY_REMOVE_AT(reexpand_stack, reexpand_len, level);
- + if (from >= 0) // re-expand the level's output
- + EXPAND_INPLACE(ret, from, ret_len);
- } else if (bstr_startswith0(str, "${") && bstr_find0(str, "}") >= 0) {
- str = bstr_cut(str, 2);
- level++;
- + // "${+" means we need to re-expand the output of the entire section.
- + // If we see '+', store the current ret_len as the starting point
- + // for re-expand which we'll use once we're done with this level.
- + int from = bstr_eatstart0(&str, "+") ? ret_len : -1;
- + MP_TARRAY_APPEND(NULL, reexpand_stack, reexpand_len, from); // push
- +
- // Assume ":" and "}" can't be part of the property name
- // => if ":" comes before "}", it must be for the fallback
- int term_pos = bstrcspn(str, ":}");
- @@ -308,6 +342,8 @@ char *m_properties_expand_string(const struct m_property *prop_list,
- }
- MP_TARRAY_APPEND(NULL, ret, ret_len, '\0');
- + if (reexpand_stack)
- + talloc_free(reexpand_stack);
- return ret;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement