Commit cd6f11693a3c0438fefd86af0a10b57b59d19369
1 parent
b939777c
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
Showing
1 changed file
with
176 additions
and
97 deletions
vl.c
@@ -23,7 +23,6 @@ | @@ -23,7 +23,6 @@ | ||
23 | */ | 23 | */ |
24 | #include "vl.h" | 24 | #include "vl.h" |
25 | 25 | ||
26 | -#include <getopt.h> | ||
27 | #include <unistd.h> | 26 | #include <unistd.h> |
28 | #include <fcntl.h> | 27 | #include <fcntl.h> |
29 | #include <signal.h> | 28 | #include <signal.h> |
@@ -1908,6 +1907,7 @@ void help(void) | @@ -1908,6 +1907,7 @@ void help(void) | ||
1908 | "-initrd file use 'file' as initial ram disk\n" | 1907 | "-initrd file use 'file' as initial ram disk\n" |
1909 | "\n" | 1908 | "\n" |
1910 | "Debug/Expert options:\n" | 1909 | "Debug/Expert options:\n" |
1910 | + "-S freeze CPU at startup (use 'c' to start execution)\n" | ||
1911 | "-s wait gdb connection to port %d\n" | 1911 | "-s wait gdb connection to port %d\n" |
1912 | "-p port change gdb connection port\n" | 1912 | "-p port change gdb connection port\n" |
1913 | "-d item1,... output log to %s (use -d ? for a list of log items)\n" | 1913 | "-d item1,... output log to %s (use -d ? for a list of log items)\n" |
@@ -1937,29 +1937,85 @@ void help(void) | @@ -1937,29 +1937,85 @@ void help(void) | ||
1937 | exit(1); | 1937 | exit(1); |
1938 | } | 1938 | } |
1939 | 1939 | ||
1940 | -struct option long_options[] = { | ||
1941 | - { "initrd", 1, NULL, 0, }, | ||
1942 | - { "hda", 1, NULL, 0, }, | ||
1943 | - { "hdb", 1, NULL, 0, }, | ||
1944 | - { "snapshot", 0, NULL, 0, }, | ||
1945 | - { "hdachs", 1, NULL, 0, }, | ||
1946 | - { "nographic", 0, NULL, 0, }, | ||
1947 | - { "kernel", 1, NULL, 0, }, | ||
1948 | - { "append", 1, NULL, 0, }, | ||
1949 | - { "tun-fd", 1, NULL, 0, }, | ||
1950 | - { "hdc", 1, NULL, 0, }, | ||
1951 | - { "hdd", 1, NULL, 0, }, | ||
1952 | - { "cdrom", 1, NULL, 0, }, | ||
1953 | - { "boot", 1, NULL, 0, }, | ||
1954 | - { "fda", 1, NULL, 0, }, | ||
1955 | - { "fdb", 1, NULL, 0, }, | ||
1956 | - { "no-code-copy", 0, NULL, 0 }, | ||
1957 | - { "nics", 1, NULL, 0 }, | ||
1958 | - { "macaddr", 1, NULL, 0 }, | ||
1959 | - { "user-net", 0, NULL, 0 }, | ||
1960 | - { "dummy-net", 0, NULL, 0 }, | ||
1961 | - { "enable-audio", 0, NULL, 0 }, | ||
1962 | - { NULL, 0, NULL, 0 }, | 1940 | +#define HAS_ARG 0x0001 |
1941 | + | ||
1942 | +enum { | ||
1943 | + QEMU_OPTION_h, | ||
1944 | + | ||
1945 | + QEMU_OPTION_fda, | ||
1946 | + QEMU_OPTION_fdb, | ||
1947 | + QEMU_OPTION_hda, | ||
1948 | + QEMU_OPTION_hdb, | ||
1949 | + QEMU_OPTION_hdc, | ||
1950 | + QEMU_OPTION_hdd, | ||
1951 | + QEMU_OPTION_cdrom, | ||
1952 | + QEMU_OPTION_boot, | ||
1953 | + QEMU_OPTION_snapshot, | ||
1954 | + QEMU_OPTION_m, | ||
1955 | + QEMU_OPTION_nographic, | ||
1956 | + QEMU_OPTION_enable_audio, | ||
1957 | + | ||
1958 | + QEMU_OPTION_nics, | ||
1959 | + QEMU_OPTION_macaddr, | ||
1960 | + QEMU_OPTION_n, | ||
1961 | + QEMU_OPTION_tun_fd, | ||
1962 | + QEMU_OPTION_user_net, | ||
1963 | + QEMU_OPTION_dummy_net, | ||
1964 | + | ||
1965 | + QEMU_OPTION_kernel, | ||
1966 | + QEMU_OPTION_append, | ||
1967 | + QEMU_OPTION_initrd, | ||
1968 | + | ||
1969 | + QEMU_OPTION_S, | ||
1970 | + QEMU_OPTION_s, | ||
1971 | + QEMU_OPTION_p, | ||
1972 | + QEMU_OPTION_d, | ||
1973 | + QEMU_OPTION_hdachs, | ||
1974 | + QEMU_OPTION_L, | ||
1975 | + QEMU_OPTION_no_code_copy, | ||
1976 | +}; | ||
1977 | + | ||
1978 | +typedef struct QEMUOption { | ||
1979 | + const char *name; | ||
1980 | + int flags; | ||
1981 | + int index; | ||
1982 | +} QEMUOption; | ||
1983 | + | ||
1984 | +const QEMUOption qemu_options[] = { | ||
1985 | + { "h", 0, QEMU_OPTION_h }, | ||
1986 | + | ||
1987 | + { "fda", HAS_ARG, QEMU_OPTION_fda }, | ||
1988 | + { "fdb", HAS_ARG, QEMU_OPTION_fdb }, | ||
1989 | + { "hda", HAS_ARG, QEMU_OPTION_hda }, | ||
1990 | + { "hdb", HAS_ARG, QEMU_OPTION_hdb }, | ||
1991 | + { "hdc", HAS_ARG, QEMU_OPTION_hdc }, | ||
1992 | + { "hdd", HAS_ARG, QEMU_OPTION_hdd }, | ||
1993 | + { "cdrom", HAS_ARG, QEMU_OPTION_cdrom }, | ||
1994 | + { "boot", HAS_ARG, QEMU_OPTION_boot }, | ||
1995 | + { "snapshot", 0, QEMU_OPTION_snapshot }, | ||
1996 | + { "m", HAS_ARG, QEMU_OPTION_m }, | ||
1997 | + { "nographic", 0, QEMU_OPTION_nographic }, | ||
1998 | + { "enable-audio", 0, QEMU_OPTION_enable_audio }, | ||
1999 | + | ||
2000 | + { "nics", HAS_ARG, QEMU_OPTION_nics}, | ||
2001 | + { "macaddr", HAS_ARG, QEMU_OPTION_macaddr}, | ||
2002 | + { "n", HAS_ARG, QEMU_OPTION_d }, | ||
2003 | + { "tun-fd", HAS_ARG, QEMU_OPTION_tun_fd }, | ||
2004 | + { "user-net", 0, QEMU_OPTION_user_net }, | ||
2005 | + { "dummy-net", 0, QEMU_OPTION_dummy_net }, | ||
2006 | + | ||
2007 | + { "kernel", HAS_ARG, QEMU_OPTION_kernel }, | ||
2008 | + { "append", HAS_ARG, QEMU_OPTION_append }, | ||
2009 | + { "initrd", HAS_ARG, QEMU_OPTION_initrd }, | ||
2010 | + | ||
2011 | + { "S", 0, QEMU_OPTION_S }, | ||
2012 | + { "s", 0, QEMU_OPTION_s }, | ||
2013 | + { "p", HAS_ARG, QEMU_OPTION_p }, | ||
2014 | + { "d", HAS_ARG, QEMU_OPTION_d }, | ||
2015 | + { "hdachs", HAS_ARG, QEMU_OPTION_hdachs }, | ||
2016 | + { "L", HAS_ARG, QEMU_OPTION_L }, | ||
2017 | + { "no-code-copy", 0, QEMU_OPTION_no_code_copy }, | ||
2018 | + { NULL }, | ||
1963 | }; | 2019 | }; |
1964 | 2020 | ||
1965 | #if defined (TARGET_I386) && defined(USE_CODE_COPY) | 2021 | #if defined (TARGET_I386) && defined(USE_CODE_COPY) |
@@ -1980,7 +2036,7 @@ int main(int argc, char **argv) | @@ -1980,7 +2036,7 @@ int main(int argc, char **argv) | ||
1980 | #ifdef CONFIG_GDBSTUB | 2036 | #ifdef CONFIG_GDBSTUB |
1981 | int use_gdbstub, gdbstub_port; | 2037 | int use_gdbstub, gdbstub_port; |
1982 | #endif | 2038 | #endif |
1983 | - int c, i, long_index, has_cdrom; | 2039 | + int i, has_cdrom; |
1984 | int snapshot, linux_boot; | 2040 | int snapshot, linux_boot; |
1985 | CPUState *env; | 2041 | CPUState *env; |
1986 | const char *initrd_filename; | 2042 | const char *initrd_filename; |
@@ -1991,7 +2047,9 @@ int main(int argc, char **argv) | @@ -1991,7 +2047,9 @@ int main(int argc, char **argv) | ||
1991 | int start_emulation = 1; | 2047 | int start_emulation = 1; |
1992 | uint8_t macaddr[6]; | 2048 | uint8_t macaddr[6]; |
1993 | int net_if_type, nb_tun_fds, tun_fds[MAX_NICS]; | 2049 | int net_if_type, nb_tun_fds, tun_fds[MAX_NICS]; |
1994 | - | 2050 | + int optind; |
2051 | + const char *r, *optarg; | ||
2052 | + | ||
1995 | #if !defined(CONFIG_SOFTMMU) | 2053 | #if !defined(CONFIG_SOFTMMU) |
1996 | /* we never want that malloc() uses mmap() */ | 2054 | /* we never want that malloc() uses mmap() */ |
1997 | mallopt(M_MMAP_THRESHOLD, 4096 * 1024); | 2055 | mallopt(M_MMAP_THRESHOLD, 4096 * 1024); |
@@ -2026,27 +2084,53 @@ int main(int argc, char **argv) | @@ -2026,27 +2084,53 @@ int main(int argc, char **argv) | ||
2026 | macaddr[4] = 0x34; | 2084 | macaddr[4] = 0x34; |
2027 | macaddr[5] = 0x56; | 2085 | macaddr[5] = 0x56; |
2028 | 2086 | ||
2029 | - | 2087 | + optind = 1; |
2030 | for(;;) { | 2088 | for(;;) { |
2031 | - c = getopt_long_only(argc, argv, "hm:d:n:sp:L:S", long_options, &long_index); | ||
2032 | - if (c == -1) | 2089 | + if (optind >= argc) |
2033 | break; | 2090 | break; |
2034 | - switch(c) { | ||
2035 | - case 0: | ||
2036 | - switch(long_index) { | ||
2037 | - case 0: | 2091 | + r = argv[optind]; |
2092 | + if (r[0] != '-') { | ||
2093 | + hd_filename[0] = argv[optind++]; | ||
2094 | + } else { | ||
2095 | + const QEMUOption *popt; | ||
2096 | + | ||
2097 | + optind++; | ||
2098 | + popt = qemu_options; | ||
2099 | + for(;;) { | ||
2100 | + if (!popt->name) { | ||
2101 | + fprintf(stderr, "%s: invalid option -- '%s'\n", | ||
2102 | + argv[0], r); | ||
2103 | + exit(1); | ||
2104 | + } | ||
2105 | + if (!strcmp(popt->name, r + 1)) | ||
2106 | + break; | ||
2107 | + popt++; | ||
2108 | + } | ||
2109 | + if (popt->flags & HAS_ARG) { | ||
2110 | + if (optind >= argc) { | ||
2111 | + fprintf(stderr, "%s: option '%s' requires an argument\n", | ||
2112 | + argv[0], r); | ||
2113 | + exit(1); | ||
2114 | + } | ||
2115 | + optarg = argv[optind++]; | ||
2116 | + } else { | ||
2117 | + optarg = NULL; | ||
2118 | + } | ||
2119 | + | ||
2120 | + switch(popt->index) { | ||
2121 | + case QEMU_OPTION_initrd: | ||
2038 | initrd_filename = optarg; | 2122 | initrd_filename = optarg; |
2039 | break; | 2123 | break; |
2040 | - case 1: | 2124 | + case QEMU_OPTION_hda: |
2041 | hd_filename[0] = optarg; | 2125 | hd_filename[0] = optarg; |
2042 | break; | 2126 | break; |
2043 | - case 2: | 2127 | + case QEMU_OPTION_hdb: |
2044 | hd_filename[1] = optarg; | 2128 | hd_filename[1] = optarg; |
2045 | break; | 2129 | break; |
2046 | - case 3: | 2130 | + case QEMU_OPTION_snapshot: |
2047 | snapshot = 1; | 2131 | snapshot = 1; |
2048 | break; | 2132 | break; |
2049 | - case 4: | 2133 | + case QEMU_OPTION_hdachs: |
2050 | { | 2134 | { |
2051 | const char *p; | 2135 | const char *p; |
2052 | p = optarg; | 2136 | p = optarg; |
@@ -2065,16 +2149,16 @@ int main(int argc, char **argv) | @@ -2065,16 +2149,16 @@ int main(int argc, char **argv) | ||
2065 | } | 2149 | } |
2066 | } | 2150 | } |
2067 | break; | 2151 | break; |
2068 | - case 5: | 2152 | + case QEMU_OPTION_nographic: |
2069 | nographic = 1; | 2153 | nographic = 1; |
2070 | break; | 2154 | break; |
2071 | - case 6: | 2155 | + case QEMU_OPTION_kernel: |
2072 | kernel_filename = optarg; | 2156 | kernel_filename = optarg; |
2073 | break; | 2157 | break; |
2074 | - case 7: | 2158 | + case QEMU_OPTION_append: |
2075 | kernel_cmdline = optarg; | 2159 | kernel_cmdline = optarg; |
2076 | break; | 2160 | break; |
2077 | - case 8: | 2161 | + case QEMU_OPTION_tun_fd: |
2078 | { | 2162 | { |
2079 | const char *p; | 2163 | const char *p; |
2080 | int fd; | 2164 | int fd; |
@@ -2089,18 +2173,18 @@ int main(int argc, char **argv) | @@ -2089,18 +2173,18 @@ int main(int argc, char **argv) | ||
2089 | } | 2173 | } |
2090 | } | 2174 | } |
2091 | break; | 2175 | break; |
2092 | - case 9: | 2176 | + case QEMU_OPTION_hdc: |
2093 | hd_filename[2] = optarg; | 2177 | hd_filename[2] = optarg; |
2094 | has_cdrom = 0; | 2178 | has_cdrom = 0; |
2095 | break; | 2179 | break; |
2096 | - case 10: | 2180 | + case QEMU_OPTION_hdd: |
2097 | hd_filename[3] = optarg; | 2181 | hd_filename[3] = optarg; |
2098 | break; | 2182 | break; |
2099 | - case 11: | 2183 | + case QEMU_OPTION_cdrom: |
2100 | hd_filename[2] = optarg; | 2184 | hd_filename[2] = optarg; |
2101 | has_cdrom = 1; | 2185 | has_cdrom = 1; |
2102 | break; | 2186 | break; |
2103 | - case 12: | 2187 | + case QEMU_OPTION_boot: |
2104 | boot_device = optarg[0]; | 2188 | boot_device = optarg[0]; |
2105 | if (boot_device != 'a' && boot_device != 'b' && | 2189 | if (boot_device != 'a' && boot_device != 'b' && |
2106 | boot_device != 'c' && boot_device != 'd') { | 2190 | boot_device != 'c' && boot_device != 'd') { |
@@ -2108,23 +2192,23 @@ int main(int argc, char **argv) | @@ -2108,23 +2192,23 @@ int main(int argc, char **argv) | ||
2108 | exit(1); | 2192 | exit(1); |
2109 | } | 2193 | } |
2110 | break; | 2194 | break; |
2111 | - case 13: | 2195 | + case QEMU_OPTION_fda: |
2112 | fd_filename[0] = optarg; | 2196 | fd_filename[0] = optarg; |
2113 | break; | 2197 | break; |
2114 | - case 14: | 2198 | + case QEMU_OPTION_fdb: |
2115 | fd_filename[1] = optarg; | 2199 | fd_filename[1] = optarg; |
2116 | break; | 2200 | break; |
2117 | - case 15: | 2201 | + case QEMU_OPTION_no_code_copy: |
2118 | code_copy_enabled = 0; | 2202 | code_copy_enabled = 0; |
2119 | break; | 2203 | break; |
2120 | - case 16: | 2204 | + case QEMU_OPTION_nics: |
2121 | nb_nics = atoi(optarg); | 2205 | nb_nics = atoi(optarg); |
2122 | if (nb_nics < 0 || nb_nics > MAX_NICS) { | 2206 | if (nb_nics < 0 || nb_nics > MAX_NICS) { |
2123 | fprintf(stderr, "qemu: invalid number of network interfaces\n"); | 2207 | fprintf(stderr, "qemu: invalid number of network interfaces\n"); |
2124 | exit(1); | 2208 | exit(1); |
2125 | } | 2209 | } |
2126 | break; | 2210 | break; |
2127 | - case 17: | 2211 | + case QEMU_OPTION_macaddr: |
2128 | { | 2212 | { |
2129 | const char *p; | 2213 | const char *p; |
2130 | int i; | 2214 | int i; |
@@ -2145,70 +2229,65 @@ int main(int argc, char **argv) | @@ -2145,70 +2229,65 @@ int main(int argc, char **argv) | ||
2145 | } | 2229 | } |
2146 | } | 2230 | } |
2147 | break; | 2231 | break; |
2148 | - case 18: | 2232 | + case QEMU_OPTION_user_net: |
2149 | net_if_type = NET_IF_USER; | 2233 | net_if_type = NET_IF_USER; |
2150 | break; | 2234 | break; |
2151 | - case 19: | 2235 | + case QEMU_OPTION_dummy_net: |
2152 | net_if_type = NET_IF_DUMMY; | 2236 | net_if_type = NET_IF_DUMMY; |
2153 | break; | 2237 | break; |
2154 | - case 20: | 2238 | + case QEMU_OPTION_enable_audio: |
2155 | audio_enabled = 1; | 2239 | audio_enabled = 1; |
2156 | break; | 2240 | break; |
2157 | - } | ||
2158 | - break; | ||
2159 | - case 'h': | ||
2160 | - help(); | ||
2161 | - break; | ||
2162 | - case 'm': | ||
2163 | - ram_size = atoi(optarg) * 1024 * 1024; | ||
2164 | - if (ram_size <= 0) | 2241 | + case QEMU_OPTION_h: |
2165 | help(); | 2242 | help(); |
2166 | - if (ram_size > PHYS_RAM_MAX_SIZE) { | ||
2167 | - fprintf(stderr, "qemu: at most %d MB RAM can be simulated\n", | ||
2168 | - PHYS_RAM_MAX_SIZE / (1024 * 1024)); | ||
2169 | - exit(1); | ||
2170 | - } | ||
2171 | - break; | ||
2172 | - case 'd': | ||
2173 | - { | ||
2174 | - int mask; | ||
2175 | - CPULogItem *item; | ||
2176 | - | ||
2177 | - mask = cpu_str_to_log_mask(optarg); | ||
2178 | - if (!mask) { | ||
2179 | - printf("Log items (comma separated):\n"); | 2243 | + break; |
2244 | + case QEMU_OPTION_m: | ||
2245 | + ram_size = atoi(optarg) * 1024 * 1024; | ||
2246 | + if (ram_size <= 0) | ||
2247 | + help(); | ||
2248 | + if (ram_size > PHYS_RAM_MAX_SIZE) { | ||
2249 | + fprintf(stderr, "qemu: at most %d MB RAM can be simulated\n", | ||
2250 | + PHYS_RAM_MAX_SIZE / (1024 * 1024)); | ||
2251 | + exit(1); | ||
2252 | + } | ||
2253 | + break; | ||
2254 | + case QEMU_OPTION_d: | ||
2255 | + { | ||
2256 | + int mask; | ||
2257 | + CPULogItem *item; | ||
2258 | + | ||
2259 | + mask = cpu_str_to_log_mask(optarg); | ||
2260 | + if (!mask) { | ||
2261 | + printf("Log items (comma separated):\n"); | ||
2180 | for(item = cpu_log_items; item->mask != 0; item++) { | 2262 | for(item = cpu_log_items; item->mask != 0; item++) { |
2181 | printf("%-10s %s\n", item->name, item->help); | 2263 | printf("%-10s %s\n", item->name, item->help); |
2182 | } | 2264 | } |
2183 | exit(1); | 2265 | exit(1); |
2266 | + } | ||
2267 | + cpu_set_log(mask); | ||
2184 | } | 2268 | } |
2185 | - cpu_set_log(mask); | ||
2186 | - } | ||
2187 | - break; | ||
2188 | - case 'n': | ||
2189 | - pstrcpy(network_script, sizeof(network_script), optarg); | ||
2190 | - break; | 2269 | + break; |
2270 | + case QEMU_OPTION_n: | ||
2271 | + pstrcpy(network_script, sizeof(network_script), optarg); | ||
2272 | + break; | ||
2191 | #ifdef CONFIG_GDBSTUB | 2273 | #ifdef CONFIG_GDBSTUB |
2192 | - case 's': | ||
2193 | - use_gdbstub = 1; | ||
2194 | - break; | ||
2195 | - case 'p': | ||
2196 | - gdbstub_port = atoi(optarg); | ||
2197 | - break; | 2274 | + case QEMU_OPTION_s: |
2275 | + use_gdbstub = 1; | ||
2276 | + break; | ||
2277 | + case QEMU_OPTION_p: | ||
2278 | + gdbstub_port = atoi(optarg); | ||
2279 | + break; | ||
2198 | #endif | 2280 | #endif |
2199 | - case 'L': | ||
2200 | - bios_dir = optarg; | ||
2201 | - break; | ||
2202 | - case 'S': | ||
2203 | - start_emulation = 0; | ||
2204 | - break; | 2281 | + case QEMU_OPTION_L: |
2282 | + bios_dir = optarg; | ||
2283 | + break; | ||
2284 | + case QEMU_OPTION_S: | ||
2285 | + start_emulation = 0; | ||
2286 | + break; | ||
2287 | + } | ||
2205 | } | 2288 | } |
2206 | } | 2289 | } |
2207 | 2290 | ||
2208 | - if (optind < argc) { | ||
2209 | - hd_filename[0] = argv[optind++]; | ||
2210 | - } | ||
2211 | - | ||
2212 | linux_boot = (kernel_filename != NULL); | 2291 | linux_boot = (kernel_filename != NULL); |
2213 | 2292 | ||
2214 | if (!linux_boot && hd_filename[0] == '\0' && hd_filename[2] == '\0' && | 2293 | if (!linux_boot && hd_filename[0] == '\0' && hd_filename[2] == '\0' && |