gdb/
[deliverable/binutils-gdb.git] / gdb / cli / cli-setshow.c
1 /* Handle set and show GDB commands.
2
3 Copyright (c) 2000-2003, 2007-2012 Free Software Foundation, Inc.
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 3 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>. */
17
18 #include "defs.h"
19 #include "readline/tilde.h"
20 #include "value.h"
21 #include <ctype.h>
22 #include "gdb_string.h"
23 #include "arch-utils.h"
24 #include "observer.h"
25
26 #include "ui-out.h"
27
28 #include "cli/cli-decode.h"
29 #include "cli/cli-cmds.h"
30 #include "cli/cli-setshow.h"
31
32 /* Prototypes for local functions. */
33
34 static int parse_binary_operation (char *);
35
36 /* Return true if the change of command parameter should be notified. */
37
38 static int
39 notify_command_param_changed_p (int param_changed, struct cmd_list_element *c)
40 {
41 if (param_changed == 0)
42 return 0;
43
44 if (c->class == class_maintenance || c->class == class_deprecated
45 || c->class == class_obscure)
46 return 0;
47
48 return 1;
49 }
50
51 \f
52 static enum auto_boolean
53 parse_auto_binary_operation (const char *arg)
54 {
55 if (arg != NULL && *arg != '\0')
56 {
57 int length = strlen (arg);
58
59 while (isspace (arg[length - 1]) && length > 0)
60 length--;
61 if (strncmp (arg, "on", length) == 0
62 || strncmp (arg, "1", length) == 0
63 || strncmp (arg, "yes", length) == 0
64 || strncmp (arg, "enable", length) == 0)
65 return AUTO_BOOLEAN_TRUE;
66 else if (strncmp (arg, "off", length) == 0
67 || strncmp (arg, "0", length) == 0
68 || strncmp (arg, "no", length) == 0
69 || strncmp (arg, "disable", length) == 0)
70 return AUTO_BOOLEAN_FALSE;
71 else if (strncmp (arg, "auto", length) == 0
72 || (strncmp (arg, "-1", length) == 0 && length > 1))
73 return AUTO_BOOLEAN_AUTO;
74 }
75 error (_("\"on\", \"off\" or \"auto\" expected."));
76 return AUTO_BOOLEAN_AUTO; /* Pacify GCC. */
77 }
78
79 static int
80 parse_binary_operation (char *arg)
81 {
82 int length;
83
84 if (!arg || !*arg)
85 return 1;
86
87 length = strlen (arg);
88
89 while (arg[length - 1] == ' ' || arg[length - 1] == '\t')
90 length--;
91
92 if (strncmp (arg, "on", length) == 0
93 || strncmp (arg, "1", length) == 0
94 || strncmp (arg, "yes", length) == 0
95 || strncmp (arg, "enable", length) == 0)
96 return 1;
97 else if (strncmp (arg, "off", length) == 0
98 || strncmp (arg, "0", length) == 0
99 || strncmp (arg, "no", length) == 0
100 || strncmp (arg, "disable", length) == 0)
101 return 0;
102 else
103 {
104 error (_("\"on\" or \"off\" expected."));
105 return 0;
106 }
107 }
108 \f
109 void
110 deprecated_show_value_hack (struct ui_file *ignore_file,
111 int ignore_from_tty,
112 struct cmd_list_element *c,
113 const char *value)
114 {
115 /* If there's no command or value, don't try to print it out. */
116 if (c == NULL || value == NULL)
117 return;
118 /* Print doc minus "show" at start. */
119 print_doc_line (gdb_stdout, c->doc + 5);
120 switch (c->var_type)
121 {
122 case var_string:
123 case var_string_noescape:
124 case var_optional_filename:
125 case var_filename:
126 case var_enum:
127 printf_filtered ((" is \"%s\".\n"), value);
128 break;
129 default:
130 printf_filtered ((" is %s.\n"), value);
131 break;
132 }
133 }
134
135 /* Do a "set" command. ARG is NULL if no argument, or the
136 text of the argument, and FROM_TTY is nonzero if this command is
137 being entered directly by the user (i.e. these are just like any
138 other command). C is the command list element for the command. */
139
140 void
141 do_set_command (char *arg, int from_tty, struct cmd_list_element *c)
142 {
143 /* A flag to indicate the option is changed or not. */
144 int option_changed = 0;
145
146 gdb_assert (c->type == set_cmd);
147
148 switch (c->var_type)
149 {
150 case var_string:
151 {
152 char *new;
153 char *p;
154 char *q;
155 int ch;
156
157 if (arg == NULL)
158 arg = "";
159 new = (char *) xmalloc (strlen (arg) + 2);
160 p = arg;
161 q = new;
162 while ((ch = *p++) != '\000')
163 {
164 if (ch == '\\')
165 {
166 /* \ at end of argument is used after spaces
167 so they won't be lost. */
168 /* This is obsolete now that we no longer strip
169 trailing whitespace and actually, the backslash
170 didn't get here in my test, readline or
171 something did something funky with a backslash
172 right before a newline. */
173 if (*p == 0)
174 break;
175 ch = parse_escape (get_current_arch (), &p);
176 if (ch == 0)
177 break; /* C loses */
178 else if (ch > 0)
179 *q++ = ch;
180 }
181 else
182 *q++ = ch;
183 }
184 #if 0
185 if (*(p - 1) != '\\')
186 *q++ = ' ';
187 #endif
188 *q++ = '\0';
189 new = (char *) xrealloc (new, q - new);
190
191 if (*(char **) c->var == NULL
192 || strcmp (*(char **) c->var, new) != 0)
193 {
194 xfree (*(char **) c->var);
195 *(char **) c->var = new;
196
197 option_changed = 1;
198 }
199 else
200 xfree (new);
201 }
202 break;
203 case var_string_noescape:
204 if (arg == NULL)
205 arg = "";
206
207 if (*(char **) c->var == NULL || strcmp (*(char **) c->var, arg) != 0)
208 {
209 xfree (*(char **) c->var);
210 *(char **) c->var = xstrdup (arg);
211
212 option_changed = 1;
213 }
214 break;
215 case var_filename:
216 if (arg == NULL)
217 error_no_arg (_("filename to set it to."));
218 /* FALLTHROUGH */
219 case var_optional_filename:
220 {
221 char *val = NULL;
222
223 if (arg != NULL)
224 {
225 /* Clear trailing whitespace of filename. */
226 char *ptr = arg + strlen (arg) - 1;
227
228 while (ptr >= arg && (*ptr == ' ' || *ptr == '\t'))
229 ptr--;
230 *(ptr + 1) = '\0';
231
232 val = tilde_expand (arg);
233 }
234 else
235 val = xstrdup ("");
236
237 if (*(char **) c->var == NULL
238 || strcmp (*(char **) c->var, val) != 0)
239 {
240 xfree (*(char **) c->var);
241 *(char **) c->var = val;
242
243 option_changed = 1;
244 }
245 else
246 xfree (val);
247 }
248 break;
249 case var_boolean:
250 {
251 int val = parse_binary_operation (arg);
252
253 if (val != *(int *) c->var)
254 {
255 *(int *) c->var = val;
256
257 option_changed = 1;
258 }
259 }
260 break;
261 case var_auto_boolean:
262 {
263 enum auto_boolean val = parse_auto_binary_operation (arg);
264
265 if (*(enum auto_boolean *) c->var != val)
266 {
267 *(enum auto_boolean *) c->var = val;
268
269 option_changed = 1;
270 }
271 }
272 break;
273 case var_uinteger:
274 case var_zuinteger:
275 if (arg == NULL)
276 error_no_arg (_("integer to set it to."));
277 {
278 unsigned int val = parse_and_eval_long (arg);
279
280 if (c->var_type == var_uinteger && val == 0)
281 val = UINT_MAX;
282
283 if (*(unsigned int *) c->var != val)
284 {
285 *(unsigned int *) c->var = val;
286
287 option_changed = 1;
288 }
289 }
290 break;
291 case var_integer:
292 case var_zinteger:
293 {
294 unsigned int val;
295
296 if (arg == NULL)
297 error_no_arg (_("integer to set it to."));
298 val = parse_and_eval_long (arg);
299 if (val == 0 && c->var_type == var_integer)
300 val = INT_MAX;
301 else if (val >= INT_MAX)
302 error (_("integer %u out of range"), val);
303
304 if (*(int *) c->var != val)
305 {
306 *(int *) c->var = val;
307
308 option_changed = 1;
309 }
310 break;
311 }
312 case var_enum:
313 {
314 int i;
315 int len;
316 int nmatches;
317 const char *match = NULL;
318 char *p;
319
320 /* If no argument was supplied, print an informative error
321 message. */
322 if (arg == NULL)
323 {
324 char *msg;
325 int msg_len = 0;
326
327 for (i = 0; c->enums[i]; i++)
328 msg_len += strlen (c->enums[i]) + 2;
329
330 msg = xmalloc (msg_len);
331 *msg = '\0';
332 make_cleanup (xfree, msg);
333
334 for (i = 0; c->enums[i]; i++)
335 {
336 if (i != 0)
337 strcat (msg, ", ");
338 strcat (msg, c->enums[i]);
339 }
340 error (_("Requires an argument. Valid arguments are %s."),
341 msg);
342 }
343
344 p = strchr (arg, ' ');
345
346 if (p)
347 len = p - arg;
348 else
349 len = strlen (arg);
350
351 nmatches = 0;
352 for (i = 0; c->enums[i]; i++)
353 if (strncmp (arg, c->enums[i], len) == 0)
354 {
355 if (c->enums[i][len] == '\0')
356 {
357 match = c->enums[i];
358 nmatches = 1;
359 break; /* Exact match. */
360 }
361 else
362 {
363 match = c->enums[i];
364 nmatches++;
365 }
366 }
367
368 if (nmatches <= 0)
369 error (_("Undefined item: \"%s\"."), arg);
370
371 if (nmatches > 1)
372 error (_("Ambiguous item \"%s\"."), arg);
373
374 if (*(const char **) c->var != match)
375 {
376 *(const char **) c->var = match;
377
378 option_changed = 1;
379 }
380 }
381 break;
382 case var_zuinteger_unlimited:
383 {
384 LONGEST val;
385
386 if (arg == NULL)
387 error_no_arg (_("integer to set it to."));
388 val = parse_and_eval_long (arg);
389
390 if (val >= INT_MAX)
391 error (_("integer %s out of range"), plongest (val));
392 else if (val < -1)
393 error (_("only -1 is allowed to set as unlimited"));
394
395 if (*(int *) c->var != val)
396 {
397 *(int *) c->var = val;
398 option_changed = 1;
399 }
400 }
401 break;
402 default:
403 error (_("gdb internal error: bad var_type in do_setshow_command"));
404 }
405 c->func (c, NULL, from_tty);
406 if (deprecated_set_hook)
407 deprecated_set_hook (c);
408
409 if (notify_command_param_changed_p (option_changed, c))
410 {
411 char *name, *cp;
412 struct cmd_list_element **cmds;
413 struct cmd_list_element *p;
414 int i;
415 int length = 0;
416
417 /* Compute the whole multi-word command options. If user types command
418 'set foo bar baz on', c->name is 'baz', and GDB can't pass "bar" to
419 command option change notification, because it is confusing. We can
420 trace back through field 'prefix' to compute the whole options,
421 and pass "foo bar baz" to notification. */
422
423 for (i = 0, p = c; p != NULL; i++)
424 {
425 length += strlen (p->name);
426 length++;
427
428 p = p->prefix;
429 }
430 cp = name = xmalloc (length);
431 cmds = xmalloc (sizeof (struct cmd_list_element *) * i);
432
433 /* Track back through filed 'prefix' and cache them in CMDS. */
434 for (i = 0, p = c; p != NULL; i++)
435 {
436 cmds[i] = p;
437 p = p->prefix;
438 }
439
440 /* Don't trigger any observer notification if prefixlist is not
441 setlist. */
442 i--;
443 if (cmds[i]->prefixlist != &setlist)
444 {
445 xfree (cmds);
446 xfree (name);
447
448 return;
449 }
450 /* Traverse them in the reversed order, and copy their names into
451 NAME. */
452 for (i--; i >= 0; i--)
453 {
454 memcpy (cp, cmds[i]->name, strlen (cmds[i]->name));
455 cp += strlen (cmds[i]->name);
456
457 if (i != 0)
458 {
459 cp[0] = ' ';
460 cp++;
461 }
462 }
463 cp[0] = 0;
464
465 xfree (cmds);
466
467 switch (c->var_type)
468 {
469 case var_string:
470 case var_string_noescape:
471 case var_filename:
472 case var_optional_filename:
473 case var_enum:
474 observer_notify_command_param_changed (name, *(char **) c->var);
475 break;
476 case var_boolean:
477 {
478 char *opt = *(int *) c->var ? "on" : "off";
479
480 observer_notify_command_param_changed (name, opt);
481 }
482 break;
483 case var_auto_boolean:
484 {
485 const char *s = auto_boolean_enums[*(enum auto_boolean *) c->var];
486
487 observer_notify_command_param_changed (name, s);
488 }
489 break;
490 case var_uinteger:
491 case var_zuinteger:
492 {
493 char s[64];
494
495 xsnprintf (s, sizeof s, "%u", *(unsigned int *) c->var);
496 observer_notify_command_param_changed (name, s);
497 }
498 break;
499 case var_integer:
500 case var_zinteger:
501 case var_zuinteger_unlimited:
502 {
503 char s[64];
504
505 xsnprintf (s, sizeof s, "%d", *(int *) c->var);
506 observer_notify_command_param_changed (name, s);
507 }
508 break;
509 }
510 xfree (name);
511 }
512 }
513
514 /* Do a "show" command. ARG is NULL if no argument, or the
515 text of the argument, and FROM_TTY is nonzero if this command is
516 being entered directly by the user (i.e. these are just like any
517 other command). C is the command list element for the command. */
518
519 void
520 do_show_command (char *arg, int from_tty, struct cmd_list_element *c)
521 {
522 struct ui_out *uiout = current_uiout;
523 struct cleanup *old_chain;
524 struct ui_file *stb;
525
526 gdb_assert (c->type == show_cmd);
527
528 stb = mem_fileopen ();
529 old_chain = make_cleanup_ui_file_delete (stb);
530
531 /* Possibly call the pre hook. */
532 if (c->pre_show_hook)
533 (c->pre_show_hook) (c);
534
535 switch (c->var_type)
536 {
537 case var_string:
538 if (*(char **) c->var)
539 fputstr_filtered (*(char **) c->var, '"', stb);
540 break;
541 case var_string_noescape:
542 case var_optional_filename:
543 case var_filename:
544 case var_enum:
545 if (*(char **) c->var)
546 fputs_filtered (*(char **) c->var, stb);
547 break;
548 case var_boolean:
549 fputs_filtered (*(int *) c->var ? "on" : "off", stb);
550 break;
551 case var_auto_boolean:
552 switch (*(enum auto_boolean*) c->var)
553 {
554 case AUTO_BOOLEAN_TRUE:
555 fputs_filtered ("on", stb);
556 break;
557 case AUTO_BOOLEAN_FALSE:
558 fputs_filtered ("off", stb);
559 break;
560 case AUTO_BOOLEAN_AUTO:
561 fputs_filtered ("auto", stb);
562 break;
563 default:
564 internal_error (__FILE__, __LINE__,
565 _("do_show_command: "
566 "invalid var_auto_boolean"));
567 break;
568 }
569 break;
570 case var_uinteger:
571 case var_zuinteger:
572 if (c->var_type == var_uinteger
573 && *(unsigned int *) c->var == UINT_MAX)
574 fputs_filtered ("unlimited", stb);
575 else
576 fprintf_filtered (stb, "%u", *(unsigned int *) c->var);
577 break;
578 case var_integer:
579 case var_zinteger:
580 if (c->var_type == var_integer
581 && *(int *) c->var == INT_MAX)
582 fputs_filtered ("unlimited", stb);
583 else
584 fprintf_filtered (stb, "%d", *(int *) c->var);
585 break;
586 case var_zuinteger_unlimited:
587 {
588 if (*(int *) c->var == -1)
589 fputs_filtered ("unlimited", stb);
590 else
591 fprintf_filtered (stb, "%u", *(int *) c->var);
592 }
593 break;
594 default:
595 error (_("gdb internal error: bad var_type in do_show_command"));
596 }
597
598
599 /* FIXME: cagney/2005-02-10: Need to split this in half: code to
600 convert the value into a string (esentially the above); and
601 code to print the value out. For the latter there should be
602 MI and CLI specific versions. */
603
604 if (ui_out_is_mi_like_p (uiout))
605 ui_out_field_stream (uiout, "value", stb);
606 else
607 {
608 char *value = ui_file_xstrdup (stb, NULL);
609
610 make_cleanup (xfree, value);
611 if (c->show_value_func != NULL)
612 c->show_value_func (gdb_stdout, from_tty, c, value);
613 else
614 deprecated_show_value_hack (gdb_stdout, from_tty, c, value);
615 }
616 do_cleanups (old_chain);
617
618 c->func (c, NULL, from_tty);
619 }
620
621 /* Show all the settings in a list of show commands. */
622
623 void
624 cmd_show_list (struct cmd_list_element *list, int from_tty, char *prefix)
625 {
626 struct cleanup *showlist_chain;
627 struct ui_out *uiout = current_uiout;
628
629 showlist_chain = make_cleanup_ui_out_tuple_begin_end (uiout, "showlist");
630 for (; list != NULL; list = list->next)
631 {
632 /* If we find a prefix, run its list, prefixing our output by its
633 prefix (with "show " skipped). */
634 if (list->prefixlist && !list->abbrev_flag)
635 {
636 struct cleanup *optionlist_chain
637 = make_cleanup_ui_out_tuple_begin_end (uiout, "optionlist");
638 char *new_prefix = strstr (list->prefixname, "show ") + 5;
639
640 if (ui_out_is_mi_like_p (uiout))
641 ui_out_field_string (uiout, "prefix", new_prefix);
642 cmd_show_list (*list->prefixlist, from_tty, new_prefix);
643 /* Close the tuple. */
644 do_cleanups (optionlist_chain);
645 }
646 else
647 {
648 if (list->class != no_set_class)
649 {
650 struct cleanup *option_chain
651 = make_cleanup_ui_out_tuple_begin_end (uiout, "option");
652
653 ui_out_text (uiout, prefix);
654 ui_out_field_string (uiout, "name", list->name);
655 ui_out_text (uiout, ": ");
656 if (list->type == show_cmd)
657 do_show_command ((char *) NULL, from_tty, list);
658 else
659 cmd_func (list, NULL, from_tty);
660 /* Close the tuple. */
661 do_cleanups (option_chain);
662 }
663 }
664 }
665 /* Close the tuple. */
666 do_cleanups (showlist_chain);
667 }
668
This page took 0.0439349999999999 seconds and 4 git commands to generate.