[U-Boot] [PATCH v4 1/4] menu: Add support for user defined item choice function

Anatolij Gustschin
2013-03-24T00:50:40Z

From: Pali Roh?r <pali.rohar@gmail.com>

Selecting menu items is currently done in menu_interactive_choice()
by reading the user input strings from standard input.

Extend menu_interactive_choice() to support user defined function
for selecting menu items. This function and its argument can be
specified when creating the menu.

Signed-off-by: Pali Roh?r <pali.rohar@gmail.com>
Signed-off-by: Anatolij Gustschin <agust@denx.de>
---
Changes in v4:
- slightly rename the new item choice callback and its argument
- add documentation for added item choice callback
- search for menu item key only if the choice callback
returned a key (not NULL)
- do not change menu_display_statusline() function argument
(previous patch changed this menu API function but didn't
update documentation for this change. This change is
actually not needed, menu item data can be obtained by
exported menu_default_choice())
- revise commit log

No changes in v3

Changes in v2:
- Rebased on next

board/ait/cam_enc_4xx/cam_enc_4xx.c | 3 +-
common/cmd_pxe.c | 3 +-
common/menu.c | 42 +++++++++++++++++++++++++---------
doc/README.menu | 4 ++-
include/menu.h | 4 ++-
5 files changed, 41 insertions(+), 15 deletions(-)

diff --git a/board/ait/cam_enc_4xx/cam_enc_4xx.c b/board/ait/cam_enc_4xx/cam_enc_4xx.c
index 32b28f9..644c445 100644
--- a/board/ait/cam_enc_4xx/cam_enc_4xx.c
+++ b/board/ait/cam_enc_4xx/cam_enc_4xx.c
@@ -561,7 +561,8 @@ static char *menu_handle(struct menu_display *display)
char *s;
char temp[6][200];

- m = menu_create(display->title, display->timeout, 1, ait_menu_print);
+ m = menu_create(display->title, display->timeout, 1, ait_menu_print,
+ NULL, NULL);

for (i = 0; display->menulist[i]; i++) {
sprintf(key, "%d", i + 1);
diff --git a/common/cmd_pxe.c b/common/cmd_pxe.c
index ee75db9..2dbd49c 100644
--- a/common/cmd_pxe.c
+++ b/common/cmd_pxe.c
@@ -1280,7 +1280,8 @@ static struct menu *pxe_menu_to_menu(struct pxe_menu *cfg)
/*
* Create a menu and add items for all the labels.
*/
- m = menu_create(cfg->title, cfg->timeout, cfg->prompt, label_print);
+ m = menu_create(cfg->title, cfg->timeout, cfg->prompt, label_print,
+ NULL, NULL);

if (!m)
return NULL;
diff --git a/common/menu.c b/common/menu.c
index 6b2a2db..322b75e 100644
--- a/common/menu.c
+++ b/common/menu.c
@@ -47,6 +47,8 @@ struct menu {
char *title;
int prompt;
void (*item_data_print)(void *);
+ char *(*item_choice)(void *);
+ void *item_choice_data;
struct list_head items;
};

@@ -204,18 +206,26 @@ static inline int menu_interactive_choice(struct menu *m, void **choice)

menu_display(m);

- readret = readline_into_buffer("Enter choice: ", cbuf,
- m->timeout / 10);
+ if (!m->item_choice) {
+ readret = readline_into_buffer("Enter choice: ", cbuf,
+ m->timeout / 10);

- if (readret >= 0) {
- choice_item = menu_item_by_key(m, cbuf);
-
- if (!choice_item) {
- printf("%s not found\n", cbuf);
- m->timeout = 0;
+ if (readret >= 0) {
+ choice_item = menu_item_by_key(m, cbuf);
+ if (!choice_item)
+ printf("%s not found\n", cbuf);
+ } else {
+ return menu_default_choice(m, choice);
}
- } else
- return menu_default_choice(m, choice);
+ } else {
+ char *key = m->item_choice(m->item_choice_data);
+
+ if (key)
+ choice_item = menu_item_by_key(m, key);
+ }
+
+ if (!choice_item)
+ m->timeout = 0;
}

*choice = choice_item->data;
@@ -348,11 +358,19 @@ int menu_item_add(struct menu *m, char *item_key, void *item_data)
* what must be entered to select an item, the item_data_print function should
* make it obvious what the key for each entry is.
*
+ * item_choice - If not NULL, will be called when asking the user to choose an
+ * item. Returns a key string corresponding to the choosen item or NULL if
+ * no item has been selected.
+ *
+ * item_choice_data - Will be passed as the argument to the item_choice function
+ *
* Returns a pointer to the menu if successful, or NULL if there is
* insufficient memory available to create the menu.
*/
struct menu *menu_create(char *title, int timeout, int prompt,
- void (*item_data_print)(void *))
+ void (*item_data_print)(void *),
+ char *(*item_choice)(void *),
+ void *item_choice_data)
{
struct menu *m;

@@ -365,6 +383,8 @@ struct menu *menu_create(char *title, int timeout, int prompt,
m->prompt = prompt;
m->timeout = timeout;
m->item_data_print = item_data_print;
+ m->item_choice = item_choice;
+ m->item_choice_data = item_choice_data;

if (title) {
m->title = strdup(title);
diff --git a/doc/README.menu b/doc/README.menu
index 6ce6bba..c949398 100644
--- a/doc/README.menu
+++ b/doc/README.menu
@@ -51,7 +51,9 @@ struct menu;
* menu_create() - Creates a menu handle with default settings
*/
struct menu *menu_create(char *title, int timeout, int prompt,
- void (*item_data_print)(void *));
+ void (*item_data_print)(void *),
+ char *(*item_choice)(void *),
+ void *item_choice_data);

/*
* menu_item_add() - Adds or replaces a menu item
diff --git a/include/menu.h b/include/menu.h
index 7af5fdb..f4dd5af 100644
--- a/include/menu.h
+++ b/include/menu.h
@@ -21,7 +21,9 @@
struct menu;

struct menu *menu_create(char *title, int timeout, int prompt,
- void (*item_data_print)(void *));
+ void (*item_data_print)(void *),
+ char *(*item_choice)(void *),
+ void *item_choice_data);
int menu_default_set(struct menu *m, char *item_key);
int menu_get_choice(struct menu *m, void **choice);
int menu_item_add(struct menu *m, char *item_key, void *item_data);
--
1.7.5.4