| /* |
| *(c) Copyright QNX Software Systems Ltd. 2002. |
| * All Rights Reserved. |
| * |
| */ |
| package org.eclipse.cdt.debug.mi.core.cdi; |
| |
| import java.util.StringTokenizer; |
| |
| import org.eclipse.cdt.debug.core.cdi.CDIException; |
| import org.eclipse.cdt.debug.core.cdi.ICDISourceManager; |
| import org.eclipse.cdt.debug.core.cdi.model.ICDIInstruction; |
| import org.eclipse.cdt.debug.core.cdi.model.ICDIMixedInstruction; |
| import org.eclipse.cdt.debug.core.cdi.model.ICDITarget; |
| import org.eclipse.cdt.debug.mi.core.GDBTypeParser; |
| import org.eclipse.cdt.debug.mi.core.MIException; |
| import org.eclipse.cdt.debug.mi.core.MISession; |
| import org.eclipse.cdt.debug.mi.core.GDBTypeParser.GDBDerivedType; |
| import org.eclipse.cdt.debug.mi.core.GDBTypeParser.GDBType; |
| import org.eclipse.cdt.debug.mi.core.cdi.model.Instruction; |
| import org.eclipse.cdt.debug.mi.core.cdi.model.MixedInstruction; |
| import org.eclipse.cdt.debug.mi.core.cdi.model.type.ArrayType; |
| import org.eclipse.cdt.debug.mi.core.cdi.model.type.BoolType; |
| import org.eclipse.cdt.debug.mi.core.cdi.model.type.CharType; |
| import org.eclipse.cdt.debug.mi.core.cdi.model.type.DerivedType; |
| import org.eclipse.cdt.debug.mi.core.cdi.model.type.DoubleType; |
| import org.eclipse.cdt.debug.mi.core.cdi.model.type.EnumType; |
| import org.eclipse.cdt.debug.mi.core.cdi.model.type.FloatType; |
| import org.eclipse.cdt.debug.mi.core.cdi.model.type.FunctionType; |
| import org.eclipse.cdt.debug.mi.core.cdi.model.type.IntType; |
| import org.eclipse.cdt.debug.mi.core.cdi.model.type.LongLongType; |
| import org.eclipse.cdt.debug.mi.core.cdi.model.type.LongType; |
| import org.eclipse.cdt.debug.mi.core.cdi.model.type.PointerType; |
| import org.eclipse.cdt.debug.mi.core.cdi.model.type.ReferenceType; |
| import org.eclipse.cdt.debug.mi.core.cdi.model.type.ShortType; |
| import org.eclipse.cdt.debug.mi.core.cdi.model.type.StructType; |
| import org.eclipse.cdt.debug.mi.core.cdi.model.type.Type; |
| import org.eclipse.cdt.debug.mi.core.cdi.model.type.VoidType; |
| import org.eclipse.cdt.debug.mi.core.cdi.model.type.WCharType; |
| import org.eclipse.cdt.debug.mi.core.command.CommandFactory; |
| import org.eclipse.cdt.debug.mi.core.command.MIDataDisassemble; |
| import org.eclipse.cdt.debug.mi.core.command.MIEnvironmentDirectory; |
| import org.eclipse.cdt.debug.mi.core.command.MIGDBShowDirectories; |
| import org.eclipse.cdt.debug.mi.core.command.MIPType; |
| import org.eclipse.cdt.debug.mi.core.output.MIAsm; |
| import org.eclipse.cdt.debug.mi.core.output.MIDataDisassembleInfo; |
| import org.eclipse.cdt.debug.mi.core.output.MIGDBShowDirectoriesInfo; |
| import org.eclipse.cdt.debug.mi.core.output.MIPTypeInfo; |
| import org.eclipse.cdt.debug.mi.core.output.MISrcAsm; |
| |
| |
| /** |
| */ |
| public class SourceManager extends SessionObject implements ICDISourceManager { |
| |
| boolean autoupdate; |
| GDBTypeParser gdbTypeParser; |
| |
| public SourceManager(Session session) { |
| super(session); |
| autoupdate = false; |
| gdbTypeParser = new GDBTypeParser(); |
| } |
| |
| /** |
| * @see org.eclipse.cdt.debug.core.cdi.ICDISourceManager#addSourcePaths(String[]) |
| */ |
| public void addSourcePaths(String[] dirs) throws CDIException { |
| Session session = (Session)getSession(); |
| MISession mi = session.getMISession(); |
| CommandFactory factory = mi.getCommandFactory(); |
| MIEnvironmentDirectory dir = factory.createMIEnvironmentDirectory(dirs); |
| try { |
| mi.postCommand(dir); |
| dir.getMIInfo(); |
| } catch (MIException e) { |
| throw new MI2CDIException(e); |
| } |
| } |
| |
| /** |
| * @see org.eclipse.cdt.debug.core.cdi.ICDISourceManager#getSourcePaths() |
| */ |
| public String[] getSourcePaths() throws CDIException { |
| Session session = (Session)getSession(); |
| MISession mi = session.getMISession(); |
| CommandFactory factory = mi.getCommandFactory(); |
| MIGDBShowDirectories dir = factory.createMIGDBShowDirectories(); |
| try { |
| mi.postCommand(dir); |
| MIGDBShowDirectoriesInfo info = dir.getMIGDBShowDirectoriesInfo(); |
| return info.getDirectories(); |
| } catch (MIException e) { |
| throw new MI2CDIException(e); |
| } |
| } |
| |
| /** |
| * @see org.eclipse.cdt.debug.core.cdi.ICDISourceManager#getInstructions(String, int, int) |
| */ |
| public ICDIInstruction[] getInstructions(String filename, int linenum, int lines) throws CDIException { |
| Session session = (Session)getSession(); |
| MISession mi = session.getMISession(); |
| CommandFactory factory = mi.getCommandFactory(); |
| MIDataDisassemble dis = factory.createMIDataDisassemble(filename, linenum, lines, false); |
| try { |
| mi.postCommand(dis); |
| MIDataDisassembleInfo info = dis.getMIDataDisassembleInfo(); |
| MIAsm[] asm = info.getMIAsms(); |
| Instruction[] instructions = new Instruction[asm.length]; |
| for (int i = 0; i < instructions.length; i++) { |
| instructions[i] = new Instruction(session.getCurrentTarget(), asm[i]); |
| } |
| return instructions; |
| } catch (MIException e) { |
| throw new MI2CDIException(e); |
| } |
| } |
| |
| /** |
| * @see org.eclipse.cdt.debug.core.cdi.ICDISourceManager#getInstructions(String, int) |
| */ |
| public ICDIInstruction[] getInstructions(String filename, int linenum) throws CDIException { |
| return getInstructions(filename, linenum, -1); |
| } |
| |
| /** |
| * @see org.eclipse.cdt.debug.core.cdi.ICDISourceManager#getInstructions(long, long) |
| */ |
| public ICDIInstruction[] getInstructions(long start, long end) throws CDIException { |
| Session session = (Session)getSession(); |
| MISession mi = session.getMISession(); |
| CommandFactory factory = mi.getCommandFactory(); |
| String hex = "0x"; |
| String sa = hex + Long.toHexString(start); |
| String ea = hex + Long.toHexString(end); |
| MIDataDisassemble dis = factory.createMIDataDisassemble(sa, ea, false); |
| try { |
| mi.postCommand(dis); |
| MIDataDisassembleInfo info = dis.getMIDataDisassembleInfo(); |
| MIAsm[] asm = info.getMIAsms(); |
| Instruction[] instructions = new Instruction[asm.length]; |
| for (int i = 0; i < instructions.length; i++) { |
| instructions[i] = new Instruction(session.getCurrentTarget(), asm[i]); |
| } |
| return instructions; |
| } catch (MIException e) { |
| throw new MI2CDIException(e); |
| } |
| } |
| |
| /** |
| * @see org.eclipse.cdt.debug.core.cdi.ICDISourceManager#getMixedInstructions(String, int, int) |
| */ |
| public ICDIMixedInstruction[] getMixedInstructions(String filename, int linenum, int lines) throws CDIException { |
| Session session = (Session)getSession(); |
| MISession mi = session.getMISession(); |
| CommandFactory factory = mi.getCommandFactory(); |
| MIDataDisassemble dis = factory.createMIDataDisassemble(filename, linenum, lines, true); |
| try { |
| mi.postCommand(dis); |
| MIDataDisassembleInfo info = dis.getMIDataDisassembleInfo(); |
| MISrcAsm[] srcAsm = info.getMISrcAsms(); |
| ICDIMixedInstruction[] mixed = new ICDIMixedInstruction[srcAsm.length]; |
| for (int i = 0; i < mixed.length; i++) { |
| mixed[i] = new MixedInstruction(session.getCurrentTarget(), srcAsm[i]); |
| } |
| return mixed; |
| } catch (MIException e) { |
| throw new MI2CDIException(e); |
| } |
| } |
| |
| /** |
| * @see org.eclipse.cdt.debug.core.cdi.ICDISourceManager#getMixedInstructions(String, int) |
| */ |
| public ICDIMixedInstruction[] getMixedInstructions(String filename, int linenum) throws CDIException { |
| return getMixedInstructions(filename, linenum, -1); |
| } |
| |
| /** |
| * @see org.eclipse.cdt.debug.core.cdi.ICDISourceManager#getMixedInstructions(long, long) |
| */ |
| public ICDIMixedInstruction[] getMixedInstructions(long start, long end) throws CDIException { |
| Session session = (Session)getSession(); |
| MISession mi = session.getMISession(); |
| CommandFactory factory = mi.getCommandFactory(); |
| String hex = "0x"; |
| String sa = hex + Long.toHexString(start); |
| String ea = hex + Long.toHexString(end); |
| MIDataDisassemble dis = factory.createMIDataDisassemble(sa, ea, true); |
| try { |
| mi.postCommand(dis); |
| MIDataDisassembleInfo info = dis.getMIDataDisassembleInfo(); |
| MISrcAsm[] srcAsm = info.getMISrcAsms(); |
| ICDIMixedInstruction[] mixed = new ICDIMixedInstruction[srcAsm.length]; |
| for (int i = 0; i < mixed.length; i++) { |
| mixed[i] = new MixedInstruction(session.getCurrentTarget(), srcAsm[i]); |
| } |
| return mixed; |
| } catch (MIException e) { |
| throw new MI2CDIException(e); |
| } |
| } |
| |
| /** |
| * @see org.eclipse.cdt.debug.core.cdi.ICDISourceManager#isAutoUpdate() |
| */ |
| public boolean isAutoUpdate() { |
| return autoupdate; |
| } |
| |
| /** |
| * @see org.eclipse.cdt.debug.core.cdi.ICDISourceManager#setAutoUpdate(boolean) |
| */ |
| public void setAutoUpdate(boolean update) { |
| autoupdate = update; |
| } |
| |
| /** |
| * @see org.eclipse.cdt.debug.core.cdi.ICDISourceManager#update() |
| */ |
| public void update() throws CDIException { |
| } |
| |
| |
| public Type getType(ICDITarget target, String name) throws CDIException { |
| if (name == null) { |
| name = new String(); |
| } |
| String typename = name.trim(); |
| |
| // Parse the string. |
| GDBType gdbType = gdbTypeParser.parse(typename); |
| Type headType = null; |
| Type type = null; |
| |
| // Convert the GDBType to an ICDIType. |
| // So we go through the gdbType tree and reconstruct an ICDIType tree |
| for (Type aType = null; gdbType != null; type = aType) { |
| if (gdbType instanceof GDBDerivedType) { |
| switch(gdbType.getType()) { |
| case GDBType.ARRAY: |
| int d = ((GDBDerivedType)gdbType).getDimension(); |
| aType = new ArrayType(target, gdbType.toString(), d); |
| break; |
| case GDBType.FUNCTION: |
| aType = new FunctionType(target, gdbType.toString()); |
| break; |
| case GDBType.POINTER: |
| aType = new PointerType(target, gdbType.toString()); |
| break; |
| case GDBType.REFERENCE: |
| aType = new ReferenceType(target, gdbType.toString()); |
| break; |
| } |
| gdbType = ((GDBDerivedType)gdbType).getChild(); |
| } else { |
| aType = toCDIType(target, gdbType.toString()); |
| gdbType = null; |
| } |
| if (type instanceof DerivedType) { |
| ((DerivedType)type).setComponentType(aType); |
| } |
| // Save the head to returning it. |
| if (headType == null) { |
| headType = aType; |
| } |
| } |
| |
| if (headType != null) { |
| return headType; |
| } |
| throw new CDIException("Unknown type"); |
| } |
| |
| Type toCDIType(ICDITarget target, String name) throws CDIException { |
| // Check the derived types and agregate types |
| if (name == null) { |
| name = new String(); |
| } |
| String typename = name.trim(); |
| |
| // Check the primitives. |
| if (typename.equals("char")) { |
| return new CharType(target, typename); |
| } else if (typename.equals("wchar_t")) { |
| return new WCharType(target, typename); |
| } else if (typename.equals("short")) { |
| return new ShortType(target, typename); |
| } else if (typename.equals("int")) { |
| return new IntType(target, typename); |
| } else if (typename.equals("long")) { |
| return new LongType(target, typename); |
| } else if (typename.equals("unsigned")) { |
| return new IntType(target, typename, true); |
| } else if (typename.equals("signed")) { |
| return new IntType(target, typename); |
| } else if (typename.equals("bool")) { |
| return new BoolType(target, typename); |
| } else if (typename.equals("_Bool")) { |
| return new BoolType(target, typename); |
| } else if (typename.equals("float")) { |
| return new FloatType(target, typename); |
| } else if (typename.equals("double")) { |
| return new DoubleType(target, typename); |
| } else if (typename.equals("void")) { |
| return new VoidType(target, typename); |
| } else if (typename.equals("enum")) { |
| return new EnumType(target, typename); |
| } else if (typename.equals("union")) { |
| return new StructType(target, typename); |
| } else if (typename.equals("struct")) { |
| return new StructType(target, typename); |
| } else if (typename.equals("class")) { |
| return new StructType(target, typename); |
| } |
| |
| StringTokenizer st = new StringTokenizer(typename); |
| int count = st.countTokens(); |
| |
| if (count == 2) { |
| String first = st.nextToken(); |
| String second = st.nextToken(); |
| |
| // ISOC allows permutations: |
| // "signed int" and "int signed" are equivalent |
| boolean isUnsigned = (first.equals("unsigned") || second.equals("unsigned")); |
| boolean isSigned = (first.equals("signed") || second.equals("signed")); |
| boolean isChar = (first.equals("char") || second.equals("char")); |
| boolean isInt = (first.equals("int") || second.equals("int")); |
| boolean isLong = (first.equals("long") || second.equals("long")); |
| boolean isShort = (first.equals("short") || second.equals("short")); |
| boolean isLongLong = (first.equals("long") && second.equals("long")); |
| |
| boolean isDouble = (first.equals("double") || second.equals("double")); |
| boolean isFloat = (first.equals("float") || second.equals("float")); |
| boolean isComplex = (first.equals("complex") || second.equals("complex") || |
| first.equals("_Complex") || second.equals("_Complex")); |
| boolean isImaginery = (first.equals("_Imaginary") || second.equals("_Imaginary")); |
| |
| boolean isStruct = first.equals("struct"); |
| boolean isClass = first.equals("class"); |
| boolean isUnion = first.equals("union"); |
| boolean isEnum = first.equals("enum"); |
| |
| if (isChar && (isSigned || isUnsigned)) { |
| return new CharType(target, typename, isUnsigned); |
| } else if (isShort && (isSigned || isUnsigned)) { |
| return new ShortType(target, typename, isUnsigned); |
| } else if (isInt && (isSigned || isUnsigned)) { |
| return new IntType(target, typename, isUnsigned); |
| } else if (isLong && (isInt || isSigned || isUnsigned)) { |
| return new LongType(target, typename, isUnsigned); |
| } else if (isLongLong) { |
| return new LongLongType(target, typename); |
| } else if (isDouble && (isLong || isComplex || isImaginery)) { |
| return new DoubleType(target, typename, isComplex, isImaginery, isLong); |
| } else if (isFloat && (isComplex || isImaginery)) { |
| return new FloatType(target, typename, isComplex, isImaginery); |
| } else if (isStruct) { |
| return new StructType(target, typename); |
| } else if (isClass) { |
| return new StructType(target, typename); |
| } else if (isUnion) { |
| return new StructType(target, typename); |
| } else if (isEnum) { |
| return new EnumType(target, typename); |
| } |
| } else if (count == 3) { |
| // ISOC allows permutation. replace short by: long or short |
| // "unsigned short int", "unsigned int short" |
| // "short unsigned int". "short int unsigned" |
| // "int unsinged short". "int short unsigned" |
| // |
| // "unsigned long long", "long long unsigned" |
| // "signed long long", "long long signed" |
| String first = st.nextToken(); |
| String second = st.nextToken(); |
| String third = st.nextToken(); |
| |
| boolean isSigned = (first.equals("signed") || second.equals("signed") || third.equals("signed")); |
| boolean unSigned = (first.equals("unsigned") || second.equals("unsigned") || third.equals("unsigned")); |
| boolean isInt = (first.equals("int") || second.equals("int") || third.equals("int")); |
| boolean isLong = (first.equals("long") || second.equals("long") || third.equals("long")); |
| boolean isShort = (first.equals("short") || second.equals("short") || third.equals("short")); |
| boolean isLongLong = (first.equals("long") && second.equals("long")) || |
| (second.equals("long") && third.equals("long")); |
| boolean isDouble = (first.equals("double") || second.equals("double") || third.equals("double")); |
| boolean isComplex = (first.equals("complex") || second.equals("complex") || third.equals("complex") || |
| first.equals("_Complex") || second.equals("_Complex") || third.equals("_Complex")); |
| boolean isImaginery = (first.equals("_Imaginary") || second.equals("_Imaginary") || third.equals("_Imaginary")); |
| |
| |
| if (isShort && isInt && (isSigned || unSigned)) { |
| return new ShortType(target, typename, unSigned); |
| } else if (isLong && isInt && (isSigned || unSigned)) { |
| return new LongType(target, typename, unSigned); |
| } else if (isLongLong && (isSigned || unSigned)) { |
| return new LongLongType(target, typename, unSigned); |
| } else if (isDouble && isLong && (isComplex || isImaginery)) { |
| return new DoubleType(target, typename, isComplex, isImaginery, isLong); |
| } |
| } else if (count == 4) { |
| // ISOC allows permutation: |
| // "unsigned long long int", "unsigned int long long" |
| // "long long unsigned int". "long long int unsigned" |
| // "int unsigned long long". "int long long unsigned" |
| String first = st.nextToken(); |
| String second = st.nextToken(); |
| String third = st.nextToken(); |
| String fourth = st.nextToken(); |
| |
| boolean unSigned = (first.equals("unsigned") || second.equals("unsigned") || third.equals("unsigned") || fourth.equals("unsigned")); |
| boolean isSigned = (first.equals("signed") || second.equals("signed") || third.equals("signed") || fourth.equals("signed")); |
| boolean isInt = (first.equals("int") || second.equals("int") || third.equals("int") || fourth.equals("int")); |
| boolean isLongLong = (first.equals("long") && second.equals("long")) |
| || (second.equals("long") && third.equals("long")) |
| || (third.equals("long") && fourth.equals("long")); |
| |
| if (isLongLong && isInt && (isSigned || unSigned)) { |
| return new LongLongType(target, typename, unSigned); |
| } |
| } |
| throw new CDIException("Unknown type"); |
| } |
| |
| public String getDetailTypeName(String typename) throws CDIException { |
| try { |
| Session session = (Session)getSession(); |
| MISession mi = session.getMISession(); |
| CommandFactory factory = mi.getCommandFactory(); |
| MIPType ptype = factory.createMIPType(typename); |
| mi.postCommand(ptype); |
| MIPTypeInfo info = ptype.getMIPtypeInfo(); |
| if (info == null) { |
| throw new CDIException("No answer"); |
| } |
| return info.getType(); |
| } catch (MIException e) { |
| throw new MI2CDIException(e); |
| } |
| } |
| |
| } |