blob: e940187fa71003516f30ff9a568feb77672413ef [file] [log] [blame]
/*
*(c) Copyright QNX Software Systems Ltd. 2002.
* All Rights Reserved.
*
*/
package org.eclipse.cdt.debug.mi.core.cdi;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.eclipse.cdt.debug.core.cdi.CDIException;
import org.eclipse.cdt.debug.core.cdi.ICDIRegisterManager;
import org.eclipse.cdt.debug.core.cdi.model.ICDIRegister;
import org.eclipse.cdt.debug.core.cdi.model.ICDIRegisterObject;
import org.eclipse.cdt.debug.mi.core.MIException;
import org.eclipse.cdt.debug.mi.core.MISession;
import org.eclipse.cdt.debug.mi.core.cdi.model.Register;
import org.eclipse.cdt.debug.mi.core.cdi.model.RegisterObject;
import org.eclipse.cdt.debug.mi.core.command.CommandFactory;
import org.eclipse.cdt.debug.mi.core.command.MIDataListChangedRegisters;
import org.eclipse.cdt.debug.mi.core.command.MIDataListRegisterNames;
import org.eclipse.cdt.debug.mi.core.command.MIVarCreate;
import org.eclipse.cdt.debug.mi.core.command.MIVarUpdate;
import org.eclipse.cdt.debug.mi.core.event.MIEvent;
import org.eclipse.cdt.debug.mi.core.event.MIRegisterChangedEvent;
import org.eclipse.cdt.debug.mi.core.event.MIVarChangedEvent;
import org.eclipse.cdt.debug.mi.core.output.MIDataListChangedRegistersInfo;
import org.eclipse.cdt.debug.mi.core.output.MIDataListRegisterNamesInfo;
import org.eclipse.cdt.debug.mi.core.output.MIVar;
import org.eclipse.cdt.debug.mi.core.output.MIVarChange;
import org.eclipse.cdt.debug.mi.core.output.MIVarCreateInfo;
import org.eclipse.cdt.debug.mi.core.output.MIVarUpdateInfo;
/**
*/
public class RegisterManager extends SessionObject implements ICDIRegisterManager {
private List regList;
private boolean autoupdate;
MIVarChange[] noChanges = new MIVarChange[0];
public RegisterManager(Session session) {
super(session);
regList = Collections.synchronizedList(new ArrayList());
autoupdate = true;
}
/**
* @see org.eclipse.cdt.debug.core.cdi.model.ICDITarget#getRegisterObjects()
*/
public ICDIRegisterObject[] getRegisterObjects() throws CDIException {
Session session = (Session)getSession();
MISession mi = session.getMISession();
CommandFactory factory = mi.getCommandFactory();
MIDataListRegisterNames registers = factory.createMIDataListRegisterNames();
try {
mi.postCommand(registers);
MIDataListRegisterNamesInfo info =
registers.getMIDataListRegisterNamesInfo();
if (info == null) {
throw new CDIException("No answer");
}
String[] names = info.getRegisterNames();
List regsList = new ArrayList(names.length);
for (int i = 0; i < names.length; i++) {
if (names[i].length() > 0) {
regsList.add(new RegisterObject(session.getCurrentTarget(), names[i], i));
}
}
return (ICDIRegisterObject[])regsList.toArray(new ICDIRegisterObject[0]);
} catch (MIException e) {
throw new MI2CDIException(e);
}
}
/**
* @see org.eclipse.cdt.debug.core.cdi.model.ICDITarget#createRegister()
*/
public ICDIRegister createRegister(ICDIRegisterObject regObject) throws CDIException {
RegisterObject regObj = null;
if (regObject instanceof RegisterObject) {
regObj = (RegisterObject)regObject;
}
if (regObj != null) {
Register reg = getRegister(regObject);
if (reg == null) {
try {
String name = "$" + regObj.getName();
Session session = (Session)getSession();
MISession mi = session.getMISession();
CommandFactory factory = mi.getCommandFactory();
MIVarCreate var = factory.createMIVarCreate(name);
mi.postCommand(var);
MIVarCreateInfo info = var.getMIVarCreateInfo();
if (info == null) {
throw new CDIException("No answer");
}
reg = new Register(regObj, info.getMIVar());
regList.add(reg);
} catch (MIException e) {
throw new MI2CDIException(e);
}
}
return reg;
}
throw new CDIException("Wrong register type");
}
public Register createRegister(RegisterObject v, MIVar mivar) throws CDIException {
Register reg = new Register(v, mivar);
regList.add(reg);
return reg;
}
/**
* @see org.eclipse.cdt.debug.core.cdi.ICDIRegisterManager#destroyRegister(ICDIRegister)
*/
public void destroyRegister(ICDIRegister reg) {
regList.remove(reg);
}
/**
* @see org.eclipse.cdt.debug.core.cdi.ICDIRegisterManager#setAutoUpdate(boolean)
*/
public void setAutoUpdate(boolean update) {
autoupdate = update;
}
/**
* @see org.eclipse.cdt.debug.core.cdi.ICDIRegisterManager#isAutoUpdate()
*/
public boolean isAutoUpdate() {
return autoupdate;
}
/**
* Use by the eventManager to find the Register;
*/
public Register getRegister(String varName) {
Register[] regs = getRegisters();
for (int i = 0; i < regs.length; i++) {
if (regs[i].getMIVar().getVarName().equals(varName)) {
return regs[i];
}
try {
Register r = (Register)regs[i].getChild(varName);
if (r != null) {
return r;
}
} catch (ClassCastException e) {
}
}
return null;
}
/**
* Use by the eventManager to find the Register;
*/
public Register getRegister(int regno) {
Register[] regs = getRegisters();
for (int i = 0; i < regs.length; i++) {
if (regs[i].getPosition() == regno) {
return regs[i];
}
}
return null;
}
/**
* Call the by the EventManager when the target is suspended.
*/
public void update() throws CDIException {
Session session = (Session)getSession();
MISession mi = session.getMISession();
CommandFactory factory = mi.getCommandFactory();
MIDataListChangedRegisters changed = factory.createMIDataListChangedRegisters();
try {
mi.postCommand(changed);
MIDataListChangedRegistersInfo info =
changed.getMIDataListChangedRegistersInfo();
if (info == null) {
throw new CDIException("No answer");
}
int[] regnos = info.getRegisterNumbers();
List eventList = new ArrayList(regnos.length);
// Now that we know the registers changed
// call -var-update to update the value in gdb.
// And send the notification.
for (int i = 0 ; i < regnos.length; i++) {
Register reg = getRegister(regnos[i]);
if (reg != null) {
String varName = reg.getMIVar().getVarName();
MIVarChange[] changes = noChanges;
MIVarUpdate update = factory.createMIVarUpdate(varName);
try {
mi.postCommand(update);
MIVarUpdateInfo updateInfo = update.getMIVarUpdateInfo();
if (updateInfo == null) {
throw new CDIException("No answer");
}
changes = updateInfo.getMIVarChanges();
} catch (MIException e) {
//throw new MI2CDIException(e);
//eventList.add(new MIVarDeletedEvent(varName));
}
if (changes.length != 0) {
for (int j = 0 ; j < changes.length; j++) {
String n = changes[j].getVarName();
if (changes[j].isInScope()) {
eventList.add(new MIVarChangedEvent(n));
}
}
} else {
// Fall back to the register number.
eventList.add(new MIRegisterChangedEvent(update.getToken(), reg.getName(), regnos[i]));
}
}
}
MIEvent[] events = (MIEvent[])eventList.toArray(new MIEvent[0]);
mi.fireEvents(events);
} catch (MIException e) {
throw new MI2CDIException(e);
}
}
private Register[] getRegisters() {
return (Register[])regList.toArray(new Register[0]);
}
private Register getRegister(ICDIRegisterObject regObject) throws CDIException {
Register[] regs = getRegisters();
for (int i = 0; i < regs.length; i++) {
if (regObject.getName().equals(regs[i].getName())) {
return regs[i];
}
}
return null;
}
}