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:
		
							parent
							
								
									b939777cec
								
							
						
					
					
						commit
						cd6f11693a
					
				
							
								
								
									
										273
									
								
								vl.c
									
									
									
									
									
								
							
							
						
						
									
										273
									
								
								vl.c
									
									
									
									
									
								
							| @ -23,7 +23,6 @@ | ||||
|  */ | ||||
| #include "vl.h" | ||||
| 
 | ||||
| #include <getopt.h> | ||||
| #include <unistd.h> | ||||
| #include <fcntl.h> | ||||
| #include <signal.h> | ||||
| @ -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' && | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 bellard
						bellard