Commit cd6f11693a3c0438fefd86af0a10b57b59d19369

Authored by bellard
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
... ... @@ -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' &&
... ...