size_t len; //!< Length of the output string.
} xlat_out_t;
+/*
+ * Helper functions
+ */
+
/** Merge flags from child to parent
*
* For pass2, if either the parent or child is marked up for pass2, then the parent
parent->pure &= !parent->needs_async; /* things needing async cannot be pure */
}
+/** Set the type of an xlat node
+ *
+ * @param[in] node to set type for.
+ * @param[in] type to set.
+ */
+static inline void xlat_exp_set_type(xlat_exp_t *node, xlat_type_t type)
+{
+ node->type = type;
+}
+
+/** Allocate an xlat node with no name, and no type set
+ *
+ * @param[in] ctx to allocate node in.
+ * @return A new xlat node.
+ */
+static inline xlat_exp_t *xlat_exp_alloc_null(TALLOC_CTX *ctx)
+{
+ xlat_exp_t *node;
+
+ MEM(node = talloc_zero(ctx, xlat_exp_t));
+ node->flags.pure = true; /* everything starts pure */
+
+ return node;
+}
+
+/** Allocate an xlat node
+ *
+ * @param[in] ctx to allocate node in.
+ * @param[in] type of the node.
+ * @param[in] in original input string.
+ * @param[in] inlen the length of the original input string.
+ * @return A new xlat node.
+ */
+static inline xlat_exp_t *xlat_exp_alloc(TALLOC_CTX *ctx, xlat_type_t type,
+ char const *in, size_t inlen)
+{
+ xlat_exp_t *node;
+
+ node = xlat_exp_alloc_null(ctx);
+ node->type = type;
+
+ if (!in) return node;
+
+ node->fmt = talloc_bstrndup(node, in, inlen);
+ switch (type) {
+ case XLAT_BOX:
+ fr_value_box_strdup_shallow(&node->data, NULL, node->fmt, false);
+ break;
+
+ default:
+ break;
+ }
+
+ return node;
+}
+
+/** Set the format string for an xlat node
+ *
+ * @param[in] node to set fmt for.
+ * @param[in] fmt talloced buffer to set as the fmt string.
+ */
+static inline void xlat_exp_set_name_buffer_shallow(xlat_exp_t *node, char const *fmt)
+{
+ if (node->fmt) talloc_const_free(node->fmt);
+ node->fmt = fmt;
+}
+
+
/** Mark an xlat function as internal
*
* @param[in] xlat to mark as internal.
int xlat_decode_value_box_list(TALLOC_CTX *ctx, fr_pair_list_t *out,
request_t *request, void *decode_ctx, fr_pair_decode_t decode,
fr_value_box_list_t *in);
+/*
+ * xlat_tokenize.c
+ */
+int xlat_tokenize_expansion(TALLOC_CTX *ctx, xlat_exp_t **head, xlat_flags_t *flags, fr_sbuff_t *in,
+ tmpl_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,
+ tmpl_rules_t const *rules);
+
#ifdef __cplusplus
}
.terminals = &FR_SBUFF_TERM(")") /* These get merged with other literal terminals */
};
-/** Allocate an xlat node with no name, and no type set
- *
- * @param[in] ctx to allocate node in.
- * @return A new xlat node.
- */
-static inline CC_HINT(always_inline) xlat_exp_t *xlat_exp_alloc_null(TALLOC_CTX *ctx)
-{
- xlat_exp_t *node;
-
- MEM(node = talloc_zero(ctx, xlat_exp_t));
- node->flags.pure = true; /* everything starts pure */
-
- return node;
-}
-
-/** Allocate an xlat node
- *
- * @param[in] ctx to allocate node in.
- * @param[in] type of the node.
- * @param[in] in original input string.
- * @param[in] inlen the length of the original input string.
- * @return A new xlat node.
- */
-static inline CC_HINT(always_inline) xlat_exp_t *xlat_exp_alloc(TALLOC_CTX *ctx, xlat_type_t type,
- char const *in, size_t inlen)
-{
- xlat_exp_t *node;
-
- node = xlat_exp_alloc_null(ctx);
- node->type = type;
-
- if (!in) return node;
-
- node->fmt = talloc_bstrndup(node, in, inlen);
- switch (type) {
- case XLAT_BOX:
- fr_value_box_strdup_shallow(&node->data, NULL, node->fmt, false);
- break;
-
- default:
- break;
- }
-
- return node;
-}
-
/** Allocate an xlat node to call an xlat function
*
* @param[in] ctx to allocate the new node in.
}
node->flags = func->flags;
- return node;
-}
+ /*
+ * A pure function can have impure arguments, e.g. hash(sql query).
+ */
+ while (args) {
+ node->flags.pure &= args->flags.pure;
+ args = args->next;
+ }
-/** Set the type of an xlat node
- *
- * @param[in] node to set type for.
- * @param[in] type to set.
- */
-static inline CC_HINT(always_inline) void xlat_exp_set_type(xlat_exp_t *node, xlat_type_t type)
-{
- node->type = type;
+ return node;
}
#if 0
}
#endif
-/** Set the format string for an xlat node
- *
- * @param[in] node to set fmt for.
- * @param[in] fmt talloced buffer to set as the fmt string.
- */
-static inline CC_HINT(always_inline) void xlat_exp_set_name_buffer_shallow(xlat_exp_t *node, char const *fmt)
-{
- if (node->fmt) talloc_const_free(node->fmt);
- node->fmt = fmt;
-}
-
/** Free a linked list of xlat nodes
*
* @param[in,out] head to free. Will be set to NULL
*head = NULL;
}
-static int xlat_tokenize_expansion(TALLOC_CTX *ctx, xlat_exp_t **head, xlat_flags_t *flags, fr_sbuff_t *in,
- tmpl_rules_t const *t_rules);
-
static int xlat_tokenize_string(TALLOC_CTX *ctx, xlat_exp_t **head, xlat_flags_t *flags,
fr_sbuff_t *in, bool brace,
fr_sbuff_parse_rules_t const *p_rules, tmpl_rules_t const *t_rules);
-static inline int xlat_tokenize_function_args(TALLOC_CTX *ctx, xlat_exp_t **head,
- xlat_flags_t *flags, fr_sbuff_t *in,
- tmpl_rules_t const *rules);
-
static inline int xlat_tokenize_alternation(TALLOC_CTX *ctx, xlat_exp_t **head, xlat_flags_t *flags, fr_sbuff_t *in,
tmpl_rules_t const *t_rules, bool func_args)
{
* - 0 if the string was parsed into a function.
* - <0 on parse error.
*/
-static inline int xlat_tokenize_function_args(TALLOC_CTX *ctx, xlat_exp_t **head,
- xlat_flags_t *flags, fr_sbuff_t *in,
- tmpl_rules_t const *rules)
+int xlat_tokenize_function_args(TALLOC_CTX *ctx, xlat_exp_t **head,
+ xlat_flags_t *flags, fr_sbuff_t *in,
+ tmpl_rules_t const *rules)
{
xlat_exp_t *node;
xlat_t *func;
return 0;
}
-static int xlat_tokenize_expansion(TALLOC_CTX *ctx, xlat_exp_t **head, xlat_flags_t *flags, fr_sbuff_t *in,
- tmpl_rules_t const *t_rules)
+int xlat_tokenize_expansion(TALLOC_CTX *ctx, xlat_exp_t **head, xlat_flags_t *flags, fr_sbuff_t *in,
+ tmpl_rules_t const *t_rules)
{
size_t len;
fr_sbuff_marker_t s_m;