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 | 23 | */ |
24 | 24 | #include "vl.h" |
25 | 25 | |
26 | -#include <getopt.h> | |
27 | 26 | #include <unistd.h> |
28 | 27 | #include <fcntl.h> |
29 | 28 | #include <signal.h> |
... | ... | @@ -1908,6 +1907,7 @@ void help(void) |
1908 | 1907 | "-initrd file use 'file' as initial ram disk\n" |
1909 | 1908 | "\n" |
1910 | 1909 | "Debug/Expert options:\n" |
1910 | + "-S freeze CPU at startup (use 'c' to start execution)\n" | |
1911 | 1911 | "-s wait gdb connection to port %d\n" |
1912 | 1912 | "-p port change gdb connection port\n" |
1913 | 1913 | "-d item1,... output log to %s (use -d ? for a list of log items)\n" |
... | ... | @@ -1937,29 +1937,85 @@ void help(void) |
1937 | 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 | 2021 | #if defined (TARGET_I386) && defined(USE_CODE_COPY) |
... | ... | @@ -1980,7 +2036,7 @@ int main(int argc, char **argv) |
1980 | 2036 | #ifdef CONFIG_GDBSTUB |
1981 | 2037 | int use_gdbstub, gdbstub_port; |
1982 | 2038 | #endif |
1983 | - int c, i, long_index, has_cdrom; | |
2039 | + int i, has_cdrom; | |
1984 | 2040 | int snapshot, linux_boot; |
1985 | 2041 | CPUState *env; |
1986 | 2042 | const char *initrd_filename; |
... | ... | @@ -1991,7 +2047,9 @@ int main(int argc, char **argv) |
1991 | 2047 | int start_emulation = 1; |
1992 | 2048 | uint8_t macaddr[6]; |
1993 | 2049 | int net_if_type, nb_tun_fds, tun_fds[MAX_NICS]; |
1994 | - | |
2050 | + int optind; | |
2051 | + const char *r, *optarg; | |
2052 | + | |
1995 | 2053 | #if !defined(CONFIG_SOFTMMU) |
1996 | 2054 | /* we never want that malloc() uses mmap() */ |
1997 | 2055 | mallopt(M_MMAP_THRESHOLD, 4096 * 1024); |
... | ... | @@ -2026,27 +2084,53 @@ int main(int argc, char **argv) |
2026 | 2084 | macaddr[4] = 0x34; |
2027 | 2085 | macaddr[5] = 0x56; |
2028 | 2086 | |
2029 | - | |
2087 | + optind = 1; | |
2030 | 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 | 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 | 2122 | initrd_filename = optarg; |
2039 | 2123 | break; |
2040 | - case 1: | |
2124 | + case QEMU_OPTION_hda: | |
2041 | 2125 | hd_filename[0] = optarg; |
2042 | 2126 | break; |
2043 | - case 2: | |
2127 | + case QEMU_OPTION_hdb: | |
2044 | 2128 | hd_filename[1] = optarg; |
2045 | 2129 | break; |
2046 | - case 3: | |
2130 | + case QEMU_OPTION_snapshot: | |
2047 | 2131 | snapshot = 1; |
2048 | 2132 | break; |
2049 | - case 4: | |
2133 | + case QEMU_OPTION_hdachs: | |
2050 | 2134 | { |
2051 | 2135 | const char *p; |
2052 | 2136 | p = optarg; |
... | ... | @@ -2065,16 +2149,16 @@ int main(int argc, char **argv) |
2065 | 2149 | } |
2066 | 2150 | } |
2067 | 2151 | break; |
2068 | - case 5: | |
2152 | + case QEMU_OPTION_nographic: | |
2069 | 2153 | nographic = 1; |
2070 | 2154 | break; |
2071 | - case 6: | |
2155 | + case QEMU_OPTION_kernel: | |
2072 | 2156 | kernel_filename = optarg; |
2073 | 2157 | break; |
2074 | - case 7: | |
2158 | + case QEMU_OPTION_append: | |
2075 | 2159 | kernel_cmdline = optarg; |
2076 | 2160 | break; |
2077 | - case 8: | |
2161 | + case QEMU_OPTION_tun_fd: | |
2078 | 2162 | { |
2079 | 2163 | const char *p; |
2080 | 2164 | int fd; |
... | ... | @@ -2089,18 +2173,18 @@ int main(int argc, char **argv) |
2089 | 2173 | } |
2090 | 2174 | } |
2091 | 2175 | break; |
2092 | - case 9: | |
2176 | + case QEMU_OPTION_hdc: | |
2093 | 2177 | hd_filename[2] = optarg; |
2094 | 2178 | has_cdrom = 0; |
2095 | 2179 | break; |
2096 | - case 10: | |
2180 | + case QEMU_OPTION_hdd: | |
2097 | 2181 | hd_filename[3] = optarg; |
2098 | 2182 | break; |
2099 | - case 11: | |
2183 | + case QEMU_OPTION_cdrom: | |
2100 | 2184 | hd_filename[2] = optarg; |
2101 | 2185 | has_cdrom = 1; |
2102 | 2186 | break; |
2103 | - case 12: | |
2187 | + case QEMU_OPTION_boot: | |
2104 | 2188 | boot_device = optarg[0]; |
2105 | 2189 | if (boot_device != 'a' && boot_device != 'b' && |
2106 | 2190 | boot_device != 'c' && boot_device != 'd') { |
... | ... | @@ -2108,23 +2192,23 @@ int main(int argc, char **argv) |
2108 | 2192 | exit(1); |
2109 | 2193 | } |
2110 | 2194 | break; |
2111 | - case 13: | |
2195 | + case QEMU_OPTION_fda: | |
2112 | 2196 | fd_filename[0] = optarg; |
2113 | 2197 | break; |
2114 | - case 14: | |
2198 | + case QEMU_OPTION_fdb: | |
2115 | 2199 | fd_filename[1] = optarg; |
2116 | 2200 | break; |
2117 | - case 15: | |
2201 | + case QEMU_OPTION_no_code_copy: | |
2118 | 2202 | code_copy_enabled = 0; |
2119 | 2203 | break; |
2120 | - case 16: | |
2204 | + case QEMU_OPTION_nics: | |
2121 | 2205 | nb_nics = atoi(optarg); |
2122 | 2206 | if (nb_nics < 0 || nb_nics > MAX_NICS) { |
2123 | 2207 | fprintf(stderr, "qemu: invalid number of network interfaces\n"); |
2124 | 2208 | exit(1); |
2125 | 2209 | } |
2126 | 2210 | break; |
2127 | - case 17: | |
2211 | + case QEMU_OPTION_macaddr: | |
2128 | 2212 | { |
2129 | 2213 | const char *p; |
2130 | 2214 | int i; |
... | ... | @@ -2145,70 +2229,65 @@ int main(int argc, char **argv) |
2145 | 2229 | } |
2146 | 2230 | } |
2147 | 2231 | break; |
2148 | - case 18: | |
2232 | + case QEMU_OPTION_user_net: | |
2149 | 2233 | net_if_type = NET_IF_USER; |
2150 | 2234 | break; |
2151 | - case 19: | |
2235 | + case QEMU_OPTION_dummy_net: | |
2152 | 2236 | net_if_type = NET_IF_DUMMY; |
2153 | 2237 | break; |
2154 | - case 20: | |
2238 | + case QEMU_OPTION_enable_audio: | |
2155 | 2239 | audio_enabled = 1; |
2156 | 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 | 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 | 2262 | for(item = cpu_log_items; item->mask != 0; item++) { |
2181 | 2263 | printf("%-10s %s\n", item->name, item->help); |
2182 | 2264 | } |
2183 | 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 | 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 | 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 | 2291 | linux_boot = (kernel_filename != NULL); |
2213 | 2292 | |
2214 | 2293 | if (!linux_boot && hd_filename[0] == '\0' && hd_filename[2] == '\0' && | ... | ... |