This will be used first by the pxe code, but is intended to be
generic and reusable for other jobs in U-boot.
Signed-off-by: Jason Hobbs jason.ho...@calxeda.com
---
changes in v2:
- new in v2
changes in v3:
- move timeout support to later patch
- fix NULL case bug in menu_item_key_match
- consistently use 'item_key' instead of 'key'
- move default/prompt logic into menu code
- consistently return int for error propagation
- change option setting functions to menu_create parameters
- add README.menu
changes in v4:
- change pxecfg to pxe in commit log
- improve the menu documentation
changes in v5:
- none
common/Makefile |1 +
common/menu.c | 393 +++
doc/README.menu | 119 +
include/menu.h | 30
4 files changed, 543 insertions(+), 0 deletions(-)
create mode 100644 common/menu.c
create mode 100644 doc/README.menu
create mode 100644 include/menu.h
diff --git a/common/Makefile b/common/Makefile
index d662468..ebe45b8 100644
--- a/common/Makefile
+++ b/common/Makefile
@@ -169,6 +169,7 @@ COBJS-$(CONFIG_CMD_KGDB) += kgdb.o kgdb_stubs.o
COBJS-$(CONFIG_KALLSYMS) += kallsyms.o
COBJS-$(CONFIG_LCD) += lcd.o
COBJS-$(CONFIG_LYNXKDI) += lynxkdi.o
+COBJS-$(CONFIG_MENU) += menu.o
COBJS-$(CONFIG_MODEM_SUPPORT) += modem.o
COBJS-$(CONFIG_UPDATE_TFTP) += update.o
COBJS-$(CONFIG_USB_KEYBOARD) += usb_kbd.o
diff --git a/common/menu.c b/common/menu.c
new file mode 100644
index 000..5643937
--- /dev/null
+++ b/common/menu.c
@@ -0,0 +1,393 @@
+/*
+ * Copyright 2010-2011 Calxeda, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see http://www.gnu.org/licenses/.
+ */
+
+#include common.h
+#include malloc.h
+#include errno.h
+#include linux/list.h
+
+#include menu.h
+
+/*
+ * Internally, each item in a menu is represented by a struct menu_item.
+ *
+ * These items will be alloc'd and initialized by menu_item_add and destroyed
+ * by menu_item_destroy, and the consumer of the interface never sees that
+ * this struct is used at all.
+ */
+struct menu_item {
+ char *key;
+ void *data;
+ struct list_head list;
+};
+
+/*
+ * The menu is composed of a list of items along with settings and callbacks
+ * provided by the user. An incomplete definition of this struct is available
+ * in menu.h, but the full definition is here to prevent consumers from
+ * relying on its contents.
+ */
+struct menu {
+ struct menu_item *default_item;
+ char *title;
+ int prompt;
+ void (*item_data_print)(void *);
+ struct list_head items;
+};
+
+/*
+ * An iterator function for menu items. callback will be called for each item
+ * in m, with m, a pointer to the item, and extra being passed to callback. If
+ * callback returns a value other than NULL, iteration stops and the value
+ * return by callback is returned from menu_items_iter. This allows it to be
+ * used for search type operations. It is also safe for callback to remove the
+ * item from the list of items.
+ */
+static inline void *menu_items_iter(struct menu *m,
+ void *(*callback)(struct menu *, struct menu_item *, void *),
+ void *extra)
+{
+ struct list_head *pos, *n;
+ struct menu_item *item;
+ void *ret;
+
+ list_for_each_safe(pos, n, m-items) {
+ item = list_entry(pos, struct menu_item, list);
+
+ ret = callback(m, item, extra);
+
+ if (ret)
+ return ret;
+ }
+
+ return NULL;
+}
+
+/*
+ * Print a menu_item. If the consumer provided an item_data_print function
+ * when creating the menu, call it with a pointer to the item's private data.
+ * Otherwise, print the key of the item.
+ */
+static inline void *menu_item_print(struct menu *m,
+ struct menu_item *item,
+ void *extra)
+{
+ if (!m-item_data_print)
+ printf(%s\n, item-key);
+ else
+ m-item_data_print(item-data);
+
+ return NULL;
+}
+
+/*
+ * Free the memory used by a menu item. This includes the memory used by its
+ * key.
+ */
+static inline void *menu_item_destroy(struct menu *m,
+ struct menu_item *item,
+ void *extra)
+{
+ if (item-key)
+ free(item-key);
+
+ free(item);
+
+ return NULL;
+}