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/>. */
20 /* This must come before any other includes. */
28 #include "libiberty.h"
29 #include "sim-options.h"
31 #include "sim-assert.h"
37 /* Add a set of options to the simulator.
38 TABLE is an array of OPTIONS terminated by a NULL `opt.name' entry.
39 This is intended to be called by modules in their `install' handler. */
42 sim_add_option_table (SIM_DESC sd
, sim_cpu
*cpu
, const OPTION
*table
)
44 struct option_list
*ol
= ((struct option_list
*)
45 xmalloc (sizeof (struct option_list
)));
47 /* Note: The list is constructed in the reverse order we're called so
48 later calls will override earlier ones (in case that ever happens).
49 This is the intended behaviour. */
53 ol
->next
= CPU_OPTIONS (cpu
);
55 CPU_OPTIONS (cpu
) = ol
;
59 ol
->next
= STATE_OPTIONS (sd
);
61 STATE_OPTIONS (sd
) = ol
;
67 /* Standard option table.
68 Modules may specify additional ones.
69 The caller of sim_parse_args may also specify additional options
70 by calling sim_add_option_table first. */
72 static DECLARE_OPTION_HANDLER (standard_option_handler
);
74 /* FIXME: We shouldn't print in --help output options that aren't usable.
75 Some fine tuning will be necessary. One can either move less general
76 options to another table or use a HAVE_FOO macro to ifdef out unavailable
79 /* ??? One might want to conditionally compile out the entries that
80 aren't enabled. There's a distinction, however, between options a
81 simulator can't support and options that haven't been configured in.
82 Certainly options a simulator can't support shouldn't appear in the
83 output of --help. Whether the same thing applies to options that haven't
84 been configured in or not isn't something I can get worked up over.
85 [Note that conditionally compiling them out might simply involve moving
86 the option to another table.]
87 If you decide to conditionally compile them out as well, delete this
88 comment and add a comment saying that that is the rule. */
91 OPTION_DEBUG_INSN
= OPTION_START
,
96 OPTION_ARCHITECTURE_INFO
,
109 static const OPTION standard_options
[] =
111 { {"verbose", no_argument
, NULL
, OPTION_VERBOSE
},
112 'v', NULL
, "Verbose output",
113 standard_option_handler
, NULL
},
115 { {"endian", required_argument
, NULL
, OPTION_ENDIAN
},
116 'E', "big|little", "Set endianness",
117 standard_option_handler
, NULL
},
119 /* This option isn't supported unless all choices are supported in keeping
120 with the goal of not printing in --help output things the simulator can't
121 do [as opposed to things that just haven't been configured in]. */
122 { {"environment", required_argument
, NULL
, OPTION_ENVIRONMENT
},
123 '\0', "user|virtual|operating", "Set running environment",
124 standard_option_handler
},
126 { {"alignment", required_argument
, NULL
, OPTION_ALIGNMENT
},
127 '\0', "strict|nonstrict|forced", "Set memory access alignment",
128 standard_option_handler
},
130 { {"debug", no_argument
, NULL
, OPTION_DEBUG
},
131 'D', NULL
, "Print debugging messages",
132 standard_option_handler
},
133 { {"debug-insn", no_argument
, NULL
, OPTION_DEBUG_INSN
},
134 '\0', NULL
, "Print instruction debugging messages",
135 standard_option_handler
},
136 { {"debug-file", required_argument
, NULL
, OPTION_DEBUG_FILE
},
137 '\0', "FILE NAME", "Specify debugging output file",
138 standard_option_handler
},
140 { {"do-command", required_argument
, NULL
, OPTION_DO_COMMAND
},
141 '\0', "COMMAND", ""/*undocumented*/,
142 standard_option_handler
},
144 { {"help", no_argument
, NULL
, OPTION_HELP
},
145 'H', NULL
, "Print help information",
146 standard_option_handler
},
147 { {"version", no_argument
, NULL
, OPTION_VERSION
},
148 '\0', NULL
, "Print version information",
149 standard_option_handler
},
151 { {"architecture", required_argument
, NULL
, OPTION_ARCHITECTURE
},
152 '\0', "MACHINE", "Specify the architecture to use",
153 standard_option_handler
},
154 { {"architecture-info", no_argument
, NULL
, OPTION_ARCHITECTURE_INFO
},
155 '\0', NULL
, "List supported architectures",
156 standard_option_handler
},
157 { {"info-architecture", no_argument
, NULL
, OPTION_ARCHITECTURE_INFO
},
159 standard_option_handler
},
161 { {"target", required_argument
, NULL
, OPTION_TARGET
},
162 '\0', "BFDNAME", "Specify the object-code format for the object files",
163 standard_option_handler
},
165 { {"load-lma", no_argument
, NULL
, OPTION_LOAD_LMA
},
167 "Use VMA or LMA addresses when loading image (default LMA)",
168 standard_option_handler
, "load-{lma,vma}" },
169 { {"load-vma", no_argument
, NULL
, OPTION_LOAD_VMA
},
170 '\0', NULL
, "", standard_option_handler
, "" },
172 { {"sysroot", required_argument
, NULL
, OPTION_SYSROOT
},
174 "Root for system calls with absolute file-names and cwd at start",
175 standard_option_handler
, NULL
},
177 { {NULL
, no_argument
, NULL
, 0}, '\0', NULL
, NULL
, NULL
, NULL
}
181 standard_option_handler (SIM_DESC sd
, sim_cpu
*cpu
, int opt
,
182 char *arg
, int is_command
)
186 switch ((STANDARD_OPTIONS
) opt
)
189 STATE_VERBOSE_P (sd
) = 1;
193 if (strcmp (arg
, "big") == 0)
195 if (WITH_TARGET_BYTE_ORDER
== BFD_ENDIAN_LITTLE
)
197 sim_io_eprintf (sd
, "Simulator compiled for little endian only.\n");
200 /* FIXME:wip: Need to set something in STATE_CONFIG. */
201 current_target_byte_order
= BFD_ENDIAN_BIG
;
203 else if (strcmp (arg
, "little") == 0)
205 if (WITH_TARGET_BYTE_ORDER
== BFD_ENDIAN_BIG
)
207 sim_io_eprintf (sd
, "Simulator compiled for big endian only.\n");
210 /* FIXME:wip: Need to set something in STATE_CONFIG. */
211 current_target_byte_order
= BFD_ENDIAN_LITTLE
;
215 sim_io_eprintf (sd
, "Invalid endian specification `%s'\n", arg
);
220 case OPTION_ENVIRONMENT
:
221 if (strcmp (arg
, "user") == 0)
222 STATE_ENVIRONMENT (sd
) = USER_ENVIRONMENT
;
223 else if (strcmp (arg
, "virtual") == 0)
224 STATE_ENVIRONMENT (sd
) = VIRTUAL_ENVIRONMENT
;
225 else if (strcmp (arg
, "operating") == 0)
226 STATE_ENVIRONMENT (sd
) = OPERATING_ENVIRONMENT
;
229 sim_io_eprintf (sd
, "Invalid environment specification `%s'\n", arg
);
232 if (WITH_ENVIRONMENT
!= ALL_ENVIRONMENT
233 && WITH_ENVIRONMENT
!= STATE_ENVIRONMENT (sd
))
236 switch (WITH_ENVIRONMENT
)
238 case USER_ENVIRONMENT
: type
= "user"; break;
239 case VIRTUAL_ENVIRONMENT
: type
= "virtual"; break;
240 case OPERATING_ENVIRONMENT
: type
= "operating"; break;
243 sim_io_eprintf (sd
, "Simulator compiled for the %s environment only.\n",
249 case OPTION_ALIGNMENT
:
250 if (strcmp (arg
, "strict") == 0)
252 if (WITH_ALIGNMENT
== 0 || WITH_ALIGNMENT
== STRICT_ALIGNMENT
)
254 current_alignment
= STRICT_ALIGNMENT
;
258 else if (strcmp (arg
, "nonstrict") == 0)
260 if (WITH_ALIGNMENT
== 0 || WITH_ALIGNMENT
== NONSTRICT_ALIGNMENT
)
262 current_alignment
= NONSTRICT_ALIGNMENT
;
266 else if (strcmp (arg
, "forced") == 0)
268 if (WITH_ALIGNMENT
== 0 || WITH_ALIGNMENT
== FORCED_ALIGNMENT
)
270 current_alignment
= FORCED_ALIGNMENT
;
276 sim_io_eprintf (sd
, "Invalid alignment specification `%s'\n", arg
);
279 switch (WITH_ALIGNMENT
)
281 case STRICT_ALIGNMENT
:
282 sim_io_eprintf (sd
, "Simulator compiled for strict alignment only.\n");
284 case NONSTRICT_ALIGNMENT
:
285 sim_io_eprintf (sd
, "Simulator compiled for nonstrict alignment only.\n");
287 case FORCED_ALIGNMENT
:
288 sim_io_eprintf (sd
, "Simulator compiled for forced alignment only.\n");
296 sim_io_eprintf (sd
, "Debugging not compiled in, `-D' ignored\n");
299 for (n
= 0; n
< MAX_NR_PROCESSORS
; ++n
)
300 for (i
= 0; i
< MAX_DEBUG_VALUES
; ++i
)
301 CPU_DEBUG_FLAGS (STATE_CPU (sd
, n
))[i
] = 1;
305 case OPTION_DEBUG_INSN
:
307 sim_io_eprintf (sd
, "Debugging not compiled in, `--debug-insn' ignored\n");
310 for (n
= 0; n
< MAX_NR_PROCESSORS
; ++n
)
311 CPU_DEBUG_FLAGS (STATE_CPU (sd
, n
))[DEBUG_INSN_IDX
] = 1;
315 case OPTION_DEBUG_FILE
:
317 sim_io_eprintf (sd
, "Debugging not compiled in, `--debug-file' ignored\n");
320 FILE *f
= fopen (arg
, "w");
324 sim_io_eprintf (sd
, "Unable to open debug output file `%s'\n", arg
);
327 for (n
= 0; n
< MAX_NR_PROCESSORS
; ++n
)
328 CPU_DEBUG_FILE (STATE_CPU (sd
, n
)) = f
;
332 case OPTION_DO_COMMAND
:
333 sim_do_command (sd
, arg
);
336 case OPTION_ARCHITECTURE
:
338 const struct bfd_arch_info
*ap
= bfd_scan_arch (arg
);
341 sim_io_eprintf (sd
, "Architecture `%s' unknown\n", arg
);
344 STATE_ARCHITECTURE (sd
) = ap
;
348 case OPTION_ARCHITECTURE_INFO
:
350 const char **list
= bfd_arch_list ();
354 sim_io_printf (sd
, "Possible architectures:");
355 for (lp
= list
; *lp
!= NULL
; lp
++)
356 sim_io_printf (sd
, " %s", *lp
);
357 sim_io_printf (sd
, "\n");
364 STATE_TARGET (sd
) = xstrdup (arg
);
368 case OPTION_LOAD_LMA
:
370 STATE_LOAD_AT_LMA_P (sd
) = 1;
374 case OPTION_LOAD_VMA
:
376 STATE_LOAD_AT_LMA_P (sd
) = 0;
381 sim_print_help (sd
, is_command
);
382 if (STATE_OPEN_KIND (sd
) == SIM_OPEN_STANDALONE
)
384 /* FIXME: 'twould be nice to do something similar if gdb. */
388 sim_print_version (sd
, is_command
);
389 if (STATE_OPEN_KIND (sd
) == SIM_OPEN_STANDALONE
)
394 /* Don't leak memory in the odd event that there's lots of
395 --sysroot=... options. We treat "" specially since this
396 is the statically initialized value and cannot free it. */
397 if (simulator_sysroot
[0] != '\0')
398 free (simulator_sysroot
);
400 simulator_sysroot
= xstrdup (arg
);
402 simulator_sysroot
= "";
409 /* Add the standard option list to the simulator. */
412 standard_install (SIM_DESC sd
)
414 SIM_ASSERT (STATE_MAGIC (sd
) == SIM_MAGIC_NUMBER
);
415 if (sim_add_option_table (sd
, NULL
, standard_options
) != SIM_RC_OK
)
417 STATE_LOAD_AT_LMA_P (sd
) = 1;
421 /* Return non-zero if arg is a duplicate argument.
422 If ARG is NULL, initialize. */
425 dup_arg_p (const char *arg
)
427 static htab_t arg_table
= NULL
;
432 if (arg_table
== NULL
)
433 arg_table
= htab_create_alloc (10, htab_hash_string
,
434 htab_eq_string
, NULL
,
436 htab_empty (arg_table
);
440 slot
= htab_find_slot (arg_table
, arg
, INSERT
);
443 *slot
= (void *) arg
;
447 /* Called by sim_open to parse the arguments. */
450 sim_parse_args (SIM_DESC sd
, char * const *argv
)
452 int c
, i
, argc
, num_opts
, save_opterr
;
453 char *p
, *short_options
;
454 /* The `val' option struct entry is dynamically assigned for options that
455 only come in the long form. ORIG_VAL is used to get the original value
458 struct option
*lp
, *long_options
;
459 const struct option_list
*ol
;
461 OPTION_HANDLER
**handlers
;
463 SIM_RC result
= SIM_RC_OK
;
465 /* Count the number of arguments. */
466 argc
= countargv (argv
);
468 /* Count the number of options. */
470 for (ol
= STATE_OPTIONS (sd
); ol
!= NULL
; ol
= ol
->next
)
471 for (opt
= ol
->options
; OPTION_VALID_P (opt
); ++opt
)
473 for (i
= 0; i
< MAX_NR_PROCESSORS
; ++i
)
474 for (ol
= CPU_OPTIONS (STATE_CPU (sd
, i
)); ol
!= NULL
; ol
= ol
->next
)
475 for (opt
= ol
->options
; OPTION_VALID_P (opt
); ++opt
)
478 /* Initialize duplicate argument checker. */
479 (void) dup_arg_p (NULL
);
481 /* Build the option table for getopt. */
483 long_options
= NZALLOC (struct option
, num_opts
+ 1);
485 short_options
= NZALLOC (char, num_opts
* 3 + 1);
487 handlers
= NZALLOC (OPTION_HANDLER
*, OPTION_START
+ num_opts
);
488 orig_val
= NZALLOC (int, OPTION_START
+ num_opts
);
489 opt_cpu
= NZALLOC (sim_cpu
*, OPTION_START
+ num_opts
);
491 /* Set '+' as first char so argument permutation isn't done. This
492 is done to stop getopt_long returning options that appear after
493 the target program. Such options should be passed unchanged into
494 the program image. */
497 for (i
= OPTION_START
, ol
= STATE_OPTIONS (sd
); ol
!= NULL
; ol
= ol
->next
)
498 for (opt
= ol
->options
; OPTION_VALID_P (opt
); ++opt
)
500 if (dup_arg_p (opt
->opt
.name
))
502 if (opt
->shortopt
!= 0)
504 *p
++ = opt
->shortopt
;
505 if (opt
->opt
.has_arg
== required_argument
)
507 else if (opt
->opt
.has_arg
== optional_argument
)
508 { *p
++ = ':'; *p
++ = ':'; }
509 handlers
[(unsigned char) opt
->shortopt
] = opt
->handler
;
510 if (opt
->opt
.val
!= 0)
511 orig_val
[(unsigned char) opt
->shortopt
] = opt
->opt
.val
;
513 orig_val
[(unsigned char) opt
->shortopt
] = opt
->shortopt
;
515 if (opt
->opt
.name
!= NULL
)
518 /* Dynamically assign `val' numbers for long options. */
520 handlers
[lp
->val
] = opt
->handler
;
521 orig_val
[lp
->val
] = opt
->opt
.val
;
522 opt_cpu
[lp
->val
] = NULL
;
527 for (c
= 0; c
< MAX_NR_PROCESSORS
; ++c
)
529 sim_cpu
*cpu
= STATE_CPU (sd
, c
);
530 for (ol
= CPU_OPTIONS (cpu
); ol
!= NULL
; ol
= ol
->next
)
531 for (opt
= ol
->options
; OPTION_VALID_P (opt
); ++opt
)
533 #if 0 /* Each option is prepended with --<cpuname>- so this greatly cuts down
534 on the need for dup_arg_p checking. Maybe in the future it'll be
535 needed so this is just commented out, and not deleted. */
536 if (dup_arg_p (opt
->opt
.name
))
539 /* Don't allow short versions of cpu specific options for now. */
540 if (opt
->shortopt
!= 0)
542 sim_io_eprintf (sd
, "internal error, short cpu specific option");
543 result
= SIM_RC_FAIL
;
546 if (opt
->opt
.name
!= NULL
)
550 /* Prepend --<cpuname>- to the option. */
551 if (asprintf (&name
, "%s-%s", CPU_NAME (cpu
), lp
->name
) < 0)
553 sim_io_eprintf (sd
, "internal error, out of memory");
554 result
= SIM_RC_FAIL
;
558 /* Dynamically assign `val' numbers for long options. */
560 handlers
[lp
->val
] = opt
->handler
;
561 orig_val
[lp
->val
] = opt
->opt
.val
;
562 opt_cpu
[lp
->val
] = cpu
;
568 /* Terminate the short and long option lists. */
572 /* Ensure getopt is initialized. */
575 /* Do not lot getopt throw errors for us. But don't mess with the state for
576 any callers higher up by saving/restoring it. */
577 save_opterr
= opterr
;
584 optc
= getopt_long (argc
, argv
, short_options
, long_options
, &longind
);
587 if (STATE_OPEN_KIND (sd
) == SIM_OPEN_STANDALONE
)
588 STATE_PROG_ARGV (sd
) = dupargv (argv
+ optind
);
593 /* If getopt rejects a short option, optopt is set to the bad char.
594 If it rejects a long option, we have to look at optind. In the
595 short option case, argv could be multiple short options. */
601 sprintf (optbuf
, "-%c", optopt
);
605 badopt
= argv
[optind
- 1];
608 "%s: unrecognized option '%s'\n"
609 "Use --help for a complete list of options.\n",
610 STATE_MY_NAME (sd
), badopt
);
612 result
= SIM_RC_FAIL
;
616 if ((*handlers
[optc
]) (sd
, opt_cpu
[optc
], orig_val
[optc
], optarg
, 0/*!is_command*/) == SIM_RC_FAIL
)
618 result
= SIM_RC_FAIL
;
623 opterr
= save_opterr
;
626 free (short_options
);
633 /* Utility of sim_print_help to print a list of option tables. */
636 print_help (SIM_DESC sd
, sim_cpu
*cpu
, const struct option_list
*ol
, int is_command
)
640 for ( ; ol
!= NULL
; ol
= ol
->next
)
641 for (opt
= ol
->options
; OPTION_VALID_P (opt
); ++opt
)
643 const int indent
= 30;
647 if (dup_arg_p (opt
->opt
.name
))
650 if (opt
->doc
== NULL
)
653 if (opt
->doc_name
!= NULL
&& opt
->doc_name
[0] == '\0')
656 sim_io_printf (sd
, " ");
661 /* list any short options (aliases) for the current OPT */
667 if (o
->shortopt
!= '\0')
669 sim_io_printf (sd
, "%s-%c", comma
? ", " : "", o
->shortopt
);
670 len
+= (comma
? 2 : 0) + 2;
673 if (o
->opt
.has_arg
== optional_argument
)
675 sim_io_printf (sd
, "[%s]", o
->arg
);
676 len
+= 1 + strlen (o
->arg
) + 1;
680 sim_io_printf (sd
, " %s", o
->arg
);
681 len
+= 1 + strlen (o
->arg
);
688 while (OPTION_VALID_P (o
) && o
->doc
== NULL
);
691 /* list any long options (aliases) for the current OPT */
696 const char *cpu_prefix
= cpu
? CPU_NAME (cpu
) : NULL
;
697 if (o
->doc_name
!= NULL
)
703 sim_io_printf (sd
, "%s%s%s%s%s",
705 is_command
? "" : "--",
706 cpu
? cpu_prefix
: "",
709 len
+= ((comma
? 2 : 0)
710 + (is_command
? 0 : 2)
714 if (o
->opt
.has_arg
== optional_argument
)
716 sim_io_printf (sd
, "[=%s]", o
->arg
);
717 len
+= 2 + strlen (o
->arg
) + 1;
721 sim_io_printf (sd
, " %s", o
->arg
);
722 len
+= 1 + strlen (o
->arg
);
729 while (OPTION_VALID_P (o
) && o
->doc
== NULL
);
733 sim_io_printf (sd
, "\n%*s", indent
, "");
736 sim_io_printf (sd
, "%*s", indent
- len
, "");
738 /* print the description, word wrap long lines */
740 const char *chp
= opt
->doc
;
741 unsigned doc_width
= 80 - indent
;
742 while (strlen (chp
) >= doc_width
) /* some slack */
744 const char *end
= chp
+ doc_width
- 1;
745 while (end
> chp
&& !isspace (*end
))
748 end
= chp
+ doc_width
- 1;
749 /* The cast should be ok - its distances between to
750 points in a string. */
751 sim_io_printf (sd
, "%.*s\n%*s", (int) (end
- chp
), chp
, indent
,
754 while (isspace (*chp
) && *chp
!= '\0')
757 sim_io_printf (sd
, "%s\n", chp
);
762 /* Print help messages for the options. */
765 sim_print_help (SIM_DESC sd
, int is_command
)
767 if (STATE_OPEN_KIND (sd
) == SIM_OPEN_STANDALONE
)
768 sim_io_printf (sd
, "Usage: %s [options] program [program args]\n",
771 /* Initialize duplicate argument checker. */
772 (void) dup_arg_p (NULL
);
774 if (STATE_OPEN_KIND (sd
) == SIM_OPEN_STANDALONE
)
775 sim_io_printf (sd
, "Options:\n");
777 sim_io_printf (sd
, "Commands:\n");
779 print_help (sd
, NULL
, STATE_OPTIONS (sd
), is_command
);
780 sim_io_printf (sd
, "\n");
782 /* Print cpu-specific options. */
786 for (i
= 0; i
< MAX_NR_PROCESSORS
; ++i
)
788 sim_cpu
*cpu
= STATE_CPU (sd
, i
);
789 if (CPU_OPTIONS (cpu
) == NULL
)
791 sim_io_printf (sd
, "CPU %s specific options:\n", CPU_NAME (cpu
));
792 print_help (sd
, cpu
, CPU_OPTIONS (cpu
), is_command
);
793 sim_io_printf (sd
, "\n");
797 sim_io_printf (sd
, "Note: Depending on the simulator configuration some %ss\n",
798 STATE_OPEN_KIND (sd
) == SIM_OPEN_STANDALONE
? "option" : "command");
799 sim_io_printf (sd
, " may not be applicable\n");
801 if (STATE_OPEN_KIND (sd
) == SIM_OPEN_STANDALONE
)
803 sim_io_printf (sd
, "\n");
804 sim_io_printf (sd
, "program args Arguments to pass to simulated program.\n");
805 sim_io_printf (sd
, " Note: Very few simulators support this.\n");
809 /* Print version information. */
812 sim_print_version (SIM_DESC sd
, int is_command
)
814 sim_io_printf (sd
, "GNU simulator %s%s\n", PKGVERSION
, version
);
816 sim_io_printf (sd
, "Copyright (C) 2021 Free Software Foundation, Inc.\n");
818 /* Following the copyright is a brief statement that the program is
819 free software, that users are free to copy and change it on
820 certain conditions, that it is covered by the GNU GPL, and that
821 there is no warranty. */
823 sim_io_printf (sd
, "\
824 License GPLv3+: GNU GPL version 3 or later <https://gnu.org/licenses/gpl.html>\
825 \nThis is free software: you are free to change and redistribute it.\n\
826 There is NO WARRANTY, to the extent permitted by law.\n");
831 sim_io_printf (sd
, "This SIM was configured as:\n");
832 sim_config_print (sd
);
834 if (REPORT_BUGS_TO
[0])
836 sim_io_printf (sd
, "For bug reporting instructions, please see:\n\
840 sim_io_printf (sd
, "Find the SIM homepage & other documentation resources \
841 online at:\n <https://sourceware.org/gdb/wiki/Sim/>.\n");
844 /* Utility of sim_args_command to find the closest match for a command.
845 Commands that have "-" in them can be specified as separate words.
846 e.g. sim memory-region 0x800000,0x4000
847 or sim memory region 0x800000,0x4000
848 If CPU is non-null, use its option table list, otherwise use the main one.
849 *PARGI is where to start looking in ARGV. It is updated to point past
852 static const OPTION
*
853 find_match (SIM_DESC sd
, sim_cpu
*cpu
, char *argv
[], int *pargi
)
855 const struct option_list
*ol
;
857 /* most recent option match */
858 const OPTION
*matching_opt
= NULL
;
859 int matching_argi
= -1;
862 ol
= CPU_OPTIONS (cpu
);
864 ol
= STATE_OPTIONS (sd
);
866 /* Skip passed elements specified by *PARGI. */
869 for ( ; ol
!= NULL
; ol
= ol
->next
)
870 for (opt
= ol
->options
; OPTION_VALID_P (opt
); ++opt
)
873 const char *name
= opt
->opt
.name
;
876 while (argv
[argi
] != NULL
877 && strncmp (name
, argv
[argi
], strlen (argv
[argi
])) == 0)
879 name
= &name
[strlen (argv
[argi
])];
882 /* leading match ...<a-b-c>-d-e-f - continue search */
883 name
++; /* skip `-' */
887 else if (name
[0] == '\0')
889 /* exact match ...<a-b-c-d-e-f> - better than before? */
890 if (argi
> matching_argi
)
892 matching_argi
= argi
;
902 *pargi
= matching_argi
;
907 complete_option_list (char **ret
, size_t *cnt
, const struct option_list
*ol
,
908 const char *text
, const char *word
)
910 const OPTION
*opt
= NULL
;
912 size_t len
= strlen (word
);
914 for ( ; ol
!= NULL
; ol
= ol
->next
)
915 for (opt
= ol
->options
; OPTION_VALID_P (opt
); ++opt
)
917 const char *name
= opt
->opt
.name
;
919 /* A long option to match against? */
923 /* Does this option actually match? */
924 if (strncmp (name
, word
, len
))
927 ret
= xrealloc (ret
, ++*cnt
* sizeof (ret
[0]));
928 ret
[*cnt
- 2] = xstrdup (name
);
934 /* All leading text is stored in @text, while the current word being
935 completed is stored in @word. Trailing text of @word is not. */
938 sim_complete_command (SIM_DESC sd
, const char *text
, const char *word
)
944 /* Only complete first word for now. */
948 cpu
= STATE_CPU (sd
, 0);
950 ret
= complete_option_list (ret
, &cnt
, CPU_OPTIONS (cpu
), text
, word
);
951 ret
= complete_option_list (ret
, &cnt
, STATE_OPTIONS (sd
), text
, word
);
959 sim_args_command (SIM_DESC sd
, const char *cmd
)
961 /* something to do? */
963 return SIM_RC_OK
; /* FIXME - perhaps help would be better */
967 /* user specified -<opt> ... form? */
968 char **argv
= buildargv (cmd
);
969 SIM_RC rc
= sim_parse_args (sd
, argv
);
975 char **argv
= buildargv (cmd
);
976 const OPTION
*matching_opt
= NULL
;
980 if (argv
[0] == NULL
)
983 return SIM_RC_OK
; /* FIXME - perhaps help would be better */
986 /* First check for a cpu selector. */
988 char *cpu_name
= xstrdup (argv
[0]);
989 char *hyphen
= strchr (cpu_name
, '-');
992 cpu
= sim_cpu_lookup (sd
, cpu_name
);
995 /* If <cpuname>-<command>, point argv[0] at <command>. */
999 argv
[0] += hyphen
- cpu_name
+ 1;
1003 matching_opt
= find_match (sd
, cpu
, argv
, &matching_argi
);
1004 /* If hyphen found restore argv[0]. */
1006 argv
[0] -= hyphen
- cpu_name
+ 1;
1011 /* If that failed, try the main table. */
1012 if (matching_opt
== NULL
)
1015 matching_opt
= find_match (sd
, NULL
, argv
, &matching_argi
);
1018 if (matching_opt
!= NULL
)
1020 switch (matching_opt
->opt
.has_arg
)
1023 if (argv
[matching_argi
+ 1] == NULL
)
1024 matching_opt
->handler (sd
, cpu
, matching_opt
->opt
.val
,
1025 NULL
, 1/*is_command*/);
1027 sim_io_eprintf (sd
, "Command `%s' takes no arguments\n",
1028 matching_opt
->opt
.name
);
1030 case optional_argument
:
1031 if (argv
[matching_argi
+ 1] == NULL
)
1032 matching_opt
->handler (sd
, cpu
, matching_opt
->opt
.val
,
1033 NULL
, 1/*is_command*/);
1034 else if (argv
[matching_argi
+ 2] == NULL
)
1035 matching_opt
->handler (sd
, cpu
, matching_opt
->opt
.val
,
1036 argv
[matching_argi
+ 1], 1/*is_command*/);
1038 sim_io_eprintf (sd
, "Command `%s' requires no more than one argument\n",
1039 matching_opt
->opt
.name
);
1041 case required_argument
:
1042 if (argv
[matching_argi
+ 1] == NULL
)
1043 sim_io_eprintf (sd
, "Command `%s' requires an argument\n",
1044 matching_opt
->opt
.name
);
1045 else if (argv
[matching_argi
+ 2] == NULL
)
1046 matching_opt
->handler (sd
, cpu
, matching_opt
->opt
.val
,
1047 argv
[matching_argi
+ 1], 1/*is_command*/);
1049 sim_io_eprintf (sd
, "Command `%s' requires only one argument\n",
1050 matching_opt
->opt
.name
);
1059 /* didn't find anything that remotly matched */