// $Id$ // Store information about a single display espression // Copyright (C) 1995 Technische Universitaet Braunschweig, Germany. // Written by Dorothea Luetkehaus <luetke@ips.cs.tu-bs.de>. // // This file is part of DDD. // // DDD is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public // License as published by the Free Software Foundation; either // version 3 of the License, or (at your option) any later version. // // DDD is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. // See the GNU General Public License for more details. // // You should have received a copy of the GNU General Public // License along with DDD -- see the file COPYING. // If not, see <http://www.gnu.org/licenses/>. // // DDD is the data display debugger. // For details, see the DDD World-Wide-Web page, // `http://www.gnu.org/software/ddd/', // or send a mail to the DDD developers <ddd@gnu.org>. #ifndef _DDD_DispNode_h #define _DDD_DispNode_h //----------------------------------------------------------------------------- // A DispNode keeps all information about a single data display //----------------------------------------------------------------------------- // Misc includes #include "strclass.h" #include "assert.h" #include "bool.h" #include "GraphNode.h" #include "HandlerL.h" #include "BoxGraphN.h" #include "DispValue.h" class DispBox; // Event types const unsigned DispNode_Disabled = 0; const unsigned DispNode_NTypes = DispNode_Disabled + 1; //----------------------------------------------------------------------------- // Non-class functions //----------------------------------------------------------------------------- // Return true iff S is a user command display (`status display') inline bool is_user_command(const string& s) { return s.length() >= 2 && s[0] == '`' && s[s.length() - 1] == '`'; } // Return user command from S string user_command(const string& s); //----------------------------------------------------------------------------- // The DispNode class //----------------------------------------------------------------------------- class DispNode: public BoxGraphNode { public: DECLARE_TYPE_INFO private: int mydisp_nr; // Display number string myname; // Display expression string myaddr; // Location of expression string myscope; // Program location where created string mydepends_on; // Display we depend upon (when deferred) bool myactive; // Flag: is display active (in scope)? bool saved_node_hidden; // Saved `hidden' flag of node bool mydeferred; // Flag: is display deferred? int myclustered; // Flag: is display clustered? bool myplotted; // Flag: is display plotted? bool myconstant; // Flag: is display constant? DispValue* disp_value; // Associated value DispValue* myselected_value; // Selected value within DISP_VALUE DispBox* disp_box; // Associated box within DISP_VALUE int mylast_change; // Last value or address change int mylast_refresh; // Last refresh static int tics; // Shared change and refresh counter public: int alias_of; // Alias of another display protected: static HandlerList handlers; static class TagBox *findTagBox(const Box *box, DispValue *dv); virtual string str() const { return myname; } DispNode(const DispNode& node); virtual void refresh_plot_state() const; private: // Prohibit assignment DispNode& operator = (const DispNode&); public: // Create a new display numbered DISP_NR, named NAME, created at // SCOPE (a function name or "") with a value of VALUE. DispNode(int disp_nr, const string& name, const string& scope, const string& value, bool plotted); // Destructor ~DispNode(); // Duplication GraphNode *dup() const { return new DispNode(*this); } // Resources int disp_nr() const { return mydisp_nr; } const string& name() const { return myname; } const string& addr() const { return myaddr; } const string& scope() const { return myscope; } const string& depends_on() const { assert(deferred()); return mydepends_on; } string& depends_on() { assert(deferred()); return mydepends_on; } bool enabled() const { return value() != 0 && value()->enabled(); } bool disabled() const { return !enabled(); } bool active() const { return myactive; } bool deferred() const { return mydeferred; } bool& deferred() { return mydeferred; } int clustered() const { return myclustered; } bool plotted() const { return myplotted; } bool& plotted() { return myplotted; } bool constant() const { return myconstant; } bool& constant() { return myconstant; } int last_change() const { return mylast_change; } int last_refresh() const { return mylast_refresh; } // These can be used to force updates void set_last_change(int value = 0) { mylast_change = value; } void set_last_refresh(int value = 0) { mylast_refresh = value; } bool is_user_command() const { return ::is_user_command(name()); } string user_command() const { return ::user_command(name()); } // Return `true' if this expression can be aliased bool alias_ok() const; DispValue* value() const { return disp_value; } DispValue* selected_value() const { return myselected_value; } // Handlers static void addHandler (unsigned type, HandlerProc proc, void* client_data = 0); static void removeHandler (unsigned type, HandlerProc proc, void *client_data = 0); // Update with NEW_VALUE; return false if value is unchanged bool update (string& new_value); // Update address with NEW_ADDR void set_addr(const string& new_addr); // Re-create the box value from old DISP_VALUE void refresh(); // Re-create the entire box from old DISP_VALUE void reset(); // Highlights the box related to the display value DV void select (DispValue *dv = 0); // Copy selection state from SRC void copy_selection_state(const DispNode& src); // Disable and enable manually void disable(); void enable(); // Show and hide manually void make_active(); void make_inactive(); // Cluster display into TARGET void cluster(int target); inline void uncluster() { cluster(0); } // Toggle titles. Return true iff changed. bool set_title(bool set); // Print plots to FILENAME void print_plots(const string& filename, const GraphGC& gc = GraphGC()) const; }; // Clustering stuff // The command to use for clusters #define CLUSTER_COMMAND "displays" inline bool is_cluster(const DispNode *dn) { return dn->is_user_command() && dn->user_command().contains(CLUSTER_COMMAND, 0); } #endif // _DDD_DispNode_h // DON'T ADD ANYTHING BEHIND THIS #endif