iPXE
menu.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2012 Michael Brown <mbrown@fensystems.co.uk>.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License as
6  * published by the Free Software Foundation; either version 2 of the
7  * License, or any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17  * 02110-1301, USA.
18  *
19  * You can also choose to distribute this program under the terms of
20  * the Unmodified Binary Distribution Licence (as given in the file
21  * COPYING.UBDL), provided that you have satisfied its requirements.
22  */
23 
24 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
25 
26 /** @file
27  *
28  * Menu selection
29  *
30  */
31 
32 #include <stdlib.h>
33 #include <string.h>
34 #include <assert.h>
35 #include <ipxe/list.h>
36 #include <ipxe/menu.h>
37 
38 /** List of all menus */
39 static LIST_HEAD ( menus );
40 
41 /**
42  * Create menu
43  *
44  * @v name Menu name, or NULL
45  * @v title Menu title, or NULL
46  * @ret menu Menu, or NULL on failure
47  */
48 struct menu * create_menu ( const char *name, const char *title ) {
49  size_t name_len;
50  size_t title_len;
51  size_t len;
52  struct menu *menu;
53  char *name_copy;
54  char *title_copy;
55 
56  /* Destroy any existing menu of this name */
57  menu = find_menu ( name );
58  if ( menu )
59  destroy_menu ( menu );
60 
61  /* Use empty title if none given */
62  if ( ! title )
63  title = "";
64 
65  /* Allocate menu */
66  name_len = ( name ? ( strlen ( name ) + 1 /* NUL */ ) : 0 );
67  title_len = ( strlen ( title ) + 1 /* NUL */ );
68  len = ( sizeof ( *menu ) + name_len + title_len );
69  menu = zalloc ( len );
70  if ( ! menu )
71  return NULL;
72  name_copy = ( ( void * ) ( menu + 1 ) );
73  title_copy = ( name_copy + name_len );
74 
75  /* Initialise menu */
76  if ( name ) {
77  strcpy ( name_copy, name );
78  menu->name = name_copy;
79  }
80  strcpy ( title_copy, title );
81  menu->title = title_copy;
83 
84  /* Add to list of menus */
85  list_add_tail ( &menu->list, &menus );
86 
87  DBGC ( menu, "MENU %s created with title \"%s\"\n",
88  menu->name, menu->title );
89 
90  return menu;
91 }
92 
93 /**
94  * Add menu item
95  *
96  * @v menu Menu
97  * @v label Label, or NULL
98  * @v text Text, or NULL
99  * @v shortcut Shortcut key
100  * @v is_default Item is the default item
101  * @ret item Menu item, or NULL on failure
102  */
103 struct menu_item * add_menu_item ( struct menu *menu, const char *label,
104  const char *text, int shortcut,
105  int is_default ) {
106  size_t label_len;
107  size_t text_len;
108  size_t len;
109  struct menu_item *item;
110  char *label_copy;
111  char *text_copy;
112 
113  /* Use empty text if none given */
114  if ( ! text )
115  text = "";
116 
117  /* Allocate item */
118  label_len = ( label ? ( strlen ( label ) + 1 /* NUL */ ) : 0 );
119  text_len = ( strlen ( text ) + 1 /* NUL */ );
120  len = ( sizeof ( *item ) + label_len + text_len );
121  item = zalloc ( len );
122  if ( ! item )
123  return NULL;
124  label_copy = ( ( void * ) ( item + 1 ) );
125  text_copy = ( label_copy + label_len );
126 
127  /* Initialise item */
128  if ( label ) {
129  strcpy ( label_copy, label );
130  item->label = label_copy;
131  }
132  strcpy ( text_copy, text );
133  item->text = text_copy;
134  item->shortcut = shortcut;
135  item->is_default = is_default;
136 
137  /* Add to list of items */
138  list_add_tail ( &item->list, &menu->items );
139 
140  return item;
141 }
142 
143 /**
144  * Destroy menu
145  *
146  * @v menu Menu
147  */
148 void destroy_menu ( struct menu *menu ) {
149  struct menu_item *item;
150  struct menu_item *tmp;
151 
152  /* Remove from list of menus */
153  list_del ( &menu->list );
154 
155  /* Free items */
156  list_for_each_entry_safe ( item, tmp, &menu->items, list ) {
157  list_del ( &item->list );
158  free ( item );
159  }
160 
161  /* Free menu */
162  free ( menu );
163 }
164 
165 /**
166  * Find menu
167  *
168  * @v name Menu name, or NULL
169  * @ret menu Menu, or NULL if not found
170  */
171 struct menu * find_menu ( const char *name ) {
172  struct menu *menu;
173 
174  list_for_each_entry ( menu, &menus, list ) {
175  if ( ( menu->name == name ) ||
176  ( strcmp ( menu->name, name ) == 0 ) ) {
177  return menu;
178  }
179  }
180 
181  return NULL;
182 }
A menu item.
Definition: menu.h:27
const char * name
Definition: ath9k_hw.c:1984
struct list_head list
List of menus.
Definition: menu.h:17
const char * label
Label.
Definition: menu.h:31
#define DBGC(...)
Definition: compiler.h:505
struct list_head items
Menu items.
Definition: menu.h:23
unsigned long tmp
Definition: linux_pci.h:53
#define list_del(list)
Delete an entry from a list.
Definition: list.h:119
struct list_head list
List of menu items.
Definition: menu.h:29
Assertions.
#define list_for_each_entry(pos, head, member)
Iterate over entries in a list.
Definition: list.h:431
#define list_add_tail(new, head)
Add a new entry to the tail of a list.
Definition: list.h:93
char * strcpy(char *dest, const char *src)
Copy string.
Definition: string.c:326
#define list_for_each_entry_safe(pos, tmp, head, member)
Iterate over entries in a list, safe against deletion of the current entry.
Definition: list.h:458
const char * name
Name.
Definition: menu.h:19
Linked lists.
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54
void * zalloc(size_t size)
Allocate cleared memory.
Definition: malloc.c:624
const char * title
Title.
Definition: menu.h:21
size_t strlen(const char *src)
Get length of string.
Definition: string.c:243
const char * text
Text.
Definition: menu.h:33
#define INIT_LIST_HEAD(list)
Initialise a list head.
Definition: list.h:45
uint32_t len
Length.
Definition: ena.h:14
int strcmp(const char *first, const char *second)
Compare strings.
Definition: string.c:173
int is_default
Is default item.
Definition: menu.h:37
A menu.
Definition: menu.h:15
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
String functions.
int shortcut
Shortcut key.
Definition: menu.h:35