Automatic Copyright Year update after running gdb/copyright.py
[deliverable/binutils-gdb.git] / sim / common / sim-options.c
CommitLineData
c906108c 1/* Simulator option handling.
88b9d363 2 Copyright (C) 1996-2022 Free Software Foundation, Inc.
c906108c
SS
3 Contributed by Cygnus Support.
4
5This file is part of GDB, the GNU debugger.
6
7This program is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
4744ac1b
JB
9the Free Software Foundation; either version 3 of the License, or
10(at your option) any later version.
c906108c
SS
11
12This program is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
4744ac1b
JB
17You should have received a copy of the GNU General Public License
18along with this program. If not, see <http://www.gnu.org/licenses/>. */
c906108c 19
6df01ab8
MF
20/* This must come before any other includes. */
21#include "defs.h"
22
c906108c 23#include "sim-main.h"
c906108c 24#include <string.h>
c906108c 25#include <stdlib.h>
c906108c 26#include <ctype.h>
b6061d4d 27#include <stdio.h>
c906108c
SS
28#include "libiberty.h"
29#include "sim-options.h"
30#include "sim-io.h"
31#include "sim-assert.h"
a542beff 32#include "version.h"
4478c331 33#include "hashtab.h"
c906108c
SS
34
35#include "bfd.h"
36
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. */
40
41SIM_RC
42sim_add_option_table (SIM_DESC sd, sim_cpu *cpu, const OPTION *table)
43{
44 struct option_list *ol = ((struct option_list *)
45 xmalloc (sizeof (struct option_list)));
46
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. */
50
51 if (cpu)
52 {
53 ol->next = CPU_OPTIONS (cpu);
54 ol->options = table;
55 CPU_OPTIONS (cpu) = ol;
56 }
57 else
58 {
59 ol->next = STATE_OPTIONS (sd);
60 ol->options = table;
61 STATE_OPTIONS (sd) = ol;
62 }
63
64 return SIM_RC_OK;
65}
66
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. */
71
72static DECLARE_OPTION_HANDLER (standard_option_handler);
73
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
77 options. */
78
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. */
89
90typedef enum {
91 OPTION_DEBUG_INSN = OPTION_START,
92 OPTION_DEBUG_FILE,
93 OPTION_DO_COMMAND,
94 OPTION_ARCHITECTURE,
95 OPTION_TARGET,
96 OPTION_ARCHITECTURE_INFO,
97 OPTION_ENVIRONMENT,
98 OPTION_ALIGNMENT,
99 OPTION_VERBOSE,
c906108c 100 OPTION_ENDIAN,
c906108c 101 OPTION_DEBUG,
c906108c 102 OPTION_HELP,
a542beff 103 OPTION_VERSION,
43e526b9
JM
104 OPTION_LOAD_LMA,
105 OPTION_LOAD_VMA,
027e2a04 106 OPTION_SYSROOT
c906108c
SS
107} STANDARD_OPTIONS;
108
109static const OPTION standard_options[] =
110{
111 { {"verbose", no_argument, NULL, OPTION_VERBOSE},
112 'v', NULL, "Verbose output",
21cf617c 113 standard_option_handler, NULL },
c906108c 114
c906108c
SS
115 { {"endian", required_argument, NULL, OPTION_ENDIAN},
116 'E', "big|little", "Set endianness",
21cf617c 117 standard_option_handler, NULL },
c906108c 118
c906108c
SS
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 },
c906108c
SS
125
126 { {"alignment", required_argument, NULL, OPTION_ALIGNMENT},
127 '\0', "strict|nonstrict|forced", "Set memory access alignment",
128 standard_option_handler },
129
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 },
139
c906108c
SS
140 { {"do-command", required_argument, NULL, OPTION_DO_COMMAND},
141 '\0', "COMMAND", ""/*undocumented*/,
142 standard_option_handler },
143
144 { {"help", no_argument, NULL, OPTION_HELP},
145 'H', NULL, "Print help information",
146 standard_option_handler },
a542beff
MF
147 { {"version", no_argument, NULL, OPTION_VERSION},
148 '\0', NULL, "Print version information",
149 standard_option_handler },
c906108c
SS
150
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},
158 '\0', NULL, NULL,
159 standard_option_handler },
160
161 { {"target", required_argument, NULL, OPTION_TARGET},
162 '\0', "BFDNAME", "Specify the object-code format for the object files",
163 standard_option_handler },
164
43e526b9
JM
165 { {"load-lma", no_argument, NULL, OPTION_LOAD_LMA},
166 '\0', NULL,
43e526b9 167 "Use VMA or LMA addresses when loading image (default LMA)",
43e526b9
JM
168 standard_option_handler, "load-{lma,vma}" },
169 { {"load-vma", no_argument, NULL, OPTION_LOAD_VMA},
170 '\0', NULL, "", standard_option_handler, "" },
43e526b9 171
027e2a04
HPN
172 { {"sysroot", required_argument, NULL, OPTION_SYSROOT},
173 '\0', "SYSROOT",
174 "Root for system calls with absolute file-names and cwd at start",
21cf617c 175 standard_option_handler, NULL },
027e2a04 176
21cf617c 177 { {NULL, no_argument, NULL, 0}, '\0', NULL, NULL, NULL, NULL }
c906108c
SS
178};
179
180static SIM_RC
181standard_option_handler (SIM_DESC sd, sim_cpu *cpu, int opt,
182 char *arg, int is_command)
183{
184 int i,n;
185
186 switch ((STANDARD_OPTIONS) opt)
187 {
188 case OPTION_VERBOSE:
189 STATE_VERBOSE_P (sd) = 1;
190 break;
191
c906108c
SS
192 case OPTION_ENDIAN:
193 if (strcmp (arg, "big") == 0)
194 {
1ac72f06 195 if (WITH_TARGET_BYTE_ORDER == BFD_ENDIAN_LITTLE)
c906108c
SS
196 {
197 sim_io_eprintf (sd, "Simulator compiled for little endian only.\n");
198 return SIM_RC_FAIL;
199 }
200 /* FIXME:wip: Need to set something in STATE_CONFIG. */
1ac72f06 201 current_target_byte_order = BFD_ENDIAN_BIG;
c906108c
SS
202 }
203 else if (strcmp (arg, "little") == 0)
204 {
1ac72f06 205 if (WITH_TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
c906108c
SS
206 {
207 sim_io_eprintf (sd, "Simulator compiled for big endian only.\n");
208 return SIM_RC_FAIL;
209 }
210 /* FIXME:wip: Need to set something in STATE_CONFIG. */
1ac72f06 211 current_target_byte_order = BFD_ENDIAN_LITTLE;
c906108c
SS
212 }
213 else
214 {
215 sim_io_eprintf (sd, "Invalid endian specification `%s'\n", arg);
216 return SIM_RC_FAIL;
217 }
218 break;
c906108c
SS
219
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;
227 else
228 {
229 sim_io_eprintf (sd, "Invalid environment specification `%s'\n", arg);
230 return SIM_RC_FAIL;
231 }
232 if (WITH_ENVIRONMENT != ALL_ENVIRONMENT
233 && WITH_ENVIRONMENT != STATE_ENVIRONMENT (sd))
234 {
3dd68605 235 const char *type;
c906108c
SS
236 switch (WITH_ENVIRONMENT)
237 {
238 case USER_ENVIRONMENT: type = "user"; break;
239 case VIRTUAL_ENVIRONMENT: type = "virtual"; break;
240 case OPERATING_ENVIRONMENT: type = "operating"; break;
72042732 241 default: abort ();
c906108c
SS
242 }
243 sim_io_eprintf (sd, "Simulator compiled for the %s environment only.\n",
244 type);
245 return SIM_RC_FAIL;
246 }
247 break;
248
249 case OPTION_ALIGNMENT:
250 if (strcmp (arg, "strict") == 0)
251 {
252 if (WITH_ALIGNMENT == 0 || WITH_ALIGNMENT == STRICT_ALIGNMENT)
253 {
254 current_alignment = STRICT_ALIGNMENT;
255 break;
256 }
257 }
258 else if (strcmp (arg, "nonstrict") == 0)
259 {
260 if (WITH_ALIGNMENT == 0 || WITH_ALIGNMENT == NONSTRICT_ALIGNMENT)
261 {
262 current_alignment = NONSTRICT_ALIGNMENT;
263 break;
264 }
265 }
266 else if (strcmp (arg, "forced") == 0)
267 {
268 if (WITH_ALIGNMENT == 0 || WITH_ALIGNMENT == FORCED_ALIGNMENT)
269 {
270 current_alignment = FORCED_ALIGNMENT;
271 break;
272 }
273 }
274 else
275 {
276 sim_io_eprintf (sd, "Invalid alignment specification `%s'\n", arg);
277 return SIM_RC_FAIL;
278 }
279 switch (WITH_ALIGNMENT)
280 {
281 case STRICT_ALIGNMENT:
282 sim_io_eprintf (sd, "Simulator compiled for strict alignment only.\n");
283 break;
284 case NONSTRICT_ALIGNMENT:
285 sim_io_eprintf (sd, "Simulator compiled for nonstrict alignment only.\n");
286 break;
287 case FORCED_ALIGNMENT:
288 sim_io_eprintf (sd, "Simulator compiled for forced alignment only.\n");
289 break;
72042732 290 default: abort ();
c906108c
SS
291 }
292 return SIM_RC_FAIL;
293
294 case OPTION_DEBUG:
295 if (! WITH_DEBUG)
296 sim_io_eprintf (sd, "Debugging not compiled in, `-D' ignored\n");
297 else
298 {
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;
302 }
303 break;
304
305 case OPTION_DEBUG_INSN :
306 if (! WITH_DEBUG)
307 sim_io_eprintf (sd, "Debugging not compiled in, `--debug-insn' ignored\n");
308 else
309 {
310 for (n = 0; n < MAX_NR_PROCESSORS; ++n)
311 CPU_DEBUG_FLAGS (STATE_CPU (sd, n))[DEBUG_INSN_IDX] = 1;
312 }
313 break;
314
315 case OPTION_DEBUG_FILE :
316 if (! WITH_DEBUG)
317 sim_io_eprintf (sd, "Debugging not compiled in, `--debug-file' ignored\n");
318 else
319 {
320 FILE *f = fopen (arg, "w");
321
322 if (f == NULL)
323 {
324 sim_io_eprintf (sd, "Unable to open debug output file `%s'\n", arg);
325 return SIM_RC_FAIL;
326 }
327 for (n = 0; n < MAX_NR_PROCESSORS; ++n)
328 CPU_DEBUG_FILE (STATE_CPU (sd, n)) = f;
329 }
330 break;
331
c906108c
SS
332 case OPTION_DO_COMMAND:
333 sim_do_command (sd, arg);
334 break;
335
336 case OPTION_ARCHITECTURE:
337 {
338 const struct bfd_arch_info *ap = bfd_scan_arch (arg);
339 if (ap == NULL)
340 {
341 sim_io_eprintf (sd, "Architecture `%s' unknown\n", arg);
342 return SIM_RC_FAIL;
343 }
344 STATE_ARCHITECTURE (sd) = ap;
345 break;
346 }
347
348 case OPTION_ARCHITECTURE_INFO:
349 {
34b47c38 350 const char **list = bfd_arch_list ();
c906108c
SS
351 const char **lp;
352 if (list == NULL)
353 abort ();
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");
358 free (list);
359 break;
360 }
361
362 case OPTION_TARGET:
363 {
364 STATE_TARGET (sd) = xstrdup (arg);
365 break;
366 }
367
43e526b9
JM
368 case OPTION_LOAD_LMA:
369 {
370 STATE_LOAD_AT_LMA_P (sd) = 1;
371 break;
372 }
373
374 case OPTION_LOAD_VMA:
375 {
376 STATE_LOAD_AT_LMA_P (sd) = 0;
377 break;
378 }
379
c906108c
SS
380 case OPTION_HELP:
381 sim_print_help (sd, is_command);
382 if (STATE_OPEN_KIND (sd) == SIM_OPEN_STANDALONE)
383 exit (0);
384 /* FIXME: 'twould be nice to do something similar if gdb. */
385 break;
027e2a04 386
a542beff 387 case OPTION_VERSION:
19b1c385 388 sim_print_version (sd, is_command);
a542beff
MF
389 if (STATE_OPEN_KIND (sd) == SIM_OPEN_STANDALONE)
390 exit (0);
391 break;
392
027e2a04
HPN
393 case OPTION_SYSROOT:
394 /* Don't leak memory in the odd event that there's lots of
440db575
MF
395 --sysroot=... options. We treat "" specially since this
396 is the statically initialized value and cannot free it. */
397 if (simulator_sysroot[0] != '\0')
027e2a04 398 free (simulator_sysroot);
440db575
MF
399 if (arg[0] != '\0')
400 simulator_sysroot = xstrdup (arg);
401 else
402 simulator_sysroot = "";
027e2a04 403 break;
c906108c
SS
404 }
405
406 return SIM_RC_OK;
407}
408
409/* Add the standard option list to the simulator. */
410
411SIM_RC
412standard_install (SIM_DESC sd)
413{
414 SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
415 if (sim_add_option_table (sd, NULL, standard_options) != SIM_RC_OK)
416 return SIM_RC_FAIL;
26936211 417 STATE_LOAD_AT_LMA_P (sd) = 1;
c906108c
SS
418 return SIM_RC_OK;
419}
420
421/* Return non-zero if arg is a duplicate argument.
422 If ARG is NULL, initialize. */
423
c906108c 424static int
e377ca52 425dup_arg_p (const char *arg)
c906108c 426{
4478c331
TT
427 static htab_t arg_table = NULL;
428 void **slot;
c906108c
SS
429
430 if (arg == NULL)
431 {
432 if (arg_table == NULL)
4478c331 433 arg_table = htab_create_alloc (10, htab_hash_string,
65a9835b 434 htab_eq_string, NULL,
4478c331 435 xcalloc, free);
e4821e2f 436 htab_empty (arg_table);
c906108c
SS
437 return 0;
438 }
439
4478c331
TT
440 slot = htab_find_slot (arg_table, arg, INSERT);
441 if (*slot != NULL)
442 return 1;
443 *slot = (void *) arg;
c906108c
SS
444 return 0;
445}
028f6515 446
c906108c
SS
447/* Called by sim_open to parse the arguments. */
448
449SIM_RC
2e3d4f4d 450sim_parse_args (SIM_DESC sd, char * const *argv)
c906108c 451{
77cf2ef5 452 int c, i, argc, num_opts, save_opterr;
c906108c
SS
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
456 back. */
457 int *orig_val;
458 struct option *lp, *long_options;
459 const struct option_list *ol;
460 const OPTION *opt;
461 OPTION_HANDLER **handlers;
462 sim_cpu **opt_cpu;
7c070881 463 SIM_RC result = SIM_RC_OK;
c906108c
SS
464
465 /* Count the number of arguments. */
34fed699 466 argc = countargv (argv);
c906108c
SS
467
468 /* Count the number of options. */
469 num_opts = 0;
470 for (ol = STATE_OPTIONS (sd); ol != NULL; ol = ol->next)
471 for (opt = ol->options; OPTION_VALID_P (opt); ++opt)
472 ++num_opts;
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)
476 ++num_opts;
477
478 /* Initialize duplicate argument checker. */
479 (void) dup_arg_p (NULL);
480
481 /* Build the option table for getopt. */
482
483 long_options = NZALLOC (struct option, num_opts + 1);
484 lp = long_options;
485 short_options = NZALLOC (char, num_opts * 3 + 1);
486 p = short_options;
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);
490
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. */
495 *p++ = '+';
496
497 for (i = OPTION_START, ol = STATE_OPTIONS (sd); ol != NULL; ol = ol->next)
498 for (opt = ol->options; OPTION_VALID_P (opt); ++opt)
499 {
500 if (dup_arg_p (opt->opt.name))
501 continue;
502 if (opt->shortopt != 0)
503 {
504 *p++ = opt->shortopt;
505 if (opt->opt.has_arg == required_argument)
506 *p++ = ':';
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;
512 else
513 orig_val[(unsigned char) opt->shortopt] = opt->shortopt;
514 }
515 if (opt->opt.name != NULL)
516 {
517 *lp = opt->opt;
518 /* Dynamically assign `val' numbers for long options. */
519 lp->val = i++;
520 handlers[lp->val] = opt->handler;
521 orig_val[lp->val] = opt->opt.val;
522 opt_cpu[lp->val] = NULL;
523 ++lp;
524 }
525 }
526
527 for (c = 0; c < MAX_NR_PROCESSORS; ++c)
528 {
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)
532 {
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))
537 continue;
538#endif
539 /* Don't allow short versions of cpu specific options for now. */
540 if (opt->shortopt != 0)
541 {
542 sim_io_eprintf (sd, "internal error, short cpu specific option");
7c070881
SC
543 result = SIM_RC_FAIL;
544 break;
c906108c
SS
545 }
546 if (opt->opt.name != NULL)
547 {
548 char *name;
549 *lp = opt->opt;
550 /* Prepend --<cpuname>- to the option. */
39a3ae0a
MF
551 if (asprintf (&name, "%s-%s", CPU_NAME (cpu), lp->name) < 0)
552 {
553 sim_io_eprintf (sd, "internal error, out of memory");
554 result = SIM_RC_FAIL;
555 break;
556 }
c906108c
SS
557 lp->name = name;
558 /* Dynamically assign `val' numbers for long options. */
559 lp->val = i++;
560 handlers[lp->val] = opt->handler;
561 orig_val[lp->val] = opt->opt.val;
562 opt_cpu[lp->val] = cpu;
563 ++lp;
564 }
565 }
566 }
028f6515 567
c906108c
SS
568 /* Terminate the short and long option lists. */
569 *p = 0;
570 lp->name = NULL;
571
572 /* Ensure getopt is initialized. */
573 optind = 0;
574
77cf2ef5
MF
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;
578 opterr = 0;
579
c906108c
SS
580 while (1)
581 {
582 int longind, optc;
583
584 optc = getopt_long (argc, argv, short_options, long_options, &longind);
585 if (optc == -1)
586 {
587 if (STATE_OPEN_KIND (sd) == SIM_OPEN_STANDALONE)
588 STATE_PROG_ARGV (sd) = dupargv (argv + optind);
589 break;
590 }
591 if (optc == '?')
7c070881 592 {
77cf2ef5
MF
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. */
596 const char *badopt;
597 char optbuf[3];
598
599 if (optopt)
600 {
601 sprintf (optbuf, "-%c", optopt);
602 badopt = optbuf;
603 }
604 else
605 badopt = argv[optind - 1];
606
607 sim_io_eprintf (sd,
8d7d784e 608 "%s: unrecognized option '%s'\n"
77cf2ef5
MF
609 "Use --help for a complete list of options.\n",
610 STATE_MY_NAME (sd), badopt);
611
7c070881
SC
612 result = SIM_RC_FAIL;
613 break;
614 }
c906108c
SS
615
616 if ((*handlers[optc]) (sd, opt_cpu[optc], orig_val[optc], optarg, 0/*!is_command*/) == SIM_RC_FAIL)
7c070881
SC
617 {
618 result = SIM_RC_FAIL;
619 break;
620 }
c906108c
SS
621 }
622
77cf2ef5
MF
623 opterr = save_opterr;
624
d79fe0d6
MF
625 free (long_options);
626 free (short_options);
627 free (handlers);
628 free (opt_cpu);
629 free (orig_val);
7c070881 630 return result;
c906108c
SS
631}
632
633/* Utility of sim_print_help to print a list of option tables. */
634
635static void
636print_help (SIM_DESC sd, sim_cpu *cpu, const struct option_list *ol, int is_command)
637{
638 const OPTION *opt;
639
640 for ( ; ol != NULL; ol = ol->next)
641 for (opt = ol->options; OPTION_VALID_P (opt); ++opt)
642 {
643 const int indent = 30;
644 int comma, len;
645 const OPTION *o;
646
647 if (dup_arg_p (opt->opt.name))
648 continue;
649
650 if (opt->doc == NULL)
651 continue;
652
653 if (opt->doc_name != NULL && opt->doc_name [0] == '\0')
654 continue;
655
656 sim_io_printf (sd, " ");
657
658 comma = 0;
659 len = 2;
660
661 /* list any short options (aliases) for the current OPT */
662 if (!is_command)
663 {
664 o = opt;
665 do
666 {
667 if (o->shortopt != '\0')
668 {
669 sim_io_printf (sd, "%s-%c", comma ? ", " : "", o->shortopt);
670 len += (comma ? 2 : 0) + 2;
671 if (o->arg != NULL)
672 {
673 if (o->opt.has_arg == optional_argument)
674 {
675 sim_io_printf (sd, "[%s]", o->arg);
676 len += 1 + strlen (o->arg) + 1;
677 }
678 else
679 {
680 sim_io_printf (sd, " %s", o->arg);
681 len += 1 + strlen (o->arg);
682 }
683 }
684 comma = 1;
685 }
686 ++o;
687 }
688 while (OPTION_VALID_P (o) && o->doc == NULL);
689 }
028f6515 690
c906108c
SS
691 /* list any long options (aliases) for the current OPT */
692 o = opt;
693 do
694 {
695 const char *name;
696 const char *cpu_prefix = cpu ? CPU_NAME (cpu) : NULL;
697 if (o->doc_name != NULL)
698 name = o->doc_name;
699 else
700 name = o->opt.name;
701 if (name != NULL)
702 {
703 sim_io_printf (sd, "%s%s%s%s%s",
704 comma ? ", " : "",
705 is_command ? "" : "--",
706 cpu ? cpu_prefix : "",
707 cpu ? "-" : "",
708 name);
709 len += ((comma ? 2 : 0)
710 + (is_command ? 0 : 2)
711 + strlen (name));
712 if (o->arg != NULL)
713 {
714 if (o->opt.has_arg == optional_argument)
715 {
c4093a6a 716 sim_io_printf (sd, "[=%s]", o->arg);
c906108c
SS
717 len += 2 + strlen (o->arg) + 1;
718 }
719 else
720 {
721 sim_io_printf (sd, " %s", o->arg);
722 len += 1 + strlen (o->arg);
723 }
724 }
725 comma = 1;
726 }
727 ++o;
728 }
729 while (OPTION_VALID_P (o) && o->doc == NULL);
730
731 if (len >= indent)
732 {
733 sim_io_printf (sd, "\n%*s", indent, "");
734 }
735 else
736 sim_io_printf (sd, "%*s", indent - len, "");
737
738 /* print the description, word wrap long lines */
739 {
740 const char *chp = opt->doc;
741 unsigned doc_width = 80 - indent;
742 while (strlen (chp) >= doc_width) /* some slack */
743 {
744 const char *end = chp + doc_width - 1;
745 while (end > chp && !isspace (*end))
746 end --;
747 if (end == chp)
748 end = chp + doc_width - 1;
e158f0a0
AC
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,
752 "");
c906108c
SS
753 chp = end;
754 while (isspace (*chp) && *chp != '\0')
755 chp++;
756 }
757 sim_io_printf (sd, "%s\n", chp);
758 }
759 }
760}
761
762/* Print help messages for the options. */
763
764void
dc416615 765sim_print_help (SIM_DESC sd, int is_command)
c906108c
SS
766{
767 if (STATE_OPEN_KIND (sd) == SIM_OPEN_STANDALONE)
768 sim_io_printf (sd, "Usage: %s [options] program [program args]\n",
769 STATE_MY_NAME (sd));
770
771 /* Initialize duplicate argument checker. */
772 (void) dup_arg_p (NULL);
773
774 if (STATE_OPEN_KIND (sd) == SIM_OPEN_STANDALONE)
775 sim_io_printf (sd, "Options:\n");
776 else
777 sim_io_printf (sd, "Commands:\n");
778
779 print_help (sd, NULL, STATE_OPTIONS (sd), is_command);
780 sim_io_printf (sd, "\n");
781
782 /* Print cpu-specific options. */
783 {
784 int i;
785
786 for (i = 0; i < MAX_NR_PROCESSORS; ++i)
787 {
788 sim_cpu *cpu = STATE_CPU (sd, i);
789 if (CPU_OPTIONS (cpu) == NULL)
790 continue;
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");
794 }
795 }
796
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");
800
801 if (STATE_OPEN_KIND (sd) == SIM_OPEN_STANDALONE)
802 {
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");
806 }
807}
808
19b1c385
MF
809/* Print version information. */
810
811void
812sim_print_version (SIM_DESC sd, int is_command)
813{
814 sim_io_printf (sd, "GNU simulator %s%s\n", PKGVERSION, version);
815
816 sim_io_printf (sd, "Copyright (C) 2021 Free Software Foundation, Inc.\n");
817
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. */
822
823 sim_io_printf (sd, "\
824License 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\
826There is NO WARRANTY, to the extent permitted by law.\n");
babd2ee1
MF
827
828 if (!is_command)
829 return;
830
831 sim_io_printf (sd, "This SIM was configured as:\n");
832 sim_config_print (sd);
833
834 if (REPORT_BUGS_TO[0])
835 {
836 sim_io_printf (sd, "For bug reporting instructions, please see:\n\
837 %s.\n",
838 REPORT_BUGS_TO);
839 }
840 sim_io_printf (sd, "Find the SIM homepage & other documentation resources \
841online at:\n <https://sourceware.org/gdb/wiki/Sim/>.\n");
19b1c385
MF
842}
843
c906108c
SS
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
850 the found option. */
851
852static const OPTION *
853find_match (SIM_DESC sd, sim_cpu *cpu, char *argv[], int *pargi)
854{
855 const struct option_list *ol;
856 const OPTION *opt;
857 /* most recent option match */
858 const OPTION *matching_opt = NULL;
859 int matching_argi = -1;
860
861 if (cpu)
862 ol = CPU_OPTIONS (cpu);
863 else
864 ol = STATE_OPTIONS (sd);
865
866 /* Skip passed elements specified by *PARGI. */
867 argv += *pargi;
868
869 for ( ; ol != NULL; ol = ol->next)
870 for (opt = ol->options; OPTION_VALID_P (opt); ++opt)
871 {
872 int argi = 0;
873 const char *name = opt->opt.name;
874 if (name == NULL)
875 continue;
876 while (argv [argi] != NULL
877 && strncmp (name, argv [argi], strlen (argv [argi])) == 0)
878 {
879 name = &name [strlen (argv[argi])];
880 if (name [0] == '-')
881 {
882 /* leading match ...<a-b-c>-d-e-f - continue search */
883 name ++; /* skip `-' */
884 argi ++;
885 continue;
886 }
887 else if (name [0] == '\0')
888 {
889 /* exact match ...<a-b-c-d-e-f> - better than before? */
890 if (argi > matching_argi)
891 {
892 matching_argi = argi;
893 matching_opt = opt;
894 }
895 break;
896 }
897 else
898 break;
899 }
900 }
901
902 *pargi = matching_argi;
903 return matching_opt;
904}
905
56a9aa1d
MF
906static char **
907complete_option_list (char **ret, size_t *cnt, const struct option_list *ol,
f06dccb0 908 const char *text, const char *word)
56a9aa1d
MF
909{
910 const OPTION *opt = NULL;
911 int argi;
912 size_t len = strlen (word);
913
914 for ( ; ol != NULL; ol = ol->next)
915 for (opt = ol->options; OPTION_VALID_P (opt); ++opt)
916 {
917 const char *name = opt->opt.name;
918
919 /* A long option to match against? */
920 if (!name)
921 continue;
922
923 /* Does this option actually match? */
924 if (strncmp (name, word, len))
925 continue;
926
927 ret = xrealloc (ret, ++*cnt * sizeof (ret[0]));
928 ret[*cnt - 2] = xstrdup (name);
929 }
930
931 return ret;
932}
933
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. */
5592f70e 936
56a9aa1d 937char **
3cb2ab1a 938sim_complete_command (SIM_DESC sd, const char *text, const char *word)
56a9aa1d
MF
939{
940 char **ret = NULL;
941 size_t cnt = 1;
942 sim_cpu *cpu;
943
944 /* Only complete first word for now. */
945 if (text != word)
946 return ret;
947
948 cpu = STATE_CPU (sd, 0);
949 if (cpu)
950 ret = complete_option_list (ret, &cnt, CPU_OPTIONS (cpu), text, word);
951 ret = complete_option_list (ret, &cnt, STATE_OPTIONS (sd), text, word);
952
953 if (ret)
954 ret[cnt - 1] = NULL;
955 return ret;
956}
957
c906108c 958SIM_RC
60d847df 959sim_args_command (SIM_DESC sd, const char *cmd)
c906108c
SS
960{
961 /* something to do? */
962 if (cmd == NULL)
109d3db3 963 return SIM_RC_OK; /* FIXME - perhaps help would be better */
028f6515 964
c906108c
SS
965 if (cmd [0] == '-')
966 {
967 /* user specified -<opt> ... form? */
968 char **argv = buildargv (cmd);
969 SIM_RC rc = sim_parse_args (sd, argv);
970 freeargv (argv);
971 return rc;
972 }
973 else
974 {
975 char **argv = buildargv (cmd);
976 const OPTION *matching_opt = NULL;
977 int matching_argi;
978 sim_cpu *cpu;
979
980 if (argv [0] == NULL)
c9ba137e
CG
981 {
982 freeargv (argv);
983 return SIM_RC_OK; /* FIXME - perhaps help would be better */
984 }
c906108c
SS
985
986 /* First check for a cpu selector. */
987 {
988 char *cpu_name = xstrdup (argv[0]);
989 char *hyphen = strchr (cpu_name, '-');
990 if (hyphen)
991 *hyphen = 0;
992 cpu = sim_cpu_lookup (sd, cpu_name);
993 if (cpu)
994 {
995 /* If <cpuname>-<command>, point argv[0] at <command>. */
996 if (hyphen)
997 {
998 matching_argi = 0;
999 argv[0] += hyphen - cpu_name + 1;
1000 }
1001 else
1002 matching_argi = 1;
1003 matching_opt = find_match (sd, cpu, argv, &matching_argi);
1004 /* If hyphen found restore argv[0]. */
1005 if (hyphen)
1006 argv[0] -= hyphen - cpu_name + 1;
1007 }
1008 free (cpu_name);
1009 }
1010
1011 /* If that failed, try the main table. */
1012 if (matching_opt == NULL)
1013 {
1014 matching_argi = 0;
1015 matching_opt = find_match (sd, NULL, argv, &matching_argi);
1016 }
1017
1018 if (matching_opt != NULL)
1019 {
1020 switch (matching_opt->opt.has_arg)
1021 {
1022 case no_argument:
1023 if (argv [matching_argi + 1] == NULL)
1024 matching_opt->handler (sd, cpu, matching_opt->opt.val,
1025 NULL, 1/*is_command*/);
1026 else
1027 sim_io_eprintf (sd, "Command `%s' takes no arguments\n",
1028 matching_opt->opt.name);
1029 break;
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*/);
1037 else
1038 sim_io_eprintf (sd, "Command `%s' requires no more than one argument\n",
1039 matching_opt->opt.name);
1040 break;
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*/);
1048 else
1049 sim_io_eprintf (sd, "Command `%s' requires only one argument\n",
1050 matching_opt->opt.name);
1051 }
1052 freeargv (argv);
1053 return SIM_RC_OK;
1054 }
1055
1056 freeargv (argv);
1057 }
028f6515 1058
c906108c
SS
1059 /* didn't find anything that remotly matched */
1060 return SIM_RC_FAIL;
1061}
This page took 1.092243 seconds and 4 git commands to generate.