From cd6f11693a3c0438fefd86af0a10b57b59d19369 Mon Sep 17 00:00:00 2001 From: bellard Date: Thu, 13 May 2004 22:02:20 +0000 Subject: [PATCH] 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 --- vl.c | 273 ++++++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 176 insertions(+), 97 deletions(-) diff --git a/vl.c b/vl.c index 7db2881770..2ad182df62 100644 --- a/vl.c +++ b/vl.c @@ -23,7 +23,6 @@ */ #include "vl.h" -#include #include #include #include @@ -1908,6 +1907,7 @@ void help(void) "-initrd file use 'file' as initial ram disk\n" "\n" "Debug/Expert options:\n" + "-S freeze CPU at startup (use 'c' to start execution)\n" "-s wait gdb connection to port %d\n" "-p port change gdb connection port\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); } -struct option long_options[] = { - { "initrd", 1, NULL, 0, }, - { "hda", 1, NULL, 0, }, - { "hdb", 1, NULL, 0, }, - { "snapshot", 0, NULL, 0, }, - { "hdachs", 1, NULL, 0, }, - { "nographic", 0, NULL, 0, }, - { "kernel", 1, NULL, 0, }, - { "append", 1, NULL, 0, }, - { "tun-fd", 1, NULL, 0, }, - { "hdc", 1, NULL, 0, }, - { "hdd", 1, NULL, 0, }, - { "cdrom", 1, NULL, 0, }, - { "boot", 1, NULL, 0, }, - { "fda", 1, NULL, 0, }, - { "fdb", 1, NULL, 0, }, - { "no-code-copy", 0, NULL, 0 }, - { "nics", 1, NULL, 0 }, - { "macaddr", 1, NULL, 0 }, - { "user-net", 0, NULL, 0 }, - { "dummy-net", 0, NULL, 0 }, - { "enable-audio", 0, NULL, 0 }, - { NULL, 0, NULL, 0 }, +#define HAS_ARG 0x0001 + +enum { + QEMU_OPTION_h, + + QEMU_OPTION_fda, + QEMU_OPTION_fdb, + QEMU_OPTION_hda, + QEMU_OPTION_hdb, + QEMU_OPTION_hdc, + QEMU_OPTION_hdd, + QEMU_OPTION_cdrom, + QEMU_OPTION_boot, + QEMU_OPTION_snapshot, + QEMU_OPTION_m, + QEMU_OPTION_nographic, + QEMU_OPTION_enable_audio, + + QEMU_OPTION_nics, + QEMU_OPTION_macaddr, + QEMU_OPTION_n, + QEMU_OPTION_tun_fd, + 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) @@ -1980,7 +2036,7 @@ int main(int argc, char **argv) #ifdef CONFIG_GDBSTUB int use_gdbstub, gdbstub_port; #endif - int c, i, long_index, has_cdrom; + int i, has_cdrom; int snapshot, linux_boot; CPUState *env; const char *initrd_filename; @@ -1991,7 +2047,9 @@ int main(int argc, char **argv) int start_emulation = 1; uint8_t macaddr[6]; int net_if_type, nb_tun_fds, tun_fds[MAX_NICS]; - + int optind; + const char *r, *optarg; + #if !defined(CONFIG_SOFTMMU) /* we never want that malloc() uses mmap() */ mallopt(M_MMAP_THRESHOLD, 4096 * 1024); @@ -2026,27 +2084,53 @@ int main(int argc, char **argv) macaddr[4] = 0x34; macaddr[5] = 0x56; - + optind = 1; for(;;) { - c = getopt_long_only(argc, argv, "hm:d:n:sp:L:S", long_options, &long_index); - if (c == -1) + if (optind >= argc) break; - switch(c) { - case 0: - switch(long_index) { - case 0: + r = argv[optind]; + if (r[0] != '-') { + hd_filename[0] = argv[optind++]; + } 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; break; - case 1: + case QEMU_OPTION_hda: hd_filename[0] = optarg; break; - case 2: + case QEMU_OPTION_hdb: hd_filename[1] = optarg; break; - case 3: + case QEMU_OPTION_snapshot: snapshot = 1; break; - case 4: + case QEMU_OPTION_hdachs: { const char *p; p = optarg; @@ -2065,16 +2149,16 @@ int main(int argc, char **argv) } } break; - case 5: + case QEMU_OPTION_nographic: nographic = 1; break; - case 6: + case QEMU_OPTION_kernel: kernel_filename = optarg; break; - case 7: + case QEMU_OPTION_append: kernel_cmdline = optarg; break; - case 8: + case QEMU_OPTION_tun_fd: { const char *p; int fd; @@ -2089,18 +2173,18 @@ int main(int argc, char **argv) } } break; - case 9: + case QEMU_OPTION_hdc: hd_filename[2] = optarg; has_cdrom = 0; break; - case 10: + case QEMU_OPTION_hdd: hd_filename[3] = optarg; break; - case 11: + case QEMU_OPTION_cdrom: hd_filename[2] = optarg; has_cdrom = 1; break; - case 12: + case QEMU_OPTION_boot: boot_device = optarg[0]; if (boot_device != 'a' && boot_device != 'b' && boot_device != 'c' && boot_device != 'd') { @@ -2108,23 +2192,23 @@ int main(int argc, char **argv) exit(1); } break; - case 13: + case QEMU_OPTION_fda: fd_filename[0] = optarg; break; - case 14: + case QEMU_OPTION_fdb: fd_filename[1] = optarg; break; - case 15: + case QEMU_OPTION_no_code_copy: code_copy_enabled = 0; break; - case 16: + case QEMU_OPTION_nics: nb_nics = atoi(optarg); if (nb_nics < 0 || nb_nics > MAX_NICS) { fprintf(stderr, "qemu: invalid number of network interfaces\n"); exit(1); } break; - case 17: + case QEMU_OPTION_macaddr: { const char *p; int i; @@ -2145,70 +2229,65 @@ int main(int argc, char **argv) } } break; - case 18: + case QEMU_OPTION_user_net: net_if_type = NET_IF_USER; break; - case 19: + case QEMU_OPTION_dummy_net: net_if_type = NET_IF_DUMMY; break; - case 20: + case QEMU_OPTION_enable_audio: audio_enabled = 1; break; - } - break; - case 'h': - help(); - break; - case 'm': - ram_size = atoi(optarg) * 1024 * 1024; - if (ram_size <= 0) + case QEMU_OPTION_h: help(); - if (ram_size > PHYS_RAM_MAX_SIZE) { - fprintf(stderr, "qemu: at most %d MB RAM can be simulated\n", - PHYS_RAM_MAX_SIZE / (1024 * 1024)); - exit(1); - } - break; - case 'd': - { - int mask; - CPULogItem *item; - - mask = cpu_str_to_log_mask(optarg); - if (!mask) { - printf("Log items (comma separated):\n"); + break; + case QEMU_OPTION_m: + ram_size = atoi(optarg) * 1024 * 1024; + if (ram_size <= 0) + help(); + if (ram_size > PHYS_RAM_MAX_SIZE) { + fprintf(stderr, "qemu: at most %d MB RAM can be simulated\n", + PHYS_RAM_MAX_SIZE / (1024 * 1024)); + exit(1); + } + break; + case QEMU_OPTION_d: + { + int mask; + CPULogItem *item; + + mask = cpu_str_to_log_mask(optarg); + if (!mask) { + printf("Log items (comma separated):\n"); for(item = cpu_log_items; item->mask != 0; item++) { printf("%-10s %s\n", item->name, item->help); } exit(1); + } + cpu_set_log(mask); } - cpu_set_log(mask); - } - break; - case 'n': - pstrcpy(network_script, sizeof(network_script), optarg); - break; + break; + case QEMU_OPTION_n: + pstrcpy(network_script, sizeof(network_script), optarg); + break; #ifdef CONFIG_GDBSTUB - case 's': - use_gdbstub = 1; - break; - case 'p': - gdbstub_port = atoi(optarg); - break; + case QEMU_OPTION_s: + use_gdbstub = 1; + break; + case QEMU_OPTION_p: + gdbstub_port = atoi(optarg); + break; #endif - case 'L': - bios_dir = optarg; - break; - case 'S': - start_emulation = 0; - break; + case QEMU_OPTION_L: + bios_dir = optarg; + break; + case QEMU_OPTION_S: + start_emulation = 0; + break; + } } } - if (optind < argc) { - hd_filename[0] = argv[optind++]; - } - linux_boot = (kernel_filename != NULL); if (!linux_boot && hd_filename[0] == '\0' && hd_filename[2] == '\0' && -- GitLab