custom option parsing to have same behavior on all OSes

git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@805 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
bellard 2004-05-13 22:02:20 +00:00
parent b939777cec
commit cd6f11693a

209
vl.c
View file

@ -23,7 +23,6 @@
*/ */
#include "vl.h" #include "vl.h"
#include <getopt.h>
#include <unistd.h> #include <unistd.h>
#include <fcntl.h> #include <fcntl.h>
#include <signal.h> #include <signal.h>
@ -1908,6 +1907,7 @@ void help(void)
"-initrd file use 'file' as initial ram disk\n" "-initrd file use 'file' as initial ram disk\n"
"\n" "\n"
"Debug/Expert options:\n" "Debug/Expert options:\n"
"-S freeze CPU at startup (use 'c' to start execution)\n"
"-s wait gdb connection to port %d\n" "-s wait gdb connection to port %d\n"
"-p port change gdb connection port\n" "-p port change gdb connection port\n"
"-d item1,... output log to %s (use -d ? for a list of log items)\n" "-d item1,... output log to %s (use -d ? for a list of log items)\n"
@ -1937,29 +1937,85 @@ void help(void)
exit(1); exit(1);
} }
struct option long_options[] = { #define HAS_ARG 0x0001
{ "initrd", 1, NULL, 0, },
{ "hda", 1, NULL, 0, }, enum {
{ "hdb", 1, NULL, 0, }, QEMU_OPTION_h,
{ "snapshot", 0, NULL, 0, },
{ "hdachs", 1, NULL, 0, }, QEMU_OPTION_fda,
{ "nographic", 0, NULL, 0, }, QEMU_OPTION_fdb,
{ "kernel", 1, NULL, 0, }, QEMU_OPTION_hda,
{ "append", 1, NULL, 0, }, QEMU_OPTION_hdb,
{ "tun-fd", 1, NULL, 0, }, QEMU_OPTION_hdc,
{ "hdc", 1, NULL, 0, }, QEMU_OPTION_hdd,
{ "hdd", 1, NULL, 0, }, QEMU_OPTION_cdrom,
{ "cdrom", 1, NULL, 0, }, QEMU_OPTION_boot,
{ "boot", 1, NULL, 0, }, QEMU_OPTION_snapshot,
{ "fda", 1, NULL, 0, }, QEMU_OPTION_m,
{ "fdb", 1, NULL, 0, }, QEMU_OPTION_nographic,
{ "no-code-copy", 0, NULL, 0 }, QEMU_OPTION_enable_audio,
{ "nics", 1, NULL, 0 },
{ "macaddr", 1, NULL, 0 }, QEMU_OPTION_nics,
{ "user-net", 0, NULL, 0 }, QEMU_OPTION_macaddr,
{ "dummy-net", 0, NULL, 0 }, QEMU_OPTION_n,
{ "enable-audio", 0, NULL, 0 }, QEMU_OPTION_tun_fd,
{ NULL, 0, NULL, 0 }, QEMU_OPTION_user_net,
QEMU_OPTION_dummy_net,
QEMU_OPTION_kernel,
QEMU_OPTION_append,
QEMU_OPTION_initrd,
QEMU_OPTION_S,
QEMU_OPTION_s,
QEMU_OPTION_p,
QEMU_OPTION_d,
QEMU_OPTION_hdachs,
QEMU_OPTION_L,
QEMU_OPTION_no_code_copy,
};
typedef struct QEMUOption {
const char *name;
int flags;
int index;
} QEMUOption;
const QEMUOption qemu_options[] = {
{ "h", 0, QEMU_OPTION_h },
{ "fda", HAS_ARG, QEMU_OPTION_fda },
{ "fdb", HAS_ARG, QEMU_OPTION_fdb },
{ "hda", HAS_ARG, QEMU_OPTION_hda },
{ "hdb", HAS_ARG, QEMU_OPTION_hdb },
{ "hdc", HAS_ARG, QEMU_OPTION_hdc },
{ "hdd", HAS_ARG, QEMU_OPTION_hdd },
{ "cdrom", HAS_ARG, QEMU_OPTION_cdrom },
{ "boot", HAS_ARG, QEMU_OPTION_boot },
{ "snapshot", 0, QEMU_OPTION_snapshot },
{ "m", HAS_ARG, QEMU_OPTION_m },
{ "nographic", 0, QEMU_OPTION_nographic },
{ "enable-audio", 0, QEMU_OPTION_enable_audio },
{ "nics", HAS_ARG, QEMU_OPTION_nics},
{ "macaddr", HAS_ARG, QEMU_OPTION_macaddr},
{ "n", HAS_ARG, QEMU_OPTION_d },
{ "tun-fd", HAS_ARG, QEMU_OPTION_tun_fd },
{ "user-net", 0, QEMU_OPTION_user_net },
{ "dummy-net", 0, QEMU_OPTION_dummy_net },
{ "kernel", HAS_ARG, QEMU_OPTION_kernel },
{ "append", HAS_ARG, QEMU_OPTION_append },
{ "initrd", HAS_ARG, QEMU_OPTION_initrd },
{ "S", 0, QEMU_OPTION_S },
{ "s", 0, QEMU_OPTION_s },
{ "p", HAS_ARG, QEMU_OPTION_p },
{ "d", HAS_ARG, QEMU_OPTION_d },
{ "hdachs", HAS_ARG, QEMU_OPTION_hdachs },
{ "L", HAS_ARG, QEMU_OPTION_L },
{ "no-code-copy", 0, QEMU_OPTION_no_code_copy },
{ NULL },
}; };
#if defined (TARGET_I386) && defined(USE_CODE_COPY) #if defined (TARGET_I386) && defined(USE_CODE_COPY)
@ -1980,7 +2036,7 @@ int main(int argc, char **argv)
#ifdef CONFIG_GDBSTUB #ifdef CONFIG_GDBSTUB
int use_gdbstub, gdbstub_port; int use_gdbstub, gdbstub_port;
#endif #endif
int c, i, long_index, has_cdrom; int i, has_cdrom;
int snapshot, linux_boot; int snapshot, linux_boot;
CPUState *env; CPUState *env;
const char *initrd_filename; const char *initrd_filename;
@ -1991,6 +2047,8 @@ int main(int argc, char **argv)
int start_emulation = 1; int start_emulation = 1;
uint8_t macaddr[6]; uint8_t macaddr[6];
int net_if_type, nb_tun_fds, tun_fds[MAX_NICS]; int net_if_type, nb_tun_fds, tun_fds[MAX_NICS];
int optind;
const char *r, *optarg;
#if !defined(CONFIG_SOFTMMU) #if !defined(CONFIG_SOFTMMU)
/* we never want that malloc() uses mmap() */ /* we never want that malloc() uses mmap() */
@ -2026,27 +2084,53 @@ int main(int argc, char **argv)
macaddr[4] = 0x34; macaddr[4] = 0x34;
macaddr[5] = 0x56; macaddr[5] = 0x56;
optind = 1;
for(;;) { for(;;) {
c = getopt_long_only(argc, argv, "hm:d:n:sp:L:S", long_options, &long_index); if (optind >= argc)
if (c == -1)
break; break;
switch(c) { r = argv[optind];
case 0: if (r[0] != '-') {
switch(long_index) { hd_filename[0] = argv[optind++];
case 0: } else {
const QEMUOption *popt;
optind++;
popt = qemu_options;
for(;;) {
if (!popt->name) {
fprintf(stderr, "%s: invalid option -- '%s'\n",
argv[0], r);
exit(1);
}
if (!strcmp(popt->name, r + 1))
break;
popt++;
}
if (popt->flags & HAS_ARG) {
if (optind >= argc) {
fprintf(stderr, "%s: option '%s' requires an argument\n",
argv[0], r);
exit(1);
}
optarg = argv[optind++];
} else {
optarg = NULL;
}
switch(popt->index) {
case QEMU_OPTION_initrd:
initrd_filename = optarg; initrd_filename = optarg;
break; break;
case 1: case QEMU_OPTION_hda:
hd_filename[0] = optarg; hd_filename[0] = optarg;
break; break;
case 2: case QEMU_OPTION_hdb:
hd_filename[1] = optarg; hd_filename[1] = optarg;
break; break;
case 3: case QEMU_OPTION_snapshot:
snapshot = 1; snapshot = 1;
break; break;
case 4: case QEMU_OPTION_hdachs:
{ {
const char *p; const char *p;
p = optarg; p = optarg;
@ -2065,16 +2149,16 @@ int main(int argc, char **argv)
} }
} }
break; break;
case 5: case QEMU_OPTION_nographic:
nographic = 1; nographic = 1;
break; break;
case 6: case QEMU_OPTION_kernel:
kernel_filename = optarg; kernel_filename = optarg;
break; break;
case 7: case QEMU_OPTION_append:
kernel_cmdline = optarg; kernel_cmdline = optarg;
break; break;
case 8: case QEMU_OPTION_tun_fd:
{ {
const char *p; const char *p;
int fd; int fd;
@ -2089,18 +2173,18 @@ int main(int argc, char **argv)
} }
} }
break; break;
case 9: case QEMU_OPTION_hdc:
hd_filename[2] = optarg; hd_filename[2] = optarg;
has_cdrom = 0; has_cdrom = 0;
break; break;
case 10: case QEMU_OPTION_hdd:
hd_filename[3] = optarg; hd_filename[3] = optarg;
break; break;
case 11: case QEMU_OPTION_cdrom:
hd_filename[2] = optarg; hd_filename[2] = optarg;
has_cdrom = 1; has_cdrom = 1;
break; break;
case 12: case QEMU_OPTION_boot:
boot_device = optarg[0]; boot_device = optarg[0];
if (boot_device != 'a' && boot_device != 'b' && if (boot_device != 'a' && boot_device != 'b' &&
boot_device != 'c' && boot_device != 'd') { boot_device != 'c' && boot_device != 'd') {
@ -2108,23 +2192,23 @@ int main(int argc, char **argv)
exit(1); exit(1);
} }
break; break;
case 13: case QEMU_OPTION_fda:
fd_filename[0] = optarg; fd_filename[0] = optarg;
break; break;
case 14: case QEMU_OPTION_fdb:
fd_filename[1] = optarg; fd_filename[1] = optarg;
break; break;
case 15: case QEMU_OPTION_no_code_copy:
code_copy_enabled = 0; code_copy_enabled = 0;
break; break;
case 16: case QEMU_OPTION_nics:
nb_nics = atoi(optarg); nb_nics = atoi(optarg);
if (nb_nics < 0 || nb_nics > MAX_NICS) { if (nb_nics < 0 || nb_nics > MAX_NICS) {
fprintf(stderr, "qemu: invalid number of network interfaces\n"); fprintf(stderr, "qemu: invalid number of network interfaces\n");
exit(1); exit(1);
} }
break; break;
case 17: case QEMU_OPTION_macaddr:
{ {
const char *p; const char *p;
int i; int i;
@ -2145,21 +2229,19 @@ int main(int argc, char **argv)
} }
} }
break; break;
case 18: case QEMU_OPTION_user_net:
net_if_type = NET_IF_USER; net_if_type = NET_IF_USER;
break; break;
case 19: case QEMU_OPTION_dummy_net:
net_if_type = NET_IF_DUMMY; net_if_type = NET_IF_DUMMY;
break; break;
case 20: case QEMU_OPTION_enable_audio:
audio_enabled = 1; audio_enabled = 1;
break; break;
} case QEMU_OPTION_h:
break;
case 'h':
help(); help();
break; break;
case 'm': case QEMU_OPTION_m:
ram_size = atoi(optarg) * 1024 * 1024; ram_size = atoi(optarg) * 1024 * 1024;
if (ram_size <= 0) if (ram_size <= 0)
help(); help();
@ -2169,7 +2251,7 @@ int main(int argc, char **argv)
exit(1); exit(1);
} }
break; break;
case 'd': case QEMU_OPTION_d:
{ {
int mask; int mask;
CPULogItem *item; CPULogItem *item;
@ -2185,28 +2267,25 @@ int main(int argc, char **argv)
cpu_set_log(mask); cpu_set_log(mask);
} }
break; break;
case 'n': case QEMU_OPTION_n:
pstrcpy(network_script, sizeof(network_script), optarg); pstrcpy(network_script, sizeof(network_script), optarg);
break; break;
#ifdef CONFIG_GDBSTUB #ifdef CONFIG_GDBSTUB
case 's': case QEMU_OPTION_s:
use_gdbstub = 1; use_gdbstub = 1;
break; break;
case 'p': case QEMU_OPTION_p:
gdbstub_port = atoi(optarg); gdbstub_port = atoi(optarg);
break; break;
#endif #endif
case 'L': case QEMU_OPTION_L:
bios_dir = optarg; bios_dir = optarg;
break; break;
case 'S': case QEMU_OPTION_S:
start_emulation = 0; start_emulation = 0;
break; break;
} }
} }
if (optind < argc) {
hd_filename[0] = argv[optind++];
} }
linux_boot = (kernel_filename != NULL); linux_boot = (kernel_filename != NULL);