/* DebuggerCommand.java Copyright 2003, Bil Lewis This program 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 2 of the License, or (at your option) any later version. This program 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 this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package com.lambda.Debugger; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.Serializable; public class DebuggerCommand implements Serializable, Runnable { private static boolean recordCommands = false; protected Class clazz; protected String command; protected int index = -1; // -1 -> "NO INDEX USED FOR THIS COMMAND" protected static DebuggerCommandHistory previousCommandHistory, previousPreviousCommandHistory; public DebuggerCommand(Class c, String cmd, int index) { clazz = c; command = cmd; this.index = index; } /* public DebuggerCommand(Class c, String cmd, int index, int value) { clazz = c; command = cmd; this.index = index; intValue = value; } */ public DebuggerCommand(Class c, String cmd) { clazz = c; command = cmd; } public DebuggerCommand() { } public void run() { // Run only in Swing main thread. replayRecording(); } public static void startRecording() { recordCommands=true; DebuggerCommandHistoryList.reset(); Debugger.message("Recording commands.", false); } public static void stopRecording() { recordCommands=false; DebuggerCommandHistoryList.writeHistory(); } public static void replayRecording() { if (recordCommands) stopRecording(); DebuggerCommandHistoryList.readHistory(); DebuggerCommandHistoryList.replayRecording(); } public void execute() { if (command == null) throw new DebuggerException("Cannot execute null command"); DebuggerCommandHistory dch = new DebuggerCommandHistory(this); //D.println("DebuggerCommand.execute( " + clazz +"."+command+"() )"); try {executeNow();} catch (Exception e) { System.out.println("Exception in DebuggerCommand:\n"); e.printStackTrace(); } previousCommandHistory = dch; if (recordCommands) dch.recordResult(); } public void executeNow() { if (clazz == CodeActionListener.class) { if (command.equals("firstLine")) CodeActionListener.firstLine(); else if (command.equals("previousLineThisFunction")) CodeActionListener.previousLineThisFunction(); else if (command.equals("previousLineAnyFunction")) CodeActionListener.previousLineAnyFunction(); else if (command.equals("nextLineAnyFunction")) CodeActionListener.nextLineAnyFunction(); else if (command.equals("nextLineThisFunction")) CodeActionListener.nextLineThisFunction(); else if (command.equals("lastLine")) CodeActionListener.lastLine(); else if (command.equals("previousIteration")) CodeActionListener.previousIteration(); else if (command.equals("nextIteration")) CodeActionListener.nextIteration(); else if (command.equals("upToCaller")) CodeActionListener.upToCaller(); else if (command.equals("returnToCaller")) CodeActionListener.returnToCaller(); else if (command.equals("firstLineB")) CodeActionListener.firstLineB(); else System.out.println("IMPOSSIBLE: DebuggerCommand.execute() no such command: " + clazz+"."+command); } if (clazz == FilterMenuActionListener.class) { if (command.equals("filterOutMethodClass")) FilterMenuActionListener.filterOutMethodClass(); else if (command.equals("unfilter")) FilterMenuActionListener.unfilter(); else if (command.equals("filterOutClass")) FilterMenuActionListener.filterOutClass(); else if (command.equals("saveFilters")) {Defaults.writeDefaults(); Debugger.message("Wrote defaults", false);} else if (command.equals("filterIn")) FilterMenuActionListener.filterIn(); else if (command.equals("filter1")) FilterMenuActionListener.filter1(); else if (command.equals("filter2")) FilterMenuActionListener.filter2(); else if (command.equals("filter3")) FilterMenuActionListener.filter3(); else if (command.equals("filter4")) FilterMenuActionListener.filter4(); else if (command.equals("filter5")) FilterMenuActionListener.filter5(); else if (command.equals("filter6")) FilterMenuActionListener.filter6(); else if (command.equals("filter7")) FilterMenuActionListener.filter7(); else if (command.equals("filter8")) FilterMenuActionListener.filter8(); else if (command.equals("filter9")) FilterMenuActionListener.filter9(); else if (command.equals("filterOutMethod")) FilterMenuActionListener.filterOutMethod(); else if (command.equals("filterOutMethodInternals")) FilterMenuActionListener.filterOutMethodInternals(); else System.out.println("IMPOSSIBLE: DebuggerCommand.execute() no such command: " + clazz+"."+command); } if (clazz == ThreadActionListener.class) { if (command.equals("first")) ThreadActionListener.first(); else if (command.equals("previous")) ThreadActionListener.previous(); else if (command.equals("next")) ThreadActionListener.next(); else if (command.equals("last")) ThreadActionListener.last(); else System.out.println("IMPOSSIBLE: DebuggerCommand.execute() no such command: " + clazz+"."+command); } if (clazz == DebuggerActionListener.class) { if (command.equals("first")) DebuggerActionListener.first(); else if (command.equals("previous")) DebuggerActionListener.previous(); else if (command.equals("next")) DebuggerActionListener.next(); else if (command.equals("last")) DebuggerActionListener.last(); else if (command.equals("previousRevert")) DebuggerActionListener.previousRevert(); else System.out.println("IMPOSSIBLE: DebuggerCommand.execute() no such command: " + clazz+"."+command); } if (clazz == LocalsActionListener.class) { if (command.equals("first")) LocalsActionListener.first(index); else if (command.equals("previous")) LocalsActionListener.previous(index); else if (command.equals("next")) LocalsActionListener.next(index); else if (command.equals("last")) LocalsActionListener.last(index); else System.out.println("IMPOSSIBLE: DebuggerCommand.execute() no such command: " + clazz+"."+command); } if (clazz == ThisActionListener.class) {// UNUSED! if (command.equals("first")) ThisActionListener.first(); else if (command.equals("previous")) ThisActionListener.previous(); else if (command.equals("next")) ThisActionListener.next(); else if (command.equals("last")) ThisActionListener.last(); else System.out.println("IMPOSSIBLE: DebuggerCommand.execute() no such command: " + clazz+"."+command); } if (clazz == TraceActionListener.class) { if (command.equals("first")) TraceActionListener.first(); else if (command.equals("previous")) TraceActionListener.previous(); else if (command.equals("next")) TraceActionListener.next(); else if (command.equals("last")) TraceActionListener.last(); else System.out.println("IMPOSSIBLE: DebuggerCommand.execute() no such command: " + clazz+"."+command); } if (clazz == ObjectActionListener.class) { if (command.equals("first")) ObjectActionListener.first(index); else if (command.equals("previous")) ObjectActionListener.previous(index); else if (command.equals("next")) ObjectActionListener.next(index); else if (command.equals("last")) ObjectActionListener.last(index); else System.out.println("IMPOSSIBLE: DebuggerCommand.execute() no such command: " + clazz+"."+command); } if (clazz == TTYActionListener.class) { if (command.equals("first")) TTYActionListener.first(); else if (command.equals("previous")) TTYActionListener.previous(); else if (command.equals("next")) TTYActionListener.next(); else if (command.equals("last")) TTYActionListener.last(); else System.out.println("IMPOSSIBLE: DebuggerCommand.execute() no such command: " + clazz+"."+command); } if (clazz == ObjectsMenuActionListener.class) { if (command.equals("copyClass")) ObjectsMenuActionListener.copyClass(); else if (command.equals("remove")) ObjectsMenuActionListener.remove(); else if (command.equals("expand")) ObjectsMenuActionListener.expand(); else if (command.equals("select")) ObjectsMenuActionListener.select(); else if (command.equals("selectLocal")) ObjectsMenuActionListener.selectLocal(); else if (command.equals("retain")) ObjectsMenuActionListener.retain(); else if (command.equals("set")) ObjectsMenuActionListener.set(); else if (command.equals("abort")) ObjectsMenuActionListener.abort(); else if (command.equals("copy")) ObjectsMenuActionListener.copy(); else if (command.equals("showAll")) ObjectsMenuActionListener.showAll(); else if (command.equals("restore")) ObjectsMenuActionListener.restore(); else if (command.equals("add")) ObjectsMenuActionListener.add(); else if (command.equals("hex")) ObjectsMenuActionListener.hex(); else if (command.equals("print")) ObjectsMenuActionListener.print(); else if (command.equals("tostring")) ObjectsMenuActionListener.tostring(); else if (command.equals("input")) ObjectsMenuActionListener.input(); else System.out.println("IMPOSSIBLE: DebuggerCommand.execute() no such command: " + clazz+"."+command); } if (clazz == CodeListener.class) { if (command.equals("selectCodeLine")) CodeListener.selectCodeLine(index); else System.out.println("IMPOSSIBLE: DebuggerCommand.execute() no such command: " + clazz+"."+command); } if (clazz == FileMenuActionListener.class) { if (command.equals("choose")) FileMenuActionListener.choose(); else System.out.println("IMPOSSIBLE: DebuggerCommand.execute() no such command: " + clazz+"."+command); } if (clazz == HelpMenuActionListener.class) { if (command.equals("ghelp")) HelpMenuActionListener.ghelp(); if (command.equals("dhelp")) HelpMenuActionListener.dhelp(); else if (command.equals("fhelp")) HelpMenuActionListener.fhelp(); else System.out.println("IMPOSSIBLE: DebuggerCommand.execute() no such command: " + clazz+"."+command); } if (clazz == StackListener.class) { if (command.equals("select")) StackListener.select(index); else System.out.println("IMPOSSIBLE: DebuggerCommand.execute() no such command: " + clazz+"."+command); } if (clazz == TTYListener.class) { if (command.equals("select")) TTYListener.select(index); else System.out.println("IMPOSSIBLE: DebuggerCommand.execute() no such command: " + clazz+"."+command); } if (clazz == TraceListener.class) { if (command.equals("select")) TraceListener.select(index); else System.out.println("IMPOSSIBLE: DebuggerCommand.execute() no such command: " + clazz+"."+command); } if (clazz == ThreadListener.class) { if (command.equals("select")) ThreadListener.select(index); else System.out.println("IMPOSSIBLE: DebuggerCommand.execute() no such command: " + clazz+"."+command); } if (clazz == TimeSliderListener.class) { if (command.equals("slider")) TimeSliderListener.slider(index); else System.out.println("IMPOSSIBLE: DebuggerCommand.execute() no such command: " + clazz+"."+command); } if (clazz == DebugMenuActionListener.class) { if (command.equals("repeat")) { if (previousCommandHistory == null) { System.out.println("No previous command to repeat"); return; } if (previousCommandHistory.command.command.equals("repeat")) { previousCommandHistory = previousPreviousCommandHistory; } System.out.println("executing command: " + previousCommandHistory.command.command); previousCommandHistory.execute(); previousPreviousCommandHistory = previousCommandHistory; } else System.out.println("IMPOSSIBLE: DebuggerCommand.execute() no such command: " + clazz+"."+command); } } } class DebuggerCommandHistory implements Serializable { final DebuggerCommand command; private int end; private String fileLine, message; public DebuggerCommandHistory(DebuggerCommand dc) { command = dc; } public void execute() { command.execute(); } public void recordResult() { DebuggerCommandHistoryList.add(this); end = TimeStamp.currentTime().time; message = Debugger.getMessage(); } public boolean replay(int i) { boolean failed = false; command.execute(); if (TimeStamp.currentTime().time != end) { if (command.index == -1) System.out.println("Replay Error["+i+"]: " + command.clazz +"." + command.command + "() \nexpected: "+end+ "\n got: " +TimeStamp.currentTime().time); else System.out.println("Replay Error["+i+"]: " + command.clazz +"." + command.command + "(" + command.index + ") \nexpected: "+end+ "\n got: " +TimeStamp.currentTime().time); failed = true; } if (!message.equals(Debugger.getMessage())) { if (command.index == -1) System.out.println("Replay Error["+i+"]: " + command.clazz +"." + command.command + " \n expected: "+message+ "\n got: " +Debugger.getMessage()); else System.out.println("Replay Error["+i+"]: " + command.clazz +"." + command.command + "(" + command.index + ") \n expected: "+message+ "\n got: " +Debugger.getMessage()); failed = true; } return failed; } } class DebuggerCommandHistoryList implements Serializable { private static DebuggerCommandHistoryList commandHistoryList = new DebuggerCommandHistoryList(); private DebuggerCommandHistory[] commandHistory = new DebuggerCommandHistory[1000]; private int index = 0; public static void add(DebuggerCommandHistory dch) { commandHistoryList.addCommand(dch); } public void addCommand(DebuggerCommandHistory dch) { commandHistory[index] = dch; index++; } public static void replayRecording() { if (commandHistoryList == null) return; commandHistoryList.replayRecordings(); } public void replayRecordings() { boolean failed = false; if (index == 0) { Debugger.message("No recorded commands.", true); return; } for (int i=0; i < index; i++) { if (commandHistory[i].replay(i)) { Debugger.message(" Command " + i + " failed.", true); return; } } Debugger.message("All "+index+" commands succeeded.", false); } public static void writeHistory() { try { ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(Debugger.programName+ ".debuggerCommands")); oos.writeObject(commandHistoryList); oos.close(); Debugger.message("Saved history to "+Debugger.programName+ ".debuggerCommands.", false); } catch (IOException e) {Debugger.message("Couldn't save history " + e, true);} } public static void readHistory() { try { ObjectInputStream ois = new ObjectInputStream(new FileInputStream(Debugger.programName+ ".debuggerCommands")); commandHistoryList = (DebuggerCommandHistoryList)ois.readObject(); ois.close(); } catch (IOException e) {Debugger.message("Couldn't read history " + e, true);} catch (ClassNotFoundException e) {Debugger.message("Couldn't read history " + e, true);} } public static void reset() { commandHistoryList.index = 0; } }