added some more command types to support pipe implementation.

git-svn-id: https://mspsim.svn.sourceforge.net/svnroot/mspsim/mspsim@160 23d1a52b-0c3c-0410-b72d-8f29ab48fe35
This commit is contained in:
joxe 2008-03-09 00:52:15 +00:00
parent 36d5a21e46
commit 51c39cf63a
17 changed files with 248 additions and 815 deletions

View File

@ -1,6 +1,7 @@
0.85
Changes:
- fixed multiplier to handle the different modes better.
-
0.84
Changes:

View File

@ -0,0 +1,50 @@
/**
* Copyright (c) 2007, Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of MSPSim.
*
* $Id: $
*
* -----------------------------------------------------------------
*
* AsyncCommand - a command that will continue its execution after it
* returns from the executeCommand method.
*
* Author : Joakim Eriksson
* Created : 9 mar 2008
* Updated : $Date:$
* $Revision:$
*/
package se.sics.mspsim.cli;
/**
* @author joakim
*
*/
public interface AsyncCommand extends Command {
public void stopCommand(CommandContext context);
}

View File

@ -1,48 +1,53 @@
/**
* Copyright (c) 2008, Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of MSPSim.
*
* $Id$
*
* -----------------------------------------------------------------
*
* CommandBundle
*
* Author : Joakim Eriksson, Niclas Finne
* Created : Mon Feb 11 21:28:00 2008
* Updated : $Date: 2007/10/21 21:17:34 $
* $Revision: 1.3 $
*/
package se.sics.mspsim.util;
public interface CommandBundle {
public void setupCommands(ComponentRegistry registry, CommandHandler handler);
}
/**
* Copyright (c) 2007, Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of MSPSim.
*
* $Id: $
*
* -----------------------------------------------------------------
*
* BasicAsyncCommand
*
* Author : Joakim Eriksson
* Created : 9 mar 2008
* Updated : $Date:$
* $Revision:$
*/
package se.sics.mspsim.cli;
/**
* @author joakim
*
*/
public abstract class BasicAsyncCommand extends BasicCommand implements
AsyncCommand {
public BasicAsyncCommand(String cmdHelp, String argHelp) {
super(cmdHelp, argHelp);
}
}

View File

@ -1,5 +1,5 @@
/**
* Copyright (c) 2008, Swedish Institute of Computer Science.
* Copyright (c) 2007, Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -27,36 +27,27 @@
*
* This file is part of MSPSim.
*
* $Id$
* $Id: $
*
* -----------------------------------------------------------------
*
* BasicCommand
* BasicLineCommand
*
* Author : Joakim Eriksson, Niclas Finne
* Created : Mon Feb 11 21:28:00 2008
* Updated : $Date: 2007/10/21 21:17:34 $
* $Revision: 1.3 $
* Author : Joakim Eriksson
* Created : 9 mar 2008
* Updated : $Date:$
* $Revision:$
*/
package se.sics.mspsim.cli;
package se.sics.mspsim.util;
/**
* @author joakim
*
*/
public abstract class BasicLineCommand extends BasicAsyncCommand implements
LineListener {
public abstract class BasicCommand implements Command {
private String argumentHelp;
private String commandHelp;
public BasicCommand(String cmdHelp, String argHelp) {
commandHelp = cmdHelp;
argumentHelp = argHelp;
public BasicLineCommand(String cmdHelp, String argHelp) {
super(cmdHelp, argHelp);
}
public String getArgumentHelp(CommandContext context) {
return argumentHelp;
}
public String getCommandHelp(CommandContext context) {
return commandHelp;
}
}

View File

@ -10,19 +10,27 @@ public class CommandContext {
private String[] args;
private MapTable mapTable;
private int pid;
public final PrintStream out;
public final PrintStream err;
public final InputStream in;
private CommandContext nextCommand;
public CommandContext(MapTable table, String[] args,
InputStream in, PrintStream out, PrintStream err) {
int pid, InputStream in, PrintStream out, PrintStream err) {
this.args = args;
this.out = out;
this.err = err;
this.in = in;
this.pid = pid;
mapTable = table;
}
public int getPID() {
return pid;
}
/**
* exit needs to be called as soon as the command is completed (or stopped).

View File

@ -18,60 +18,60 @@ public class CommandHandler implements ActiveComponent, Runnable {
private Hashtable<String, Command> commands = new Hashtable<String, Command>();
private boolean exit;
private boolean workaround = false;
private BufferedReader inReader;
private InputStream in;
private PrintStream out;
private PrintStream err;
private MapTable mapTable;
private ComponentRegistry registry;
public CommandHandler() {
exit = false;
inReader = new BufferedReader(new InputStreamReader(in = System.in));
out = System.out;
err = System.err;
registerCommand("help", new Command() {
public int executeCommand(CommandContext context) {
if (context.getArgumentCount() == 0) {
context.out.println("Available commands:");
for(Map.Entry entry: commands.entrySet()) {
String name = (String) entry.getKey();
Command command = (Command) entry.getValue();
CommandContext cc = new CommandContext(mapTable, new String[] {
name
}, context.in, context.out, context.err);
String prefix = ' ' + name + ' ' + command.getArgumentHelp(cc);
String helpText = command.getCommandHelp(cc);
int n;
if (helpText != null && (n = helpText.indexOf('\n')) > 0) {
helpText = helpText.substring(0, n);
}
context.out.print(prefix);
if (prefix.length() < 8) {
context.out.print('\t');
}
if (prefix.length() < 16) {
context.out.print('\t');
}
context.out.println("\t " + helpText);
}
return 0;
}
context.out.println("Available commands:");
for(Map.Entry entry: commands.entrySet()) {
String name = (String) entry.getKey();
Command command = (Command) entry.getValue();
CommandContext cc = new CommandContext(mapTable, new String[] {
name
}, 0, context.in, context.out, context.err);
String prefix = ' ' + name + ' ' + command.getArgumentHelp(cc);
String helpText = command.getCommandHelp(cc);
int n;
if (helpText != null && (n = helpText.indexOf('\n')) > 0) {
helpText = helpText.substring(0, n);
}
context.out.print(prefix);
if (prefix.length() < 8) {
context.out.print('\t');
}
if (prefix.length() < 16) {
context.out.print('\t');
}
context.out.println("\t " + helpText);
}
return 0;
}
String cmd = context.getArgument(0);
Command command = commands.get(cmd);
if (command != null) {
CommandContext cc = new CommandContext(mapTable, new String[] {
cmd
}, context.in, context.out, context.err);
context.out.println(cmd + ' ' + command.getArgumentHelp(cc));
context.out.println(" " + command.getCommandHelp(cc));
return 0;
}
context.err.println("Error: unknown command '" + cmd + '\'');
return 1;
String cmd = context.getArgument(0);
Command command = commands.get(cmd);
if (command != null) {
CommandContext cc = new CommandContext(mapTable, new String[] {
cmd
}, 0, context.in, context.out, context.err);
context.out.println(cmd + ' ' + command.getArgumentHelp(cc));
context.out.println(" " + command.getCommandHelp(cc));
return 0;
}
context.err.println("Error: unknown command '" + cmd + '\'');
return 1;
}
public String getArgumentHelp(CommandContext context) {
return "<command>";
@ -87,62 +87,63 @@ public class CommandHandler implements ActiveComponent, Runnable {
}
});
}
// Add it to the hashtable (overwriting anything there)
public void registerCommand(String cmd, Command command) {
commands.put(cmd, command);
}
private String readLine(BufferedReader inReader2) throws IOException {
if (workaround) {
StringBuilder str = new StringBuilder();
while(true) {
if (inReader2.ready()) {
int c = inReader2.read();
if (c == '\n') {
return str.toString();
}
if (c != '\r') {
str.append((char)c);
}
} else {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
throw new InterruptedIOException();
StringBuilder str = new StringBuilder();
while(true) {
if (inReader2.ready()) {
int c = inReader2.read();
if (c == '\n') {
return str.toString();
}
if (c != '\r') {
str.append((char)c);
}
} else {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
throw new InterruptedIOException();
}
}
}
}
} else {
return inReader2.readLine();
}
}
public void run() {
while(!exit) {
try {
try {
out.print(">");
out.flush();
String line = readLine(inReader);//.readLine();
if (line != null && line.length() > 0) {
String[][] parts = CommandParser.parseLine(line);
if(parts.length > 0) {
// TODO add support for pipes
String[] args = parts[0];
Command cmd = commands.get(args[0]);
if (cmd == null) {
out.println("Error: Unknown command " + args[0]);
} else {
CommandContext cc = new CommandContext(mapTable, args, in, out, err);
try {
cmd.executeCommand(cc);
} catch (Exception e) {
err.println("Error: Command failed: " + e.getMessage());
e.printStackTrace(err);
}
}
}
String[][] parts = CommandParser.parseLine(line);
if(parts.length > 0) {
checkCommands(parts);
// TODO add support for pipes
String[] args = parts[0];
Command cmd = commands.get(args[0]);
if (cmd == null) {
out.println("Error: Unknown command " + args[0]);
} else {
CommandContext cc = new CommandContext(mapTable, args, 0, in, out, err);
try {
cmd.executeCommand(cc);
} catch (Exception e) {
err.println("Error: Command failed: " + e.getMessage());
e.printStackTrace(err);
}
}
}
}
} catch (IOException e) {
e.printStackTrace();
@ -152,6 +153,17 @@ public class CommandHandler implements ActiveComponent, Runnable {
}
}
private int checkCommands(String[][] cmds) {
for (int i = 0; i < cmds.length; i++) {
Command command = commands.get(cmds[i][0]);
if (i > 0 && command != null && !(command instanceof LineListener)) {
System.out.println("CLI: Error " + cmds[i][0] + " does not take input");
return -1;
}
}
return 0;
}
public void setComponentRegistry(ComponentRegistry registry) {
this.registry = registry;
}
@ -159,14 +171,14 @@ public class CommandHandler implements ActiveComponent, Runnable {
public void setWorkaround(boolean w) {
workaround = w;
}
public void start() {
mapTable = (MapTable) registry.getComponent(MapTable.class);
Object[] commandBundles = registry.getAllComponents(CommandBundle.class);
if (commandBundles != null) {
for (int i = 0, n = commandBundles.length; i < n; i++) {
((CommandBundle) commandBundles[i]).setupCommands(registry, this);
((CommandBundle) commandBundles[i]).setupCommands(registry, this);
}
}
new Thread(this, "cmd").start();

View File

@ -77,8 +77,10 @@ public class DebugCommands implements CommandBundle {
}
});
ch.registerCommand("watch", new Command() {
ch.registerCommand("watch",
new BasicAsyncCommand("adds a write watch to a given address or symbol", "<address or symbol>") {
int mode = 0;
int address = 0;
public int executeCommand(final CommandContext context) {
int baddr = context.getArgumentAsAddress(0);
if (baddr == -1) {
@ -91,7 +93,7 @@ public class DebugCommands implements CommandBundle {
mode = 1;
}
}
cpu.setBreakPoint(baddr,
cpu.setBreakPoint(address = baddr,
new CPUMonitor() {
public void cpuAction(int type, int adr, int data) {
if (mode == 0) {
@ -108,13 +110,9 @@ public class DebugCommands implements CommandBundle {
context.out.println("Watch set at: " + baddr);
return 0;
}
public String getArgumentHelp(CommandContext context) {
return "<address or symbol>";
}
public String getCommandHelp(CommandContext context) {
return "adds a write watch to a given address or symbol";
public void stopCommand(CommandContext context) {
cpu.clearBreakPoint(address);
}
});
@ -197,6 +195,17 @@ public class DebugCommands implements CommandBundle {
return 0;
}
});
// Does nothign yet... TODO!!!
ch.registerCommand("grep", new BasicLineCommand("grep", "regexp") {
public void lineRead(String line) {
}
public void stopCommand(CommandContext context) {
}
public int executeCommand(CommandContext context) {
return 0;
}
});
}
}
}

View File

@ -1,4 +1,4 @@
/**
/**
* Copyright (c) 2007, Swedish Institute of Computer Science.
* All rights reserved.
*

View File

@ -252,9 +252,13 @@ public class MSP430Core extends Chip implements MSP430Constants {
breakPoints[address] = mon;
}
public boolean hasBreakpoint(int address) {
public boolean hasBreakPoint(int address) {
return breakPoints[address] != null;
}
public void clearBreakPoint(int address) {
breakPoints[address] = null;
}
public void setRegisterWriteMonitor(int r, CPUMonitor mon) {
regWriteMonitors[r] = mon;

View File

@ -41,14 +41,14 @@ package se.sics.mspsim.platform;
import java.io.File;
import java.io.IOException;
import se.sics.mspsim.cli.CommandHandler;
import se.sics.mspsim.cli.DebugCommands;
import se.sics.mspsim.core.Chip;
import se.sics.mspsim.core.MSP430;
import se.sics.mspsim.extutil.highlight.HighlightSourceViewer;
import se.sics.mspsim.extutil.jfreechart.DataChart;
import se.sics.mspsim.ui.ControlUI;
import se.sics.mspsim.util.CommandHandler;
import se.sics.mspsim.util.ComponentRegistry;
import se.sics.mspsim.util.DebugCommands;
import se.sics.mspsim.util.ELF;
import se.sics.mspsim.util.IHexReader;
import se.sics.mspsim.util.MapTable;

View File

@ -46,6 +46,8 @@ import java.io.IOException;
import se.sics.mspsim.chip.CC2420;
import se.sics.mspsim.chip.M25P80;
import se.sics.mspsim.chip.PacketListener;
import se.sics.mspsim.cli.CommandHandler;
import se.sics.mspsim.cli.DebugCommands;
import se.sics.mspsim.core.CPUMonitor;
import se.sics.mspsim.core.Chip;
import se.sics.mspsim.core.IOPort;
@ -60,10 +62,8 @@ import se.sics.mspsim.extutil.jfreechart.DataChart;
import se.sics.mspsim.extutil.jfreechart.DataSourceSampler;
import se.sics.mspsim.platform.GenericNode;
import se.sics.mspsim.ui.ControlUI;
import se.sics.mspsim.util.CommandHandler;
import se.sics.mspsim.util.ComponentRegistry;
import se.sics.mspsim.util.DataSource;
import se.sics.mspsim.util.DebugCommands;
import se.sics.mspsim.util.ELF;
import se.sics.mspsim.util.IHexReader;
import se.sics.mspsim.util.MapTable;

View File

@ -186,7 +186,7 @@ public class DebugUI extends JPanel {
s += "; " + i.getFunction();
}
pos = i.getPos();
if (cpu.hasBreakpoint(pos)) {
if (cpu.hasBreakPoint(pos)) {
s = "*B " + s;
} else {
s = " " + s;

View File

@ -1,7 +0,0 @@
package se.sics.mspsim.util;
public interface Command {
public int executeCommand(CommandContext context);
public String getCommandHelp(CommandContext context);
public String getArgumentHelp(CommandContext context);
}

View File

@ -1,74 +0,0 @@
package se.sics.mspsim.util;
import java.io.InputStream;
import java.io.PrintStream;
public class CommandContext {
private String[] args;
private MapTable mapTable;
public final PrintStream out;
public final PrintStream err;
public final InputStream in;
public CommandContext(MapTable table, String[] args,
InputStream in, PrintStream out, PrintStream err) {
this.args = args;
this.out = out;
this.err = err;
this.in = in;
mapTable = table;
}
public int getArgumentCount() {
return args.length - 1;
}
public String getArgument(int index) {
return args[index + 1];
}
public MapTable getMapTable() {
return mapTable;
}
public String getCommand() {
return args[0];
}
public int getArgumentAsAddress(int index) {
String adr = getArgument(index);
if (adr == null || adr.length() == 0) return 0;
adr = adr.trim();
if (adr.charAt(0) == '$') {
try {
return Integer.parseInt(adr.substring(1), 16);
} catch (Exception e) {
err.println("Illegal hex number format: " + adr);
}
} else if (Character.isDigit(adr.charAt(0))) {
try {
return Integer.parseInt(adr);
} catch (Exception e) {
err.println("Illegal number format: " + adr);
}
} else {
// Assume that it is a symbol
if (mapTable != null) {
return mapTable.getFunctionAddress(adr);
}
}
return 0;
}
public int getArgumentAsInt(int i) {
try {
return Integer.parseInt(getArgument(i));
} catch (Exception e) {
err.println("Illegal number format: " + getArgument(i));
}
return 0;
}
}

View File

@ -1,170 +0,0 @@
package se.sics.mspsim.util;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.InterruptedIOException;
import java.io.PrintStream;
import java.util.Hashtable;
import java.util.Map;
public class CommandHandler implements ActiveComponent, Runnable {
private Hashtable<String, Command> commands = new Hashtable<String, Command>();
private boolean exit;
private boolean workaround = false;
private BufferedReader inReader;
private InputStream in;
private PrintStream out;
private PrintStream err;
private MapTable mapTable;
private ComponentRegistry registry;
public CommandHandler() {
exit = false;
inReader = new BufferedReader(new InputStreamReader(in = System.in));
out = System.out;
err = System.err;
registerCommand("help", new Command() {
public int executeCommand(CommandContext context) {
if (context.getArgumentCount() == 0) {
context.out.println("Available commands:");
for(Map.Entry entry: commands.entrySet()) {
String name = (String) entry.getKey();
Command command = (Command) entry.getValue();
CommandContext cc = new CommandContext(mapTable, new String[] {
name
}, context.in, context.out, context.err);
String prefix = ' ' + name + ' ' + command.getArgumentHelp(cc);
String helpText = command.getCommandHelp(cc);
int n;
if (helpText != null && (n = helpText.indexOf('\n')) > 0) {
helpText = helpText.substring(0, n);
}
context.out.print(prefix);
if (prefix.length() < 8) {
context.out.print('\t');
}
if (prefix.length() < 16) {
context.out.print('\t');
}
context.out.println("\t " + helpText);
}
return 0;
}
String cmd = context.getArgument(0);
Command command = commands.get(cmd);
if (command != null) {
CommandContext cc = new CommandContext(mapTable, new String[] {
cmd
}, context.in, context.out, context.err);
context.out.println(cmd + ' ' + command.getArgumentHelp(cc));
context.out.println(" " + command.getCommandHelp(cc));
return 0;
}
context.err.println("Error: unknown command '" + cmd + '\'');
return 1;
}
public String getArgumentHelp(CommandContext context) {
return "<command>";
}
public String getCommandHelp(CommandContext context) {
return "shows help for the specified command";
}
});
registerCommand("workaround", new BasicCommand("", "") {
public int executeCommand(CommandContext context) {
workaround = true;
return 0;
}
});
}
// Add it to the hashtable (overwriting anything there)
public void registerCommand(String cmd, Command command) {
commands.put(cmd, command);
}
private String readLine(BufferedReader inReader2) throws IOException {
if (workaround) {
StringBuilder str = new StringBuilder();
while(true) {
if (inReader2.ready()) {
int c = inReader2.read();
if (c == '\n') {
return str.toString();
}
if (c != '\r') {
str.append((char)c);
}
} else {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
throw new InterruptedIOException();
}
}
}
} else {
return inReader2.readLine();
}
}
public void run() {
while(!exit) {
try {
out.print(">");
out.flush();
String line = readLine(inReader);//.readLine();
if (line != null && line.length() > 0) {
String[][] parts = CommandParser.parseLine(line);
if(parts.length > 0) {
// TODO add support for pipes
String[] args = parts[0];
Command cmd = commands.get(args[0]);
if (cmd == null) {
out.println("Error: Unknown command " + args[0]);
} else {
CommandContext cc = new CommandContext(mapTable, args, in, out, err);
try {
cmd.executeCommand(cc);
} catch (Exception e) {
err.println("Error: Command failed: " + e.getMessage());
e.printStackTrace(err);
}
}
}
}
} catch (IOException e) {
e.printStackTrace();
err.println("Command line tool exiting...");
exit = true;
}
}
}
public void setComponentRegistry(ComponentRegistry registry) {
this.registry = registry;
}
public void setWorkaround(boolean w) {
workaround = w;
}
public void start() {
mapTable = (MapTable) registry.getComponent(MapTable.class);
Object[] commandBundles = registry.getAllComponents(CommandBundle.class);
if (commandBundles != null) {
for (int i = 0, n = commandBundles.length; i < n; i++) {
((CommandBundle) commandBundles[i]).setupCommands(registry, this);
}
}
new Thread(this, "cmd").start();
}
}

View File

@ -1,179 +0,0 @@
/**
* Copyright (c) 2008, Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of MSPSim.
*
* -----------------------------------------------------------------
*
* CommandParser
*
* Author : Joakim Eriksson, Niclas Finne
* Created : Sun Mar 2 19:41:00 2008
* Updated : $Date: 2007/10/21 21:17:34 $
* $Revision: 1.3 $
*/
package se.sics.mspsim.util;
import java.util.ArrayList;
public class CommandParser {
private static final int TEXT = 0;
private static final int ARG = 1;
private static final int QUOTE = 2;
private CommandParser() {
// Prevent instances of this class
}
public static String[][] parseLine(String line) {
ArrayList<String[]> list = new ArrayList<String[]>();
ArrayList<String> args = new ArrayList<String>();
StringBuilder sb = null;
int state = TEXT;
int index = 0;
char quote = 0;
for (int i = 0, n = line.length(); i < n; i++) {
char c = line.charAt(i);
if (c <= 32) {
// White space
if (state == ARG) {
if (sb == null) {
args.add(line.substring(index, i));
} else {
args.add(sb.append(line.substring(index, i)).toString());
sb = null;
}
state = TEXT;
}
} else {
switch (c) {
case '\\':
i++;
if (i >= n) {
throw new IllegalArgumentException("unexpected end of line");
}
if (state == TEXT) {
state = ARG;
} else {
if (sb == null) {
sb = new StringBuilder();
}
sb.append(line.substring(index, i - 1));
}
index = i;
break;
case '"':
case '\'':
if (state == QUOTE) {
if (c == quote) {
// End of quote
if (sb == null) {
args.add(line.substring(index, i));
} else {
args.add(sb.append(line.substring(index, i)).toString());
sb = null;
}
state = TEXT;
}
} else {
// Start new quote
if (state != TEXT) {
if (sb == null) {
args.add(line.substring(index, i));
} else {
args.add(sb.append(line.substring(index, i)).toString());
sb = null;
}
}
index = i + 1;
state = QUOTE;
quote = c;
}
break;
case '|':
if (state != QUOTE) {
// PIPE
if (state == ARG) {
if (sb == null) {
args.add(line.substring(index, i));
} else {
args.add(sb.append(line.substring(index, i)).toString());
sb = null;
}
}
state = TEXT;
if (args.size() == 0) {
throw new IllegalArgumentException("empty command");
}
list.add(args.toArray(new String[args.size()]));
args.clear();
}
break;
default:
if (state == TEXT) {
index = i;
state = ARG;
}
break;
}
}
}
if (state == QUOTE) {
throw new IllegalArgumentException("unexpected end of line");
}
if (state == ARG) {
if (sb == null) {
args.add(line.substring(index));
} else {
args.add(sb.append(line.substring(index)).toString());
}
}
if (args.size() > 0) {
list.add(args.toArray(new String[args.size()]));
}
return list.toArray(new String[list.size()][]);
}
// public static void main(String[] args) {
// StringBuilder sb = new StringBuilder();
// for (int i = 0, n = args.length; i < n; i++) {
// if (i > 0) sb.append(' ');
// sb.append(args[0]);
// }
// String[][] list = parseLine(sb.toString());
// for (int j = 0, m = list.length; j < m; j++) {
// String[] a = list[j];
// System.out.println("PARSED LINE:");
// for (int i = 0, n = a.length; i < n; i++) {
// System.out.println(" ARG " + (i + 1) + ": '" + a[i] + '\'');
// }
// }
// }
}

View File

@ -1,217 +0,0 @@
/**
* Copyright (c) 2008, Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of MSPSim.
*
* $Id$
*
* -----------------------------------------------------------------
*
* CommandBundle
*
* Author : Joakim Eriksson, Niclas Finne
* Created : Mon Feb 11 2008
* Updated : $Date: 2007/10/21 21:17:34 $
* $Revision: 1.3 $
*/
package se.sics.mspsim.util;
import se.sics.mspsim.core.CPUMonitor;
import se.sics.mspsim.core.MSP430;
import se.sics.mspsim.platform.GenericNode;
public class DebugCommands implements CommandBundle {
public void setupCommands(ComponentRegistry registry, CommandHandler ch) {
final MSP430 cpu = (MSP430) registry.getComponent(MSP430.class);
final ELF elf = (ELF) registry.getComponent(ELF.class);
final GenericNode node = (GenericNode) registry.getComponent("node");
if (cpu != null) {
ch.registerCommand("break", new Command() {
public int executeCommand(final CommandContext context) {
int baddr = context.getArgumentAsAddress(0);
cpu.setBreakPoint(baddr,
new CPUMonitor() {
public void cpuAction(int type, int adr, int data) {
context.out.println("*** Break at " + adr);
}
});
context.out.println("Breakpoint set at: " + baddr);
return 0;
}
public String getArgumentHelp(CommandContext context) {
return "<address or symbol>";
}
public String getCommandHelp(CommandContext context) {
return "adds a breakpoint to a given address or symbol";
}
});
ch.registerCommand("watch", new Command() {
int mode = 0;
public int executeCommand(final CommandContext context) {
int baddr = context.getArgumentAsAddress(0);
if (baddr == -1) {
context.out.println("Error: unkown symbol:" + context.getArgument(0));
return -1;
}
if (context.getArgumentCount() > 1) {
String modeStr = context.getArgument(1);
if ("char".equals(modeStr)) {
mode = 1;
}
}
cpu.setBreakPoint(baddr,
new CPUMonitor() {
public void cpuAction(int type, int adr, int data) {
if (mode == 0) {
int pc = cpu.readRegister(0);
String adrStr = getSymOrAddr(context, adr);
String pcStr = getSymOrAddrELF(elf, pc);
context.out.println("*** Write from " + pcStr +
": " + adrStr + " = " + data);
} else {
context.out.print((char) data);
}
}
});
context.out.println("Watch set at: " + baddr);
return 0;
}
public String getArgumentHelp(CommandContext context) {
return "<address or symbol>";
}
public String getCommandHelp(CommandContext context) {
return "adds a write watch to a given address or symbol";
}
});
ch.registerCommand("clear", new Command() {
public int executeCommand(final CommandContext context) {
int baddr = context.getArgumentAsAddress(0);
cpu.setBreakPoint(baddr, null);
return 0;
}
public String getArgumentHelp(CommandContext context) {
return "<address or symbol>";
}
public String getCommandHelp(CommandContext context) {
return "clears a breakpoint or watch from a given address or symbol";
}
});
ch.registerCommand("symbol", new BasicCommand("lists matching symbold", "<regexp>") {
public int executeCommand(final CommandContext context) {
String regExp = context.getArgument(0);
MapEntry[] entries = context.getMapTable().getEntries(regExp);
for (int i = 0; i < entries.length; i++) {
MapEntry mapEntry = entries[i];
context.out.println(" " + mapEntry.getName() + " at " +
Utils.hex16(mapEntry.getAddress()));
}
return 0;
}
});
if (node != null) {
ch.registerCommand("stop", new BasicCommand("stops mspsim", "") {
public int executeCommand(CommandContext context) {
node.stop();
context.out.println("CPU stopped at: " + Utils.hex16(cpu.readRegister(0)));
return 0;
}
});
ch.registerCommand("start", new BasicCommand("starts mspsim", "") {
public int executeCommand(CommandContext context) {
node.start();
return 0;
}
});
ch.registerCommand("step", new BasicCommand("singlesteps mspsim", "<number of lines>") {
public int executeCommand(CommandContext context) {
int nr = context.getArgumentCount() > 0 ? context.getArgumentAsInt(0) : 1;
while(nr-- > 0)
node.step();
context.out.println("CPU stepped to: " + Utils.hex16(cpu.readRegister(0)));
return 0;
}
});
ch.registerCommand("print", new BasicCommand("prints value of an address or symbol", "<address or symbol>") {
public int executeCommand(CommandContext context) {
int adr = context.getArgumentAsAddress(0);
if (adr != -1) {
context.out.println("" + context.getArgument(0) + " = " + Utils.hex16(cpu.read(adr, adr >= 0x100)));
} else {
context.out.println("unkown symbol");
}
return 0;
}
});
ch.registerCommand("printreg", new BasicCommand("prints value of an register", "<register>") {
public int executeCommand(CommandContext context) {
int adr = context.getArgumentAsInt(0);
context.out.println("" + context.getArgument(0) + " = " + Utils.hex16(cpu.readRegister(adr)));
return 0;
}
});
ch.registerCommand("time", new BasicCommand("prints the elapse time and cycles", "") {
public int executeCommand(CommandContext context) {
long time = ((long)(cpu.getTimeMillis()));
context.out.println("Emulated time elapsed:" + time + "(ms) cycles: " + cpu.cycles);
return 0;
}
});
}
}
}
private static String getSymOrAddr(CommandContext context, int adr) {
MapEntry me = context.getMapTable().getEntry(adr);
if (me != null) {
return me.getName();
} else {
return Utils.hex16(adr);
}
}
private static String getSymOrAddrELF(ELF elf, int adr) {
DebugInfo me = elf.getDebugInfo(adr);
if (me != null) {
return me.toString();
} else {
return Utils.hex16(adr);
}
}
}