From: Alan T. DeKok Date: Fri, 3 Jun 2022 19:59:52 +0000 (-0400) Subject: add xlat_is_truthy(), to replace COND_TYPE_TRUE and COND_TYPE_FALSE X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=34a669ae7764ee507149154108064268191a2136;p=thirdparty%2Ffreeradius-server.git add xlat_is_truthy(), to replace COND_TYPE_TRUE and COND_TYPE_FALSE --- diff --git a/src/lib/unlang/xlat.h b/src/lib/unlang/xlat.h index a27edeb36c7..9051c250c1c 100644 --- a/src/lib/unlang/xlat.h +++ b/src/lib/unlang/xlat.h @@ -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). diff --git a/src/lib/unlang/xlat_expr.c b/src/lib/unlang/xlat_expr.c index f2f85050713..fd35945181a 100644 --- a/src/lib/unlang/xlat_expr.c +++ b/src/lib/unlang/xlat_expr.c @@ -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; +}