From d318976c46b92e4d8640f1310bb7b6b517c8bcf7 Mon Sep 17 00:00:00 2001 From: Fernando Nasser Date: Fri, 1 Dec 2000 18:01:38 +0000 Subject: 2000-12-01 Fernando Nasser * cli/cli-decode.c: New file. Handle lists of commands, their decoding and documentation. (add_cmd, deprecate_cmd, add_abbrev_cmd, add_alias_cmd, add_prefix_cmd, add_abbrev_prefix_cmd, not_just_help_class_command, empty_sfunc, add_set_cmd, add_set_enum_cmd, add_set_auto_boolean_cmd, add_show_from_set, delete_cmd, apropos_cmd, help_cmd, help_list, help_all, print_doc_line, help_cmd_list, find_cmd, lookup_cmd_1, undef_cmd_error, lookup_cmd, deprecated_cmd_warning, lookup_cmd_composition, complete_on_cmdlist, complete_on_enum): Moved here from command.c. (add_info, add_info_alias, add_com, add_com_alias): Moved here from top.c. * cli/cli-decode.h: Definitions/declarations for the above. * cli/cli-cmds.c: New file. GDB CLI commands. (error_no_arg, info_command, show_command, help_command, show_version, quit_command, pwd_command, cd_command, echo_command, shell_escape, make_command, show_user, set_debug, show_debug, init_cmd_lists): Moved here from top.c. (apropos_command): Moved here from command.c. (complete_command, source_command): Moved here (part) from top.c. (is_complete_command): New function. Checks if a command is the "complete" command. (init_cli_cmds): New function. Add commands to the CLI (from code previously in top.c. * cli/cli-cmds.h: Definitions/declarations for the above. * cli/cli-script.c: New file. GDB CLI command scripting. (build_command_line, get_command_line, print_command_lines, print_command_line, execute_user_command, execute_control_command, while_command, if_command, arg_cleanup, setup_user_args, locate_arg, insert_args, realloc_body_list, read_next_line, recurse_read_control_structure, read_command_lines, free_command_lines, do_free_command_lines_cleanup, make_cleanup_free_command_lines, validate_comname, user_defined_command, define_command, document_command, source_cleanup_lines, do_fclose_cleanup, show_user_1): Moved here from top.c. (script_from_file): New function. Implements execution of a script contained in a file (part of code for the source_command() that used to exist in top.c). * cli/cli-script.h: Definitions/declarations for the above. * cli/cli-setshow.c: New file. Handle set and show GDB CLI commands. (parse_auto_binary_operation, parse_binary_operation, do_setshow_command, cmd_show_list): Moved here from command.c. * cli/cli-setshow.h: Definitions/declarations for the above. * top.c: Remove all CLI code, except the command loop. (gdb_init): Call init_cli_cmds(). * command.c: Remove obsolete file. * command.h: Mark as DEPRECATED. * gdbcmd.h: Ditto. * call-cmds.h: Ditto. * Makefile.in (SFILES): Remove command.c. (COMMON_OBS): Remove command.o. (command.o): Remove obsolete target. (cli_decode_h, cli_cmds_h, cli_script_h, cli_setshow_h): New macros. Refer to CLI header files. (cli-decode.o, cli-cmds.o, cli-setshow.o, cli-script.o): New targets. (SUBDIR_CLI_OBS, SUBDIR_CLI_SRCS, SUBDIR_CLI_DEPS, SUBDIR_CLI_INITS, SUBDIR_CLI_LDFLAGS, SUBDIR_CLI_CFLAGS, SUBDIR_CLI_ALL, SUBDIR_CLI_CLEAN, SUBDIR_CLI_INSTALL, SUBDIR_CLI_UNINSTALL): New macros for new cli subdirectory. * configure.in (enable_gdbcli): New option. Include the CLI in the executable (cannot be disabled yet). (CONFIG_OBS, CONFIG_DEPS, CONFIG_SRCS, CONFIG_INITS, ENABLE_CFLAGS, CONFIG_ALL, CONFIG_CLEAN, CONFIG_INSTALL, CONFIG_UNINSTALL): Add the corresponding SUBDIR_CLI_* macros if CLI requested. * configure: Regenerate. --- gdb/cli/cli-setshow.c | 462 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 462 insertions(+) create mode 100644 gdb/cli/cli-setshow.c (limited to 'gdb/cli/cli-setshow.c') diff --git a/gdb/cli/cli-setshow.c b/gdb/cli/cli-setshow.c new file mode 100644 index 00000000000..eebcf5ee8ab --- /dev/null +++ b/gdb/cli/cli-setshow.c @@ -0,0 +1,462 @@ +/* Handle set and show GDB commands. + Copyright 2000 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "defs.h" +#include "value.h" +#include +#if 0 +#include "gdb_string.h" +#endif + +#ifdef UI_OUT +#include "ui-out.h" +#endif + +#include "cli/cli-decode.h" +#include "cli/cli-cmds.h" +#include "cli/cli-setshow.h" + +/* Prototypes for local functions */ + +static int parse_binary_operation (char *); + +static enum cmd_auto_boolean parse_auto_binary_operation (const char *arg); + +static enum cmd_auto_boolean +parse_auto_binary_operation (const char *arg) +{ + if (arg != NULL && *arg != '\0') + { + int length = strlen (arg); + while (isspace (arg[length - 1]) && length > 0) + length--; + if (strncmp (arg, "on", length) == 0 + || strncmp (arg, "1", length) == 0 + || strncmp (arg, "yes", length) == 0 + || strncmp (arg, "enable", length) == 0) + return CMD_AUTO_BOOLEAN_TRUE; + else if (strncmp (arg, "off", length) == 0 + || strncmp (arg, "0", length) == 0 + || strncmp (arg, "no", length) == 0 + || strncmp (arg, "disable", length) == 0) + return CMD_AUTO_BOOLEAN_FALSE; + else if (strncmp (arg, "auto", length) == 0 + || (strncmp (arg, "-1", length) == 0 && length > 1)) + return CMD_AUTO_BOOLEAN_AUTO; + } + error ("\"on\", \"off\" or \"auto\" expected."); + return CMD_AUTO_BOOLEAN_AUTO; /* pacify GCC */ +} + +static int +parse_binary_operation (char *arg) +{ + int length; + + if (!arg || !*arg) + return 1; + + length = strlen (arg); + + while (arg[length - 1] == ' ' || arg[length - 1] == '\t') + length--; + + if (strncmp (arg, "on", length) == 0 + || strncmp (arg, "1", length) == 0 + || strncmp (arg, "yes", length) == 0 + || strncmp (arg, "enable", length) == 0) + return 1; + else if (strncmp (arg, "off", length) == 0 + || strncmp (arg, "0", length) == 0 + || strncmp (arg, "no", length) == 0 + || strncmp (arg, "disable", length) == 0) + return 0; + else + { + error ("\"on\" or \"off\" expected."); + return 0; + } +} + +/* Do a "set" or "show" command. ARG is NULL if no argument, or the text + of the argument, and FROM_TTY is nonzero if this command is being entered + directly by the user (i.e. these are just like any other + command). C is the command list element for the command. */ + +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 *new; + char *p; + char *q; + int ch; + + if (arg == NULL) + arg = ""; + new = (char *) xmalloc (strlen (arg) + 2); + p = arg; + q = new; + 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 + *q++ = '\0'; + new = (char *) xrealloc (new, q - new); + if (*(char **) c->var != NULL) + free (*(char **) c->var); + *(char **) c->var = new; + } + break; + case var_string_noescape: + if (arg == NULL) + arg = ""; + if (*(char **) c->var != NULL) + free (*(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) + free (*(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 cmd_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 = 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 = 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 = 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[1024]; + strcpy (msg, "Requires an argument. Valid arguments are "); + for (i = 0; c->enums[i]; i++) + { + if (i != 0) + strcat (msg, ", "); + strcat (msg, c->enums[i]); + } + strcat (msg, "."); + error (msg); + } + + 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) + error ("Undefined item: \"%s\".", arg); + + if (nmatches > 1) + error ("Ambiguous item \"%s\".", arg); + + *(const char **) c->var = match; + } + break; + default: + error ("gdb internal error: bad var_type in do_setshow_command"); + } + } + else if (c->type == show_cmd) + { +#ifdef UI_OUT + struct cleanup *old_chain; + struct ui_stream *stb; + int quote; + + stb = ui_out_stream_new (uiout); + old_chain = make_cleanup_ui_out_stream_delete (stb); +#endif /* UI_OUT */ + + /* Print doc minus "show" at start. */ + print_doc_line (gdb_stdout, c->doc + 5); + +#ifdef UI_OUT + ui_out_text (uiout, " is "); + ui_out_wrap_hint (uiout, " "); + quote = 0; + switch (c->var_type) + { + case var_string: + { + unsigned char *p; + + if (*(unsigned char **) c->var) + fputstr_filtered (*(unsigned char **) c->var, '"', stb->stream); + quote = 1; + } + break; + case var_string_noescape: + case var_filename: + case var_enum: + if (*(char **) c->var) + fputs_filtered (*(char **) c->var, stb->stream); + quote = 1; + break; + case var_boolean: + fputs_filtered (*(int *) c->var ? "on" : "off", stb->stream); + break; + case var_auto_boolean: + switch (*(enum cmd_auto_boolean*) c->var) + { + case CMD_AUTO_BOOLEAN_TRUE: + fputs_filtered ("on", stb->stream); + break; + case CMD_AUTO_BOOLEAN_FALSE: + fputs_filtered ("off", stb->stream); + break; + case CMD_AUTO_BOOLEAN_AUTO: + fputs_filtered ("auto", stb->stream); + break; + default: + internal_error ("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"); + } + if (quote) + ui_out_text (uiout, "\""); + ui_out_field_stream (uiout, "value", stb); + if (quote) + ui_out_text (uiout, "\""); + ui_out_text (uiout, ".\n"); + do_cleanups (old_chain); +#else + fputs_filtered (" is ", gdb_stdout); + wrap_here (" "); + switch (c->var_type) + { + case var_string: + { + fputs_filtered ("\"", gdb_stdout); + if (*(unsigned char **) c->var) + fputstr_filtered (*(unsigned char **) c->var, '"', gdb_stdout); + fputs_filtered ("\"", gdb_stdout); + } + break; + case var_string_noescape: + case var_filename: + case var_enum: + fputs_filtered ("\"", gdb_stdout); + if (*(char **) c->var) + fputs_filtered (*(char **) c->var, gdb_stdout); + fputs_filtered ("\"", gdb_stdout); + break; + case var_boolean: + fputs_filtered (*(int *) c->var ? "on" : "off", gdb_stdout); + break; + case var_auto_boolean: + switch (*(enum cmd_auto_boolean*) c->var) + { + case CMD_AUTO_BOOLEAN_TRUE: + fputs_filtered ("on", gdb_stdout); + break; + case CMD_AUTO_BOOLEAN_FALSE: + fputs_filtered ("off", gdb_stdout); + break; + case CMD_AUTO_BOOLEAN_AUTO: + fputs_filtered ("auto", gdb_stdout); + break; + default: + internal_error ("do_setshow_command: invalid var_auto_boolean"); + break; + } + break; + case var_uinteger: + if (*(unsigned int *) c->var == UINT_MAX) + { + fputs_filtered ("unlimited", gdb_stdout); + break; + } + /* else fall through */ + case var_zinteger: + fprintf_filtered (gdb_stdout, "%u", *(unsigned int *) c->var); + break; + case var_integer: + if (*(int *) c->var == INT_MAX) + { + fputs_filtered ("unlimited", gdb_stdout); + } + else + fprintf_filtered (gdb_stdout, "%d", *(int *) c->var); + break; + + default: + error ("gdb internal error: bad var_type in do_setshow_command"); + } + fputs_filtered (".\n", gdb_stdout); +#endif + } + else + error ("gdb internal error: bad cmd_type in do_setshow_command"); + (*c->function.sfunc) (NULL, from_tty, c); + if (c->type == set_cmd && set_hook) + set_hook (c); +} + +/* Show all the settings in a list of show commands. */ + +void +cmd_show_list (struct cmd_list_element *list, int from_tty, char *prefix) +{ +#ifdef UI_OUT + ui_out_list_begin (uiout, "showlist"); +#endif + for (; list != NULL; list = list->next) + { + /* If we find a prefix, run its list, prefixing our output by its + prefix (with "show " skipped). */ +#ifdef UI_OUT + if (list->prefixlist && !list->abbrev_flag) + { + ui_out_list_begin (uiout, "optionlist"); + ui_out_field_string (uiout, "prefix", list->prefixname + 5); + cmd_show_list (*list->prefixlist, from_tty, list->prefixname + 5); + ui_out_list_end (uiout); + } + if (list->type == show_cmd) + { + ui_out_list_begin (uiout, "option"); + ui_out_text (uiout, prefix); + ui_out_field_string (uiout, "name", list->name); + ui_out_text (uiout, ": "); + do_setshow_command ((char *) NULL, from_tty, list); + ui_out_list_end (uiout); + } +#else + if (list->prefixlist && !list->abbrev_flag) + cmd_show_list (*list->prefixlist, from_tty, list->prefixname + 5); + if (list->type == show_cmd) + { + fputs_filtered (prefix, gdb_stdout); + fputs_filtered (list->name, gdb_stdout); + fputs_filtered (": ", gdb_stdout); + do_setshow_command ((char *) NULL, from_tty, list); + } +#endif + } +#ifdef UI_OUT + ui_out_list_end (uiout); +#endif +} + -- cgit v1.2.1