sim: add default cases to two switches in sim-options.c
[deliverable/binutils-gdb.git] / sim / common / sim-options.c
1 /* Simulator option handling.
2 Copyright (C) 1996-2021 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 #include "config.h"
21 #include "sim-main.h"
22 #include <string.h>
23 #include <stdlib.h>
24 #include <ctype.h>
25 #include <stdio.h>
26 #include "libiberty.h"
27 #include "sim-options.h"
28 #include "sim-io.h"
29 #include "sim-assert.h"
30 #include "version.h"
31 #include "hashtab.h"
32
33 #include "bfd.h"
34
35 /* Add a set of options to the simulator.
36 TABLE is an array of OPTIONS terminated by a NULL `opt.name' entry.
37 This is intended to be called by modules in their `install' handler. */
38
39 SIM_RC
40 sim_add_option_table (SIM_DESC sd, sim_cpu *cpu, const OPTION *table)
41 {
42 struct option_list *ol = ((struct option_list *)
43 xmalloc (sizeof (struct option_list)));
44
45 /* Note: The list is constructed in the reverse order we're called so
46 later calls will override earlier ones (in case that ever happens).
47 This is the intended behaviour. */
48
49 if (cpu)
50 {
51 ol->next = CPU_OPTIONS (cpu);
52 ol->options = table;
53 CPU_OPTIONS (cpu) = ol;
54 }
55 else
56 {
57 ol->next = STATE_OPTIONS (sd);
58 ol->options = table;
59 STATE_OPTIONS (sd) = ol;
60 }
61
62 return SIM_RC_OK;
63 }
64
65 /* Standard option table.
66 Modules may specify additional ones.
67 The caller of sim_parse_args may also specify additional options
68 by calling sim_add_option_table first. */
69
70 static DECLARE_OPTION_HANDLER (standard_option_handler);
71
72 /* FIXME: We shouldn't print in --help output options that aren't usable.
73 Some fine tuning will be necessary. One can either move less general
74 options to another table or use a HAVE_FOO macro to ifdef out unavailable
75 options. */
76
77 /* ??? One might want to conditionally compile out the entries that
78 aren't enabled. There's a distinction, however, between options a
79 simulator can't support and options that haven't been configured in.
80 Certainly options a simulator can't support shouldn't appear in the
81 output of --help. Whether the same thing applies to options that haven't
82 been configured in or not isn't something I can get worked up over.
83 [Note that conditionally compiling them out might simply involve moving
84 the option to another table.]
85 If you decide to conditionally compile them out as well, delete this
86 comment and add a comment saying that that is the rule. */
87
88 typedef enum {
89 OPTION_DEBUG_INSN = OPTION_START,
90 OPTION_DEBUG_FILE,
91 OPTION_DO_COMMAND,
92 OPTION_ARCHITECTURE,
93 OPTION_TARGET,
94 OPTION_ARCHITECTURE_INFO,
95 OPTION_ENVIRONMENT,
96 OPTION_ALIGNMENT,
97 OPTION_VERBOSE,
98 OPTION_ENDIAN,
99 OPTION_DEBUG,
100 OPTION_HELP,
101 OPTION_VERSION,
102 OPTION_LOAD_LMA,
103 OPTION_LOAD_VMA,
104 OPTION_SYSROOT
105 } STANDARD_OPTIONS;
106
107 static const OPTION standard_options[] =
108 {
109 { {"verbose", no_argument, NULL, OPTION_VERBOSE},
110 'v', NULL, "Verbose output",
111 standard_option_handler, NULL },
112
113 { {"endian", required_argument, NULL, OPTION_ENDIAN},
114 'E', "big|little", "Set endianness",
115 standard_option_handler, NULL },
116
117 /* This option isn't supported unless all choices are supported in keeping
118 with the goal of not printing in --help output things the simulator can't
119 do [as opposed to things that just haven't been configured in]. */
120 { {"environment", required_argument, NULL, OPTION_ENVIRONMENT},
121 '\0', "user|virtual|operating", "Set running environment",
122 standard_option_handler },
123
124 { {"alignment", required_argument, NULL, OPTION_ALIGNMENT},
125 '\0', "strict|nonstrict|forced", "Set memory access alignment",
126 standard_option_handler },
127
128 { {"debug", no_argument, NULL, OPTION_DEBUG},
129 'D', NULL, "Print debugging messages",
130 standard_option_handler },
131 { {"debug-insn", no_argument, NULL, OPTION_DEBUG_INSN},
132 '\0', NULL, "Print instruction debugging messages",
133 standard_option_handler },
134 { {"debug-file", required_argument, NULL, OPTION_DEBUG_FILE},
135 '\0', "FILE NAME", "Specify debugging output file",
136 standard_option_handler },
137
138 { {"do-command", required_argument, NULL, OPTION_DO_COMMAND},
139 '\0', "COMMAND", ""/*undocumented*/,
140 standard_option_handler },
141
142 { {"help", no_argument, NULL, OPTION_HELP},
143 'H', NULL, "Print help information",
144 standard_option_handler },
145 { {"version", no_argument, NULL, OPTION_VERSION},
146 '\0', NULL, "Print version information",
147 standard_option_handler },
148
149 { {"architecture", required_argument, NULL, OPTION_ARCHITECTURE},
150 '\0', "MACHINE", "Specify the architecture to use",
151 standard_option_handler },
152 { {"architecture-info", no_argument, NULL, OPTION_ARCHITECTURE_INFO},
153 '\0', NULL, "List supported architectures",
154 standard_option_handler },
155 { {"info-architecture", no_argument, NULL, OPTION_ARCHITECTURE_INFO},
156 '\0', NULL, NULL,
157 standard_option_handler },
158
159 { {"target", required_argument, NULL, OPTION_TARGET},
160 '\0', "BFDNAME", "Specify the object-code format for the object files",
161 standard_option_handler },
162
163 { {"load-lma", no_argument, NULL, OPTION_LOAD_LMA},
164 '\0', NULL,
165 "Use VMA or LMA addresses when loading image (default LMA)",
166 standard_option_handler, "load-{lma,vma}" },
167 { {"load-vma", no_argument, NULL, OPTION_LOAD_VMA},
168 '\0', NULL, "", standard_option_handler, "" },
169
170 { {"sysroot", required_argument, NULL, OPTION_SYSROOT},
171 '\0', "SYSROOT",
172 "Root for system calls with absolute file-names and cwd at start",
173 standard_option_handler, NULL },
174
175 { {NULL, no_argument, NULL, 0}, '\0', NULL, NULL, NULL, NULL }
176 };
177
178 static SIM_RC
179 standard_option_handler (SIM_DESC sd, sim_cpu *cpu, int opt,
180 char *arg, int is_command)
181 {
182 int i,n;
183
184 switch ((STANDARD_OPTIONS) opt)
185 {
186 case OPTION_VERBOSE:
187 STATE_VERBOSE_P (sd) = 1;
188 break;
189
190 case OPTION_ENDIAN:
191 if (strcmp (arg, "big") == 0)
192 {
193 if (WITH_TARGET_BYTE_ORDER == BFD_ENDIAN_LITTLE)
194 {
195 sim_io_eprintf (sd, "Simulator compiled for little endian only.\n");
196 return SIM_RC_FAIL;
197 }
198 /* FIXME:wip: Need to set something in STATE_CONFIG. */
199 current_target_byte_order = BFD_ENDIAN_BIG;
200 }
201 else if (strcmp (arg, "little") == 0)
202 {
203 if (WITH_TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
204 {
205 sim_io_eprintf (sd, "Simulator compiled for big endian only.\n");
206 return SIM_RC_FAIL;
207 }
208 /* FIXME:wip: Need to set something in STATE_CONFIG. */
209 current_target_byte_order = BFD_ENDIAN_LITTLE;
210 }
211 else
212 {
213 sim_io_eprintf (sd, "Invalid endian specification `%s'\n", arg);
214 return SIM_RC_FAIL;
215 }
216 break;
217
218 case OPTION_ENVIRONMENT:
219 if (strcmp (arg, "user") == 0)
220 STATE_ENVIRONMENT (sd) = USER_ENVIRONMENT;
221 else if (strcmp (arg, "virtual") == 0)
222 STATE_ENVIRONMENT (sd) = VIRTUAL_ENVIRONMENT;
223 else if (strcmp (arg, "operating") == 0)
224 STATE_ENVIRONMENT (sd) = OPERATING_ENVIRONMENT;
225 else
226 {
227 sim_io_eprintf (sd, "Invalid environment specification `%s'\n", arg);
228 return SIM_RC_FAIL;
229 }
230 if (WITH_ENVIRONMENT != ALL_ENVIRONMENT
231 && WITH_ENVIRONMENT != STATE_ENVIRONMENT (sd))
232 {
233 const char *type;
234 switch (WITH_ENVIRONMENT)
235 {
236 case USER_ENVIRONMENT: type = "user"; break;
237 case VIRTUAL_ENVIRONMENT: type = "virtual"; break;
238 case OPERATING_ENVIRONMENT: type = "operating"; break;
239 default: abort ();
240 }
241 sim_io_eprintf (sd, "Simulator compiled for the %s environment only.\n",
242 type);
243 return SIM_RC_FAIL;
244 }
245 break;
246
247 case OPTION_ALIGNMENT:
248 if (strcmp (arg, "strict") == 0)
249 {
250 if (WITH_ALIGNMENT == 0 || WITH_ALIGNMENT == STRICT_ALIGNMENT)
251 {
252 current_alignment = STRICT_ALIGNMENT;
253 break;
254 }
255 }
256 else if (strcmp (arg, "nonstrict") == 0)
257 {
258 if (WITH_ALIGNMENT == 0 || WITH_ALIGNMENT == NONSTRICT_ALIGNMENT)
259 {
260 current_alignment = NONSTRICT_ALIGNMENT;
261 break;
262 }
263 }
264 else if (strcmp (arg, "forced") == 0)
265 {
266 if (WITH_ALIGNMENT == 0 || WITH_ALIGNMENT == FORCED_ALIGNMENT)
267 {
268 current_alignment = FORCED_ALIGNMENT;
269 break;
270 }
271 }
272 else
273 {
274 sim_io_eprintf (sd, "Invalid alignment specification `%s'\n", arg);
275 return SIM_RC_FAIL;
276 }
277 switch (WITH_ALIGNMENT)
278 {
279 case STRICT_ALIGNMENT:
280 sim_io_eprintf (sd, "Simulator compiled for strict alignment only.\n");
281 break;
282 case NONSTRICT_ALIGNMENT:
283 sim_io_eprintf (sd, "Simulator compiled for nonstrict alignment only.\n");
284 break;
285 case FORCED_ALIGNMENT:
286 sim_io_eprintf (sd, "Simulator compiled for forced alignment only.\n");
287 break;
288 default: abort ();
289 }
290 return SIM_RC_FAIL;
291
292 case OPTION_DEBUG:
293 if (! WITH_DEBUG)
294 sim_io_eprintf (sd, "Debugging not compiled in, `-D' ignored\n");
295 else
296 {
297 for (n = 0; n < MAX_NR_PROCESSORS; ++n)
298 for (i = 0; i < MAX_DEBUG_VALUES; ++i)
299 CPU_DEBUG_FLAGS (STATE_CPU (sd, n))[i] = 1;
300 }
301 break;
302
303 case OPTION_DEBUG_INSN :
304 if (! WITH_DEBUG)
305 sim_io_eprintf (sd, "Debugging not compiled in, `--debug-insn' ignored\n");
306 else
307 {
308 for (n = 0; n < MAX_NR_PROCESSORS; ++n)
309 CPU_DEBUG_FLAGS (STATE_CPU (sd, n))[DEBUG_INSN_IDX] = 1;
310 }
311 break;
312
313 case OPTION_DEBUG_FILE :
314 if (! WITH_DEBUG)
315 sim_io_eprintf (sd, "Debugging not compiled in, `--debug-file' ignored\n");
316 else
317 {
318 FILE *f = fopen (arg, "w");
319
320 if (f == NULL)
321 {
322 sim_io_eprintf (sd, "Unable to open debug output file `%s'\n", arg);
323 return SIM_RC_FAIL;
324 }
325 for (n = 0; n < MAX_NR_PROCESSORS; ++n)
326 CPU_DEBUG_FILE (STATE_CPU (sd, n)) = f;
327 }
328 break;
329
330 case OPTION_DO_COMMAND:
331 sim_do_command (sd, arg);
332 break;
333
334 case OPTION_ARCHITECTURE:
335 {
336 const struct bfd_arch_info *ap = bfd_scan_arch (arg);
337 if (ap == NULL)
338 {
339 sim_io_eprintf (sd, "Architecture `%s' unknown\n", arg);
340 return SIM_RC_FAIL;
341 }
342 STATE_ARCHITECTURE (sd) = ap;
343 break;
344 }
345
346 case OPTION_ARCHITECTURE_INFO:
347 {
348 const char **list = bfd_arch_list ();
349 const char **lp;
350 if (list == NULL)
351 abort ();
352 sim_io_printf (sd, "Possible architectures:");
353 for (lp = list; *lp != NULL; lp++)
354 sim_io_printf (sd, " %s", *lp);
355 sim_io_printf (sd, "\n");
356 free (list);
357 break;
358 }
359
360 case OPTION_TARGET:
361 {
362 STATE_TARGET (sd) = xstrdup (arg);
363 break;
364 }
365
366 case OPTION_LOAD_LMA:
367 {
368 STATE_LOAD_AT_LMA_P (sd) = 1;
369 break;
370 }
371
372 case OPTION_LOAD_VMA:
373 {
374 STATE_LOAD_AT_LMA_P (sd) = 0;
375 break;
376 }
377
378 case OPTION_HELP:
379 sim_print_help (sd, is_command);
380 if (STATE_OPEN_KIND (sd) == SIM_OPEN_STANDALONE)
381 exit (0);
382 /* FIXME: 'twould be nice to do something similar if gdb. */
383 break;
384
385 case OPTION_VERSION:
386 sim_print_version (sd, is_command);
387 if (STATE_OPEN_KIND (sd) == SIM_OPEN_STANDALONE)
388 exit (0);
389 break;
390
391 case OPTION_SYSROOT:
392 /* Don't leak memory in the odd event that there's lots of
393 --sysroot=... options. We treat "" specially since this
394 is the statically initialized value and cannot free it. */
395 if (simulator_sysroot[0] != '\0')
396 free (simulator_sysroot);
397 if (arg[0] != '\0')
398 simulator_sysroot = xstrdup (arg);
399 else
400 simulator_sysroot = "";
401 break;
402 }
403
404 return SIM_RC_OK;
405 }
406
407 /* Add the standard option list to the simulator. */
408
409 SIM_RC
410 standard_install (SIM_DESC sd)
411 {
412 SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
413 if (sim_add_option_table (sd, NULL, standard_options) != SIM_RC_OK)
414 return SIM_RC_FAIL;
415 STATE_LOAD_AT_LMA_P (sd) = 1;
416 return SIM_RC_OK;
417 }
418
419 /* Equality function for arguments. */
420
421 static int
422 compare_strings (const void *a, const void *b)
423 {
424 return strcmp (a, b) == 0;
425 }
426
427 /* Return non-zero if arg is a duplicate argument.
428 If ARG is NULL, initialize. */
429
430 static int
431 dup_arg_p (const char *arg)
432 {
433 static htab_t arg_table = NULL;
434 void **slot;
435
436 if (arg == NULL)
437 {
438 if (arg_table == NULL)
439 arg_table = htab_create_alloc (10, htab_hash_string,
440 compare_strings, NULL,
441 xcalloc, free);
442 htab_empty (arg_table);
443 return 0;
444 }
445
446 slot = htab_find_slot (arg_table, arg, INSERT);
447 if (*slot != NULL)
448 return 1;
449 *slot = (void *) arg;
450 return 0;
451 }
452
453 /* Called by sim_open to parse the arguments. */
454
455 SIM_RC
456 sim_parse_args (SIM_DESC sd, char * const *argv)
457 {
458 int c, i, argc, num_opts, save_opterr;
459 char *p, *short_options;
460 /* The `val' option struct entry is dynamically assigned for options that
461 only come in the long form. ORIG_VAL is used to get the original value
462 back. */
463 int *orig_val;
464 struct option *lp, *long_options;
465 const struct option_list *ol;
466 const OPTION *opt;
467 OPTION_HANDLER **handlers;
468 sim_cpu **opt_cpu;
469 SIM_RC result = SIM_RC_OK;
470
471 /* Count the number of arguments. */
472 argc = countargv (argv);
473
474 /* Count the number of options. */
475 num_opts = 0;
476 for (ol = STATE_OPTIONS (sd); ol != NULL; ol = ol->next)
477 for (opt = ol->options; OPTION_VALID_P (opt); ++opt)
478 ++num_opts;
479 for (i = 0; i < MAX_NR_PROCESSORS; ++i)
480 for (ol = CPU_OPTIONS (STATE_CPU (sd, i)); ol != NULL; ol = ol->next)
481 for (opt = ol->options; OPTION_VALID_P (opt); ++opt)
482 ++num_opts;
483
484 /* Initialize duplicate argument checker. */
485 (void) dup_arg_p (NULL);
486
487 /* Build the option table for getopt. */
488
489 long_options = NZALLOC (struct option, num_opts + 1);
490 lp = long_options;
491 short_options = NZALLOC (char, num_opts * 3 + 1);
492 p = short_options;
493 handlers = NZALLOC (OPTION_HANDLER *, OPTION_START + num_opts);
494 orig_val = NZALLOC (int, OPTION_START + num_opts);
495 opt_cpu = NZALLOC (sim_cpu *, OPTION_START + num_opts);
496
497 /* Set '+' as first char so argument permutation isn't done. This
498 is done to stop getopt_long returning options that appear after
499 the target program. Such options should be passed unchanged into
500 the program image. */
501 *p++ = '+';
502
503 for (i = OPTION_START, ol = STATE_OPTIONS (sd); ol != NULL; ol = ol->next)
504 for (opt = ol->options; OPTION_VALID_P (opt); ++opt)
505 {
506 if (dup_arg_p (opt->opt.name))
507 continue;
508 if (opt->shortopt != 0)
509 {
510 *p++ = opt->shortopt;
511 if (opt->opt.has_arg == required_argument)
512 *p++ = ':';
513 else if (opt->opt.has_arg == optional_argument)
514 { *p++ = ':'; *p++ = ':'; }
515 handlers[(unsigned char) opt->shortopt] = opt->handler;
516 if (opt->opt.val != 0)
517 orig_val[(unsigned char) opt->shortopt] = opt->opt.val;
518 else
519 orig_val[(unsigned char) opt->shortopt] = opt->shortopt;
520 }
521 if (opt->opt.name != NULL)
522 {
523 *lp = opt->opt;
524 /* Dynamically assign `val' numbers for long options. */
525 lp->val = i++;
526 handlers[lp->val] = opt->handler;
527 orig_val[lp->val] = opt->opt.val;
528 opt_cpu[lp->val] = NULL;
529 ++lp;
530 }
531 }
532
533 for (c = 0; c < MAX_NR_PROCESSORS; ++c)
534 {
535 sim_cpu *cpu = STATE_CPU (sd, c);
536 for (ol = CPU_OPTIONS (cpu); ol != NULL; ol = ol->next)
537 for (opt = ol->options; OPTION_VALID_P (opt); ++opt)
538 {
539 #if 0 /* Each option is prepended with --<cpuname>- so this greatly cuts down
540 on the need for dup_arg_p checking. Maybe in the future it'll be
541 needed so this is just commented out, and not deleted. */
542 if (dup_arg_p (opt->opt.name))
543 continue;
544 #endif
545 /* Don't allow short versions of cpu specific options for now. */
546 if (opt->shortopt != 0)
547 {
548 sim_io_eprintf (sd, "internal error, short cpu specific option");
549 result = SIM_RC_FAIL;
550 break;
551 }
552 if (opt->opt.name != NULL)
553 {
554 char *name;
555 *lp = opt->opt;
556 /* Prepend --<cpuname>- to the option. */
557 if (asprintf (&name, "%s-%s", CPU_NAME (cpu), lp->name) < 0)
558 {
559 sim_io_eprintf (sd, "internal error, out of memory");
560 result = SIM_RC_FAIL;
561 break;
562 }
563 lp->name = name;
564 /* Dynamically assign `val' numbers for long options. */
565 lp->val = i++;
566 handlers[lp->val] = opt->handler;
567 orig_val[lp->val] = opt->opt.val;
568 opt_cpu[lp->val] = cpu;
569 ++lp;
570 }
571 }
572 }
573
574 /* Terminate the short and long option lists. */
575 *p = 0;
576 lp->name = NULL;
577
578 /* Ensure getopt is initialized. */
579 optind = 0;
580
581 /* Do not lot getopt throw errors for us. But don't mess with the state for
582 any callers higher up by saving/restoring it. */
583 save_opterr = opterr;
584 opterr = 0;
585
586 while (1)
587 {
588 int longind, optc;
589
590 optc = getopt_long (argc, argv, short_options, long_options, &longind);
591 if (optc == -1)
592 {
593 if (STATE_OPEN_KIND (sd) == SIM_OPEN_STANDALONE)
594 STATE_PROG_ARGV (sd) = dupargv (argv + optind);
595 break;
596 }
597 if (optc == '?')
598 {
599 /* If getopt rejects a short option, optopt is set to the bad char.
600 If it rejects a long option, we have to look at optind. In the
601 short option case, argv could be multiple short options. */
602 const char *badopt;
603 char optbuf[3];
604
605 if (optopt)
606 {
607 sprintf (optbuf, "-%c", optopt);
608 badopt = optbuf;
609 }
610 else
611 badopt = argv[optind - 1];
612
613 sim_io_eprintf (sd,
614 "%s: unrecognized option '%s'\n"
615 "Use --help for a complete list of options.\n",
616 STATE_MY_NAME (sd), badopt);
617
618 result = SIM_RC_FAIL;
619 break;
620 }
621
622 if ((*handlers[optc]) (sd, opt_cpu[optc], orig_val[optc], optarg, 0/*!is_command*/) == SIM_RC_FAIL)
623 {
624 result = SIM_RC_FAIL;
625 break;
626 }
627 }
628
629 opterr = save_opterr;
630
631 free (long_options);
632 free (short_options);
633 free (handlers);
634 free (opt_cpu);
635 free (orig_val);
636 return result;
637 }
638
639 /* Utility of sim_print_help to print a list of option tables. */
640
641 static void
642 print_help (SIM_DESC sd, sim_cpu *cpu, const struct option_list *ol, int is_command)
643 {
644 const OPTION *opt;
645
646 for ( ; ol != NULL; ol = ol->next)
647 for (opt = ol->options; OPTION_VALID_P (opt); ++opt)
648 {
649 const int indent = 30;
650 int comma, len;
651 const OPTION *o;
652
653 if (dup_arg_p (opt->opt.name))
654 continue;
655
656 if (opt->doc == NULL)
657 continue;
658
659 if (opt->doc_name != NULL && opt->doc_name [0] == '\0')
660 continue;
661
662 sim_io_printf (sd, " ");
663
664 comma = 0;
665 len = 2;
666
667 /* list any short options (aliases) for the current OPT */
668 if (!is_command)
669 {
670 o = opt;
671 do
672 {
673 if (o->shortopt != '\0')
674 {
675 sim_io_printf (sd, "%s-%c", comma ? ", " : "", o->shortopt);
676 len += (comma ? 2 : 0) + 2;
677 if (o->arg != NULL)
678 {
679 if (o->opt.has_arg == optional_argument)
680 {
681 sim_io_printf (sd, "[%s]", o->arg);
682 len += 1 + strlen (o->arg) + 1;
683 }
684 else
685 {
686 sim_io_printf (sd, " %s", o->arg);
687 len += 1 + strlen (o->arg);
688 }
689 }
690 comma = 1;
691 }
692 ++o;
693 }
694 while (OPTION_VALID_P (o) && o->doc == NULL);
695 }
696
697 /* list any long options (aliases) for the current OPT */
698 o = opt;
699 do
700 {
701 const char *name;
702 const char *cpu_prefix = cpu ? CPU_NAME (cpu) : NULL;
703 if (o->doc_name != NULL)
704 name = o->doc_name;
705 else
706 name = o->opt.name;
707 if (name != NULL)
708 {
709 sim_io_printf (sd, "%s%s%s%s%s",
710 comma ? ", " : "",
711 is_command ? "" : "--",
712 cpu ? cpu_prefix : "",
713 cpu ? "-" : "",
714 name);
715 len += ((comma ? 2 : 0)
716 + (is_command ? 0 : 2)
717 + strlen (name));
718 if (o->arg != NULL)
719 {
720 if (o->opt.has_arg == optional_argument)
721 {
722 sim_io_printf (sd, "[=%s]", o->arg);
723 len += 2 + strlen (o->arg) + 1;
724 }
725 else
726 {
727 sim_io_printf (sd, " %s", o->arg);
728 len += 1 + strlen (o->arg);
729 }
730 }
731 comma = 1;
732 }
733 ++o;
734 }
735 while (OPTION_VALID_P (o) && o->doc == NULL);
736
737 if (len >= indent)
738 {
739 sim_io_printf (sd, "\n%*s", indent, "");
740 }
741 else
742 sim_io_printf (sd, "%*s", indent - len, "");
743
744 /* print the description, word wrap long lines */
745 {
746 const char *chp = opt->doc;
747 unsigned doc_width = 80 - indent;
748 while (strlen (chp) >= doc_width) /* some slack */
749 {
750 const char *end = chp + doc_width - 1;
751 while (end > chp && !isspace (*end))
752 end --;
753 if (end == chp)
754 end = chp + doc_width - 1;
755 /* The cast should be ok - its distances between to
756 points in a string. */
757 sim_io_printf (sd, "%.*s\n%*s", (int) (end - chp), chp, indent,
758 "");
759 chp = end;
760 while (isspace (*chp) && *chp != '\0')
761 chp++;
762 }
763 sim_io_printf (sd, "%s\n", chp);
764 }
765 }
766 }
767
768 /* Print help messages for the options. */
769
770 void
771 sim_print_help (SIM_DESC sd, int is_command)
772 {
773 if (STATE_OPEN_KIND (sd) == SIM_OPEN_STANDALONE)
774 sim_io_printf (sd, "Usage: %s [options] program [program args]\n",
775 STATE_MY_NAME (sd));
776
777 /* Initialize duplicate argument checker. */
778 (void) dup_arg_p (NULL);
779
780 if (STATE_OPEN_KIND (sd) == SIM_OPEN_STANDALONE)
781 sim_io_printf (sd, "Options:\n");
782 else
783 sim_io_printf (sd, "Commands:\n");
784
785 print_help (sd, NULL, STATE_OPTIONS (sd), is_command);
786 sim_io_printf (sd, "\n");
787
788 /* Print cpu-specific options. */
789 {
790 int i;
791
792 for (i = 0; i < MAX_NR_PROCESSORS; ++i)
793 {
794 sim_cpu *cpu = STATE_CPU (sd, i);
795 if (CPU_OPTIONS (cpu) == NULL)
796 continue;
797 sim_io_printf (sd, "CPU %s specific options:\n", CPU_NAME (cpu));
798 print_help (sd, cpu, CPU_OPTIONS (cpu), is_command);
799 sim_io_printf (sd, "\n");
800 }
801 }
802
803 sim_io_printf (sd, "Note: Depending on the simulator configuration some %ss\n",
804 STATE_OPEN_KIND (sd) == SIM_OPEN_STANDALONE ? "option" : "command");
805 sim_io_printf (sd, " may not be applicable\n");
806
807 if (STATE_OPEN_KIND (sd) == SIM_OPEN_STANDALONE)
808 {
809 sim_io_printf (sd, "\n");
810 sim_io_printf (sd, "program args Arguments to pass to simulated program.\n");
811 sim_io_printf (sd, " Note: Very few simulators support this.\n");
812 }
813 }
814
815 /* Print version information. */
816
817 void
818 sim_print_version (SIM_DESC sd, int is_command)
819 {
820 sim_io_printf (sd, "GNU simulator %s%s\n", PKGVERSION, version);
821
822 sim_io_printf (sd, "Copyright (C) 2021 Free Software Foundation, Inc.\n");
823
824 /* Following the copyright is a brief statement that the program is
825 free software, that users are free to copy and change it on
826 certain conditions, that it is covered by the GNU GPL, and that
827 there is no warranty. */
828
829 sim_io_printf (sd, "\
830 License GPLv3+: GNU GPL version 3 or later <https://gnu.org/licenses/gpl.html>\
831 \nThis is free software: you are free to change and redistribute it.\n\
832 There is NO WARRANTY, to the extent permitted by law.\n");
833
834 if (!is_command)
835 return;
836
837 sim_io_printf (sd, "This SIM was configured as:\n");
838 sim_config_print (sd);
839
840 if (REPORT_BUGS_TO[0])
841 {
842 sim_io_printf (sd, "For bug reporting instructions, please see:\n\
843 %s.\n",
844 REPORT_BUGS_TO);
845 }
846 sim_io_printf (sd, "Find the SIM homepage & other documentation resources \
847 online at:\n <https://sourceware.org/gdb/wiki/Sim/>.\n");
848 }
849
850 /* Utility of sim_args_command to find the closest match for a command.
851 Commands that have "-" in them can be specified as separate words.
852 e.g. sim memory-region 0x800000,0x4000
853 or sim memory region 0x800000,0x4000
854 If CPU is non-null, use its option table list, otherwise use the main one.
855 *PARGI is where to start looking in ARGV. It is updated to point past
856 the found option. */
857
858 static const OPTION *
859 find_match (SIM_DESC sd, sim_cpu *cpu, char *argv[], int *pargi)
860 {
861 const struct option_list *ol;
862 const OPTION *opt;
863 /* most recent option match */
864 const OPTION *matching_opt = NULL;
865 int matching_argi = -1;
866
867 if (cpu)
868 ol = CPU_OPTIONS (cpu);
869 else
870 ol = STATE_OPTIONS (sd);
871
872 /* Skip passed elements specified by *PARGI. */
873 argv += *pargi;
874
875 for ( ; ol != NULL; ol = ol->next)
876 for (opt = ol->options; OPTION_VALID_P (opt); ++opt)
877 {
878 int argi = 0;
879 const char *name = opt->opt.name;
880 if (name == NULL)
881 continue;
882 while (argv [argi] != NULL
883 && strncmp (name, argv [argi], strlen (argv [argi])) == 0)
884 {
885 name = &name [strlen (argv[argi])];
886 if (name [0] == '-')
887 {
888 /* leading match ...<a-b-c>-d-e-f - continue search */
889 name ++; /* skip `-' */
890 argi ++;
891 continue;
892 }
893 else if (name [0] == '\0')
894 {
895 /* exact match ...<a-b-c-d-e-f> - better than before? */
896 if (argi > matching_argi)
897 {
898 matching_argi = argi;
899 matching_opt = opt;
900 }
901 break;
902 }
903 else
904 break;
905 }
906 }
907
908 *pargi = matching_argi;
909 return matching_opt;
910 }
911
912 static char **
913 complete_option_list (char **ret, size_t *cnt, const struct option_list *ol,
914 const char *text, const char *word)
915 {
916 const OPTION *opt = NULL;
917 int argi;
918 size_t len = strlen (word);
919
920 for ( ; ol != NULL; ol = ol->next)
921 for (opt = ol->options; OPTION_VALID_P (opt); ++opt)
922 {
923 const char *name = opt->opt.name;
924
925 /* A long option to match against? */
926 if (!name)
927 continue;
928
929 /* Does this option actually match? */
930 if (strncmp (name, word, len))
931 continue;
932
933 ret = xrealloc (ret, ++*cnt * sizeof (ret[0]));
934 ret[*cnt - 2] = xstrdup (name);
935 }
936
937 return ret;
938 }
939
940 /* All leading text is stored in @text, while the current word being
941 completed is stored in @word. Trailing text of @word is not. */
942
943 char **
944 sim_complete_command (SIM_DESC sd, const char *text, const char *word)
945 {
946 char **ret = NULL;
947 size_t cnt = 1;
948 sim_cpu *cpu;
949
950 /* Only complete first word for now. */
951 if (text != word)
952 return ret;
953
954 cpu = STATE_CPU (sd, 0);
955 if (cpu)
956 ret = complete_option_list (ret, &cnt, CPU_OPTIONS (cpu), text, word);
957 ret = complete_option_list (ret, &cnt, STATE_OPTIONS (sd), text, word);
958
959 if (ret)
960 ret[cnt - 1] = NULL;
961 return ret;
962 }
963
964 SIM_RC
965 sim_args_command (SIM_DESC sd, const char *cmd)
966 {
967 /* something to do? */
968 if (cmd == NULL)
969 return SIM_RC_OK; /* FIXME - perhaps help would be better */
970
971 if (cmd [0] == '-')
972 {
973 /* user specified -<opt> ... form? */
974 char **argv = buildargv (cmd);
975 SIM_RC rc = sim_parse_args (sd, argv);
976 freeargv (argv);
977 return rc;
978 }
979 else
980 {
981 char **argv = buildargv (cmd);
982 const OPTION *matching_opt = NULL;
983 int matching_argi;
984 sim_cpu *cpu;
985
986 if (argv [0] == NULL)
987 {
988 freeargv (argv);
989 return SIM_RC_OK; /* FIXME - perhaps help would be better */
990 }
991
992 /* First check for a cpu selector. */
993 {
994 char *cpu_name = xstrdup (argv[0]);
995 char *hyphen = strchr (cpu_name, '-');
996 if (hyphen)
997 *hyphen = 0;
998 cpu = sim_cpu_lookup (sd, cpu_name);
999 if (cpu)
1000 {
1001 /* If <cpuname>-<command>, point argv[0] at <command>. */
1002 if (hyphen)
1003 {
1004 matching_argi = 0;
1005 argv[0] += hyphen - cpu_name + 1;
1006 }
1007 else
1008 matching_argi = 1;
1009 matching_opt = find_match (sd, cpu, argv, &matching_argi);
1010 /* If hyphen found restore argv[0]. */
1011 if (hyphen)
1012 argv[0] -= hyphen - cpu_name + 1;
1013 }
1014 free (cpu_name);
1015 }
1016
1017 /* If that failed, try the main table. */
1018 if (matching_opt == NULL)
1019 {
1020 matching_argi = 0;
1021 matching_opt = find_match (sd, NULL, argv, &matching_argi);
1022 }
1023
1024 if (matching_opt != NULL)
1025 {
1026 switch (matching_opt->opt.has_arg)
1027 {
1028 case no_argument:
1029 if (argv [matching_argi + 1] == NULL)
1030 matching_opt->handler (sd, cpu, matching_opt->opt.val,
1031 NULL, 1/*is_command*/);
1032 else
1033 sim_io_eprintf (sd, "Command `%s' takes no arguments\n",
1034 matching_opt->opt.name);
1035 break;
1036 case optional_argument:
1037 if (argv [matching_argi + 1] == NULL)
1038 matching_opt->handler (sd, cpu, matching_opt->opt.val,
1039 NULL, 1/*is_command*/);
1040 else if (argv [matching_argi + 2] == NULL)
1041 matching_opt->handler (sd, cpu, matching_opt->opt.val,
1042 argv [matching_argi + 1], 1/*is_command*/);
1043 else
1044 sim_io_eprintf (sd, "Command `%s' requires no more than one argument\n",
1045 matching_opt->opt.name);
1046 break;
1047 case required_argument:
1048 if (argv [matching_argi + 1] == NULL)
1049 sim_io_eprintf (sd, "Command `%s' requires an argument\n",
1050 matching_opt->opt.name);
1051 else if (argv [matching_argi + 2] == NULL)
1052 matching_opt->handler (sd, cpu, matching_opt->opt.val,
1053 argv [matching_argi + 1], 1/*is_command*/);
1054 else
1055 sim_io_eprintf (sd, "Command `%s' requires only one argument\n",
1056 matching_opt->opt.name);
1057 }
1058 freeargv (argv);
1059 return SIM_RC_OK;
1060 }
1061
1062 freeargv (argv);
1063 }
1064
1065 /* didn't find anything that remotly matched */
1066 return SIM_RC_FAIL;
1067 }
This page took 0.050744 seconds and 5 git commands to generate.