From: Arran Cudbard-Bell Date: Sun, 5 Dec 2021 05:21:41 +0000 (-0500) Subject: Add debug functions for parse rules X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2501fb72eadb8aa6ba89d4521b4435a11e765236;p=thirdparty%2Ffreeradius-server.git Add debug functions for parse rules Fix quicksort --- diff --git a/src/lib/util/misc.c b/src/lib/util/misc.c index 8de3f3f05f7..5d6821ecfca 100644 --- a/src/lib/util/misc.c +++ b/src/lib/util/misc.c @@ -598,34 +598,34 @@ int8_t fr_pointer_cmp(void const *a, void const *b) * * @param to_sort array of pointers to sort. * @param start the lowest index (usually 0). - * @param len the length of the array. + * @param end the length of the array. * @param cmp the comparison function to use to sort the array elements. */ -void fr_quick_sort(void const *to_sort[], int start, int len, fr_cmp_t cmp) +void fr_quick_sort(void const *to_sort[], int start, int end, fr_cmp_t cmp) { - int i = start; - int j = len; + int i, pi; + void const *pivot; - void const *pivot = to_sort[(i + j) / 2]; + if (start >= end) return; - while (i < j) { - void const *tmp; - - do ++i; while ((i < len) && (cmp(to_sort[i], pivot) < 0)); - do --j; while ((i > start) && (cmp(to_sort[j], pivot) > 0)); - - if (i <= j) { - tmp = to_sort[i]; - to_sort[i] = to_sort[j]; - to_sort[j] = tmp; +#define SWAP(_a, _b) \ + do { \ + void const *_tmp = to_sort[_a]; \ + to_sort[_a] = to_sort[_b]; \ + to_sort[_b] = _tmp; \ + } while (0) - i++; - j--; + pivot = to_sort[end]; + for (pi = start, i = start; i < end; i++) { + if (cmp(to_sort[i], pivot) < 0) { + SWAP(i , pi); + pi++; } } + SWAP(end, pi); - if (start < j) fr_quick_sort(to_sort, start, j, cmp); - if (i < len) fr_quick_sort(to_sort, i, len, cmp); + fr_quick_sort(to_sort, start, pi - 1, cmp); + fr_quick_sort(to_sort, pi + 1, end, cmp); } #ifdef TALLOC_DEBUG diff --git a/src/lib/util/sbuff.c b/src/lib/util/sbuff.c index 78e1c1c22e7..1602b640b93 100644 --- a/src/lib/util/sbuff.c +++ b/src/lib/util/sbuff.c @@ -590,7 +590,7 @@ fr_sbuff_term_t *fr_sbuff_terminals_amerge(TALLOC_CTX *ctx, fr_sbuff_term_t cons for (j = 0; j < b->len; i++, j++) tmp[i] = &b->elem[j]; if (likely(i > 1)) { - fr_quick_sort((void const **)tmp, 0, i, terminal_cmp); + fr_quick_sort((void const **)tmp, 0, i - 1, terminal_cmp); for (j = 0; j < (i - 1); j++) { /* @@ -2037,3 +2037,99 @@ bool fr_sbuff_is_terminal(fr_sbuff_t *in, fr_sbuff_term_t const *tt) return fr_sbuff_terminal_search(in, in->p, idx, tt, needle_len); } + +/** Print a char in a friendly format + * + */ +static char const *sbuff_print_char(char c) +{ + static bool const unprintables[UINT8_MAX + 1] = { + SBUFF_CHAR_UNPRINTABLES_LOW, + SBUFF_CHAR_UNPRINTABLES_EXTENDED + }; + + static _Thread_local char str[10][5]; + static _Thread_local char **p; + + switch (c) { + case '\a': + return "\a"; + + case '\b': + return "\b"; + + case '\n': + return "\n"; + + case '\r': + return "\r"; + + case '\t': + return "\t"; + + case '\f': + return "\f"; + + case '\v': + return "\v"; + + default: + if (!p || (p++ >= ((char **)str + (NUM_ELEMENTS(str) - 1)))) p = (char **)str; + + if (unprintables[(uint8_t)c]) { + snprintf(*p, sizeof(*str), "\\x%x", c); + return *p; + } + + *p[0] = c; + *p[1] = '\0'; + return *p; + } +} + +void fr_sbuff_unescape_debug(fr_sbuff_unescape_rules_t const *escapes) +{ + uint8_t i; + + FR_FAULT_LOG("Escape rules %s (%p)", escapes->name, escapes); + FR_FAULT_LOG("chr : %c", escapes->chr ? escapes->chr : ' '); + FR_FAULT_LOG("do_hex : %s", escapes->do_hex ? "yes" : "no"); + FR_FAULT_LOG("do_oct : %s", escapes->do_oct ? "yes" : "no"); + + FR_FAULT_LOG("substitutions:"); + for (i = 0; i < UINT8_MAX; i++) { + if (escapes->subs[i]) FR_FAULT_LOG("\t%s -> %s", + sbuff_print_char((char)i), + sbuff_print_char((char)escapes->subs[i])); + } + FR_FAULT_LOG("skipes:"); + for (i = 0; i < UINT8_MAX; i++) { + if (escapes->skip[i]) FR_FAULT_LOG("\t%s", sbuff_print_char((char)i)); + } +} + +void fr_sbuff_terminal_debug(fr_sbuff_term_t const *tt) +{ + size_t i; + + FR_FAULT_LOG("Terminal count %zu", tt->len); + + for (i = 0; i < tt->len; i++) FR_FAULT_LOG("\t\"%s\" (%zu)", tt->elem[i].str, tt->elem[i].len); +} + +void fr_sbuff_parse_rules_debug(fr_sbuff_parse_rules_t const *p_rules) +{ + FR_FAULT_LOG("Parse rules %p", p_rules); + + if (p_rules->escapes) { + fr_sbuff_unescape_debug(p_rules->escapes); + } else { + FR_FAULT_LOG("No unescapes"); + } + + if (p_rules->terminals) { + fr_sbuff_terminal_debug(p_rules->terminals); + } else { + FR_FAULT_LOG("No terminals"); + } +} diff --git a/src/lib/util/sbuff.h b/src/lib/util/sbuff.h index dee5033902e..afe979e1052 100644 --- a/src/lib/util/sbuff.h +++ b/src/lib/util/sbuff.h @@ -1700,6 +1700,12 @@ static inline bool _fr_sbuff_is_hex(fr_sbuff_t *sbuff, char const *p) /** @} */ +void fr_sbuff_unescape_debug(fr_sbuff_unescape_rules_t const *escapes); + +void fr_sbuff_terminal_debug(fr_sbuff_term_t const *tt); + +void fr_sbuff_parse_rules_debug(fr_sbuff_parse_rules_t const *p_rules); + #ifdef __cplusplus } #endif diff --git a/src/tests/unit/condition/xlat.txt b/src/tests/unit/condition/xlat.txt new file mode 100644 index 00000000000..deab84cf4c6 --- /dev/null +++ b/src/tests/unit/condition/xlat.txt @@ -0,0 +1,10 @@ +proto-dictionary radius + +condition %(integer:0) +match %(integer:0) + +condition (%(integer:0)) +match %(integer:0) + +count +match 5