void do_setshow_command(char *arg, int from_tty, struct cmd_list_element *c) { if (c->type == set_cmd) { switch (c->var_type) { case var_string: { char *newstr; char *p; char *q; int ch; if (arg == NULL) arg = ""; newstr = (char *)xmalloc(strlen(arg) + 2); p = arg; q = newstr; while ((ch = *p++) != '\000') { if (ch == '\\') { /* \ at end of argument is used after spaces so they won't be lost. */ /* This is obsolete now that we no longer strip trailing whitespace and actually, the backslash didn't get here in my test, readline or something did something funky with a backslash right before a newline. */ if (*p == 0) break; ch = parse_escape(&p); if (ch == 0) break; /* C loses */ else if (ch > 0) *q++ = ch; } else *q++ = ch; } #if 0 if (*(p - 1) != '\\') *q++ = ' '; #endif /* 0 */ *q++ = '\0'; newstr = (char *)xrealloc(newstr, (q - newstr)); if (*(char **)c->var != NULL) xfree(*(char **)c->var); *(char **)c->var = newstr; } break; case var_string_noescape: if (arg == NULL) arg = ""; if (*(char **)c->var != NULL) xfree(*(char **)c->var); *(char **)c->var = savestring(arg, strlen(arg)); break; case var_optional_filename: if (arg == NULL) arg = ""; if (*(char **)c->var != NULL) xfree(*(char **)c->var); *(char **)c->var = savestring(arg, strlen(arg)); break; case var_filename: if (arg == NULL) error_no_arg(_("filename to set it to.")); if (*(char **)c->var != NULL) xfree (*(char **)c->var); *(char **)c->var = tilde_expand(arg); break; case var_boolean: *(int *)c->var = parse_binary_operation(arg); break; case var_auto_boolean: *(enum auto_boolean *)c->var = parse_auto_binary_operation(arg); break; case var_uinteger: if (arg == NULL) error_no_arg(_("integer to set it to.")); *(unsigned int *)c->var = (unsigned int)parse_and_eval_long(arg); if (*(unsigned int *)c->var == 0) *(unsigned int *)c->var = UINT_MAX; break; case var_integer: { unsigned int val; if (arg == NULL) error_no_arg(_("integer to set it to.")); val = (unsigned int)parse_and_eval_long(arg); if (val == 0) *(int *)c->var = INT_MAX; else if (val >= INT_MAX) error(_("integer %u out of range"), val); else *(int *)c->var = val; break; } case var_zinteger: if (arg == NULL) error_no_arg(_("integer to set it to.")); *(int *)c->var = (int)parse_and_eval_long(arg); break; case var_enum: { int i; int len; int nmatches = 0; const char *match = NULL; char *p; /* APPLE LOCAL: Give the valid options for all error messages for enum type commands. */ /* If an argument was supplied, parse it. */ if (arg != NULL) { p = strchr(arg, ' '); if (p) len = (p - arg); else len = strlen(arg); nmatches = 0; for (i = 0; c->enums[i]; i++) if (strncmp(arg, c->enums[i], len) == 0) { if (c->enums[i][len] == '\0') { match = c->enums[i]; nmatches = 1; break; /* exact match. */ } else { match = c->enums[i]; nmatches++; } } } if (nmatches == 1) *(const char **)c->var = match; else { /* If there was an error, print an informative error message. */ struct ui_file *tmp_error_stream = mem_fileopen(); make_cleanup_ui_file_delete (tmp_error_stream); if (arg == NULL) fprintf_unfiltered(tmp_error_stream, "Requires an argument."); else if (nmatches <= 0) fprintf_unfiltered(tmp_error_stream, "Undefined item: \"%s\".", arg); else if (nmatches > 1) fprintf_unfiltered(tmp_error_stream, "Ambiguous item \"%s\".", arg); fprintf_unfiltered(tmp_error_stream, " Valid arguments are "); for (i = 0; c->enums[i]; i++) { if (i != 0) fprintf_unfiltered(tmp_error_stream, ", "); fputs_unfiltered(c->enums[i], tmp_error_stream); } fprintf_unfiltered(tmp_error_stream, "."); error_stream(tmp_error_stream); } /* END APPLE LOCAL */ } break; default: error(_("gdb internal error: bad var_type in do_setshow_command")); } } else if (c->type == show_cmd) { struct cleanup *old_chain; struct ui_stream *stb; stb = ui_out_stream_new(uiout); old_chain = make_cleanup_ui_out_stream_delete(stb); /* Possibly call the pre hook: */ if (c->pre_show_hook) (c->pre_show_hook)(c); switch (c->var_type) { case var_string: { if (*(unsigned char **)c->var) fputstr_filtered(*(char **)c->var, '"', stb->stream); } break; case var_string_noescape: case var_optional_filename: case var_filename: case var_enum: if (*(char **)c->var) fputs_filtered(*(char **)c->var, stb->stream); break; case var_boolean: fputs_filtered(*(int *)c->var ? "on" : "off", stb->stream); break; case var_auto_boolean: switch (*(enum auto_boolean*)c->var) { case AUTO_BOOLEAN_TRUE: fputs_filtered("on", stb->stream); break; case AUTO_BOOLEAN_FALSE: fputs_filtered("off", stb->stream); break; case AUTO_BOOLEAN_AUTO: fputs_filtered("auto", stb->stream); break; default: internal_error(__FILE__, __LINE__, _("do_setshow_command: invalid var_auto_boolean")); break; } break; case var_uinteger: if (*(unsigned int *)c->var == UINT_MAX) { fputs_filtered("unlimited", stb->stream); break; } /* else fall through */ case var_zinteger: fprintf_filtered(stb->stream, "%u", *(unsigned int *)c->var); break; case var_integer: if (*(int *)c->var == INT_MAX) { fputs_filtered("unlimited", stb->stream); } else fprintf_filtered(stb->stream, "%d", *(int *)c->var); break; default: error(_("gdb internal error: bad var_type in do_setshow_command")); } /* FIXME: cagney/2005-02-10: Need to split this in half: code to convert the value into a string (esentially the above); and code to print the value out. For the latter there should be MI and CLI specific versions. */ if (ui_out_is_mi_like_p(uiout)) ui_out_field_stream(uiout, "value", stb); else { long length; char *value = ui_file_xstrdup(stb->stream, &length); make_cleanup(xfree, value); if (c->show_value_func != NULL) c->show_value_func(gdb_stdout, from_tty, c, value); else deprecated_show_value_hack(gdb_stdout, from_tty, c, value); } do_cleanups(old_chain); } else error(_("gdb internal error: bad cmd_type in do_setshow_command")); c->func(c, NULL, from_tty); if ((c->type == set_cmd) && deprecated_set_hook) deprecated_set_hook(c); }
void do_setshow_command (char *arg, int from_tty, struct cmd_list_element *c) { if (c->type == set_cmd) { switch (c->var_type) { case var_string: { if (arg == NULL) arg = ""; *(char **) c->var = g_strcompress (arg); } break; case var_string_noescape: if (arg == NULL) arg = ""; if (*(char **) c->var != NULL) g_free (*(char **) c->var); *(char **) c->var = savestring (arg, strlen (arg)); break; case var_optional_filename: if (arg == NULL) arg = ""; if (*(char **) c->var != NULL) g_free (*(char **) c->var); *(char **) c->var = savestring (arg, strlen (arg)); break; case var_filename: if (arg == NULL) bosh_command_error_no_argument (_("filename to set it to.")); if (*(char **) c->var != NULL) g_free (*(char **) c->var); { /* Clear trailing whitespace of filename. */ char *ptr = arg + strlen (arg) - 1; while (ptr >= arg && (*ptr == ' ' || *ptr == '\t')) ptr--; *(ptr + 1) = '\0'; } *(char **) c->var = tilde_expand (arg); break; case var_boolean: { int val = parse_binary_operation (arg); if (val != -1) *(int *) c->var = val; break; } case var_auto_boolean: { enum auto_boolean val = parse_auto_binary_operation (arg); if (val != AUTO_BOOLEAN_INVALID) *(enum auto_boolean *) c->var = val; break; } case var_uinteger: if (arg == NULL) bosh_command_error_no_argument (_("integer to set it to.")); *(unsigned int *) c->var = parse_and_eval_long (arg); if (*(unsigned int *) c->var == 0) *(unsigned int *) c->var = UINT_MAX; break; case var_integer: { unsigned int val; if (arg == NULL) { bosh_command_error_no_argument (_("integer to set it to.")); break; } val = parse_and_eval_long (arg); if (val == 0) *(int *) c->var = INT_MAX; else if (val >= INT_MAX) { g_print (_("integer %u out of range"), val); break; } else *(int *) c->var = val; break; } case var_zinteger: if (arg == NULL) bosh_command_error_no_argument (_("integer to set it to.")); *(int *) c->var = parse_and_eval_long (arg); break; case var_enum: { int i; int len; int nmatches; const char *match = NULL; char *p; /* if no argument was supplied, print an informative error message */ if (arg == NULL) { char *msg; int msg_len = 0; for (i = 0; c->enums[i]; i++) msg_len += strlen (c->enums[i]) + 2; msg = g_malloc (msg_len); *msg = '\0'; for (i = 0; c->enums[i]; i++) { if (i != 0) strcat (msg, ", "); strcat (msg, c->enums[i]); } g_print (_("Requires an argument. Valid arguments are %s."), msg); g_free (msg); break; } p = strchr (arg, ' '); if (p) len = p - arg; else len = strlen (arg); nmatches = 0; for (i = 0; c->enums[i]; i++) if (strncmp (arg, c->enums[i], len) == 0) { if (c->enums[i][len] == '\0') { match = c->enums[i]; nmatches = 1; break; /* exact match. */ } else { match = c->enums[i]; nmatches++; } } if (nmatches <= 0) { g_print (_("Undefined item: \"%s\"."), arg); break; } if (nmatches > 1) { g_print (_("Ambiguous item \"%s\"."), arg); break; } *(const char **) c->var = match; } break; default: g_warning (_("gdb internal error: bad var_type in do_setshow_command")); } } else if (c->type == show_cmd) { char *val; /* Possibly call the pre hook. */ if (c->pre_show_hook) (c->pre_show_hook) (c); switch (c->var_type) { case var_string: if (*(char **) c->var) val = g_strescape (*(char **) c->var, ""); break; case var_string_noescape: case var_optional_filename: case var_filename: case var_enum: if (*(char **) c->var) val = g_strdup (*(char **) c->var); break; case var_boolean: val = g_strdup (c->var ? "on" : "off"); break; case var_auto_boolean: switch (*(enum auto_boolean*) c->var) { case AUTO_BOOLEAN_TRUE: val = g_strdup ("on"); break; case AUTO_BOOLEAN_FALSE: val = g_strdup ("off"); break; case AUTO_BOOLEAN_AUTO: val = g_strdup ("auto"); break; default: g_warning ("%s:%d %s", __FILE__, __LINE__, _("do_setshow_command: invalid var_auto_boolean")); break; } break; case var_uinteger: if (*(unsigned int *) c->var == UINT_MAX) { val = g_strdup ("unlimited"); break; } /* else fall through */ case var_zinteger: val = g_strdup_printf ("%u", *(unsigned int *) c->var); break; case var_integer: if (*(int *) c->var == INT_MAX) val = g_strdup ("unlimited"); else val = g_strdup_printf ("%d", *(int *) c->var); break; default: g_warning (_("gdb internal error: bad var_type in do_setshow_command")); } if (c->show_value_func != NULL) c->show_value_func (NULL, from_tty, c, val); else g_warning ("command %s missing show_value_func", c->name); } else g_warning (_("gdb internal error: bad cmd_type in do_setshow_command")); c->func (c, NULL, from_tty); }