Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
From: Nick Roberts <nickrob@snap.net.nz>
To: gdb-patches@sourceware.org
Subject: [PATCH:MI] Return a subset of a variable object's children
Date: Sun, 27 Apr 2008 15:34:00 -0000	[thread overview]
Message-ID: <18452.24568.655617.907458@kahikatea.snap.net.nz> (raw)


This patch allows -var-list-children to create just some of a variable object's
children.  Following a discussion last year with Mark Khouzam, this is useful
for displaying large arrays (and structures) where it would take too long to
create all the children: it is only really necessary to create those that are
visible on the screen and update as further become visible.  It also allows a
step size (stride) other than one.

ISTR that it was said a long time ago that mi_getopt won't take long options
but that doesn't seem to be the case.  The difficulty is that 
-var-list-children takes 0, 1 and 2 as options so I've had to separate the
logic to keep it backward compatible.

Use of these new options means that the elements might not be printed in order
but it is always preserved if only the old options are used.

Example of use (Note subsequent -var-list-children _adds_ to list):

n
&"n\n"
~~"151\t  int i, n, m[10] = {0, 1, 4, 9, 16, 25, 36, 49, 64, 81};\n"
^done
(gdb) 
n
&"n\n"
~"152\t  int m1[2][3] = {{0, 1, 2}, {10, 11, 12}};\n"
^done
(gdb) 
-var-create - * m
^done,name="var1",numchild="10",value="[10]",type="int [10]",thread-id="1"
(gdb) 
-var-list-children -f 7 -n 2 --all-values var1
^done,numchild="2",children=[child={name="var1.7",exp="7",numchild="0",value="49",type="int",thread-id="1"},child={name="var1.8",exp="8",numchild="0",value="64",type="int",thread-id="1"}]
(gdb) 
-var-list-children -f 4 -n 3 -s 2 --all-values var1
^done,numchild="4",children=[child={name="var1.7",exp="7",numchild="0",value="49",type="int",thread-id="1"},child={name="var1.8",exp="8",numchild="0",value="64",type="int",thread-id="1"},child={name="var1.4",exp="4",numchild="0",value="16",type="int",thread-id="1"},child={name="var1.6",exp="6",numchild="0",value="36",type="int",thread-id="1"}]
(gdb) 


-- 
Nick                                           http://www.inet.net.nz/~nickrob


2008-04-27  Nick Roberts  <nickrob@snap.net.nz>

	* mi/mi-cmd-var.c (mi_cmd_var_list_children): Add options to select
	a subset of children.

	* varobj.h (varobj_list_children): Declare new parameters.

	* varobj.c (struct varobj): New member current_children.
	(varobj_list_children): Create any new varobjs for children
	specified by mi_cmd_var_list_children.
	(create_child): Add parameter real_index.  Use it.


*** mi-cmd-var.c	20 Apr 2008 10:20:39 +1200	1.50
--- mi-cmd-var.c	27 Apr 2008 21:34:58 +1200	
*************** mi_cmd_var_list_children (char *command,
*** 374,397 ****
    int numchild;
    enum print_values print_values;
    int ix;
  
!   if (argc != 1 && argc != 2)
!     error (_("mi_cmd_var_list_children: Usage: [PRINT_VALUES] NAME"));
  
!   /* Get varobj handle, if a valid var obj name was specified */
!   if (argc == 1)
!     var = varobj_get_handle (argv[0]);
    else
!     var = varobj_get_handle (argv[1]);
!   if (var == NULL)
!     error (_("Variable object not found"));
  
!   children = varobj_list_children (var);
    ui_out_field_int (uiout, "numchild", VEC_length (varobj_p, children));
-   if (argc == 2)
-     print_values = mi_parse_values_option (argv[0]);
-   else
-     print_values = PRINT_NO_VALUES;
  
    if (VEC_length (varobj_p, children) == 0)
      return MI_CMD_DONE;
--- 374,462 ----
    int numchild;
    enum print_values print_values;
    int ix;
+   int start, number, stride = 1;
  
!   enum opt
!     {
!       NO_VALUES, SIMPLE_VALUES, ALL_VALUES, FROM_OPT, NUMBER_OPT, STRIDE_OPT
!     };
  
!   static struct mi_opt opts[] =
!   {
!       { "-no-values", NO_VALUES, 0 },
!       { "-simple-values", SIMPLE_VALUES, 0 },
!       { "-all-values", ALL_VALUES, 0 },
!       { "f", FROM_OPT, 1 },
!       { "n", NUMBER_OPT, 1 },
!       { "s", STRIDE_OPT, 1 },
!       { 0, 0, 0 }
!     };
! 
!   if (argc == 1 || argc == 2)
!     {
!       /* Get varobj handle, if a valid var obj name was specified */
!       if (argc == 1)
! 	var = varobj_get_handle (argv[0]);
!       else
! 	var = varobj_get_handle (argv[1]);
!       if (var == NULL)
! 	error (_("Variable object not found"));
! 
!       if (argc == 2)
! 	print_values = mi_parse_values_option (argv[0]);
!       else
! 	print_values = PRINT_NO_VALUES;
! 
!       start = 0;
!       number = varobj_get_num_children (var);
!     }
    else
!     {
!       int optind = 0;
!       char *optarg;
!       while (1)
! 	{
! 	  int opt = mi_getopt ("mi_cmd_var_list_children",
! 			       argc, argv, opts, &optind, &optarg);
! 	  if (opt < 0)
! 	    break;
! 	  switch ((enum opt) opt)
! 	    {
! 	    case NO_VALUES:
! 	      print_values = PRINT_NO_VALUES;
! 	      break;
! 	    case SIMPLE_VALUES:
! 	      print_values = PRINT_SIMPLE_VALUES;
! 	      break;
! 	    case ALL_VALUES:
! 	      print_values = PRINT_ALL_VALUES;
! 	      break;
! 	    case FROM_OPT:
! 	      start = atol (optarg);
! 	      if (start < 0)
! 		start = 0;
! 	      break;
! 	    case NUMBER_OPT:
! 	      number = atol (optarg);
! 	      break;
! 	    case STRIDE_OPT:
! 	      stride = atol (optarg);
! 	      if (stride < 1)
! 	      	error (_("Positive stride values only"));
! 	      break;
! 	    }
! 	}
!       if (optind >= argc)
! 	error (_("Missing VARNAME"));
  
!       if (optind < argc - 1)
! 	error (_("Garbage at end of command"));
! 
!       var = varobj_get_handle (argv[optind]);
!     }
! 
!   children = varobj_list_children (var, start, number, stride);
    ui_out_field_int (uiout, "numchild", VEC_length (varobj_p, children));
  
    if (VEC_length (varobj_p, children) == 0)
      return MI_CMD_DONE;


*** varobj.h	10 Apr 2008 08:41:40 +1200	1.18
--- varobj.h	27 Apr 2008 15:14:51 +1200	
*************** extern int varobj_get_num_children (stru
*** 99,105 ****
  
  /* Return the list of children of VAR.  The returned vector
     should not be modified in any way.  */
! extern VEC (varobj_p)* varobj_list_children (struct varobj *var);
  
  extern char *varobj_get_type (struct varobj *var);
  
--- 99,106 ----
  
  /* Return the list of children of VAR.  The returned vector
     should not be modified in any way.  */
! extern VEC (varobj_p)* varobj_list_children (struct varobj *var, int start,
! 					     int number, int stride);
  
  extern char *varobj_get_type (struct varobj *var);
  


*** varobj.c	20 Apr 2008 10:20:39 +1200	1.111
--- varobj.c	27 Apr 2008 22:58:28 +1200	
*************** struct varobj
*** 131,136 ****
--- 131,140 ----
    /* The number of (immediate) children this variable has */
    int num_children;
  
+   /* The number of (immediate) children this variable that exist as varobjs.  
+      current_children < num_children  */
+   int current_children;
+ 
    /* If this object is a child, this points to its immediate parent. */
    struct varobj *parent;
  
*************** static int install_variable (struct varo
*** 187,193 ****
  
  static void uninstall_variable (struct varobj *);
  
! static struct varobj *create_child (struct varobj *, int, char *);
  
  /* Utility routines */
  
--- 191,197 ----
  
  static void uninstall_variable (struct varobj *);
  
! static struct varobj *create_child (struct varobj *, int, int, char *);
  
  /* Utility routines */
  
*************** varobj_get_num_children (struct varobj *
*** 752,762 ****
     the return code is the number of such children or -1 on error */
  
  VEC (varobj_p)*
! varobj_list_children (struct varobj *var)
  {
    struct varobj *child;
    char *name;
!   int i;
  
    if (var->num_children == -1)
      var->num_children = number_of_children (var);
--- 756,767 ----
     the return code is the number of such children or -1 on error */
  
  VEC (varobj_p)*
! varobj_list_children (struct varobj *var, int start, int number, int stride)
  {
    struct varobj *child;
    char *name;
!   int i, j, new_children = 0;
!   varobj_p varchild;
  
    if (var->num_children == -1)
      var->num_children = number_of_children (var);
*************** varobj_list_children (struct varobj *var
*** 765,790 ****
    if (var->num_children == -1)
      return var->children;
  
!   /* If we're called when the list of children is not yet initialized,
!      allocate enough elements in it.  */
!   while (VEC_length (varobj_p, var->children) < var->num_children)
!     VEC_safe_push (varobj_p, var->children, NULL);
! 
!   for (i = 0; i < var->num_children; i++)
!     {
!       varobj_p existing = VEC_index (varobj_p, var->children, i);
! 
!       if (existing == NULL)
! 	{
! 	  /* Either it's the first call to varobj_list_children for
! 	     this variable object, and the child was never created,
! 	     or it was explicitly deleted by the client.  */
! 	  name = name_of_child (var, i);
! 	  existing = create_child (var, i, name);
! 	  VEC_replace (varobj_p, var->children, i, existing);
  	}
      }
  
    return var->children;
  }
  
--- 770,800 ----
    if (var->num_children == -1)
      return var->children;
  
!   for (j = 0; j < number; j++)
!     {
!       int real_index = start + j * stride;
!       if (real_index >= var->num_children)
! 	break;
!       name = name_of_child (var, real_index);
! 
!       for (i = 0; i < var->current_children; i++)
! 	{
! 	  varchild = VEC_index (varobj_p, var->children, i);
! 
! 	  /* Child already exists */
! 	  if (strcmp (varchild->name, name) == 0)
! 	    break;
! 	}
!       /* No child found */
!       if (i == var->current_children)
! 	{
! 	  varchild = create_child (var, i + new_children, real_index, name);
! 	  VEC_safe_push (varobj_p, var->children, varchild);
! 	  new_children++;
  	}
      }
  
+   var->current_children += new_children;
    return var->children;
  }
  
*************** uninstall_variable (struct varobj *var)
*** 1442,1448 ****
  
  /* Create and install a child of the parent of the given name */
  static struct varobj *
! create_child (struct varobj *parent, int index, char *name)
  {
    struct varobj *child;
    char *childs_name;
--- 1452,1458 ----
  
  /* Create and install a child of the parent of the given name */
  static struct varobj *
! create_child (struct varobj *parent, int index, int real_index, char *name)
  {
    struct varobj *child;
    char *childs_name;
*************** create_child (struct varobj *parent, int
*** 1453,1459 ****
    /* name is allocated by name_of_child */
    child->name = name;
    child->index = index;
!   value = value_of_child (parent, index);
    child->parent = parent;
    child->root = parent->root;
    childs_name = xstrprintf ("%s.%s", parent->obj_name, name);
--- 1463,1469 ----
    /* name is allocated by name_of_child */
    child->name = name;
    child->index = index;
!   value = value_of_child (parent, real_index);
    child->parent = parent;
    child->root = parent->root;
    childs_name = xstrprintf ("%s.%s", parent->obj_name, name);
*************** new_variable (void)
*** 1494,1499 ****
--- 1504,1510 ----
    var->type = NULL;
    var->value = NULL;
    var->num_children = -1;
+   var->current_children = 0;
    var->parent = NULL;
    var->children = NULL;
    var->format = 0;


             reply	other threads:[~2008-04-27 11:14 UTC|newest]

Thread overview: 34+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-04-27 15:34 Nick Roberts [this message]
2008-04-29 15:58 ` Marc Khouzam
2008-04-30  7:02   ` Nick Roberts
2008-04-30  9:20     ` Vladimir Prus
2008-04-30  9:25       ` Nick Roberts
2008-04-30  9:39         ` Vladimir Prus
2008-04-30 16:29           ` Marc Khouzam
2008-05-01 15:56             ` Vladimir Prus
2008-05-01 17:29               ` Marc Khouzam
2008-05-01 12:15           ` Nick Roberts
2008-05-10 14:45             ` Nick Roberts
2008-05-28 19:15               ` Vladimir Prus
2008-05-29 12:01                 ` Nick Roberts
2008-04-30 16:22         ` Marc Khouzam
2008-05-01 15:54           ` Vladimir Prus
2008-05-01 18:14             ` Marc Khouzam
2008-05-01 18:40               ` Vladimir Prus
2008-05-01 20:49                 ` Daniel Jacobowitz
2008-05-01 23:38                   ` Nick Roberts
2008-05-02  0:58                 ` Marc Khouzam
2008-05-11 17:45                   ` Vladimir Prus
2008-04-30 10:47       ` André Pönitz
2008-04-30 12:20         ` Vladimir Prus
2008-04-30 12:53           ` André Pönitz
2008-04-30 13:11             ` Vladimir Prus
2008-04-30 12:44         ` Nick Roberts
     [not found]           ` <200804301244.55116.apoenitz@trolltech.com>
2008-04-30 13:16             ` André Pönitz
2008-05-01  6:27               ` Nick Roberts
2008-05-05 11:46                 ` André Pönitz
2008-04-30 14:59     ` Marc Khouzam
2008-05-01 12:06       ` Nick Roberts
2008-05-01 14:22         ` Marc Khouzam
2008-05-01 20:41     ` Daniel Jacobowitz
2008-04-30  8:59 ` Vladimir Prus

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=18452.24568.655617.907458@kahikatea.snap.net.nz \
    --to=nickrob@snap.net.nz \
    --cc=gdb-patches@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox