Automatic Copyright Year update after running gdb/copyright.py
[deliverable/binutils-gdb.git] / sim / common / sim-options.c
1 /* Simulator option handling.
2 Copyright (C) 1996-2022 Free Software Foundation, Inc.
3 Contributed by Cygnus Support.
4
5 This file is part of GDB, the GNU debugger.
6
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.
11
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.
16
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/>. */
19
20 /* This must come before any other includes. */
21 #include "defs.h"
22
23 #include "sim-main.h"
24 #include <string.h>
25 #include <stdlib.h>
26 #include <ctype.h>
27 #include <stdio.h>
28 #include "libiberty.h"
29 #include "sim-options.h"
30 #include "sim-io.h"
31 #include "sim-assert.h"
32 #include "version.h"
33 #include "hashtab.h"
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
41 SIM_RC
42 sim_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
72 static 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
90 typedef 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,
100 OPTION_ENDIAN,
101 OPTION_DEBUG,
102 OPTION_HELP,
103 OPTION_VERSION,
104 OPTION_LOAD_LMA,
105 OPTION_LOAD_VMA,
106 OPTION_SYSROOT
107 } STANDARD_OPTIONS;
108
109 static const OPTION standard_options[] =
110 {
111 { {"verbose", no_argument, NULL, OPTION_VERBOSE},
112 'v', NULL, "Verbose output",
113 standard_option_handler, NULL },
114
115 { {"endian", required_argument, NULL, OPTION_ENDIAN},
116 'E', "big|little", "Set endianness",
117 standard_option_handler, NULL },
118
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 },
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
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 },
147 { {"version", no_argument, NULL, OPTION_VERSION},
148 '\0', NULL, "Print version information",
149 standard_option_handler },
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
165 { {"load-lma", no_argument, NULL, OPTION_LOAD_LMA},
166 '\0', NULL,
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, "" },
171
172 { {"sysroot", required_argument, NULL, OPTION_SYSROOT},
173 '\0', "SYSROOT",
174 "Root for system calls with absolute file-names and cwd at start",
175 standard_option_handler, NULL },
176
177 { {NULL, no_argument, NULL, 0}, '\0', NULL, NULL, NULL, NULL }
178 };
179
180 static SIM_RC
181 standard_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
192 case OPTION_ENDIAN:
193 if (strcmp (arg, "big") == 0)
194 {
195 if (WITH_TARGET_BYTE_ORDER == BFD_ENDIAN_LITTLE)
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. */
201 current_target_byte_order = BFD_ENDIAN_BIG;
202 }
203 else if (strcmp (arg, "little") == 0)
204 {
205 if (WITH_TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
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. */
211 current_target_byte_order = BFD_ENDIAN_LITTLE;
212 }
213 else
214 {
215 sim_io_eprintf (sd, "Invalid endian specification `%s'\n", arg);
216 return SIM_RC_FAIL;
217 }
218 break;
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 {
235 const char *type;
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;
241 default: abort ();
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;
290 default: abort ();
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
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 {
350 const char **list = bfd_arch_list ();
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
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
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;
386
387 case OPTION_VERSION:
388 sim_print_version (sd, is_command);
389 if (STATE_OPEN_KIND (sd) == SIM_OPEN_STANDALONE)
390 exit (0);
391 break;
392
393 case OPTION_SYSROOT:
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);
399 if (arg[0] != '\0')
400 simulator_sysroot = xstrdup (arg);
401 else
402 simulator_sysroot = "";
403 break;
404 }
405
406 return SIM_RC_OK;
407 }
408
409 /* Add the standard option list to the simulator. */
410
411 SIM_RC
412 standard_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;
417 STATE_LOAD_AT_LMA_P (sd) = 1;
418 return SIM_RC_OK;
419 }
420
421 /* Return non-zero if arg is a duplicate argument.
422 If ARG is NULL, initialize. */
423
424 static int
425 dup_arg_p (const char *arg)
426 {
427 static htab_t arg_table = NULL;
428 void **slot;
429
430 if (arg == NULL)
431 {
432 if (arg_table == NULL)
433 arg_table = htab_create_alloc (10, htab_hash_string,
434 htab_eq_string, NULL,
435 xcalloc, free);
436 htab_empty (arg_table);
437 return 0;
438 }
439
440 slot = htab_find_slot (arg_table, arg, INSERT);
441 if (*slot != NULL)
442 return 1;
443 *slot = (void *) arg;
444 return 0;
445 }
446
447 /* Called by sim_open to parse the arguments. */
448
449 SIM_RC
450 sim_parse_args (SIM_DESC sd, char * const *argv)
451 {
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
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;
463 SIM_RC result = SIM_RC_OK;
464
465 /* Count the number of arguments. */
466 argc = countargv (argv);
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");
543 result = SIM_RC_FAIL;
544 break;
545 }
546 if (opt->opt.name != NULL)
547 {
548 char *name;
549 *lp = opt->opt;
550 /* Prepend --<cpuname>- to the option. */
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 }
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 }
567
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
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
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 == '?')
592 {
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,
608 "%s: unrecognized option '%s'\n"
609 "Use --help for a complete list of options.\n",
610 STATE_MY_NAME (sd), badopt);
611
612 result = SIM_RC_FAIL;
613 break;
614 }
615
616 if ((*handlers[optc]) (sd, opt_cpu[optc], orig_val[optc], optarg, 0/*!is_command*/) == SIM_RC_FAIL)
617 {
618 result = SIM_RC_FAIL;
619 break;
620 }
621 }
622
623 opterr = save_opterr;
624
625 free (long_options);
626 free (short_options);
627 free (handlers);
628 free (opt_cpu);
629 free (orig_val);
630 return result;
631 }
632
633 /* Utility of sim_print_help to print a list of option tables. */
634
635 static void
636 print_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 }
690
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 {
716 sim_io_printf (sd, "[=%s]", o->arg);
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;
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 "");
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
764 void
765 sim_print_help (SIM_DESC sd, int is_command)
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
809 /* Print version information. */
810
811 void
812 sim_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, "\
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");
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 \
841 online at:\n <https://sourceware.org/gdb/wiki/Sim/>.\n");
842 }
843
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
852 static const OPTION *
853 find_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
906 static char **
907 complete_option_list (char **ret, size_t *cnt, const struct option_list *ol,
908 const char *text, const char *word)
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. */
936
937 char **
938 sim_complete_command (SIM_DESC sd, const char *text, const char *word)
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
958 SIM_RC
959 sim_args_command (SIM_DESC sd, const char *cmd)
960 {
961 /* something to do? */
962 if (cmd == NULL)
963 return SIM_RC_OK; /* FIXME - perhaps help would be better */
964
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)
981 {
982 freeargv (argv);
983 return SIM_RC_OK; /* FIXME - perhaps help would be better */
984 }
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 }
1058
1059 /* didn't find anything that remotly matched */
1060 return SIM_RC_FAIL;
1061 }
This page took 0.050994 seconds and 4 git commands to generate.