]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
add xlat_is_truthy(), to replace COND_TYPE_TRUE and COND_TYPE_FALSE
authorAlan T. DeKok <aland@freeradius.org>
Fri, 3 Jun 2022 19:59:52 +0000 (15:59 -0400)
committerAlan T. DeKok <aland@freeradius.org>
Mon, 6 Jun 2022 20:28:14 +0000 (16:28 -0400)
src/lib/unlang/xlat.h
src/lib/unlang/xlat_expr.c

index a27edeb36c7a9cfaa70ba89cce949beea2b02ab1..9051c250c1c430b594c1f066a0bc5ee7df3fbc46 100644 (file)
@@ -337,6 +337,8 @@ int         xlat_func_args(xlat_t *xlat, xlat_arg_parser_t const args[]) CC_HINT(nonnul
 
 int            xlat_func_mono(xlat_t *xlat, xlat_arg_parser_t const *arg) CC_HINT(nonnull);
 
+bool           xlat_is_truthy(xlat_exp_head_t const *head, bool *out);
+
 /** Set a callback for global instantiation of xlat functions
  *
  * @param[in] _xlat            function to set the callback for (as returned by xlat_register).
index f2f850507130965deee5584209ea1f965447458f..fd35945181aa512e9bb00cd4bba8323b6f36fb7e 100644 (file)
@@ -2343,3 +2343,46 @@ ssize_t xlat_tokenize_ephemeral_expression(TALLOC_CTX *ctx, xlat_exp_head_t **ou
        *out = head;
        return slen;
 }
+
+/**  Allow callers to see if an xlat is truthy
+ *
+ *  So the caller can cache it, and needs to check fewer things at run
+ *  time.
+ *
+ *  @param[in] head    of the xlat to check
+ *  @param[out] out    truthiness of the box
+ *  @return
+ *     - false - xlat is not truthy, *out is unchanged.
+ *     - true - xlat is truthy, *out is the result of fr_value_box_is_truthy()
+ */
+bool xlat_is_truthy(xlat_exp_head_t const *head, bool *out)
+{
+       xlat_exp_t const *node;
+       fr_value_box_t const *box;
+
+       /*
+        *      Only pure / constant things can be truthy.
+        */
+       if (!head->flags.pure) return false;
+
+       node = xlat_exp_head(head);
+       if (!node) {
+               *out = false;
+               return true;
+       }
+
+       if (xlat_exp_next(head, node)) return false;
+
+       if (node->type == XLAT_BOX) {
+               box = &node->data;
+
+       } else if ((node->type == XLAT_TMPL) && tmpl_is_data(node->vpt)) {
+               box = tmpl_value(node->vpt);
+
+       } else {
+               return false;
+       }
+
+       *out = fr_value_box_is_truthy(box);
+       return true;
+}