]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
update APIs to allow for "evaluate only one node"
authorAlan T. DeKok <aland@freeradius.org>
Thu, 19 May 2022 14:39:49 +0000 (10:39 -0400)
committerAlan T. DeKok <aland@freeradius.org>
Thu, 19 May 2022 15:40:47 +0000 (11:40 -0400)
instead of looping through everything

src/lib/unlang/xlat.c
src/lib/unlang/xlat_priv.h

index 7edace23758f1615c00cc98ec1586047d0adce45..89a65efe8ee0c5a5beb006b195fa1fa4f92a8bb7 100644 (file)
@@ -178,15 +178,16 @@ int unlang_xlat_timeout_add(request_t *request,
  *                             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] xlat             to evaluate.
+ * @param[in] xlat             head of list
+ * @param[in] node             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
  *     - 0 on success.
  *     - -1 on failure.
  */
-int unlang_xlat_push(TALLOC_CTX *ctx, bool *p_success, fr_value_box_list_t *out,
-                    request_t *request, xlat_exp_head_t const *xlat, bool top_frame)
+static int unlang_xlat_push_internal(TALLOC_CTX *ctx, bool *p_success, fr_value_box_list_t *out,
+                                    request_t *request, xlat_exp_head_t const *xlat, xlat_exp_t *node, bool top_frame)
 {
        /** Static instruction for performing xlat evaluations
         *
@@ -226,8 +227,8 @@ int unlang_xlat_push(TALLOC_CTX *ctx, bool *p_success, fr_value_box_list_t *out,
         *      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(xlat, xlat_exp_head_t);       /* Ensure the node is valid */
-       state->exp = xlat_exp_head(state->head);
+       state->head = xlat;
+       state->exp = node;
        state->success = p_success;
        state->ctx = ctx;
 
@@ -240,6 +241,46 @@ int unlang_xlat_push(TALLOC_CTX *ctx, bool *p_success, fr_value_box_list_t *out,
        return 0;
 }
 
+/** Push a pre-compiled xlat onto the stack for evaluation
+ *
+ * @param[in] ctx              To allocate value boxes and values in.
+ * @param[out] p_success       If set, and execution succeeds, true will be written
+ *                             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] 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
+ *     - 0 on success.
+ *     - -1 on failure.
+ */
+int unlang_xlat_push(TALLOC_CTX *ctx, bool *p_success, fr_value_box_list_t *out,
+                    request_t *request, xlat_exp_head_t const *xlat, bool top_frame)
+{
+       (void) talloc_get_type_abort_const(xlat, xlat_exp_head_t);
+
+       return unlang_xlat_push_internal(ctx, p_success, out, request, xlat, xlat_exp_head(xlat), top_frame);
+}
+
+/** Push a pre-compiled xlat onto the stack for evaluation
+ *
+ * @param[in] ctx              To allocate value boxes and values in.
+ * @param[out] p_success       If set, and execution succeeds, true will be written
+ *                             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] node             to evaluate.  Only this node will be evaluated.
+ * @return
+ *     - 0 on success.
+ *     - -1 on failure.
+ */
+int unlang_xlat_push_node(TALLOC_CTX *ctx, bool *p_success, fr_value_box_list_t *out,
+                         request_t *request, xlat_exp_t *node)
+{
+       return unlang_xlat_push_internal(ctx, p_success, out, request, NULL, node, UNLANG_TOP_FRAME);
+}
+
 static unlang_action_t unlang_xlat_repeat(rlm_rcode_t *p_result, request_t *request, unlang_stack_frame_t *frame)
 {
        unlang_frame_state_xlat_t       *state = talloc_get_type_abort(frame->state, unlang_frame_state_xlat_t);
index 82e86a51091d97324c97bcf16b95ca771e410323..67581289bc1670a3cdc3a6f49ca056bb10f8271f 100644 (file)
@@ -311,6 +311,9 @@ void                xlat_eval_free(void);
 
 void           unlang_xlat_init(void);
 
+int            unlang_xlat_push_node(TALLOC_CTX *ctx, bool *p_success, fr_value_box_list_t *out,
+                                     request_t *request, xlat_exp_t *node);
+
 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);
@@ -349,6 +352,8 @@ static inline xlat_exp_t *xlat_exp_head(xlat_exp_head_t const *head)
 
 static inline xlat_exp_t *xlat_exp_next(xlat_exp_head_t const *head, xlat_exp_t const *node)
 {
+       if (!head) return NULL;
+
        return fr_dlist_next(&head->dlist, node);
 }