From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 27705 invoked by alias); 27 Apr 2008 11:14:54 -0000 Received: (qmail 27691 invoked by uid 22791); 27 Apr 2008 11:14:53 -0000 X-Spam-Check-By: sourceware.org Received: from viper.snap.net.nz (HELO viper.snap.net.nz) (202.37.101.25) by sourceware.org (qpsmtpd/0.31) with ESMTP; Sun, 27 Apr 2008 11:14:15 +0000 Received: from kahikatea.snap.net.nz (9.30.255.123.static.snap.net.nz [123.255.30.9]) by viper.snap.net.nz (Postfix) with ESMTP id 50C123D9E2F for ; Sun, 27 Apr 2008 23:14:12 +1200 (NZST) Received: by kahikatea.snap.net.nz (Postfix, from userid 1000) id 845CA8FC6D; Sun, 27 Apr 2008 23:14:02 +1200 (NZST) From: Nick Roberts MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Message-ID: <18452.24568.655617.907458@kahikatea.snap.net.nz> Date: Sun, 27 Apr 2008 15:34:00 -0000 To: gdb-patches@sourceware.org Subject: [PATCH:MI] Return a subset of a variable object's children X-Mailer: VM 7.19 under Emacs 22.2.50.2 X-IsSubscribed: yes Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2008-04/txt/msg00619.txt.bz2 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 * 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;