From: Alan T. DeKok Date: Tue, 18 Jan 2022 21:14:43 +0000 (-0500) Subject: rearrange xlat_print() X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c56f3c2ef2e5d9be96bf598b99aa7193e4f20917;p=thirdparty%2Ffreeradius-server.git rearrange xlat_print() into xlat_print_node() for one, and xlat_print() which loops in preparation for other cleanups --- diff --git a/src/lib/unlang/xlat_tokenize.c b/src/lib/unlang/xlat_tokenize.c index b2834989fc9..3c85770213e 100644 --- a/src/lib/unlang/xlat_tokenize.c +++ b/src/lib/unlang/xlat_tokenize.c @@ -1190,13 +1190,7 @@ void xlat_debug(xlat_exp_t const *node) _xlat_debug(node, 0); } -/** Reconstitute an xlat expression from its constituent nodes - * - * @param[in] out Where to write the output string. - * @param[in] head First node to print. - * @param[in] e_rules Specifying how to escape literal values. - */ -ssize_t xlat_print(fr_sbuff_t *out, xlat_exp_t const *head, fr_sbuff_escape_rules_t const *e_rules) +static ssize_t xlat_print_node(fr_sbuff_t *out, xlat_exp_t const *head, fr_sbuff_escape_rules_t const *e_rules) { ssize_t slen; size_t at_in = fr_sbuff_used_total(out); @@ -1205,96 +1199,121 @@ ssize_t xlat_print(fr_sbuff_t *out, xlat_exp_t const *head, fr_sbuff_escape_rule if (!node) return 0; - while (node) { - switch (node->type) { - case XLAT_GROUP: - if (node->quote != T_BARE_WORD) FR_SBUFF_IN_CHAR_RETURN(out, fr_token_quote[node->quote]); - xlat_print(out, node->child, fr_value_escape_by_quote[node->quote]); - if (node->quote != T_BARE_WORD) FR_SBUFF_IN_CHAR_RETURN(out, fr_token_quote[node->quote]); - if (node->next) FR_SBUFF_IN_CHAR_RETURN(out, ' '); /* Add ' ' between args */ - goto next; + switch (node->type) { + case XLAT_GROUP: + if (node->quote != T_BARE_WORD) FR_SBUFF_IN_CHAR_RETURN(out, fr_token_quote[node->quote]); + xlat_print(out, node->child, fr_value_escape_by_quote[node->quote]); + if (node->quote != T_BARE_WORD) FR_SBUFF_IN_CHAR_RETURN(out, fr_token_quote[node->quote]); + if (node->next) FR_SBUFF_IN_CHAR_RETURN(out, ' '); /* Add ' ' between args */ + goto done; - case XLAT_BOX: - FR_SBUFF_RETURN(fr_value_box_print, out, &node->data, e_rules); - goto next; + case XLAT_BOX: + FR_SBUFF_RETURN(fr_value_box_print, out, &node->data, e_rules); + goto done; - case XLAT_ONE_LETTER: - FR_SBUFF_IN_CHAR_RETURN(out, '%', node->fmt[0]); - goto next; + case XLAT_ONE_LETTER: + FR_SBUFF_IN_CHAR_RETURN(out, '%', node->fmt[0]); + goto done; - default: - break; - } + default: + break; + } + + /* + * Now print %(...) or %{...} + */ + if ((node->type == XLAT_FUNC) && (node->call.func->input_type == XLAT_INPUT_ARGS)) { + FR_SBUFF_IN_STRCPY_LITERAL_RETURN(out, "%("); + close = ')'; + } else { + FR_SBUFF_IN_STRCPY_LITERAL_RETURN(out, "%{"); + close = '}'; + } - if ((node->type == XLAT_FUNC) && (node->call.func->input_type == XLAT_INPUT_ARGS)) { - FR_SBUFF_IN_STRCPY_LITERAL_RETURN(out, "%("); - close = ')'; - } else { - FR_SBUFF_IN_STRCPY_LITERAL_RETURN(out, "%{"); - close = '}'; + switch (node->type) { + case XLAT_ATTRIBUTE: + slen = tmpl_attr_print(out, node->attr, TMPL_ATTR_REF_PREFIX_NO); + if (slen < 0) { + error: + return slen; } - switch (node->type) { - case XLAT_ATTRIBUTE: - slen = tmpl_attr_print(out, node->attr, TMPL_ATTR_REF_PREFIX_NO); - if (slen < 0) { - error: - return slen; - } - break; + break; #ifdef HAVE_REGEX - case XLAT_REGEX: - FR_SBUFF_IN_SPRINTF_RETURN(out, "%i", node->regex_index); - break; + case XLAT_REGEX: + FR_SBUFF_IN_SPRINTF_RETURN(out, "%i", node->regex_index); + break; #endif - case XLAT_VIRTUAL: - FR_SBUFF_IN_BSTRCPY_BUFFER_RETURN(out, node->call.func->name); - break; + case XLAT_VIRTUAL: + FR_SBUFF_IN_BSTRCPY_BUFFER_RETURN(out, node->call.func->name); + break; - case XLAT_VIRTUAL_UNRESOLVED: - FR_SBUFF_IN_BSTRCPY_BUFFER_RETURN(out, node->fmt); - break; + case XLAT_VIRTUAL_UNRESOLVED: + FR_SBUFF_IN_BSTRCPY_BUFFER_RETURN(out, node->fmt); + break; - case XLAT_FUNC: - FR_SBUFF_IN_BSTRCPY_BUFFER_RETURN(out, node->call.func->name); - FR_SBUFF_IN_CHAR_RETURN(out, ':'); + case XLAT_FUNC: + FR_SBUFF_IN_BSTRCPY_BUFFER_RETURN(out, node->call.func->name); + FR_SBUFF_IN_CHAR_RETURN(out, ':'); - if (node->child) { - slen = xlat_print(out, node->child, &xlat_escape); - if (slen < 0) goto error; - } - break; - - case XLAT_FUNC_UNRESOLVED: - FR_SBUFF_IN_BSTRCPY_BUFFER_RETURN(out, node->fmt); - FR_SBUFF_IN_CHAR_RETURN(out, ':'); + if (node->child) { + slen = xlat_print(out, node->child, &xlat_escape); + if (slen < 0) goto error; + } + break; - if (node->child) { - slen = xlat_print(out, node->child, &xlat_escape); - if (slen < 0) goto error; - } - break; + case XLAT_FUNC_UNRESOLVED: + FR_SBUFF_IN_BSTRCPY_BUFFER_RETURN(out, node->fmt); + FR_SBUFF_IN_CHAR_RETURN(out, ':'); - case XLAT_ALTERNATE: + if (node->child) { slen = xlat_print(out, node->child, &xlat_escape); if (slen < 0) goto error; + } + break; - FR_SBUFF_IN_STRCPY_LITERAL_RETURN(out, ":-"); - slen = xlat_print(out, node->alternate, &xlat_escape); - if (slen < 0) goto error; - break; + case XLAT_ALTERNATE: + slen = xlat_print(out, node->child, &xlat_escape); + if (slen < 0) goto error; - fr_assert_fail(NULL); - break; + FR_SBUFF_IN_STRCPY_LITERAL_RETURN(out, ":-"); + slen = xlat_print(out, node->alternate, &xlat_escape); + if (slen < 0) goto error; + break; + + fr_assert_fail(NULL); + break; + + case XLAT_INVALID: + case XLAT_BOX: + case XLAT_ONE_LETTER: + case XLAT_GROUP: + fr_assert_fail(NULL); + break; + } + FR_SBUFF_IN_CHAR_RETURN(out, close); + +done: + return fr_sbuff_used_total(out) - at_in; +} + +/** Reconstitute an xlat expression from its constituent nodes + * + * @param[in] out Where to write the output string. + * @param[in] head First node to print. + * @param[in] e_rules Specifying how to escape literal values. + */ +ssize_t xlat_print(fr_sbuff_t *out, xlat_exp_t const *head, fr_sbuff_escape_rules_t const *e_rules) +{ + ssize_t slen; + size_t at_in = fr_sbuff_used_total(out); + xlat_exp_t const *node = head; + + if (!node) return 0; + + while (node) { + slen = xlat_print_node(out, node, e_rules); + if (slen < 0) return slen - (fr_sbuff_used_total(out) - at_in); - case XLAT_INVALID: - case XLAT_BOX: - case XLAT_ONE_LETTER: - case XLAT_GROUP: - fr_assert_fail(NULL); - break; - } - FR_SBUFF_IN_CHAR_RETURN(out, close); - next: if (node->next) { if ((node->next->type == XLAT_BOX) && (node->next->data.type != FR_TYPE_STRING)) { FR_SBUFF_IN_CHAR_RETURN(out, ' ',); @@ -1309,6 +1328,7 @@ ssize_t xlat_print(fr_sbuff_t *out, xlat_exp_t const *head, fr_sbuff_escape_rule return fr_sbuff_used_total(out) - at_in; } + /** Tokenize an xlat expansion at runtime * * This is used for runtime parsing of xlat expansions, such as those we receive from datastores