/* MI Command Set - varobj commands. Copyright (C) 2000, Free Software Foundation, Inc. Contributed by Cygnus Solutions (a Red Hat company). 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 /* 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: */