commit: 4ea745c4b0b681457301cd5b7543775fe4c6beef Author: Mike Pagano <mpagano <AT> gentoo <DOT> org> AuthorDate: Fri Feb 14 12:09:18 2025 +0000 Commit: Mike Pagano <mpagano <AT> gentoo <DOT> org> CommitDate: Fri Feb 14 12:09:18 2025 +0000 URL: https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=4ea745c4
menuconfig: Allow sorting the entries alphabetically Signed-off-by: Mike Pagano <mpagano <AT> gentoo.org> 0000_README | 4 + 2901_permit-menuconfig-sorting.patch | 219 +++++++++++++++++++++++++++++++++++ 2 files changed, 223 insertions(+) diff --git a/0000_README b/0000_README index a507da31..65a7cda3 100644 --- a/0000_README +++ b/0000_README @@ -71,6 +71,10 @@ Patch: 2000_BT-Check-key-sizes-only-if-Secure-Simple-Pairing-enabled.patch From: https://lore.kernel.org/linux-bluetooth/[email protected]/raw Desc: Bluetooth: Check key sizes only when Secure Simple Pairing is enabled. See bug #686758 +Patch: 2901_permit-menuconfig-sorting.patch +From: https://lore.kernel.org/ +Desc: menuconfig: Allow sorting the entries alphabetically + Patch: 2910_bfp-mark-get-entry-ip-as--maybe-unused.patch From: https://www.spinics.net/lists/stable/msg604665.html Desc: bpf: mark get_entry_ip as __maybe_unused diff --git a/2901_permit-menuconfig-sorting.patch b/2901_permit-menuconfig-sorting.patch new file mode 100644 index 00000000..1ceade0c --- /dev/null +++ b/2901_permit-menuconfig-sorting.patch @@ -0,0 +1,219 @@ +From git@z Thu Jan 1 00:00:00 1970 +Subject: [PATCH] menuconfig: Allow sorting the entries alphabetically +From: Ivan Orlov <[email protected]> +Date: Fri, 16 Aug 2024 15:18:31 +0100 +Message-Id: <[email protected]> +MIME-Version: 1.0 +Content-Type: text/plain; charset="utf-8" +Content-Transfer-Encoding: 7bit + +Implement the functionality which allows to sort the Kconfig entries +alphabetically if user decides to. It may help finding the desired entry +faster, so the user will spend less time looking through the list. + +The sorting is done on the dialog_list elements in the 'dialog_menu' +function, so on the option "representation" layer. The sorting could be +enabled/disabled by pressing the '>' key. The labels are sorted in the +following way: + +1. Put all entries into the array (from the linked list) +2. Sort them alphabetically using qsort and custom comparator +3. Restore the items linked list structure + +I know that this modification includes the ugly heruistics for +extracting the actual label text from " [ ] Some-option"-like +expressions (to be able to alphabetically compare the labels), and I +would be happy to discuss alternative solutions. + +Signed-off-by: Ivan Orlov <[email protected]> +--- + scripts/kconfig/lxdialog/dialog.h | 5 +- + scripts/kconfig/lxdialog/menubox.c | 7 ++- + scripts/kconfig/lxdialog/util.c | 79 ++++++++++++++++++++++++++++++ + scripts/kconfig/mconf.c | 9 +++- + 4 files changed, 97 insertions(+), 3 deletions(-) + +diff --git a/scripts/kconfig/lxdialog/dialog.h b/scripts/kconfig/lxdialog/dialog.h +index f6c2ebe6d1f9..a036ed8cb43c 100644 +--- a/scripts/kconfig/lxdialog/dialog.h ++++ b/scripts/kconfig/lxdialog/dialog.h +@@ -58,6 +58,8 @@ + #define ACS_DARROW 'v' + #endif + ++#define KEY_ACTION_SORT 11 ++ + /* error return codes */ + #define ERRDISPLAYTOOSMALL (KEY_MAX + 1) + +@@ -127,6 +129,7 @@ void item_set_selected(int val); + int item_activate_selected(void); + void *item_data(void); + char item_tag(void); ++void sort_items(void); + + /* item list manipulation for lxdialog use */ + #define MAXITEMSTR 200 +@@ -196,7 +199,7 @@ int dialog_textbox(const char *title, const char *tbuf, int initial_height, + int initial_width, int *_vscroll, int *_hscroll, + int (*extra_key_cb)(int, size_t, size_t, void *), void *data); + int dialog_menu(const char *title, const char *prompt, +- const void *selected, int *s_scroll); ++ const void *selected, int *s_scroll, bool sort); + int dialog_checklist(const char *title, const char *prompt, int height, + int width, int list_height); + int dialog_inputbox(const char *title, const char *prompt, int height, +diff --git a/scripts/kconfig/lxdialog/menubox.c b/scripts/kconfig/lxdialog/menubox.c +index 6e6244df0c56..4cba15f967c5 100644 +--- a/scripts/kconfig/lxdialog/menubox.c ++++ b/scripts/kconfig/lxdialog/menubox.c +@@ -161,7 +161,7 @@ static void do_scroll(WINDOW *win, int *scroll, int n) + * Display a menu for choosing among a number of options + */ + int dialog_menu(const char *title, const char *prompt, +- const void *selected, int *s_scroll) ++ const void *selected, int *s_scroll, bool sort) + { + int i, j, x, y, box_x, box_y; + int height, width, menu_height; +@@ -181,6 +181,9 @@ int dialog_menu(const char *title, const char *prompt, + + max_choice = MIN(menu_height, item_count()); + ++ if (sort) ++ sort_items(); ++ + /* center dialog box on screen */ + x = (getmaxx(stdscr) - width) / 2; + y = (getmaxy(stdscr) - height) / 2; +@@ -408,6 +411,8 @@ int dialog_menu(const char *title, const char *prompt, + delwin(menu); + delwin(dialog); + goto do_resize; ++ case '>': ++ return KEY_ACTION_SORT; + } + } + delwin(menu); +diff --git a/scripts/kconfig/lxdialog/util.c b/scripts/kconfig/lxdialog/util.c +index 964139c87fcb..cc87ddd69c10 100644 +--- a/scripts/kconfig/lxdialog/util.c ++++ b/scripts/kconfig/lxdialog/util.c +@@ -563,6 +563,85 @@ void item_reset(void) + item_cur = &item_nil; + } + ++/* ++ * Function skips a part of the label to get the actual label text ++ * (without the '[ ]'-like prefix). ++ */ ++static char *skip_spec_characters(char *s) ++{ ++ bool unbalanced = false; ++ ++ while (*s) { ++ if (isalnum(*s) && !unbalanced) { ++ break; ++ } else if (*s == '[' || *s == '<' || *s == '(') { ++ /* ++ * '[', '<' or '(' means that we need to look for ++ * closure ++ */ ++ unbalanced = true; ++ } else if (*s == '-') { ++ /* ++ * Labels could start with "-*-", so '-' here either ++ * opens or closes the "checkbox" ++ */ ++ unbalanced = !unbalanced; ++ } else if (*s == '>' || *s == ']' || *s == ')') { ++ unbalanced = false; ++ } ++ s++; ++ } ++ return s; ++} ++ ++static int compare_labels(const void *a, const void *b) ++{ ++ struct dialog_list *el1 = *((struct dialog_list **)a); ++ struct dialog_list *el2 = *((struct dialog_list **)b); ++ ++ return strcasecmp(skip_spec_characters(el1->node.str), ++ skip_spec_characters(el2->node.str)); ++} ++ ++void sort_items(void) ++{ ++ struct dialog_list **arr; ++ struct dialog_list *cur; ++ size_t n, i; ++ ++ n = item_count(); ++ if (n == 0) ++ return; ++ ++ /* Copy all items from linked list into array */ ++ cur = item_head; ++ arr = malloc(sizeof(*arr) * n); ++ ++ if (!arr) { ++ /* Don't have enough memory, so don't do anything */ ++ return; ++ } ++ ++ for (i = 0; i < n; i++) { ++ arr[i] = cur; ++ cur = cur->next; ++ } ++ ++ qsort(arr, n, sizeof(struct dialog_list *), compare_labels); ++ ++ /* Restore the linked list structure from the sorted array */ ++ for (i = 0; i < n; i++) { ++ if (i < n - 1) ++ arr[i]->next = arr[i + 1]; ++ else ++ arr[i]->next = NULL; ++ } ++ ++ item_head = arr[0]; ++ ++ free(arr); ++} ++ + void item_make(const char *fmt, ...) + { + va_list ap; +diff --git a/scripts/kconfig/mconf.c b/scripts/kconfig/mconf.c +index 3887eac75289..8a961a41cae4 100644 +--- a/scripts/kconfig/mconf.c ++++ b/scripts/kconfig/mconf.c +@@ -749,6 +749,7 @@ static void conf_save(void) + } + } + ++static bool should_sort; + static void conf(struct menu *menu, struct menu *active_menu) + { + struct menu *submenu; +@@ -774,9 +775,15 @@ static void conf(struct menu *menu, struct menu *active_menu) + dialog_clear(); + res = dialog_menu(prompt ? prompt : "Main Menu", + menu_instructions, +- active_menu, &s_scroll); ++ active_menu, &s_scroll, should_sort); + if (res == 1 || res == KEY_ESC || res == -ERRDISPLAYTOOSMALL) + break; ++ ++ if (res == KEY_ACTION_SORT) { ++ should_sort = !should_sort; ++ continue; ++ } ++ + if (item_count() != 0) { + if (!item_activate_selected()) + continue; +-- +2.34.1 +
