SIZEOF(xlat_call_t);
SIZEOF(xlat_exp_t);
+ SIZEOF(xlat_exp_head_t);
return 0;
}
char *data, UNUSED size_t data_used, char *in, UNUSED size_t inlen)
{
ssize_t dec_len;
- xlat_exp_t *head = NULL;
+ xlat_exp_head_t *head = NULL;
size_t input_len = strlen(in), escaped_len;
fr_sbuff_parse_rules_t p_rules = { .escapes = &fr_value_unescape_double };
char *data, UNUSED size_t data_used, char *in, UNUSED size_t inlen)
{
ssize_t dec_len;
- xlat_exp_t *head = NULL;
+ xlat_exp_head_t *head = NULL;
size_t input_len = strlen(in), escaped_len;
// fr_sbuff_parse_rules_t p_rules = { .escapes = &fr_value_unescape_double };
char *data, UNUSED size_t data_used, char *in, UNUSED size_t inlen)
{
ssize_t dec_len;
- xlat_exp_t *head = NULL;
+ xlat_exp_head_t *head = NULL;
size_t input_len = strlen(in), escaped_len;
// fr_sbuff_parse_rules_t p_rules = { .escapes = &fr_value_unescape_double };
xlat_flags_t flags = {
int i, argc;
char *p;
ssize_t slen;
- xlat_exp_t *head = NULL;
- xlat_exp_t const **argv;
+ xlat_exp_head_t *head = NULL;
+ xlat_exp_head_t const **argv;
size_t len;
size_t input_len = strlen(in);
char buff[1024];
ssize_t slen;
TALLOC_CTX *xlat_ctx = talloc_init_const("xlat");
char *fmt = talloc_typed_strdup(xlat_ctx, input + 5);
- xlat_exp_t *head = NULL;
+ xlat_exp_head_t *head = NULL;
fr_sbuff_parse_rules_t p_rules = { .escapes = &fr_value_unescape_double };
slen = xlat_tokenize_ephemeral(xlat_ctx, &head, el, NULL,
ssize_t slen;
TALLOC_CTX *xlat_ctx = talloc_init_const("xlat");
char *fmt = talloc_typed_strdup(xlat_ctx, input + 10);
- xlat_exp_t *head = NULL;
+ xlat_exp_head_t *head = NULL;
xlat_flags_t flags = { };
slen = xlat_tokenize_ephemeral_expression(xlat_ctx, &head, el, &flags,
*/
if (is_xlat) {
ssize_t slen;
- xlat_exp_t *xlat;
+ xlat_exp_head_t *xlat;
redo:
xlat = NULL;
/*
* We do the debug printing because xlat_aeval_compiled
* doesn't have access to the original string. It's been
- * mangled during the parsing to xlat_exp_t
+ * mangled during the parsing to an internal data structure
*/
RDEBUG2("EXPAND %s", map->rhs->name);
RINDENT();
struct {
union {
_CONST struct {
- xlat_exp_t *ex; //!< pre-parsed xlat_exp_t
+ xlat_exp_head_t *ex; //!< pre-parsed xlat expansion
xlat_flags_t flags; //!< Flags controlling evaluation
///< and expansion.
} xlat;
*/
if (fr_sbuff_is_char(&our_in, '%')) {
tmpl_type_t type = TMPL_TYPE_XLAT;
- xlat_exp_t *head = NULL;
+ xlat_exp_head_t *head = NULL;
xlat_flags_t flags = {};
vpt = tmpl_alloc_null(ctx);
case T_DOUBLE_QUOTED_STRING:
{
- xlat_exp_t *head = NULL;
+ xlat_exp_head_t *head = NULL;
xlat_flags_t flags = {};
tmpl_type_t type = TMPL_TYPE_XLAT;
case T_BACK_QUOTED_STRING:
{
tmpl_type_t type = TMPL_TYPE_EXEC;
- xlat_exp_t *head = NULL;
+ xlat_exp_head_t *head = NULL;
xlat_flags_t flags = {};
vpt = tmpl_alloc_null(ctx);
case T_SOLIDUS_QUOTED_STRING:
{
- xlat_exp_t *head = NULL;
+ xlat_exp_head_t *head = NULL;
xlat_flags_t flags = {};
tmpl_type_t type = TMPL_TYPE_REGEX_XLAT;
typedef struct {
char *command; //!< Name of the trigger.
- xlat_exp_t *xlat; //!< xlat representation of the trigger args.
+ xlat_exp_head_t *xlat; //!< xlat representation of the trigger args.
fr_value_box_list_t args; //!< Arguments to pass to the trigger exec.
fr_exec_state_t exec; //!< Used for asynchronous execution.
{
unlang_frame_state_tmpl_t *state = talloc_get_type_abort(frame->state, unlang_frame_state_tmpl_t);
unlang_tmpl_t *ut = unlang_generic_to_tmpl(frame->instruction);
- xlat_exp_t const *xlat;
+ xlat_exp_head_t const *xlat;
/*
* If we're not called from unlang_tmpl_push(), then
typedef struct {
TALLOC_CTX *ctx; //!< to allocate boxes and values in.
TALLOC_CTX *event_ctx; //!< for temporary events
- xlat_exp_t const *head; //!< of the xlat list
+ xlat_exp_head_t const *head; //!< of the xlat list
xlat_exp_t const *exp; //!< current one we're evaluating
fr_dcursor_t values; //!< Values aggregated so far.
* here. If execution fails, false will be written.
* @param[out] out Where to write the result of the expansion.
* @param[in] request to push xlat onto.
- * @param[in] exp node to evaluate.
+ * @param[in] xlat to evaluate.
* @param[in] top_frame Set to UNLANG_TOP_FRAME if the interpreter should return.
* Set to UNLANG_SUB_FRAME if the interprer should continue.
* @return
* - -1 on failure.
*/
int unlang_xlat_push(TALLOC_CTX *ctx, bool *p_success, fr_value_box_list_t *out,
- request_t *request, xlat_exp_t const *exp, bool top_frame)
+ request_t *request, xlat_exp_head_t const *xlat, bool top_frame)
{
/** Static instruction for performing xlat evaluations
*
* Allocate its state, and setup a cursor for the xlat nodes
*/
MEM(frame->state = state = talloc_zero(stack, unlang_frame_state_xlat_t));
- state->head = talloc_get_type_abort_const(exp, xlat_exp_t); /* Ensure the node is valid */
- state->exp = state->head;
+ state->head = talloc_get_type_abort_const(xlat, xlat_exp_t); /* Ensure the node is valid */
+ state->exp = xlat_exp_head(state->head);
state->success = p_success;
state->ctx = ctx;
void const *escape_ctx)
CC_HINT(nonnull (1 ,3 ,4));
-ssize_t xlat_eval_compiled(char *out, size_t outlen, request_t *request, xlat_exp_t const *xlat,
+ssize_t xlat_eval_compiled(char *out, size_t outlen, request_t *request, xlat_exp_head_t const *head,
xlat_escape_legacy_t escape, void const *escape_ctx)
CC_HINT(nonnull (1 ,3 ,4));
CC_HINT(nonnull(2, 3, 4));
ssize_t xlat_aeval_compiled(TALLOC_CTX *ctx, char **out, request_t *request,
- xlat_exp_t const *xlat, xlat_escape_legacy_t escape, void const *escape_ctx)
+ xlat_exp_head_t const *head, xlat_escape_legacy_t escape, void const *escape_ctx)
CC_HINT(nonnull (2, 3, 4));
int xlat_aeval_compiled_argv(TALLOC_CTX *ctx, char ***argv, request_t *request,
- xlat_exp_t const *xlat, xlat_escape_legacy_t escape, void const *escape_ctx);
+ xlat_exp_head_t const *head, xlat_escape_legacy_t escape, void const *escape_ctx);
-int xlat_flatten_compiled_argv(TALLOC_CTX *ctx, xlat_exp_t const ***argv, xlat_exp_t const *xlat);
+int xlat_flatten_compiled_argv(TALLOC_CTX *ctx, xlat_exp_head_t const ***argv, xlat_exp_head_t const *head);
-bool xlat_async_required(xlat_exp_t const *xlat);
+bool xlat_async_required(xlat_exp_head_t const *xlat);
-ssize_t xlat_tokenize_expression(TALLOC_CTX *ctx, xlat_exp_t **head, xlat_flags_t *flags, fr_sbuff_t *in,
+ssize_t xlat_tokenize_expression(TALLOC_CTX *ctx, xlat_exp_head_t **head, xlat_flags_t *flags, fr_sbuff_t *in,
fr_sbuff_parse_rules_t const *p_rules, tmpl_rules_t const *t_rules);
-ssize_t xlat_tokenize_ephemeral_expression(TALLOC_CTX *ctx, xlat_exp_t **head,
+ssize_t xlat_tokenize_ephemeral_expression(TALLOC_CTX *ctx, xlat_exp_head_t **head,
fr_event_list_t *el,
xlat_flags_t *flags, fr_sbuff_t *in,
fr_sbuff_parse_rules_t const *p_rules, tmpl_rules_t const *t_rules);
-ssize_t xlat_tokenize_ephemeral(TALLOC_CTX *ctx, xlat_exp_t **head,
+ssize_t xlat_tokenize_ephemeral(TALLOC_CTX *ctx, xlat_exp_head_t **head,
fr_event_list_t *el,
xlat_flags_t *flags, fr_sbuff_t *in,
fr_sbuff_parse_rules_t const *p_rules, tmpl_rules_t const *t_rules);
-ssize_t xlat_tokenize_argv(TALLOC_CTX *ctx, xlat_exp_t **head, xlat_flags_t *flags, fr_sbuff_t *in,
+ssize_t xlat_tokenize_argv(TALLOC_CTX *ctx, xlat_exp_head_t **head, xlat_flags_t *flags, fr_sbuff_t *in,
fr_sbuff_parse_rules_t const *p_rules, tmpl_attr_rules_t const *t_rules);
-ssize_t xlat_tokenize(TALLOC_CTX *ctx, xlat_exp_t **head, xlat_flags_t *flags, fr_sbuff_t *in,
+ssize_t xlat_tokenize(TALLOC_CTX *ctx, xlat_exp_head_t **head, xlat_flags_t *flags, fr_sbuff_t *in,
fr_sbuff_parse_rules_t const *p_rules, tmpl_attr_rules_t const *t_rules);
-ssize_t xlat_print(fr_sbuff_t *in, xlat_exp_t const *node, fr_sbuff_escape_rules_t const *e_rules);
+ssize_t xlat_print(fr_sbuff_t *in, xlat_exp_head_t const *node, fr_sbuff_escape_rules_t const *e_rules);
-static inline fr_slen_t xlat_aprint(TALLOC_CTX *ctx, char **out, xlat_exp_t const *node,
+static inline fr_slen_t xlat_aprint(TALLOC_CTX *ctx, char **out, xlat_exp_head_t const *head,
fr_sbuff_escape_rules_t const *e_rules)
- SBUFF_OUT_TALLOC_FUNC_NO_LEN_DEF(xlat_print, node, e_rules)
+ SBUFF_OUT_TALLOC_FUNC_NO_LEN_DEF(xlat_print, head, e_rules)
int xlat_validate_function_mono(xlat_exp_t *node);
int xlat_validate_function_args(xlat_exp_t *node);
-void xlat_debug(xlat_exp_t const *node);
+void xlat_debug(xlat_exp_head_t const *head);
-bool xlat_is_literal(xlat_exp_t const *head);
+bool xlat_is_literal(xlat_exp_head_t const *head);
-bool xlat_to_string(TALLOC_CTX *ctx, char **str, xlat_exp_t **head);
+bool xlat_to_string(TALLOC_CTX *ctx, char **str, xlat_exp_head_t **head);
-int xlat_resolve(xlat_exp_t **head, xlat_flags_t *flags, xlat_res_rules_t const *xr_rules);
+int xlat_resolve(xlat_exp_head_t **head, xlat_flags_t *flags, xlat_res_rules_t const *xr_rules);
xlat_t *xlat_register_module(TALLOC_CTX *ctx, module_inst_ctx_t const *mctx,
char const *name, xlat_func_t func, xlat_flags_t const *flags);
/*
* xlat_tokenize.c
*/
-xlat_exp_t *xlat_exp_func_alloc(TALLOC_CTX *ctx, xlat_t *func, xlat_exp_t const *args);
+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_t **head);
+void xlat_exp_free(xlat_exp_head_t **head);
-tmpl_t *xlat_to_tmpl_attr(TALLOC_CTX *ctx, xlat_exp_t *xlat);
+tmpl_t *xlat_to_tmpl_attr(TALLOC_CTX *ctx, xlat_exp_head_t *xlat);
-int xlat_from_tmpl_attr(TALLOC_CTX *ctx, xlat_exp_t **head, xlat_flags_t *flags, tmpl_t **vpt_p);
+int xlat_from_tmpl_attr(TALLOC_CTX *ctx, xlat_exp_head_t **head, xlat_flags_t *flags, tmpl_t **vpt_p);
int xlat_copy(TALLOC_CTX *ctx, xlat_exp_t **out, xlat_exp_t const *in);
/*
* xlat_inst.c
*/
-int xlat_instantiate_ephemeral(xlat_exp_t *root, fr_event_list_t *el) CC_HINT(nonnull(1));
+int xlat_instantiate_ephemeral(xlat_exp_head_t *head, fr_event_list_t *el) CC_HINT(nonnull(1));
xlat_thread_inst_t *xlat_thread_instance_find(xlat_exp_t const *node);
void const *rctx, fr_time_t when);
int unlang_xlat_push(TALLOC_CTX *ctx, bool *p_success, fr_value_box_list_t *out,
- request_t *request, xlat_exp_t const *exp, bool top_frame)
+ request_t *request, xlat_exp_head_t const *head, bool top_frame)
CC_HINT(warn_unused_result);
xlat_action_t unlang_xlat_yield(request_t *request,
/* So we don't need to include xlat.h */
typedef struct xlat_exp xlat_exp_t;
+typedef struct xlat_exp xlat_exp_head_t;
/** An xlat calling ctx
*
};
size_t xlat_action_table_len = NUM_ELEMENTS(xlat_action_table);
-static ssize_t xlat_eval_sync(TALLOC_CTX *ctx, char **out, request_t *request, xlat_exp_t const * const head,
- xlat_escape_legacy_t escape, void const *escape_ctx);
+static ssize_t xlat_eval_sync(TALLOC_CTX *ctx, char **out, request_t *request, xlat_exp_head_t const * const head,
+ xlat_escape_legacy_t escape, void const *escape_ctx);
/** Reconstruct the original expansion string from an xlat tree
*
{
char *first, *second, *result;
- first = xlat_fmt_aprint(NULL, node->alternate[0]);
- second = xlat_fmt_aprint(NULL, node->alternate[1]);
+ first = xlat_fmt_aprint(NULL, xlat_exp_head(node->alternate[0]));
+ second = xlat_fmt_aprint(NULL, xlat_exp_head(node->alternate[1]));
result = talloc_asprintf(ctx, "%%{%s:-%s}", first, second);
talloc_free(first);
talloc_free(second);
* we print the concatenated arguments list as
* well as the original fmt string.
*/
- if ((node->type == XLAT_FUNC) && !xlat_is_literal(xlat_exp_head(node->call.args))) {
+ if ((node->type == XLAT_FUNC) && !xlat_is_literal(node->call.args)) {
RDEBUG2(" (%%%c%s:%pM%c)",
(node->call.func->input_type == XLAT_INPUT_ARGS) ? '(' : '{',
node->call.func->name, args,
* @param[in] result of a previous nested evaluation.
*/
xlat_action_t xlat_frame_eval_repeat(TALLOC_CTX *ctx, fr_dcursor_t *out,
- xlat_exp_t const **child, bool *alternate,
- request_t *request, xlat_exp_t const *head, xlat_exp_t const **in,
+ xlat_exp_head_t const **child, bool *alternate,
+ request_t *request, xlat_exp_head_t const *head, xlat_exp_t const **in,
fr_value_box_list_t *result)
{
xlat_exp_t const *node = *in;
* - XLAT_ACTION_DONE we're done, pop the frame.
* - XLAT_ACTION_FAIL an xlat module failed.
*/
-xlat_action_t xlat_frame_eval(TALLOC_CTX *ctx, fr_dcursor_t *out, xlat_exp_t const **child,
- request_t *request, xlat_exp_t const *head, xlat_exp_t const **in)
+xlat_action_t xlat_frame_eval(TALLOC_CTX *ctx, fr_dcursor_t *out, xlat_exp_head_t const **child,
+ request_t *request, xlat_exp_head_t const *head, xlat_exp_t const **in)
{
xlat_action_t xa = XLAT_ACTION_DONE;
xlat_exp_t const *node;
* for evaluation.
*/
if (xlat_exp_head(node->call.args)) {
- *child = xlat_exp_head(node->call.args);
+ *child = node->call.args;
xa = XLAT_ACTION_PUSH_CHILD;
goto finish;
}
return xa;
}
-static ssize_t xlat_eval_sync(TALLOC_CTX *ctx, char **out, request_t *request, xlat_exp_t const * const head,
+static ssize_t xlat_eval_sync(TALLOC_CTX *ctx, char **out, request_t *request, xlat_exp_head_t const * const head,
xlat_escape_legacy_t escape, void const *escape_ctx)
{
fr_value_box_list_t result;
* @param[out] out Where to write pointer to output buffer.
* @param[in] outlen Size of out.
* @param[in] request current request.
- * @param[in] node the xlat structure to expand
+ * @param[in] head the xlat structure to expand
* @param[in] escape function to escape final value e.g. SQL quoting.
* @param[in] escape_ctx pointer to pass to escape function.
* @return length of string written @bug should really have -1 for failure.
*/
static ssize_t _xlat_eval_compiled(TALLOC_CTX *ctx, char **out, size_t outlen, request_t *request,
- xlat_exp_t const *node, xlat_escape_legacy_t escape, void const *escape_ctx)
+ xlat_exp_head_t const *head, xlat_escape_legacy_t escape, void const *escape_ctx)
{
char *buff;
ssize_t slen;
- fr_assert(node != NULL);
+ fr_assert(head != NULL);
- slen = xlat_eval_sync(ctx, &buff, request, node, escape, escape_ctx);
+ slen = xlat_eval_sync(ctx, &buff, request, head, escape, escape_ctx);
if (slen < 0) {
fr_assert(buff == NULL);
if (*out) **out = '\0';
xlat_escape_legacy_t escape, void const *escape_ctx)
{
ssize_t len;
- xlat_exp_t *node;
+ xlat_exp_head_t *head;
RINDENT();
/*
* Give better errors than the old code.
*/
- len = xlat_tokenize_ephemeral(ctx, &node, unlang_interpret_event_list(request), NULL,
+ len = xlat_tokenize_ephemeral(ctx, &head, unlang_interpret_event_list(request), NULL,
&FR_SBUFF_IN(fmt, strlen(fmt)),
NULL,
&(tmpl_rules_t){
return -1;
}
- len = _xlat_eval_compiled(ctx, out, outlen, request, node, escape, escape_ctx);
- talloc_free(node);
+ len = _xlat_eval_compiled(ctx, out, outlen, request, head, escape, escape_ctx);
+ talloc_free(head);
REXDENT();
}
ssize_t xlat_eval_compiled(char *out, size_t outlen, request_t *request,
- xlat_exp_t const *xlat, xlat_escape_legacy_t escape, void const *escape_ctx)
+ xlat_exp_head_t const *xlat, xlat_escape_legacy_t escape, void const *escape_ctx)
{
fr_assert(done_init);
}
ssize_t xlat_aeval_compiled(TALLOC_CTX *ctx, char **out, request_t *request,
- xlat_exp_t const *xlat, xlat_escape_legacy_t escape, void const *escape_ctx)
+ xlat_exp_head_t const *xlat, xlat_escape_legacy_t escape, void const *escape_ctx)
{
fr_assert(done_init);
* - >0 on success which is argc to the corresponding argv
*/
int xlat_aeval_compiled_argv(TALLOC_CTX *ctx, char ***argv, request_t *request,
- xlat_exp_t const *head, xlat_escape_legacy_t escape, void const *escape_ctx)
+ xlat_exp_head_t const *head, xlat_escape_legacy_t escape, void const *escape_ctx)
{
int i;
ssize_t slen;
char **my_argv;
size_t count;
- if (head->type != XLAT_GROUP) return -1;
+ if (!xlat_exp_is_head(head)) return -1;
count = 0;
xlat_exp_foreach(head, node) {
*
* This is mostly for async use.
*/
-int xlat_flatten_compiled_argv(TALLOC_CTX *ctx, xlat_exp_t const ***argv, xlat_exp_t const *head)
+int xlat_flatten_compiled_argv(TALLOC_CTX *ctx, xlat_exp_head_t const ***argv, xlat_exp_head_t const *head)
{
int i;
- xlat_exp_t const **my_argv;
+ xlat_exp_head_t const **my_argv;
size_t count;
- if (head->type != XLAT_GROUP) return -1;
+ if (!xlat_exp_is_head(head)) return -1;
count = 0;
xlat_exp_foreach(head, node) {
count++;
}
- MEM(my_argv = talloc_zero_array(ctx, xlat_exp_t const *, count + 1));
+ MEM(my_argv = talloc_zero_array(ctx, xlat_exp_head_t const *, count + 1));
*argv = my_argv;
fr_assert(done_init);
* - 0 on success (walker always returned 0).
* - <0 if walker returned <0.
*/
-int xlat_eval_walk(xlat_exp_t *head, xlat_walker_t walker, xlat_type_t type, void *uctx)
+int xlat_eval_walk(xlat_exp_head_t *head, xlat_walker_t walker, xlat_type_t type, void *uctx)
{
int ret;
*
* If the xlat yields, then async is required.
*/
-bool xlat_async_required(xlat_exp_t const *head)
+bool xlat_async_required(xlat_exp_head_t const *head)
{
- if (head->type != XLAT_GROUP) {
- return head->flags.needs_async;
+ xlat_exp_t *first;
+
+ if (head) return false;
+
+ first = xlat_exp_head(head);
+ if (first->type != XLAT_GROUP) {
+ return first->flags.needs_async;
}
/*
size_t at_in = fr_sbuff_used_total(out);
FR_SBUFF_IN_STRCPY_RETURN(out, fr_tokens[node->call.func->token]);
- xlat_print_node(out, xlat_exp_head(node->call.args), e_rules);
+ xlat_print_node(out, node->call.args, xlat_exp_head(node->call.args), e_rules);
return fr_sbuff_used_total(out) - at_in;
}
size_t at_in = fr_sbuff_used_total(out);
FR_SBUFF_IN_CHAR_RETURN(out, '(');
- xlat_print_node(out, xlat_exp_head(node->call.args), e_rules); /* prints a space after the first argument */
+ xlat_print_node(out, node->call.args, xlat_exp_head(node->call.args), e_rules); /* prints a space after the first argument */
/*
* @todo - when things like "+" support more than 2 arguments, print them all out
*/
FR_SBUFF_IN_STRCPY_RETURN(out, fr_tokens[node->call.func->token]);
FR_SBUFF_IN_CHAR_RETURN(out, ' ');
- xlat_print_node(out, xlat_exp_next(node->call.args, xlat_exp_head(node->call.args)), e_rules);
+ xlat_print_node(out, node->call.args, xlat_exp_next(node->call.args, xlat_exp_head(node->call.args)), e_rules);
FR_SBUFF_IN_CHAR_RETURN(out, ')');
{
size_t at_in = fr_sbuff_used_total(out);
xlat_logical_inst_t *inst = instance;
- xlat_exp_t *head = inst->args;
+ xlat_exp_head_t *head = inst->args;
/*
* We might get called before the node is instantiated.
FR_SBUFF_IN_CHAR_RETURN(out, '(');
xlat_exp_foreach(head, child) {
- xlat_print_node(out, child, e_rules);
+ xlat_print_node(out, head, child, e_rules);
if (!xlat_exp_next(head, child)) break;
while (isspace((int) *fr_sbuff_current(_x))) fr_sbuff_advance(_x, 1); \
} while (0)
-static ssize_t tokenize_expression(TALLOC_CTX *ctx, xlat_exp_t **head, xlat_flags_t *flags, fr_sbuff_t *in,
+static ssize_t tokenize_expression(TALLOC_CTX *ctx, xlat_exp_head_t **head, xlat_flags_t *flags, fr_sbuff_t *in,
fr_sbuff_parse_rules_t const *p_rules, tmpl_rules_t const *t_rules,
fr_token_t prev, fr_sbuff_parse_rules_t const *bracket_rules);
static size_t expr_quote_table_len = NUM_ELEMENTS(expr_quote_table);
#ifdef HAVE_REGEX
-static ssize_t tokenize_regex(TALLOC_CTX *ctx, xlat_exp_t **head, xlat_flags_t *flags, fr_sbuff_t *in,
+static ssize_t tokenize_regex(TALLOC_CTX *ctx, xlat_exp_head_t **head, xlat_flags_t *flags, fr_sbuff_t *in,
fr_sbuff_parse_rules_t const *p_rules, tmpl_rules_t const *t_rules)
{
ssize_t slen;
* to parse the next thing we get. Otherwise, parse the thing as
* int64_t.
*/
-static ssize_t tokenize_field(TALLOC_CTX *input_ctx, xlat_exp_t **head, xlat_flags_t *flags, fr_sbuff_t *in,
+static ssize_t tokenize_field(TALLOC_CTX *input_ctx, xlat_exp_head_t **head, xlat_flags_t *flags, fr_sbuff_t *in,
fr_sbuff_parse_rules_t const *p_rules, tmpl_rules_t const *t_rules,
fr_sbuff_parse_rules_t const *bracket_rules)
{
* !EXPR
* A OP B
*/
-static ssize_t tokenize_expression(TALLOC_CTX *ctx, xlat_exp_t **head, xlat_flags_t *flags, fr_sbuff_t *in,
+static ssize_t tokenize_expression(TALLOC_CTX *ctx, xlat_exp_head_t **head, xlat_flags_t *flags, fr_sbuff_t *in,
fr_sbuff_parse_rules_t const *p_rules, tmpl_rules_t const *t_rules,
fr_token_t prev, fr_sbuff_parse_rules_t const *bracket_rules)
{
L("<"),
);
-ssize_t xlat_tokenize_expression(TALLOC_CTX *ctx, xlat_exp_t **head, xlat_flags_t *flags, fr_sbuff_t *in,
+ssize_t xlat_tokenize_expression(TALLOC_CTX *ctx, xlat_exp_head_t **head, xlat_flags_t *flags, fr_sbuff_t *in,
fr_sbuff_parse_rules_t const *p_rules, tmpl_rules_t const *t_rules)
{
ssize_t slen;
* - 0 and *head != NULL - Zero length expansion
* - <0 the negative offset of the parse failure.
*/
-ssize_t xlat_tokenize_ephemeral_expression(TALLOC_CTX *ctx, xlat_exp_t **head,
+ssize_t xlat_tokenize_ephemeral_expression(TALLOC_CTX *ctx, xlat_exp_head_t **head,
fr_event_list_t *el,
xlat_flags_t *flags, fr_sbuff_t *in,
fr_sbuff_parse_rules_t const *p_rules, tmpl_rules_t const *t_rules)
*
* @note This must only be used for xlats created at runtime.
*
- * @param[in] root of xlat tree to create instance data for.
+ * @param[in] head of xlat tree to create instance data for.
*/
-int xlat_instantiate_ephemeral(xlat_exp_t *root, fr_event_list_t *el)
+int xlat_instantiate_ephemeral(xlat_exp_head_t *head, fr_event_list_t *el)
{
- return xlat_eval_walk(root, _xlat_instantiate_ephemeral_walker, XLAT_FUNC, el);
+ return xlat_eval_walk(head, _xlat_instantiate_ephemeral_walker, XLAT_FUNC, el);
}
/** Retrieve xlat/thread specific instance data
typedef fr_slen_t (*xlat_print_t)(fr_sbuff_t *in, xlat_exp_t const *self, void *inst, fr_sbuff_escape_rules_t const *e_rules);
-
typedef struct xlat_s {
fr_rb_node_t node; //!< Entry in the xlat function tree.
char const *name; //!< Name of xlat function.
///< nodes by the time they were created.
xlat_t const *func; //!< The xlat expansion to expand format with.
- xlat_exp_t *args; //!< arguments to the function call
+ xlat_exp_head_t *args; //!< arguments to the function call
xlat_inst_t *inst; //!< Instance data for the #xlat_t.
xlat_thread_inst_t *thread_inst; //!< Thread specific instance.
xlat_exp_t *next; //!< Next in the list.
union {
- xlat_exp_t *alternate[2]; //!< alternate expansions
+ xlat_exp_head_t *alternate[2]; //!< alternate expansions
- xlat_exp_t *group; //!< children of a group
+ xlat_exp_head_t *group; //!< children of a group
/** An tmpl_t reference
*
request_t *request, fr_value_box_list_t *result, void *rctx);
xlat_action_t xlat_frame_eval_repeat(TALLOC_CTX *ctx, fr_dcursor_t *out,
- xlat_exp_t const **child, bool *alternate,
- request_t *request, xlat_exp_t const *head, xlat_exp_t const **in,
+ xlat_exp_head_t const **child, bool *alternate,
+ request_t *request, xlat_exp_head_t const *head, xlat_exp_t const **in,
fr_value_box_list_t *result) CC_HINT(nonnull(1,2,3,5,6));
-xlat_action_t xlat_frame_eval(TALLOC_CTX *ctx, fr_dcursor_t *out, xlat_exp_t const **child,
- request_t *request, xlat_exp_t const *head, xlat_exp_t const **in);
+xlat_action_t xlat_frame_eval(TALLOC_CTX *ctx, fr_dcursor_t *out, xlat_exp_head_t const **child,
+ request_t *request, xlat_exp_head_t const *head, xlat_exp_t const **in);
-int xlat_eval_walk(xlat_exp_t *exp, xlat_walker_t walker, xlat_type_t type, void *uctx);
+int xlat_eval_walk(xlat_exp_head_t *head, xlat_walker_t walker, xlat_type_t type, void *uctx);
int xlat_eval_init(void);
/*
* xlat_tokenize.c
*/
-int xlat_tokenize_expansion(TALLOC_CTX *ctx, xlat_exp_t **head, xlat_flags_t *flags, fr_sbuff_t *in,
+int xlat_tokenize_expansion(TALLOC_CTX *ctx, xlat_exp_head_t **head, xlat_flags_t *flags, fr_sbuff_t *in,
tmpl_attr_rules_t const *t_rules);
-int xlat_tokenize_function_args(TALLOC_CTX *ctx, xlat_exp_t **head, xlat_flags_t *flags, fr_sbuff_t *in,
+int xlat_tokenize_function_args(TALLOC_CTX *ctx, xlat_exp_head_t **head, xlat_flags_t *flags, fr_sbuff_t *in,
tmpl_attr_rules_t const *rules);
-ssize_t xlat_print_node(fr_sbuff_t *out, xlat_exp_t const *head, fr_sbuff_escape_rules_t const *e_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);
+
+static inline xlat_exp_t *xlat_exp_head(xlat_exp_head_t const *head)
+{
+ return UNCONST(xlat_exp_t *, head);
+}
/** Iterate over the contents of a list, only one level
*
* Will be declared in the scope of the loop.
*/
#define xlat_exp_foreach(_list_head, _iter) \
- for (xlat_exp_t *_iter = UNCONST(xlat_exp_t *, _list_head); _iter; _iter = _iter->next)
+ for (xlat_exp_t *_iter = xlat_exp_head(_list_head); _iter; _iter = _iter->next)
-static inline xlat_exp_t *xlat_exp_head(xlat_exp_t const *head)
+static inline xlat_exp_t *xlat_exp_next(UNUSED xlat_exp_head_t const *head, xlat_exp_t const *item)
{
- return UNCONST(xlat_exp_t *, head);
+ if (!item->next) return NULL;
+
+ return UNCONST(xlat_exp_t *, item->next);
}
-static inline xlat_exp_t *xlat_exp_next(UNUSED xlat_exp_t const *head, xlat_exp_t const *item)
+static inline bool xlat_exp_is_head(xlat_exp_head_t const *head)
{
- if (!item->next) return NULL;
+ return (head && (head->type == XLAT_GROUP));
- return UNCONST(xlat_exp_t *, item->next);
+// return (head && head->next && (head->next->type == XLAT_GROUP));
}
#ifdef __cplusplus
*
* @param[in,out] head to free. Will be set to NULL
*/
-void xlat_exp_free(xlat_exp_t **head)
+void xlat_exp_free(xlat_exp_head_t **head)
{
- xlat_exp_t *to_free = *head, *next;
+ xlat_exp_t *to_free = xlat_exp_head(*head), *next;
while (to_free) {
next = to_free->next;
};
static size_t xlat_quote_table_len = NUM_ELEMENTS(xlat_quote_table);
-static void _xlat_debug(xlat_exp_t const *head, int depth)
+static void _xlat_debug(xlat_exp_head_t const *head, int depth)
{
#define INFO_INDENT(_fmt, ...) INFO("%*s"_fmt, depth * 2, " ", ## __VA_ARGS__)
}
}
-void xlat_debug(xlat_exp_t const *node)
+void xlat_debug(xlat_exp_head_t const *head)
{
- _xlat_debug(node, 0);
+ _xlat_debug(head, 0);
}
-ssize_t xlat_print_node(fr_sbuff_t *out, xlat_exp_t const *head, fr_sbuff_escape_rules_t const *e_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)
{
ssize_t slen;
size_t at_in = fr_sbuff_used_total(out);
- xlat_exp_t const *node;
char close;
- node = xlat_exp_head(head);
if (!node) return 0;
switch (node->type) {
size_t at_in = fr_sbuff_used_total(out);
xlat_exp_foreach(head, node) {
- slen = xlat_print_node(out, node, e_rules);
+ slen = xlat_print_node(out, head, node, e_rules);
if (slen < 0) return slen - (fr_sbuff_used_total(out) - at_in);
}
* - 0 and *head != NULL - Zero length expansion
* - <0 the negative offset of the parse failure.
*/
-ssize_t xlat_tokenize_ephemeral(TALLOC_CTX *ctx, xlat_exp_t **head,
+ssize_t xlat_tokenize_ephemeral(TALLOC_CTX *ctx, xlat_exp_head_t **head,
fr_event_list_t *el,
xlat_flags_t *flags, fr_sbuff_t *in,
fr_sbuff_parse_rules_t const *p_rules, tmpl_rules_t const *t_rules)
* - <=0 on error.
* - >0 on success which is the number of characters parsed.
*/
-ssize_t xlat_tokenize_argv(TALLOC_CTX *ctx, xlat_exp_t **head, xlat_flags_t *flags, fr_sbuff_t *in,
+ssize_t xlat_tokenize_argv(TALLOC_CTX *ctx, xlat_exp_head_t **head, xlat_flags_t *flags, fr_sbuff_t *in,
fr_sbuff_parse_rules_t const *p_rules, tmpl_attr_rules_t const *t_rules)
{
fr_sbuff_t our_in = FR_SBUFF(in);
* - 0 and *head != NULL - Zero length expansion
* - < 0 the negative offset of the parse failure.
*/
-ssize_t xlat_tokenize(TALLOC_CTX *ctx, xlat_exp_t **head, xlat_flags_t *flags, fr_sbuff_t *in,
+ssize_t xlat_tokenize(TALLOC_CTX *ctx, xlat_exp_head_t **head, xlat_flags_t *flags, fr_sbuff_t *in,
fr_sbuff_parse_rules_t const *p_rules, tmpl_attr_rules_t const *t_rules)
{
fr_sbuff_t our_in = FR_SBUFF(in);
* - true if expansion contains only literal elements.
* - false if expansion contains expandable elements.
*/
-bool xlat_is_literal(xlat_exp_t const *head)
+bool xlat_is_literal(xlat_exp_head_t const *head)
{
xlat_exp_foreach(head, node) {
if (node->type != XLAT_BOX) return false;
* - true the tree consists of a single value node which was converted.
* - false the tree was more complex than a single literal, op was a noop.
*/
-bool xlat_to_string(TALLOC_CTX *ctx, char **str, xlat_exp_t **head)
+bool xlat_to_string(TALLOC_CTX *ctx, char **str, xlat_exp_head_t **head)
{
fr_sbuff_t out;
fr_sbuff_uctx_talloc_t tctx;
* - 0 on success.
* - -1 on failure.
*/
-int xlat_resolve(xlat_exp_t **head, xlat_flags_t *flags, xlat_res_rules_t const *xr_rules)
+int xlat_resolve(xlat_exp_head_t **head, xlat_flags_t *flags, xlat_res_rules_t const *xr_rules)
{
static xlat_res_rules_t xr_default;
xlat_flags_t our_flags;
* - 0 on success.
* - -1 on failure.
*/
-int xlat_from_tmpl_attr(TALLOC_CTX *ctx, xlat_exp_t **head, xlat_flags_t *flags, tmpl_t **vpt_p)
+int xlat_from_tmpl_attr(TALLOC_CTX *ctx, xlat_exp_head_t **head, xlat_flags_t *flags, tmpl_t **vpt_p)
{
xlat_exp_t *node;
xlat_t *func;