From: Arran Cudbard-Bell Date: Sun, 19 Feb 2023 22:49:52 +0000 (-0600) Subject: xlat: Move copy function to xlat_alloc.c X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=3d40895ede6f7b8776596b99013c8e13c51cf7cf;p=thirdparty%2Ffreeradius-server.git xlat: Move copy function to xlat_alloc.c --- diff --git a/src/lib/unlang/xlat.h b/src/lib/unlang/xlat.h index 46d867f054e..a5404b2f574 100644 --- a/src/lib/unlang/xlat.h +++ b/src/lib/unlang/xlat.h @@ -480,7 +480,11 @@ 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); -int xlat_copy(TALLOC_CTX *ctx, xlat_exp_head_t *out, xlat_exp_head_t const *in); +/* + * xlat_alloc.c + */ +int _xlat_copy(NDEBUG_LOCATION_ARGS TALLOC_CTX *ctx, xlat_exp_head_t *out, xlat_exp_head_t const *in); +#define xlat_copy(_ctx, _out, _in) _xlat_copy(NDEBUG_LOCATION_EXP _ctx, _out, _in) #ifdef WITH_VERIFY_PTR void xlat_exp_verify(xlat_exp_t const *node); void xlat_exp_head_verify(xlat_exp_head_t const *head); diff --git a/src/lib/unlang/xlat_alloc.c b/src/lib/unlang/xlat_alloc.c index 8dd42d4c8ca..24a28ac97e7 100644 --- a/src/lib/unlang/xlat_alloc.c +++ b/src/lib/unlang/xlat_alloc.c @@ -207,6 +207,119 @@ void xlat_exp_set_name_buffer_shallow(xlat_exp_t *node, char const *fmt) if (node->fmt) talloc_const_free(node->fmt); node->fmt = talloc_get_type_abort(fmt, char); } + +/** Copy all nodes in the input list to the output list + * + * @param[in] ctx to allocate new nodes in. + * @param[out] out Where to write new nodes. + * @param[in] in Input nodes. + * @return + * - 0 on success. + * - -1 on failure. + */ +static int _xlat_copy_internal(NDEBUG_LOCATION_ARGS TALLOC_CTX *ctx, xlat_exp_head_t *out, xlat_exp_head_t const *in) +{ + xlat_exp_head_t *head = NULL; + + xlat_flags_merge(&out->flags, &in->flags); + + /* + * Copy everything in the list of nodes + */ + xlat_exp_foreach(in, p) { + xlat_exp_t *node; + + (void)talloc_get_type_abort(p, xlat_exp_t); + + /* + * Ensure the format string is valid... At this point + * they should all be talloc'd strings. + */ + MEM(node = xlat_exp_alloc(ctx, p->type, + talloc_get_type_abort(p->fmt, char), talloc_array_length(p->fmt) - 1)); + node->quote = p->quote; + node->flags = p->flags; + + switch (p->type) { + case XLAT_INVALID: + fr_strerror_printf("Cannot copy xlat node of type \"invalid\""); + error: + talloc_free(head); + return -1; + + case XLAT_BOX: + if (unlikely(fr_value_box_copy(node, &node->data, &p->data) < 0)) goto error; + break; + + case XLAT_ONE_LETTER: /* Done with format */ + case XLAT_FUNC_UNRESOLVED: + case XLAT_VIRTUAL_UNRESOLVED: + break; + + case XLAT_VIRTUAL: + node->call.func = p->call.func; + node->call.ephemeral = p->call.ephemeral; + break; + + case XLAT_FUNC: + /* + * Only copy the function pointer, and whether this + * is ephemeral. + * + * All instance data is specific to the xlat node and + * cannot be duplicated. + * + * The node xlat nodes will need to be registered in + * the xlat instantiation table later. + */ + node->call.func = p->call.func; + node->call.ephemeral = p->call.ephemeral; + if (unlikely(_xlat_copy_internal(NDEBUG_LOCATION_VALS + node, node->call.args, p->call.args) < 0)) goto error; + break; + + case XLAT_TMPL: + node->vpt = tmpl_copy(node, p->vpt); + break; + +#ifdef HAVE_REGEX + case XLAT_REGEX: + node->regex_index = p->regex_index; + break; +#endif + + case XLAT_ALTERNATE: + if (unlikely(_xlat_copy_internal(NDEBUG_LOCATION_VALS + node, node->alternate[0], p->alternate[0]) < 0)) goto error; + if (unlikely(_xlat_copy_internal(NDEBUG_LOCATION_VALS + node, node->alternate[1], p->alternate[1]) < 0)) goto error; + break; + + case XLAT_GROUP: + if (unlikely(_xlat_copy_internal(NDEBUG_LOCATION_VALS + node, node->group, p->group) < 0)) goto error; + break; + } + + xlat_exp_insert_tail(out, node); + } + + return 0; +} + +int _xlat_copy(NDEBUG_LOCATION_ARGS TALLOC_CTX *ctx, xlat_exp_head_t *out, xlat_exp_head_t const *in) +{ + int ret; + + if (!in) return 0; + + XLAT_HEAD_VERIFY(in); + ret = _xlat_copy_internal(NDEBUG_LOCATION_VALS ctx, out, in); + XLAT_HEAD_VERIFY(out); + + return ret; +} + #ifdef WITH_VERIFY_PTR void xlat_exp_verify(xlat_exp_t const *node) { diff --git a/src/lib/unlang/xlat_tokenize.c b/src/lib/unlang/xlat_tokenize.c index 861158f0d16..fb6050729b2 100644 --- a/src/lib/unlang/xlat_tokenize.c +++ b/src/lib/unlang/xlat_tokenize.c @@ -2029,100 +2029,7 @@ int xlat_from_tmpl_attr(TALLOC_CTX *ctx, xlat_exp_head_t **out, tmpl_t **vpt_p) done: xlat_exp_insert_tail(head, node); - *out = head; - return 0; -} - -/** Copy all nodes in the input list to the output list - * - * @param[in] ctx to allocate new nodes in. - * @param[out] out Where to write new nodes. - * @param[in] in Input nodes. - * @return - * - 0 on success. - * - -1 on failure. - */ -int xlat_copy(TALLOC_CTX *ctx, xlat_exp_head_t *out, xlat_exp_head_t const *in) -{ - xlat_exp_head_t *head = NULL; - - if (!in) return 0; - - xlat_flags_merge(&out->flags, &in->flags); - - /* - * Copy everything in the list of nodes - */ - xlat_exp_foreach(in, p) { - xlat_exp_t *node; - - (void)talloc_get_type_abort(p, xlat_exp_t); - - /* - * Ensure the format string is valid... At this point - * they should all be talloc'd strings. - */ - MEM(node = xlat_exp_alloc(ctx, p->type, - talloc_get_type_abort(p->fmt, char), talloc_array_length(p->fmt) - 1)); - node->quote = p->quote; - node->flags = p->flags; - - switch (p->type) { - case XLAT_INVALID: - fr_strerror_printf("Cannot copy xlat node of type \"invalid\""); - error: - talloc_free(head); - return -1; - - case XLAT_BOX: - if (unlikely(fr_value_box_copy(node, &node->data, &p->data) < 0)) goto error; - break; - - case XLAT_ONE_LETTER: /* Done with format */ - case XLAT_FUNC_UNRESOLVED: - case XLAT_VIRTUAL_UNRESOLVED: - break; - - case XLAT_FUNC: - case XLAT_VIRTUAL: - /* - * Only copy the function pointer, and whether this - * is ephemeral. - * - * All instance data is specific to the xlat node and - * cannot be duplicated. - * - * The node xlat nodes will need to be registered in - * the xlat instantiation table later. - */ - node->call.func = p->call.func; - node->call.ephemeral = p->call.ephemeral; - if (unlikely(xlat_copy(node, node->call.args, p->call.args) < 0)) goto error; - break; - - case XLAT_TMPL: - node->vpt = tmpl_copy(node, p->vpt); - break; - -#ifdef HAVE_REGEX - case XLAT_REGEX: - node->regex_index = p->regex_index; - break; -#endif - - case XLAT_ALTERNATE: - if (unlikely(xlat_copy(node, node->alternate[0], p->alternate[0]) < 0)) goto error; - if (unlikely(xlat_copy(node, node->alternate[1], p->alternate[1]) < 0)) goto error; - break; - - case XLAT_GROUP: - if (unlikely(xlat_copy(node, node->group, p->group) < 0)) goto error; - break; - } - - xlat_exp_insert_tail(out, node); - } return 0; }