]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
xlat: Make xlat debug work for nodes again
authorArran Cudbard-Bell <a.cudbardb@freeradius.org>
Mon, 20 Feb 2023 18:35:21 +0000 (12:35 -0600)
committerArran Cudbard-Bell <a.cudbardb@freeradius.org>
Mon, 20 Feb 2023 20:51:58 +0000 (14:51 -0600)
...like it was originally intended to be used for

src/bin/unit_test_attribute.c
src/lib/unlang/xlat.h
src/lib/unlang/xlat_tokenize.c

index 8f2e5fe564deecd3dfa48bc78cf7c51d1560b36d..7a4503be40abd69f1e674f29149fbf051ee22601 100644 (file)
@@ -2925,14 +2925,14 @@ static size_t command_xlat_purify(command_result_t *result, command_file_ctx_t *
 
        if (fr_debug_lvl > 2) {
                DEBUG("Before purify --------------------------------------------------");
-               xlat_debug(head);
+               xlat_debug_head(head);
        }
 
        (void) xlat_purify(head, NULL);
 
        if (fr_debug_lvl > 2) {
                DEBUG("After purify --------------------------------------------------");
-               xlat_debug(head);
+               xlat_debug_head(head);
        }
 
        escaped_len = xlat_print(&FR_SBUFF_OUT(data, COMMAND_OUTPUT_MAX), head, &fr_value_escape_double);
index a5404b2f574a60858e5e666ccde6b9dd0338c2aa..7c6fd973fe830d98de100e82e02752d8e38f21a1 100644 (file)
@@ -412,7 +412,9 @@ int         xlat_validate_function_mono(xlat_exp_t *node);
 
 int            xlat_validate_function_args(xlat_exp_t *node);
 
-void           xlat_debug(xlat_exp_head_t const *head);
+void           xlat_debug(xlat_exp_t const *node);
+
+void           xlat_debug_head(xlat_exp_head_t const *head);
 
 bool           xlat_is_literal(xlat_exp_head_t const *head);
 
index 3cda3904284d2d3977b81468010bb221f5502678..70416bacb46e7e82db459b03177fe1677bc7999a 100644 (file)
@@ -1037,156 +1037,154 @@ static fr_table_num_sorted_t const xlat_quote_table[] = {
 };
 static size_t xlat_quote_table_len = NUM_ELEMENTS(xlat_quote_table);
 
-static void _xlat_debug(xlat_exp_head_t const *head, int depth)
-{
-       int i = 0;
-#ifndef NDEBUG
-       bool needs_resolving = false;
-#endif
-
 #define INFO_INDENT(_fmt, ...)  INFO("%*s"_fmt, depth * 2, " ", ## __VA_ARGS__)
 
-       fr_assert(head != NULL);
-
-       INFO_INDENT("head flags = %s %s %s",
-                   head->flags.needs_resolving ? "need_resolving," : "",
-                   head->flags.pure ? "pure" : "",
-                   head->flags.can_purify ? "can_purify" : "");
-
+static void _xlat_debug_head(xlat_exp_head_t const *head, int depth);
+static void _xlat_debug_node(xlat_exp_t const *node, int depth)
+{
+       INFO_INDENT("{");
        depth++;
 
-       xlat_exp_foreach(head, node) {
-               INFO_INDENT("[%d] flags = %s %s %s ", i++,
-                           node->flags.needs_resolving ? "need_resolving" : "",
-                           node->flags.pure ? "pure" : "",
-                           node->flags.can_purify ? "can_purify" : "");
-
-#ifndef NDEBUG
-               if (node->flags.needs_resolving) fr_assert(head->flags.needs_resolving);
-
-               if (!head->flags.needs_resolving) fr_assert(!node->flags.needs_resolving);
+       if (node->quote != T_BARE_WORD) INFO_INDENT("quote = %c", fr_token_quote[node->quote]);
 
-               needs_resolving |= node->flags.needs_resolving;
-#endif
+       switch (node->type) {
+       case XLAT_BOX:
+               INFO_INDENT("value %s --> %pV", fr_type_to_str(node->data.type), &node->data);
+               break;
 
+       case XLAT_GROUP:
+               INFO_INDENT("group");
                INFO_INDENT("{");
-               depth++;
-
-               if (node->quote != T_BARE_WORD) INFO_INDENT("quote = %c", fr_token_quote[node->quote]);
+               _xlat_debug_head(node->group, depth + 1);
+               INFO_INDENT("}");
+               break;
 
-               switch (node->type) {
-               case XLAT_BOX:
-                       INFO_INDENT("value %s --> %pV", fr_type_to_str(node->data.type), &node->data);
-                       break;
+       case XLAT_ONE_LETTER:
+               INFO_INDENT("percent (%c)", node->fmt[0]);
+               break;
 
-               case XLAT_GROUP:
-                       INFO_INDENT("group");
-                       INFO_INDENT("{");
-                       _xlat_debug(node->group, depth + 1);
-                       INFO_INDENT("}");
-                       break;
+       case XLAT_TMPL:
+       {
+               if (tmpl_is_attr(node->vpt)) {
+                       fr_assert(!node->flags.pure);
+                       INFO_INDENT("attribute (%s)", tmpl_attr_tail_da(node->vpt)->name);
+                       if (tmpl_attr_tail_num(node->vpt) != NUM_UNSPEC) {
+                               FR_DLIST_HEAD(tmpl_request_list) const *list;
+                               tmpl_request_t *rr = NULL;
 
-               case XLAT_ONE_LETTER:
-                       INFO_INDENT("percent (%c)", node->fmt[0]);
-                       break;
+                               INFO_INDENT("{");
 
-               case XLAT_TMPL:
-               {
-                       if (tmpl_is_attr(node->vpt)) {
-                               fr_assert(!node->flags.pure);
-                               INFO_INDENT("attribute (%s)", tmpl_attr_tail_da(node->vpt)->name);
+                               /*
+                                *      Loop over the request references
+                                */
+                               list = tmpl_request(node->vpt);
+                               while ((rr = tmpl_request_list_next(list, rr))) {
+                                       INFO_INDENT("ref  %d", rr->request);
+                               }
+                               INFO_INDENT("list %s", tmpl_list_name(tmpl_list(node->vpt), "<INVALID>"));
                                if (tmpl_attr_tail_num(node->vpt) != NUM_UNSPEC) {
-                                       FR_DLIST_HEAD(tmpl_request_list) const *list;
-                                       tmpl_request_t *rr = NULL;
-
-                                       INFO_INDENT("{");
-
-                                       /*
-                                        *      Loop over the request references
-                                        */
-                                       list = tmpl_request(node->vpt);
-                                       while ((rr = tmpl_request_list_next(list, rr))) {
-                                               INFO_INDENT("ref  %d", rr->request);
-                                       }
-                                       INFO_INDENT("list %s", tmpl_list_name(tmpl_list(node->vpt), "<INVALID>"));
-                                       if (tmpl_attr_tail_num(node->vpt) != NUM_UNSPEC) {
-                                               if (tmpl_attr_tail_num(node->vpt) == NUM_COUNT) {
-                                                       INFO_INDENT("[#]");
-                                               } else if (tmpl_attr_tail_num(node->vpt) == NUM_ALL) {
-                                                       INFO_INDENT("[*]");
-                                               } else {
-                                                       INFO_INDENT("[%d]", tmpl_attr_tail_num(node->vpt));
-                                               }
+                                       if (tmpl_attr_tail_num(node->vpt) == NUM_COUNT) {
+                                               INFO_INDENT("[#]");
+                                       } else if (tmpl_attr_tail_num(node->vpt) == NUM_ALL) {
+                                               INFO_INDENT("[*]");
+                                       } else {
+                                               INFO_INDENT("[%d]", tmpl_attr_tail_num(node->vpt));
                                        }
-                                       INFO_INDENT("}");
                                }
-                       } else if (tmpl_is_data(node->vpt)) {
-                               INFO_INDENT("tmpl (%s) type %s", node->fmt, fr_type_to_str(tmpl_value_type(node->vpt)));
-                       } else {
-                               INFO_INDENT("tmpl (%s)", node->fmt);
+                               INFO_INDENT("}");
                        }
+               } else if (tmpl_is_data(node->vpt)) {
+                       INFO_INDENT("tmpl (%s) type %s", node->fmt, fr_type_to_str(tmpl_value_type(node->vpt)));
+               } else {
+                       INFO_INDENT("tmpl (%s)", node->fmt);
                }
-                       break;
+       }
+               break;
 
-               case XLAT_VIRTUAL:
-                       fr_assert(node->fmt != NULL);
-                       INFO_INDENT("virtual (%s)", node->fmt);
-                       break;
+       case XLAT_VIRTUAL:
+               fr_assert(node->fmt != NULL);
+               INFO_INDENT("virtual (%s)", node->fmt);
+               break;
 
-               case XLAT_VIRTUAL_UNRESOLVED:
-                       fr_assert(node->fmt != NULL);
-                       INFO_INDENT("virtual-unresolved (%s)", node->fmt);
-                       break;
+       case XLAT_VIRTUAL_UNRESOLVED:
+               fr_assert(node->fmt != NULL);
+               INFO_INDENT("virtual-unresolved (%s)", node->fmt);
+               break;
 
-               case XLAT_FUNC:
-                       fr_assert(node->call.func != NULL);
-                       INFO_INDENT("xlat (%s)", node->call.func->name);
-                       if (xlat_exp_head(node->call.args)) {
-                               INFO_INDENT("{");
-                               _xlat_debug(node->call.args, depth + 1);
-                               INFO_INDENT("}");
-                       }
-                       break;
+       case XLAT_FUNC:
+               fr_assert(node->call.func != NULL);
+               INFO_INDENT("xlat (%s)", node->call.func->name);
+               if (xlat_exp_head(node->call.args)) {
+                       INFO_INDENT("{");
+                       _xlat_debug_head(node->call.args, depth + 1);
+                       INFO_INDENT("}");
+               }
+               break;
 
-               case XLAT_FUNC_UNRESOLVED:
-                       INFO_INDENT("xlat-unresolved (%s)", node->fmt);
-                       if (xlat_exp_head(node->call.args)) {
-                               INFO_INDENT("{");
-                               _xlat_debug(node->call.args, depth + 1);
-                               INFO_INDENT("}");
-                       }
-                       break;
+       case XLAT_FUNC_UNRESOLVED:
+               INFO_INDENT("xlat-unresolved (%s)", node->fmt);
+               if (xlat_exp_head(node->call.args)) {
+                       INFO_INDENT("{");
+                       _xlat_debug_head(node->call.args, depth + 1);
+                       INFO_INDENT("}");
+               }
+               break;
 
 #ifdef HAVE_REGEX
-               case XLAT_REGEX:
-                       INFO_INDENT("regex-var -- %d", node->regex_index);
-                       break;
+       case XLAT_REGEX:
+               INFO_INDENT("regex-var -- %d", node->regex_index);
+               break;
 #endif
 
-               case XLAT_ALTERNATE:
-                       DEBUG("XLAT-IF {");
-                       _xlat_debug(node->alternate[0], depth);
-                       DEBUG("}");
-                       DEBUG("XLAT-ELSE {");
-                       _xlat_debug(node->alternate[1], depth);
-                       DEBUG("}");
-                       break;
-
-               case XLAT_INVALID:
-                       DEBUG("XLAT-INVALID");
-                       break;
-               }
+       case XLAT_ALTERNATE:
+               DEBUG("XLAT-IF {");
+               _xlat_debug_head(node->alternate[0], depth);
+               DEBUG("}");
+               DEBUG("XLAT-ELSE {");
+               _xlat_debug_head(node->alternate[1], depth);
+               DEBUG("}");
+               break;
 
-               depth--;
-               INFO_INDENT("}");
+       case XLAT_INVALID:
+               DEBUG("XLAT-INVALID");
+               break;
        }
 
-       fr_assert(needs_resolving == head->flags.needs_resolving);
+       depth--;
+       INFO_INDENT("}");
+}
+
+void xlat_debug(xlat_exp_t const *node)
+{
+       _xlat_debug_node(node, 0);
+}
+
+static void _xlat_debug_head(xlat_exp_head_t const *head, int depth)
+{
+       int i = 0;
+
+       fr_assert(head != NULL);
+
+       INFO_INDENT("head flags = %s %s %s",
+                   head->flags.needs_resolving ? "need_resolving," : "",
+                   head->flags.pure ? "pure" : "",
+                   head->flags.can_purify ? "can_purify" : "");
+
+       depth++;
+
+       xlat_exp_foreach(head, node) {
+               INFO_INDENT("[%d] flags = %s %s %s ", i++,
+                           node->flags.needs_resolving ? "need_resolving" : "",
+                           node->flags.pure ? "pure" : "",
+                           node->flags.can_purify ? "can_purify" : "");
+
+               _xlat_debug_node(node, depth);
+       }
 }
 
-void xlat_debug(xlat_exp_head_t const *head)
+void xlat_debug_head(xlat_exp_head_t const *head)
 {
-       _xlat_debug(head, 0);
+       _xlat_debug_head(head, 0);
 }
 
 ssize_t xlat_print_node(fr_sbuff_t *out, xlat_exp_head_t const *head, xlat_exp_t const *node,