// $Id$ -*- C++ -*- // Undo/Redo buffer // Copyright (C) 1998 Technische Universitaet Braunschweig, Germany. // Written by Andreas Zeller <zeller@gnu.org>. // // 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_UndoBuffer_h #define _DDD_UndoBuffer_h #include "bool.h" #include "UndoBE.h" #include "string-fun.h" // itostring() #include "IntArray.h" class BreakPoint; class StatusMsg; class UndoBuffer { private: // The history itself static UndoBufferArray history; // Last position in history + 1 static int history_position; // Currently processed entry static int current_entry; // If true, next `add' creates new entry static bool force_new_entry; // A collector for state values static UndoBufferEntry collector; // True if we have undone some exec position static bool _showing_earlier_state; // Current command source static string current_source; // True if position history is to stay unchanged static bool locked; // Helpers static bool process_command(UndoBufferEntry& entry); static bool process_state(UndoBufferEntry& entry); static bool process_frame(UndoBufferEntry& entry); static bool process_pos(UndoBufferEntry& entry); // True if we're undoing static bool undoing; // Rename all breakpoints from OLD_BP_NR to NEW_BP_NR static void remap_breakpoint(int old_bp_nr, int new_bp_nr); static void remap_breakpoint(string& cmd, int old_bp_nr, int new_bp_nr); // Enter or leave `past exec' mode static void showing_earlier_state(bool set, StatusMsg *msg = 0); // Remove all later entries, except for exec positions static void clear_after_position(); // Remove all exec commands static void clear_exec_commands(); // Remove all entries with no effect static void cleanup(); protected: // Add new entry static void add_entry(const UndoBufferEntry& entry); // Process entry static bool process_command(int entry); static bool process_state(int entry); static bool process_frame(int entry); static bool process_pos(int entry); // Log current position static void log(); // Call when all is done. If MSG is set, leave the outcome there. static void done(StatusMsg *msg = 0); // Get a short action description from COMMAND static string action(const string& command); // True if ENTRY has any effect static bool has_effect(const UndoBufferEntry& entry); public: // Maximum depth (-1: unlimited) static int max_history_depth; // Maximum memory size (-1: unlimited) static int max_history_size; // Set source command. static void set_source(const string& source); // Start a new entry. static void start(); static void start(const string& source) { set_source(source); start(); } // Adding entries // If START was called before any of these add_SOMETHING // calls, the call creates a new entry in the history. Otherwise, // the values are added to the last entry, possibly overriding // existing values. // Add status NAME/VALUE to history. static void add_status(const string& name, const string& value); // Add command COMMAND to history. If EXEC is set, COMMAND is // treated as execution command, i.e. dependent on the current // program state. static void add_command(const string &command, bool exec = false); // Custom calls static void add_state() { add_status(UB_STATE, ""); } static void add_position(const string& file_name, int line, bool exec) { add_status(exec ? UB_EXEC_POS : UB_POS, file_name + ":" + itostring(line)); } static void add_address(const string& address, bool exec) { add_status(exec ? UB_EXEC_ADDRESS : UB_ADDRESS, address); } static void add_where(const string& where) { add_status(UB_WHERE, where); } static void add_frame(const string& frame) { add_status(UB_FRAME, frame); } static void add_registers(const string& registers) { add_status(UB_REGISTERS, registers); } static void add_threads(const string& threads) { add_status(UB_THREADS, threads); } static void add_display(const string& name, const string& value) { add_status(UB_DISPLAY_PREFIX + name, value); } static void add_display_address(const string& name, const string& addr) { add_status(UB_DISPLAY_ADDRESS_PREFIX + name, addr); } // Removals // Remove status NAME from current history entry. static void remove_status(const string& name); static void remove_position() { remove_status(UB_EXEC_POS); remove_status(UB_POS); } static void remove_address() { remove_status(UB_EXEC_ADDRESS); remove_status(UB_ADDRESS); } static void remove_where() { remove_status(UB_WHERE); } static void remove_frame() { remove_status(UB_FRAME); } static void remove_registers() { remove_status(UB_REGISTERS); } static void remove_threads() { remove_status(UB_THREADS); } static void remove_display(const string& name) { remove_status(UB_DISPLAY_PREFIX + name); remove_status(UB_DISPLAY_ADDRESS_PREFIX + name); } // Undo/Redo action static void undo(); static void redo(); // Undo/Redo action descriptions static string undo_action(); static string redo_action(); // True iff we're showing an earlier program state static bool showing_earlier_state() { return _showing_earlier_state; } // Restore current program state static void restore_current_state(); // Clear history static void clear(); // Clear all execution positions static void clear_exec_pos(); // Add breakpoint state to OS static void add_breakpoint_state(std::ostream& os, BreakPoint *bp); // Return history of display NAME static string display_history(const string& name); // Return currently allocated bytes static int allocation(); // Invariant static bool OK(); }; extern UndoBuffer undo_buffer; #endif // _DDD_UndoBuffer_h // DON'T ADD ANYTHING BEHIND THIS #endif