From 3a4134280fea577b666518eade191b9498cba971 Mon Sep 17 00:00:00 2001 From: Khairul Azhar Kasmiran Date: Tue, 30 Sep 2025 17:46:45 +0800 Subject: [PATCH] `-h`: Refactor out column width code (#5420) --- binrz/rz-test/rz-test.c | 10 +------- librz/include/rz_util/rz_print.h | 2 ++ librz/main/rizin.c | 10 +------- librz/main/rz-asm.c | 10 +------- librz/main/rz-ax.c | 16 ++----------- librz/main/rz-bin.c | 10 +------- librz/main/rz-diff.c | 10 +------- librz/main/rz-find.c | 10 +------- librz/main/rz-gg.c | 10 +------- librz/main/rz-hash.c | 10 +------- librz/main/rz-run.c | 10 +------- librz/main/rz-sign.c | 10 +------- librz/util/print.c | 40 +++++++++++++++++++++++++++++--- 13 files changed, 51 insertions(+), 107 deletions(-) diff --git a/binrz/rz-test/rz-test.c b/binrz/rz-test/rz-test.c index 7637889529..191a4c303d 100644 --- a/binrz/rz-test/rz-test.c +++ b/binrz/rz-test/rz-test.c @@ -88,15 +88,7 @@ static int help(bool verbose) { "-x", "[num]", "Number of expected failed tests", // clang-format on }; - size_t maxFlagAndArgLength = 0; - for (int i = 0; i < RZ_ARRAY_SIZE(options); i += 3) { - size_t flagLength = strlen(options[i]); - size_t argLength = strlen(options[i + 1]); - size_t flagAndArgLength = flagLength + argLength; - if (flagAndArgLength > maxFlagAndArgLength) { - maxFlagAndArgLength = flagAndArgLength; - } - } + size_t maxFlagAndArgLength = rz_print_options_get_max_len(options, RZ_ARRAY_SIZE(options), NULL); for (int i = 0; i < RZ_ARRAY_SIZE(options); i += 3) { if (i + 1 < RZ_ARRAY_SIZE(options)) { rz_print_colored_help_option(options[i], options[i + 1], options[i + 2], maxFlagAndArgLength); diff --git a/librz/include/rz_util/rz_print.h b/librz/include/rz_util/rz_print.h index f1a8b14080..8304448d8e 100644 --- a/librz/include/rz_util/rz_print.h +++ b/librz/include/rz_util/rz_print.h @@ -234,6 +234,8 @@ RZ_API RZ_OWN char *rz_print_json_indent(RZ_NULLABLE const char *s, bool color, RZ_API char *rz_print_json_human(const char *s); RZ_API RZ_OWN RzStrBuf *rz_print_colorize_asm_str(RZ_BORROW RzPrint *p, const RzAsmTokenString *toks); +RZ_API size_t rz_print_options_get_max_len(const char **options, size_t options_len, + RZ_NULLABLE size_t *maxDescLength); RZ_API void rz_print_colored_help_option(const char *flag, const char *arg, const char *desc, size_t maxFlagAndArgLength); RZ_API void rz_print_colored_help_option_example(RZ_NULLABLE const char *flag, RZ_NULLABLE const char *arg, diff --git a/librz/main/rizin.c b/librz/main/rizin.c index 24ad0be47c..6481548f77 100644 --- a/librz/main/rizin.c +++ b/librz/main/rizin.c @@ -139,15 +139,7 @@ static int main_help(RZ_BORROW RZ_NONNULL RzCore *core, int line) { "-z, -zz", "", "Do not load strings or load them even in raw", // clang-format on }; - size_t maxFlagAndArgLength = 0; - for (int i = 0; i < RZ_ARRAY_SIZE(options); i += 3) { - size_t flagLength = strlen(options[i]); - size_t argLength = strlen(options[i + 1]); - size_t flagAndArgLength = flagLength + argLength; - if (flagAndArgLength > maxFlagAndArgLength) { - maxFlagAndArgLength = flagAndArgLength; - } - } + size_t maxFlagAndArgLength = rz_print_options_get_max_len(options, RZ_ARRAY_SIZE(options), NULL); for (int i = 0; i < RZ_ARRAY_SIZE(options); i += 3) { if (i + 1 < RZ_ARRAY_SIZE(options)) { rz_print_colored_help_option(options[i], options[i + 1], options[i + 2], maxFlagAndArgLength); diff --git a/librz/main/rz-asm.c b/librz/main/rz-asm.c index 9253da416b..b51b4e8b27 100644 --- a/librz/main/rz-asm.c +++ b/librz/main/rz-asm.c @@ -207,15 +207,7 @@ static int rasm_show_help(int v) { // clang-format on }; if (v != 1) { - size_t maxFlagAndArgLength = 0; - for (int i = 0; i < RZ_ARRAY_SIZE(options); i += 3) { - size_t flagLength = strlen(options[i]); - size_t argLength = strlen(options[i + 1]); - size_t flagAndArgLength = flagLength + argLength; - if (flagAndArgLength > maxFlagAndArgLength) { - maxFlagAndArgLength = flagAndArgLength; - } - } + size_t maxFlagAndArgLength = rz_print_options_get_max_len(options, RZ_ARRAY_SIZE(options), NULL); for (int i = 0; i < RZ_ARRAY_SIZE(options); i += 3) { if (i + 1 < RZ_ARRAY_SIZE(options)) { rz_print_colored_help_option(options[i], options[i + 1], options[i + 2], maxFlagAndArgLength); diff --git a/librz/main/rz-ax.c b/librz/main/rz-ax.c index 544063f547..64dc3e1050 100644 --- a/librz/main/rz-ax.c +++ b/librz/main/rz-ax.c @@ -248,20 +248,8 @@ static int help(void) { #undef CF #undef CA #undef CR - size_t maxFlagAndArgLength = 0; - size_t maxDescLength = 0; - for (int i = 0; i < RZ_ARRAY_SIZE(options); i += 4) { - size_t flagLength = options[i] ? strlen(options[i]) : 0; - size_t argLength = options[i + 1] ? strlen(options[i + 1]) : 0; - size_t flagAndArgLength = flagLength + argLength; - if (flagAndArgLength > maxFlagAndArgLength) { - maxFlagAndArgLength = flagAndArgLength; - } - size_t descLength = strlen(options[i + 2]); - if (descLength > maxDescLength) { - maxDescLength = descLength; - } - } + size_t maxDescLength = SIZE_MAX; + size_t maxFlagAndArgLength = rz_print_options_get_max_len(options, RZ_ARRAY_SIZE(options), &maxDescLength); for (int i = 0; i < RZ_ARRAY_SIZE(options); i += 4) { if (i + 1 < RZ_ARRAY_SIZE(options)) { rz_print_colored_help_option_example(options[i], options[i + 1], options[i + 2], diff --git a/librz/main/rz-bin.c b/librz/main/rz-bin.c index 1ef97eed23..0faaf110fc 100644 --- a/librz/main/rz-bin.c +++ b/librz/main/rz-bin.c @@ -218,15 +218,7 @@ static int rzbin_show_help(int v) { "-Z", "", "Guess size of binary program", // clang-format on }; - size_t maxFlagAndArgLength = 0; - for (int i = 0; i < RZ_ARRAY_SIZE(options); i += 3) { - size_t flagLength = strlen(options[i]); - size_t argLength = strlen(options[i + 1]); - size_t flagAndArgLength = flagLength + argLength; - if (flagAndArgLength > maxFlagAndArgLength) { - maxFlagAndArgLength = flagAndArgLength; - } - } + size_t maxFlagAndArgLength = rz_print_options_get_max_len(options, RZ_ARRAY_SIZE(options), NULL); for (int i = 0; i < RZ_ARRAY_SIZE(options); i += 3) { if (i + 1 < RZ_ARRAY_SIZE(options)) { rz_print_colored_help_option(options[i], options[i + 1], options[i + 2], maxFlagAndArgLength); diff --git a/librz/main/rz-diff.c b/librz/main/rz-diff.c index 4f4bbe4923..d3839ea26c 100644 --- a/librz/main/rz-diff.c +++ b/librz/main/rz-diff.c @@ -243,15 +243,7 @@ static void rz_diff_show_help(bool usage_only) { "", "", " symbols | compare symbols found in the files", // clang-format on }; - size_t maxFlagAndArgLength = 0; - for (int i = 0; i < RZ_ARRAY_SIZE(options); i += 3) { - size_t flagLength = strlen(options[i]); - size_t argLength = strlen(options[i + 1]); - size_t flagAndArgLength = flagLength + argLength; - if (flagAndArgLength > maxFlagAndArgLength) { - maxFlagAndArgLength = flagAndArgLength; - } - } + size_t maxFlagAndArgLength = rz_print_options_get_max_len(options, RZ_ARRAY_SIZE(options), NULL); for (int i = 0; i < RZ_ARRAY_SIZE(options); i += 3) { if (i + 1 < RZ_ARRAY_SIZE(options)) { rz_print_colored_help_option(options[i], options[i + 1], options[i + 2], maxFlagAndArgLength); diff --git a/librz/main/rz-find.c b/librz/main/rz-find.c index 3fe3432dbb..c24f6c4315 100644 --- a/librz/main/rz-find.c +++ b/librz/main/rz-find.c @@ -223,15 +223,7 @@ static int show_help(const char *argv0, int line) { "-Z", "", "Show string found on each search hit", // clang-format on }; - size_t maxFlagAndArgLength = 0; - for (int i = 0; i < RZ_ARRAY_SIZE(options); i += 3) { - size_t flagLength = strlen(options[i]); - size_t argLength = strlen(options[i + 1]); - size_t flagAndArgLength = flagLength + argLength; - if (flagAndArgLength > maxFlagAndArgLength) { - maxFlagAndArgLength = flagAndArgLength; - } - } + size_t maxFlagAndArgLength = rz_print_options_get_max_len(options, RZ_ARRAY_SIZE(options), NULL); for (int i = 0; i < RZ_ARRAY_SIZE(options); i += 3) { if (i + 1 < RZ_ARRAY_SIZE(options)) { rz_print_colored_help_option(options[i], options[i + 1], options[i + 2], maxFlagAndArgLength); diff --git a/librz/main/rz-gg.c b/librz/main/rz-gg.c index 1340e57791..3bd1541f0a 100644 --- a/librz/main/rz-gg.c +++ b/librz/main/rz-gg.c @@ -50,15 +50,7 @@ static int usage(int v) { "-z", "" ,"Output in C string syntax", // clang-format on }; - size_t maxFlagAndArgLength = 0; - for (int i = 0; i < RZ_ARRAY_SIZE(options); i += 3) { - size_t flagLength = strlen(options[i]); - size_t argLength = strlen(options[i + 1]); - size_t flagAndArgLength = flagLength + argLength; - if (flagAndArgLength > maxFlagAndArgLength) { - maxFlagAndArgLength = flagAndArgLength; - } - } + size_t maxFlagAndArgLength = rz_print_options_get_max_len(options, RZ_ARRAY_SIZE(options), NULL); for (int i = 0; i < RZ_ARRAY_SIZE(options); i += 3) { if (i + 1 < RZ_ARRAY_SIZE(options)) { rz_print_colored_help_option(options[i], options[i + 1], options[i + 2], maxFlagAndArgLength); diff --git a/librz/main/rz-hash.c b/librz/main/rz-hash.c index dfe0955030..3d8a71c6e5 100644 --- a/librz/main/rz-hash.c +++ b/librz/main/rz-hash.c @@ -109,15 +109,7 @@ static void rz_hash_show_help(bool usage_only) { "", "", "If 's:' prefix is specified", // clang-format on }; - size_t maxFlagAndArgLength = 0; - for (int i = 0; i < RZ_ARRAY_SIZE(options); i += 3) { - size_t flagLength = strlen(options[i]); - size_t argLength = strlen(options[i + 1]); - size_t flagAndArgLength = flagLength + argLength; - if (flagAndArgLength > maxFlagAndArgLength) { - maxFlagAndArgLength = flagAndArgLength; - } - } + size_t maxFlagAndArgLength = rz_print_options_get_max_len(options, RZ_ARRAY_SIZE(options), NULL); for (int i = 0; i < RZ_ARRAY_SIZE(options); i += 3) { if (i + 1 < RZ_ARRAY_SIZE(options)) { rz_print_colored_help_option(options[i], options[i + 1], options[i + 2], maxFlagAndArgLength); diff --git a/librz/main/rz-run.c b/librz/main/rz-run.c index a4eb3117f4..dd4f99df58 100644 --- a/librz/main/rz-run.c +++ b/librz/main/rz-run.c @@ -37,15 +37,7 @@ static void rz_run_help(int v) { "--", "[program] [args]", "Run commands", // clang-format on }; - size_t maxFlagAndArgLength = 0; - for (int i = 0; i < RZ_ARRAY_SIZE(options); i += 3) { - size_t flagLength = strlen(options[i]); - size_t argLength = strlen(options[i + 1]); - size_t flagAndArgLength = flagLength + argLength; - if (flagAndArgLength > maxFlagAndArgLength) { - maxFlagAndArgLength = flagAndArgLength; - } - } + size_t maxFlagAndArgLength = rz_print_options_get_max_len(options, RZ_ARRAY_SIZE(options), NULL); for (int i = 0; i < RZ_ARRAY_SIZE(options); i += 3) { if (i + 1 < RZ_ARRAY_SIZE(options)) { rz_print_colored_help_option(options[i], options[i + 1], options[i + 2], maxFlagAndArgLength); diff --git a/librz/main/rz-sign.c b/librz/main/rz-sign.c index 4e88086580..93b13926a1 100644 --- a/librz/main/rz-sign.c +++ b/librz/main/rz-sign.c @@ -26,15 +26,7 @@ static void rz_sign_show_help(void) { "-v", "", "Show version information", // clang-format on }; - size_t maxFlagAndArgLength = 0; - for (int i = 0; i < RZ_ARRAY_SIZE(options); i += 3) { - size_t flagLength = strlen(options[i]); - size_t argLength = strlen(options[i + 1]); - size_t flagAndArgLength = flagLength + argLength; - if (flagAndArgLength > maxFlagAndArgLength) { - maxFlagAndArgLength = flagAndArgLength; - } - } + size_t maxFlagAndArgLength = rz_print_options_get_max_len(options, RZ_ARRAY_SIZE(options), NULL); for (int i = 0; i < RZ_ARRAY_SIZE(options); i += 3) { if (i + 1 < RZ_ARRAY_SIZE(options)) { rz_print_colored_help_option(options[i], options[i + 1], options[i + 2], maxFlagAndArgLength); diff --git a/librz/util/print.c b/librz/util/print.c index 979d98bf2f..27cb1f9922 100644 --- a/librz/util/print.c +++ b/librz/util/print.c @@ -1456,6 +1456,40 @@ RZ_API RZ_OWN RzStrBuf *rz_print_colorize_asm_str(RZ_BORROW RzPrint *p, const Rz return out; } +/** + * \brief Returns the maximum flag+arg length in \p options, and optionally the maximum description length. + * + * \param options Options string array, with 3 (default) or 4 strings per option depending on \p maxDescLength. + * \param options_len Length of \p options in strings, should be RZ_ARRAY_SIZE(options). + * \param maxDescLength If not NULL, this will contain the maximum description length in \p options, and function will + * assume that there are 4 strings per option. + * \return The maximum flag+arg length in \p options. + */ +RZ_API size_t rz_print_options_get_max_len(const char **options, size_t options_len, + RZ_NULLABLE size_t *maxDescLength) { + + int items_per_opt = maxDescLength ? 4 : 3; + size_t maxFlagAndArgLength = 0; + if (maxDescLength) { + *maxDescLength = 0; + } + for (int i = 0; i < options_len; i += items_per_opt) { + size_t flagLength = options[i] ? strlen(options[i]) : 0; + size_t argLength = options[i + 1] ? strlen(options[i + 1]) : 0; + size_t flagAndArgLength = flagLength + argLength; + if (flagAndArgLength > maxFlagAndArgLength) { + maxFlagAndArgLength = flagAndArgLength; + } + if (maxDescLength) { + size_t descLength = strlen(options[i + 2]); + if (descLength > *maxDescLength) { + *maxDescLength = descLength; + } + } + } + return maxFlagAndArgLength; +} + /** * \brief Prints a help option with the option flag and arg strings colorized, and description aligned to a column. * @@ -1463,7 +1497,7 @@ RZ_API RZ_OWN RzStrBuf *rz_print_colorize_asm_str(RZ_BORROW RzPrint *p, const Rz * \param arg Option arg, will be colored yellow. * \param desc Option description, will be aligned in the third column. * \param maxFlagAndArgLength Width of column containing \p flag and \p arg. It needs to be calculated beforehand - * as the max over all options. + * as the max over all options, perhaps via rz_print_options_get_max_len(). */ RZ_API void rz_print_colored_help_option(const char *flag, const char *arg, const char *desc, size_t maxFlagAndArgLength) { @@ -1481,10 +1515,10 @@ RZ_API void rz_print_colored_help_option(const char *flag, const char *arg, cons * \param desc Option description, will be aligned in the third column unless both \p flag and \p arg are NULL. If so, * it will be aligned at the first column. * \param maxFlagAndArgLength Width of column containing \p flag and \p arg. It needs to be calculated beforehand - * as the max over all options. + * as the max over all options, perhaps via rz_print_options_get_max_len(). * \param example Optional option example, will be aligned in a column after the description and prefixed with "; ". * \param maxDescLength Width of column containing \p desc. It needs to be calculated beforehand as the max over all - * descriptions. + * descriptions, perhaps via rz_print_options_get_max_len(). */ RZ_API void rz_print_colored_help_option_example(RZ_NULLABLE const char *flag, RZ_NULLABLE const char *arg, const char *desc, size_t maxFlagAndArgLength, RZ_NULLABLE const char *example, size_t maxDescLength) {