Add note to check that all changes have been pushed before creating the source tarballs
[binutils-gdb.git] / sim / common / sim-options.c
bloba6cd0037d2aac37594ec5424b650f338d5d81c23
1 /* Simulator option handling.
2 Copyright (C) 1996-2023 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. */
21 #include "defs.h"
23 #include <ctype.h>
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include <unistd.h>
29 #include "bfd.h"
30 #include "environ.h"
31 #include "hashtab.h"
32 #include "libiberty.h"
34 #include "sim-main.h"
35 #include "sim-options.h"
36 #include "sim-io.h"
37 #include "sim-assert.h"
38 #include "version.h"
40 /* Add a set of options to the simulator.
41 TABLE is an array of OPTIONS terminated by a NULL `opt.name' entry.
42 This is intended to be called by modules in their `install' handler. */
44 SIM_RC
45 sim_add_option_table (SIM_DESC sd, sim_cpu *cpu, const OPTION *table)
47 struct option_list *ol = ((struct option_list *)
48 xmalloc (sizeof (struct option_list)));
50 /* Note: The list is constructed in the reverse order we're called so
51 later calls will override earlier ones (in case that ever happens).
52 This is the intended behaviour. */
54 if (cpu)
56 ol->next = CPU_OPTIONS (cpu);
57 ol->options = table;
58 CPU_OPTIONS (cpu) = ol;
60 else
62 ol->next = STATE_OPTIONS (sd);
63 ol->options = table;
64 STATE_OPTIONS (sd) = ol;
67 return SIM_RC_OK;
70 /* Standard option table.
71 Modules may specify additional ones.
72 The caller of sim_parse_args may also specify additional options
73 by calling sim_add_option_table first. */
75 static DECLARE_OPTION_HANDLER (standard_option_handler);
77 /* FIXME: We shouldn't print in --help output options that aren't usable.
78 Some fine tuning will be necessary. One can either move less general
79 options to another table or use a HAVE_FOO macro to ifdef out unavailable
80 options. */
82 /* ??? One might want to conditionally compile out the entries that
83 aren't enabled. There's a distinction, however, between options a
84 simulator can't support and options that haven't been configured in.
85 Certainly options a simulator can't support shouldn't appear in the
86 output of --help. Whether the same thing applies to options that haven't
87 been configured in or not isn't something I can get worked up over.
88 [Note that conditionally compiling them out might simply involve moving
89 the option to another table.]
90 If you decide to conditionally compile them out as well, delete this
91 comment and add a comment saying that that is the rule. */
93 typedef enum {
94 OPTION_DEBUG_INSN = OPTION_START,
95 OPTION_DEBUG_FILE,
96 OPTION_DO_COMMAND,
97 OPTION_ARCHITECTURE,
98 OPTION_TARGET,
99 OPTION_TARGET_INFO,
100 OPTION_ARCHITECTURE_INFO,
101 OPTION_ENVIRONMENT,
102 OPTION_ALIGNMENT,
103 OPTION_VERBOSE,
104 OPTION_ENDIAN,
105 OPTION_DEBUG,
106 OPTION_HELP,
107 OPTION_VERSION,
108 OPTION_LOAD_LMA,
109 OPTION_LOAD_VMA,
110 OPTION_SYSROOT,
111 OPTION_ARGV0,
112 OPTION_ENV_SET,
113 OPTION_ENV_UNSET,
114 OPTION_ENV_CLEAR,
115 } STANDARD_OPTIONS;
117 static const OPTION standard_options[] =
119 { {"verbose", no_argument, NULL, OPTION_VERBOSE},
120 'v', NULL, "Verbose output",
121 standard_option_handler, NULL },
123 { {"endian", required_argument, NULL, OPTION_ENDIAN},
124 'E', "B|big|L|little", "Set endianness",
125 standard_option_handler, NULL },
127 /* This option isn't supported unless all choices are supported in keeping
128 with the goal of not printing in --help output things the simulator can't
129 do [as opposed to things that just haven't been configured in]. */
130 { {"environment", required_argument, NULL, OPTION_ENVIRONMENT},
131 '\0', "user|virtual|operating", "Set running environment",
132 standard_option_handler },
134 { {"alignment", required_argument, NULL, OPTION_ALIGNMENT},
135 '\0', "strict|nonstrict|forced", "Set memory access alignment",
136 standard_option_handler },
138 { {"debug", no_argument, NULL, OPTION_DEBUG},
139 'D', NULL, "Print debugging messages",
140 standard_option_handler },
141 { {"debug-insn", no_argument, NULL, OPTION_DEBUG_INSN},
142 '\0', NULL, "Print instruction debugging messages",
143 standard_option_handler },
144 { {"debug-file", required_argument, NULL, OPTION_DEBUG_FILE},
145 '\0', "FILE NAME", "Specify debugging output file",
146 standard_option_handler },
148 { {"do-command", required_argument, NULL, OPTION_DO_COMMAND},
149 '\0', "COMMAND", ""/*undocumented*/,
150 standard_option_handler },
152 { {"help", no_argument, NULL, OPTION_HELP},
153 'h', NULL, "Print help information",
154 standard_option_handler },
155 { {"version", no_argument, NULL, OPTION_VERSION},
156 '\0', NULL, "Print version information",
157 standard_option_handler },
159 { {"architecture", required_argument, NULL, OPTION_ARCHITECTURE},
160 '\0', "MACHINE", "Specify the architecture to use",
161 standard_option_handler },
162 { {"architecture-info", no_argument, NULL, OPTION_ARCHITECTURE_INFO},
163 '\0', NULL, "List supported architectures",
164 standard_option_handler },
165 { {"info-architecture", no_argument, NULL, OPTION_ARCHITECTURE_INFO},
166 '\0', NULL, NULL,
167 standard_option_handler },
169 { {"target", required_argument, NULL, OPTION_TARGET},
170 '\0', "BFDNAME", "Specify the object-code format for the object files",
171 standard_option_handler },
172 { {"target-info", no_argument, NULL, OPTION_TARGET_INFO},
173 '\0', NULL, "List supported targets", standard_option_handler },
174 { {"info-target", no_argument, NULL, OPTION_TARGET_INFO},
175 '\0', NULL, NULL, standard_option_handler },
177 { {"load-lma", no_argument, NULL, OPTION_LOAD_LMA},
178 '\0', NULL,
179 "Use VMA or LMA addresses when loading image (default LMA)",
180 standard_option_handler, "load-{lma,vma}" },
181 { {"load-vma", no_argument, NULL, OPTION_LOAD_VMA},
182 '\0', NULL, "", standard_option_handler, "" },
184 { {"sysroot", required_argument, NULL, OPTION_SYSROOT},
185 '\0', "SYSROOT",
186 "Root for system calls with absolute file-names and cwd at start",
187 standard_option_handler, NULL },
189 { {"argv0", required_argument, NULL, OPTION_ARGV0},
190 '\0', "ARGV0", "Set argv[0] to the specified string",
191 standard_option_handler, NULL },
193 { {"env-set", required_argument, NULL, OPTION_ENV_SET},
194 '\0', "VAR=VAL", "Set the variable in the program's environment",
195 standard_option_handler, NULL },
196 { {"env-unset", required_argument, NULL, OPTION_ENV_UNSET},
197 '\0', "VAR", "Unset the variable in the program's environment",
198 standard_option_handler, NULL },
199 { {"env-clear", no_argument, NULL, OPTION_ENV_CLEAR},
200 '\0', NULL, "Clear the program's environment",
201 standard_option_handler, NULL },
203 { {NULL, no_argument, NULL, 0}, '\0', NULL, NULL, NULL, NULL }
206 static SIM_RC
207 env_set (SIM_DESC sd, const char *arg)
209 int i, varlen;
210 char *eq;
211 char **envp;
213 if (STATE_PROG_ENVP (sd) == NULL)
214 STATE_PROG_ENVP (sd) = dupargv (environ);
216 eq = strchr (arg, '=');
217 if (eq == NULL)
219 sim_io_eprintf (sd, "invalid syntax when setting env var `%s'"
220 ": missing value", arg);
221 return SIM_RC_FAIL;
223 /* Include the = in the comparison below. */
224 varlen = eq - arg + 1;
226 /* If we can find an existing variable, replace it. */
227 envp = STATE_PROG_ENVP (sd);
228 for (i = 0; envp[i]; ++i)
230 if (strncmp (envp[i], arg, varlen) == 0)
232 free (envp[i]);
233 envp[i] = xstrdup (arg);
234 break;
238 /* If we didn't find the var, add it. */
239 if (envp[i] == NULL)
241 envp = xrealloc (envp, (i + 2) * sizeof (char *));
242 envp[i] = xstrdup (arg);
243 envp[i + 1] = NULL;
244 STATE_PROG_ENVP (sd) = envp;
247 return SIM_RC_OK;
250 static SIM_RC
251 standard_option_handler (SIM_DESC sd, sim_cpu *cpu, int opt,
252 char *arg, int is_command)
254 int i,n;
256 switch ((STANDARD_OPTIONS) opt)
258 case OPTION_VERBOSE:
259 STATE_VERBOSE_P (sd) = 1;
260 break;
262 case OPTION_ENDIAN:
263 if (strcmp (arg, "big") == 0 || strcmp (arg, "B") == 0)
265 if (WITH_TARGET_BYTE_ORDER == BFD_ENDIAN_LITTLE)
267 sim_io_eprintf (sd, "Simulator compiled for little endian only.\n");
268 return SIM_RC_FAIL;
270 /* FIXME:wip: Need to set something in STATE_CONFIG. */
271 current_target_byte_order = BFD_ENDIAN_BIG;
273 else if (strcmp (arg, "little") == 0 || strcmp (arg, "L") == 0)
275 if (WITH_TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
277 sim_io_eprintf (sd, "Simulator compiled for big endian only.\n");
278 return SIM_RC_FAIL;
280 /* FIXME:wip: Need to set something in STATE_CONFIG. */
281 current_target_byte_order = BFD_ENDIAN_LITTLE;
283 else
285 sim_io_eprintf (sd, "Invalid endian specification `%s'\n", arg);
286 return SIM_RC_FAIL;
288 break;
290 case OPTION_ENVIRONMENT:
291 if (strcmp (arg, "user") == 0)
292 STATE_ENVIRONMENT (sd) = USER_ENVIRONMENT;
293 else if (strcmp (arg, "virtual") == 0)
294 STATE_ENVIRONMENT (sd) = VIRTUAL_ENVIRONMENT;
295 else if (strcmp (arg, "operating") == 0)
296 STATE_ENVIRONMENT (sd) = OPERATING_ENVIRONMENT;
297 else
299 sim_io_eprintf (sd, "Invalid environment specification `%s'\n", arg);
300 return SIM_RC_FAIL;
302 if (WITH_ENVIRONMENT != ALL_ENVIRONMENT
303 && WITH_ENVIRONMENT != STATE_ENVIRONMENT (sd))
305 const char *type;
306 switch (WITH_ENVIRONMENT)
308 case USER_ENVIRONMENT: type = "user"; break;
309 case VIRTUAL_ENVIRONMENT: type = "virtual"; break;
310 case OPERATING_ENVIRONMENT: type = "operating"; break;
311 default: abort ();
313 sim_io_eprintf (sd, "Simulator compiled for the %s environment only.\n",
314 type);
315 return SIM_RC_FAIL;
317 break;
319 case OPTION_ALIGNMENT:
320 if (strcmp (arg, "strict") == 0)
322 if (WITH_ALIGNMENT == 0 || WITH_ALIGNMENT == STRICT_ALIGNMENT)
324 current_alignment = STRICT_ALIGNMENT;
325 break;
328 else if (strcmp (arg, "nonstrict") == 0)
330 if (WITH_ALIGNMENT == 0 || WITH_ALIGNMENT == NONSTRICT_ALIGNMENT)
332 current_alignment = NONSTRICT_ALIGNMENT;
333 break;
336 else if (strcmp (arg, "forced") == 0)
338 if (WITH_ALIGNMENT == 0 || WITH_ALIGNMENT == FORCED_ALIGNMENT)
340 current_alignment = FORCED_ALIGNMENT;
341 break;
344 else
346 sim_io_eprintf (sd, "Invalid alignment specification `%s'\n", arg);
347 return SIM_RC_FAIL;
349 switch (WITH_ALIGNMENT)
351 case STRICT_ALIGNMENT:
352 sim_io_eprintf (sd, "Simulator compiled for strict alignment only.\n");
353 break;
354 case NONSTRICT_ALIGNMENT:
355 sim_io_eprintf (sd, "Simulator compiled for nonstrict alignment only.\n");
356 break;
357 case FORCED_ALIGNMENT:
358 sim_io_eprintf (sd, "Simulator compiled for forced alignment only.\n");
359 break;
360 default: abort ();
362 return SIM_RC_FAIL;
364 case OPTION_DEBUG:
365 if (! WITH_DEBUG)
366 sim_io_eprintf (sd, "Debugging not compiled in, `-D' ignored\n");
367 else
369 for (n = 0; n < MAX_NR_PROCESSORS; ++n)
370 for (i = 0; i < MAX_DEBUG_VALUES; ++i)
371 CPU_DEBUG_FLAGS (STATE_CPU (sd, n))[i] = 1;
373 break;
375 case OPTION_DEBUG_INSN :
376 if (! WITH_DEBUG)
377 sim_io_eprintf (sd, "Debugging not compiled in, `--debug-insn' ignored\n");
378 else
380 for (n = 0; n < MAX_NR_PROCESSORS; ++n)
381 CPU_DEBUG_FLAGS (STATE_CPU (sd, n))[DEBUG_INSN_IDX] = 1;
383 break;
385 case OPTION_DEBUG_FILE :
386 if (! WITH_DEBUG)
387 sim_io_eprintf (sd, "Debugging not compiled in, `--debug-file' ignored\n");
388 else
390 FILE *f = fopen (arg, "w");
392 if (f == NULL)
394 sim_io_eprintf (sd, "Unable to open debug output file `%s'\n", arg);
395 return SIM_RC_FAIL;
397 for (n = 0; n < MAX_NR_PROCESSORS; ++n)
398 CPU_DEBUG_FILE (STATE_CPU (sd, n)) = f;
400 break;
402 case OPTION_DO_COMMAND:
403 sim_do_command (sd, arg);
404 break;
406 case OPTION_ARCHITECTURE:
408 const struct bfd_arch_info *ap = bfd_scan_arch (arg);
409 if (ap == NULL)
411 sim_io_eprintf (sd, "Architecture `%s' unknown\n", arg);
412 return SIM_RC_FAIL;
414 STATE_ARCHITECTURE (sd) = ap;
415 break;
418 case OPTION_ARCHITECTURE_INFO:
420 const char **list = bfd_arch_list ();
421 const char **lp;
422 if (list == NULL)
423 abort ();
424 sim_io_printf (sd, "Possible architectures:");
425 for (lp = list; *lp != NULL; lp++)
426 sim_io_printf (sd, " %s", *lp);
427 sim_io_printf (sd, "\n");
428 free (list);
429 break;
432 case OPTION_TARGET:
434 STATE_TARGET (sd) = xstrdup (arg);
435 break;
438 case OPTION_TARGET_INFO:
440 const char **list = bfd_target_list ();
441 const char **lp;
442 if (list == NULL)
443 abort ();
444 sim_io_printf (sd, "Possible targets:");
445 for (lp = list; *lp != NULL; lp++)
446 sim_io_printf (sd, " %s", *lp);
447 sim_io_printf (sd, "\n");
448 free (list);
449 break;
452 case OPTION_LOAD_LMA:
454 STATE_LOAD_AT_LMA_P (sd) = 1;
455 break;
458 case OPTION_LOAD_VMA:
460 STATE_LOAD_AT_LMA_P (sd) = 0;
461 break;
464 case OPTION_HELP:
465 sim_print_help (sd, is_command);
466 if (STATE_OPEN_KIND (sd) == SIM_OPEN_STANDALONE)
467 exit (0);
468 /* FIXME: 'twould be nice to do something similar if gdb. */
469 break;
471 case OPTION_VERSION:
472 sim_print_version (sd, is_command);
473 if (STATE_OPEN_KIND (sd) == SIM_OPEN_STANDALONE)
474 exit (0);
475 break;
477 case OPTION_SYSROOT:
478 /* Don't leak memory in the odd event that there's lots of
479 --sysroot=... options. We treat "" specially since this
480 is the statically initialized value and cannot free it. */
481 if (simulator_sysroot[0] != '\0')
482 free (simulator_sysroot);
483 if (arg[0] != '\0')
484 simulator_sysroot = xstrdup (arg);
485 else
486 simulator_sysroot = "";
487 break;
489 case OPTION_ARGV0:
490 free (STATE_PROG_ARGV0 (sd));
491 STATE_PROG_ARGV0 (sd) = xstrdup (arg);
492 break;
494 case OPTION_ENV_SET:
495 return env_set (sd, arg);
497 case OPTION_ENV_UNSET:
499 int i, varlen;
500 char **envp;
502 if (STATE_PROG_ENVP (sd) == NULL)
503 STATE_PROG_ENVP (sd) = dupargv (environ);
505 varlen = strlen (arg);
507 /* If we can find an existing variable, replace it. */
508 envp = STATE_PROG_ENVP (sd);
509 for (i = 0; envp[i]; ++i)
511 char *env = envp[i];
513 if (strncmp (env, arg, varlen) == 0
514 && (env[varlen] == '\0' || env[varlen] == '='))
516 free (envp[i]);
517 break;
521 /* If we clear the var, shift the array down. */
522 for (; envp[i]; ++i)
523 envp[i] = envp[i + 1];
525 break;
528 case OPTION_ENV_CLEAR:
529 freeargv (STATE_PROG_ENVP (sd));
530 STATE_PROG_ENVP (sd) = xmalloc (sizeof (char *));
531 STATE_PROG_ENVP (sd)[0] = NULL;
532 break;
535 return SIM_RC_OK;
538 /* Add the standard option list to the simulator. */
540 SIM_RC
541 standard_install (SIM_DESC sd)
543 SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
544 if (sim_add_option_table (sd, NULL, standard_options) != SIM_RC_OK)
545 return SIM_RC_FAIL;
546 STATE_LOAD_AT_LMA_P (sd) = 1;
547 return SIM_RC_OK;
550 /* Return non-zero if arg is a duplicate argument.
551 If ARG is NULL, initialize. */
553 static int
554 dup_arg_p (const char *arg)
556 static htab_t arg_table = NULL;
557 void **slot;
559 if (arg == NULL)
561 if (arg_table == NULL)
562 arg_table = htab_create_alloc (10, htab_hash_string,
563 htab_eq_string, NULL,
564 xcalloc, free);
565 htab_empty (arg_table);
566 return 0;
569 slot = htab_find_slot (arg_table, arg, INSERT);
570 if (*slot != NULL)
571 return 1;
572 *slot = (void *) arg;
573 return 0;
576 /* Called by sim_open to parse the arguments. */
578 SIM_RC
579 sim_parse_args (SIM_DESC sd, char * const *argv)
581 int c, i, argc, num_opts, save_opterr;
582 char *p, *short_options;
583 /* The `val' option struct entry is dynamically assigned for options that
584 only come in the long form. ORIG_VAL is used to get the original value
585 back. */
586 int *orig_val;
587 struct option *lp, *long_options;
588 const struct option_list *ol;
589 const OPTION *opt;
590 OPTION_HANDLER **handlers;
591 sim_cpu **opt_cpu;
592 SIM_RC result = SIM_RC_OK;
594 /* Count the number of arguments. */
595 argc = countargv (argv);
597 /* Count the number of options. */
598 num_opts = 0;
599 for (ol = STATE_OPTIONS (sd); ol != NULL; ol = ol->next)
600 for (opt = ol->options; OPTION_VALID_P (opt); ++opt)
601 ++num_opts;
602 for (i = 0; i < MAX_NR_PROCESSORS; ++i)
603 for (ol = CPU_OPTIONS (STATE_CPU (sd, i)); ol != NULL; ol = ol->next)
604 for (opt = ol->options; OPTION_VALID_P (opt); ++opt)
605 ++num_opts;
607 /* Initialize duplicate argument checker. */
608 (void) dup_arg_p (NULL);
610 /* Build the option table for getopt. */
612 long_options = NZALLOC (struct option, num_opts + 1);
613 lp = long_options;
614 short_options = NZALLOC (char, num_opts * 3 + 1);
615 p = short_options;
616 handlers = NZALLOC (OPTION_HANDLER *, OPTION_START + num_opts);
617 orig_val = NZALLOC (int, OPTION_START + num_opts);
618 opt_cpu = NZALLOC (sim_cpu *, OPTION_START + num_opts);
620 /* Set '+' as first char so argument permutation isn't done. This
621 is done to stop getopt_long returning options that appear after
622 the target program. Such options should be passed unchanged into
623 the program image. */
624 *p++ = '+';
626 for (i = OPTION_START, ol = STATE_OPTIONS (sd); ol != NULL; ol = ol->next)
627 for (opt = ol->options; OPTION_VALID_P (opt); ++opt)
629 if (dup_arg_p (opt->opt.name))
630 continue;
631 if (opt->shortopt != 0)
633 *p++ = opt->shortopt;
634 if (opt->opt.has_arg == required_argument)
635 *p++ = ':';
636 else if (opt->opt.has_arg == optional_argument)
637 { *p++ = ':'; *p++ = ':'; }
638 handlers[(unsigned char) opt->shortopt] = opt->handler;
639 if (opt->opt.val != 0)
640 orig_val[(unsigned char) opt->shortopt] = opt->opt.val;
641 else
642 orig_val[(unsigned char) opt->shortopt] = opt->shortopt;
644 if (opt->opt.name != NULL)
646 *lp = opt->opt;
647 /* Dynamically assign `val' numbers for long options. */
648 lp->val = i++;
649 handlers[lp->val] = opt->handler;
650 orig_val[lp->val] = opt->opt.val;
651 opt_cpu[lp->val] = NULL;
652 ++lp;
656 for (c = 0; c < MAX_NR_PROCESSORS; ++c)
658 sim_cpu *cpu = STATE_CPU (sd, c);
659 for (ol = CPU_OPTIONS (cpu); ol != NULL; ol = ol->next)
660 for (opt = ol->options; OPTION_VALID_P (opt); ++opt)
662 #if 0 /* Each option is prepended with --<cpuname>- so this greatly cuts down
663 on the need for dup_arg_p checking. Maybe in the future it'll be
664 needed so this is just commented out, and not deleted. */
665 if (dup_arg_p (opt->opt.name))
666 continue;
667 #endif
668 /* Don't allow short versions of cpu specific options for now. */
669 if (opt->shortopt != 0)
671 sim_io_eprintf (sd, "internal error, short cpu specific option");
672 result = SIM_RC_FAIL;
673 break;
675 if (opt->opt.name != NULL)
677 char *name;
678 *lp = opt->opt;
679 /* Prepend --<cpuname>- to the option. */
680 if (asprintf (&name, "%s-%s", CPU_NAME (cpu), lp->name) < 0)
682 sim_io_eprintf (sd, "internal error, out of memory");
683 result = SIM_RC_FAIL;
684 break;
686 lp->name = name;
687 /* Dynamically assign `val' numbers for long options. */
688 lp->val = i++;
689 handlers[lp->val] = opt->handler;
690 orig_val[lp->val] = opt->opt.val;
691 opt_cpu[lp->val] = cpu;
692 ++lp;
697 /* Terminate the short and long option lists. */
698 *p = 0;
699 lp->name = NULL;
701 /* Ensure getopt is initialized. */
702 optind = 0;
704 /* Do not lot getopt throw errors for us. But don't mess with the state for
705 any callers higher up by saving/restoring it. */
706 save_opterr = opterr;
707 opterr = 0;
709 while (1)
711 int longind, optc;
713 optc = getopt_long (argc, argv, short_options, long_options, &longind);
714 if (optc == -1)
716 if (STATE_OPEN_KIND (sd) == SIM_OPEN_STANDALONE)
718 char **new_argv;
720 free (STATE_PROG_FILE (sd));
721 STATE_PROG_FILE (sd) = NULL;
723 /* Handle any inline variables if -- wasn't used. */
724 if (argv[optind] != NULL && optind > 0
725 && strcmp (argv[optind - 1], "--") != 0)
727 while (1)
729 const char *arg = argv[optind];
731 if (strchr (arg, '=') == NULL)
732 break;
734 env_set (sd, arg);
735 ++optind;
739 new_argv = dupargv (argv + optind);
740 freeargv (STATE_PROG_ARGV (sd));
741 STATE_PROG_ARGV (sd) = new_argv;
743 /* Skip steps when argc == 0. */
744 if (argv[optind] != NULL)
746 STATE_PROG_FILE (sd) = xstrdup (argv[optind]);
748 if (STATE_PROG_ARGV0 (sd) != NULL)
750 free (new_argv[0]);
751 new_argv[0] = xstrdup (STATE_PROG_ARGV0 (sd));
755 break;
757 if (optc == '?')
759 /* If getopt rejects a short option, optopt is set to the bad char.
760 If it rejects a long option, we have to look at optind. In the
761 short option case, argv could be multiple short options. */
762 const char *badopt;
763 char optbuf[3];
765 if (optopt)
767 sprintf (optbuf, "-%c", optopt);
768 badopt = optbuf;
770 else
771 badopt = argv[optind - 1];
773 sim_io_eprintf (sd,
774 "%s: unrecognized option '%s'\n"
775 "Use --help for a complete list of options.\n",
776 STATE_MY_NAME (sd), badopt);
778 result = SIM_RC_FAIL;
779 break;
782 if ((*handlers[optc]) (sd, opt_cpu[optc], orig_val[optc], optarg, 0/*!is_command*/) == SIM_RC_FAIL)
784 result = SIM_RC_FAIL;
785 break;
789 opterr = save_opterr;
791 free (long_options);
792 free (short_options);
793 free (handlers);
794 free (opt_cpu);
795 free (orig_val);
796 return result;
799 /* Utility of sim_print_help to print a list of option tables. */
801 static void
802 print_help (SIM_DESC sd, sim_cpu *cpu, const struct option_list *ol, int is_command)
804 const OPTION *opt;
806 for ( ; ol != NULL; ol = ol->next)
807 for (opt = ol->options; OPTION_VALID_P (opt); ++opt)
809 const int indent = 30;
810 int comma, len;
811 const OPTION *o;
813 if (dup_arg_p (opt->opt.name))
814 continue;
816 if (opt->doc == NULL)
817 continue;
819 if (opt->doc_name != NULL && opt->doc_name [0] == '\0')
820 continue;
822 sim_io_printf (sd, " ");
824 comma = 0;
825 len = 2;
827 /* list any short options (aliases) for the current OPT */
828 if (!is_command)
830 o = opt;
833 if (o->shortopt != '\0')
835 sim_io_printf (sd, "%s-%c", comma ? ", " : "", o->shortopt);
836 len += (comma ? 2 : 0) + 2;
837 if (o->arg != NULL)
839 if (o->opt.has_arg == optional_argument)
841 sim_io_printf (sd, "[%s]", o->arg);
842 len += 1 + strlen (o->arg) + 1;
844 else
846 sim_io_printf (sd, " %s", o->arg);
847 len += 1 + strlen (o->arg);
850 comma = 1;
852 ++o;
854 while (OPTION_VALID_P (o) && o->doc == NULL);
857 /* list any long options (aliases) for the current OPT */
858 o = opt;
861 const char *name;
862 const char *cpu_prefix = cpu ? CPU_NAME (cpu) : NULL;
863 if (o->doc_name != NULL)
864 name = o->doc_name;
865 else
866 name = o->opt.name;
867 if (name != NULL)
869 sim_io_printf (sd, "%s%s%s%s%s",
870 comma ? ", " : "",
871 is_command ? "" : "--",
872 cpu ? cpu_prefix : "",
873 cpu ? "-" : "",
874 name);
875 len += ((comma ? 2 : 0)
876 + (is_command ? 0 : 2)
877 + strlen (name));
878 if (o->arg != NULL)
880 if (o->opt.has_arg == optional_argument)
882 sim_io_printf (sd, "[=%s]", o->arg);
883 len += 2 + strlen (o->arg) + 1;
885 else
887 sim_io_printf (sd, " %s", o->arg);
888 len += 1 + strlen (o->arg);
891 comma = 1;
893 ++o;
895 while (OPTION_VALID_P (o) && o->doc == NULL);
897 if (len >= indent)
899 sim_io_printf (sd, "\n%*s", indent, "");
901 else
902 sim_io_printf (sd, "%*s", indent - len, "");
904 /* print the description, word wrap long lines */
906 const char *chp = opt->doc;
907 unsigned doc_width = 80 - indent;
908 while (strlen (chp) >= doc_width) /* some slack */
910 const char *end = chp + doc_width - 1;
911 while (end > chp && !isspace (*end))
912 end --;
913 if (end == chp)
914 end = chp + doc_width - 1;
915 /* The cast should be ok - its distances between to
916 points in a string. */
917 sim_io_printf (sd, "%.*s\n%*s", (int) (end - chp), chp, indent,
918 "");
919 chp = end;
920 while (isspace (*chp) && *chp != '\0')
921 chp++;
923 sim_io_printf (sd, "%s\n", chp);
928 /* Print help messages for the options. */
930 void
931 sim_print_help (SIM_DESC sd, int is_command)
933 if (STATE_OPEN_KIND (sd) == SIM_OPEN_STANDALONE)
934 sim_io_printf (sd,
935 "Usage: %s [options] [VAR=VAL|--] program [program args]\n",
936 STATE_MY_NAME (sd));
938 /* Initialize duplicate argument checker. */
939 (void) dup_arg_p (NULL);
941 if (STATE_OPEN_KIND (sd) == SIM_OPEN_STANDALONE)
942 sim_io_printf (sd, "Options:\n");
943 else
944 sim_io_printf (sd, "Commands:\n");
946 print_help (sd, NULL, STATE_OPTIONS (sd), is_command);
947 sim_io_printf (sd, "\n");
949 /* Print cpu-specific options. */
951 int i;
953 for (i = 0; i < MAX_NR_PROCESSORS; ++i)
955 sim_cpu *cpu = STATE_CPU (sd, i);
956 if (CPU_OPTIONS (cpu) == NULL)
957 continue;
958 sim_io_printf (sd, "CPU %s specific options:\n", CPU_NAME (cpu));
959 print_help (sd, cpu, CPU_OPTIONS (cpu), is_command);
960 sim_io_printf (sd, "\n");
964 sim_io_printf (sd, "Note: Depending on the simulator configuration some %ss\n",
965 STATE_OPEN_KIND (sd) == SIM_OPEN_STANDALONE ? "option" : "command");
966 sim_io_printf (sd, " may not be applicable\n");
968 if (STATE_OPEN_KIND (sd) == SIM_OPEN_STANDALONE)
970 sim_io_printf (sd, "\n");
971 sim_io_printf (sd,
972 "VAR=VAL Environment variables to set. "
973 "Ignored if -- is used.\n");
974 sim_io_printf (sd, "program args Arguments to pass to simulated program.\n");
975 sim_io_printf (sd, " Note: Very few simulators support this.\n");
979 /* Print version information. */
981 void
982 sim_print_version (SIM_DESC sd, int is_command)
984 sim_io_printf (sd, "GNU simulator %s%s\n", PKGVERSION, version);
986 sim_io_printf (sd, "Copyright (C) 2023 Free Software Foundation, Inc.\n");
988 /* Following the copyright is a brief statement that the program is
989 free software, that users are free to copy and change it on
990 certain conditions, that it is covered by the GNU GPL, and that
991 there is no warranty. */
993 sim_io_printf (sd, "\
994 License GPLv3+: GNU GPL version 3 or later <https://gnu.org/licenses/gpl.html>\
995 \nThis is free software: you are free to change and redistribute it.\n\
996 There is NO WARRANTY, to the extent permitted by law.\n");
998 if (!is_command)
999 return;
1001 sim_io_printf (sd, "This SIM was configured as:\n");
1002 sim_config_print (sd);
1004 if (REPORT_BUGS_TO[0])
1006 sim_io_printf (sd, "For bug reporting instructions, please see:\n\
1007 %s.\n",
1008 REPORT_BUGS_TO);
1010 sim_io_printf (sd, "Find the SIM homepage & other documentation resources \
1011 online at:\n <https://sourceware.org/gdb/wiki/Sim/>.\n");
1014 /* Utility of sim_args_command to find the closest match for a command.
1015 Commands that have "-" in them can be specified as separate words.
1016 e.g. sim memory-region 0x800000,0x4000
1017 or sim memory region 0x800000,0x4000
1018 If CPU is non-null, use its option table list, otherwise use the main one.
1019 *PARGI is where to start looking in ARGV. It is updated to point past
1020 the found option. */
1022 static const OPTION *
1023 find_match (SIM_DESC sd, sim_cpu *cpu, char *argv[], int *pargi)
1025 const struct option_list *ol;
1026 const OPTION *opt;
1027 /* most recent option match */
1028 const OPTION *matching_opt = NULL;
1029 int matching_argi = -1;
1031 if (cpu)
1032 ol = CPU_OPTIONS (cpu);
1033 else
1034 ol = STATE_OPTIONS (sd);
1036 /* Skip passed elements specified by *PARGI. */
1037 argv += *pargi;
1039 for ( ; ol != NULL; ol = ol->next)
1040 for (opt = ol->options; OPTION_VALID_P (opt); ++opt)
1042 int argi = 0;
1043 const char *name = opt->opt.name;
1044 if (name == NULL)
1045 continue;
1046 while (argv [argi] != NULL
1047 && strncmp (name, argv [argi], strlen (argv [argi])) == 0)
1049 name = &name [strlen (argv[argi])];
1050 if (name [0] == '-')
1052 /* leading match ...<a-b-c>-d-e-f - continue search */
1053 name ++; /* skip `-' */
1054 argi ++;
1055 continue;
1057 else if (name [0] == '\0')
1059 /* exact match ...<a-b-c-d-e-f> - better than before? */
1060 if (argi > matching_argi)
1062 matching_argi = argi;
1063 matching_opt = opt;
1065 break;
1067 else
1068 break;
1072 *pargi = matching_argi;
1073 return matching_opt;
1076 static char **
1077 complete_option_list (char **ret, size_t *cnt, const struct option_list *ol,
1078 const char *text, const char *word)
1080 const OPTION *opt = NULL;
1081 int argi;
1082 size_t len = strlen (word);
1084 for ( ; ol != NULL; ol = ol->next)
1085 for (opt = ol->options; OPTION_VALID_P (opt); ++opt)
1087 const char *name = opt->opt.name;
1089 /* A long option to match against? */
1090 if (!name)
1091 continue;
1093 /* Does this option actually match? */
1094 if (strncmp (name, word, len))
1095 continue;
1097 ret = xrealloc (ret, ++*cnt * sizeof (ret[0]));
1098 ret[*cnt - 2] = xstrdup (name);
1101 return ret;
1104 /* All leading text is stored in @text, while the current word being
1105 completed is stored in @word. Trailing text of @word is not. */
1107 char **
1108 sim_complete_command (SIM_DESC sd, const char *text, const char *word)
1110 char **ret = NULL;
1111 size_t cnt = 1;
1112 sim_cpu *cpu;
1114 /* Only complete first word for now. */
1115 if (text != word)
1116 return ret;
1118 cpu = STATE_CPU (sd, 0);
1119 if (cpu)
1120 ret = complete_option_list (ret, &cnt, CPU_OPTIONS (cpu), text, word);
1121 ret = complete_option_list (ret, &cnt, STATE_OPTIONS (sd), text, word);
1123 if (ret)
1124 ret[cnt - 1] = NULL;
1125 return ret;
1128 SIM_RC
1129 sim_args_command (SIM_DESC sd, const char *cmd)
1131 /* something to do? */
1132 if (cmd == NULL)
1133 return SIM_RC_OK; /* FIXME - perhaps help would be better */
1135 if (cmd [0] == '-')
1137 /* user specified -<opt> ... form? */
1138 char **argv = buildargv (cmd);
1139 SIM_RC rc = sim_parse_args (sd, argv);
1140 freeargv (argv);
1141 return rc;
1143 else
1145 char **argv = buildargv (cmd);
1146 const OPTION *matching_opt = NULL;
1147 int matching_argi;
1148 sim_cpu *cpu;
1150 if (argv [0] == NULL)
1152 freeargv (argv);
1153 return SIM_RC_OK; /* FIXME - perhaps help would be better */
1156 /* First check for a cpu selector. */
1158 char *cpu_name = xstrdup (argv[0]);
1159 char *hyphen = strchr (cpu_name, '-');
1160 if (hyphen)
1161 *hyphen = 0;
1162 cpu = sim_cpu_lookup (sd, cpu_name);
1163 if (cpu)
1165 /* If <cpuname>-<command>, point argv[0] at <command>. */
1166 if (hyphen)
1168 matching_argi = 0;
1169 argv[0] += hyphen - cpu_name + 1;
1171 else
1172 matching_argi = 1;
1173 matching_opt = find_match (sd, cpu, argv, &matching_argi);
1174 /* If hyphen found restore argv[0]. */
1175 if (hyphen)
1176 argv[0] -= hyphen - cpu_name + 1;
1178 free (cpu_name);
1181 /* If that failed, try the main table. */
1182 if (matching_opt == NULL)
1184 matching_argi = 0;
1185 matching_opt = find_match (sd, NULL, argv, &matching_argi);
1188 if (matching_opt != NULL)
1190 switch (matching_opt->opt.has_arg)
1192 case no_argument:
1193 if (argv [matching_argi + 1] == NULL)
1194 matching_opt->handler (sd, cpu, matching_opt->opt.val,
1195 NULL, 1/*is_command*/);
1196 else
1197 sim_io_eprintf (sd, "Command `%s' takes no arguments\n",
1198 matching_opt->opt.name);
1199 break;
1200 case optional_argument:
1201 if (argv [matching_argi + 1] == NULL)
1202 matching_opt->handler (sd, cpu, matching_opt->opt.val,
1203 NULL, 1/*is_command*/);
1204 else if (argv [matching_argi + 2] == NULL)
1205 matching_opt->handler (sd, cpu, matching_opt->opt.val,
1206 argv [matching_argi + 1], 1/*is_command*/);
1207 else
1208 sim_io_eprintf (sd, "Command `%s' requires no more than one argument\n",
1209 matching_opt->opt.name);
1210 break;
1211 case required_argument:
1212 if (argv [matching_argi + 1] == NULL)
1213 sim_io_eprintf (sd, "Command `%s' requires an argument\n",
1214 matching_opt->opt.name);
1215 else if (argv [matching_argi + 2] == NULL)
1216 matching_opt->handler (sd, cpu, matching_opt->opt.val,
1217 argv [matching_argi + 1], 1/*is_command*/);
1218 else
1219 sim_io_eprintf (sd, "Command `%s' requires only one argument\n",
1220 matching_opt->opt.name);
1222 freeargv (argv);
1223 return SIM_RC_OK;
1226 freeargv (argv);
1229 /* didn't find anything that remotly matched */
1230 return SIM_RC_FAIL;