sim-options.c revision 1.5 1 1.1 christos /* Simulator option handling.
2 1.3 christos Copyright (C) 1996-2015 Free Software Foundation, Inc.
3 1.1 christos Contributed by Cygnus Support.
4 1.1 christos
5 1.1 christos This file is part of GDB, the GNU debugger.
6 1.1 christos
7 1.1 christos This program is free software; you can redistribute it and/or modify
8 1.1 christos it under the terms of the GNU General Public License as published by
9 1.1 christos the Free Software Foundation; either version 3 of the License, or
10 1.1 christos (at your option) any later version.
11 1.1 christos
12 1.1 christos This program is distributed in the hope that it will be useful,
13 1.1 christos but WITHOUT ANY WARRANTY; without even the implied warranty of
14 1.1 christos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 1.1 christos GNU General Public License for more details.
16 1.1 christos
17 1.1 christos You should have received a copy of the GNU General Public License
18 1.1 christos along with this program. If not, see <http://www.gnu.org/licenses/>. */
19 1.1 christos
20 1.1 christos #include "sim-main.h"
21 1.1 christos #ifdef HAVE_STRING_H
22 1.1 christos #include <string.h>
23 1.1 christos #else
24 1.1 christos #ifdef HAVE_STRINGS_H
25 1.1 christos #include <strings.h>
26 1.1 christos #endif
27 1.1 christos #endif
28 1.1 christos #ifdef HAVE_STDLIB_H
29 1.1 christos #include <stdlib.h>
30 1.1 christos #endif
31 1.1 christos #include <ctype.h>
32 1.1 christos #include "libiberty.h"
33 1.1 christos #include "sim-options.h"
34 1.1 christos #include "sim-io.h"
35 1.1 christos #include "sim-assert.h"
36 1.5 christos #include "version.h"
37 1.1 christos
38 1.1 christos #include "bfd.h"
39 1.1 christos
40 1.1 christos /* Add a set of options to the simulator.
41 1.1 christos TABLE is an array of OPTIONS terminated by a NULL `opt.name' entry.
42 1.1 christos This is intended to be called by modules in their `install' handler. */
43 1.1 christos
44 1.1 christos SIM_RC
45 1.1 christos sim_add_option_table (SIM_DESC sd, sim_cpu *cpu, const OPTION *table)
46 1.1 christos {
47 1.1 christos struct option_list *ol = ((struct option_list *)
48 1.1 christos xmalloc (sizeof (struct option_list)));
49 1.1 christos
50 1.1 christos /* Note: The list is constructed in the reverse order we're called so
51 1.1 christos later calls will override earlier ones (in case that ever happens).
52 1.1 christos This is the intended behaviour. */
53 1.1 christos
54 1.1 christos if (cpu)
55 1.1 christos {
56 1.1 christos ol->next = CPU_OPTIONS (cpu);
57 1.1 christos ol->options = table;
58 1.1 christos CPU_OPTIONS (cpu) = ol;
59 1.1 christos }
60 1.1 christos else
61 1.1 christos {
62 1.1 christos ol->next = STATE_OPTIONS (sd);
63 1.1 christos ol->options = table;
64 1.1 christos STATE_OPTIONS (sd) = ol;
65 1.1 christos }
66 1.1 christos
67 1.1 christos return SIM_RC_OK;
68 1.1 christos }
69 1.1 christos
70 1.1 christos /* Standard option table.
71 1.1 christos Modules may specify additional ones.
72 1.1 christos The caller of sim_parse_args may also specify additional options
73 1.1 christos by calling sim_add_option_table first. */
74 1.1 christos
75 1.1 christos static DECLARE_OPTION_HANDLER (standard_option_handler);
76 1.1 christos
77 1.1 christos /* FIXME: We shouldn't print in --help output options that aren't usable.
78 1.1 christos Some fine tuning will be necessary. One can either move less general
79 1.1 christos options to another table or use a HAVE_FOO macro to ifdef out unavailable
80 1.1 christos options. */
81 1.1 christos
82 1.1 christos /* ??? One might want to conditionally compile out the entries that
83 1.1 christos aren't enabled. There's a distinction, however, between options a
84 1.1 christos simulator can't support and options that haven't been configured in.
85 1.1 christos Certainly options a simulator can't support shouldn't appear in the
86 1.1 christos output of --help. Whether the same thing applies to options that haven't
87 1.1 christos been configured in or not isn't something I can get worked up over.
88 1.1 christos [Note that conditionally compiling them out might simply involve moving
89 1.1 christos the option to another table.]
90 1.1 christos If you decide to conditionally compile them out as well, delete this
91 1.1 christos comment and add a comment saying that that is the rule. */
92 1.1 christos
93 1.1 christos typedef enum {
94 1.1 christos OPTION_DEBUG_INSN = OPTION_START,
95 1.1 christos OPTION_DEBUG_FILE,
96 1.1 christos OPTION_DO_COMMAND,
97 1.1 christos OPTION_ARCHITECTURE,
98 1.1 christos OPTION_TARGET,
99 1.1 christos OPTION_ARCHITECTURE_INFO,
100 1.1 christos OPTION_ENVIRONMENT,
101 1.1 christos OPTION_ALIGNMENT,
102 1.1 christos OPTION_VERBOSE,
103 1.1 christos OPTION_ENDIAN,
104 1.1 christos OPTION_DEBUG,
105 1.1 christos #ifdef SIM_HAVE_FLATMEM
106 1.1 christos OPTION_MEM_SIZE,
107 1.1 christos #endif
108 1.1 christos OPTION_HELP,
109 1.5 christos OPTION_VERSION,
110 1.1 christos #ifdef SIM_H8300 /* FIXME: Should be movable to h8300 dir. */
111 1.1 christos OPTION_H8300H,
112 1.1 christos OPTION_H8300S,
113 1.1 christos OPTION_H8300SX,
114 1.1 christos #endif
115 1.1 christos OPTION_LOAD_LMA,
116 1.1 christos OPTION_LOAD_VMA,
117 1.1 christos OPTION_SYSROOT
118 1.1 christos } STANDARD_OPTIONS;
119 1.1 christos
120 1.1 christos static const OPTION standard_options[] =
121 1.1 christos {
122 1.1 christos { {"verbose", no_argument, NULL, OPTION_VERBOSE},
123 1.1 christos 'v', NULL, "Verbose output",
124 1.1 christos standard_option_handler, NULL },
125 1.1 christos
126 1.1 christos { {"endian", required_argument, NULL, OPTION_ENDIAN},
127 1.1 christos 'E', "big|little", "Set endianness",
128 1.1 christos standard_option_handler, NULL },
129 1.1 christos
130 1.1 christos #ifdef SIM_HAVE_ENVIRONMENT
131 1.1 christos /* This option isn't supported unless all choices are supported in keeping
132 1.1 christos with the goal of not printing in --help output things the simulator can't
133 1.1 christos do [as opposed to things that just haven't been configured in]. */
134 1.1 christos { {"environment", required_argument, NULL, OPTION_ENVIRONMENT},
135 1.1 christos '\0', "user|virtual|operating", "Set running environment",
136 1.1 christos standard_option_handler },
137 1.1 christos #endif
138 1.1 christos
139 1.1 christos { {"alignment", required_argument, NULL, OPTION_ALIGNMENT},
140 1.1 christos '\0', "strict|nonstrict|forced", "Set memory access alignment",
141 1.1 christos standard_option_handler },
142 1.1 christos
143 1.1 christos { {"debug", no_argument, NULL, OPTION_DEBUG},
144 1.1 christos 'D', NULL, "Print debugging messages",
145 1.1 christos standard_option_handler },
146 1.1 christos { {"debug-insn", no_argument, NULL, OPTION_DEBUG_INSN},
147 1.1 christos '\0', NULL, "Print instruction debugging messages",
148 1.1 christos standard_option_handler },
149 1.1 christos { {"debug-file", required_argument, NULL, OPTION_DEBUG_FILE},
150 1.1 christos '\0', "FILE NAME", "Specify debugging output file",
151 1.1 christos standard_option_handler },
152 1.1 christos
153 1.1 christos #ifdef SIM_H8300 /* FIXME: Should be movable to h8300 dir. */
154 1.1 christos { {"h8300h", no_argument, NULL, OPTION_H8300H},
155 1.1 christos 'h', NULL, "Indicate the CPU is H8/300H",
156 1.1 christos standard_option_handler },
157 1.1 christos { {"h8300s", no_argument, NULL, OPTION_H8300S},
158 1.1 christos 'S', NULL, "Indicate the CPU is H8S",
159 1.1 christos standard_option_handler },
160 1.1 christos { {"h8300sx", no_argument, NULL, OPTION_H8300SX},
161 1.1 christos 'x', NULL, "Indicate the CPU is H8SX",
162 1.1 christos standard_option_handler },
163 1.1 christos #endif
164 1.1 christos
165 1.1 christos #ifdef SIM_HAVE_FLATMEM
166 1.1 christos { {"mem-size", required_argument, NULL, OPTION_MEM_SIZE},
167 1.1 christos 'm', "<size>[in bytes, Kb (k suffix), Mb (m suffix) or Gb (g suffix)]",
168 1.1 christos "Specify memory size", standard_option_handler },
169 1.1 christos #endif
170 1.1 christos
171 1.1 christos { {"do-command", required_argument, NULL, OPTION_DO_COMMAND},
172 1.1 christos '\0', "COMMAND", ""/*undocumented*/,
173 1.1 christos standard_option_handler },
174 1.1 christos
175 1.1 christos { {"help", no_argument, NULL, OPTION_HELP},
176 1.1 christos 'H', NULL, "Print help information",
177 1.1 christos standard_option_handler },
178 1.5 christos { {"version", no_argument, NULL, OPTION_VERSION},
179 1.5 christos '\0', NULL, "Print version information",
180 1.5 christos standard_option_handler },
181 1.1 christos
182 1.1 christos { {"architecture", required_argument, NULL, OPTION_ARCHITECTURE},
183 1.1 christos '\0', "MACHINE", "Specify the architecture to use",
184 1.1 christos standard_option_handler },
185 1.1 christos { {"architecture-info", no_argument, NULL, OPTION_ARCHITECTURE_INFO},
186 1.1 christos '\0', NULL, "List supported architectures",
187 1.1 christos standard_option_handler },
188 1.1 christos { {"info-architecture", no_argument, NULL, OPTION_ARCHITECTURE_INFO},
189 1.1 christos '\0', NULL, NULL,
190 1.1 christos standard_option_handler },
191 1.1 christos
192 1.1 christos { {"target", required_argument, NULL, OPTION_TARGET},
193 1.1 christos '\0', "BFDNAME", "Specify the object-code format for the object files",
194 1.1 christos standard_option_handler },
195 1.1 christos
196 1.1 christos #ifdef SIM_HANDLES_LMA
197 1.1 christos { {"load-lma", no_argument, NULL, OPTION_LOAD_LMA},
198 1.1 christos '\0', NULL,
199 1.1 christos #if SIM_HANDLES_LMA
200 1.1 christos "Use VMA or LMA addresses when loading image (default LMA)",
201 1.1 christos #else
202 1.1 christos "Use VMA or LMA addresses when loading image (default VMA)",
203 1.1 christos #endif
204 1.1 christos standard_option_handler, "load-{lma,vma}" },
205 1.1 christos { {"load-vma", no_argument, NULL, OPTION_LOAD_VMA},
206 1.1 christos '\0', NULL, "", standard_option_handler, "" },
207 1.1 christos #endif
208 1.1 christos
209 1.1 christos { {"sysroot", required_argument, NULL, OPTION_SYSROOT},
210 1.1 christos '\0', "SYSROOT",
211 1.1 christos "Root for system calls with absolute file-names and cwd at start",
212 1.1 christos standard_option_handler, NULL },
213 1.1 christos
214 1.1 christos { {NULL, no_argument, NULL, 0}, '\0', NULL, NULL, NULL, NULL }
215 1.1 christos };
216 1.1 christos
217 1.1 christos static SIM_RC
218 1.1 christos standard_option_handler (SIM_DESC sd, sim_cpu *cpu, int opt,
219 1.1 christos char *arg, int is_command)
220 1.1 christos {
221 1.1 christos int i,n;
222 1.1 christos
223 1.1 christos switch ((STANDARD_OPTIONS) opt)
224 1.1 christos {
225 1.1 christos case OPTION_VERBOSE:
226 1.1 christos STATE_VERBOSE_P (sd) = 1;
227 1.1 christos break;
228 1.1 christos
229 1.1 christos case OPTION_ENDIAN:
230 1.1 christos if (strcmp (arg, "big") == 0)
231 1.1 christos {
232 1.1 christos if (WITH_TARGET_BYTE_ORDER == LITTLE_ENDIAN)
233 1.1 christos {
234 1.1 christos sim_io_eprintf (sd, "Simulator compiled for little endian only.\n");
235 1.1 christos return SIM_RC_FAIL;
236 1.1 christos }
237 1.1 christos /* FIXME:wip: Need to set something in STATE_CONFIG. */
238 1.1 christos current_target_byte_order = BIG_ENDIAN;
239 1.1 christos }
240 1.1 christos else if (strcmp (arg, "little") == 0)
241 1.1 christos {
242 1.1 christos if (WITH_TARGET_BYTE_ORDER == BIG_ENDIAN)
243 1.1 christos {
244 1.1 christos sim_io_eprintf (sd, "Simulator compiled for big endian only.\n");
245 1.1 christos return SIM_RC_FAIL;
246 1.1 christos }
247 1.1 christos /* FIXME:wip: Need to set something in STATE_CONFIG. */
248 1.1 christos current_target_byte_order = LITTLE_ENDIAN;
249 1.1 christos }
250 1.1 christos else
251 1.1 christos {
252 1.1 christos sim_io_eprintf (sd, "Invalid endian specification `%s'\n", arg);
253 1.1 christos return SIM_RC_FAIL;
254 1.1 christos }
255 1.1 christos break;
256 1.1 christos
257 1.1 christos case OPTION_ENVIRONMENT:
258 1.1 christos if (strcmp (arg, "user") == 0)
259 1.1 christos STATE_ENVIRONMENT (sd) = USER_ENVIRONMENT;
260 1.1 christos else if (strcmp (arg, "virtual") == 0)
261 1.1 christos STATE_ENVIRONMENT (sd) = VIRTUAL_ENVIRONMENT;
262 1.1 christos else if (strcmp (arg, "operating") == 0)
263 1.1 christos STATE_ENVIRONMENT (sd) = OPERATING_ENVIRONMENT;
264 1.1 christos else
265 1.1 christos {
266 1.1 christos sim_io_eprintf (sd, "Invalid environment specification `%s'\n", arg);
267 1.1 christos return SIM_RC_FAIL;
268 1.1 christos }
269 1.1 christos if (WITH_ENVIRONMENT != ALL_ENVIRONMENT
270 1.1 christos && WITH_ENVIRONMENT != STATE_ENVIRONMENT (sd))
271 1.1 christos {
272 1.1 christos const char *type;
273 1.1 christos switch (WITH_ENVIRONMENT)
274 1.1 christos {
275 1.1 christos case USER_ENVIRONMENT: type = "user"; break;
276 1.1 christos case VIRTUAL_ENVIRONMENT: type = "virtual"; break;
277 1.1 christos case OPERATING_ENVIRONMENT: type = "operating"; break;
278 1.1 christos }
279 1.1 christos sim_io_eprintf (sd, "Simulator compiled for the %s environment only.\n",
280 1.1 christos type);
281 1.1 christos return SIM_RC_FAIL;
282 1.1 christos }
283 1.1 christos break;
284 1.1 christos
285 1.1 christos case OPTION_ALIGNMENT:
286 1.1 christos if (strcmp (arg, "strict") == 0)
287 1.1 christos {
288 1.1 christos if (WITH_ALIGNMENT == 0 || WITH_ALIGNMENT == STRICT_ALIGNMENT)
289 1.1 christos {
290 1.1 christos current_alignment = STRICT_ALIGNMENT;
291 1.1 christos break;
292 1.1 christos }
293 1.1 christos }
294 1.1 christos else if (strcmp (arg, "nonstrict") == 0)
295 1.1 christos {
296 1.1 christos if (WITH_ALIGNMENT == 0 || WITH_ALIGNMENT == NONSTRICT_ALIGNMENT)
297 1.1 christos {
298 1.1 christos current_alignment = NONSTRICT_ALIGNMENT;
299 1.1 christos break;
300 1.1 christos }
301 1.1 christos }
302 1.1 christos else if (strcmp (arg, "forced") == 0)
303 1.1 christos {
304 1.1 christos if (WITH_ALIGNMENT == 0 || WITH_ALIGNMENT == FORCED_ALIGNMENT)
305 1.1 christos {
306 1.1 christos current_alignment = FORCED_ALIGNMENT;
307 1.1 christos break;
308 1.1 christos }
309 1.1 christos }
310 1.1 christos else
311 1.1 christos {
312 1.1 christos sim_io_eprintf (sd, "Invalid alignment specification `%s'\n", arg);
313 1.1 christos return SIM_RC_FAIL;
314 1.1 christos }
315 1.1 christos switch (WITH_ALIGNMENT)
316 1.1 christos {
317 1.1 christos case STRICT_ALIGNMENT:
318 1.1 christos sim_io_eprintf (sd, "Simulator compiled for strict alignment only.\n");
319 1.1 christos break;
320 1.1 christos case NONSTRICT_ALIGNMENT:
321 1.1 christos sim_io_eprintf (sd, "Simulator compiled for nonstrict alignment only.\n");
322 1.1 christos break;
323 1.1 christos case FORCED_ALIGNMENT:
324 1.1 christos sim_io_eprintf (sd, "Simulator compiled for forced alignment only.\n");
325 1.1 christos break;
326 1.1 christos }
327 1.1 christos return SIM_RC_FAIL;
328 1.1 christos
329 1.1 christos case OPTION_DEBUG:
330 1.1 christos if (! WITH_DEBUG)
331 1.1 christos sim_io_eprintf (sd, "Debugging not compiled in, `-D' ignored\n");
332 1.1 christos else
333 1.1 christos {
334 1.1 christos for (n = 0; n < MAX_NR_PROCESSORS; ++n)
335 1.1 christos for (i = 0; i < MAX_DEBUG_VALUES; ++i)
336 1.1 christos CPU_DEBUG_FLAGS (STATE_CPU (sd, n))[i] = 1;
337 1.1 christos }
338 1.1 christos break;
339 1.1 christos
340 1.1 christos case OPTION_DEBUG_INSN :
341 1.1 christos if (! WITH_DEBUG)
342 1.1 christos sim_io_eprintf (sd, "Debugging not compiled in, `--debug-insn' ignored\n");
343 1.1 christos else
344 1.1 christos {
345 1.1 christos for (n = 0; n < MAX_NR_PROCESSORS; ++n)
346 1.1 christos CPU_DEBUG_FLAGS (STATE_CPU (sd, n))[DEBUG_INSN_IDX] = 1;
347 1.1 christos }
348 1.1 christos break;
349 1.1 christos
350 1.1 christos case OPTION_DEBUG_FILE :
351 1.1 christos if (! WITH_DEBUG)
352 1.1 christos sim_io_eprintf (sd, "Debugging not compiled in, `--debug-file' ignored\n");
353 1.1 christos else
354 1.1 christos {
355 1.1 christos FILE *f = fopen (arg, "w");
356 1.1 christos
357 1.1 christos if (f == NULL)
358 1.1 christos {
359 1.1 christos sim_io_eprintf (sd, "Unable to open debug output file `%s'\n", arg);
360 1.1 christos return SIM_RC_FAIL;
361 1.1 christos }
362 1.1 christos for (n = 0; n < MAX_NR_PROCESSORS; ++n)
363 1.1 christos CPU_DEBUG_FILE (STATE_CPU (sd, n)) = f;
364 1.1 christos }
365 1.1 christos break;
366 1.1 christos
367 1.1 christos #ifdef SIM_H8300 /* FIXME: Can be moved to h8300 dir. */
368 1.1 christos case OPTION_H8300H:
369 1.1 christos set_h8300h (bfd_mach_h8300h);
370 1.1 christos break;
371 1.1 christos case OPTION_H8300S:
372 1.1 christos set_h8300h (bfd_mach_h8300s);
373 1.1 christos break;
374 1.1 christos case OPTION_H8300SX:
375 1.1 christos set_h8300h (bfd_mach_h8300sx);
376 1.1 christos break;
377 1.1 christos #endif
378 1.1 christos
379 1.1 christos #ifdef SIM_HAVE_FLATMEM
380 1.1 christos case OPTION_MEM_SIZE:
381 1.1 christos {
382 1.1 christos char * endp;
383 1.1 christos unsigned long ul = strtol (arg, &endp, 0);
384 1.1 christos
385 1.1 christos switch (* endp)
386 1.1 christos {
387 1.1 christos case 'k': case 'K': size <<= 10; break;
388 1.1 christos case 'm': case 'M': size <<= 20; break;
389 1.1 christos case 'g': case 'G': size <<= 30; break;
390 1.1 christos case ' ': case '\0': case '\t': break;
391 1.1 christos default:
392 1.1 christos if (ul > 0)
393 1.1 christos sim_io_eprintf (sd, "Ignoring strange character at end of memory size: %c\n", * endp);
394 1.1 christos break;
395 1.1 christos }
396 1.1 christos
397 1.1 christos /* 16384: some minimal amount */
398 1.1 christos if (! isdigit (arg[0]) || ul < 16384)
399 1.1 christos {
400 1.1 christos sim_io_eprintf (sd, "Invalid memory size `%s'", arg);
401 1.1 christos return SIM_RC_FAIL;
402 1.1 christos }
403 1.1 christos STATE_MEM_SIZE (sd) = ul;
404 1.1 christos }
405 1.1 christos break;
406 1.1 christos #endif
407 1.1 christos
408 1.1 christos case OPTION_DO_COMMAND:
409 1.1 christos sim_do_command (sd, arg);
410 1.1 christos break;
411 1.1 christos
412 1.1 christos case OPTION_ARCHITECTURE:
413 1.1 christos {
414 1.1 christos const struct bfd_arch_info *ap = bfd_scan_arch (arg);
415 1.1 christos if (ap == NULL)
416 1.1 christos {
417 1.1 christos sim_io_eprintf (sd, "Architecture `%s' unknown\n", arg);
418 1.1 christos return SIM_RC_FAIL;
419 1.1 christos }
420 1.1 christos STATE_ARCHITECTURE (sd) = ap;
421 1.1 christos break;
422 1.1 christos }
423 1.1 christos
424 1.1 christos case OPTION_ARCHITECTURE_INFO:
425 1.1 christos {
426 1.1 christos const char **list = bfd_arch_list ();
427 1.1 christos const char **lp;
428 1.1 christos if (list == NULL)
429 1.1 christos abort ();
430 1.1 christos sim_io_printf (sd, "Possible architectures:");
431 1.1 christos for (lp = list; *lp != NULL; lp++)
432 1.1 christos sim_io_printf (sd, " %s", *lp);
433 1.1 christos sim_io_printf (sd, "\n");
434 1.1 christos free (list);
435 1.1 christos break;
436 1.1 christos }
437 1.1 christos
438 1.1 christos case OPTION_TARGET:
439 1.1 christos {
440 1.1 christos STATE_TARGET (sd) = xstrdup (arg);
441 1.1 christos break;
442 1.1 christos }
443 1.1 christos
444 1.1 christos case OPTION_LOAD_LMA:
445 1.1 christos {
446 1.1 christos STATE_LOAD_AT_LMA_P (sd) = 1;
447 1.1 christos break;
448 1.1 christos }
449 1.1 christos
450 1.1 christos case OPTION_LOAD_VMA:
451 1.1 christos {
452 1.1 christos STATE_LOAD_AT_LMA_P (sd) = 0;
453 1.1 christos break;
454 1.1 christos }
455 1.1 christos
456 1.1 christos case OPTION_HELP:
457 1.1 christos sim_print_help (sd, is_command);
458 1.1 christos if (STATE_OPEN_KIND (sd) == SIM_OPEN_STANDALONE)
459 1.1 christos exit (0);
460 1.1 christos /* FIXME: 'twould be nice to do something similar if gdb. */
461 1.1 christos break;
462 1.1 christos
463 1.5 christos case OPTION_VERSION:
464 1.5 christos sim_io_printf (sd, "GNU simulator %s%s\n", PKGVERSION, version);
465 1.5 christos if (STATE_OPEN_KIND (sd) == SIM_OPEN_STANDALONE)
466 1.5 christos exit (0);
467 1.5 christos break;
468 1.5 christos
469 1.1 christos case OPTION_SYSROOT:
470 1.1 christos /* Don't leak memory in the odd event that there's lots of
471 1.1 christos --sysroot=... options. We treat "" specially since this
472 1.1 christos is the statically initialized value and cannot free it. */
473 1.1 christos if (simulator_sysroot[0] != '\0')
474 1.1 christos free (simulator_sysroot);
475 1.1 christos if (arg[0] != '\0')
476 1.1 christos simulator_sysroot = xstrdup (arg);
477 1.1 christos else
478 1.1 christos simulator_sysroot = "";
479 1.1 christos break;
480 1.1 christos }
481 1.1 christos
482 1.1 christos return SIM_RC_OK;
483 1.1 christos }
484 1.1 christos
485 1.1 christos /* Add the standard option list to the simulator. */
486 1.1 christos
487 1.1 christos SIM_RC
488 1.1 christos standard_install (SIM_DESC sd)
489 1.1 christos {
490 1.1 christos SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
491 1.1 christos if (sim_add_option_table (sd, NULL, standard_options) != SIM_RC_OK)
492 1.1 christos return SIM_RC_FAIL;
493 1.1 christos #ifdef SIM_HANDLES_LMA
494 1.1 christos STATE_LOAD_AT_LMA_P (sd) = SIM_HANDLES_LMA;
495 1.1 christos #endif
496 1.1 christos return SIM_RC_OK;
497 1.1 christos }
498 1.1 christos
499 1.1 christos /* Return non-zero if arg is a duplicate argument.
500 1.1 christos If ARG is NULL, initialize. */
501 1.1 christos
502 1.1 christos #define ARG_HASH_SIZE 97
503 1.1 christos #define ARG_HASH(a) ((256 * (unsigned char) a[0] + (unsigned char) a[1]) % ARG_HASH_SIZE)
504 1.1 christos
505 1.1 christos static int
506 1.1 christos dup_arg_p (const char *arg)
507 1.1 christos {
508 1.1 christos int hash;
509 1.1 christos static const char **arg_table = NULL;
510 1.1 christos
511 1.1 christos if (arg == NULL)
512 1.1 christos {
513 1.1 christos if (arg_table == NULL)
514 1.1 christos arg_table = (const char **) xmalloc (ARG_HASH_SIZE * sizeof (char *));
515 1.1 christos memset (arg_table, 0, ARG_HASH_SIZE * sizeof (char *));
516 1.1 christos return 0;
517 1.1 christos }
518 1.1 christos
519 1.1 christos hash = ARG_HASH (arg);
520 1.1 christos while (arg_table[hash] != NULL)
521 1.1 christos {
522 1.1 christos if (strcmp (arg, arg_table[hash]) == 0)
523 1.1 christos return 1;
524 1.1 christos /* We assume there won't be more than ARG_HASH_SIZE arguments so we
525 1.1 christos don't check if the table is full. */
526 1.1 christos if (++hash == ARG_HASH_SIZE)
527 1.1 christos hash = 0;
528 1.1 christos }
529 1.1 christos arg_table[hash] = arg;
530 1.1 christos return 0;
531 1.1 christos }
532 1.1 christos
533 1.1 christos /* Called by sim_open to parse the arguments. */
534 1.1 christos
535 1.1 christos SIM_RC
536 1.1 christos sim_parse_args (SIM_DESC sd, char **argv)
537 1.1 christos {
538 1.1 christos int c, i, argc, num_opts;
539 1.1 christos char *p, *short_options;
540 1.1 christos /* The `val' option struct entry is dynamically assigned for options that
541 1.1 christos only come in the long form. ORIG_VAL is used to get the original value
542 1.1 christos back. */
543 1.1 christos int *orig_val;
544 1.1 christos struct option *lp, *long_options;
545 1.1 christos const struct option_list *ol;
546 1.1 christos const OPTION *opt;
547 1.1 christos OPTION_HANDLER **handlers;
548 1.1 christos sim_cpu **opt_cpu;
549 1.1 christos SIM_RC result = SIM_RC_OK;
550 1.1 christos
551 1.1 christos /* Count the number of arguments. */
552 1.1 christos for (argc = 0; argv[argc] != NULL; ++argc)
553 1.1 christos continue;
554 1.1 christos
555 1.1 christos /* Count the number of options. */
556 1.1 christos num_opts = 0;
557 1.1 christos for (ol = STATE_OPTIONS (sd); ol != NULL; ol = ol->next)
558 1.1 christos for (opt = ol->options; OPTION_VALID_P (opt); ++opt)
559 1.1 christos ++num_opts;
560 1.1 christos for (i = 0; i < MAX_NR_PROCESSORS; ++i)
561 1.1 christos for (ol = CPU_OPTIONS (STATE_CPU (sd, i)); ol != NULL; ol = ol->next)
562 1.1 christos for (opt = ol->options; OPTION_VALID_P (opt); ++opt)
563 1.1 christos ++num_opts;
564 1.1 christos
565 1.1 christos /* Initialize duplicate argument checker. */
566 1.1 christos (void) dup_arg_p (NULL);
567 1.1 christos
568 1.1 christos /* Build the option table for getopt. */
569 1.1 christos
570 1.1 christos long_options = NZALLOC (struct option, num_opts + 1);
571 1.1 christos lp = long_options;
572 1.1 christos short_options = NZALLOC (char, num_opts * 3 + 1);
573 1.1 christos p = short_options;
574 1.1 christos handlers = NZALLOC (OPTION_HANDLER *, OPTION_START + num_opts);
575 1.1 christos orig_val = NZALLOC (int, OPTION_START + num_opts);
576 1.1 christos opt_cpu = NZALLOC (sim_cpu *, OPTION_START + num_opts);
577 1.1 christos
578 1.1 christos /* Set '+' as first char so argument permutation isn't done. This
579 1.1 christos is done to stop getopt_long returning options that appear after
580 1.1 christos the target program. Such options should be passed unchanged into
581 1.1 christos the program image. */
582 1.1 christos *p++ = '+';
583 1.1 christos
584 1.1 christos for (i = OPTION_START, ol = STATE_OPTIONS (sd); ol != NULL; ol = ol->next)
585 1.1 christos for (opt = ol->options; OPTION_VALID_P (opt); ++opt)
586 1.1 christos {
587 1.1 christos if (dup_arg_p (opt->opt.name))
588 1.1 christos continue;
589 1.1 christos if (opt->shortopt != 0)
590 1.1 christos {
591 1.1 christos *p++ = opt->shortopt;
592 1.1 christos if (opt->opt.has_arg == required_argument)
593 1.1 christos *p++ = ':';
594 1.1 christos else if (opt->opt.has_arg == optional_argument)
595 1.1 christos { *p++ = ':'; *p++ = ':'; }
596 1.1 christos handlers[(unsigned char) opt->shortopt] = opt->handler;
597 1.1 christos if (opt->opt.val != 0)
598 1.1 christos orig_val[(unsigned char) opt->shortopt] = opt->opt.val;
599 1.1 christos else
600 1.1 christos orig_val[(unsigned char) opt->shortopt] = opt->shortopt;
601 1.1 christos }
602 1.1 christos if (opt->opt.name != NULL)
603 1.1 christos {
604 1.1 christos *lp = opt->opt;
605 1.1 christos /* Dynamically assign `val' numbers for long options. */
606 1.1 christos lp->val = i++;
607 1.1 christos handlers[lp->val] = opt->handler;
608 1.1 christos orig_val[lp->val] = opt->opt.val;
609 1.1 christos opt_cpu[lp->val] = NULL;
610 1.1 christos ++lp;
611 1.1 christos }
612 1.1 christos }
613 1.1 christos
614 1.1 christos for (c = 0; c < MAX_NR_PROCESSORS; ++c)
615 1.1 christos {
616 1.1 christos sim_cpu *cpu = STATE_CPU (sd, c);
617 1.1 christos for (ol = CPU_OPTIONS (cpu); ol != NULL; ol = ol->next)
618 1.1 christos for (opt = ol->options; OPTION_VALID_P (opt); ++opt)
619 1.1 christos {
620 1.1 christos #if 0 /* Each option is prepended with --<cpuname>- so this greatly cuts down
621 1.1 christos on the need for dup_arg_p checking. Maybe in the future it'll be
622 1.1 christos needed so this is just commented out, and not deleted. */
623 1.1 christos if (dup_arg_p (opt->opt.name))
624 1.1 christos continue;
625 1.1 christos #endif
626 1.1 christos /* Don't allow short versions of cpu specific options for now. */
627 1.1 christos if (opt->shortopt != 0)
628 1.1 christos {
629 1.1 christos sim_io_eprintf (sd, "internal error, short cpu specific option");
630 1.1 christos result = SIM_RC_FAIL;
631 1.1 christos break;
632 1.1 christos }
633 1.1 christos if (opt->opt.name != NULL)
634 1.1 christos {
635 1.1 christos char *name;
636 1.1 christos *lp = opt->opt;
637 1.1 christos /* Prepend --<cpuname>- to the option. */
638 1.1 christos if (asprintf (&name, "%s-%s", CPU_NAME (cpu), lp->name) < 0)
639 1.1 christos {
640 1.1 christos sim_io_eprintf (sd, "internal error, out of memory");
641 1.1 christos result = SIM_RC_FAIL;
642 1.1 christos break;
643 1.1 christos }
644 1.1 christos lp->name = name;
645 1.1 christos /* Dynamically assign `val' numbers for long options. */
646 1.1 christos lp->val = i++;
647 1.1 christos handlers[lp->val] = opt->handler;
648 1.1 christos orig_val[lp->val] = opt->opt.val;
649 1.1 christos opt_cpu[lp->val] = cpu;
650 1.1 christos ++lp;
651 1.1 christos }
652 1.1 christos }
653 1.1 christos }
654 1.1 christos
655 1.1 christos /* Terminate the short and long option lists. */
656 1.1 christos *p = 0;
657 1.1 christos lp->name = NULL;
658 1.1 christos
659 1.1 christos /* Ensure getopt is initialized. */
660 1.1 christos optind = 0;
661 1.1 christos
662 1.1 christos while (1)
663 1.1 christos {
664 1.1 christos int longind, optc;
665 1.1 christos
666 1.1 christos optc = getopt_long (argc, argv, short_options, long_options, &longind);
667 1.1 christos if (optc == -1)
668 1.1 christos {
669 1.1 christos if (STATE_OPEN_KIND (sd) == SIM_OPEN_STANDALONE)
670 1.1 christos STATE_PROG_ARGV (sd) = dupargv (argv + optind);
671 1.1 christos break;
672 1.1 christos }
673 1.1 christos if (optc == '?')
674 1.1 christos {
675 1.1 christos result = SIM_RC_FAIL;
676 1.1 christos break;
677 1.1 christos }
678 1.1 christos
679 1.1 christos if ((*handlers[optc]) (sd, opt_cpu[optc], orig_val[optc], optarg, 0/*!is_command*/) == SIM_RC_FAIL)
680 1.1 christos {
681 1.1 christos result = SIM_RC_FAIL;
682 1.1 christos break;
683 1.1 christos }
684 1.1 christos }
685 1.1 christos
686 1.1 christos free (long_options);
687 1.1 christos free (short_options);
688 1.1 christos free (handlers);
689 1.1 christos free (opt_cpu);
690 1.1 christos free (orig_val);
691 1.1 christos return result;
692 1.1 christos }
693 1.1 christos
694 1.1 christos /* Utility of sim_print_help to print a list of option tables. */
695 1.1 christos
696 1.1 christos static void
697 1.1 christos print_help (SIM_DESC sd, sim_cpu *cpu, const struct option_list *ol, int is_command)
698 1.1 christos {
699 1.1 christos const OPTION *opt;
700 1.1 christos
701 1.1 christos for ( ; ol != NULL; ol = ol->next)
702 1.1 christos for (opt = ol->options; OPTION_VALID_P (opt); ++opt)
703 1.1 christos {
704 1.1 christos const int indent = 30;
705 1.1 christos int comma, len;
706 1.1 christos const OPTION *o;
707 1.1 christos
708 1.1 christos if (dup_arg_p (opt->opt.name))
709 1.1 christos continue;
710 1.1 christos
711 1.1 christos if (opt->doc == NULL)
712 1.1 christos continue;
713 1.1 christos
714 1.1 christos if (opt->doc_name != NULL && opt->doc_name [0] == '\0')
715 1.1 christos continue;
716 1.1 christos
717 1.1 christos sim_io_printf (sd, " ");
718 1.1 christos
719 1.1 christos comma = 0;
720 1.1 christos len = 2;
721 1.1 christos
722 1.1 christos /* list any short options (aliases) for the current OPT */
723 1.1 christos if (!is_command)
724 1.1 christos {
725 1.1 christos o = opt;
726 1.1 christos do
727 1.1 christos {
728 1.1 christos if (o->shortopt != '\0')
729 1.1 christos {
730 1.1 christos sim_io_printf (sd, "%s-%c", comma ? ", " : "", o->shortopt);
731 1.1 christos len += (comma ? 2 : 0) + 2;
732 1.1 christos if (o->arg != NULL)
733 1.1 christos {
734 1.1 christos if (o->opt.has_arg == optional_argument)
735 1.1 christos {
736 1.1 christos sim_io_printf (sd, "[%s]", o->arg);
737 1.1 christos len += 1 + strlen (o->arg) + 1;
738 1.1 christos }
739 1.1 christos else
740 1.1 christos {
741 1.1 christos sim_io_printf (sd, " %s", o->arg);
742 1.1 christos len += 1 + strlen (o->arg);
743 1.1 christos }
744 1.1 christos }
745 1.1 christos comma = 1;
746 1.1 christos }
747 1.1 christos ++o;
748 1.1 christos }
749 1.1 christos while (OPTION_VALID_P (o) && o->doc == NULL);
750 1.1 christos }
751 1.1 christos
752 1.1 christos /* list any long options (aliases) for the current OPT */
753 1.1 christos o = opt;
754 1.1 christos do
755 1.1 christos {
756 1.1 christos const char *name;
757 1.1 christos const char *cpu_prefix = cpu ? CPU_NAME (cpu) : NULL;
758 1.1 christos if (o->doc_name != NULL)
759 1.1 christos name = o->doc_name;
760 1.1 christos else
761 1.1 christos name = o->opt.name;
762 1.1 christos if (name != NULL)
763 1.1 christos {
764 1.1 christos sim_io_printf (sd, "%s%s%s%s%s",
765 1.1 christos comma ? ", " : "",
766 1.1 christos is_command ? "" : "--",
767 1.1 christos cpu ? cpu_prefix : "",
768 1.1 christos cpu ? "-" : "",
769 1.1 christos name);
770 1.1 christos len += ((comma ? 2 : 0)
771 1.1 christos + (is_command ? 0 : 2)
772 1.1 christos + strlen (name));
773 1.1 christos if (o->arg != NULL)
774 1.1 christos {
775 1.1 christos if (o->opt.has_arg == optional_argument)
776 1.1 christos {
777 1.1 christos sim_io_printf (sd, "[=%s]", o->arg);
778 1.1 christos len += 2 + strlen (o->arg) + 1;
779 1.1 christos }
780 1.1 christos else
781 1.1 christos {
782 1.1 christos sim_io_printf (sd, " %s", o->arg);
783 1.1 christos len += 1 + strlen (o->arg);
784 1.1 christos }
785 1.1 christos }
786 1.1 christos comma = 1;
787 1.1 christos }
788 1.1 christos ++o;
789 1.1 christos }
790 1.1 christos while (OPTION_VALID_P (o) && o->doc == NULL);
791 1.1 christos
792 1.1 christos if (len >= indent)
793 1.1 christos {
794 1.1 christos sim_io_printf (sd, "\n%*s", indent, "");
795 1.1 christos }
796 1.1 christos else
797 1.1 christos sim_io_printf (sd, "%*s", indent - len, "");
798 1.1 christos
799 1.1 christos /* print the description, word wrap long lines */
800 1.1 christos {
801 1.1 christos const char *chp = opt->doc;
802 1.1 christos unsigned doc_width = 80 - indent;
803 1.1 christos while (strlen (chp) >= doc_width) /* some slack */
804 1.1 christos {
805 1.1 christos const char *end = chp + doc_width - 1;
806 1.1 christos while (end > chp && !isspace (*end))
807 1.1 christos end --;
808 1.1 christos if (end == chp)
809 1.1 christos end = chp + doc_width - 1;
810 1.1 christos /* The cast should be ok - its distances between to
811 1.1 christos points in a string. */
812 1.1 christos sim_io_printf (sd, "%.*s\n%*s", (int) (end - chp), chp, indent,
813 1.1 christos "");
814 1.1 christos chp = end;
815 1.1 christos while (isspace (*chp) && *chp != '\0')
816 1.1 christos chp++;
817 1.1 christos }
818 1.1 christos sim_io_printf (sd, "%s\n", chp);
819 1.1 christos }
820 1.1 christos }
821 1.1 christos }
822 1.1 christos
823 1.1 christos /* Print help messages for the options. */
824 1.1 christos
825 1.1 christos void
826 1.1 christos sim_print_help (SIM_DESC sd, int is_command)
827 1.1 christos {
828 1.1 christos if (STATE_OPEN_KIND (sd) == SIM_OPEN_STANDALONE)
829 1.1 christos sim_io_printf (sd, "Usage: %s [options] program [program args]\n",
830 1.1 christos STATE_MY_NAME (sd));
831 1.1 christos
832 1.1 christos /* Initialize duplicate argument checker. */
833 1.1 christos (void) dup_arg_p (NULL);
834 1.1 christos
835 1.1 christos if (STATE_OPEN_KIND (sd) == SIM_OPEN_STANDALONE)
836 1.1 christos sim_io_printf (sd, "Options:\n");
837 1.1 christos else
838 1.1 christos sim_io_printf (sd, "Commands:\n");
839 1.1 christos
840 1.1 christos print_help (sd, NULL, STATE_OPTIONS (sd), is_command);
841 1.1 christos sim_io_printf (sd, "\n");
842 1.1 christos
843 1.1 christos /* Print cpu-specific options. */
844 1.1 christos {
845 1.1 christos int i;
846 1.1 christos
847 1.1 christos for (i = 0; i < MAX_NR_PROCESSORS; ++i)
848 1.1 christos {
849 1.1 christos sim_cpu *cpu = STATE_CPU (sd, i);
850 1.1 christos if (CPU_OPTIONS (cpu) == NULL)
851 1.1 christos continue;
852 1.1 christos sim_io_printf (sd, "CPU %s specific options:\n", CPU_NAME (cpu));
853 1.1 christos print_help (sd, cpu, CPU_OPTIONS (cpu), is_command);
854 1.1 christos sim_io_printf (sd, "\n");
855 1.1 christos }
856 1.1 christos }
857 1.1 christos
858 1.1 christos sim_io_printf (sd, "Note: Depending on the simulator configuration some %ss\n",
859 1.1 christos STATE_OPEN_KIND (sd) == SIM_OPEN_STANDALONE ? "option" : "command");
860 1.1 christos sim_io_printf (sd, " may not be applicable\n");
861 1.1 christos
862 1.1 christos if (STATE_OPEN_KIND (sd) == SIM_OPEN_STANDALONE)
863 1.1 christos {
864 1.1 christos sim_io_printf (sd, "\n");
865 1.1 christos sim_io_printf (sd, "program args Arguments to pass to simulated program.\n");
866 1.1 christos sim_io_printf (sd, " Note: Very few simulators support this.\n");
867 1.1 christos }
868 1.1 christos }
869 1.1 christos
870 1.1 christos /* Utility of sim_args_command to find the closest match for a command.
871 1.1 christos Commands that have "-" in them can be specified as separate words.
872 1.1 christos e.g. sim memory-region 0x800000,0x4000
873 1.1 christos or sim memory region 0x800000,0x4000
874 1.1 christos If CPU is non-null, use its option table list, otherwise use the main one.
875 1.1 christos *PARGI is where to start looking in ARGV. It is updated to point past
876 1.1 christos the found option. */
877 1.1 christos
878 1.1 christos static const OPTION *
879 1.1 christos find_match (SIM_DESC sd, sim_cpu *cpu, char *argv[], int *pargi)
880 1.1 christos {
881 1.1 christos const struct option_list *ol;
882 1.1 christos const OPTION *opt;
883 1.1 christos /* most recent option match */
884 1.1 christos const OPTION *matching_opt = NULL;
885 1.1 christos int matching_argi = -1;
886 1.1 christos
887 1.1 christos if (cpu)
888 1.1 christos ol = CPU_OPTIONS (cpu);
889 1.1 christos else
890 1.1 christos ol = STATE_OPTIONS (sd);
891 1.1 christos
892 1.1 christos /* Skip passed elements specified by *PARGI. */
893 1.1 christos argv += *pargi;
894 1.1 christos
895 1.1 christos for ( ; ol != NULL; ol = ol->next)
896 1.1 christos for (opt = ol->options; OPTION_VALID_P (opt); ++opt)
897 1.1 christos {
898 1.1 christos int argi = 0;
899 1.1 christos const char *name = opt->opt.name;
900 1.1 christos if (name == NULL)
901 1.1 christos continue;
902 1.1 christos while (argv [argi] != NULL
903 1.1 christos && strncmp (name, argv [argi], strlen (argv [argi])) == 0)
904 1.1 christos {
905 1.1 christos name = &name [strlen (argv[argi])];
906 1.1 christos if (name [0] == '-')
907 1.1 christos {
908 1.1 christos /* leading match ...<a-b-c>-d-e-f - continue search */
909 1.1 christos name ++; /* skip `-' */
910 1.1 christos argi ++;
911 1.1 christos continue;
912 1.1 christos }
913 1.1 christos else if (name [0] == '\0')
914 1.1 christos {
915 1.1 christos /* exact match ...<a-b-c-d-e-f> - better than before? */
916 1.1 christos if (argi > matching_argi)
917 1.1 christos {
918 1.1 christos matching_argi = argi;
919 1.1 christos matching_opt = opt;
920 1.1 christos }
921 1.1 christos break;
922 1.1 christos }
923 1.1 christos else
924 1.1 christos break;
925 1.1 christos }
926 1.1 christos }
927 1.1 christos
928 1.1 christos *pargi = matching_argi;
929 1.1 christos return matching_opt;
930 1.1 christos }
931 1.1 christos
932 1.1 christos static char **
933 1.1 christos complete_option_list (char **ret, size_t *cnt, const struct option_list *ol,
934 1.1 christos const char *text, const char *word)
935 1.1 christos {
936 1.1 christos const OPTION *opt = NULL;
937 1.1 christos int argi;
938 1.1 christos size_t len = strlen (word);
939 1.1 christos
940 1.1 christos for ( ; ol != NULL; ol = ol->next)
941 1.1 christos for (opt = ol->options; OPTION_VALID_P (opt); ++opt)
942 1.1 christos {
943 1.1 christos const char *name = opt->opt.name;
944 1.1 christos
945 1.1 christos /* A long option to match against? */
946 1.1 christos if (!name)
947 1.1 christos continue;
948 1.1 christos
949 1.1 christos /* Does this option actually match? */
950 1.1 christos if (strncmp (name, word, len))
951 1.1 christos continue;
952 1.1 christos
953 1.1 christos ret = xrealloc (ret, ++*cnt * sizeof (ret[0]));
954 1.1 christos ret[*cnt - 2] = xstrdup (name);
955 1.1 christos }
956 1.1 christos
957 1.1 christos return ret;
958 1.1 christos }
959 1.1 christos
960 1.1 christos /* All leading text is stored in @text, while the current word being
961 1.1 christos completed is stored in @word. Trailing text of @word is not. */
962 1.1 christos
963 1.1 christos char **
964 1.1 christos sim_complete_command (SIM_DESC sd, const char *text, const char *word)
965 1.1 christos {
966 1.1 christos char **ret = NULL;
967 1.1 christos size_t cnt = 1;
968 1.1 christos sim_cpu *cpu;
969 1.1 christos
970 1.1 christos /* Only complete first word for now. */
971 1.1 christos if (text != word)
972 1.1 christos return ret;
973 1.1 christos
974 1.1 christos cpu = STATE_CPU (sd, 0);
975 1.1 christos if (cpu)
976 1.1 christos ret = complete_option_list (ret, &cnt, CPU_OPTIONS (cpu), text, word);
977 1.1 christos ret = complete_option_list (ret, &cnt, STATE_OPTIONS (sd), text, word);
978 1.1 christos
979 1.1 christos if (ret)
980 1.1 christos ret[cnt - 1] = NULL;
981 1.1 christos return ret;
982 1.1 christos }
983 1.1 christos
984 1.1 christos SIM_RC
985 1.3 christos sim_args_command (SIM_DESC sd, const char *cmd)
986 1.1 christos {
987 1.1 christos /* something to do? */
988 1.1 christos if (cmd == NULL)
989 1.1 christos return SIM_RC_OK; /* FIXME - perhaps help would be better */
990 1.1 christos
991 1.1 christos if (cmd [0] == '-')
992 1.1 christos {
993 1.1 christos /* user specified -<opt> ... form? */
994 1.1 christos char **argv = buildargv (cmd);
995 1.1 christos SIM_RC rc = sim_parse_args (sd, argv);
996 1.1 christos freeargv (argv);
997 1.1 christos return rc;
998 1.1 christos }
999 1.1 christos else
1000 1.1 christos {
1001 1.1 christos char **argv = buildargv (cmd);
1002 1.1 christos const OPTION *matching_opt = NULL;
1003 1.1 christos int matching_argi;
1004 1.1 christos sim_cpu *cpu;
1005 1.1 christos
1006 1.1 christos if (argv [0] == NULL)
1007 1.5 christos {
1008 1.5 christos freeargv (argv);
1009 1.5 christos return SIM_RC_OK; /* FIXME - perhaps help would be better */
1010 1.5 christos }
1011 1.1 christos
1012 1.1 christos /* First check for a cpu selector. */
1013 1.1 christos {
1014 1.1 christos char *cpu_name = xstrdup (argv[0]);
1015 1.1 christos char *hyphen = strchr (cpu_name, '-');
1016 1.1 christos if (hyphen)
1017 1.1 christos *hyphen = 0;
1018 1.1 christos cpu = sim_cpu_lookup (sd, cpu_name);
1019 1.1 christos if (cpu)
1020 1.1 christos {
1021 1.1 christos /* If <cpuname>-<command>, point argv[0] at <command>. */
1022 1.1 christos if (hyphen)
1023 1.1 christos {
1024 1.1 christos matching_argi = 0;
1025 1.1 christos argv[0] += hyphen - cpu_name + 1;
1026 1.1 christos }
1027 1.1 christos else
1028 1.1 christos matching_argi = 1;
1029 1.1 christos matching_opt = find_match (sd, cpu, argv, &matching_argi);
1030 1.1 christos /* If hyphen found restore argv[0]. */
1031 1.1 christos if (hyphen)
1032 1.1 christos argv[0] -= hyphen - cpu_name + 1;
1033 1.1 christos }
1034 1.1 christos free (cpu_name);
1035 1.1 christos }
1036 1.1 christos
1037 1.1 christos /* If that failed, try the main table. */
1038 1.1 christos if (matching_opt == NULL)
1039 1.1 christos {
1040 1.1 christos matching_argi = 0;
1041 1.1 christos matching_opt = find_match (sd, NULL, argv, &matching_argi);
1042 1.1 christos }
1043 1.1 christos
1044 1.1 christos if (matching_opt != NULL)
1045 1.1 christos {
1046 1.1 christos switch (matching_opt->opt.has_arg)
1047 1.1 christos {
1048 1.1 christos case no_argument:
1049 1.1 christos if (argv [matching_argi + 1] == NULL)
1050 1.1 christos matching_opt->handler (sd, cpu, matching_opt->opt.val,
1051 1.1 christos NULL, 1/*is_command*/);
1052 1.1 christos else
1053 1.1 christos sim_io_eprintf (sd, "Command `%s' takes no arguments\n",
1054 1.1 christos matching_opt->opt.name);
1055 1.1 christos break;
1056 1.1 christos case optional_argument:
1057 1.1 christos if (argv [matching_argi + 1] == NULL)
1058 1.1 christos matching_opt->handler (sd, cpu, matching_opt->opt.val,
1059 1.1 christos NULL, 1/*is_command*/);
1060 1.1 christos else if (argv [matching_argi + 2] == NULL)
1061 1.1 christos matching_opt->handler (sd, cpu, matching_opt->opt.val,
1062 1.1 christos argv [matching_argi + 1], 1/*is_command*/);
1063 1.1 christos else
1064 1.1 christos sim_io_eprintf (sd, "Command `%s' requires no more than one argument\n",
1065 1.1 christos matching_opt->opt.name);
1066 1.1 christos break;
1067 1.1 christos case required_argument:
1068 1.1 christos if (argv [matching_argi + 1] == NULL)
1069 1.1 christos sim_io_eprintf (sd, "Command `%s' requires an argument\n",
1070 1.1 christos matching_opt->opt.name);
1071 1.1 christos else if (argv [matching_argi + 2] == NULL)
1072 1.1 christos matching_opt->handler (sd, cpu, matching_opt->opt.val,
1073 1.1 christos argv [matching_argi + 1], 1/*is_command*/);
1074 1.1 christos else
1075 1.1 christos sim_io_eprintf (sd, "Command `%s' requires only one argument\n",
1076 1.1 christos matching_opt->opt.name);
1077 1.1 christos }
1078 1.1 christos freeargv (argv);
1079 1.1 christos return SIM_RC_OK;
1080 1.1 christos }
1081 1.1 christos
1082 1.1 christos freeargv (argv);
1083 1.1 christos }
1084 1.1 christos
1085 1.1 christos /* didn't find anything that remotly matched */
1086 1.1 christos return SIM_RC_FAIL;
1087 1.1 christos }
1088