From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 8452 invoked by alias); 18 Dec 2006 21:57:43 -0000 Received: (qmail 8178 invoked by uid 22791); 18 Dec 2006 21:57:41 -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; Mon, 18 Dec 2006 21:57:19 +0000 Received: from kahikatea.snap.net.nz (p202-124-124-222.snap.net.nz [202.124.124.222]) by viper.snap.net.nz (Postfix) with ESMTP id 580AD3D950B; Tue, 19 Dec 2006 10:58:42 +1300 (NZDT) Received: by kahikatea.snap.net.nz (Postfix, from userid 500) id C34C5BE456; Tue, 19 Dec 2006 10:52:42 +1300 (NZDT) From: Nick Roberts MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Message-ID: <17799.3497.476593.138858@kahikatea.snap.net.nz> Date: Mon, 18 Dec 2006 21:57: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: <20061218133827.GA24800@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> X-Mailer: VM 7.19 under Emacs 22.0.91.19 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: 2006-12/txt/msg00247.txt.bz2 > Should a varobj always report changed if the way GDB > would display the value has changed, in which case the special casing > isn't necessary? 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. It also means that value_contents_equal is not needed any longer, although I guess there's no harm in keeping it. -- Nick http://www.inet.net.nz/~nickrob 2006-12-19 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. *** varobj.c 11 Dec 2006 08:13:03 +1300 1.65 --- varobj.c 19 Dec 2006 10:27:50 +1300 *************** struct varobj *** 101,106 **** --- 101,107 ---- /* 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 *** 126,131 **** --- 127,135 ---- /* 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 *** 233,238 **** --- 237,245 ---- 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