From: Alan T. DeKok Date: Sun, 22 Mar 2020 15:44:05 +0000 (-0400) Subject: framework for adding XLAT_TYPE_CHILD X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=47b75cf4e80e61d8035739325cc25d8a17e61caf;p=thirdparty%2Ffreeradius-server.git framework for adding XLAT_TYPE_CHILD --- diff --git a/src/lib/server/xlat_eval.c b/src/lib/server/xlat_eval.c index 5664919fb35..aa355b4a383 100644 --- a/src/lib/server/xlat_eval.c +++ b/src/lib/server/xlat_eval.c @@ -126,6 +126,7 @@ static char *xlat_fmt_aprint(TALLOC_CTX *ctx, xlat_exp_t const *node) { switch (node->type) { case XLAT_LITERAL: + case XLAT_CHILD: return talloc_asprintf(ctx, "%s", node->fmt); case XLAT_ONE_LETTER: @@ -184,6 +185,7 @@ static char *xlat_fmt_aprint(TALLOC_CTX *ctx, xlat_exp_t const *node) return result; } + default: return NULL; } @@ -1068,6 +1070,18 @@ xlat_action_t xlat_frame_eval(TALLOC_CTX *ctx, fr_cursor_t *out, xlat_exp_t cons *child = node->child; xa = XLAT_ACTION_PUSH_CHILD; goto finish; + + case XLAT_CHILD: + XLAT_DEBUG("** [%i] %s(child) - %%{%s:...}", unlang_interpret_stack_depth(request), __FUNCTION__, + node->fmt); + + /* + * Hand back the child node to the caller + * for evaluation. + */ + *child = node->child; + xa = XLAT_ACTION_PUSH_CHILD; + goto finish; } } @@ -1103,6 +1117,10 @@ static char *xlat_aprint(TALLOC_CTX *ctx, REQUEST *request, xlat_exp_t const * c XLAT_DEBUG("%.*sxlat_aprint LITERAL", lvl, xlat_spaces); return talloc_typed_strdup(ctx, node->fmt); + case XLAT_CHILD: + XLAT_DEBUG("%.*sxlat_aprint CHILD", lvl, xlat_spaces); + return talloc_typed_strdup(ctx, node->fmt); + /* * Do a one-character expansion. */ @@ -1686,6 +1704,19 @@ int xlat_eval_walk(xlat_exp_t *exp, xlat_walker_t walker, xlat_type_t type, void if (ret < 0) return ret; break; + case XLAT_CHILD: + if (!type || (type & XLAT_CHILD)) { + ret = walker(node, uctx); + if (ret < 0) return ret; + } + + /* + * Evaluate the child. + */ + ret = xlat_eval_walk(node->child, walker, type, uctx); + if (ret < 0) return ret; + break; + default: if (!type || (type & node->type)) { ret = walker(node, uctx); diff --git a/src/lib/server/xlat_priv.h b/src/lib/server/xlat_priv.h index 414d5185be7..70581cbcb94 100644 --- a/src/lib/server/xlat_priv.h +++ b/src/lib/server/xlat_priv.h @@ -88,6 +88,7 @@ typedef enum { XLAT_REGEX = 0x20, //!< regex reference #endif XLAT_ALTERNATE = 0x40, //!< xlat conditional syntax :- + XLAT_CHILD = 0x80 //!< encapsulated string of xlats } xlat_type_t; /** An xlat expansion node diff --git a/src/lib/server/xlat_tokenize.c b/src/lib/server/xlat_tokenize.c index d8324e733a0..07497aa164c 100644 --- a/src/lib/server/xlat_tokenize.c +++ b/src/lib/server/xlat_tokenize.c @@ -749,6 +749,15 @@ static void xlat_tokenize_debug(REQUEST *request, xlat_exp_t const *node) RDEBUG3("literal --> %s", node->fmt); break; + case XLAT_CHILD: + RDEBUG3("child --> %s", node->fmt); + RDEBUG3("{"); + RINDENT(); + xlat_tokenize_debug(request, node->child); + REXDENT(); + RDEBUG3("}"); + break; + case XLAT_ONE_LETTER: RDEBUG3("percent --> %c", node->fmt[0]); break; @@ -831,7 +840,7 @@ size_t xlat_snprint(char *out, size_t outlen, xlat_exp_t const *node) #define CHECK_SPACE(_p, _end) if (_p >= _end) goto oob while (node) { - if (node->type == XLAT_LITERAL) { + if ((node->type == XLAT_LITERAL) || (node->type == XLAT_CHILD)) { p += strlcpy(p, node->fmt, end - p); CHECK_SPACE(p, end); goto next;