Support 'help' as a synonym for '?' in command line options
For command line options which permit '?' meaning 'please list the permitted values', add support for 'help' as a synonym, by abstracting the check out into a helper function. This change means that in some cases where we were being lazy in our string parsing, "?junk" will now be rejected as an invalid option rather than being (undocumentedly) treated the same way as "?". Update the documentation to use 'help' rather than '?', since '?' is a shell metacharacter and thus prone to fail confusingly if there is a single character filename in the current working directory and the '?' has not been escaped. It's therefore better to steer users towards 'help', though '?' is retained for backwards compatibility. We do not, however, update the output of the system emulator's -help (or any documentation autogenerated from the qemu-options.hx which is the source of the -help text) because libvirt parses our -help output and will break. At a later date when QEMU provides a better interface so libvirt can avoid having to do this, we can update the -help text too. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
This commit is contained in:
parent
02d2bd5d57
commit
c8057f951d
@ -680,7 +680,7 @@ void select_soundhw(const char *optarg)
|
|||||||
{
|
{
|
||||||
struct soundhw *c;
|
struct soundhw *c;
|
||||||
|
|
||||||
if (*optarg == '?') {
|
if (is_help_option(optarg)) {
|
||||||
show_valid_cards:
|
show_valid_cards:
|
||||||
|
|
||||||
printf("Valid sound card names (comma separated):\n");
|
printf("Valid sound card names (comma separated):\n");
|
||||||
@ -688,7 +688,7 @@ void select_soundhw(const char *optarg)
|
|||||||
printf ("%-11s %s\n", c->name, c->descr);
|
printf ("%-11s %s\n", c->name, c->descr);
|
||||||
}
|
}
|
||||||
printf("\n-soundhw all will enable all of the above\n");
|
printf("\n-soundhw all will enable all of the above\n");
|
||||||
exit(*optarg != '?');
|
exit(!is_help_option(optarg));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
size_t l;
|
size_t l;
|
||||||
|
10
blockdev.c
10
blockdev.c
@ -398,11 +398,11 @@ DriveInfo *drive_init(QemuOpts *opts, int default_to_scsi)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
if ((buf = qemu_opt_get(opts, "format")) != NULL) {
|
if ((buf = qemu_opt_get(opts, "format")) != NULL) {
|
||||||
if (strcmp(buf, "?") == 0) {
|
if (is_help_option(buf)) {
|
||||||
error_printf("Supported formats:");
|
error_printf("Supported formats:");
|
||||||
bdrv_iterate_format(bdrv_format_print, NULL);
|
bdrv_iterate_format(bdrv_format_print, NULL);
|
||||||
error_printf("\n");
|
error_printf("\n");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
drv = bdrv_find_whitelisted_format(buf);
|
drv = bdrv_find_whitelisted_format(buf);
|
||||||
if (!drv) {
|
if (!drv) {
|
||||||
|
@ -681,7 +681,7 @@ static void usage(void)
|
|||||||
"-g port wait gdb connection to port\n"
|
"-g port wait gdb connection to port\n"
|
||||||
"-L path set the elf interpreter prefix (default=%s)\n"
|
"-L path set the elf interpreter prefix (default=%s)\n"
|
||||||
"-s size set the stack size in bytes (default=%ld)\n"
|
"-s size set the stack size in bytes (default=%ld)\n"
|
||||||
"-cpu model select CPU (-cpu ? for list)\n"
|
"-cpu model select CPU (-cpu help for list)\n"
|
||||||
"-drop-ld-preload drop LD_PRELOAD for target process\n"
|
"-drop-ld-preload drop LD_PRELOAD for target process\n"
|
||||||
"-E var=value sets/modifies targets environment variable(s)\n"
|
"-E var=value sets/modifies targets environment variable(s)\n"
|
||||||
"-U var unsets targets environment variable(s)\n"
|
"-U var unsets targets environment variable(s)\n"
|
||||||
@ -825,7 +825,7 @@ int main(int argc, char **argv)
|
|||||||
qemu_uname_release = argv[optind++];
|
qemu_uname_release = argv[optind++];
|
||||||
} else if (!strcmp(r, "cpu")) {
|
} else if (!strcmp(r, "cpu")) {
|
||||||
cpu_model = argv[optind++];
|
cpu_model = argv[optind++];
|
||||||
if (strcmp(cpu_model, "?") == 0) {
|
if (is_help_option(cpu_model)) {
|
||||||
/* XXX: implement xxx_cpu_list for targets that still miss it */
|
/* XXX: implement xxx_cpu_list for targets that still miss it */
|
||||||
#if defined(cpu_list)
|
#if defined(cpu_list)
|
||||||
cpu_list(stdout, &fprintf);
|
cpu_list(stdout, &fprintf);
|
||||||
|
@ -239,7 +239,7 @@ static void mips_jazz_init(MemoryRegion *address_space,
|
|||||||
dp83932_init(nd, 0x80001000, 2, get_system_memory(), rc4030[4],
|
dp83932_init(nd, 0x80001000, 2, get_system_memory(), rc4030[4],
|
||||||
rc4030_opaque, rc4030_dma_memory_rw);
|
rc4030_opaque, rc4030_dma_memory_rw);
|
||||||
break;
|
break;
|
||||||
} else if (strcmp(nd->model, "?") == 0) {
|
} else if (is_help_option(nd->model)) {
|
||||||
fprintf(stderr, "qemu: Supported NICs: dp83932\n");
|
fprintf(stderr, "qemu: Supported NICs: dp83932\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
} else {
|
} else {
|
||||||
|
@ -138,13 +138,13 @@ int qdev_device_help(QemuOpts *opts)
|
|||||||
ObjectClass *klass;
|
ObjectClass *klass;
|
||||||
|
|
||||||
driver = qemu_opt_get(opts, "driver");
|
driver = qemu_opt_get(opts, "driver");
|
||||||
if (driver && !strcmp(driver, "?")) {
|
if (driver && is_help_option(driver)) {
|
||||||
bool show_no_user = false;
|
bool show_no_user = false;
|
||||||
object_class_foreach(qdev_print_devinfo, TYPE_DEVICE, false, &show_no_user);
|
object_class_foreach(qdev_print_devinfo, TYPE_DEVICE, false, &show_no_user);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!driver || !qemu_opt_get(opts, "?")) {
|
if (!driver || !qemu_opt_has_help_opt(opts)) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -55,7 +55,7 @@ int select_watchdog(const char *p)
|
|||||||
QemuOpts *opts;
|
QemuOpts *opts;
|
||||||
|
|
||||||
/* -watchdog ? lists available devices and exits cleanly. */
|
/* -watchdog ? lists available devices and exits cleanly. */
|
||||||
if (strcmp(p, "?") == 0) {
|
if (is_help_option(p)) {
|
||||||
QLIST_FOREACH(model, &watchdog_list, entry) {
|
QLIST_FOREACH(model, &watchdog_list, entry) {
|
||||||
fprintf(stderr, "\t%s\t%s\n",
|
fprintf(stderr, "\t%s\t%s\n",
|
||||||
model->wdt_name, model->wdt_description);
|
model->wdt_name, model->wdt_description);
|
||||||
|
@ -3140,7 +3140,7 @@ static void handle_arg_uname(const char *arg)
|
|||||||
static void handle_arg_cpu(const char *arg)
|
static void handle_arg_cpu(const char *arg)
|
||||||
{
|
{
|
||||||
cpu_model = strdup(arg);
|
cpu_model = strdup(arg);
|
||||||
if (cpu_model == NULL || strcmp(cpu_model, "?") == 0) {
|
if (cpu_model == NULL || is_help_option(cpu_model)) {
|
||||||
/* XXX: implement xxx_cpu_list for targets that still miss it */
|
/* XXX: implement xxx_cpu_list for targets that still miss it */
|
||||||
#if defined(cpu_list_id)
|
#if defined(cpu_list_id)
|
||||||
cpu_list_id(stdout, &fprintf, "");
|
cpu_list_id(stdout, &fprintf, "");
|
||||||
@ -3231,7 +3231,7 @@ struct qemu_argument arg_table[] = {
|
|||||||
{"s", "QEMU_STACK_SIZE", true, handle_arg_stack_size,
|
{"s", "QEMU_STACK_SIZE", true, handle_arg_stack_size,
|
||||||
"size", "set the stack size to 'size' bytes"},
|
"size", "set the stack size to 'size' bytes"},
|
||||||
{"cpu", "QEMU_CPU", true, handle_arg_cpu,
|
{"cpu", "QEMU_CPU", true, handle_arg_cpu,
|
||||||
"model", "select CPU (-cpu ? for list)"},
|
"model", "select CPU (-cpu help for list)"},
|
||||||
{"E", "QEMU_SET_ENV", true, handle_arg_set_env,
|
{"E", "QEMU_SET_ENV", true, handle_arg_set_env,
|
||||||
"var=value", "sets targets environment variable (see below)"},
|
"var=value", "sets targets environment variable (see below)"},
|
||||||
{"U", "QEMU_UNSET_ENV", true, handle_arg_unset_env,
|
{"U", "QEMU_UNSET_ENV", true, handle_arg_unset_env,
|
||||||
|
3
net.c
3
net.c
@ -691,8 +691,9 @@ int qemu_show_nic_models(const char *arg, const char *const *models)
|
|||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (!arg || strcmp(arg, "?"))
|
if (!arg || !is_help_option(arg)) {
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
fprintf(stderr, "qemu: Supported NIC models: ");
|
fprintf(stderr, "qemu: Supported NIC models: ");
|
||||||
for (i = 0 ; models[i]; i++)
|
for (i = 0 ; models[i]; i++)
|
||||||
|
@ -136,6 +136,24 @@ int qemu_main(int argc, char **argv, char **envp);
|
|||||||
void qemu_get_timedate(struct tm *tm, int offset);
|
void qemu_get_timedate(struct tm *tm, int offset);
|
||||||
int qemu_timedate_diff(struct tm *tm);
|
int qemu_timedate_diff(struct tm *tm);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* is_help_option:
|
||||||
|
* @s: string to test
|
||||||
|
*
|
||||||
|
* Check whether @s is one of the standard strings which indicate
|
||||||
|
* that the user is asking for a list of the valid values for a
|
||||||
|
* command option like -cpu or -M. The current accepted strings
|
||||||
|
* are 'help' and '?'. '?' is deprecated (it is a shell wildcard
|
||||||
|
* which makes it annoying to use in a reliable way) but provided
|
||||||
|
* for backwards compatibility.
|
||||||
|
*
|
||||||
|
* Returns: true if @s is a request for a list.
|
||||||
|
*/
|
||||||
|
static inline bool is_help_option(const char *s)
|
||||||
|
{
|
||||||
|
return !strcmp(s, "?") || !strcmp(s, "help");
|
||||||
|
}
|
||||||
|
|
||||||
/* cutils.c */
|
/* cutils.c */
|
||||||
void pstrcpy(char *buf, int buf_size, const char *str);
|
void pstrcpy(char *buf, int buf_size, const char *str);
|
||||||
void strpadcpy(char *buf, int buf_size, const char *str, char pad);
|
void strpadcpy(char *buf, int buf_size, const char *str, char pad);
|
||||||
|
@ -2390,7 +2390,7 @@ Set the x86 elf interpreter prefix (default=/usr/local/qemu-i386)
|
|||||||
@item -s size
|
@item -s size
|
||||||
Set the x86 stack size in bytes (default=524288)
|
Set the x86 stack size in bytes (default=524288)
|
||||||
@item -cpu model
|
@item -cpu model
|
||||||
Select CPU model (-cpu ? for list and additional feature selection)
|
Select CPU model (-cpu help for list and additional feature selection)
|
||||||
@item -ignore-environment
|
@item -ignore-environment
|
||||||
Start with an empty environment. Without this option,
|
Start with an empty environment. Without this option,
|
||||||
the initial environment is a copy of the caller's environment.
|
the initial environment is a copy of the caller's environment.
|
||||||
|
@ -736,7 +736,7 @@ int main(int argc, char **argv)
|
|||||||
break;
|
break;
|
||||||
case 'b': {
|
case 'b': {
|
||||||
char **list_head, **list;
|
char **list_head, **list;
|
||||||
if (*optarg == '?') {
|
if (is_help_option(optarg)) {
|
||||||
list_head = list = qmp_get_command_list();
|
list_head = list = qmp_get_command_list();
|
||||||
while (*list != NULL) {
|
while (*list != NULL) {
|
||||||
printf("%s\n", *list);
|
printf("%s\n", *list);
|
||||||
|
@ -350,7 +350,7 @@ static int img_create(int argc, char **argv)
|
|||||||
img_size = (uint64_t)sval;
|
img_size = (uint64_t)sval;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (options && !strcmp(options, "?")) {
|
if (options && is_help_option(options)) {
|
||||||
ret = print_block_option_help(filename, fmt);
|
ret = print_block_option_help(filename, fmt);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
@ -744,7 +744,7 @@ static int img_convert(int argc, char **argv)
|
|||||||
/* Initialize before goto out */
|
/* Initialize before goto out */
|
||||||
qemu_progress_init(progress, 2.0);
|
qemu_progress_init(progress, 2.0);
|
||||||
|
|
||||||
if (options && !strcmp(options, "?")) {
|
if (options && is_help_option(options)) {
|
||||||
ret = print_block_option_help(out_filename, out_fmt);
|
ret = print_block_option_help(out_filename, out_fmt);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
@ -529,6 +529,18 @@ const char *qemu_opt_get(QemuOpts *opts, const char *name)
|
|||||||
return opt ? opt->str : NULL;
|
return opt ? opt->str : NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool qemu_opt_has_help_opt(QemuOpts *opts)
|
||||||
|
{
|
||||||
|
QemuOpt *opt;
|
||||||
|
|
||||||
|
QTAILQ_FOREACH_REVERSE(opt, &opts->head, QemuOptHead, next) {
|
||||||
|
if (is_help_option(opt->name)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool qemu_opt_get_bool(QemuOpts *opts, const char *name, bool defval)
|
bool qemu_opt_get_bool(QemuOpts *opts, const char *name, bool defval)
|
||||||
{
|
{
|
||||||
QemuOpt *opt = qemu_opt_find(opts, name);
|
QemuOpt *opt = qemu_opt_find(opts, name);
|
||||||
|
@ -107,6 +107,18 @@ struct QemuOptsList {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const char *qemu_opt_get(QemuOpts *opts, const char *name);
|
const char *qemu_opt_get(QemuOpts *opts, const char *name);
|
||||||
|
/**
|
||||||
|
* qemu_opt_has_help_opt:
|
||||||
|
* @opts: options to search for a help request
|
||||||
|
*
|
||||||
|
* Check whether the options specified by @opts include one of the
|
||||||
|
* standard strings which indicate that the user is asking for a
|
||||||
|
* list of the valid values for a command line option (as defined
|
||||||
|
* by is_help_option()).
|
||||||
|
*
|
||||||
|
* Returns: true if @opts includes 'help' or equivalent.
|
||||||
|
*/
|
||||||
|
bool qemu_opt_has_help_opt(QemuOpts *opts);
|
||||||
bool qemu_opt_get_bool(QemuOpts *opts, const char *name, bool defval);
|
bool qemu_opt_get_bool(QemuOpts *opts, const char *name, bool defval);
|
||||||
uint64_t qemu_opt_get_number(QemuOpts *opts, const char *name, uint64_t defval);
|
uint64_t qemu_opt_get_number(QemuOpts *opts, const char *name, uint64_t defval);
|
||||||
uint64_t qemu_opt_get_size(QemuOpts *opts, const char *name, uint64_t defval);
|
uint64_t qemu_opt_get_size(QemuOpts *opts, const char *name, uint64_t defval);
|
||||||
|
@ -6,6 +6,10 @@ HXCOMM construct option structures, enums and help message for specified
|
|||||||
HXCOMM architectures.
|
HXCOMM architectures.
|
||||||
HXCOMM HXCOMM can be used for comments, discarded from both texi and C
|
HXCOMM HXCOMM can be used for comments, discarded from both texi and C
|
||||||
|
|
||||||
|
HXCOMM TODO : when we are able to change -help output without breaking
|
||||||
|
HXCOMM libvirt we should update the help options which refer to -cpu ?,
|
||||||
|
HXCOMM -driver ?, etc to use the preferred -cpu help etc instead.
|
||||||
|
|
||||||
DEFHEADING(Standard options:)
|
DEFHEADING(Standard options:)
|
||||||
STEXI
|
STEXI
|
||||||
@table @option
|
@table @option
|
||||||
|
@ -183,7 +183,7 @@ void configure_alarms(char const *opt)
|
|||||||
char *name;
|
char *name;
|
||||||
struct qemu_alarm_timer tmp;
|
struct qemu_alarm_timer tmp;
|
||||||
|
|
||||||
if (!strcmp(opt, "?")) {
|
if (is_help_option(opt)) {
|
||||||
show_available_alarms();
|
show_available_alarms();
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
4
vl.c
4
vl.c
@ -2086,7 +2086,7 @@ static QEMUMachine *machine_parse(const char *name)
|
|||||||
printf("%-20s %s%s\n", m->name, m->desc,
|
printf("%-20s %s%s\n", m->name, m->desc,
|
||||||
m->is_default ? " (default)" : "");
|
m->is_default ? " (default)" : "");
|
||||||
}
|
}
|
||||||
exit(!name || *name != '?');
|
exit(!name || !is_help_option(name));
|
||||||
}
|
}
|
||||||
|
|
||||||
static int tcg_init(void)
|
static int tcg_init(void)
|
||||||
@ -3216,7 +3216,7 @@ int main(int argc, char **argv, char **envp)
|
|||||||
*/
|
*/
|
||||||
cpudef_init();
|
cpudef_init();
|
||||||
|
|
||||||
if (cpu_model && *cpu_model == '?') {
|
if (cpu_model && is_help_option(cpu_model)) {
|
||||||
list_cpus(stdout, &fprintf, cpu_model);
|
list_cpus(stdout, &fprintf, cpu_model);
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user