diff options
Diffstat (limited to 'gdb/mi/mi-cmd-var.c')
-rw-r--r-- | gdb/mi/mi-cmd-var.c | 474 |
1 files changed, 474 insertions, 0 deletions
diff --git a/gdb/mi/mi-cmd-var.c b/gdb/mi/mi-cmd-var.c new file mode 100644 index 0000000..cf94496 --- /dev/null +++ b/gdb/mi/mi-cmd-var.c @@ -0,0 +1,474 @@ +/* MI Command Set - varobj commands. + Copyright (C) 2000, Free Software Foundation, Inc. + Contributed by Cygnus Solutions. + + This file is part of GDB. + + 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 "mi-cmds.h" +#include "ui-out.h" +#include "mi-out.h" +#include "varobj.h" +#include "value.h" +#include <ctype.h> + +/* Convenience macro for allocting typesafe memory. */ + +#undef XMALLOC +#define XMALLOC(TYPE) (TYPE*) xmalloc (sizeof (TYPE)) + +extern int varobjdebug; /* defined in varobj.c */ + +static void varobj_update_one (struct varobj *var); + +/* VAROBJ operations */ + +enum mi_cmd_result +mi_cmd_var_create (char *command, char **argv, int argc) +{ + CORE_ADDR frameaddr; + struct varobj *var; + char *name; + char *frame; + char *expr; + char *type; + struct cleanup *old_cleanups; + + if (argc != 3) + { + /* asprintf (&mi_error_message, + "mi_cmd_var_create: Usage: ."); + return MI_CMD_ERROR; */ + error ("mi_cmd_var_create: Usage: NAME FRAME EXPRESSION."); + } + + name = xstrdup (argv[0]); + /* Add cleanup for name. Must be free_current_contents as + name can be reallocated */ + old_cleanups = make_cleanup ((make_cleanup_func) free_current_contents, + &name); + + frame = xstrdup (argv[1]); + old_cleanups = make_cleanup (free, frame); + + expr = xstrdup (argv[2]); + + if (strcmp (name, "-") == 0) + { + free (name); + name = varobj_gen_name (); + } + else if (!isalpha (*name)) + error ("mi_cmd_var_create: name of object must begin with a letter"); + + if (strcmp (frame, "*") == 0) + frameaddr = -1; + else + frameaddr = parse_and_eval_address (frame); + + if (varobjdebug) + fprintf_unfiltered (gdb_stdlog, + "Name=\"%s\", Frame=\"%s\" (0x%s), Expression=\"%s\"\n", + name, frame, paddr (frameaddr), expr); + + var = varobj_create (name, expr, frameaddr); + + if (var == NULL) + error ("mi_cmd_var_create: unable to create variable object"); + + ui_out_field_string (uiout, "name", name); + ui_out_field_int (uiout, "numchild", varobj_get_num_children (var)); + type = varobj_get_type (var); + if (type == NULL) + ui_out_field_string (uiout, "type", ""); + else + { + ui_out_field_string (uiout, "type", type); + free (type); + } + + do_cleanups (old_cleanups); + return MI_CMD_DONE; +} + +enum mi_cmd_result +mi_cmd_var_delete (char *command, char **argv, int argc) +{ + char *name; + char *expr; + struct varobj *var; + int numdel; + int children_only_p = 0; + struct cleanup *old_cleanups; + + if (argc < 1 || argc > 2) + error ("mi_cmd_var_delete: Usage: [-c] EXPRESSION."); + + name = xstrdup (argv[0]); + /* Add cleanup for name. Must be free_current_contents as + name can be reallocated */ + old_cleanups = make_cleanup ((make_cleanup_func) free_current_contents, + &name); + + /* If we have one single argument it cannot be '-c' or any string + starting with '-'. */ + if (argc == 1) + { + if (strcmp (name, "-c") == 0) + error ("mi_cmd_var_delete: Missing required argument after '-c': variable object name"); + if (*name == '-') + error ("mi_cmd_var_delete: Illegal variable object name"); + } + + /* If we have 2 arguments they must be '-c' followed by a string + which would be the variable name. */ + if (argc == 2) + { + expr = xstrdup (argv[1]); + if (strcmp (name, "-c") != 0) + error ("mi_cmd_var_delete: Invalid option."); + children_only_p = 1; + free (name); + name = xstrdup (expr); + free (expr); + } + + /* If we didn't error out, now NAME contains the name of the + variable. */ + + var = varobj_get_handle (name); + + if (var == NULL) + error ("mi_cmd_var_delete: Variable object not found."); + + numdel = varobj_delete (var, NULL, children_only_p); + + ui_out_field_int (uiout, "ndeleted", numdel); + + do_cleanups (old_cleanups); + return MI_CMD_DONE; +} + +enum mi_cmd_result +mi_cmd_var_set_format (char *command, char **argv, int argc) +{ + enum varobj_display_formats format; + int len; + struct varobj *var; + char *formspec; + + if (argc != 2) + error ("mi_cmd_var_set_format: Usage: NAME FORMAT."); + + /* Get varobj handle, if a valid var obj name was specified */ + var = varobj_get_handle (argv[0]); + + if (var == NULL) + error ("mi_cmd_var_set_format: Variable object not found"); + + formspec = xstrdup (argv[1]); + if (formspec == NULL) + error ("mi_cmd_var_set_format: Must specify the format as: \"natural\", \"binary\", \"decimal\", \"hexadecimal\", or \"octal\""); + + len = strlen (formspec); + + if (STREQN (formspec, "natural", len)) + format = FORMAT_NATURAL; + else if (STREQN (formspec, "binary", len)) + format = FORMAT_BINARY; + else if (STREQN (formspec, "decimal", len)) + format = FORMAT_DECIMAL; + else if (STREQN (formspec, "hexadecimal", len)) + format = FORMAT_HEXADECIMAL; + else if (STREQN (formspec, "octal", len)) + format = FORMAT_OCTAL; + else + error ("mi_cmd_var_set_format: Unknown display format: must be: \"natural\", \"binary\", \"decimal\", \"hexadecimal\", or \"octal\""); + + /* Set the format of VAR to given format */ + varobj_set_display_format (var, format); + + /* Report the new current format */ + ui_out_field_string (uiout, "format", varobj_format_string[(int) format]); + return MI_CMD_DONE; +} + +enum mi_cmd_result +mi_cmd_var_show_format (char *command, char **argv, int argc) +{ + enum varobj_display_formats format; + struct varobj *var; + + if (argc != 1) + error ("mi_cmd_var_show_format: Usage: NAME."); + + /* Get varobj handle, if a valid var obj name was specified */ + var = varobj_get_handle (argv[0]); + if (var == NULL) + error ("mi_cmd_var_show_format: Variable object not found"); + + format = varobj_get_display_format (var); + + /* Report the current format */ + ui_out_field_string (uiout, "format", varobj_format_string[(int) format]); + return MI_CMD_DONE; +} + +enum mi_cmd_result +mi_cmd_var_info_num_children (char *command, char **argv, int argc) +{ + struct varobj *var; + + if (argc != 1) + error ("mi_cmd_var_info_num_children: Usage: NAME."); + + /* Get varobj handle, if a valid var obj name was specified */ + var = varobj_get_handle (argv[0]); + if (var == NULL) + error ("mi_cmd_var_info_num_children: Variable object not found"); + + ui_out_field_int (uiout, "numchild", varobj_get_num_children (var)); + return MI_CMD_DONE; +} + +enum mi_cmd_result +mi_cmd_var_list_children (char *command, char **argv, int argc) +{ + struct varobj *var; + struct varobj **childlist; + struct varobj **cc; + int numchild; + char *type; + + if (argc != 1) + error ("mi_cmd_var_list_children: Usage: NAME."); + + /* Get varobj handle, if a valid var obj name was specified */ + var = varobj_get_handle (argv[0]); + if (var == NULL) + error ("mi_cmd_var_list_children: Variable object not found"); + + numchild = varobj_list_children (var, &childlist); + ui_out_field_int (uiout, "numchild", numchild); + + if (numchild <= 0) + return MI_CMD_DONE; + + ui_out_list_begin (uiout, "children"); + cc = childlist; + while (*cc != NULL) + { + ui_out_list_begin (uiout, "child"); + ui_out_field_string (uiout, "name", varobj_get_objname (*cc)); + ui_out_field_string (uiout, "exp", varobj_get_expression (*cc)); + ui_out_field_int (uiout, "numchild", varobj_get_num_children (*cc)); + type = varobj_get_type (*cc); + /* C++ pseudo-variables (public, private, protected) do not have a type */ + if (type) + ui_out_field_string (uiout, "type", varobj_get_type (*cc)); + ui_out_list_end (uiout); + cc++; + } + ui_out_list_end (uiout); + free (childlist); + return MI_CMD_DONE; +} + +enum mi_cmd_result +mi_cmd_var_info_type (char *command, char **argv, int argc) +{ + struct varobj *var; + + if (argc != 1) + error ("mi_cmd_var_info_type: Usage: NAME."); + + /* Get varobj handle, if a valid var obj name was specified */ + var = varobj_get_handle (argv[0]); + if (var == NULL) + error ("mi_cmd_var_info_type: Variable object not found"); + + ui_out_field_string (uiout, "type", varobj_get_type (var)); + return MI_CMD_DONE; +} + +enum mi_cmd_result +mi_cmd_var_info_expression (char *command, char **argv, int argc) +{ + enum varobj_languages lang; + struct varobj *var; + + if (argc != 1) + error ("mi_cmd_var_info_expression: Usage: NAME."); + + /* Get varobj handle, if a valid var obj name was specified */ + var = varobj_get_handle (argv[0]); + if (var == NULL) + error ("mi_cmd_var_info_expression: Variable object not found"); + + lang = varobj_get_language (var); + + ui_out_field_string (uiout, "lang", varobj_language_string[(int) lang]); + ui_out_field_string (uiout, "exp", varobj_get_expression (var)); + return MI_CMD_DONE; +} + +enum mi_cmd_result +mi_cmd_var_show_attributes (char *command, char **argv, int argc) +{ + int attr; + char *attstr; + struct varobj *var; + + if (argc != 1) + error ("mi_cmd_var_show_attributes: Usage: NAME."); + + /* Get varobj handle, if a valid var obj name was specified */ + var = varobj_get_handle (argv[0]); + if (var == NULL) + error ("mi_cmd_var_show_attributes: Variable object not found"); + + attr = varobj_get_attributes (var); + /* FIXME: define masks for attributes */ + if (attr & 0x00000001) + attstr = "editable"; + else + attstr = "noneditable"; + + ui_out_field_string (uiout, "attr", attstr); + return MI_CMD_DONE; +} + +enum mi_cmd_result +mi_cmd_var_evaluate_expression (char *command, char **argv, int argc) +{ + struct varobj *var; + + if (argc != 1) + error ("mi_cmd_var_evaluate_expression: Usage: NAME."); + + /* Get varobj handle, if a valid var obj name was specified */ + var = varobj_get_handle (argv[0]); + if (var == NULL) + error ("mi_cmd_var_evaluate_expression: Variable object not found"); + + ui_out_field_string (uiout, "value", varobj_get_value (var)); + return MI_CMD_DONE; +} + +enum mi_cmd_result +mi_cmd_var_assign (char *command, char **argv, int argc) +{ + struct varobj *var; + char *expression; + + if (argc != 2) + error ("mi_cmd_var_assign: Usage: NAME EXPRESSION."); + + /* Get varobj handle, if a valid var obj name was specified */ + var = varobj_get_handle (argv[0]); + if (var == NULL) + error ("mi_cmd_var_assign: Variable object not found"); + + /* FIXME: define masks for attributes */ + if (!(varobj_get_attributes (var) & 0x00000001)) + error ("mi_cmd_var_assign: Variable object is not editable"); + + expression = xstrdup (argv[1]); + + if (!varobj_set_value (var, expression)) + error ("mi_cmd_var_assign: Could not assign expression to varible object"); + + ui_out_field_string (uiout, "value", varobj_get_value (var)); + return MI_CMD_DONE; +} + +enum mi_cmd_result +mi_cmd_var_update (char *command, char **argv, int argc) +{ + struct varobj *var; + struct varobj **rootlist; + struct varobj **cr; + char *name; + int nv; + + if (argc != 1) + error ("mi_cmd_var_update: Usage: NAME."); + + name = argv[0]; + + /* Check if the parameter is a "*" which means that we want + to update all variables */ + + if ((*name == '*') && (*(name + 1) == '\0')) + { + nv = varobj_list (&rootlist); + ui_out_list_begin (uiout, "changelist"); + if (nv <= 0) + { + ui_out_list_end (uiout); + return MI_CMD_DONE; + } + cr = rootlist; + while (*cr != NULL) + { + varobj_update_one (*cr); + cr++; + } + free (rootlist); + ui_out_list_end (uiout); + } + else + { + /* Get varobj handle, if a valid var obj name was specified */ + var = varobj_get_handle (name); + if (var == NULL) + error ("mi_cmd_var_update: Variable object not found"); + + ui_out_list_begin (uiout, "changelist"); + varobj_update_one (var); + ui_out_list_end (uiout); + } + return MI_CMD_DONE; +} + +/* Helper for mi_cmd_var_update() */ + +static void +varobj_update_one (struct varobj *var) +{ + struct varobj **changelist; + struct varobj **cc; + int nc; + + nc = varobj_update (var, &changelist); + + if (nc <= 0) + return; + + cc = changelist; + while (*cc != NULL) + { + ui_out_field_string (uiout, "name", varobj_get_objname (*cc)); + cc++; + } + free (changelist); +} + +/* Local variables: */ +/* change-log-default-name: "ChangeLog-mi" */ +/* End: */ |