Add option architecture-info to list supported architectures.
[deliverable/binutils-gdb.git] / sim / common / sim-options.c
1 /* Simulator option handling.
2 Copyright (C) 1996, 1997 Free Software Foundation, Inc.
3 Contributed by Cygnus Support.
4
5 This file is part of GDB, the GNU debugger.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License along
18 with this program; if not, write to the Free Software Foundation, Inc.,
19 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
20
21 #include "sim-main.h"
22 #ifdef HAVE_STRING_H
23 #include <string.h>
24 #else
25 #ifdef HAVE_STRINGS_H
26 #include <strings.h>
27 #endif
28 #endif
29 #ifdef HAVE_STDLIB_H
30 #include <stdlib.h>
31 #endif
32 #include <ctype.h>
33 #include "libiberty.h"
34 #include "../libiberty/alloca-conf.h"
35 #include "sim-options.h"
36 #include "sim-io.h"
37 #include "sim-assert.h"
38
39 #include "bfd.h"
40
41 /* Add a set of options to the simulator.
42 TABLE is an array of OPTIONS terminated by a NULL `opt.name' entry.
43 This is intended to be called by modules in their `install' handler. */
44
45 SIM_RC
46 sim_add_option_table (sd, table)
47 SIM_DESC sd;
48 const OPTION *table;
49 {
50 struct option_list *ol = ((struct option_list *)
51 xmalloc (sizeof (struct option_list)));
52
53 /* Note: The list is constructed in the reverse order we're called so
54 later calls will override earlier ones (in case that ever happens).
55 This is the intended behaviour. */
56 ol->next = STATE_OPTIONS (sd);
57 ol->options = table;
58 STATE_OPTIONS (sd) = ol;
59
60 return SIM_RC_OK;
61 }
62
63 /* Standard option table.
64 Modules may specify additional ones.
65 The caller of sim_parse_args may also specify additional options
66 by calling sim_add_option_table first. */
67
68 static DECLARE_OPTION_HANDLER (standard_option_handler);
69
70 /* FIXME: We shouldn't print in --help output options that aren't usable.
71 Some fine tuning will be necessary. One can either move less general
72 options to another table or use a HAVE_FOO macro to ifdef out unavailable
73 options. */
74
75 /* ??? One might want to conditionally compile out the entries that
76 aren't enabled. There's a distinction, however, between options a
77 simulator can't support and options that haven't been configured in.
78 Certainly options a simulator can't support shouldn't appear in the
79 output of --help. Whether the same thing applies to options that haven't
80 been configured in or not isn't something I can get worked up over.
81 [Note that conditionally compiling them out might simply involve moving
82 the option to another table.]
83 If you decide to conditionally compile them out as well, delete this
84 comment and add a comment saying that that is the rule. */
85
86 #define OPTION_DEBUG_INSN (OPTION_START + 0)
87 #define OPTION_DEBUG_FILE (OPTION_START + 1)
88 #define OPTION_DO_COMMAND (OPTION_START + 2)
89 #define OPTION_ARCHITECTURE (OPTION_START + 3)
90 #define OPTION_TARGET (OPTION_START + 4)
91 #define OPTION_ARCHITECTURE_INFO (OPTION_START + 5)
92
93 static const OPTION standard_options[] =
94 {
95 { {"verbose", no_argument, NULL, 'v'},
96 'v', NULL, "Verbose output",
97 standard_option_handler },
98
99 #if defined (SIM_HAVE_BIENDIAN) /* ??? && WITH_TARGET_BYTE_ORDER == 0 */
100 { {"endian", required_argument, NULL, 'E'},
101 'E', "big|little", "Set endianness",
102 standard_option_handler },
103 #endif
104
105 { {"debug", no_argument, NULL, 'D'},
106 'D', NULL, "Print debugging messages",
107 standard_option_handler },
108 { {"debug-insn", no_argument, NULL, OPTION_DEBUG_INSN},
109 '\0', NULL, "Print instruction debugging messages",
110 standard_option_handler },
111 { {"debug-file", required_argument, NULL, OPTION_DEBUG_FILE},
112 '\0', "FILE NAME", "Specify debugging output file",
113 standard_option_handler },
114
115 #ifdef SIM_H8300 /* FIXME: Should be movable to h8300 dir. */
116 { {"h8300h", no_argument, NULL, 'h'},
117 'h', NULL, "Indicate the CPU is h8/300h or h8/300s",
118 standard_option_handler },
119 #endif
120
121 #ifdef SIM_HAVE_FLATMEM
122 { {"mem-size", required_argument, NULL, 'm'},
123 'm', "MEMORY SIZE", "Specify memory size",
124 standard_option_handler },
125 #endif
126
127 { {"do-command", required_argument, NULL, OPTION_DO_COMMAND},
128 '\0', "COMMAND", ""/*undocumented*/,
129 standard_option_handler },
130
131 { {"help", no_argument, NULL, 'H'},
132 'H', NULL, "Print help information",
133 standard_option_handler },
134
135 { {"architecture", required_argument, NULL, OPTION_ARCHITECTURE},
136 '\0', "MACHINE", "Specify the architecture to use",
137 standard_option_handler },
138 { {"architecture-info", no_argument, NULL, OPTION_ARCHITECTURE_INFO},
139 '\0', NULL, "List supported architectures",
140 standard_option_handler },
141 { {"info-architecture", no_argument, NULL, OPTION_ARCHITECTURE_INFO},
142 '\0', NULL, NULL,
143 standard_option_handler },
144
145 { {"target", required_argument, NULL, OPTION_TARGET},
146 '\0', "BFDNAME", "Specify the object-code format for the object files",
147 standard_option_handler },
148
149 { {NULL, no_argument, NULL, 0}, '\0', NULL, NULL, NULL }
150 };
151
152 static SIM_RC
153 standard_option_handler (sd, opt, arg, is_command)
154 SIM_DESC sd;
155 int opt;
156 char *arg;
157 int is_command;
158 {
159 int i,n;
160
161 switch (opt)
162 {
163 case 'v' :
164 STATE_VERBOSE_P (sd) = 1;
165 break;
166
167 #ifdef SIM_HAVE_BIENDIAN
168 case 'E' :
169 if (strcmp (arg, "big") == 0)
170 {
171 if (WITH_TARGET_BYTE_ORDER == LITTLE_ENDIAN)
172 {
173 sim_io_eprintf (sd, "Simulator compiled for little endian only.\n");
174 return SIM_RC_FAIL;
175 }
176 /* FIXME:wip: Need to set something in STATE_CONFIG. */
177 current_target_byte_order = BIG_ENDIAN;
178 }
179 else if (strcmp (arg, "little") == 0)
180 {
181 if (WITH_TARGET_BYTE_ORDER == BIG_ENDIAN)
182 {
183 sim_io_eprintf (sd, "Simulator compiled for big endian only.\n");
184 return SIM_RC_FAIL;
185 }
186 /* FIXME:wip: Need to set something in STATE_CONFIG. */
187 current_target_byte_order = LITTLE_ENDIAN;
188 }
189 else
190 {
191 sim_io_eprintf (sd, "Invalid endian specification `%s'\n", arg);
192 return SIM_RC_FAIL;
193 }
194 break;
195 #endif
196
197 case 'D' :
198 if (! WITH_DEBUG)
199 sim_io_eprintf (sd, "Debugging not compiled in, `-D' ignored\n");
200 else
201 {
202 for (n = 0; n < MAX_NR_PROCESSORS; ++n)
203 for (i = 0; i < MAX_DEBUG_VALUES; ++i)
204 CPU_DEBUG_FLAGS (STATE_CPU (sd, n))[i] = 1;
205 }
206 break;
207
208 case OPTION_DEBUG_INSN :
209 if (! WITH_DEBUG)
210 sim_io_eprintf (sd, "Debugging not compiled in, `--debug-insn' ignored\n");
211 else
212 {
213 for (n = 0; n < MAX_NR_PROCESSORS; ++n)
214 CPU_DEBUG_FLAGS (STATE_CPU (sd, n))[DEBUG_INSN_IDX] = 1;
215 }
216 break;
217
218 case OPTION_DEBUG_FILE :
219 if (! WITH_DEBUG)
220 sim_io_eprintf (sd, "Debugging not compiled in, `--debug-file' ignored\n");
221 else
222 {
223 FILE *f = fopen (arg, "w");
224
225 if (f == NULL)
226 {
227 sim_io_eprintf (sd, "Unable to open debug output file `%s'\n", arg);
228 return SIM_RC_FAIL;
229 }
230 for (n = 0; n < MAX_NR_PROCESSORS; ++n)
231 CPU_DEBUG_FILE (STATE_CPU (sd, n)) = f;
232 }
233 break;
234
235 #ifdef SIM_H8300 /* FIXME: Can be moved to h8300 dir. */
236 case 'h' :
237 set_h8300h (1);
238 break;
239 #endif
240
241 #ifdef SIM_HAVE_FLATMEM
242 case 'm':
243 {
244 unsigned long ul = strtol (arg, NULL, 0);
245 /* 16384: some minimal amount */
246 if (! isdigit (arg[0]) || ul < 16384)
247 {
248 sim_io_eprintf (sd, "Invalid memory size `%s'", arg);
249 return SIM_RC_FAIL;
250 }
251 STATE_MEM_SIZE (sd) = ul;
252 }
253 break;
254 #endif
255
256 case OPTION_DO_COMMAND:
257 sim_do_command (sd, arg);
258 break;
259
260 case OPTION_ARCHITECTURE:
261 {
262 const struct bfd_arch_info *ap = bfd_scan_arch (arg);
263 if (ap == NULL)
264 {
265 sim_io_eprintf (sd, "Architecture `%s' unknown\n", arg);
266 return SIM_RC_FAIL;
267 }
268 STATE_ARCHITECTURE (sd) = ap;
269 break;
270 }
271
272 case OPTION_ARCHITECTURE_INFO:
273 {
274 const char **list = bfd_arch_list();
275 const char **lp;
276 if (list == NULL)
277 abort ();
278 sim_io_printf (sd, "Valid architectures:");
279 for (lp = list; *lp != NULL; lp++)
280 sim_io_printf (sd, " %s", *lp);
281 sim_io_printf (sd, "\n");
282 free (list);
283 break;
284 }
285
286 case OPTION_TARGET:
287 {
288 STATE_TARGET (sd) = xstrdup (arg);
289 break;
290 }
291
292 case 'H':
293 sim_print_help (sd, is_command);
294 if (STATE_OPEN_KIND (sd) == SIM_OPEN_STANDALONE)
295 exit (0);
296 /* FIXME: 'twould be nice to do something similar if gdb. */
297 break;
298 }
299
300 return SIM_RC_OK;
301 }
302
303 /* Add the standard option list to the simulator. */
304
305 SIM_RC
306 standard_install (SIM_DESC sd)
307 {
308 SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
309 if (sim_add_option_table (sd, standard_options) != SIM_RC_OK)
310 return SIM_RC_FAIL;
311 return SIM_RC_OK;
312 }
313
314 /* Return non-zero if arg is a duplicate argument.
315 If ARG is NULL, initialize. */
316
317 #define ARG_HASH_SIZE 97
318 #define ARG_HASH(a) ((256 * (unsigned char) a[0] + (unsigned char) a[1]) % ARG_HASH_SIZE)
319
320 static int
321 dup_arg_p (arg)
322 char *arg;
323 {
324 int hash;
325 static char **arg_table = NULL;
326
327 if (arg == NULL)
328 {
329 if (arg_table == NULL)
330 arg_table = (char **) xmalloc (ARG_HASH_SIZE * sizeof (char *));
331 memset (arg_table, 0, ARG_HASH_SIZE * sizeof (char *));
332 return 0;
333 }
334
335 hash = ARG_HASH (arg);
336 while (arg_table[hash] != NULL)
337 {
338 if (strcmp (arg, arg_table[hash]) == 0)
339 return 1;
340 /* We assume there won't be more than ARG_HASH_SIZE arguments so we
341 don't check if the table is full. */
342 if (++hash == ARG_HASH_SIZE)
343 hash = 0;
344 }
345 arg_table[hash] = arg;
346 return 0;
347 }
348
349 /* Called by sim_open to parse the arguments. */
350
351 SIM_RC
352 sim_parse_args (sd, argv)
353 SIM_DESC sd;
354 char **argv;
355 {
356 int i, argc, num_opts;
357 char *p, *short_options;
358 /* The `val' option struct entry is dynamically assigned for options that
359 only come in the long form. ORIG_VAL is used to get the original value
360 back. */
361 unsigned char *orig_val;
362 struct option *lp, *long_options;
363 const struct option_list *ol;
364 const OPTION *opt;
365 OPTION_HANDLER **handlers;
366
367 /* Count the number of arguments. */
368 for (argc = 0; argv[argc] != NULL; ++argc)
369 continue;
370
371 /* Count the number of options. */
372 num_opts = 0;
373 for (ol = STATE_OPTIONS (sd); ol != NULL; ol = ol->next)
374 for (opt = ol->options; opt->opt.name != NULL; ++opt)
375 ++num_opts;
376
377 /* Initialize duplicate argument checker. */
378 (void) dup_arg_p (NULL);
379
380 /* Build the option table for getopt. */
381 long_options = (struct option *) alloca ((num_opts + 1) * sizeof (struct option));
382 lp = long_options;
383 short_options = (char *) alloca (num_opts * 3 + 1);
384 p = short_options;
385 #if 0 /* ??? necessary anymore? */
386 /* Set '+' as first char so argument permutation isn't done. This is done
387 to workaround a problem with invoking getopt_long in run.c.: optind gets
388 decremented when the program name is reached. */
389 *p++ = '+';
390 #endif
391 handlers = (OPTION_HANDLER **) alloca (256 * sizeof (OPTION_HANDLER *));
392 memset (handlers, 0, 256 * sizeof (OPTION_HANDLER *));
393 orig_val = (unsigned char *) alloca (256);
394 for (i = OPTION_START, ol = STATE_OPTIONS (sd); ol != NULL; ol = ol->next)
395 for (opt = ol->options; opt->opt.name != NULL; ++opt)
396 {
397 if (dup_arg_p (opt->opt.name))
398 continue;
399 if (opt->shortopt != 0)
400 {
401 *p++ = opt->shortopt;
402 if (opt->opt.has_arg == required_argument)
403 *p++ = ':';
404 else if (opt->opt.has_arg == optional_argument)
405 { *p++ = ':'; *p++ = ':'; }
406 }
407 *lp = opt->opt;
408 /* Dynamically assign `val' numbers for long options that don't have
409 a short option equivalent. */
410 if (OPTION_LONG_ONLY_P (opt->opt.val))
411 lp->val = i++;
412 handlers[(unsigned char) lp->val] = opt->handler;
413 orig_val[(unsigned char) lp->val] = opt->opt.val;
414 ++lp;
415 }
416 *p = 0;
417 lp->name = NULL;
418
419 /* Ensure getopt is initialized. */
420 optind = 0;
421 while (1)
422 {
423 int longind, optc;
424
425 optc = getopt_long (argc, argv, short_options, long_options, &longind);
426 if (optc == -1)
427 {
428 if (STATE_OPEN_KIND (sd) == SIM_OPEN_STANDALONE)
429 STATE_PROG_ARGV (sd) = dupargv (argv + optind);
430 break;
431 }
432 if (optc == '?')
433 return SIM_RC_FAIL;
434
435 if ((*handlers[optc]) (sd, orig_val[optc], optarg, 0/*!is_command*/) == SIM_RC_FAIL)
436 return SIM_RC_FAIL;
437 }
438
439 return SIM_RC_OK;
440 }
441
442 /* Print help messages for the options. */
443
444 void
445 sim_print_help (sd, is_command)
446 SIM_DESC sd;
447 int is_command;
448 {
449 const struct option_list *ol;
450 const OPTION *opt;
451
452 if (STATE_OPEN_KIND (sd) == SIM_OPEN_STANDALONE)
453 sim_io_printf (sd, "Usage: %s [options] program [program args]\n",
454 STATE_MY_NAME (sd));
455
456 /* Initialize duplicate argument checker. */
457 (void) dup_arg_p (NULL);
458
459 if (STATE_OPEN_KIND (sd) == SIM_OPEN_STANDALONE)
460 sim_io_printf (sd, "Options:\n");
461 else
462 sim_io_printf (sd, "Commands:\n");
463
464 for (ol = STATE_OPTIONS (sd); ol != NULL; ol = ol->next)
465 for (opt = ol->options; opt->opt.name != NULL; ++opt)
466 {
467 int comma, len;
468 const OPTION *o;
469
470 if (dup_arg_p (opt->opt.name))
471 continue;
472
473 if (opt->doc == NULL)
474 continue;
475
476 if (opt->doc_name != NULL && opt->doc_name [0] == '\0')
477 continue;
478
479 sim_io_printf (sd, " ");
480
481 comma = 0;
482 len = 2;
483
484 if (!is_command)
485 {
486 o = opt;
487 do
488 {
489 if (o->shortopt != '\0')
490 {
491 sim_io_printf (sd, "%s-%c", comma ? ", " : "", o->shortopt);
492 len += (comma ? 2 : 0) + 2;
493 if (o->arg != NULL)
494 {
495 if (o->opt.has_arg == optional_argument)
496 {
497 sim_io_printf (sd, "[%s]", o->arg);
498 len += 1 + strlen (o->arg) + 1;
499 }
500 else
501 {
502 sim_io_printf (sd, " %s", o->arg);
503 len += 1 + strlen (o->arg);
504 }
505 }
506 comma = 1;
507 }
508 ++o;
509 }
510 while (o->opt.name != NULL && o->doc == NULL);
511 }
512
513 o = opt;
514 do
515 {
516 const char *name;
517 if (o->doc_name != NULL)
518 name = o->doc_name;
519 else
520 name = o->opt.name;
521 if (name != NULL)
522 {
523 sim_io_printf (sd, "%s%s%s",
524 comma ? ", " : "",
525 is_command ? "" : "--",
526 name);
527 len += ((comma ? 2 : 0)
528 + (is_command ? 0 : 2)
529 + strlen (name));
530 if (o->arg != NULL)
531 {
532 if (o->opt.has_arg == optional_argument)
533 {
534 sim_io_printf (sd, " [%s]", o->arg);
535 len += 2 + strlen (o->arg) + 1;
536 }
537 else
538 {
539 sim_io_printf (sd, " %s", o->arg);
540 len += 1 + strlen (o->arg);
541 }
542 }
543 comma = 1;
544 }
545 ++o;
546 }
547 while (o->opt.name != NULL && o->doc == NULL);
548
549 if (len >= 30)
550 {
551 sim_io_printf (sd, "\n");
552 len = 0;
553 }
554
555 for (; len < 30; len++)
556 sim_io_printf (sd, " ");
557
558 sim_io_printf (sd, "%s\n", opt->doc);
559 }
560
561 sim_io_printf (sd, "\n");
562 sim_io_printf (sd, "Note: Depending on the simulator configuration some %ss\n",
563 STATE_OPEN_KIND (sd) == SIM_OPEN_STANDALONE ? "option" : "command");
564 sim_io_printf (sd, " may not be applicable\n");
565
566 if (STATE_OPEN_KIND (sd) == SIM_OPEN_STANDALONE)
567 {
568 sim_io_printf (sd, "\n");
569 sim_io_printf (sd, "program args Arguments to pass to simulated program.\n");
570 sim_io_printf (sd, " Note: Very few simulators support this.\n");
571 }
572 }
573
574
575
576
577 SIM_RC
578 sim_args_command (sd, cmd)
579 SIM_DESC sd;
580 char *cmd;
581 {
582 /* something to do? */
583 if (cmd == NULL)
584 return SIM_RC_OK; /* FIXME - perhaphs help would be better */
585
586 if (cmd [0] == '-')
587 {
588 /* user specified -<opt> ... form? */
589 char **argv = buildargv (cmd);
590 SIM_RC rc = sim_parse_args (sd, argv);
591 freeargv (argv);
592 return rc;
593 }
594 else
595 {
596 /* user specified <opt> form? */
597 const struct option_list *ol;
598 const OPTION *opt;
599 char **argv = buildargv (cmd);
600 /* most recent option match */
601 const OPTION *matching_opt = NULL;
602 int matching_argi = -1;
603 if (argv [0] != NULL)
604 for (ol = STATE_OPTIONS (sd); ol != NULL; ol = ol->next)
605 for (opt = ol->options; opt->opt.name != NULL; ++opt)
606 {
607 int argi = 0;
608 const char *name = opt->opt.name;
609 while (strncmp (name, argv [argi], strlen (argv [argi])) == 0)
610 {
611 name = &name [strlen (argv[argi])];
612 if (name [0] == '-')
613 {
614 /* leading match ...<a-b-c>-d-e-f - continue search */
615 name ++; /* skip `-' */
616 argi ++;
617 continue;
618 }
619 else if (name [0] == '\0')
620 {
621 /* exact match ...<a-b-c-d-e-f> - better than before? */
622 if (argi > matching_argi)
623 {
624 matching_argi = argi;
625 matching_opt = opt;
626 }
627 break;
628 }
629 else
630 break;
631 }
632 }
633 if (matching_opt != NULL)
634 {
635 switch (matching_opt->opt.has_arg)
636 {
637 case no_argument:
638 if (argv [matching_argi + 1] == NULL)
639 matching_opt->handler (sd, matching_opt->opt.val,
640 NULL, 1/*is_command*/);
641 else
642 sim_io_eprintf (sd, "Command `%s' takes no arguments\n",
643 matching_opt->opt.name);
644 break;
645 case optional_argument:
646 if (argv [matching_argi + 1] == NULL)
647 matching_opt->handler (sd, matching_opt->opt.val,
648 NULL, 1/*is_command*/);
649 else if (argv [matching_argi + 2] == NULL)
650 matching_opt->handler (sd, matching_opt->opt.val,
651 argv [matching_argi + 1], 1/*is_command*/);
652 else
653 sim_io_eprintf (sd, "Command `%s' requires no more than one argument\n",
654 matching_opt->opt.name);
655 break;
656 case required_argument:
657 if (argv [matching_argi + 1] == NULL)
658 sim_io_eprintf (sd, "Command `%s' requires an argument\n",
659 matching_opt->opt.name);
660 else if (argv [matching_argi + 2] == NULL)
661 matching_opt->handler (sd, matching_opt->opt.val,
662 argv [matching_argi + 1], 1/*is_command*/);
663 else
664 sim_io_eprintf (sd, "Command `%s' requires only one argument\n",
665 matching_opt->opt.name);
666 }
667 return SIM_RC_OK;
668 }
669 }
670
671 /* didn't find anything that remotly matched */
672 return SIM_RC_FAIL;
673 }
This page took 0.044581 seconds and 4 git commands to generate.