Refactor varobj_update interface.
authorVladimir Prus <vladimir@codesourcery.com>
Wed, 28 May 2008 12:06:36 +0000 (12:06 +0000)
committerVladimir Prus <vladimir@codesourcery.com>
Wed, 28 May 2008 12:06:36 +0000 (12:06 +0000)
        * varobj.c (varobj_update): Report changes as vector.  Also
        return not just a list of varobj, but a list of special structures
        that tell what exactly has changed.
        * varobj.h (enum varobj_update_error): Rename to
        varobj_scope_status.
        (struct varobj_update_result_t): New.
        (varobj_update): Adjust prototype.
        * mi/mi-cmd-var.c: Adjust for changes.

gdb/ChangeLog
gdb/mi/mi-cmd-var.c
gdb/testsuite/ChangeLog
gdb/testsuite/gdb.mi/mi-var-cmd.exp
gdb/testsuite/gdb.mi/mi2-var-cmd.exp
gdb/varobj.c
gdb/varobj.h

index ae01bb9..dfe0321 100644 (file)
@@ -1,5 +1,17 @@
 2008-05-28  Vladimir Prus  <vladimir@codesourcery.com>
 
+       Refactor varobj_update interface.
+        * varobj.c (varobj_update): Report changes as vector.  Also
+        return not just a list of varobj, but a list of special structures
+        that tell what exactly has changed.
+        * varobj.h (enum varobj_update_error): Rename to
+        varobj_scope_status.
+        (struct varobj_update_result_t): New.
+        (varobj_update): Adjust prototype.
+        * mi/mi-cmd-var.c: Adjust for changes.
+
+2008-05-28  Vladimir Prus  <vladimir@codesourcery.com>
+
        * varobj.c (varobj_update): Fix comment typo.
        Fix indentation.
 
index 2f009fa..50f7add 100644 (file)
@@ -654,62 +654,52 @@ static void
 varobj_update_one (struct varobj *var, enum print_values print_values,
                   int explicit)
 {
-  struct varobj **changelist;
   struct varobj **cc;
   struct cleanup *cleanup = NULL;
-  int nc;
-
-  nc = varobj_update (&var, &changelist, explicit);
-
-  /* nc >= 0  represents the number of changes reported into changelist.
-     nc < 0   means that an error occured or the the variable has 
-              changed type (TYPE_CHANGED).  */
+  VEC (varobj_update_result) *changes;
+  varobj_update_result *r;
+  int i;
+  
+  changes = varobj_update (&var, explicit);
   
-  if (nc == 0)
-    return;
-  else if (nc < 0)
+  for (i = 0; VEC_iterate (varobj_update_result, changes, i, r); ++i)
     {
       if (mi_version (uiout) > 1)
         cleanup = make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
-      ui_out_field_string (uiout, "name", varobj_get_objname(var));
+      ui_out_field_string (uiout, "name", varobj_get_objname (r->varobj));
 
-      switch (nc)
-      {
-        case NOT_IN_SCOPE:
+      switch (r->status)
+       {
+       case VAROBJ_IN_SCOPE:
+         if (mi_print_value_p (varobj_get_gdb_type (r->varobj), print_values))
+           ui_out_field_string (uiout, "value", varobj_get_value (r->varobj));
+         ui_out_field_string (uiout, "in_scope", "true");
+         break;
+        case VAROBJ_NOT_IN_SCOPE:
           ui_out_field_string (uiout, "in_scope", "false");
          break;
-        case INVALID:
+        case VAROBJ_INVALID:
           ui_out_field_string (uiout, "in_scope", "invalid");
          break;
-        case TYPE_CHANGED:
-         ui_out_field_string (uiout, "in_scope", "true");
-         ui_out_field_string (uiout, "type_changed", "true");
-          ui_out_field_string (uiout, "new_type", varobj_get_type(var));
-          ui_out_field_int (uiout, "new_num_children", 
-                           varobj_get_num_children(var));
-         if (mi_print_value_p (varobj_get_gdb_type (var), print_values))
-           ui_out_field_string (uiout, "value", varobj_get_value (var));
-         break;
-      }
-      if (mi_version (uiout) > 1)
-        do_cleanups (cleanup);
-    }
-  else
-    {
-      cc = changelist;
-      while (*cc != NULL)
+       }
+
+      if (r->status != VAROBJ_INVALID)
        {
-         if (mi_version (uiout) > 1)
-           cleanup = make_cleanup_ui_out_tuple_begin_end (uiout, NULL);
-         ui_out_field_string (uiout, "name", varobj_get_objname (*cc));
-         if (mi_print_value_p (varobj_get_gdb_type (*cc), print_values))
-           ui_out_field_string (uiout, "value", varobj_get_value (*cc));
-         ui_out_field_string (uiout, "in_scope", "true");
-         ui_out_field_string (uiout, "type_changed", "false");
-         if (mi_version (uiout) > 1)
-           do_cleanups (cleanup);
-         cc++;
+         if (r->type_changed)
+           ui_out_field_string (uiout, "type_changed", "true");
+         else
+           ui_out_field_string (uiout, "type_changed", "false");
        }
-      xfree (changelist);
+
+      if (r->type_changed)
+       {
+          ui_out_field_string (uiout, "new_type", varobj_get_type (r->varobj));
+          ui_out_field_int (uiout, "new_num_children", 
+                           varobj_get_num_children (r->varobj));
+       }
+  
+      if (mi_version (uiout) > 1)
+       do_cleanups (cleanup);
     }
+  VEC_free (varobj_update_result, changes);
 }
index 369f2b4..f2aa2fa 100644 (file)
@@ -1,3 +1,9 @@
+2008-05-28  Vladimir Prus  <vladimir@codesourcery.com>
+
+        * gdb.mi/mi-var-cmd.exp: Adjust for the fact that type_changed field is
+        now printed.
+        * gdb.mi/mi2-var-cmd.exp: Likewise.
+
 2008-05-27  Andreas Schwab  <schwab@suse.de>
 
        * gdb.base/frame-args.exp: Handle arguments that are optimized
index 27331ce..f47c1d5 100644 (file)
@@ -458,7 +458,7 @@ mi_next_to "do_locals_tests" ""     "var-cmd.c" \
 # Test: c_variable-2.15
 # Desc: check for out of scope subroutine1 locals
 mi_gdb_test "-var-update *" \
-       "\\^done,changelist=\\\[\{name=\"l\",in_scope=\"false\"\},\{name=\"i\",in_scope=\"false\"\}\\\]" \
+       "\\^done,changelist=\\\[\{name=\"l\",in_scope=\"false\"\,type_changed=\"false\"},\{name=\"i\",in_scope=\"false\",type_changed=\"false\"\}\\\]" \
        "update all vars: all now out of scope"
 
 # Done with locals/globals tests. Erase all variables
index d980917..2477721 100644 (file)
@@ -421,7 +421,7 @@ mi_next_to "do_locals_tests" ""     "var-cmd.c" \
 # Test: c_variable-2.15
 # Desc: check for out of scope subroutine1 locals
 mi_gdb_test "-var-update *" \
-       "\\^done,changelist=\\\[\{name=\"l\",in_scope=\"false\"\},\{name=\"i\",in_scope=\"false\"\}\\\]" \
+       "\\^done,changelist=\\\[\{name=\"l\",in_scope=\"false\"\,type_changed=\"false\"},\{name=\"i\",in_scope=\"false\",type_changed=\"false\"\}\\\]" \
        "update all vars: all now out of scope"
 
 # Done with locals/globals tests. Erase all variables
index 34db574..e94a35e 100644 (file)
@@ -1120,9 +1120,6 @@ install_new_value (struct varobj *var, struct value *value, int initial)
    expression to see if it's changed.  Then go all the way
    through its children, reconstructing them and noting if they've
    changed.
-   Return value: 
-    < 0 for error values, see varobj.h.
-    Otherwise it is the number of children + parent changed.
 
    The EXPLICIT parameter specifies if this call is result
    of MI request to update this specific variable, or 
@@ -1133,9 +1130,7 @@ install_new_value (struct varobj *var, struct value *value, int initial)
    returns TYPE_CHANGED, then it has done this and VARP will be modified
    to point to the new varobj.  */
 
-int
-varobj_update (struct varobj **varp, struct varobj ***changelist,
-              int explicit)
+VEC(varobj_update_result) *varobj_update (struct varobj **varp, int explicit)
 {
   int changed = 0;
   int type_changed = 0;
@@ -1146,52 +1141,50 @@ varobj_update (struct varobj **varp, struct varobj ***changelist,
   struct varobj **templist = NULL;
   struct value *new;
   VEC (varobj_p) *stack = NULL;
-  VEC (varobj_p) *result = NULL;
+  VEC (varobj_update_result) *result = NULL;
   struct frame_info *fi;
 
-  /* sanity check: have we been passed a pointer?  */
-  gdb_assert (changelist);
-
   /* Frozen means frozen -- we don't check for any change in
      this varobj, including its going out of scope, or
      changing type.  One use case for frozen varobjs is
      retaining previously evaluated expressions, and we don't
      want them to be reevaluated at all.  */
   if (!explicit && (*varp)->frozen)
-    return 0;
+    return result;
 
   if (!(*varp)->root->is_valid)
-    return INVALID;
+    {
+      varobj_update_result r = {*varp};
+      r.status = VAROBJ_INVALID;
+      VEC_safe_push (varobj_update_result, result, &r);
+      return result;
+    }
 
   if ((*varp)->root->rootvar == *varp)
     {
+      varobj_update_result r = {*varp};
+      r.status = VAROBJ_IN_SCOPE;
+
       /* Update the root variable. value_of_root can return NULL
         if the variable is no longer around, i.e. we stepped out of
         the frame in which a local existed. We are letting the 
         value_of_root variable dispose of the varobj if the type
         has changed.  */
       new = value_of_root (varp, &type_changed);
-      
-      /* If this is a floating varobj, and its type has changed,
-        then note that it's changed.  */
-      if (type_changed)
-       VEC_safe_push (varobj_p, result, *varp);
-      
+      r.varobj = *varp;
+
+      r.type_changed = type_changed;
       if (install_new_value ((*varp), new, type_changed))
-       {
-         /* If type_changed is 1, install_new_value will never return
-            non-zero, so we'll never report the same variable twice.  */
-         gdb_assert (!type_changed);
-         VEC_safe_push (varobj_p, result, *varp);
-       }
+       r.changed = 1;
       
       if (new == NULL)
-       {
-         /* This means the varobj itself is out of scope.
-            Report it.  */
-         VEC_free (varobj_p, result);
-         return NOT_IN_SCOPE;
-       }
+       r.status = VAROBJ_NOT_IN_SCOPE;
+
+      if (r.type_changed || r.changed)
+       VEC_safe_push (varobj_update_result, result, &r);
+
+      if (r.status == VAROBJ_NOT_IN_SCOPE)
+       return result;
     }
 
   VEC_safe_push (varobj_p, stack, *varp);
@@ -1221,32 +1214,16 @@ varobj_update (struct varobj **varp, struct varobj ***changelist,
          if (install_new_value (v, new, 0 /* type not changed */))
            {
              /* Note that it's changed */
-             VEC_safe_push (varobj_p, result, v);
+             varobj_update_result r = {v};
+             r.changed = 1;
+             VEC_safe_push (varobj_update_result, result, &r);
              v->updated = 0;
            }
        }
     }
 
-  /* Alloc (changed + 1) list entries.  */
-  changed = VEC_length (varobj_p, result);
-  *changelist = xmalloc ((changed + 1) * sizeof (struct varobj *));
-  cv = *changelist;
-
-  for (i = 0; i < changed; ++i)
-    {
-      *cv = VEC_index (varobj_p, result, i);
-      gdb_assert (*cv != NULL);
-      ++cv;
-    }
-  *cv = 0;
-
   VEC_free (varobj_p, stack);
-  VEC_free (varobj_p, result);
-
-  if (type_changed)
-    return TYPE_CHANGED;
-  else
-    return changed;
+  return result;
 }
 \f
 
index 4fc7d1e..9ecef0f 100644 (file)
@@ -39,12 +39,14 @@ enum varobj_type
     USE_SELECTED_FRAME          /* Always reevaluate in selected frame */
   };
 
-/* Error return values for varobj_update function.  */
-enum varobj_update_error
+/* Enumerator describing if a variable object is in scope.  */
+enum varobj_scope_status
   {
-    NOT_IN_SCOPE = -1,          /* varobj not in scope, can not be updated.  */
-    TYPE_CHANGED = -2,          /* varobj type has changed.  */
-    INVALID = -3,               /* varobj is not valid anymore.  */
+    VAROBJ_IN_SCOPE = 0,        /* Varobj is scope, value available.  */
+    VAROBJ_NOT_IN_SCOPE = 1,    /* Varobj is not in scope, value not available, 
+                                  but varobj can become in scope later.  */
+    VAROBJ_INVALID = 2,         /* Varobj no longer has any value, and never
+                                  will.  */
   };
 
 /* String representations of gdb's format codes (defined in varobj.c) */
@@ -65,6 +67,16 @@ struct varobj;
 typedef struct varobj *varobj_p;
 DEF_VEC_P (varobj_p);
 
+typedef struct varobj_update_result_t
+{
+  struct varobj *varobj;
+  int type_changed;
+  int changed;
+  enum varobj_scope_status status;
+} varobj_update_result;
+
+DEF_VEC_O (varobj_update_result);
+
 /* API functions */
 
 extern struct varobj *varobj_create (char *objname,
@@ -120,8 +132,8 @@ extern int varobj_set_value (struct varobj *var, char *expression);
 
 extern int varobj_list (struct varobj ***rootlist);
 
-extern int varobj_update (struct varobj **varp, struct varobj ***changelist,
-                         int explicit);
+extern VEC(varobj_update_result) *varobj_update (struct varobj **varp, 
+                                                int explicit);
 
 extern void varobj_invalidate (void);