From: Alan T. DeKok Date: Fri, 13 May 2022 18:31:08 +0000 (-0400) Subject: move xlats to dlists. X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=457682c20a073d677000966a045dab8225e8f117;p=thirdparty%2Ffreeradius-server.git move xlats to dlists. --- diff --git a/src/lib/unlang/xlat.h b/src/lib/unlang/xlat.h index 45e198de42c..85509250dc8 100644 --- a/src/lib/unlang/xlat.h +++ b/src/lib/unlang/xlat.h @@ -379,8 +379,6 @@ void xlat_free(void); */ xlat_exp_t *xlat_exp_func_alloc(TALLOC_CTX *ctx, xlat_t *func, xlat_exp_head_t const *args); -void xlat_exp_free(xlat_exp_head_t **head); - tmpl_t *xlat_to_tmpl_attr(TALLOC_CTX *ctx, xlat_exp_head_t *xlat); int xlat_from_tmpl_attr(TALLOC_CTX *ctx, xlat_exp_head_t **head, tmpl_t **vpt_p); diff --git a/src/lib/unlang/xlat_builtin.c b/src/lib/unlang/xlat_builtin.c index b0e2dade7ad..281b0ae9c04 100644 --- a/src/lib/unlang/xlat_builtin.c +++ b/src/lib/unlang/xlat_builtin.c @@ -752,7 +752,8 @@ static int xlat_redundant_instantiate(xlat_inst_ctx_t const *xctx) * correctly. */ MEM(head = xlat_exp_head_alloc(xri->ex)); - MEM(head->next = node = xlat_exp_func_alloc(head, xrf->func, xctx->ex->call.args)); + MEM(node = xlat_exp_func_alloc(head, xrf->func, xctx->ex->call.args)); + xlat_exp_insert_tail(head, node); switch (xrf->func->input_type) { case XLAT_INPUT_UNPROCESSED: @@ -797,7 +798,7 @@ static int xlat_redundant_instantiate(xlat_inst_ctx_t const *xctx) * a copy of the original arguments with each * function that's called. */ - xlat_exp_free(&xctx->ex->call.args); + fr_dlist_talloc_free(&xctx->ex->call.args->dlist); return 0; } diff --git a/src/lib/unlang/xlat_expr.c b/src/lib/unlang/xlat_expr.c index d673c644309..84c3858bedc 100644 --- a/src/lib/unlang/xlat_expr.c +++ b/src/lib/unlang/xlat_expr.c @@ -97,6 +97,8 @@ static fr_slen_t xlat_expr_print_binary(fr_sbuff_t *out, xlat_exp_t const *node, size_t at_in = fr_sbuff_used_total(out); xlat_exp_t *child = xlat_exp_head(node->call.args); + fr_assert(child != NULL); + FR_SBUFF_IN_CHAR_RETURN(out, '('); xlat_print_node(out, node->call.args, child, e_rules); /* prints a space after the first argument */ @@ -106,7 +108,10 @@ static fr_slen_t xlat_expr_print_binary(fr_sbuff_t *out, xlat_exp_t const *node, */ FR_SBUFF_IN_STRCPY_RETURN(out, fr_tokens[node->call.func->token]); FR_SBUFF_IN_CHAR_RETURN(out, ' '); + child = xlat_exp_next(node->call.args, child); + fr_assert(child != NULL); + xlat_print_node(out, node->call.args, child, e_rules); FR_SBUFF_IN_CHAR_RETURN(out, ')'); @@ -116,7 +121,7 @@ static fr_slen_t xlat_expr_print_binary(fr_sbuff_t *out, xlat_exp_t const *node, static void xlat_func_append_arg(xlat_exp_t *head, xlat_exp_t *node) { - xlat_exp_t *group, **tail; + xlat_exp_t *group; fr_assert(head->type == XLAT_FUNC); fr_assert(node->type != XLAT_GROUP); @@ -128,16 +133,12 @@ static void xlat_func_append_arg(xlat_exp_t *head, xlat_exp_t *node) group->fmt = node->fmt; /* not entirely correct, but good enough for now */ MEM(group->group = xlat_exp_head_alloc(group)); - group->group->next = talloc_steal(group->group, node); + talloc_steal(group->group, node); + xlat_exp_insert_tail(group->group, node); - group->flags = node->flags; - xlat_flags_merge(&head->call.args->flags, &group->flags); - xlat_flags_merge(&head->flags, &group->flags); + xlat_exp_insert_tail(head->call.args, group); - tail = &head->call.args->next; - while (*tail) tail = &((*tail)->next); - - *tail = group; + xlat_flags_merge(&head->flags, &head->call.args->flags); } @@ -764,8 +765,9 @@ static ssize_t tokenize_unary(xlat_exp_head_t *head, xlat_exp_t **out, fr_sbuff_ fr_sbuff_parse_rules_t const *bracket_rules) { ssize_t slen; - xlat_exp_t *unary = NULL; + xlat_exp_t *node, *unary = NULL; xlat_t *func = NULL; + char const *fmt = NULL; fr_sbuff_t our_in = FR_SBUFF(in); XLAT_DEBUG("UNARY <-- %pV", fr_box_strvalue_len(fr_sbuff_current(in), fr_sbuff_remaining(in))); @@ -776,10 +778,12 @@ static ssize_t tokenize_unary(xlat_exp_head_t *head, xlat_exp_t **out, fr_sbuff_ * we allocate. */ if (fr_sbuff_next_if_char(&our_in, '!')) { /* unary not */ + fmt = "!"; func = xlat_func_find("unary_not", 9); fr_assert(func != NULL); } else if (fr_sbuff_next_if_char(&our_in, '-')) { /* unary minus */ + fmt = "-"; func = xlat_func_find("unary_minus", 11); fr_assert(func != NULL); } @@ -797,23 +801,29 @@ static ssize_t tokenize_unary(xlat_exp_head_t *head, xlat_exp_t **out, fr_sbuff_ MEM(unary = xlat_exp_alloc(head, XLAT_FUNC, func->name, strlen(func->name))); MEM(unary->call.args = xlat_exp_head_alloc(unary)); + unary->fmt = fmt; unary->call.func = func; unary->flags = func->flags; - slen = tokenize_field(unary->call.args, &unary->call.args->next, &our_in, p_rules, t_rules, bracket_rules); + slen = tokenize_field(unary->call.args, &node, &our_in, p_rules, t_rules, bracket_rules); if (slen <= 0) { talloc_free(unary); FR_SBUFF_ERROR_RETURN_ADJ(&our_in, slen); } - if (!xlat_exp_head(unary->call.args)) { + if (!node) { fr_strerror_const("Empty expression is invalid"); FR_SBUFF_ERROR_RETURN_ADJ(&our_in, -slen); } - *out = unary; - xlat_flags_merge(&head->flags, &unary->flags); + xlat_exp_insert_tail(unary->call.args, node); + xlat_flags_merge(&unary->flags, &unary->call.args->flags); + /* + * Don't add it to head->flags, that will be done when it's actually inserted. + */ + + *out = unary; return fr_sbuff_set(in, &our_in); } @@ -979,7 +989,6 @@ done: #endif *out = node; - xlat_flags_merge(&head->flags, &node->flags); return fr_sbuff_set(in, &our_in); } @@ -1023,6 +1032,9 @@ static size_t const expr_assignment_op_table_len = NUM_ELEMENTS(expr_assignment_ * (EXPR) * !EXPR * A OP B + * + * If "out" is NULL then the expression is added to "head". + * Otherwise, it's returned to the caller. */ static ssize_t tokenize_expression(xlat_exp_head_t *head, xlat_exp_t **out, fr_sbuff_t *in, fr_sbuff_parse_rules_t const *p_rules, tmpl_rules_t const *t_rules, @@ -1060,7 +1072,13 @@ redo: */ if (fr_sbuff_extend(&our_in) == 0) { done: - *out = lhs; + + if (!out) { + xlat_exp_insert_tail(head, lhs); + } else { + *out = lhs; + } + return fr_sbuff_set(in, &our_in); } @@ -1181,8 +1199,6 @@ redo: } /* - * @todo - purify the node. - * * @todo - also if the have differenting data types on the LHS and RHS, and one of them is an * XLAT_BOX, then try to upcast the XLAT_BOX to the destination data type before returning. This * optimization minimizes the amount of run-time work we have to do. @@ -1200,6 +1216,8 @@ redo: xlat_func_append_arg(node, lhs); xlat_func_append_arg(node, rhs); + fr_assert(xlat_exp_head(node->call.args) != NULL); + lhs = node; goto redo; } @@ -1268,7 +1286,7 @@ ssize_t xlat_tokenize_expression(TALLOC_CTX *ctx, xlat_exp_head_t **out, fr_sbuf MEM(head = xlat_exp_head_alloc(ctx)); - slen = tokenize_expression(head, &head->next, in, terminal_rules, t_rules, T_INVALID, bracket_rules); + slen = tokenize_expression(head, NULL, in, terminal_rules, t_rules, T_INVALID, bracket_rules); talloc_free(bracket_rules); talloc_free(terminal_rules); @@ -1349,7 +1367,7 @@ ssize_t xlat_tokenize_ephemeral_expression(TALLOC_CTX *ctx, xlat_exp_head_t **ou MEM(head = xlat_exp_head_alloc(ctx)); - slen = tokenize_expression(head, &head->next, in, terminal_rules, &my_rules, T_INVALID, bracket_rules); + slen = tokenize_expression(head, NULL, in, terminal_rules, &my_rules, T_INVALID, bracket_rules); talloc_free(bracket_rules); talloc_free(terminal_rules); diff --git a/src/lib/unlang/xlat_priv.h b/src/lib/unlang/xlat_priv.h index 5b8baa687ee..7a8ba508c61 100644 --- a/src/lib/unlang/xlat_priv.h +++ b/src/lib/unlang/xlat_priv.h @@ -120,7 +120,7 @@ struct xlat_exp { xlat_flags_t flags; //!< Flags that control resolution and evaluation. xlat_type_t type; //!< type of this expansion. - xlat_exp_t *next; //!< Next in the list. + fr_dlist_t entry; union { xlat_exp_head_t *alternate[2]; //!< alternate expansions @@ -151,7 +151,7 @@ struct xlat_exp { struct xlat_exp_head { char const *fmt; //!< The original format string (a talloced buffer). xlat_flags_t flags; //!< Flags that control resolution and evaluation. - xlat_exp_t *next; //!< Next in the list. + fr_dlist_head_t dlist; }; @@ -321,10 +321,10 @@ int xlat_register_expressions(void); /* * xlat_tokenize.c */ -int xlat_tokenize_expansion(xlat_exp_head_t *head, xlat_exp_t **out, fr_sbuff_t *in, +int xlat_tokenize_expansion(xlat_exp_head_t *head, fr_sbuff_t *in, tmpl_attr_rules_t const *t_rules); -int xlat_tokenize_function_args(xlat_exp_head_t *head, xlat_exp_t **out, fr_sbuff_t *in, +int xlat_tokenize_function_args(xlat_exp_head_t *head, fr_sbuff_t *in, tmpl_attr_rules_t const *rules); ssize_t xlat_print_node(fr_sbuff_t *out, xlat_exp_head_t const *head, xlat_exp_t const *node, fr_sbuff_escape_rules_t const *e_rules); @@ -333,9 +333,9 @@ ssize_t xlat_print_node(fr_sbuff_t *out, xlat_exp_head_t const *head, xlat_exp_ static inline xlat_exp_t *xlat_exp_head(xlat_exp_head_t const *head) { - if (!head || !head->next) return NULL; + if (!head) return NULL; - return UNCONST(xlat_exp_t *, (head->next)); + return fr_dlist_head(&head->dlist); } /** Iterate over the contents of a list, only one level @@ -344,19 +344,28 @@ static inline xlat_exp_t *xlat_exp_head(xlat_exp_head_t const *head) * @param[in] _iter Name of iteration variable. * Will be declared in the scope of the loop. */ -#define xlat_exp_foreach(_list_head, _iter) \ - for (xlat_exp_t *_iter = xlat_exp_head(_list_head); _iter; _iter = _iter->next) +#define xlat_exp_foreach(_list_head, _iter) fr_dlist_foreach(&((_list_head)->dlist), xlat_exp_t, _iter) -static inline xlat_exp_t *xlat_exp_next(UNUSED xlat_exp_head_t const *head, xlat_exp_t const *item) +static inline xlat_exp_t *xlat_exp_next(xlat_exp_head_t const *head, xlat_exp_t const *node) { - if (!item->next) return NULL; + return fr_dlist_next(&head->dlist, node); +} - return UNCONST(xlat_exp_t *, item->next); +static inline int xlat_exp_insert_tail(xlat_exp_head_t *head, xlat_exp_t *node) +{ + xlat_flags_merge(&head->flags, &node->flags); + return fr_dlist_insert_tail(&head->dlist, node); } static inline xlat_exp_head_t *xlat_exp_head_alloc(TALLOC_CTX *ctx) { - return talloc_zero(ctx, xlat_exp_head_t); + xlat_exp_head_t *head; + + head = talloc_zero(ctx, xlat_exp_head_t); + if (!head) return NULL; + + fr_dlist_init(&head->dlist, xlat_exp_t, entry); + return head; } #ifdef __cplusplus diff --git a/src/lib/unlang/xlat_tokenize.c b/src/lib/unlang/xlat_tokenize.c index f65064bc338..3bdb7f48e06 100644 --- a/src/lib/unlang/xlat_tokenize.c +++ b/src/lib/unlang/xlat_tokenize.c @@ -150,26 +150,10 @@ static inline CC_HINT(always_inline) void xlat_exp_set_name_buffer(xlat_exp_t *n } #endif -/** Free a linked list of xlat nodes - * - * @param[in,out] head to free. Will be set to NULL - */ -void xlat_exp_free(xlat_exp_head_t **head) -{ - xlat_exp_t *to_free = xlat_exp_head(*head), *next; - - while (to_free) { - next = to_free->next; - talloc_free(to_free); - to_free = next; - }; - *head = NULL; -} - static int xlat_tokenize_string(xlat_exp_head_t *head, fr_sbuff_t *in, bool brace, fr_sbuff_parse_rules_t const *p_rules, tmpl_attr_rules_t const *t_rules); -static inline int xlat_tokenize_alternation(xlat_exp_head_t *head, xlat_exp_t **out, fr_sbuff_t *in, +static inline int xlat_tokenize_alternation(xlat_exp_head_t *head, fr_sbuff_t *in, tmpl_attr_rules_t const *t_rules, bool func_args) { xlat_exp_t *node; @@ -182,13 +166,13 @@ static inline int xlat_tokenize_alternation(xlat_exp_head_t *head, xlat_exp_t ** MEM(node->alternate[1] = xlat_exp_head_alloc(node)); if (func_args) { - if (xlat_tokenize_function_args(node->alternate[0], &node->alternate[0]->next, in, t_rules) < 0) { + if (xlat_tokenize_function_args(node->alternate[0], in, t_rules) < 0) { error: talloc_free(node); return -1; } } else { - if (xlat_tokenize_expansion(node->alternate[0], &node->alternate[0]->next, in, t_rules) < 0) goto error; + if (xlat_tokenize_expansion(node->alternate[0], in, t_rules) < 0) goto error; } if (!fr_sbuff_adv_past_str_literal(in, ":-")) { @@ -208,7 +192,7 @@ static inline int xlat_tokenize_alternation(xlat_exp_head_t *head, xlat_exp_t ** if (xlat_tokenize_string(node->alternate[1], in, true, &xlat_expansion_rules, t_rules) < 0) goto error; - if (!node->alternate[1]->next) { + if (!xlat_exp_head(node->alternate[1])) { talloc_free(node); fr_strerror_const("Empty expansion is invalid"); goto error; @@ -221,8 +205,7 @@ static inline int xlat_tokenize_alternation(xlat_exp_head_t *head, xlat_exp_t ** xlat_flags_merge(&node->flags, &node->alternate[1]->flags); done: - xlat_flags_merge(&head->flags, &node->flags); - *out = node; + xlat_exp_insert_tail(head, node); return 0; } @@ -234,7 +217,7 @@ done: * @verbatim %{} @endverbatim * */ -static inline int xlat_tokenize_regex(xlat_exp_head_t *head, xlat_exp_t **out, fr_sbuff_t *in) +static inline int xlat_tokenize_regex(xlat_exp_head_t *head, fr_sbuff_t *in) { uint8_t num; xlat_exp_t *node; @@ -276,8 +259,7 @@ static inline int xlat_tokenize_regex(xlat_exp_head_t *head, xlat_exp_t **out, f fr_sbuff_marker_release(&m_s); fr_sbuff_next(in); /* Skip '}' */ - xlat_flags_merge(&head->flags, &node->flags); - *out = node; + xlat_exp_insert_tail(head, node); return 0; } @@ -304,7 +286,7 @@ int xlat_validate_function_mono(xlat_exp_t *node) * - 0 if the string was parsed into a function. * - <0 on parse error. */ -static inline int xlat_tokenize_function_mono(xlat_exp_head_t *head, xlat_exp_t **out, +static inline int xlat_tokenize_function_mono(xlat_exp_head_t *head, fr_sbuff_t *in, tmpl_attr_rules_t const *rules) { @@ -332,7 +314,6 @@ static inline int xlat_tokenize_function_mono(xlat_exp_head_t *head, xlat_exp_t if (!fr_sbuff_is_char(in, ':')) { fr_strerror_const("Can't find function/argument separator"); bad_function: - *out = NULL; fr_sbuff_set(in, &m_s); /* backtrack */ fr_sbuff_marker_release(&m_s); return -1; @@ -398,8 +379,7 @@ static inline int xlat_tokenize_function_mono(xlat_exp_head_t *head, xlat_exp_t } xlat_flags_merge(&node->flags, &node->call.args->flags); - xlat_flags_merge(&head->flags, &node->flags); - *out = node; + xlat_exp_insert_tail(head, node); return 0; } @@ -441,8 +421,7 @@ int xlat_validate_function_args(xlat_exp_t *node) * - 0 if the string was parsed into a function. * - <0 on parse error. */ -int xlat_tokenize_function_args(xlat_exp_head_t *head, xlat_exp_t **out, - fr_sbuff_t *in, +int xlat_tokenize_function_args(xlat_exp_head_t *head, fr_sbuff_t *in, tmpl_attr_rules_t const *rules) { xlat_exp_t *node; @@ -469,7 +448,6 @@ int xlat_tokenize_function_args(xlat_exp_head_t *head, xlat_exp_t **out, if (!fr_sbuff_is_char(in, ':')) { fr_strerror_const("Can't find function/argument separator"); bad_function: - *out = NULL; fr_sbuff_set(in, &m_s); /* backtrack */ fr_sbuff_marker_release(&m_s); return -1; @@ -533,8 +511,7 @@ int xlat_tokenize_function_args(xlat_exp_head_t *head, xlat_exp_t **out, goto error; } - xlat_flags_merge(&head->flags, &node->flags); - *out = node; + xlat_exp_insert_tail(head, node); return 0; } @@ -564,7 +541,7 @@ static int xlat_resolve_virtual_attribute(xlat_exp_t *node, tmpl_t *vpt) /** Parse an attribute ref or a virtual attribute * */ -static inline int xlat_tokenize_attribute(xlat_exp_head_t *head, xlat_exp_t **out, fr_sbuff_t *in, +static inline int xlat_tokenize_attribute(xlat_exp_head_t *head, fr_sbuff_t *in, fr_sbuff_parse_rules_t const *p_rules, tmpl_attr_rules_t const *t_rules) { ssize_t slen; @@ -610,7 +587,6 @@ static inline int xlat_tokenize_attribute(xlat_exp_head_t *head, xlat_exp_t **ou */ if (err == TMPL_ATTR_ERROR_MISSING_TERMINATOR) fr_sbuff_set(in, &m_s); error: - *out = NULL; fr_sbuff_marker_release(&m_s); talloc_free(node); return -1; @@ -684,13 +660,13 @@ done: goto error; } - xlat_flags_merge(&head->flags, &node->flags); - *out = node; + xlat_exp_insert_tail(head, node); + fr_sbuff_marker_release(&m_s); return 0; } -int xlat_tokenize_expansion(xlat_exp_head_t *head, xlat_exp_t **out, fr_sbuff_t *in, +int xlat_tokenize_expansion(xlat_exp_head_t *head, fr_sbuff_t *in, tmpl_attr_rules_t const *t_rules) { size_t len; @@ -714,14 +690,14 @@ int xlat_tokenize_expansion(xlat_exp_head_t *head, xlat_exp_t **out, fr_sbuff_t * %{...}:-bar} */ if (fr_sbuff_adv_past_str_literal(in, "%{")) { - return xlat_tokenize_alternation(head, out, in, t_rules, false); + return xlat_tokenize_alternation(head, in, t_rules, false); } /* * %(...):-bar} */ if (fr_sbuff_adv_past_str_literal(in, "%(")) { - return xlat_tokenize_alternation(head, out, in, t_rules, true); + return xlat_tokenize_alternation(head, in, t_rules, true); } /* @@ -739,7 +715,7 @@ int xlat_tokenize_expansion(xlat_exp_head_t *head, xlat_exp_t **out, fr_sbuff_t if (fr_sbuff_is_digit(in)) { int ret; - ret = xlat_tokenize_regex(head, out, in); + ret = xlat_tokenize_regex(head, in); if (ret <= 0) return ret; /* ret==1 means "nope, it's an attribute" */ @@ -801,7 +777,7 @@ int xlat_tokenize_expansion(xlat_exp_head_t *head, xlat_exp_t **out, fr_sbuff_t fr_sbuff_set(in, &s_m); /* backtrack */ fr_sbuff_marker_release(&s_m); - return xlat_tokenize_function_mono(head, out, in, t_rules); + return xlat_tokenize_function_mono(head, in, t_rules); /* * Hint token is a: @@ -814,7 +790,7 @@ int xlat_tokenize_expansion(xlat_exp_head_t *head, xlat_exp_t **out, fr_sbuff_t fr_sbuff_set(in, &s_m); /* backtrack */ fr_sbuff_marker_release(&s_m); - return xlat_tokenize_attribute(head, out, in, &attr_p_rules, t_rules); + return xlat_tokenize_attribute(head, in, &attr_p_rules, t_rules); /* * Hint token was whitespace @@ -832,28 +808,6 @@ int xlat_tokenize_expansion(xlat_exp_head_t *head, xlat_exp_t **out, fr_sbuff_t return -1; } -/* - * Temporary things until we swap to using tlists - */ -#define xlat_exp_append(_tail, _node) do { \ - *_tail = _node; \ - _tail = &(_node)->next; \ - _node = NULL; \ - } while (0) - -static void xlat_exp_list_free(xlat_exp_t **head) -{ - xlat_exp_t *node = *head; - - while (node) { - xlat_exp_t *next = node->next; - talloc_free(node); - node = next; - } - - *head = NULL; -} - /** Parse an xlat string i.e. a non-expansion or non-function * * When this function is being used outside of an xlat expansion, i.e. on a string @@ -904,10 +858,6 @@ static int xlat_tokenize_string(xlat_exp_head_t *head, ); fr_sbuff_term_t *tokens; fr_sbuff_unescape_rules_t const *escapes; - xlat_exp_t *first, **tail; - - first = NULL; - tail = &first; XLAT_DEBUG("STRING <-- %pV", fr_box_strvalue_len(fr_sbuff_current(in), fr_sbuff_remaining(in))); @@ -940,11 +890,11 @@ static int xlat_tokenize_string(xlat_exp_head_t *head, escapes ? escapes->name : "(none)", fr_box_strvalue_len(str, talloc_array_length(str) - 1)); XLAT_HEXDUMP((uint8_t const *)str, talloc_array_length(str) - 1, " VALUE-BOX "); - xlat_exp_append(tail, node); + + xlat_exp_insert_tail(head, node); } else if (slen < 0) { error: talloc_free(node); - xlat_exp_list_free(&first); /* * Free our temporary array of terminals @@ -956,8 +906,7 @@ static int xlat_tokenize_string(xlat_exp_head_t *head, if (fr_sbuff_adv_past_str_literal(in, "%{")) { if (slen == 0) TALLOC_FREE(node); /* Free the empty node */ - if (xlat_tokenize_expansion(head, &node, in, t_rules) < 0) goto error; - xlat_exp_append(tail, node); + if (xlat_tokenize_expansion(head, in, t_rules) < 0) goto error; continue; } @@ -967,8 +916,7 @@ static int xlat_tokenize_string(xlat_exp_head_t *head, if (fr_sbuff_adv_past_str_literal(in, "%(")) { if (slen == 0) TALLOC_FREE(node); /* Free the empty node */ - if (xlat_tokenize_function_args(head, &node, in, t_rules) < 0) goto error; - xlat_exp_append(tail, node); + if (xlat_tokenize_function_args(head, in, t_rules) < 0) goto error; continue; } @@ -992,8 +940,7 @@ static int xlat_tokenize_string(xlat_exp_head_t *head, node->flags.pure = true; /* value boxes are always pure */ node->flags.needs_async = false; /* value boxes are always non-async */ - xlat_flags_merge(&head->flags, &node->flags); - xlat_exp_append(tail, node); + xlat_exp_insert_tail(head, node); continue; } @@ -1012,7 +959,7 @@ static int xlat_tokenize_string(xlat_exp_head_t *head, * Empty input, emit no arguments */ } else if (slen == 0) { - talloc_free(node); + TALLOC_FREE(node); XLAT_DEBUG("VALUE-BOX <-- (empty)"); } break; @@ -1022,8 +969,7 @@ static int xlat_tokenize_string(xlat_exp_head_t *head, * Free our temporary array of terminals */ if (tokens != &expansions) talloc_free(tokens); - - head->next = first; + return 0; } @@ -1338,7 +1284,7 @@ ssize_t xlat_tokenize_ephemeral(TALLOC_CTX *ctx, xlat_exp_head_t **out, /* * Zero length expansion, return a zero length node. */ - if (!head->next) { + if (!xlat_exp_head(head)) { *out = head; return 0; } @@ -1380,11 +1326,9 @@ ssize_t xlat_tokenize_argv(TALLOC_CTX *ctx, xlat_exp_head_t **out, fr_sbuff_t *i fr_sbuff_marker_t m; fr_sbuff_parse_rules_t const *our_p_rules; /* Bareword parse rules */ fr_sbuff_parse_rules_t tmp_p_rules; - xlat_exp_t **tail; xlat_exp_head_t *head; MEM(head = xlat_exp_head_alloc(ctx)); - tail = &head->next; if (p_rules && p_rules->terminals) { tmp_p_rules = (fr_sbuff_parse_rules_t){ /* Stack allocated due to CL scope */ @@ -1457,7 +1401,7 @@ ssize_t xlat_tokenize_argv(TALLOC_CTX *ctx, xlat_exp_head_t **out, fr_sbuff_t *i char *str; xlat_exp_t *child; - node->group->next = child = xlat_exp_alloc_null(node->group); + child = xlat_exp_alloc_null(node->group); xlat_exp_set_type(child, XLAT_BOX); slen = fr_sbuff_out_aunescape_until(child, &str, &our_in, SIZE_MAX, @@ -1467,6 +1411,7 @@ ssize_t xlat_tokenize_argv(TALLOC_CTX *ctx, xlat_exp_head_t **out, fr_sbuff_t *i xlat_exp_set_name_buffer_shallow(child, str); fr_value_box_strdup_shallow(&child->data, NULL, str, false); + xlat_exp_insert_tail(node->group, child); } break; @@ -1492,8 +1437,8 @@ ssize_t xlat_tokenize_argv(TALLOC_CTX *ctx, xlat_exp_head_t **out, fr_sbuff_t *i xlat_exp_set_name_buffer_shallow(node, fmt); node->flags = node->group->flags; - xlat_flags_merge(&head->flags, &node->flags); - xlat_exp_append(tail, node); + + xlat_exp_insert_tail(head, node); /* * If we're not and the end of the string @@ -1917,8 +1862,7 @@ int xlat_from_tmpl_attr(TALLOC_CTX *ctx, xlat_exp_head_t **out, tmpl_t **vpt_p) node->vpt = talloc_move(node, vpt_p); done: - head->next = node; - head->flags = node->flags; + xlat_exp_insert_tail(head, node); *out = head; return 0; @@ -1935,7 +1879,6 @@ done: */ int xlat_copy(TALLOC_CTX *ctx, xlat_exp_head_t **out, xlat_exp_head_t const *in) { - xlat_exp_t **tail; xlat_exp_head_t *head; if (!in) { @@ -1945,7 +1888,6 @@ int xlat_copy(TALLOC_CTX *ctx, xlat_exp_head_t **out, xlat_exp_head_t const *in) head = xlat_exp_head_alloc(ctx); head->flags = in->flags; - tail = &head->next; /* * Copy everything in the list of nodes @@ -2010,7 +1952,7 @@ int xlat_copy(TALLOC_CTX *ctx, xlat_exp_head_t **out, xlat_exp_head_t const *in) break; } - xlat_exp_append(tail, node); + xlat_exp_insert_tail(head, node); } *out = head;