mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-23 22:52:11 +02:00
more work on the parser.
This commit is contained in:
parent
e779696228
commit
945fd6b033
22 changed files with 329 additions and 79 deletions
|
@ -15,16 +15,16 @@ public class MIPlugin extends Plugin {
|
||||||
private static MIPlugin plugin;
|
private static MIPlugin plugin;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The constructor.
|
* The constructor.
|
||||||
*/
|
*/
|
||||||
public MIPlugin(IPluginDescriptor descriptor) {
|
public MIPlugin(IPluginDescriptor descriptor) {
|
||||||
super(descriptor);
|
super(descriptor);
|
||||||
plugin = this;
|
plugin = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the shared instance.
|
* Returns the singleton.
|
||||||
*/
|
*/
|
||||||
public static MIPlugin getDefault() {
|
public static MIPlugin getDefault() {
|
||||||
return plugin;
|
return plugin;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package org.eclipse.cdt.debug.mi.core;
|
package org.eclipse.cdt.debug.mi.core;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.util.Observable;
|
import java.util.Observable;
|
||||||
|
@ -9,8 +10,11 @@ import org.eclipse.cdt.debug.mi.core.command.CommandFactory;
|
||||||
import org.eclipse.cdt.debug.mi.core.output.MIOutput;
|
import org.eclipse.cdt.debug.mi.core.output.MIOutput;
|
||||||
import org.eclipse.cdt.debug.mi.core.output.MIParser;
|
import org.eclipse.cdt.debug.mi.core.output.MIParser;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Represents a GDB/MI session.
|
||||||
|
* Note that on GNU/Linux the target stream is not
|
||||||
|
* preceded by the token '@' until this is fix, on GNU/Linux
|
||||||
|
* there a good change to confuse the parser.
|
||||||
*/
|
*/
|
||||||
public class MISession extends Observable {
|
public class MISession extends Observable {
|
||||||
|
|
||||||
|
@ -31,18 +35,22 @@ public class MISession extends Observable {
|
||||||
|
|
||||||
MIParser parser;
|
MIParser parser;
|
||||||
|
|
||||||
long cmdTimeout = 0000; // 20 * 1000 (~ 20 secs);
|
long cmdTimeout = 0000; // 20 * 1000 (~ 20 secs);
|
||||||
|
|
||||||
final int STOPPED = 0;
|
final int STOPPED = 0;
|
||||||
final int RUNNING = 1;
|
final int RUNNING = 1;
|
||||||
|
final int SUSPENDED = 1;
|
||||||
int state = STOPPED;
|
int state = STOPPED;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The constructor.
|
* Create the gdb session.
|
||||||
|
*
|
||||||
|
* @param i the gdb input channel.
|
||||||
|
* @param o gdb output channel.
|
||||||
*/
|
*/
|
||||||
public MISession(InputStream i, OutputStream o) {
|
public MISession(InputStream i, OutputStream o) {
|
||||||
inChannel = i;
|
inChannel = i;
|
||||||
outChannel= o;
|
outChannel = o;
|
||||||
factory = new CommandFactory();
|
factory = new CommandFactory();
|
||||||
parser = new MIParser();
|
parser = new MIParser();
|
||||||
txQueue = new Queue();
|
txQueue = new Queue();
|
||||||
|
@ -60,48 +68,84 @@ public class MISession extends Observable {
|
||||||
consoleStream = console;
|
consoleStream = console;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get Console Stream.
|
||||||
|
*/
|
||||||
|
OutputStream getConsoleStream() {
|
||||||
|
return consoleStream;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set Target Stream.
|
* Set Target Stream.
|
||||||
*/
|
*/
|
||||||
public void setTargetStreamOutput(OutputStream target) {
|
public void setTargetStream(OutputStream target) {
|
||||||
targetStream = target;
|
targetStream = target;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Target Stream.
|
||||||
|
*/
|
||||||
|
OutputStream getTargetStream() {
|
||||||
|
return targetStream;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set Log Stream
|
* Set Log Stream
|
||||||
*/
|
*/
|
||||||
public void setLogStreamOutput(OutputStream log) {
|
public void setLogStream(OutputStream log) {
|
||||||
logStream = log;
|
logStream = log;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* Get Log Stream
|
||||||
|
*/
|
||||||
|
OutputStream getLogStream() {
|
||||||
|
return logStream;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* For example the CDI/MI adapters uses the command
|
||||||
|
* factory to create MI commands this allow overloading.
|
||||||
*/
|
*/
|
||||||
public CommandFactory getCommandFactory() {
|
public CommandFactory getCommandFactory() {
|
||||||
return factory;
|
return factory;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* Set a new factory to use in CDI/MI adapters.
|
||||||
*/
|
*/
|
||||||
public void setCommandFactory(CommandFactory f) {
|
public void setCommandFactory(CommandFactory f) {
|
||||||
factory = f;
|
factory = f;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* Return the MI main parser.
|
||||||
*/
|
*/
|
||||||
public MIParser getMIParser() {
|
public MIParser getMIParser() {
|
||||||
return parser;
|
return parser;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* Reset the parser.
|
||||||
*/
|
*/
|
||||||
public void setMIParser(MIParser p) {
|
public void setMIParser(MIParser p) {
|
||||||
parser = p;
|
parser = p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reset the default Command Timeout.
|
||||||
|
*/
|
||||||
|
public void setCommandTimeout(long timeout) {
|
||||||
|
cmdTimeout = timeout;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the default Command Timeout, default 20 secs.
|
||||||
|
*/
|
||||||
|
public long getCommandTimeout() {
|
||||||
|
return cmdTimeout;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* postCommand(cmd, 20 secs)
|
* postCommand(cmd, 20 secs)
|
||||||
*/
|
*/
|
||||||
|
@ -109,21 +153,13 @@ public class MISession extends Observable {
|
||||||
postCommand(cmd, cmdTimeout);
|
postCommand(cmd, cmdTimeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setCommandTimeout(long timeout) {
|
|
||||||
cmdTimeout = timeout;
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getCommandTimeout() {
|
|
||||||
return cmdTimeout;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* Sends a command to gdb.
|
||||||
*/
|
*/
|
||||||
public void postCommand(Command cmd, long timeout) throws MIException {
|
public void postCommand(Command cmd, long timeout) throws MIException {
|
||||||
|
|
||||||
if (!txThread.isAlive()) {
|
if (!txThread.isAlive() || !rxThread.isAlive()) {
|
||||||
throw new MIException("TxThread terminated");
|
throw new MIException("{R,T}xThread terminated");
|
||||||
}
|
}
|
||||||
txQueue.addCommand(cmd);
|
txQueue.addCommand(cmd);
|
||||||
synchronized (cmd) {
|
synchronized (cmd) {
|
||||||
|
@ -139,24 +175,94 @@ public class MISession extends Observable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Close the MISession.
|
||||||
|
*/
|
||||||
|
public void terminate() {
|
||||||
|
|
||||||
|
// Closing the channel will kill the RxThread.
|
||||||
|
try {
|
||||||
|
inChannel.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
}
|
||||||
|
inChannel = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
outChannel.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
}
|
||||||
|
outChannel = null; // This is needed to stop the txThread.
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (txThread.isAlive()) {
|
||||||
|
txThread.interrupt();
|
||||||
|
}
|
||||||
|
txThread.join();
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (rxThread.isAlive()) {
|
||||||
|
rxThread.interrupt();
|
||||||
|
}
|
||||||
|
rxThread.join();
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The session is in STOPPED state.
|
||||||
|
* It means the 'run/-exec-run' command was not issued.
|
||||||
|
* Or the program exited, via a signal or normally.
|
||||||
|
* It is not the same as gdb/MI *stopped async-class
|
||||||
|
* gdb/MI stopped means suspended here.
|
||||||
|
*/
|
||||||
public boolean isStopped() {
|
public boolean isStopped() {
|
||||||
return state == STOPPED;
|
return state == STOPPED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The session is in SUSPENDED state.
|
||||||
|
* State after hitting a breakpoint or after attach.
|
||||||
|
*/
|
||||||
|
public boolean isSuspended() {
|
||||||
|
return state == SUSPENDED;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The session is in RUNNING state.
|
||||||
|
*/
|
||||||
public boolean isRunning() {
|
public boolean isRunning() {
|
||||||
return state == RUNNING;
|
return state == RUNNING;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setStopped() {
|
/**
|
||||||
|
* Set the state STOPPED.
|
||||||
|
*/
|
||||||
|
public void setStopped() {
|
||||||
state = STOPPED;
|
state = STOPPED;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setRunning() {
|
/**
|
||||||
|
* Set the state SUSPENDED.
|
||||||
|
*/
|
||||||
|
public void setSuspended() {
|
||||||
|
state = SUSPENDED;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the state STOPPED.
|
||||||
|
*/
|
||||||
|
public void setRunning() {
|
||||||
state = RUNNING;
|
state = RUNNING;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setDirty() {
|
/**
|
||||||
|
* Notify the observers of new MI OOB events.
|
||||||
|
*/
|
||||||
|
public void notifyObservers(Object arg) {
|
||||||
setChanged();
|
setChanged();
|
||||||
|
super.notifyObservers(arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
Queue getTxQueue() {
|
Queue getTxQueue() {
|
||||||
|
|
|
@ -3,6 +3,7 @@ package org.eclipse.cdt.debug.mi.core;
|
||||||
import java.io.BufferedReader;
|
import java.io.BufferedReader;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
|
import java.io.OutputStream;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
@ -15,12 +16,19 @@ import org.eclipse.cdt.debug.mi.core.event.MIFunctionFinishedEvent;
|
||||||
import org.eclipse.cdt.debug.mi.core.event.MISignalEvent;
|
import org.eclipse.cdt.debug.mi.core.event.MISignalEvent;
|
||||||
import org.eclipse.cdt.debug.mi.core.event.MIStepEvent;
|
import org.eclipse.cdt.debug.mi.core.event.MIStepEvent;
|
||||||
import org.eclipse.cdt.debug.mi.core.event.MIWatchpointEvent;
|
import org.eclipse.cdt.debug.mi.core.event.MIWatchpointEvent;
|
||||||
|
import org.eclipse.cdt.debug.mi.core.output.MIAsyncRecord;
|
||||||
|
import org.eclipse.cdt.debug.mi.core.output.MIConsoleStreamOutput;
|
||||||
import org.eclipse.cdt.debug.mi.core.output.MIConst;
|
import org.eclipse.cdt.debug.mi.core.output.MIConst;
|
||||||
import org.eclipse.cdt.debug.mi.core.output.MIExecAsyncOutput;
|
import org.eclipse.cdt.debug.mi.core.output.MIExecAsyncOutput;
|
||||||
|
import org.eclipse.cdt.debug.mi.core.output.MILogStreamOutput;
|
||||||
|
import org.eclipse.cdt.debug.mi.core.output.MINotifyAsyncOutput;
|
||||||
import org.eclipse.cdt.debug.mi.core.output.MIOOBRecord;
|
import org.eclipse.cdt.debug.mi.core.output.MIOOBRecord;
|
||||||
import org.eclipse.cdt.debug.mi.core.output.MIOutput;
|
import org.eclipse.cdt.debug.mi.core.output.MIOutput;
|
||||||
import org.eclipse.cdt.debug.mi.core.output.MIResult;
|
import org.eclipse.cdt.debug.mi.core.output.MIResult;
|
||||||
import org.eclipse.cdt.debug.mi.core.output.MIResultRecord;
|
import org.eclipse.cdt.debug.mi.core.output.MIResultRecord;
|
||||||
|
import org.eclipse.cdt.debug.mi.core.output.MIStatusAsyncOutput;
|
||||||
|
import org.eclipse.cdt.debug.mi.core.output.MIStreamRecord;
|
||||||
|
import org.eclipse.cdt.debug.mi.core.output.MITargetStreamOutput;
|
||||||
import org.eclipse.cdt.debug.mi.core.output.MIValue;
|
import org.eclipse.cdt.debug.mi.core.output.MIValue;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -29,7 +37,6 @@ import org.eclipse.cdt.debug.mi.core.output.MIValue;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public class RxThread extends Thread {
|
public class RxThread extends Thread {
|
||||||
|
|
||||||
final MISession session;
|
final MISession session;
|
||||||
|
@ -37,7 +44,6 @@ public class RxThread extends Thread {
|
||||||
public RxThread(MISession s) {
|
public RxThread(MISession s) {
|
||||||
super("MI RX Thread");
|
super("MI RX Thread");
|
||||||
session = s;
|
session = s;
|
||||||
setDaemon(true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -52,7 +58,14 @@ public class RxThread extends Thread {
|
||||||
while (true) {
|
while (true) {
|
||||||
String line;
|
String line;
|
||||||
while ((line = reader.readLine()) != null) {
|
while ((line = reader.readLine()) != null) {
|
||||||
if (line.startsWith("(gdb)")) {
|
// Testing on GNU/Linux where target stream output
|
||||||
|
// is entertwine with MI out,
|
||||||
|
// comment out the if/else below and just use:
|
||||||
|
// processMIOutput(line);
|
||||||
|
// at least for testing.
|
||||||
|
|
||||||
|
// We accumulate until we see the gdb terminator.
|
||||||
|
if (line.startsWith(MIOutput.terminator)) {
|
||||||
// discard termination
|
// discard termination
|
||||||
processMIOutput(buffer.toString());
|
processMIOutput(buffer.toString());
|
||||||
buffer = new StringBuffer();
|
buffer = new StringBuffer();
|
||||||
|
@ -62,7 +75,7 @@ public class RxThread extends Thread {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
//e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -85,7 +98,7 @@ public class RxThread extends Thread {
|
||||||
String state = rr.getResultClass();
|
String state = rr.getResultClass();
|
||||||
if ("running".equals(state)) {
|
if ("running".equals(state)) {
|
||||||
session.setRunning();
|
session.setRunning();
|
||||||
} else {
|
} else if ("exit".equals(state)) {
|
||||||
session.setStopped();
|
session.setStopped();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -121,27 +134,81 @@ public class RxThread extends Thread {
|
||||||
* Dispatch a thread to deal with the listeners.
|
* Dispatch a thread to deal with the listeners.
|
||||||
*/
|
*/
|
||||||
void processMIOOBRecord(MIOOBRecord oob, List list) {
|
void processMIOOBRecord(MIOOBRecord oob, List list) {
|
||||||
if (oob instanceof MIExecAsyncOutput) {
|
if (oob instanceof MIAsyncRecord) {
|
||||||
MIExecAsyncOutput exec = (MIExecAsyncOutput)oob;
|
processMIOOBRecord((MIAsyncRecord)oob, list);
|
||||||
|
} else if (oob instanceof MIStreamRecord) {
|
||||||
|
processMIOOBRecord((MIStreamRecord)oob);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void processMIOOBRecord(MIAsyncRecord async, List list) {
|
||||||
|
if (async instanceof MIExecAsyncOutput) {
|
||||||
|
MIExecAsyncOutput exec = (MIExecAsyncOutput)async;
|
||||||
|
|
||||||
// Change of state.
|
// Change of state.
|
||||||
String state = exec.getAsyncClass();
|
String state = exec.getAsyncClass();
|
||||||
if ("stopped".equals(state)) {
|
if ("stopped".equals(state)) {
|
||||||
session.setStopped();
|
session.setSuspended();
|
||||||
}
|
}
|
||||||
|
|
||||||
MIResult[] results = exec.getMIResults();
|
MIResult[] results = exec.getMIResults();
|
||||||
for (int i = 0; i < results.length; i++) {
|
for (int i = 0; i < results.length; i++) {
|
||||||
String var = results[i].getVariable();
|
String var = results[i].getVariable();
|
||||||
MIValue value = results[i].getMIValue();
|
MIValue val = results[i].getMIValue();
|
||||||
if (var.equals("reason")) {
|
if (var.equals("reason")) {
|
||||||
if (value instanceof MIConst) {
|
if (val instanceof MIConst) {
|
||||||
String reason = ((MIConst)value).getString();
|
String reason = ((MIConst)val).getString();
|
||||||
MIEvent e = createEvent(reason, exec);
|
MIEvent e = createEvent(reason, exec);
|
||||||
if (e != null) {
|
if (e != null) {
|
||||||
list.add(e);
|
list.add(e);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (async instanceof MIStatusAsyncOutput) {
|
||||||
|
// Nothing done .. but what about +download??
|
||||||
|
} else if (async instanceof MINotifyAsyncOutput) {
|
||||||
|
// Nothing
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void processMIOOBRecord(MIStreamRecord stream) {
|
||||||
|
if (stream instanceof MIConsoleStreamOutput) {
|
||||||
|
OutputStream console = session.getConsoleStream();
|
||||||
|
if (console != null) {
|
||||||
|
MIConsoleStreamOutput out = (MIConsoleStreamOutput)stream;
|
||||||
|
String str = out.getString();
|
||||||
|
if (str != null) {
|
||||||
|
try {
|
||||||
|
console.write(str.getBytes());
|
||||||
|
console.flush();
|
||||||
|
} catch (IOException e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (stream instanceof MITargetStreamOutput) {
|
||||||
|
OutputStream target = session.getTargetStream();
|
||||||
|
if (target != null) {
|
||||||
|
MITargetStreamOutput out = (MITargetStreamOutput)stream;
|
||||||
|
String str = out.getString();
|
||||||
|
if (str != null) {
|
||||||
|
try {
|
||||||
|
target.write(str.getBytes());
|
||||||
|
target.flush();
|
||||||
|
} catch (IOException e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (stream instanceof MILogStreamOutput) {
|
||||||
|
OutputStream log = session.getLogStream();
|
||||||
|
if (log != null) {
|
||||||
|
MILogStreamOutput out = (MILogStreamOutput)stream;
|
||||||
|
String str = out.getString();
|
||||||
|
if (str != null) {
|
||||||
|
try {
|
||||||
|
log.write(str.getBytes());
|
||||||
|
log.flush();
|
||||||
|
} catch (IOException e) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -184,38 +251,45 @@ public class RxThread extends Thread {
|
||||||
} else if (rr != null) {
|
} else if (rr != null) {
|
||||||
event = new MIBreakpointEvent(rr);
|
event = new MIBreakpointEvent(rr);
|
||||||
}
|
}
|
||||||
|
session.setSuspended();
|
||||||
} else if ("watchpoint-trigger".equals(reason)) {
|
} else if ("watchpoint-trigger".equals(reason)) {
|
||||||
if (exec != null) {
|
if (exec != null) {
|
||||||
event = new MIWatchpointEvent(exec);
|
event = new MIWatchpointEvent(exec);
|
||||||
} else if (rr != null) {
|
} else if (rr != null) {
|
||||||
event = new MIWatchpointEvent(rr);
|
event = new MIWatchpointEvent(rr);
|
||||||
}
|
}
|
||||||
|
session.setSuspended();
|
||||||
} else if ("end-stepping-range".equals(reason)) {
|
} else if ("end-stepping-range".equals(reason)) {
|
||||||
if (exec != null) {
|
if (exec != null) {
|
||||||
event = new MIStepEvent(exec);
|
event = new MIStepEvent(exec);
|
||||||
} else if (rr != null) {
|
} else if (rr != null) {
|
||||||
event = new MIStepEvent(rr);
|
event = new MIStepEvent(rr);
|
||||||
}
|
}
|
||||||
|
session.setSuspended();
|
||||||
} else if ("signal-received".equals(reason)) {
|
} else if ("signal-received".equals(reason)) {
|
||||||
if (exec != null) {
|
if (exec != null) {
|
||||||
event = new MISignalEvent(exec);
|
event = new MISignalEvent(exec);
|
||||||
} else if (rr != null) {
|
} else if (rr != null) {
|
||||||
event = new MISignalEvent(rr);
|
event = new MISignalEvent(rr);
|
||||||
}
|
}
|
||||||
|
session.setStopped();
|
||||||
} else if ("location-reached".equals(reason)) {
|
} else if ("location-reached".equals(reason)) {
|
||||||
if (exec != null) {
|
if (exec != null) {
|
||||||
event = new MISignalEvent(exec);
|
event = new MISignalEvent(exec);
|
||||||
} else if (rr != null) {
|
} else if (rr != null) {
|
||||||
event = new MISignalEvent(rr);
|
event = new MISignalEvent(rr);
|
||||||
}
|
}
|
||||||
|
session.setSuspended();
|
||||||
} else if ("function-finished".equals(reason)) {
|
} else if ("function-finished".equals(reason)) {
|
||||||
if (exec != null) {
|
if (exec != null) {
|
||||||
event = new MIFunctionFinishedEvent(exec);
|
event = new MIFunctionFinishedEvent(exec);
|
||||||
} else if (rr != null) {
|
} else if (rr != null) {
|
||||||
event = new MIFunctionFinishedEvent(rr);
|
event = new MIFunctionFinishedEvent(rr);
|
||||||
}
|
}
|
||||||
|
session.setSuspended();
|
||||||
} else if ("exited-normally".equals(reason)) {
|
} else if ("exited-normally".equals(reason)) {
|
||||||
event = new MIExitEvent();
|
event = new MIExitEvent();
|
||||||
|
session.setStopped();
|
||||||
}
|
}
|
||||||
return event;
|
return event;
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,6 @@ public class TxThread extends Thread {
|
||||||
super("MI TX Thread");
|
super("MI TX Thread");
|
||||||
session = s;
|
session = s;
|
||||||
token = 1;
|
token = 1;
|
||||||
setDaemon(true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void run () {
|
public void run () {
|
||||||
|
@ -30,7 +29,11 @@ public class TxThread extends Thread {
|
||||||
// removeCommand() will block until a command is available.
|
// removeCommand() will block until a command is available.
|
||||||
try {
|
try {
|
||||||
cmd = txQueue.removeCommand();
|
cmd = txQueue.removeCommand();
|
||||||
} catch (Exception e) {
|
} catch (InterruptedException e) {
|
||||||
|
// signal by the session of time to die.
|
||||||
|
if (session.getChannelOutputStream() == null) {
|
||||||
|
throw new IOException();
|
||||||
|
}
|
||||||
//e.printStackTrace();
|
//e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,6 @@ public class EventThread extends Thread {
|
||||||
/*
|
/*
|
||||||
*/
|
*/
|
||||||
public void run () {
|
public void run () {
|
||||||
session.setDirty();
|
|
||||||
session.notifyObservers(events);
|
session.notifyObservers(events);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,7 +44,7 @@ public class MIArg {
|
||||||
for (int i = 0; i < results.length; i++) {
|
for (int i = 0; i < results.length; i++) {
|
||||||
MIValue value = results[i].getMIValue();
|
MIValue value = results[i].getMIValue();
|
||||||
if (value instanceof MIConst) {
|
if (value instanceof MIConst) {
|
||||||
String str = ((MIConst)value).getString();
|
String str = ((MIConst)value).getCString();
|
||||||
aList.add(new MIArg(str, ""));
|
aList.add(new MIArg(str, ""));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -63,7 +63,7 @@ public class MIArg {
|
||||||
String aName = "";
|
String aName = "";
|
||||||
MIValue value = args[0].getMIValue();
|
MIValue value = args[0].getMIValue();
|
||||||
if (value != null && value instanceof MIConst) {
|
if (value != null && value instanceof MIConst) {
|
||||||
aName = ((MIConst)value).getString();
|
aName = ((MIConst)value).getCString();
|
||||||
} else {
|
} else {
|
||||||
aName = "";
|
aName = "";
|
||||||
}
|
}
|
||||||
|
@ -72,7 +72,7 @@ public class MIArg {
|
||||||
String aValue = "";
|
String aValue = "";
|
||||||
value = args[1].getMIValue();
|
value = args[1].getMIValue();
|
||||||
if (value != null && value instanceof MIConst) {
|
if (value != null && value instanceof MIConst) {
|
||||||
aValue = ((MIConst)value).getString();
|
aValue = ((MIConst)value).getCString();
|
||||||
} else {
|
} else {
|
||||||
aValue = "";
|
aValue = "";
|
||||||
}
|
}
|
||||||
|
|
|
@ -72,7 +72,7 @@ public class MIAsm {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (value != null && value instanceof MIConst) {
|
if (value != null && value instanceof MIConst) {
|
||||||
str = ((MIConst)value).getString();
|
str = ((MIConst)value).getCString();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (var.equals("address")) {
|
if (var.equals("address")) {
|
||||||
|
|
|
@ -66,7 +66,7 @@ public class MIBreakPoint {
|
||||||
MIValue value = results[i].getMIValue();
|
MIValue value = results[i].getMIValue();
|
||||||
String str = "";
|
String str = "";
|
||||||
if (value != null && value instanceof MIConst) {
|
if (value != null && value instanceof MIConst) {
|
||||||
str = ((MIConst)value).getString();
|
str = ((MIConst)value).getCString();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (var.equals("number")) {
|
if (var.equals("number")) {
|
||||||
|
|
|
@ -17,10 +17,70 @@ public class MIConst extends MIValue {
|
||||||
* Translate gdb c-string.
|
* Translate gdb c-string.
|
||||||
*/
|
*/
|
||||||
public String getString() {
|
public String getString() {
|
||||||
return cstring;
|
return getString(cstring);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getString(String str) {
|
||||||
|
StringBuffer buffer = new StringBuffer();
|
||||||
|
boolean escape = false;
|
||||||
|
for (int i = 0; i < str.length(); i++) {
|
||||||
|
char c = str.charAt(i);
|
||||||
|
if (c == '\\') {
|
||||||
|
if (escape) {
|
||||||
|
buffer.append(c);
|
||||||
|
escape = false;
|
||||||
|
} else {
|
||||||
|
escape = true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (escape) {
|
||||||
|
buffer.append(isoC(c));
|
||||||
|
} else {
|
||||||
|
buffer.append(c);
|
||||||
|
}
|
||||||
|
escape = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If escape is still true it means that the
|
||||||
|
// last char was an '\'.
|
||||||
|
if (escape) {
|
||||||
|
buffer.append('\\');
|
||||||
|
}
|
||||||
|
|
||||||
|
return buffer.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return getString();
|
return getCString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Assuming that the precedent character was the
|
||||||
|
* escape sequence '\'
|
||||||
|
*/
|
||||||
|
private static char isoC(char c) {
|
||||||
|
if (c == '"') {
|
||||||
|
c = '"';
|
||||||
|
} else if (c == '\'') {
|
||||||
|
c = '\'';
|
||||||
|
} else if (c == '?') {
|
||||||
|
c = '?';
|
||||||
|
} else if (c == 'a') {
|
||||||
|
c = 7;
|
||||||
|
} else if (c == 'b') {
|
||||||
|
c = '\b';
|
||||||
|
} else if (c == 'f') {
|
||||||
|
c = '\f';
|
||||||
|
} else if (c == 'n') {
|
||||||
|
c = '\n';
|
||||||
|
} else if (c == 'r') {
|
||||||
|
c = '\r';
|
||||||
|
} else if (c == 't') {
|
||||||
|
c = '\t';
|
||||||
|
} else if (c == 'v') {
|
||||||
|
c = 11;
|
||||||
|
}
|
||||||
|
return c;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,7 +31,7 @@ public class MIDataEvaluateExpressionInfo extends MIInfo{
|
||||||
if (var.equals("value")) {
|
if (var.equals("value")) {
|
||||||
MIValue value = results[i].getMIValue();
|
MIValue value = results[i].getMIValue();
|
||||||
if (value instanceof MIConst) {
|
if (value instanceof MIConst) {
|
||||||
expr = ((MIConst)value).getString();
|
expr = ((MIConst)value).getCString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,7 +52,7 @@ public class MIDataListChangedRegistersInfo extends MIInfo {
|
||||||
MIValue[] values = list.getMIValues();
|
MIValue[] values = list.getMIValues();
|
||||||
for (int i = 0; i < values.length; i++) {
|
for (int i = 0; i < values.length; i++) {
|
||||||
if (values[i] instanceof MIConst) {
|
if (values[i] instanceof MIConst) {
|
||||||
String str = ((MIConst)values[i]).getString();
|
String str = ((MIConst)values[i]).getCString();
|
||||||
if (str != null && str.length() > 0) {
|
if (str != null && str.length() > 0) {
|
||||||
aList.add(str);
|
aList.add(str);
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,7 +45,7 @@ public class MIDataListRegisterNamesInfo extends MIInfo {
|
||||||
MIValue[] values = list.getMIValues();
|
MIValue[] values = list.getMIValues();
|
||||||
for (int i = 0; i < values.length; i++) {
|
for (int i = 0; i < values.length; i++) {
|
||||||
if (values[i] instanceof MIConst) {
|
if (values[i] instanceof MIConst) {
|
||||||
String str = ((MIConst)values[i]).getString();
|
String str = ((MIConst)values[i]).getCString();
|
||||||
if (str != null && str.length() > 0) {
|
if (str != null && str.length() > 0) {
|
||||||
aList.add(str);
|
aList.add(str);
|
||||||
}
|
}
|
||||||
|
|
|
@ -105,7 +105,7 @@ public class MIDataReadMemoryInfo extends MIInfo {
|
||||||
MIValue value = results[i].getMIValue();
|
MIValue value = results[i].getMIValue();
|
||||||
String str = "";
|
String str = "";
|
||||||
if (value != null && value instanceof MIConst) {
|
if (value != null && value instanceof MIConst) {
|
||||||
str = ((MIConst)value).getString();
|
str = ((MIConst)value).getCString();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (var.equals("addr")) {
|
if (var.equals("addr")) {
|
||||||
|
|
|
@ -53,7 +53,7 @@ public class MIFrame {
|
||||||
MIValue value = results[i].getMIValue();
|
MIValue value = results[i].getMIValue();
|
||||||
String str = "";
|
String str = "";
|
||||||
if (value != null && value instanceof MIConst) {
|
if (value != null && value instanceof MIConst) {
|
||||||
str = ((MIConst)value).getString();
|
str = ((MIConst)value).getCString();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (var.equals("level")) {
|
if (var.equals("level")) {
|
||||||
|
|
|
@ -64,7 +64,7 @@ public class MIInfo {
|
||||||
if (var.equals("msg")) {
|
if (var.equals("msg")) {
|
||||||
MIValue value = results[i].getMIValue();
|
MIValue value = results[i].getMIValue();
|
||||||
if (value instanceof MIConst) {
|
if (value instanceof MIConst) {
|
||||||
String s = ((MIConst)value).getString();
|
String s = ((MIConst)value).getCString();
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,7 +47,7 @@ public class MIMemory {
|
||||||
MIValue value = results[i].getMIValue();
|
MIValue value = results[i].getMIValue();
|
||||||
String str = "";
|
String str = "";
|
||||||
if (value != null && value instanceof MIConst) {
|
if (value != null && value instanceof MIConst) {
|
||||||
str = ((MIConst)value).getString();
|
str = ((MIConst)value).getCString();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (var.equals("addr")) {
|
if (var.equals("addr")) {
|
||||||
|
@ -70,7 +70,7 @@ public class MIMemory {
|
||||||
data = new long[values.length];
|
data = new long[values.length];
|
||||||
for (int i = 0; i < values.length; i++) {
|
for (int i = 0; i < values.length; i++) {
|
||||||
if (values[i] instanceof MIConst) {
|
if (values[i] instanceof MIConst) {
|
||||||
String str = ((MIConst)values[i]).getString();
|
String str = ((MIConst)values[i]).getCString();
|
||||||
try {
|
try {
|
||||||
data[i] = Long.decode(str.trim()).longValue();
|
data[i] = Long.decode(str.trim()).longValue();
|
||||||
} catch (NumberFormatException e) {
|
} catch (NumberFormatException e) {
|
||||||
|
|
|
@ -117,8 +117,8 @@ public class MIParser {
|
||||||
if (token.charAt(0) == '^') {
|
if (token.charAt(0) == '^') {
|
||||||
token.deleteCharAt(0);
|
token.deleteCharAt(0);
|
||||||
rr = processMIResultRecord(token, id);
|
rr = processMIResultRecord(token, id);
|
||||||
//} else if(token.startsWith(MIOutput.terminator)) {
|
} else if(token.toString().startsWith(MIOutput.terminator)) {
|
||||||
// break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
MIOOBRecord band = processMIOOBRecord(token, id);
|
MIOOBRecord band = processMIOOBRecord(token, id);
|
||||||
if (band != null) {
|
if (band != null) {
|
||||||
|
@ -137,7 +137,7 @@ public class MIParser {
|
||||||
/**
|
/**
|
||||||
* Assuming '^' was deleted.
|
* Assuming '^' was deleted.
|
||||||
*/
|
*/
|
||||||
MIResultRecord processMIResultRecord(StringBuffer buffer, int id) {
|
private MIResultRecord processMIResultRecord(StringBuffer buffer, int id) {
|
||||||
MIResultRecord rr = new MIResultRecord();
|
MIResultRecord rr = new MIResultRecord();
|
||||||
rr.setToken(id);
|
rr.setToken(id);
|
||||||
if (buffer.toString().startsWith(MIResultRecord.DONE)) {
|
if (buffer.toString().startsWith(MIResultRecord.DONE)) {
|
||||||
|
@ -171,7 +171,7 @@ public class MIParser {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*/
|
*/
|
||||||
MIOOBRecord processMIOOBRecord(StringBuffer buffer, int id) {
|
private MIOOBRecord processMIOOBRecord(StringBuffer buffer, int id) {
|
||||||
MIOOBRecord oob = null;
|
MIOOBRecord oob = null;
|
||||||
char c = buffer.charAt(0);
|
char c = buffer.charAt(0);
|
||||||
if (c == '*' || c == '+' || c == '=') {
|
if (c == '*' || c == '+' || c == '=') {
|
||||||
|
@ -220,6 +220,10 @@ public class MIParser {
|
||||||
stream = new MILogStreamOutput();
|
stream = new MILogStreamOutput();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
// translateCString() assumes that the leading " is deleted
|
||||||
|
if (buffer.length() > 0 && buffer.charAt(0) == '"') {
|
||||||
|
buffer.deleteCharAt(0);
|
||||||
|
}
|
||||||
stream.setCString(translateCString(buffer));
|
stream.setCString(translateCString(buffer));
|
||||||
oob = stream;
|
oob = stream;
|
||||||
}
|
}
|
||||||
|
@ -229,7 +233,7 @@ public class MIParser {
|
||||||
/**
|
/**
|
||||||
* Assuming that the usual leading comma was consume.
|
* Assuming that the usual leading comma was consume.
|
||||||
*/
|
*/
|
||||||
MIResult[] processMIResults(StringBuffer buffer) {
|
private MIResult[] processMIResults(StringBuffer buffer) {
|
||||||
List aList = new ArrayList();
|
List aList = new ArrayList();
|
||||||
MIResult result = processMIResult(buffer);
|
MIResult result = processMIResult(buffer);
|
||||||
if (result != null) {
|
if (result != null) {
|
||||||
|
@ -249,7 +253,7 @@ public class MIParser {
|
||||||
* Construct the MIResult. Characters will be consume/delete
|
* Construct the MIResult. Characters will be consume/delete
|
||||||
* has moving forward constructing the AST.
|
* has moving forward constructing the AST.
|
||||||
*/
|
*/
|
||||||
MIResult processMIResult(StringBuffer buffer) {
|
private MIResult processMIResult(StringBuffer buffer) {
|
||||||
MIResult result = new MIResult();
|
MIResult result = new MIResult();
|
||||||
int equal;
|
int equal;
|
||||||
if (buffer.length() > 0 && Character.isLetter(buffer.charAt(0))
|
if (buffer.length() > 0 && Character.isLetter(buffer.charAt(0))
|
||||||
|
@ -270,7 +274,7 @@ public class MIParser {
|
||||||
/**
|
/**
|
||||||
* Find a MIValue implementation or return null.
|
* Find a MIValue implementation or return null.
|
||||||
*/
|
*/
|
||||||
MIValue processMIValue(StringBuffer buffer) {
|
private MIValue processMIValue(StringBuffer buffer) {
|
||||||
MIValue value = null;
|
MIValue value = null;
|
||||||
if (buffer.length() > 0) {
|
if (buffer.length() > 0) {
|
||||||
if (buffer.charAt(0) == '{') {
|
if (buffer.charAt(0) == '{') {
|
||||||
|
@ -294,7 +298,7 @@ public class MIParser {
|
||||||
* go to the closing '}' consuming/deleting all the characters.
|
* go to the closing '}' consuming/deleting all the characters.
|
||||||
* This is usually call by processMIvalue();
|
* This is usually call by processMIvalue();
|
||||||
*/
|
*/
|
||||||
MIValue processMITuple(StringBuffer buffer) {
|
private MIValue processMITuple(StringBuffer buffer) {
|
||||||
MITuple tuple = new MITuple();
|
MITuple tuple = new MITuple();
|
||||||
MIResult[] results = null;
|
MIResult[] results = null;
|
||||||
// Catch closing '}'
|
// Catch closing '}'
|
||||||
|
@ -315,7 +319,7 @@ public class MIParser {
|
||||||
* Assuming the leading '[' was deleted, find the closing
|
* Assuming the leading '[' was deleted, find the closing
|
||||||
* ']' consuming/delete chars from the StringBuffer.
|
* ']' consuming/delete chars from the StringBuffer.
|
||||||
*/
|
*/
|
||||||
MIValue processMIList(StringBuffer buffer) {
|
private MIValue processMIList(StringBuffer buffer) {
|
||||||
MIList list = new MIList();
|
MIList list = new MIList();
|
||||||
List valueList = new ArrayList();
|
List valueList = new ArrayList();
|
||||||
List resultList = new ArrayList();
|
List resultList = new ArrayList();
|
||||||
|
@ -345,7 +349,7 @@ public class MIParser {
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
String translateCString(StringBuffer buffer) {
|
private String translateCString(StringBuffer buffer) {
|
||||||
boolean escape = false;
|
boolean escape = false;
|
||||||
boolean closingQuotes = false;
|
boolean closingQuotes = false;
|
||||||
|
|
||||||
|
@ -356,14 +360,14 @@ public class MIParser {
|
||||||
char c = buffer.charAt(index);
|
char c = buffer.charAt(index);
|
||||||
if (c == '\\') {
|
if (c == '\\') {
|
||||||
if (escape) {
|
if (escape) {
|
||||||
sb.append('\\').append(c);
|
sb.append(c);
|
||||||
escape = false;
|
escape = false;
|
||||||
} else {
|
} else {
|
||||||
escape = true;
|
escape = true;
|
||||||
}
|
}
|
||||||
} else if (c == '"') {
|
} else if (c == '"') {
|
||||||
if (escape) {
|
if (escape) {
|
||||||
sb.append('\\').append(c);;
|
sb.append(c);;
|
||||||
escape = false;
|
escape = false;
|
||||||
} else {
|
} else {
|
||||||
// Bail out.
|
// Bail out.
|
||||||
|
|
|
@ -61,7 +61,7 @@ public class MIRegisterValue {
|
||||||
String aName = "";
|
String aName = "";
|
||||||
MIValue value = args[0].getMIValue();
|
MIValue value = args[0].getMIValue();
|
||||||
if (value != null && value instanceof MIConst) {
|
if (value != null && value instanceof MIConst) {
|
||||||
aName = ((MIConst)value).getString();
|
aName = ((MIConst)value).getCString();
|
||||||
} else {
|
} else {
|
||||||
aName = "";
|
aName = "";
|
||||||
}
|
}
|
||||||
|
@ -70,7 +70,7 @@ public class MIRegisterValue {
|
||||||
String aValue = "";
|
String aValue = "";
|
||||||
value = args[1].getMIValue();
|
value = args[1].getMIValue();
|
||||||
if (value != null && value instanceof MIConst) {
|
if (value != null && value instanceof MIConst) {
|
||||||
aValue = ((MIConst)value).getString();
|
aValue = ((MIConst)value).getCString();
|
||||||
} else {
|
} else {
|
||||||
aValue = "";
|
aValue = "";
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,7 +28,7 @@ public class MIStackInfoDepthInfo extends MIInfo {
|
||||||
if (var.equals("depth")) {
|
if (var.equals("depth")) {
|
||||||
MIValue val = results[i].getMIValue();
|
MIValue val = results[i].getMIValue();
|
||||||
if (val instanceof MIConst) {
|
if (val instanceof MIConst) {
|
||||||
String str = ((MIConst)val).getString();
|
String str = ((MIConst)val).getCString();
|
||||||
try {
|
try {
|
||||||
depth = Integer.parseInt(str.trim());
|
depth = Integer.parseInt(str.trim());
|
||||||
} catch (NumberFormatException e) {
|
} catch (NumberFormatException e) {
|
||||||
|
|
|
@ -14,6 +14,10 @@ public abstract class MIStreamRecord extends MIOOBRecord {
|
||||||
cstring = str;
|
cstring = str;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getString () {
|
||||||
|
return MIConst.getString(getCString());
|
||||||
|
}
|
||||||
|
|
||||||
public String toString() {
|
public String toString() {
|
||||||
if (this instanceof MIConsoleStreamOutput) {
|
if (this instanceof MIConsoleStreamOutput) {
|
||||||
return "~\"" + cstring + "\"\n";
|
return "~\"" + cstring + "\"\n";
|
||||||
|
|
|
@ -47,7 +47,7 @@ public class MIThreadListIdsInfo extends MIInfo {
|
||||||
if (var.equals("thread-id")) {
|
if (var.equals("thread-id")) {
|
||||||
MIValue value = results[i].getMIValue();
|
MIValue value = results[i].getMIValue();
|
||||||
if (value instanceof MIConst) {
|
if (value instanceof MIConst) {
|
||||||
String str = ((MIConst)value).getString();
|
String str = ((MIConst)value).getCString();
|
||||||
try {
|
try {
|
||||||
threadIds[i] = Integer.parseInt(str.trim());
|
threadIds[i] = Integer.parseInt(str.trim());
|
||||||
} catch (NumberFormatException e) {
|
} catch (NumberFormatException e) {
|
||||||
|
|
|
@ -38,7 +38,7 @@ public class MIThreadSelectInfo extends MIInfo {
|
||||||
if (var.equals("new-thread-ids")) {
|
if (var.equals("new-thread-ids")) {
|
||||||
MIValue value = results[i].getMIValue();
|
MIValue value = results[i].getMIValue();
|
||||||
if (value instanceof MIConst) {
|
if (value instanceof MIConst) {
|
||||||
String str = ((MIConst)value).getString();
|
String str = ((MIConst)value).getCString();
|
||||||
try {
|
try {
|
||||||
threadId = Integer.parseInt(str.trim());
|
threadId = Integer.parseInt(str.trim());
|
||||||
} catch (NumberFormatException e) {
|
} catch (NumberFormatException e) {
|
||||||
|
|
Loading…
Add table
Reference in a new issue