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