1 /* Simulator option handling.
2 Copyright (C) 1996-2021 Free Software Foundation, Inc.
3 Contributed by Cygnus Support.
5 This file is part of GDB, the GNU debugger.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
26 #include "libiberty.h"
27 #include "sim-options.h"
29 #include "sim-assert.h"
35 /* Add a set of options to the simulator.
36 TABLE is an array of OPTIONS terminated by a NULL `opt.name' entry.
37 This is intended to be called by modules in their `install' handler. */
40 sim_add_option_table (SIM_DESC sd
, sim_cpu
*cpu
, const OPTION
*table
)
42 struct option_list
*ol
= ((struct option_list
*)
43 xmalloc (sizeof (struct option_list
)));
45 /* Note: The list is constructed in the reverse order we're called so
46 later calls will override earlier ones (in case that ever happens).
47 This is the intended behaviour. */
51 ol
->next
= CPU_OPTIONS (cpu
);
53 CPU_OPTIONS (cpu
) = ol
;
57 ol
->next
= STATE_OPTIONS (sd
);
59 STATE_OPTIONS (sd
) = ol
;
65 /* Standard option table.
66 Modules may specify additional ones.
67 The caller of sim_parse_args may also specify additional options
68 by calling sim_add_option_table first. */
70 static DECLARE_OPTION_HANDLER (standard_option_handler
);
72 /* FIXME: We shouldn't print in --help output options that aren't usable.
73 Some fine tuning will be necessary. One can either move less general
74 options to another table or use a HAVE_FOO macro to ifdef out unavailable
77 /* ??? One might want to conditionally compile out the entries that
78 aren't enabled. There's a distinction, however, between options a
79 simulator can't support and options that haven't been configured in.
80 Certainly options a simulator can't support shouldn't appear in the
81 output of --help. Whether the same thing applies to options that haven't
82 been configured in or not isn't something I can get worked up over.
83 [Note that conditionally compiling them out might simply involve moving
84 the option to another table.]
85 If you decide to conditionally compile them out as well, delete this
86 comment and add a comment saying that that is the rule. */
89 OPTION_DEBUG_INSN
= OPTION_START
,
94 OPTION_ARCHITECTURE_INFO
,
107 static const OPTION standard_options
[] =
109 { {"verbose", no_argument
, NULL
, OPTION_VERBOSE
},
110 'v', NULL
, "Verbose output",
111 standard_option_handler
, NULL
},
113 { {"endian", required_argument
, NULL
, OPTION_ENDIAN
},
114 'E', "big|little", "Set endianness",
115 standard_option_handler
, NULL
},
117 /* This option isn't supported unless all choices are supported in keeping
118 with the goal of not printing in --help output things the simulator can't
119 do [as opposed to things that just haven't been configured in]. */
120 { {"environment", required_argument
, NULL
, OPTION_ENVIRONMENT
},
121 '\0', "user|virtual|operating", "Set running environment",
122 standard_option_handler
},
124 { {"alignment", required_argument
, NULL
, OPTION_ALIGNMENT
},
125 '\0', "strict|nonstrict|forced", "Set memory access alignment",
126 standard_option_handler
},
128 { {"debug", no_argument
, NULL
, OPTION_DEBUG
},
129 'D', NULL
, "Print debugging messages",
130 standard_option_handler
},
131 { {"debug-insn", no_argument
, NULL
, OPTION_DEBUG_INSN
},
132 '\0', NULL
, "Print instruction debugging messages",
133 standard_option_handler
},
134 { {"debug-file", required_argument
, NULL
, OPTION_DEBUG_FILE
},
135 '\0', "FILE NAME", "Specify debugging output file",
136 standard_option_handler
},
138 { {"do-command", required_argument
, NULL
, OPTION_DO_COMMAND
},
139 '\0', "COMMAND", ""/*undocumented*/,
140 standard_option_handler
},
142 { {"help", no_argument
, NULL
, OPTION_HELP
},
143 'H', NULL
, "Print help information",
144 standard_option_handler
},
145 { {"version", no_argument
, NULL
, OPTION_VERSION
},
146 '\0', NULL
, "Print version information",
147 standard_option_handler
},
149 { {"architecture", required_argument
, NULL
, OPTION_ARCHITECTURE
},
150 '\0', "MACHINE", "Specify the architecture to use",
151 standard_option_handler
},
152 { {"architecture-info", no_argument
, NULL
, OPTION_ARCHITECTURE_INFO
},
153 '\0', NULL
, "List supported architectures",
154 standard_option_handler
},
155 { {"info-architecture", no_argument
, NULL
, OPTION_ARCHITECTURE_INFO
},
157 standard_option_handler
},
159 { {"target", required_argument
, NULL
, OPTION_TARGET
},
160 '\0', "BFDNAME", "Specify the object-code format for the object files",
161 standard_option_handler
},
163 { {"load-lma", no_argument
, NULL
, OPTION_LOAD_LMA
},
165 "Use VMA or LMA addresses when loading image (default LMA)",
166 standard_option_handler
, "load-{lma,vma}" },
167 { {"load-vma", no_argument
, NULL
, OPTION_LOAD_VMA
},
168 '\0', NULL
, "", standard_option_handler
, "" },
170 { {"sysroot", required_argument
, NULL
, OPTION_SYSROOT
},
172 "Root for system calls with absolute file-names and cwd at start",
173 standard_option_handler
, NULL
},
175 { {NULL
, no_argument
, NULL
, 0}, '\0', NULL
, NULL
, NULL
, NULL
}
179 standard_option_handler (SIM_DESC sd
, sim_cpu
*cpu
, int opt
,
180 char *arg
, int is_command
)
184 switch ((STANDARD_OPTIONS
) opt
)
187 STATE_VERBOSE_P (sd
) = 1;
191 if (strcmp (arg
, "big") == 0)
193 if (WITH_TARGET_BYTE_ORDER
== BFD_ENDIAN_LITTLE
)
195 sim_io_eprintf (sd
, "Simulator compiled for little endian only.\n");
198 /* FIXME:wip: Need to set something in STATE_CONFIG. */
199 current_target_byte_order
= BFD_ENDIAN_BIG
;
201 else if (strcmp (arg
, "little") == 0)
203 if (WITH_TARGET_BYTE_ORDER
== BFD_ENDIAN_BIG
)
205 sim_io_eprintf (sd
, "Simulator compiled for big endian only.\n");
208 /* FIXME:wip: Need to set something in STATE_CONFIG. */
209 current_target_byte_order
= BFD_ENDIAN_LITTLE
;
213 sim_io_eprintf (sd
, "Invalid endian specification `%s'\n", arg
);
218 case OPTION_ENVIRONMENT
:
219 if (strcmp (arg
, "user") == 0)
220 STATE_ENVIRONMENT (sd
) = USER_ENVIRONMENT
;
221 else if (strcmp (arg
, "virtual") == 0)
222 STATE_ENVIRONMENT (sd
) = VIRTUAL_ENVIRONMENT
;
223 else if (strcmp (arg
, "operating") == 0)
224 STATE_ENVIRONMENT (sd
) = OPERATING_ENVIRONMENT
;
227 sim_io_eprintf (sd
, "Invalid environment specification `%s'\n", arg
);
230 if (WITH_ENVIRONMENT
!= ALL_ENVIRONMENT
231 && WITH_ENVIRONMENT
!= STATE_ENVIRONMENT (sd
))
234 switch (WITH_ENVIRONMENT
)
236 case USER_ENVIRONMENT
: type
= "user"; break;
237 case VIRTUAL_ENVIRONMENT
: type
= "virtual"; break;
238 case OPERATING_ENVIRONMENT
: type
= "operating"; break;
240 sim_io_eprintf (sd
, "Simulator compiled for the %s environment only.\n",
246 case OPTION_ALIGNMENT
:
247 if (strcmp (arg
, "strict") == 0)
249 if (WITH_ALIGNMENT
== 0 || WITH_ALIGNMENT
== STRICT_ALIGNMENT
)
251 current_alignment
= STRICT_ALIGNMENT
;
255 else if (strcmp (arg
, "nonstrict") == 0)
257 if (WITH_ALIGNMENT
== 0 || WITH_ALIGNMENT
== NONSTRICT_ALIGNMENT
)
259 current_alignment
= NONSTRICT_ALIGNMENT
;
263 else if (strcmp (arg
, "forced") == 0)
265 if (WITH_ALIGNMENT
== 0 || WITH_ALIGNMENT
== FORCED_ALIGNMENT
)
267 current_alignment
= FORCED_ALIGNMENT
;
273 sim_io_eprintf (sd
, "Invalid alignment specification `%s'\n", arg
);
276 switch (WITH_ALIGNMENT
)
278 case STRICT_ALIGNMENT
:
279 sim_io_eprintf (sd
, "Simulator compiled for strict alignment only.\n");
281 case NONSTRICT_ALIGNMENT
:
282 sim_io_eprintf (sd
, "Simulator compiled for nonstrict alignment only.\n");
284 case FORCED_ALIGNMENT
:
285 sim_io_eprintf (sd
, "Simulator compiled for forced alignment only.\n");
292 sim_io_eprintf (sd
, "Debugging not compiled in, `-D' ignored\n");
295 for (n
= 0; n
< MAX_NR_PROCESSORS
; ++n
)
296 for (i
= 0; i
< MAX_DEBUG_VALUES
; ++i
)
297 CPU_DEBUG_FLAGS (STATE_CPU (sd
, n
))[i
] = 1;
301 case OPTION_DEBUG_INSN
:
303 sim_io_eprintf (sd
, "Debugging not compiled in, `--debug-insn' ignored\n");
306 for (n
= 0; n
< MAX_NR_PROCESSORS
; ++n
)
307 CPU_DEBUG_FLAGS (STATE_CPU (sd
, n
))[DEBUG_INSN_IDX
] = 1;
311 case OPTION_DEBUG_FILE
:
313 sim_io_eprintf (sd
, "Debugging not compiled in, `--debug-file' ignored\n");
316 FILE *f
= fopen (arg
, "w");
320 sim_io_eprintf (sd
, "Unable to open debug output file `%s'\n", arg
);
323 for (n
= 0; n
< MAX_NR_PROCESSORS
; ++n
)
324 CPU_DEBUG_FILE (STATE_CPU (sd
, n
)) = f
;
328 case OPTION_DO_COMMAND
:
329 sim_do_command (sd
, arg
);
332 case OPTION_ARCHITECTURE
:
334 const struct bfd_arch_info
*ap
= bfd_scan_arch (arg
);
337 sim_io_eprintf (sd
, "Architecture `%s' unknown\n", arg
);
340 STATE_ARCHITECTURE (sd
) = ap
;
344 case OPTION_ARCHITECTURE_INFO
:
346 const char **list
= bfd_arch_list ();
350 sim_io_printf (sd
, "Possible architectures:");
351 for (lp
= list
; *lp
!= NULL
; lp
++)
352 sim_io_printf (sd
, " %s", *lp
);
353 sim_io_printf (sd
, "\n");
360 STATE_TARGET (sd
) = xstrdup (arg
);
364 case OPTION_LOAD_LMA
:
366 STATE_LOAD_AT_LMA_P (sd
) = 1;
370 case OPTION_LOAD_VMA
:
372 STATE_LOAD_AT_LMA_P (sd
) = 0;
377 sim_print_help (sd
, is_command
);
378 if (STATE_OPEN_KIND (sd
) == SIM_OPEN_STANDALONE
)
380 /* FIXME: 'twould be nice to do something similar if gdb. */
384 sim_print_version (sd
, is_command
);
385 if (STATE_OPEN_KIND (sd
) == SIM_OPEN_STANDALONE
)
390 /* Don't leak memory in the odd event that there's lots of
391 --sysroot=... options. We treat "" specially since this
392 is the statically initialized value and cannot free it. */
393 if (simulator_sysroot
[0] != '\0')
394 free (simulator_sysroot
);
396 simulator_sysroot
= xstrdup (arg
);
398 simulator_sysroot
= "";
405 /* Add the standard option list to the simulator. */
408 standard_install (SIM_DESC sd
)
410 SIM_ASSERT (STATE_MAGIC (sd
) == SIM_MAGIC_NUMBER
);
411 if (sim_add_option_table (sd
, NULL
, standard_options
) != SIM_RC_OK
)
413 STATE_LOAD_AT_LMA_P (sd
) = 1;
417 /* Equality function for arguments. */
420 compare_strings (const void *a
, const void *b
)
422 return strcmp (a
, b
) == 0;
425 /* Return non-zero if arg is a duplicate argument.
426 If ARG is NULL, initialize. */
429 dup_arg_p (const char *arg
)
431 static htab_t arg_table
= NULL
;
436 if (arg_table
== NULL
)
437 arg_table
= htab_create_alloc (10, htab_hash_string
,
438 compare_strings
, NULL
,
440 htab_empty (arg_table
);
444 slot
= htab_find_slot (arg_table
, arg
, INSERT
);
447 *slot
= (void *) arg
;
451 /* Called by sim_open to parse the arguments. */
454 sim_parse_args (SIM_DESC sd
, char * const *argv
)
456 int c
, i
, argc
, num_opts
, save_opterr
;
457 char *p
, *short_options
;
458 /* The `val' option struct entry is dynamically assigned for options that
459 only come in the long form. ORIG_VAL is used to get the original value
462 struct option
*lp
, *long_options
;
463 const struct option_list
*ol
;
465 OPTION_HANDLER
**handlers
;
467 SIM_RC result
= SIM_RC_OK
;
469 /* Count the number of arguments. */
470 argc
= countargv (argv
);
472 /* Count the number of options. */
474 for (ol
= STATE_OPTIONS (sd
); ol
!= NULL
; ol
= ol
->next
)
475 for (opt
= ol
->options
; OPTION_VALID_P (opt
); ++opt
)
477 for (i
= 0; i
< MAX_NR_PROCESSORS
; ++i
)
478 for (ol
= CPU_OPTIONS (STATE_CPU (sd
, i
)); ol
!= NULL
; ol
= ol
->next
)
479 for (opt
= ol
->options
; OPTION_VALID_P (opt
); ++opt
)
482 /* Initialize duplicate argument checker. */
483 (void) dup_arg_p (NULL
);
485 /* Build the option table for getopt. */
487 long_options
= NZALLOC (struct option
, num_opts
+ 1);
489 short_options
= NZALLOC (char, num_opts
* 3 + 1);
491 handlers
= NZALLOC (OPTION_HANDLER
*, OPTION_START
+ num_opts
);
492 orig_val
= NZALLOC (int, OPTION_START
+ num_opts
);
493 opt_cpu
= NZALLOC (sim_cpu
*, OPTION_START
+ num_opts
);
495 /* Set '+' as first char so argument permutation isn't done. This
496 is done to stop getopt_long returning options that appear after
497 the target program. Such options should be passed unchanged into
498 the program image. */
501 for (i
= OPTION_START
, ol
= STATE_OPTIONS (sd
); ol
!= NULL
; ol
= ol
->next
)
502 for (opt
= ol
->options
; OPTION_VALID_P (opt
); ++opt
)
504 if (dup_arg_p (opt
->opt
.name
))
506 if (opt
->shortopt
!= 0)
508 *p
++ = opt
->shortopt
;
509 if (opt
->opt
.has_arg
== required_argument
)
511 else if (opt
->opt
.has_arg
== optional_argument
)
512 { *p
++ = ':'; *p
++ = ':'; }
513 handlers
[(unsigned char) opt
->shortopt
] = opt
->handler
;
514 if (opt
->opt
.val
!= 0)
515 orig_val
[(unsigned char) opt
->shortopt
] = opt
->opt
.val
;
517 orig_val
[(unsigned char) opt
->shortopt
] = opt
->shortopt
;
519 if (opt
->opt
.name
!= NULL
)
522 /* Dynamically assign `val' numbers for long options. */
524 handlers
[lp
->val
] = opt
->handler
;
525 orig_val
[lp
->val
] = opt
->opt
.val
;
526 opt_cpu
[lp
->val
] = NULL
;
531 for (c
= 0; c
< MAX_NR_PROCESSORS
; ++c
)
533 sim_cpu
*cpu
= STATE_CPU (sd
, c
);
534 for (ol
= CPU_OPTIONS (cpu
); ol
!= NULL
; ol
= ol
->next
)
535 for (opt
= ol
->options
; OPTION_VALID_P (opt
); ++opt
)
537 #if 0 /* Each option is prepended with --<cpuname>- so this greatly cuts down
538 on the need for dup_arg_p checking. Maybe in the future it'll be
539 needed so this is just commented out, and not deleted. */
540 if (dup_arg_p (opt
->opt
.name
))
543 /* Don't allow short versions of cpu specific options for now. */
544 if (opt
->shortopt
!= 0)
546 sim_io_eprintf (sd
, "internal error, short cpu specific option");
547 result
= SIM_RC_FAIL
;
550 if (opt
->opt
.name
!= NULL
)
554 /* Prepend --<cpuname>- to the option. */
555 if (asprintf (&name
, "%s-%s", CPU_NAME (cpu
), lp
->name
) < 0)
557 sim_io_eprintf (sd
, "internal error, out of memory");
558 result
= SIM_RC_FAIL
;
562 /* Dynamically assign `val' numbers for long options. */
564 handlers
[lp
->val
] = opt
->handler
;
565 orig_val
[lp
->val
] = opt
->opt
.val
;
566 opt_cpu
[lp
->val
] = cpu
;
572 /* Terminate the short and long option lists. */
576 /* Ensure getopt is initialized. */
579 /* Do not lot getopt throw errors for us. But don't mess with the state for
580 any callers higher up by saving/restoring it. */
581 save_opterr
= opterr
;
588 optc
= getopt_long (argc
, argv
, short_options
, long_options
, &longind
);
591 if (STATE_OPEN_KIND (sd
) == SIM_OPEN_STANDALONE
)
592 STATE_PROG_ARGV (sd
) = dupargv (argv
+ optind
);
597 /* If getopt rejects a short option, optopt is set to the bad char.
598 If it rejects a long option, we have to look at optind. In the
599 short option case, argv could be multiple short options. */
605 sprintf (optbuf
, "-%c", optopt
);
609 badopt
= argv
[optind
- 1];
612 "%s: unrecognized option '%s'\n"
613 "Use --help for a complete list of options.\n",
614 STATE_MY_NAME (sd
), badopt
);
616 result
= SIM_RC_FAIL
;
620 if ((*handlers
[optc
]) (sd
, opt_cpu
[optc
], orig_val
[optc
], optarg
, 0/*!is_command*/) == SIM_RC_FAIL
)
622 result
= SIM_RC_FAIL
;
627 opterr
= save_opterr
;
630 free (short_options
);
637 /* Utility of sim_print_help to print a list of option tables. */
640 print_help (SIM_DESC sd
, sim_cpu
*cpu
, const struct option_list
*ol
, int is_command
)
644 for ( ; ol
!= NULL
; ol
= ol
->next
)
645 for (opt
= ol
->options
; OPTION_VALID_P (opt
); ++opt
)
647 const int indent
= 30;
651 if (dup_arg_p (opt
->opt
.name
))
654 if (opt
->doc
== NULL
)
657 if (opt
->doc_name
!= NULL
&& opt
->doc_name
[0] == '\0')
660 sim_io_printf (sd
, " ");
665 /* list any short options (aliases) for the current OPT */
671 if (o
->shortopt
!= '\0')
673 sim_io_printf (sd
, "%s-%c", comma
? ", " : "", o
->shortopt
);
674 len
+= (comma
? 2 : 0) + 2;
677 if (o
->opt
.has_arg
== optional_argument
)
679 sim_io_printf (sd
, "[%s]", o
->arg
);
680 len
+= 1 + strlen (o
->arg
) + 1;
684 sim_io_printf (sd
, " %s", o
->arg
);
685 len
+= 1 + strlen (o
->arg
);
692 while (OPTION_VALID_P (o
) && o
->doc
== NULL
);
695 /* list any long options (aliases) for the current OPT */
700 const char *cpu_prefix
= cpu
? CPU_NAME (cpu
) : NULL
;
701 if (o
->doc_name
!= NULL
)
707 sim_io_printf (sd
, "%s%s%s%s%s",
709 is_command
? "" : "--",
710 cpu
? cpu_prefix
: "",
713 len
+= ((comma
? 2 : 0)
714 + (is_command
? 0 : 2)
718 if (o
->opt
.has_arg
== optional_argument
)
720 sim_io_printf (sd
, "[=%s]", o
->arg
);
721 len
+= 2 + strlen (o
->arg
) + 1;
725 sim_io_printf (sd
, " %s", o
->arg
);
726 len
+= 1 + strlen (o
->arg
);
733 while (OPTION_VALID_P (o
) && o
->doc
== NULL
);
737 sim_io_printf (sd
, "\n%*s", indent
, "");
740 sim_io_printf (sd
, "%*s", indent
- len
, "");
742 /* print the description, word wrap long lines */
744 const char *chp
= opt
->doc
;
745 unsigned doc_width
= 80 - indent
;
746 while (strlen (chp
) >= doc_width
) /* some slack */
748 const char *end
= chp
+ doc_width
- 1;
749 while (end
> chp
&& !isspace (*end
))
752 end
= chp
+ doc_width
- 1;
753 /* The cast should be ok - its distances between to
754 points in a string. */
755 sim_io_printf (sd
, "%.*s\n%*s", (int) (end
- chp
), chp
, indent
,
758 while (isspace (*chp
) && *chp
!= '\0')
761 sim_io_printf (sd
, "%s\n", chp
);
766 /* Print help messages for the options. */
769 sim_print_help (SIM_DESC sd
, int is_command
)
771 if (STATE_OPEN_KIND (sd
) == SIM_OPEN_STANDALONE
)
772 sim_io_printf (sd
, "Usage: %s [options] program [program args]\n",
775 /* Initialize duplicate argument checker. */
776 (void) dup_arg_p (NULL
);
778 if (STATE_OPEN_KIND (sd
) == SIM_OPEN_STANDALONE
)
779 sim_io_printf (sd
, "Options:\n");
781 sim_io_printf (sd
, "Commands:\n");
783 print_help (sd
, NULL
, STATE_OPTIONS (sd
), is_command
);
784 sim_io_printf (sd
, "\n");
786 /* Print cpu-specific options. */
790 for (i
= 0; i
< MAX_NR_PROCESSORS
; ++i
)
792 sim_cpu
*cpu
= STATE_CPU (sd
, i
);
793 if (CPU_OPTIONS (cpu
) == NULL
)
795 sim_io_printf (sd
, "CPU %s specific options:\n", CPU_NAME (cpu
));
796 print_help (sd
, cpu
, CPU_OPTIONS (cpu
), is_command
);
797 sim_io_printf (sd
, "\n");
801 sim_io_printf (sd
, "Note: Depending on the simulator configuration some %ss\n",
802 STATE_OPEN_KIND (sd
) == SIM_OPEN_STANDALONE
? "option" : "command");
803 sim_io_printf (sd
, " may not be applicable\n");
805 if (STATE_OPEN_KIND (sd
) == SIM_OPEN_STANDALONE
)
807 sim_io_printf (sd
, "\n");
808 sim_io_printf (sd
, "program args Arguments to pass to simulated program.\n");
809 sim_io_printf (sd
, " Note: Very few simulators support this.\n");
813 /* Print version information. */
816 sim_print_version (SIM_DESC sd
, int is_command
)
818 sim_io_printf (sd
, "GNU simulator %s%s\n", PKGVERSION
, version
);
820 sim_io_printf (sd
, "Copyright (C) 2021 Free Software Foundation, Inc.\n");
822 /* Following the copyright is a brief statement that the program is
823 free software, that users are free to copy and change it on
824 certain conditions, that it is covered by the GNU GPL, and that
825 there is no warranty. */
827 sim_io_printf (sd
, "\
828 License GPLv3+: GNU GPL version 3 or later <https://gnu.org/licenses/gpl.html>\
829 \nThis is free software: you are free to change and redistribute it.\n\
830 There is NO WARRANTY, to the extent permitted by law.\n");
835 sim_io_printf (sd
, "This SIM was configured as:\n");
836 sim_config_print (sd
);
838 if (REPORT_BUGS_TO
[0])
840 sim_io_printf (sd
, "For bug reporting instructions, please see:\n\
844 sim_io_printf (sd
, "Find the SIM homepage & other documentation resources \
845 online at:\n <https://sourceware.org/gdb/wiki/Sim/>.\n");
848 /* Utility of sim_args_command to find the closest match for a command.
849 Commands that have "-" in them can be specified as separate words.
850 e.g. sim memory-region 0x800000,0x4000
851 or sim memory region 0x800000,0x4000
852 If CPU is non-null, use its option table list, otherwise use the main one.
853 *PARGI is where to start looking in ARGV. It is updated to point past
856 static const OPTION
*
857 find_match (SIM_DESC sd
, sim_cpu
*cpu
, char *argv
[], int *pargi
)
859 const struct option_list
*ol
;
861 /* most recent option match */
862 const OPTION
*matching_opt
= NULL
;
863 int matching_argi
= -1;
866 ol
= CPU_OPTIONS (cpu
);
868 ol
= STATE_OPTIONS (sd
);
870 /* Skip passed elements specified by *PARGI. */
873 for ( ; ol
!= NULL
; ol
= ol
->next
)
874 for (opt
= ol
->options
; OPTION_VALID_P (opt
); ++opt
)
877 const char *name
= opt
->opt
.name
;
880 while (argv
[argi
] != NULL
881 && strncmp (name
, argv
[argi
], strlen (argv
[argi
])) == 0)
883 name
= &name
[strlen (argv
[argi
])];
886 /* leading match ...<a-b-c>-d-e-f - continue search */
887 name
++; /* skip `-' */
891 else if (name
[0] == '\0')
893 /* exact match ...<a-b-c-d-e-f> - better than before? */
894 if (argi
> matching_argi
)
896 matching_argi
= argi
;
906 *pargi
= matching_argi
;
911 complete_option_list (char **ret
, size_t *cnt
, const struct option_list
*ol
,
912 const char *text
, const char *word
)
914 const OPTION
*opt
= NULL
;
916 size_t len
= strlen (word
);
918 for ( ; ol
!= NULL
; ol
= ol
->next
)
919 for (opt
= ol
->options
; OPTION_VALID_P (opt
); ++opt
)
921 const char *name
= opt
->opt
.name
;
923 /* A long option to match against? */
927 /* Does this option actually match? */
928 if (strncmp (name
, word
, len
))
931 ret
= xrealloc (ret
, ++*cnt
* sizeof (ret
[0]));
932 ret
[*cnt
- 2] = xstrdup (name
);
938 /* All leading text is stored in @text, while the current word being
939 completed is stored in @word. Trailing text of @word is not. */
942 sim_complete_command (SIM_DESC sd
, const char *text
, const char *word
)
948 /* Only complete first word for now. */
952 cpu
= STATE_CPU (sd
, 0);
954 ret
= complete_option_list (ret
, &cnt
, CPU_OPTIONS (cpu
), text
, word
);
955 ret
= complete_option_list (ret
, &cnt
, STATE_OPTIONS (sd
), text
, word
);
963 sim_args_command (SIM_DESC sd
, const char *cmd
)
965 /* something to do? */
967 return SIM_RC_OK
; /* FIXME - perhaps help would be better */
971 /* user specified -<opt> ... form? */
972 char **argv
= buildargv (cmd
);
973 SIM_RC rc
= sim_parse_args (sd
, argv
);
979 char **argv
= buildargv (cmd
);
980 const OPTION
*matching_opt
= NULL
;
984 if (argv
[0] == NULL
)
987 return SIM_RC_OK
; /* FIXME - perhaps help would be better */
990 /* First check for a cpu selector. */
992 char *cpu_name
= xstrdup (argv
[0]);
993 char *hyphen
= strchr (cpu_name
, '-');
996 cpu
= sim_cpu_lookup (sd
, cpu_name
);
999 /* If <cpuname>-<command>, point argv[0] at <command>. */
1003 argv
[0] += hyphen
- cpu_name
+ 1;
1007 matching_opt
= find_match (sd
, cpu
, argv
, &matching_argi
);
1008 /* If hyphen found restore argv[0]. */
1010 argv
[0] -= hyphen
- cpu_name
+ 1;
1015 /* If that failed, try the main table. */
1016 if (matching_opt
== NULL
)
1019 matching_opt
= find_match (sd
, NULL
, argv
, &matching_argi
);
1022 if (matching_opt
!= NULL
)
1024 switch (matching_opt
->opt
.has_arg
)
1027 if (argv
[matching_argi
+ 1] == NULL
)
1028 matching_opt
->handler (sd
, cpu
, matching_opt
->opt
.val
,
1029 NULL
, 1/*is_command*/);
1031 sim_io_eprintf (sd
, "Command `%s' takes no arguments\n",
1032 matching_opt
->opt
.name
);
1034 case optional_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 if (argv
[matching_argi
+ 2] == NULL
)
1039 matching_opt
->handler (sd
, cpu
, matching_opt
->opt
.val
,
1040 argv
[matching_argi
+ 1], 1/*is_command*/);
1042 sim_io_eprintf (sd
, "Command `%s' requires no more than one argument\n",
1043 matching_opt
->opt
.name
);
1045 case required_argument
:
1046 if (argv
[matching_argi
+ 1] == NULL
)
1047 sim_io_eprintf (sd
, "Command `%s' requires an argument\n",
1048 matching_opt
->opt
.name
);
1049 else if (argv
[matching_argi
+ 2] == NULL
)
1050 matching_opt
->handler (sd
, cpu
, matching_opt
->opt
.val
,
1051 argv
[matching_argi
+ 1], 1/*is_command*/);
1053 sim_io_eprintf (sd
, "Command `%s' requires only one argument\n",
1054 matching_opt
->opt
.name
);
1063 /* didn't find anything that remotly matched */