Add qemu 2.4.0
[kvmfornfv.git] / qemu / roms / ipxe / src / hci / commands / menu_cmd.c
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
20 FILE_LICENCE ( GPL2_OR_LATER );
21
22 /** @file
23  *
24  * Menu commands
25  *
26  */
27
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <string.h>
31 #include <errno.h>
32 #include <getopt.h>
33 #include <ipxe/menu.h>
34 #include <ipxe/command.h>
35 #include <ipxe/parseopt.h>
36 #include <ipxe/settings.h>
37 #include <ipxe/features.h>
38
39 FEATURE ( FEATURE_MISC, "Menu", DHCP_EB_FEATURE_MENU, 1 );
40
41 /** "menu" options */
42 struct menu_options {
43         /** Name */
44         char *name;
45         /** Delete */
46         int delete;
47 };
48
49 /** "menu" option list */
50 static struct option_descriptor menu_opts[] = {
51         OPTION_DESC ( "name", 'n', required_argument,
52                       struct menu_options, name, parse_string ),
53         OPTION_DESC ( "delete", 'd', no_argument,
54                       struct menu_options, delete, parse_flag ),
55 };
56
57 /** "menu" command descriptor */
58 static struct command_descriptor menu_cmd =
59         COMMAND_DESC ( struct menu_options, menu_opts, 0, MAX_ARGUMENTS,
60                        "[<title>]" );
61
62 /**
63  * The "menu" command
64  *
65  * @v argc              Argument count
66  * @v argv              Argument list
67  * @ret rc              Return status code
68  */
69 static int menu_exec ( int argc, char **argv ) {
70         struct menu_options opts;
71         struct menu *menu;
72         char *title;
73         int rc;
74
75         /* Parse options */
76         if ( ( rc = parse_options ( argc, argv, &menu_cmd, &opts ) ) != 0 )
77                 goto err_parse_options;
78
79         /* Parse title */
80         title = concat_args ( &argv[optind] );
81         if ( ! title ) {
82                 rc = -ENOMEM;
83                 goto err_parse_title;
84         }
85
86         /* Create menu */
87         menu = create_menu ( opts.name, title );
88         if ( ! menu ) {
89                 rc = -ENOMEM;
90                 goto err_create_menu;
91         }
92
93         /* Destroy menu, if applicable */
94         if ( opts.delete )
95                 destroy_menu ( menu );
96
97         /* Success */
98         rc = 0;
99
100  err_create_menu:
101         free ( title );
102  err_parse_title:
103  err_parse_options:
104         return rc;
105 }
106
107 /** "item" options */
108 struct item_options {
109         /** Menu name */
110         char *menu;
111         /** Shortcut key */
112         unsigned int key;
113         /** Use as default */
114         int is_default;
115         /** Use as a separator */
116         int is_gap;
117 };
118
119 /** "item" option list */
120 static struct option_descriptor item_opts[] = {
121         OPTION_DESC ( "menu", 'm', required_argument,
122                       struct item_options, menu, parse_string ),
123         OPTION_DESC ( "key", 'k', required_argument,
124                       struct item_options, key, parse_key ),
125         OPTION_DESC ( "default", 'd', no_argument,
126                       struct item_options, is_default, parse_flag ),
127         OPTION_DESC ( "gap", 'g', no_argument,
128                       struct item_options, is_gap, parse_flag ),
129 };
130
131 /** "item" command descriptor */
132 static struct command_descriptor item_cmd =
133         COMMAND_DESC ( struct item_options, item_opts, 0, MAX_ARGUMENTS,
134                        "[<label> [<text>]]" );
135
136 /**
137  * The "item" command
138  *
139  * @v argc              Argument count
140  * @v argv              Argument list
141  * @ret rc              Return status code
142  */
143 static int item_exec ( int argc, char **argv ) {
144         struct item_options opts;
145         struct menu *menu;
146         struct menu_item *item;
147         char *label = NULL;
148         char *text = NULL;
149         int rc;
150
151         /* Parse options */
152         if ( ( rc = parse_options ( argc, argv, &item_cmd, &opts ) ) != 0 )
153                 goto err_parse_options;
154
155         /* Parse label, if present */
156         if ( ! opts.is_gap )
157                 label = argv[optind++]; /* May be NULL */
158
159         /* Parse text, if present */
160         if ( optind < argc ) {
161                 text = concat_args ( &argv[optind] );
162                 if ( ! text ) {
163                         rc = -ENOMEM;
164                         goto err_parse_text;
165                 }
166         }
167
168         /* Identify menu */
169         if ( ( rc = parse_menu ( opts.menu, &menu ) ) != 0 )
170                 goto err_parse_menu;
171
172         /* Add menu item */
173         item = add_menu_item ( menu, label, ( text ? text : "" ),
174                                opts.key, opts.is_default );
175         if ( ! item ) {
176                 rc = -ENOMEM;
177                 goto err_add_menu_item;
178         }
179
180         /* Success */
181         rc = 0;
182
183  err_add_menu_item:
184  err_parse_menu:
185         free ( text );
186  err_parse_text:
187  err_parse_options:
188         return rc;
189 }
190
191 /** "choose" options */
192 struct choose_options {
193         /** Menu name */
194         char *menu;
195         /** Timeout */
196         unsigned long timeout;
197         /** Default selection */
198         char *select;
199         /** Keep menu */
200         int keep;
201 };
202
203 /** "choose" option list */
204 static struct option_descriptor choose_opts[] = {
205         OPTION_DESC ( "menu", 'm', required_argument,
206                       struct choose_options, menu, parse_string ),
207         OPTION_DESC ( "default", 'd', required_argument,
208                       struct choose_options, select, parse_string ),
209         OPTION_DESC ( "timeout", 't', required_argument,
210                       struct choose_options, timeout, parse_timeout ),
211         OPTION_DESC ( "keep", 'k', no_argument,
212                       struct choose_options, keep, parse_flag ),
213 };
214
215 /** "choose" command descriptor */
216 static struct command_descriptor choose_cmd =
217         COMMAND_DESC ( struct choose_options, choose_opts, 1, 1, "<setting>" );
218
219 /**
220  * The "choose" command
221  *
222  * @v argc              Argument count
223  * @v argv              Argument list
224  * @ret rc              Return status code
225  */
226 static int choose_exec ( int argc, char **argv ) {
227         struct choose_options opts;
228         struct named_setting setting;
229         struct menu *menu;
230         struct menu_item *item;
231         int rc;
232
233         /* Parse options */
234         if ( ( rc = parse_options ( argc, argv, &choose_cmd, &opts ) ) != 0 )
235                 goto err_parse_options;
236
237         /* Parse setting name */
238         if ( ( rc = parse_autovivified_setting ( argv[optind],
239                                                  &setting ) ) != 0 )
240                 goto err_parse_setting;
241
242         /* Identify menu */
243         if ( ( rc = parse_menu ( opts.menu, &menu ) ) != 0 )
244                 goto err_parse_menu;
245
246         /* Show menu */
247         if ( ( rc = show_menu ( menu, opts.timeout, opts.select, &item ) ) != 0)
248                 goto err_show_menu;
249
250         /* Apply default type if necessary */
251         if ( ! setting.setting.type )
252                 setting.setting.type = &setting_type_string;
253
254         /* Store setting */
255         if ( ( rc = storef_setting ( setting.settings, &setting.setting,
256                                      item->label ) ) != 0 ) {
257                 printf ( "Could not store \"%s\": %s\n",
258                          setting.setting.name, strerror ( rc ) );
259                 goto err_store;
260         }
261
262         /* Success */
263         rc = 0;
264
265  err_store:
266  err_show_menu:
267         /* Destroy menu, if applicable */
268         if ( ! opts.keep )
269                 destroy_menu ( menu );
270  err_parse_menu:
271  err_parse_setting:
272  err_parse_options:
273         return rc;
274 }
275
276 /** Menu commands */
277 struct command menu_commands[] __command = {
278         {
279                 .name = "menu",
280                 .exec = menu_exec,
281         },
282         {
283                 .name = "item",
284                 .exec = item_exec,
285         },
286         {
287                 .name = "choose",
288                 .exec = choose_exec,
289         },
290 };