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