GDB (API)
/home/stan/gdb/src/gdb/gdbtk/generic/gdbtk-varobj.c
Go to the documentation of this file.
00001 /* Variable user interface layer for GDB, the GNU debugger.
00002    Copyright (C) 1999, 2000, 2001, 2002, 2008, 2010
00003    Free Software Foundation, Inc.
00004 
00005    This file is part of GDB.
00006 
00007    This program is free software; you can redistribute it and/or modify
00008    it under the terms of the GNU General Public License as published by
00009    the Free Software Foundation; either version 2 of the License, or
00010    (at your option) any later version.
00011 
00012    This program is distributed in the hope that it will be useful,
00013    but WITHOUT ANY WARRANTY; without even the implied warranty of
00014    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015    GNU General Public License for more details.
00016 
00017    You should have received a copy of the GNU General Public License
00018    along with this program; if not, write to the Free Software
00019    Foundation, Inc., 51 Franklin Street, Fifth Floor,
00020    Boston, MA 02110-1301, USA.  */
00021 
00022 #include "defs.h"
00023 #include "value.h"
00024 #include "gdb_string.h"
00025 #include "varobj.h"
00026 #include "exceptions.h"
00027 
00028 #include <tcl.h>
00029 #include "gdbtk.h"
00030 #include "gdbtk-cmds.h"
00031 #include "gdbtk-wrapper.h"
00032 
00033 /*
00034  * Public functions defined in this file
00035  */
00036 
00037 int gdb_variable_init (Tcl_Interp *);
00038 
00039 /*
00040  * Private functions defined in this file
00041  */
00042 
00043 /* Entries into this file */
00044 
00045 static int gdb_variable_command (ClientData, Tcl_Interp *, int,
00046                                  Tcl_Obj * CONST[]);
00047 
00048 static int variable_obj_command (ClientData, Tcl_Interp *, int,
00049                                  Tcl_Obj * CONST[]);
00050 
00051 /* Variable object subcommands */
00052 
00053 static int variable_create (Tcl_Interp *, int, Tcl_Obj * CONST[]);
00054 
00055 static void variable_delete (Tcl_Interp *, struct varobj *, int);
00056 
00057 static Tcl_Obj *variable_children (Tcl_Interp *, struct varobj *);
00058 
00059 static int variable_format (Tcl_Interp *, int, Tcl_Obj * CONST[],
00060                             struct varobj *);
00061 
00062 static int variable_type (Tcl_Interp *, int, Tcl_Obj * CONST[],
00063                           struct varobj *);
00064 
00065 static int variable_value (Tcl_Interp *, int, Tcl_Obj * CONST[],
00066                            struct varobj *);
00067 
00068 static Tcl_Obj *variable_update (Tcl_Interp * interp, struct varobj **var);
00069 
00070 /* Helper functions for the above subcommands. */
00071 
00072 static void install_variable (Tcl_Interp *, char *);
00073 
00074 static void uninstall_variable (Tcl_Interp *, char *);
00075 
00076 /* String representations of gdb's format codes */
00077 static char *format_string[] =
00078   {"natural", "binary", "decimal", "hexadecimal", "octal"};
00079 
00080 
00081 /* Initialize the variable code. This function should be called once
00082    to install and initialize the variable code into the interpreter. */
00083 int
00084 gdb_variable_init (Tcl_Interp *interp)
00085 {
00086   Tcl_Command result;
00087   static int initialized = 0;
00088 
00089   if (!initialized)
00090     {
00091       result = Tcl_CreateObjCommand (interp, "gdb_variable", gdbtk_call_wrapper,
00092                                      (ClientData) gdb_variable_command, NULL);
00093       if (result == NULL)
00094         return TCL_ERROR;
00095 
00096       initialized = 1;
00097     }
00098 
00099   return TCL_OK;
00100 }
00101 
00102 /* This function defines the "gdb_variable" command which is used to
00103    create variable objects. Its syntax includes:
00104 
00105    gdb_variable create
00106    gdb_variable create NAME
00107    gdb_variable create -expr EXPR
00108    gdb_variable create -frame FRAME
00109    (it will also include permutations of the above options)
00110 
00111    NAME  = name of object to create. If no NAME, then automatically create
00112    a name
00113    EXPR  = the gdb expression for which to create a variable. This will
00114    be the most common usage.
00115    FRAME = the frame defining the scope of the variable.
00116 */
00117 static int
00118 gdb_variable_command (ClientData clientData, Tcl_Interp *interp,
00119                       int objc, Tcl_Obj *CONST objv[])
00120 {
00121   static const char *commands[] =
00122     {"create", "list", NULL};
00123   enum commands_enum
00124     {
00125       VARIABLE_CREATE, VARIABLE_LIST
00126     };
00127   int index, result;
00128 
00129   if (objc < 2)
00130     {
00131       Tcl_WrongNumArgs (interp, 1, objv, "option ?arg...?");
00132       return TCL_ERROR;
00133     }
00134 
00135   if (Tcl_GetIndexFromObj (interp, objv[1], commands, "options", 0,
00136                            &index) != TCL_OK)
00137     {
00138       return TCL_ERROR;
00139     }
00140 
00141   switch ((enum commands_enum) index)
00142     {
00143     case VARIABLE_CREATE:
00144       result = variable_create (interp, objc - 2, objv + 2);
00145       break;
00146 
00147     default:
00148       return TCL_ERROR;
00149     }
00150 
00151   return result;
00152 }
00153 
00154 /* This function implements the actual object command for each
00155    variable object that is created (and each of its children).
00156 
00157    Currently the following commands are implemented:
00158    - delete        delete this object and its children
00159    - update        update the variable and its children (root vars only)
00160    - numChildren   how many children does this object have
00161    - children      create the children and return a list of their objects
00162    - name          print out the name of this variable
00163    - format        query/set the display format of this variable
00164    - type          get the type of this variable
00165    - value         get/set the value of this variable
00166    - editable      is this variable editable?
00167 */
00168 static int
00169 variable_obj_command (ClientData clientData, Tcl_Interp *interp,
00170                       int objc, Tcl_Obj *CONST objv[])
00171 {
00172   enum commands_enum
00173     {
00174       VARIABLE_DELETE,
00175       VARIABLE_NUM_CHILDREN,
00176       VARIABLE_CHILDREN,
00177       VARIABLE_FORMAT,
00178       VARIABLE_TYPE,
00179       VARIABLE_VALUE,
00180       VARIABLE_NAME,
00181       VARIABLE_EDITABLE,
00182       VARIABLE_UPDATE
00183     };
00184   static const char *commands[] =
00185     {
00186       "delete",
00187       "numChildren",
00188       "children",
00189       "format",
00190       "type",
00191       "value",
00192       "name",
00193       "editable",
00194       "update",
00195       NULL
00196     };
00197   struct varobj *var;
00198   char *varobj_name;
00199   int index, result;
00200   
00201   /* Get the current handle for this variable token (name). */
00202   varobj_name = Tcl_GetStringFromObj (objv[0], NULL);
00203   if (varobj_name == NULL)
00204     return TCL_ERROR;
00205   var = varobj_get_handle (varobj_name);
00206   
00207 
00208   if (objc < 2)
00209     {
00210       Tcl_WrongNumArgs (interp, 1, objv, "option ?arg...?");
00211       return TCL_ERROR;
00212     }
00213 
00214   if (Tcl_GetIndexFromObj (interp, objv[1], commands, "options", 0,
00215                            &index) != TCL_OK)
00216     return TCL_ERROR;
00217 
00218   result = TCL_OK;
00219   switch ((enum commands_enum) index)
00220     {
00221     case VARIABLE_DELETE:
00222       if (objc > 2)
00223         {
00224           int len;
00225           char *s = Tcl_GetStringFromObj (objv[2], &len);
00226           if (*s == 'c' && strncmp (s, "children", len) == 0)
00227             {
00228               variable_delete (interp, var, 1 /* only children */ );
00229               break;
00230             }
00231         }
00232       variable_delete (interp, var, 0 /* var and children */ );
00233       break;
00234 
00235     case VARIABLE_NUM_CHILDREN:
00236       Tcl_SetObjResult (interp, Tcl_NewIntObj (varobj_get_num_children (var)));
00237       break;
00238 
00239     case VARIABLE_CHILDREN:
00240       {
00241         Tcl_Obj *children = variable_children (interp, var);
00242         Tcl_SetObjResult (interp, children);
00243       }
00244       break;
00245 
00246     case VARIABLE_FORMAT:
00247       result = variable_format (interp, objc, objv, var);
00248       break;
00249 
00250     case VARIABLE_TYPE:
00251       result = variable_type (interp, objc, objv, var);
00252       break;
00253 
00254     case VARIABLE_VALUE:
00255       result = variable_value (interp, objc, objv, var);
00256       break;
00257 
00258     case VARIABLE_NAME:
00259       {
00260         char *name = varobj_get_expression (var);
00261         Tcl_SetObjResult (interp, Tcl_NewStringObj (name, -1));
00262         xfree (name);
00263       }
00264       break;
00265 
00266     case VARIABLE_EDITABLE:
00267       Tcl_SetObjResult (interp, 
00268                         Tcl_NewIntObj (varobj_get_attributes (var) & 0x00000001 /* Editable? */ ));
00269       break;
00270 
00271     case VARIABLE_UPDATE:
00272       /* Only root variables can be updated */
00273       {
00274         Tcl_Obj *obj = variable_update (interp, &var);
00275         Tcl_SetObjResult (interp, obj);
00276       }
00277       break;
00278 
00279     default:
00280       return TCL_ERROR;
00281     }
00282 
00283   return result;
00284 }
00285 
00286 /*
00287  * Variable object construction/destruction
00288  */
00289 
00290 /* This function is responsible for processing the user's specifications
00291    and constructing a variable object. */
00292 static int
00293 variable_create (Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
00294 {
00295   enum create_opts
00296     {
00297       CREATE_EXPR, CREATE_FRAME
00298     };
00299   static const char *create_options[] =
00300     {"-expr", "-frame", NULL};
00301   struct varobj *var;
00302   char *name;
00303   char *obj_name;
00304   int index;
00305   CORE_ADDR frame = (CORE_ADDR) -1;
00306   int how_specified = USE_SELECTED_FRAME;
00307 
00308   /* REMINDER: This command may be invoked in the following ways:
00309      gdb_variable create [NAME] [-expr EXPR] [-frame FRAME]
00310 
00311      NAME  = name of object to create. If no NAME, then automatically create
00312      a name
00313      EXPR  = the gdb expression for which to create a variable. This will
00314      be the most common usage.
00315      FRAME = the address of the frame defining the variable's scope
00316   */
00317   name = NULL;
00318   if (objc)
00319     name = Tcl_GetStringFromObj (objv[0], NULL);
00320   if (name == NULL || *name == '-')
00321     {
00322       /* generate a name for this object */
00323       obj_name = varobj_gen_name ();
00324     }
00325   else
00326     {
00327       /* specified name for object */
00328       obj_name = xstrdup (name);
00329       objv++;
00330       objc--;
00331     }
00332 
00333   /* Run through all the possible options for this command */
00334   name = NULL;
00335   while (objc > 0)
00336     {
00337       if (Tcl_GetIndexFromObj (interp, objv[0], create_options, "options",
00338                                0, &index) != TCL_OK)
00339         {
00340           xfree (obj_name);
00341           result_ptr->flags |= GDBTK_IN_TCL_RESULT;
00342           return TCL_ERROR;
00343         }
00344 
00345       switch ((enum create_opts) index)
00346         {
00347         case CREATE_EXPR:
00348           name = Tcl_GetStringFromObj (objv[1], NULL);
00349           objc--;
00350           objv++;
00351           break;
00352 
00353         case CREATE_FRAME:
00354           {
00355             char *str;
00356             str = Tcl_GetStringFromObj (objv[1], NULL);
00357             frame = string_to_core_addr (str);
00358             how_specified = USE_SPECIFIED_FRAME;
00359             objc--;
00360             objv++;
00361           }
00362           break;
00363 
00364         default:
00365           break;
00366         }
00367 
00368       objc--;
00369       objv++;
00370     }
00371 
00372   /* Create the variable */
00373   var = varobj_create (obj_name, name, frame, how_specified);
00374 
00375   if (var != NULL)
00376     {
00377       /* Install a command into the interpreter that represents this
00378          object */
00379       install_variable (interp, obj_name);
00380       Tcl_SetObjResult (interp, Tcl_NewStringObj (obj_name, -1));
00381       result_ptr->flags |= GDBTK_IN_TCL_RESULT;
00382 
00383       xfree (obj_name);
00384       return TCL_OK;
00385     }
00386 
00387   xfree (obj_name);
00388   return TCL_ERROR;
00389 }
00390 
00391 /* Delete the variable object VAR and its children */
00392 /* If only_children_p, Delete only the children associated with the object. */
00393 static void
00394 variable_delete (Tcl_Interp *interp, struct varobj *var,
00395                  int only_children_p)
00396 {
00397   char **dellist;
00398   char **vc;
00399 
00400   varobj_delete (var, &dellist, only_children_p);
00401 
00402   vc = dellist;
00403   while (*vc != NULL)
00404     {
00405       uninstall_variable (interp, *vc);
00406       xfree (*vc);
00407       vc++;
00408     }
00409 
00410   xfree (dellist);
00411 }
00412 
00413 /* Return a list of all the children of VAR, creating them if necessary. */
00414 static Tcl_Obj *
00415 variable_children (Tcl_Interp *interp, struct varobj *var)
00416 {
00417   Tcl_Obj *list;
00418   VEC(varobj_p) *children;
00419   struct varobj *child;
00420   char *childname;
00421   int ix, from, to;
00422 
00423   list = Tcl_NewListObj (0, NULL);
00424 
00425   from = -1;
00426   to = -1;
00427 
00428   children = varobj_list_children (var, &from, &to);
00429 
00430   for (ix = from; ix < to && VEC_iterate (varobj_p, children, ix, child); ++ix)
00431     {
00432       childname = varobj_get_objname (child);
00433       /* Add child to result list and install the Tcl command for it. */
00434       Tcl_ListObjAppendElement (NULL, list,
00435                                 Tcl_NewStringObj (childname, -1));
00436       install_variable (interp, childname);
00437     }
00438 
00439   return list;
00440 }
00441 
00442 /* Update the values for a variable and its children. */
00443 /* NOTE:   Only root variables can be updated... */
00444 
00445 static Tcl_Obj *
00446 variable_update (Tcl_Interp *interp, struct varobj **var)
00447 {
00448   int i;
00449   Tcl_Obj *changed;
00450   VEC (varobj_update_result) *changes;
00451   varobj_update_result *r;
00452 
00453   if (GDB_varobj_update (var, 1, &changes) != GDB_OK)
00454     return Tcl_NewStringObj ("-1", -1);
00455 
00456   changed = Tcl_NewListObj (0, NULL);
00457   for (i = 0; VEC_iterate (varobj_update_result, changes, i, r); ++i)
00458     {
00459       switch (r->status)
00460         {
00461         case VAROBJ_IN_SCOPE:
00462           {
00463             Tcl_Obj *var
00464               =  Tcl_NewStringObj (varobj_get_objname (r->varobj), -1);
00465             Tcl_ListObjAppendElement (NULL, changed, var);
00466           }
00467           break;
00468 
00469         case VAROBJ_NOT_IN_SCOPE:
00470         case VAROBJ_INVALID:
00471           /* These need to be (re-)implemented in the UI */
00472           break;
00473         }
00474     }
00475 
00476   return changed;
00477 }
00478 
00479 /* This implements the format object command allowing
00480    the querying or setting of the object's display format. */
00481 static int
00482 variable_format (Tcl_Interp *interp, int objc, 
00483                  Tcl_Obj *CONST objv[], struct varobj *var)
00484 {
00485   if (objc > 2)
00486     {
00487       /* Set the format of VAR to given format */
00488       int len;
00489       char *fmt = Tcl_GetStringFromObj (objv[2], &len);
00490       if (strncmp (fmt, "natural", len) == 0)
00491         varobj_set_display_format (var, FORMAT_NATURAL);
00492       else if (strncmp (fmt, "binary", len) == 0)
00493         varobj_set_display_format (var, FORMAT_BINARY);
00494       else if (strncmp (fmt, "decimal", len) == 0)
00495         varobj_set_display_format (var, FORMAT_DECIMAL);
00496       else if (strncmp (fmt, "hexadecimal", len) == 0)
00497         varobj_set_display_format (var, FORMAT_HEXADECIMAL);
00498       else if (strncmp (fmt, "octal", len) == 0)
00499         varobj_set_display_format (var, FORMAT_OCTAL);
00500       else
00501         {
00502           gdbtk_set_result (interp, "unknown display format \"",
00503                             fmt, "\": must be: \"natural\", \"binary\""
00504                             ", \"decimal\", \"hexadecimal\", or \"octal\"");
00505           return TCL_ERROR;
00506         }
00507     }
00508   else
00509     {
00510       /* Report the current format */
00511       Tcl_Obj *fmt;
00512 
00513       /* FIXME: Use varobj_format_string[] instead */
00514       fmt = Tcl_NewStringObj (
00515                               format_string[(int) varobj_get_display_format (var)], -1);
00516       Tcl_SetObjResult (interp, fmt);
00517     }
00518 
00519   return TCL_OK;
00520 }
00521 
00522 /* This function implements the type object command, which returns the type of a
00523    variable in the interpreter (or an error). */
00524 static int
00525 variable_type (Tcl_Interp *interp, int objc,
00526                Tcl_Obj *CONST objv[], struct varobj *var)
00527 {
00528   const char *first;
00529   const char *last;
00530   char *string;
00531   Tcl_RegExp regexp;
00532 
00533   /* For the "fake" variables, do not return a type.
00534      Their type is NULL anyway */
00535   /* FIXME: varobj_get_type() calls type_print(), so we may have to wrap
00536      its call here and return TCL_ERROR in the case it errors out */
00537   if ((string = varobj_get_type (var)) == NULL)
00538     {
00539       Tcl_ResetResult (interp);
00540       return TCL_OK;
00541     }
00542 
00543   first = string;
00544 
00545   /* gdb will print things out like "struct {...}" for anonymous structs.
00546      In gui-land, we don't want the {...}, so we strip it here. */
00547   regexp = Tcl_RegExpCompile (interp, "{...}");
00548   if (Tcl_RegExpExec (interp, regexp, string, first))
00549     {
00550       /* We have an anonymous struct/union/class/enum */
00551       Tcl_RegExpRange (regexp, 0, &first, &last);
00552       if (*(first - 1) == ' ')
00553         first--;
00554       string[first - string] = '\0';
00555     }
00556 
00557   Tcl_SetObjResult (interp, Tcl_NewStringObj (string, -1));
00558   xfree (string);
00559   return TCL_OK;
00560 }
00561 
00562 /* This function implements the value object command, which allows an object's
00563    value to be queried or set. */
00564 static int
00565 variable_value (Tcl_Interp *interp, int objc,
00566                 Tcl_Obj *CONST objv[], struct varobj *var)
00567 {
00568   char *r;
00569 
00570   /* If we're setting the value of the variable, objv[2] will contain the
00571      variable's new value. */
00572   if (objc > 2)
00573     {
00574       /* FIXME: Do we need to test if val->error is set here?
00575          If so, make it an attribute. */
00576       if (varobj_get_attributes (var) & 0x00000001 /* Editable? */ )
00577         {
00578           char *s;
00579           int ok = 0;
00580           struct gdb_exception e;
00581 
00582           s = Tcl_GetStringFromObj (objv[2], NULL);
00583           TRY_CATCH (e, RETURN_MASK_ERROR)
00584             {
00585               ok = varobj_set_value (var, s);
00586             }
00587 
00588           if (e.reason < 0 || !ok)
00589             {
00590               gdbtk_set_result (interp, "Could not assign expression to variable object");
00591               return TCL_ERROR;
00592             }
00593         }
00594 
00595       Tcl_ResetResult (interp);
00596       return TCL_OK;
00597     }
00598 
00599   r = varobj_get_value (var);
00600 
00601   if (r == NULL)
00602     {
00603       gdbtk_set_result (interp, "Could not read variable object value after assignment");
00604       return TCL_ERROR;
00605     }
00606   else
00607     {
00608       Tcl_SetObjResult (interp, Tcl_NewStringObj (r, -1));
00609       xfree (r);
00610       return TCL_OK;
00611     }
00612 }
00613 
00614 /* Helper functions for the above */
00615 
00616 /* Install the given variable VAR into the tcl interpreter with
00617    the object name NAME. */
00618 static void
00619 install_variable (Tcl_Interp *interp, char *name)
00620 {
00621   Tcl_CreateObjCommand (interp, name, variable_obj_command,
00622                         NULL, NULL);
00623 }
00624 
00625 /* Unistall the object VAR in the tcl interpreter. */
00626 static void
00627 uninstall_variable (Tcl_Interp *interp, char *varname)
00628 {
00629   Tcl_DeleteCommand (interp, varname);
00630 }
00631 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines