/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code 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
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* This source code is provided to illustrate the usage of a given feature
* or technique and has been deliberately simplified. Additional steps
* required for a production-quality application, such as security checks,
* input validation and proper error handling, might not be present in
* this sample code.
*/
public class CommandInterpreter {
boolean echo;
this(env, true);
}
}
/*
* The numbering of threads is relative to the current set of threads,
* and may be affected by the creation and termination of new threads.
* Commands issued using such thread ids will only give reliable behavior
* relative to what was shown earlier in 'list' commands if the VM is interrupted.
* We need a better scheme.
*/
}
}
return threads;
}
} else {
}
try {
break;
}
}
//env.failure("No thread for id \"" + idToken + "\"");
}
} catch (NumberFormatException e) {
}
return thread;
}
//### Why not use runtime.allThreads().iterator() ?
}
return new ThreadIterator(getDefaultThreadGroup());
}
}
if (defaultThreadGroup == null) {
}
return defaultThreadGroup;
}
}
/*
* Command handlers.
*/
// Command: classes
//out.println("** classes list **");
}
}
// Command: methods
if (!t.hasMoreTokens()) {
return;
}
while (true) {
break;
}
}
}
}
} else {
//### Should validate class name syntax.
}
}
//### Should handle multiple results sensibly.
}
return null;
}
// Command: threads
if (!t.hasMoreTokens()) {
return;
}
} else {
}
}
//### Issue: Uniqueness of thread group names is not enforced.
return tg;
}
}
return null;
}
int maxId = 0;
int maxName = 0;
}
}
}
}
char buf[] = new char[80];
for (int j = 0; j < 79; j++) {
buf[j] = ' ';
}
// Right-justify the thread number at start of output string
}
}
}
}
}
// Command: threadgroups
int cnt = 0;
++cnt;
}
}
// Command: thread
if (!t.hasMoreTokens()) {
return;
}
//### Should notify user.
}
}
// Command: threadgroup
if (!t.hasMoreTokens()) {
return;
}
} else {
//### Should notify user.
}
}
// Command: run
if (doLoad(false, t)) {
}
}
// Command: load
if (doLoad(true, t)) {}
}
StringTokenizer t) throws NoSessionException {
if (!t.hasMoreTokens()) {
// Run from prevously-set class name.
try {
return true;
} catch (VMLaunchFailureException e) {
}
} else {
}
} else {
// Allow VM arguments to be specified here?
while (t.hasMoreTokens()) {
if (t.hasMoreTokens()) {
}
}
try {
//context.setVmArguments(vmArgs);
return true;
} catch (VMLaunchFailureException e) {
}
}
return false;
}
// Command: connect
try {
} catch (VMLaunchFailureException e) {
}
}
// Command: attach
if (!t.hasMoreTokens()) {
try {
} catch (VMLaunchFailureException e) {
}
} else {
}
} else {
try {
} catch (VMLaunchFailureException e) {
}
}
}
// Command: detach
}
// Command: interrupt
}
// Command: suspend
if (!t.hasMoreTokens()) {
// Suspend all threads in the current thread group.
//### Issue: help message says default is all threads.
//### Behavior here agrees with 'jdb', however.
// TODO - don't suspend debugger threads
}
} else {
while (t.hasMoreTokens()) {
//thread.suspend();
}
}
}
}
// Command: resume
if (!t.hasMoreTokens()) {
// Suspend all threads in the current thread group.
//### Issue: help message says default is all threads.
//### Behavior here agrees with 'jdb', however.
// TODO - don't suspend debugger threads
}
} else {
while (t.hasMoreTokens()) {
//thread.resume();
}
}
}
}
// Command: cont
try {
} catch (VMNotInterruptedException e) {
//### failure?
}
}
// Command: step
return;
}
try {
if (t.hasMoreTokens() &&
} else {
}
} catch (AbsentInformationException e) {
"Try \"stepi\" to step by instructions.");
}
}
// Command: stepi
return;
}
}
// Command: next
return;
}
try {
} catch (AbsentInformationException e) {
"Try \"nexti\" to step by instructions.");
}
}
// Command: nexti (NEW)
return;
}
}
// Command: kill
//### Should change the way in which thread ids and threadgroup names
//### are distinguished.
if (!t.hasMoreTokens()) {
return;
}
while (t.hasMoreTokens()) {
return;
} else {
/* Check for threadgroup name, NOT skipping "system". */
//### Should skip "system"? Classic 'jdb' does this.
//### Should deal with possible non-uniqueness of threadgroup names.
}
return;
}
}
"\" is not a valid threadgroup or id.");
}
}
}
/*************
// TODO
private void commandCatchException(StringTokenizer t) throws NoSessionException {}
// TODO
private void commandIgnoreException(StringTokenizer t) throws NoSessionException {}
*************/
// Command: up
//### Print current frame after command?
int cnt = 1;
if (t.hasMoreTokens()) {
try {
} catch (NumberFormatException e) {
cnt = -1;
}
}
return cnt;
}
return;
}
if (nLevels <= 0) {
return;
}
try {
if (delta == 0) {
}
} catch (VMNotInterruptedException e) {
}
}
return;
}
if (nLevels <= 0) {
return;
}
try {
if (delta == 0) {
}
} catch (VMNotInterruptedException e) {
}
}
// Command: frame
return;
}
if (!t.hasMoreTokens()) {
return;
}
int n;
try {
} catch (NumberFormatException e) {
n = 0;
}
if (n <= 0) {
return;
}
try {
if (delta == 0) {
} else if (delta < 0) {
} else {
}
} catch (VMNotInterruptedException e) {
}
}
// Command: where
//### Should we insist that VM be interrupted here?
//### There is an inconsistency between the 'where' command
//### and 'up' and 'down' in this respect.
throws NoSessionException {
if (!t.hasMoreTokens()) {
return;
}
} else {
}
} else {
//### Do we want to set current thread here?
//### Should notify user of change.
}
}
}
}
//### Check for these.
//env.failure("Thread no longer exists.");
//env.failure("Target VM must be in interrupted state.");
//env.failure("Current thread isn't suspended.");
//### Should handle extremely long stack traces sensibly for user.
try {
} catch (IncompatibleThreadStateException e) {
}
//### Fix this!
//### Previously mishandled cases where thread was not current.
//### Now, prints all of the stack regardless of current frame.
int frameIndex = 0;
//int frameIndex = context.getCurrentFrameIndex();
} else {
for (int i = frameIndex; i < nFrames; i++) {
try {
} catch (AbsentInformationException e) {
}
}
if (showPC) {
if (pc != -1) {
}
}
}
}
}
// Print set breakpoints
} else {
}
}
}
// try {
// We can't use hasMoreTokens here because it will cause any leading
// paren to be lost.
try {
} catch (NoSuchElementException e) {
}
if (t.hasMoreTokens()) {
return null;
}
if (t.hasMoreTokens()) {
return null;
}
} else {
// Try stripping method from class.method token.
return null;
}
//### Should throw exception with error message
//out.println("Invalid method specification: "
// + methodName + rest);
return null;
}
// Trim the parens
//### What about spaces in arglist?
while (t.hasMoreTokens()) {
}
}
}
// } catch (Exception e) {
// env.error("Exception attempting to create breakpoint: " + e);
// return null;
// }
return bpSpec;
}
if (!t.hasMoreTokens()) {
} else {
// Ignore optional "at" or "in" token.
// Allowed for backward compatibility.
if (t.hasMoreTokens()) {
} else {
return;
}
}
//### Add sanity-checks for deferred breakpoint.
} else {
}
}
}
if (!t.hasMoreTokens()) {
// Print set breakpoints
return;
}
//### need 'clear all'
} else {
}
}
// The request used for matching should be found
}
}
}
} else {
}
}
// Command: list
return;
}
try {
return;
}
} catch (VMNotInterruptedException e) {
return;
}
return;
}
return;
}
if (t.hasMoreTokens()) {
// See if token is a line number.
try {
} catch (NumberFormatException nfe) {
// It isn't -- see if it's a method name.
" is not a valid line number or " +
"method name for class " +
return;
" is an ambiguous method name in" +
return;
}
}
}
if (sourceLine == null) {
lineno +
" is an invalid line number for " +
} else {
if (sourceLine == null) {
break;
}
if (i == lineno) {
} else {
}
}
}
}
// Command: use
// Get or set the source file path list.
if (!t.hasMoreTokens()) {
} else {
//### Should throw exception for invalid path.
//### E.g., vetoable property change.
}
}
// Command: sourcepath
// Get or set the source file path list. (Alternate to 'use'.)
if (!t.hasMoreTokens()) {
} else {
//### Should throw exception for invalid path.
//### E.g., vetoable property change.
}
}
// Command: classpath
// Get or set the class file path list.
if (!t.hasMoreTokens()) {
} else {
//### Should throw exception for invalid path.
//### E.g., vetoable property change.
}
}
// Command: view
// Display source for source file or class.
if (!t.hasMoreTokens()) {
} else {
} else {
//### JDI crashes taking line number for class.
/*****
ReferenceType cls = findClass(name);
if (cls != null) {
env.viewLocation(cls.location());
} else {
env.failure("No such class");
}
*****/
}
}
}
// Command: locals
// Print all local variables in current stack frame.
"use the \"thread\" command first.");
return;
}
try {
return;
}
} catch (VMNotInterruptedException e) {
return;
}
try {
return;
}
} catch (AbsentInformationException e) {
" Compile with -g to generate variable information");
return;
}
if (var.isArgument()) {
}
}
if (!var.isArgument()) {
}
}
return;
}
/**
* Command: monitor
* Monitor an expression
*/
if (!t.hasMoreTokens()) {
} else {
}
}
/**
* Command: unmonitor
* Unmonitor an expression
*/
if (!t.hasMoreTokens()) {
} else {
}
}
// Print a stack variable.
} else {
}
}
// Command: print
// Evaluate an expression.
if (!t.hasMoreTokens()) {
//### Probably confused if expresion contains whitespace.
return;
}
"use the \"thread\" command first.");
return;
}
try {
return;
}
} catch (VMNotInterruptedException e) {
return;
}
while (t.hasMoreTokens()) {
try {
} catch(Exception e) {
//### Fix this!
}
return; // Error message already printed
}
!(val instanceof StringReference)) {
} else {
}
}
}
}
}
}
} else if (refType instanceof InterfaceType) {
}
}
}
/*
* Display help message.
*/
private void help() {
// out.println("print <expression> -- print value of expression");
// out.println("eval <expression> -- evaluate expression (same as print)");
// out.println("catch <class id> -- break for the specified exception");
// out.println("ignore <class id> -- ignore when the specified exception\n");
//### new
//### new
// out.println("memory -- report memory usage");
// out.println("gc -- free unused objects\n");
}
/*
* Execute a command.
*/
//### Treatment of 'out' here is dirty...
if (echo) {
}
try {
if (t.hasMoreTokens()) {
lastCommand = cmd;
} else {
cmd = lastCommand;
}
commandPrint(t, false);
commandPrint(t, false);
commandPrint(t, true);
commandMethods(t);
commandThreads(t);
commandThread(t);
commandSuspend(t);
commandResume(t);
commandCont();
commandRun(t);
commandLoad(t);
commandConnect(t);
commandAttach(t);
commandDetach(t);
commandInterrupt(t);
//### Not implemented.
// } else if (cmd.equals("catch")) {
// commandCatchException(t);
//### Not implemented.
// } else if (cmd.equals("ignore")) {
// commandIgnoreException(t);
commandStep(t);
commandStepi();
commandNext();
commandNexti();
commandKill(t);
commandWhere(t, false);
commandWhere(t, true);
commandUp(t);
commandDown(t);
commandFrame(t);
commandStop(t);
commandClear(t);
commandList(t);
commandUse(t);
commandClasspath(t);
commandMonitor(t);
commandUnmonitor(t);
commandView(t);
// } else if (cmd.equals("read")) {
// readCommand(t);
help();
try {
} catch (NoSessionException e) {
// ignore
}
} else {
//### Dubious repeat-count feature inherited from 'jdb'
if (t.hasMoreTokens()) {
try {
while (repeat-- > 0) {
}
return;
} catch (NumberFormatException exc) {
}
}
}
} catch (NoSessionException e) {
} catch (Exception e) {
e.printStackTrace();
}
}
}