From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 14225 invoked by alias); 4 Jan 2007 04:13:56 -0000 Received: (qmail 14190 invoked by uid 22791); 4 Jan 2007 04:13:55 -0000 X-Spam-Check-By: sourceware.org Received: from viper.snap.net.nz (HELO viper.snap.net.nz) (202.37.101.8) by sourceware.org (qpsmtpd/0.31) with ESMTP; Thu, 04 Jan 2007 04:13:48 +0000 Received: from kahikatea.snap.net.nz (p202-124-120-135.snap.net.nz [202.124.120.135]) by viper.snap.net.nz (Postfix) with ESMTP id E7DEF3D80D9; Thu, 4 Jan 2007 17:13:39 +1300 (NZDT) Received: by kahikatea.snap.net.nz (Postfix, from userid 500) id A16BD4F6CB; Thu, 4 Jan 2007 17:13:38 +1300 (NZDT) From: Nick Roberts MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Message-ID: <17820.32496.851404.587153@kahikatea.snap.net.nz> Date: Thu, 04 Jan 2007 04:13:00 -0000 To: Daniel Jacobowitz Cc: Vladimir Prus , gdb-patches@sources.redhat.com Subject: Re: RFC: MI - Detecting change of string contents with variable objects In-Reply-To: <20070103224605.GO17935@nevyn.them.org> References: <17797.65268.689590.797944@kahikatea.snap.net.nz> <17798.19683.251190.740216@kahikatea.snap.net.nz> <200612181136.02429.ghost@cs.msu.su> <20061218133827.GA24800@nevyn.them.org> <17799.3497.476593.138858@kahikatea.snap.net.nz> <20070103224605.GO17935@nevyn.them.org> X-Mailer: VM 7.19 under Emacs 22.0.92.5 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: 2007-01/txt/msg00100.txt.bz2 > > That's a vary good idea. Here's a revised patch that isn't language > > dependent. In addition to detecting string contents changes it detects > > when the output format has changed with -var-set-format. I don't see this > > as a bad thing and it means that my patch earlier in the year for > > including the value in the output of -var-set-format probably isn't > > needed. > > Sounds good. I generally agree with Vladimir about reusing > c_value_of_variable, however. > > I believe it is as simple as: > - Passing a struct value *. > - Always returning NULL if there is no value, instead of doing > the struct and array special cases first. > - Using value_type to get the type code and the number of children. > - Probably calling value_fetch_lazy first when passing it the new > value, to avoid the assertions. I've probably done it the other way round to how you're asking (used value_get_print_value in c_value_of_variable) but, likewise, it involves re-use. > Let me know if you want me to try that myself. If you approve what I've done that's fine, if not, perhaps you could show me what you want. -- Nick http://www.inet.net.nz/~nickrob 2007-01-03 Nick Roberts * varobj.c (struct varobj): New member print_value. (install_new_value): Compare last printed value with current one instead of contents. (new_variable): Initialize var->print_value to NULL. (free_variable): Free var->print_value. (value_get_print_value): New function derived from c_value_of_variable. (c_value_of_variable): Use value_get_print_value. *** varobj.c 04 Jan 2007 16:22:25 +1300 1.68 --- varobj.c 04 Jan 2007 17:00:45 +1300 *************** struct varobj *** 102,107 **** --- 102,108 ---- /* The type of this variable. This may NEVER be NULL. */ struct type *type; + /* The value of this expression or subexpression. This may be NULL. Invariant: if type_changeable (this) is non-zero, the value is either NULL, or not lazy. */ *************** struct varobj *** 127,132 **** --- 128,136 ---- /* Was this variable updated via a varobj_set_value operation */ int updated; + + /* Last print value */ + char *print_value; }; /* Every variable keeps a linked list of its children, described *************** static int variable_editable (struct var *** 234,239 **** --- 238,246 ---- static char *my_value_of_variable (struct varobj *var); + static char *value_get_print_value (struct value *value, + enum varobj_display_formats format); + static int type_changeable (struct varobj *var); /* C implementation */ *************** install_new_value (struct varobj *var, s *** 979,1003 **** else { gdb_assert (!value_lazy (var->value)); - gdb_assert (!value_lazy (value)); ! if (!value_contents_equal (var->value, value)) ! changed = 1; } } } ! /* We must always keep the new value, since children depend on it. */ if (var->value != NULL) value_free (var->value); var->value = value; var->updated = 0; ! gdb_assert (!var->value || value_type (var->value)); return changed; } - /* Update the values for a variable and its children. This is a two-pronged attack. First, re-parse the value for the root's --- 986,1020 ---- else { gdb_assert (!value_lazy (var->value)); ! if (var->print_value) ! { ! if (strcmp (var->print_value, ! value_get_print_value (value, var->format))) ! { ! xfree (var->print_value); ! var->print_value = ! xstrdup (value_get_print_value (value, var->format)); ! changed = 1; ! } ! } ! else ! var->print_value = ! xstrdup (value_get_print_value (value, var->format)); } } } ! /* We must always keep the new value, since children depend on it. */ if (var->value != NULL) value_free (var->value); var->value = value; var->updated = 0; ! gdb_assert (!var->value || value_type (var->value)); return changed; } /* Update the values for a variable and its children. This is a two-pronged attack. First, re-parse the value for the root's *************** new_variable (void) *** 1470,1475 **** --- 1487,1493 ---- var->format = 0; var->root = NULL; var->updated = 0; + var->print_value = NULL; return var; } *************** free_variable (struct varobj *var) *** 1503,1508 **** --- 1521,1527 ---- xfree (var->name); xfree (var->obj_name); + xfree (var->print_value); xfree (var); } *************** my_value_of_variable (struct varobj *var *** 1785,1790 **** --- 1804,1823 ---- return (*var->root->lang->value_of_variable) (var); } + static char * + value_get_print_value (struct value *value, enum varobj_display_formats format) + { + long dummy; + struct ui_file *stb = mem_fileopen (); + struct cleanup *old_chain = make_cleanup_ui_file_delete (stb); + char *thevalue; + + common_val_print (value, stb, format_code[(int) format], 1, 0, 0); + thevalue = ui_file_xstrdup (stb, &dummy); + do_cleanups (old_chain); + return thevalue; + } + /* Return non-zero if changes in value of VAR must be detected and reported by -var-update. Return zero is -var-update should never report *************** c_value_of_variable (struct varobj *var) *** 2153,2171 **** } else { - long dummy; - struct ui_file *stb = mem_fileopen (); - struct cleanup *old_chain = make_cleanup_ui_file_delete (stb); - char *thevalue; - gdb_assert (type_changeable (var)); gdb_assert (!value_lazy (var->value)); ! common_val_print (var->value, stb, ! format_code[(int) var->format], 1, 0, 0); ! thevalue = ui_file_xstrdup (stb, &dummy); ! do_cleanups (old_chain); ! return thevalue; ! } } } } --- 2186,2195 ---- } else { gdb_assert (type_changeable (var)); gdb_assert (!value_lazy (var->value)); ! return value_get_print_value (var->value, var->format); ! } } } }