diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/ARMember.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/ARMember.java new file mode 100644 index 00000000000..73ec760ad76 --- /dev/null +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/ARMember.java @@ -0,0 +1,90 @@ +/********************************************************************** + * Copyright (c) 2002,2003 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * QNX Software Systems - Initial API and implementation +***********************************************************************/ +package org.eclipse.cdt.utils.coff.parser; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.List; + +import org.eclipse.cdt.core.IBinaryParser.ISymbol; +import org.eclipse.cdt.utils.Addr2line; +import org.eclipse.cdt.utils.CPPFilt; +import org.eclipse.cdt.utils.CygPath; +import org.eclipse.cdt.utils.ICygwinToolsProvider; +import org.eclipse.cdt.utils.coff.Coff; +import org.eclipse.cdt.utils.coff.PE; +import org.eclipse.cdt.utils.coff.PEArchive; +import org.eclipse.core.runtime.IPath; + +/** + */ +public class ARMember extends BinaryObject { + PEArchive.ARHeader header; + + public ARMember(IPath p, PEArchive.ARHeader h, ICygwinToolsProvider provider) throws IOException { + super(p, h.getPE(), provider); + header = h; + } + + /** + * @see org.eclipse.cdt.core.model.IBinaryParser.IBinaryFile#getContents() + */ + public InputStream getContents() { + InputStream stream = null; + if (path != null && header != null) { + try { + stream = new ByteArrayInputStream(header.getObjectData()); + } catch (IOException e) { + } + } + if (stream == null) { + stream = super.getContents(); + } + return stream; + } + + /** + * @see org.eclipse.cdt.core.model.IBinaryParser.IBinaryObject#getName() + */ + public String getName() { + if (header != null) { + return header.getObjectName(); + } + return ""; + } + + protected PE getPE() throws IOException { + if (header != null) { + return header.getPE(); + } + throw new IOException("No file assiocated with Binary"); + } + + protected void addSymbols(Coff.Symbol[] peSyms, byte[] table, Addr2line addr2line, CPPFilt cppfilt, CygPath cypath, List list) { + for (int i = 0; i < peSyms.length; i++) { + if (peSyms[i].isFunction() || peSyms[i].isPointer() ||peSyms[i].isArray()) { + String name = peSyms[i].getName(table); + if (name == null || name.trim().length() == 0 || + !Character.isJavaIdentifierStart(name.charAt(0))) { + continue; + } + Symbol sym = new Symbol(this); + sym.type = peSyms[i].isFunction() ? ISymbol.FUNCTION : ISymbol.VARIABLE; + + sym.name = name; + sym.addr = peSyms[i].n_value; + list.add(sym); + } + } + } + +} diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/BinaryArchive.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/BinaryArchive.java new file mode 100644 index 00000000000..d32d6e22dfb --- /dev/null +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/BinaryArchive.java @@ -0,0 +1,88 @@ +package org.eclipse.cdt.utils.coff.parser; + +/* + * (c) Copyright IBM Corp. 2000, 2001. + * All Rights Reserved. + */ + +import java.io.IOException; +import java.util.ArrayList; + +import org.eclipse.cdt.core.IBinaryParser.IBinaryArchive; +import org.eclipse.cdt.core.IBinaryParser.IBinaryFile; +import org.eclipse.cdt.core.IBinaryParser.IBinaryObject; +import org.eclipse.cdt.utils.coff.PEArchive; +import org.eclipse.cdt.utils.coff.PE.Attribute; +import org.eclipse.core.runtime.IPath; + +/** + */ +public class BinaryArchive extends BinaryFile implements IBinaryArchive { + + ArrayList children; + + public BinaryArchive(IPath p) throws IOException { + super(p); + new PEArchive(p.toOSString()).dispose(); // check file type + children = new ArrayList(5); + } + + /** + * @see org.eclipse.cdt.core.model.IBinaryParser.IBinaryArchive#getObjects() + */ + public IBinaryObject[] getObjects() { + if (hasChanged()) { + children.clear(); + PEArchive ar = null; + try { + ar = new PEArchive(getPath().toOSString()); + PEArchive.ARHeader[] headers = ar.getHeaders(); + for (int i = 0; i < headers.length; i++) { + IBinaryObject bin = new ARMember(path, headers[i], toolsProvider); + children.add(bin); + } + } catch (IOException e) { + //e.printStackTrace(); + } + if (ar != null) { + ar.dispose(); + } + children.trimToSize(); + } + return (IBinaryObject[])children.toArray(new IBinaryObject[0]); + } + + /** + * @see org.eclipse.cdt.core.model.IBinaryParser.IBinaryFile#getFile() + */ + public IPath getPath() { + return path; + } + + /** + * @see org.eclipse.cdt.core.model.IBinaryParser.IBinaryFile#getType() + */ + public int getType() { + return IBinaryFile.ARCHIVE; + } + + /** + * @see org.eclipse.cdt.core.model.IBinaryParser.IBinaryArchive#add(IBinaryObject[]) + */ + public void add(IBinaryObject[] objs) throws IOException { + } + + /** + * @see org.eclipse.cdt.core.model.IBinaryParser.IBinaryArchive#delete(IBinaryObject[]) + */ + public void delete(IBinaryObject[] objs) throws IOException { + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.utils.coff.parser.BinaryFile#getAttribute() + */ + protected Attribute getAttribute() { + return null; + } + +} diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/BinaryObject.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/BinaryObject.java new file mode 100644 index 00000000000..1ea7e6d2b93 --- /dev/null +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/BinaryObject.java @@ -0,0 +1,262 @@ +/********************************************************************** + * Copyright (c) 2002,2003 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * QNX Software Systems - Initial API and implementation +***********************************************************************/ +package org.eclipse.cdt.utils.coff.parser; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import org.eclipse.cdt.core.IBinaryParser.IBinaryFile; +import org.eclipse.cdt.core.IBinaryParser.IBinaryObject; +import org.eclipse.cdt.core.IBinaryParser.ISymbol; +import org.eclipse.cdt.utils.Addr2line; +import org.eclipse.cdt.utils.CPPFilt; +import org.eclipse.cdt.utils.CygPath; +import org.eclipse.cdt.utils.ICygwinToolsProvider; +import org.eclipse.cdt.utils.coff.Coff; +import org.eclipse.cdt.utils.coff.PE; +import org.eclipse.cdt.utils.coff.PE.Attribute; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.Path; + +/** + */ +public class BinaryObject extends BinaryFile implements IBinaryObject { + + PE.Attribute attribute; + ISymbol[] symbols; + int type = IBinaryFile.OBJECT; + private ISymbol[] NO_SYMBOLS = new ISymbol[0]; + + public BinaryObject(IPath p) throws IOException { + super(p); + } + + public BinaryObject(IPath p, PE pe, ICygwinToolsProvider provider) throws IOException { + super(p); + setToolsProvider(provider); + loadInformation(pe); + pe.dispose(); + hasChanged(); + } + + public void setType(int t) { + type = t; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.IBinaryParser.IBinaryObject#getSymbol(long) + */ + public ISymbol getSymbol(long addr) { + ISymbol[] syms = getSymbols(); + int i = Arrays.binarySearch(syms, new Long(addr)); + if (i < 0 || i >= syms.length) { + return null; + } + return syms[i]; + } + + /** + * @see org.eclipse.cdt.core.model.IBinaryParser.IBinaryFile#getType() + */ + public int getType() { + return type; + } + + /** + * @see org.eclipse.cdt.core.model.IBinaryParser.IBinaryObject#getBSS() + */ + public long getBSS() { + return 0; + } + + /** + * @see org.eclipse.cdt.core.model.IBinaryParser.IBinaryObject#getCPU() + */ + public String getCPU() { + Attribute attr = getAttribute(); + if (attr != null) { + return attribute.getCPU(); + } + return ""; + } + + /** + * @see org.eclipse.cdt.core.model.IBinaryParser.IBinaryObject#getData() + */ + public long getData() { + return 0; + } + + /** + * @see org.eclipse.cdt.core.model.IBinaryParser.IBinaryObject#getName() + */ + public String getName() { + return getPath().lastSegment().toString(); + } + + /** + * @see org.eclipse.cdt.core.model.IBinaryParser.IBinaryObject#getSymbols() + */ + public ISymbol[] getSymbols() { + if (hasChanged() || symbols == null) { + try { + loadInformation(); + } catch (IOException e) { + } + if (symbols == null) { + symbols = NO_SYMBOLS; + } + } + return symbols; + } + + /** + * @see org.eclipse.cdt.core.model.IBinaryParser.IBinaryObject#getText() + */ + public long getText() { + return 0; + } + + /** + * @see org.eclipse.cdt.core.model.IBinaryParser.IBinaryObject#hasDebug() + */ + public boolean hasDebug() { + Attribute attr = getAttribute(); + if (attr != null) { + return attr.hasDebug(); + } + return false; + } + + /** + * @see org.eclipse.cdt.core.model.IBinaryParser.IBinaryObject#isLittleEndian() + */ + public boolean isLittleEndian() { + Attribute attr = getAttribute(); + if (attr != null) { + return attr.isLittleEndian(); + } + return false; + } + + /** + * @see org.eclipse.cdt.core.model.IBinaryParser.IBinaryExecutable#getNeededSharedLibs() + */ + public String[] getNeededSharedLibs() { + return new String[0]; + } + + /** + * @see org.eclipse.cdt.core.model.IBinaryParser.IBinaryShared#getSoName() + */ + public String getSoName() { + return ""; + } + + protected PE getPE() throws IOException { + return new PE(getPath().toOSString()); + } + + protected PE.Attribute getAttribute() { + if (hasChanged()) { + try { + loadInformation(); + } catch (IOException e) { + } + } + return attribute; + } + + protected void loadInformation() throws IOException { + PE pe = getPE(); + loadInformation(pe); + pe.dispose(); + } + + private void loadInformation(PE pe) throws IOException { + loadAttribute(pe); + loadSymbols(pe); + } + + private void loadAttribute(PE pe) throws IOException { + attribute = pe.getAttribute(); + } + + private void loadSymbols(PE pe) throws IOException { + ArrayList list = new ArrayList(); + Addr2line addr2line = getAddr2Line(); + CPPFilt cppfilt = getCPPFilt(); + CygPath cygpath = getCygPath(); + + Coff.Symbol[] peSyms = pe.getSymbols(); + byte[] table = pe.getStringTable(); + addSymbols(peSyms, table, addr2line, cppfilt, cygpath, list); + + if (addr2line != null) { + addr2line.dispose(); + } + if (cppfilt != null) { + cppfilt.dispose(); + } + if (cygpath != null) { + cygpath.dispose(); + } + + symbols = (ISymbol[])list.toArray(NO_SYMBOLS); + Arrays.sort(symbols); + list.clear(); + } + + protected void addSymbols(Coff.Symbol[] peSyms, byte[] table, Addr2line addr2line, CPPFilt cppfilt, CygPath cygpath, List list) { + for (int i = 0; i < peSyms.length; i++) { + if (peSyms[i].isFunction() || peSyms[i].isPointer() ||peSyms[i].isArray()) { + String name = peSyms[i].getName(table); + if (name == null || name.trim().length() == 0 || + !Character.isJavaIdentifierStart(name.charAt(0))) { + continue; + } + Symbol sym = new Symbol(this); + sym.type = peSyms[i].isFunction() ? ISymbol.FUNCTION : ISymbol.VARIABLE; + sym.addr = peSyms[i].n_value; + + sym.name = name; + if (cppfilt != null) { + try { + sym.name = cppfilt.getFunction(sym.name); + } catch (IOException e1) { + } + } + + sym.filename = null; + sym.startLine = 0; + sym.endLine = 0; + if (addr2line != null) { + try { + String filename = addr2line.getFileName(sym.addr); + if (filename != null) { + if (cygpath != null) { + sym.filename = new Path(cygpath.getFileName(filename)); + } else { + sym.filename = new Path(filename); + } + } + sym.startLine = addr2line.getLineNumber(sym.addr); + } catch (IOException e) { + } + } + list.add(sym); + } + } + } + +} diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/PEParser.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/PEParser.java new file mode 100644 index 00000000000..1043a4a21e9 --- /dev/null +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/PEParser.java @@ -0,0 +1,81 @@ +/********************************************************************** + * Copyright (c) 2002,2003 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * QNX Software Systems - Initial API and implementation +***********************************************************************/ + +package org.eclipse.cdt.utils.coff.parser; + +import java.io.IOException; + +import org.eclipse.cdt.core.AbstractCExtension; +import org.eclipse.cdt.core.IBinaryParser; +import org.eclipse.cdt.utils.coff.PE; +import org.eclipse.cdt.utils.coff.PEArchive; +import org.eclipse.cdt.utils.coff.PE.Attribute; +import org.eclipse.core.runtime.IPath; + +/** + */ +public class PEParser extends AbstractCExtension implements IBinaryParser { + + /** + * @see org.eclipse.cdt.core.model.IBinaryParser#getBinary(IFile) + */ + public IBinaryFile getBinary(IPath path) throws IOException { + if (path == null) { + throw new IOException("path is null"); + } + + BinaryFile binary = null; + try { + PE.Attribute attribute = PE.getAttributes(path.toOSString()); + if (attribute != null) { + switch (attribute.getType()) { + case Attribute.PE_TYPE_EXE : + binary = new BinaryExecutable(path); + break; + + case Attribute.PE_TYPE_SHLIB : + binary = new BinaryShared(path); + break; + + case Attribute.PE_TYPE_OBJ : + binary = new BinaryObject(path); + break; + + case Attribute.PE_TYPE_CORE : + BinaryObject obj = new BinaryObject(path); + obj.setType(IBinaryFile.CORE); + binary = obj; + break; + } + } + } catch (IOException e) { + // Is it an Archive? + binary = new BinaryArchive(path); + } + + return binary; + } + + /** + * @see org.eclipse.cdt.core.model.IBinaryParser#getFormat() + */ + public String getFormat() { + return "PE"; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.IBinaryParser#isBinary(byte[], org.eclipse.core.runtime.IPath) + */ + public boolean isBinary(byte[] array, IPath path) { + return PE.isExeHeader(array) || PEArchive.isARHeader(array); + } + +} diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/Symbol.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/Symbol.java new file mode 100644 index 00000000000..e0535a68416 --- /dev/null +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/coff/parser/Symbol.java @@ -0,0 +1,110 @@ +/********************************************************************** + * Copyright (c) 2002,2003 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * QNX Software Systems - Initial API and implementation +***********************************************************************/ +package org.eclipse.cdt.utils.coff.parser; + +import java.io.IOException; + +import org.eclipse.cdt.core.IBinaryParser.ISymbol; +import org.eclipse.cdt.utils.Addr2line; +import org.eclipse.core.runtime.IPath; + +public class Symbol implements ISymbol { + + BinaryObject binary; + + public IPath filename; + public int startLine; + public int endLine; + public long addr; + public String name; + public int type; + + public Symbol(BinaryObject bin) { + binary = bin; + } + /** + * @see org.eclipse.cdt.core.model.IBinaryParser.ISymbol#getFilename() + */ + public IPath getFilename() { + return filename; + } + + + /** + * @see org.eclipse.cdt.core.model.IBinaryParser.ISymbol#getName() + */ + public String getName() { + return name; + } + + /** + * @see org.eclipse.cdt.core.model.IBinaryParser.ISymbol#getType() + */ + public int getType() { + return type; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.IBinaryParser.ISymbol#getAdress() + */ + public long getAddress() { + return addr; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.IBinaryParser.ISymbol#getEndLine() + */ + public int getEndLine() { + return endLine; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.IBinaryParser.ISymbol#getStartLine() + */ + public int getStartLine() { + return startLine; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.IBinaryParser.ISymbol#getLineNumber(long) + */ + public int getLineNumber(long offset) { + int line = -1; + try { + Addr2line addr2line = binary.getAddr2Line(); + if (addr2line != null) { + line = addr2line.getLineNumber(addr + offset); + addr2line.dispose(); + } + } catch (IOException e) { + } + return line; + } + + /* (non-Javadoc) + * @see java.lang.Comparable#compareTo(java.lang.Object) + */ + public int compareTo(Object obj) { + long thisVal = 0; + long anotherVal = 0; + if (obj instanceof Symbol) { + Symbol sym = (Symbol) obj; + thisVal = this.addr; + anotherVal = sym.addr; + } else if (obj instanceof Long) { + Long val = (Long) obj; + anotherVal = val.longValue(); + thisVal = (long) this.addr; + } + return (thisVal < anotherVal ? -1 : (thisVal == anotherVal ? 0 : 1)); + } + +} diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/elf/parser/ElfParser.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/elf/parser/ElfParser.java new file mode 100644 index 00000000000..b3c4679ab65 --- /dev/null +++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/elf/parser/ElfParser.java @@ -0,0 +1,78 @@ +/********************************************************************** + * Copyright (c) 2002,2003 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * QNX Software Systems - Initial API and implementation +***********************************************************************/ +package org.eclipse.cdt.utils.elf.parser; + +import java.io.IOException; + +import org.eclipse.cdt.core.AbstractCExtension; +import org.eclipse.cdt.core.IBinaryParser; +import org.eclipse.cdt.utils.elf.AR; +import org.eclipse.cdt.utils.elf.Elf; +import org.eclipse.cdt.utils.elf.Elf.Attribute; +import org.eclipse.core.runtime.IPath; + +/** + */ +public class ElfParser extends AbstractCExtension implements IBinaryParser { + + /** + * @see org.eclipse.cdt.core.model.IBinaryParser#getBinary(IPath) + */ + public IBinaryFile getBinary(IPath path) throws IOException { + if (path == null) { + throw new IOException("path is null"); + } + + BinaryFile binary = null; + try { + Elf.Attribute attribute = Elf.getAttributes(path.toOSString()); + if (attribute != null) { + switch (attribute.getType()) { + case Attribute.ELF_TYPE_EXE : + binary = new BinaryExecutable(path); + break; + + case Attribute.ELF_TYPE_SHLIB : + binary = new BinaryShared(path); + break; + + case Attribute.ELF_TYPE_OBJ : + binary = new BinaryObject(path); + break; + + case Attribute.ELF_TYPE_CORE : + BinaryObject obj = new BinaryObject(path); + obj.setType(IBinaryFile.CORE); + binary = obj; + break; + } + } + } catch (IOException e) { + binary = new BinaryArchive(path); + } + return binary; + } + + /** + * @see org.eclipse.cdt.core.model.IBinaryParser#getFormat() + */ + public String getFormat() { + return "ELF"; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.IBinaryParser#isBinary(byte[], org.eclipse.core.runtime.IPath) + */ + public boolean isBinary(byte[] array, IPath path) { + return Elf.isElfHeader(array) || AR.isARHeader(array); + } + +} diff --git a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/CBreakpointManager.java b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/CBreakpointManager.java new file mode 100644 index 00000000000..8a2a2801715 --- /dev/null +++ b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/CBreakpointManager.java @@ -0,0 +1,739 @@ +/* + *(c) Copyright QNX Software Systems Ltd. 2002. + * All Rights Reserved. + * + */ + +package org.eclipse.cdt.debug.internal.core; + +import java.util.HashMap; +import java.util.Set; + +import org.eclipse.cdt.debug.core.CDebugCorePlugin; +import org.eclipse.cdt.debug.core.CDebugModel; +import org.eclipse.cdt.debug.core.CDebugUtils; +import org.eclipse.cdt.debug.core.ICBreakpointManager; +import org.eclipse.cdt.debug.core.cdi.CDIException; +import org.eclipse.cdt.debug.core.cdi.ICDIBreakpointManager; +import org.eclipse.cdt.debug.core.cdi.ICDICondition; +import org.eclipse.cdt.debug.core.cdi.ICDILocation; +import org.eclipse.cdt.debug.core.cdi.event.ICDIChangedEvent; +import org.eclipse.cdt.debug.core.cdi.event.ICDICreatedEvent; +import org.eclipse.cdt.debug.core.cdi.event.ICDIDestroyedEvent; +import org.eclipse.cdt.debug.core.cdi.event.ICDIEvent; +import org.eclipse.cdt.debug.core.cdi.event.ICDIEventListener; +import org.eclipse.cdt.debug.core.cdi.model.ICDIBreakpoint; +import org.eclipse.cdt.debug.core.cdi.model.ICDILocationBreakpoint; +import org.eclipse.cdt.debug.core.cdi.model.ICDIObject; +import org.eclipse.cdt.debug.core.cdi.model.ICDIWatchpoint; +import org.eclipse.cdt.debug.core.model.ICAddressBreakpoint; +import org.eclipse.cdt.debug.core.model.ICBreakpoint; +import org.eclipse.cdt.debug.core.model.ICDebugTarget; +import org.eclipse.cdt.debug.core.model.ICFunctionBreakpoint; +import org.eclipse.cdt.debug.core.model.ICLineBreakpoint; +import org.eclipse.cdt.debug.core.model.ICWatchpoint; +import org.eclipse.cdt.debug.core.sourcelookup.ICSourceLocator; +import org.eclipse.cdt.debug.internal.core.breakpoints.CBreakpoint; +import org.eclipse.cdt.debug.internal.core.model.CDebugTarget; +import org.eclipse.core.resources.IFile; +import org.eclipse.core.resources.IMarkerDelta; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.debug.core.DebugException; +import org.eclipse.debug.core.model.IBreakpoint; +import org.eclipse.debug.core.model.IDebugTarget; +import org.eclipse.debug.core.model.ISourceLocator; + +/** + * Enter type comment. + * + * @since Nov 3, 2003 + */ +public class CBreakpointManager implements ICBreakpointManager, ICDIEventListener, IAdaptable +{ + public class BreakpointMap + { + /** + * Maps CBreakpoints to CDI breakpoints. + */ + private HashMap fCBreakpoints; + + /** + * Maps CDI breakpoints to CBreakpoints. + */ + private HashMap fCDIBreakpoints; + + protected BreakpointMap() + { + fCBreakpoints = new HashMap( 10 ); + fCDIBreakpoints = new HashMap( 10 ); + } + + protected synchronized void put( ICBreakpoint breakpoint, ICDIBreakpoint cdiBreakpoint ) + { + fCBreakpoints.put( breakpoint, cdiBreakpoint ); + fCDIBreakpoints.put( cdiBreakpoint, breakpoint ); + } + + protected synchronized ICDIBreakpoint getCDIBreakpoint( ICBreakpoint breakpoint ) + { + return (ICDIBreakpoint)fCBreakpoints.get( breakpoint ); + } + + protected synchronized ICBreakpoint getCBreakpoint( ICDIBreakpoint cdiBreakpoint ) + { + return (ICBreakpoint)fCDIBreakpoints.get( cdiBreakpoint ); + } + + protected void removeCBreakpoint( ICBreakpoint breakpoint ) + { + if ( breakpoint != null ) + { + ICDIBreakpoint cdiBreakpoint = (ICDIBreakpoint)fCBreakpoints.remove( breakpoint ); + if ( cdiBreakpoint != null ) + fCDIBreakpoints.remove( cdiBreakpoint ); + } + } + + protected void removeCDIBreakpoint( ICBreakpoint breakpoin, ICDIBreakpoint cdiBreakpoint ) + { + if ( cdiBreakpoint != null ) + { + ICBreakpoint breakpoint = (ICBreakpoint)fCDIBreakpoints.remove( cdiBreakpoint ); + if ( breakpoint != null ) + fCBreakpoints.remove( breakpoint ); + } + } + + protected ICBreakpoint[] getAllCBreakpoints() + { + Set set = fCBreakpoints.keySet(); + return (ICBreakpoint[])set.toArray( new ICBreakpoint[set.size()]); + } + + protected ICDIBreakpoint[] getAllCDIBreakpoints() + { + Set set = fCDIBreakpoints.keySet(); + return (ICDIBreakpoint[])set.toArray( new ICDIBreakpoint[set.size()]); + } + + protected void dispose() + { + fCBreakpoints.clear(); + fCDIBreakpoints.clear(); + } + } + + private CDebugTarget fDebugTarget; + + private BreakpointMap fMap; + + public CBreakpointManager( CDebugTarget target ) + { + super(); + setDebugTarget( target ); + fMap = new BreakpointMap(); + getDebugTarget().getCDISession().getEventManager().addEventListener( this ); + } + + /* (non-Javadoc) + * @see org.eclipse.core.runtime.IAdaptable#getAdapter(java.lang.Class) + */ + public Object getAdapter( Class adapter ) + { + if ( CBreakpointManager.class.equals( adapter ) ) + return this; + if ( CDebugTarget.class.equals( adapter ) ) + return getDebugTarget(); + if ( ICDebugTarget.class.equals( adapter ) ) + return getDebugTarget(); + if ( IDebugTarget.class.equals( adapter ) ) + return getDebugTarget(); + return null; + } + + public CDebugTarget getDebugTarget() + { + return fDebugTarget; + } + + private void setDebugTarget( CDebugTarget target ) + { + fDebugTarget = target; + } + + protected ICDIBreakpointManager getCDIBreakpointManager() + { + return getDebugTarget().getCDISession().getBreakpointManager(); + } + + protected ICSourceLocator getCSourceLocator() + { + ISourceLocator locator = getDebugTarget().getLaunch().getSourceLocator(); + if ( locator instanceof IAdaptable ) + return (ICSourceLocator)((IAdaptable)locator).getAdapter( ICSourceLocator.class ); + return null; + } + + public void dispose() + { + getDebugTarget().getCDISession().getEventManager().removeEventListener( this ); + removeAllBreakpoints(); + getBreakpointMap().dispose(); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.debug.core.cdi.event.ICDIEventListener#handleDebugEvent(org.eclipse.cdt.debug.core.cdi.event.ICDIEvent) + */ + public void handleDebugEvent( ICDIEvent event ) + { + ICDIObject source = event.getSource(); + if ( source != null && source.getTarget().equals( getDebugTarget().getCDITarget() ) ) + { + if ( event instanceof ICDICreatedEvent ) + { + if ( source instanceof ICDIBreakpoint ) + handleBreakpointCreatedEvent( (ICDIBreakpoint)source ); + } + else if ( event instanceof ICDIDestroyedEvent ) + { + if ( source instanceof ICDIBreakpoint ) + handleBreakpointDestroyedEvent( (ICDIBreakpoint)source ); + } + else if ( event instanceof ICDIChangedEvent ) + { + if ( source instanceof ICDIBreakpoint ) + handleBreakpointChangedEvent( (ICDIBreakpoint)source ); + } + } + } + + public boolean isTargetBreakpoint( ICBreakpoint breakpoint ) + { + IResource resource = breakpoint.getMarker().getResource(); + if ( breakpoint instanceof ICAddressBreakpoint ) + return supportsAddressBreakpoint( (ICAddressBreakpoint)breakpoint ); + if ( breakpoint instanceof ICLineBreakpoint ) + { + ICSourceLocator sl = getSourceLocator(); + if ( sl != null ) + return sl.contains( resource ); + } + else + { + IProject project = resource.getProject(); + if ( project != null && project.exists() ) + { + ICSourceLocator sl = getSourceLocator(); + if ( sl != null ) + return sl.contains( project ); + else + { + if ( project.equals( getExecFile().getProject() ) ) + return true; + return CDebugUtils.isReferencedProject( getExecFile().getProject(), project ); + } + } + } + return true; + } + + public boolean isCDIRegistered( ICBreakpoint breakpoint ) + { + return ( getBreakpointMap().getCDIBreakpoint( breakpoint ) != null ); + } + + public boolean supportsAddressBreakpoint( ICAddressBreakpoint breakpoint ) + { + return ( getExecFile() != null && + getExecFile().getLocation().toOSString().equals( breakpoint.getMarker().getResource().getLocation().toOSString() ) ); + } + + public IFile getCDIBreakpointFile( ICDIBreakpoint cdiBreakpoint ) + { + IBreakpoint breakpoint = getBreakpointMap().getCBreakpoint( cdiBreakpoint ); + if ( breakpoint instanceof ICLineBreakpoint && !(breakpoint instanceof ICAddressBreakpoint) ) + { + IResource resource = ((ICLineBreakpoint)breakpoint).getMarker().getResource(); + if ( resource instanceof IFile ) + return (IFile)resource; + } + return null; + } + + public ICBreakpoint getBreakpoint( ICDIBreakpoint cdiBreakpoint ) + { + return getBreakpointMap().getCBreakpoint( cdiBreakpoint ); + } + + public long getBreakpointAddress( ICBreakpoint breakpoint ) + { + if ( breakpoint != null ) + { + ICDIBreakpoint cdiBreakpoint = getBreakpointMap().getCDIBreakpoint( breakpoint ); + if ( cdiBreakpoint instanceof ICDILocationBreakpoint ) + { + try + { + ICDILocation location = ((ICDILocationBreakpoint)cdiBreakpoint).getLocation(); + if ( location != null ) + return location.getAddress(); + } + catch( CDIException e ) + { + } + } + } + return 0; + } + + public void setBreakpoint( final ICBreakpoint breakpoint ) throws DebugException + { + Runnable runnable = new Runnable() + { + public void run() + { + try + { + doSetBreakpoint( breakpoint ); + } + catch( DebugException e ) + { + } + } + }; + CDebugCorePlugin.getDefault().asyncExec( runnable ); + } + + protected void doSetBreakpoint( ICBreakpoint breakpoint ) throws DebugException + { + try + { + ICDIBreakpoint cdiBreakpoint = getBreakpointMap().getCDIBreakpoint( breakpoint ); + if ( cdiBreakpoint == null ) + { + if ( breakpoint instanceof ICFunctionBreakpoint ) + cdiBreakpoint = setFunctionBreakpoint( (ICFunctionBreakpoint)breakpoint ); + else if ( breakpoint instanceof ICAddressBreakpoint ) + cdiBreakpoint = setAddressBreakpoint( (ICAddressBreakpoint)breakpoint ); + else if ( breakpoint instanceof ICLineBreakpoint ) + cdiBreakpoint = setLineBreakpoint( (ICLineBreakpoint)breakpoint ); + else if ( breakpoint instanceof ICWatchpoint ) + cdiBreakpoint = setWatchpoint( (ICWatchpoint)breakpoint ); + } + if ( cdiBreakpoint == null ) + return; + if ( !breakpoint.isEnabled() ) + cdiBreakpoint.setEnabled( false ); + setBreakpointCondition( breakpoint ); + } + catch( CoreException e ) + { + requestFailed( "Set breakpoint failed. Reason: " + e.getMessage(), e ); + } + catch( NumberFormatException e ) + { + requestFailed( "Set breakpoint failed. Reason: " + e.getMessage(), e ); + } + catch( CDIException e ) + { + targetRequestFailed( "Set breakpoint failed. Reason: " + e.getMessage(), e ); + } + } + + public void removeBreakpoint( final ICBreakpoint breakpoint ) throws DebugException + { + Runnable runnable = new Runnable() + { + public void run() + { + try + { + doRemoveBreakpoint( breakpoint ); + } + catch( DebugException e ) + { + } + } + }; + CDebugCorePlugin.getDefault().asyncExec( runnable ); + } + + protected void doRemoveBreakpoint( ICBreakpoint breakpoint ) throws DebugException + { + ICDIBreakpoint cdiBreakpoint = getBreakpointMap().getCDIBreakpoint( breakpoint ); + if ( cdiBreakpoint != null ) + { + ICDIBreakpointManager bm = getCDIBreakpointManager(); + try + { + bm.deleteBreakpoints( new ICDIBreakpoint[] { cdiBreakpoint } ); + } + catch( CDIException e ) + { + targetRequestFailed( "Delete breakpoint failed. Reason: " + e.getMessage(), e ); + } + } + } + + public void changeBreakpointProperties( final ICBreakpoint breakpoint, final IMarkerDelta delta ) throws DebugException + { + Runnable runnable = new Runnable() + { + public void run() + { + try + { + doChangeBreakpointProperties( breakpoint, delta ); + } + catch( DebugException e ) + { + } + } + }; + CDebugCorePlugin.getDefault().asyncExec( runnable ); + } + + protected void doChangeBreakpointProperties( ICBreakpoint breakpoint, IMarkerDelta delta ) throws DebugException + { + ICDIBreakpoint cdiBreakpoint = getBreakpointMap().getCDIBreakpoint( breakpoint ); + if ( cdiBreakpoint == null ) + return; + ICDIBreakpointManager bm = getCDIBreakpointManager(); + try + { + boolean enabled = breakpoint.isEnabled(); + boolean oldEnabled = delta.getAttribute( IBreakpoint.ENABLED, true ); + int ignoreCount = breakpoint.getIgnoreCount(); + int oldIgnoreCount = delta.getAttribute( ICBreakpoint.IGNORE_COUNT, 0 ); + String condition = breakpoint.getCondition(); + String oldCondition = delta.getAttribute( ICBreakpoint.CONDITION, "" ); + if ( enabled != oldEnabled ) + { + cdiBreakpoint.setEnabled( enabled ); + } + if ( ignoreCount != oldIgnoreCount || !condition.equals( oldCondition ) ) + { + ICDICondition cdiCondition = bm.createCondition( ignoreCount, condition ); + cdiBreakpoint.setCondition( cdiCondition ); + } + } + catch( CoreException e ) + { + requestFailed( "Change breakpoint properties failed. Reason: " + e.getMessage(), e ); + } + catch( CDIException e ) + { + targetRequestFailed( "Change breakpoint properties failed. Reason: " + e.getMessage(), e ); + } + } + + private void handleBreakpointCreatedEvent( final ICDIBreakpoint cdiBreakpoint ) + { + Runnable runnable = new Runnable() + { + public void run() + { + if ( cdiBreakpoint instanceof ICDILocationBreakpoint ) + doHandleLocationBreakpointCreatedEvent( (ICDILocationBreakpoint)cdiBreakpoint ); + else if ( cdiBreakpoint instanceof ICDIWatchpoint ) + doHandleWatchpointCreatedEvent( (ICDIWatchpoint)cdiBreakpoint ); + } + }; + CDebugCorePlugin.getDefault().asyncExec( runnable ); + } + + protected void doHandleLocationBreakpointCreatedEvent( ICDILocationBreakpoint cdiBreakpoint ) + { + if ( cdiBreakpoint.isTemporary() ) + return; + ICBreakpoint breakpoint = getBreakpointMap().getCBreakpoint( cdiBreakpoint ); + if ( breakpoint == null ) + { + try + { + if ( cdiBreakpoint.getLocation().getFile() != null && cdiBreakpoint.getLocation().getFile().length() > 0 ) + { + ICSourceLocator locator = getSourceLocator(); + if ( locator != null ) + { + Object sourceElement = locator.findSourceElement( cdiBreakpoint.getLocation().getFile() ); + if ( sourceElement != null && sourceElement instanceof IFile ) + { + breakpoint = createLineBreakpoint( (IFile)sourceElement, cdiBreakpoint ); + } + else if ( cdiBreakpoint.getLocation().getAddress() > 0 ) + { + breakpoint = createAddressBreakpoint( cdiBreakpoint ); + } + } + } + else if ( cdiBreakpoint.getLocation().getAddress() > 0 ) + { + breakpoint = createAddressBreakpoint( cdiBreakpoint ); + } + } + catch( CDIException e ) + { + } + catch( CoreException e ) + { + } + } + if ( breakpoint != null ) + { + try + { + ((CBreakpoint)breakpoint).incrementInstallCount(); + } + catch( CoreException e ) + { + CDebugCorePlugin.log( e.getStatus() ); + } + } + } + + protected void doHandleWatchpointCreatedEvent( ICDIWatchpoint cdiWatchpoint ) + { + ICBreakpoint breakpoint = getBreakpointMap().getCBreakpoint( cdiWatchpoint ); + if ( breakpoint == null ) + { + try + { + breakpoint = CDebugModel.createWatchpoint( getExecFile().getProject(), + cdiWatchpoint.isWriteType(), + cdiWatchpoint.isReadType(), + cdiWatchpoint.getWatchExpression(), + cdiWatchpoint.isEnabled(), + cdiWatchpoint.getCondition().getIgnoreCount(), + cdiWatchpoint.getCondition().getExpression(), + false ); + getBreakpointMap().put( breakpoint, cdiWatchpoint ); + ((CBreakpoint)breakpoint).register( true ); + } + catch( CDIException e ) + { + } + catch( CoreException e ) + { + } + } + if ( breakpoint != null ) + { + try + { + ((CBreakpoint)breakpoint).incrementInstallCount(); + } + catch( CoreException e ) + { + CDebugCorePlugin.log( e.getStatus() ); + } + } + } + + private void handleBreakpointDestroyedEvent( final ICDIBreakpoint cdiBreakpoint ) + { + Runnable runnable = new Runnable() + { + public void run() + { + doHandleBreakpointDestroyedEvent( cdiBreakpoint ); + } + + }; + CDebugCorePlugin.getDefault().asyncExec( runnable ); + } + + protected void doHandleBreakpointDestroyedEvent( ICDIBreakpoint cdiBreakpoint ) + { + ICBreakpoint breakpoint = getBreakpointMap().getCBreakpoint( cdiBreakpoint ); + if ( breakpoint != null ) + { + getBreakpointMap().removeCDIBreakpoint( breakpoint, cdiBreakpoint ); + try + { + ((CBreakpoint)breakpoint).decrementInstallCount(); + } + catch( CoreException e ) + { + CDebugCorePlugin.log( e.getStatus() ); + } + } + } + + private void handleBreakpointChangedEvent( final ICDIBreakpoint cdiBreakpoint ) + { + Runnable runnable = new Runnable() + { + public void run() + { + doHandleBreakpointChangedEvent( cdiBreakpoint ); + } + + }; + CDebugCorePlugin.getDefault().asyncExec( runnable ); + } + + protected void doHandleBreakpointChangedEvent( ICDIBreakpoint cdiBreakpoint ) + { + ICBreakpoint breakpoint = getBreakpointMap().getCBreakpoint( cdiBreakpoint ); + if ( breakpoint != null ) + { + try + { + breakpoint.setEnabled( cdiBreakpoint.isEnabled() ); + breakpoint.setIgnoreCount( cdiBreakpoint.getCondition().getIgnoreCount() ); + breakpoint.setCondition( cdiBreakpoint.getCondition().getExpression() ); + } + catch( CDIException e ) + { + } + catch( CoreException e ) + { + } + } + } + + private void removeAllBreakpoints() + { + ICDIBreakpoint[] cdiBreakpoints = getBreakpointMap().getAllCDIBreakpoints(); + ICDIBreakpointManager bm = getCDIBreakpointManager(); + if ( cdiBreakpoints.length > 0 ) + { + try + { + bm.deleteBreakpoints( cdiBreakpoints ); + } + catch( CDIException e ) + { + CDebugCorePlugin.log( e.getMessage() ); + } + ICBreakpoint[] breakpoints = getBreakpointMap().getAllCBreakpoints(); + for ( int i = 0; i < breakpoints.length; ++i ) + { + try + { + ((CBreakpoint)breakpoints[i]).decrementInstallCount(); + } + catch( CoreException e ) + { + CDebugCorePlugin.log( e.getMessage() ); + } + } + } + } + + private synchronized ICDIBreakpoint setFunctionBreakpoint( ICFunctionBreakpoint breakpoint ) throws CDIException, CoreException + { + ICDIBreakpointManager bm = getCDIBreakpointManager(); + String function = breakpoint.getFunction(); + String fileName = ( function != null && function.indexOf( "::" ) == -1 ) ? breakpoint.getFileName() : null; + ICDILocation location = bm.createLocation( fileName, function, -1 ); + ICDIBreakpoint cdiBreakpoint = bm.setLocationBreakpoint( ICDIBreakpoint.REGULAR, location, null, null, true ); + getBreakpointMap().put( breakpoint, cdiBreakpoint ); + return cdiBreakpoint; + } + + private synchronized ICDIBreakpoint setAddressBreakpoint( ICAddressBreakpoint breakpoint ) throws CDIException, CoreException, NumberFormatException + { + ICDIBreakpointManager bm = getCDIBreakpointManager(); + ICDILocation location = bm.createLocation( Long.parseLong( breakpoint.getAddress() ) ); + ICDIBreakpoint cdiBreakpoint = bm.setLocationBreakpoint( ICDIBreakpoint.REGULAR, location, null, null, true ); + getBreakpointMap().put( breakpoint, cdiBreakpoint ); + return cdiBreakpoint; + } + + private synchronized ICDIBreakpoint setLineBreakpoint( ICLineBreakpoint breakpoint ) throws CDIException, CoreException + { + ICDIBreakpointManager bm = getCDIBreakpointManager(); + ICDILocation location = bm.createLocation( breakpoint.getMarker().getResource().getLocation().lastSegment(), null, breakpoint.getLineNumber() ); + ICDIBreakpoint cdiBreakpoint = bm.setLocationBreakpoint( ICDIBreakpoint.REGULAR, location, null, null, true ); + getBreakpointMap().put( breakpoint, cdiBreakpoint ); + return cdiBreakpoint; + } + + private synchronized ICDIBreakpoint setWatchpoint( ICWatchpoint watchpoint ) throws CDIException, CoreException + { + ICDIBreakpointManager bm = getCDIBreakpointManager(); + int accessType = 0; + accessType |= ( watchpoint.isWriteType() ) ? ICDIWatchpoint.WRITE : 0; + accessType |= ( watchpoint.isReadType() ) ? ICDIWatchpoint.READ : 0; + String expression = watchpoint.getExpression(); + ICDIWatchpoint cdiWatchpoint = bm.setWatchpoint( ICDIBreakpoint.REGULAR, accessType, expression, null ); + getBreakpointMap().put( watchpoint, cdiWatchpoint ); + return cdiWatchpoint; + } + + private void setBreakpointCondition( ICBreakpoint breakpoint ) throws CoreException, CDIException + { + ICDIBreakpoint cdiBreakpoint = getBreakpointMap().getCDIBreakpoint( breakpoint ); + ICDIBreakpointManager bm = getCDIBreakpointManager(); + ICDICondition condition = bm.createCondition( breakpoint.getIgnoreCount(), breakpoint.getCondition() ); + cdiBreakpoint.setCondition( condition ); + } + + private BreakpointMap getBreakpointMap() + { + return fMap; + } + + protected void targetRequestFailed( String message, Throwable e ) throws DebugException + { + requestFailed0( message, e, DebugException.TARGET_REQUEST_FAILED ); + } + + protected void requestFailed( String message, Throwable e ) throws DebugException + { + requestFailed0( message, e, DebugException.REQUEST_FAILED ); + } + + private void requestFailed0( String message, Throwable e, int code ) throws DebugException + { + throw new DebugException( new Status( IStatus.ERROR, + CDebugModel.getPluginIdentifier(), + code, + message, + e ) ); + } + + private ICLineBreakpoint createLineBreakpoint( IFile file, ICDILocationBreakpoint cdiBreakpoint ) throws CDIException, CoreException + { + ICLineBreakpoint breakpoint = CDebugModel.createLineBreakpoint( file, + cdiBreakpoint.getLocation().getLineNumber(), + cdiBreakpoint.isEnabled(), + cdiBreakpoint.getCondition().getIgnoreCount(), + cdiBreakpoint.getCondition().getExpression(), + false ); + getBreakpointMap().put( breakpoint, cdiBreakpoint ); + ((CBreakpoint)breakpoint).register( true ); + return breakpoint; + } + + private ICAddressBreakpoint createAddressBreakpoint( ICDILocationBreakpoint cdiBreakpoint ) throws CDIException, CoreException + { + ICAddressBreakpoint breakpoint = CDebugModel.createAddressBreakpoint( getExecFile(), + cdiBreakpoint.getLocation().getAddress(), + cdiBreakpoint.isEnabled(), + cdiBreakpoint.getCondition().getIgnoreCount(), + cdiBreakpoint.getCondition().getExpression(), + false ); + getBreakpointMap().put( breakpoint, cdiBreakpoint ); + ((CBreakpoint)breakpoint).register( true ); + return breakpoint; + } + + private ICSourceLocator getSourceLocator() + { + ISourceLocator locator = getDebugTarget().getLaunch().getSourceLocator(); + return ( locator instanceof IAdaptable ) ? (ICSourceLocator)((IAdaptable)locator).getAdapter( ICSourceLocator.class ) : null; + } + + private IFile getExecFile() + { + return getDebugTarget().getExecFile(); + } +} diff --git a/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/sourcelookup/SourceUtils.java b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/sourcelookup/SourceUtils.java new file mode 100644 index 00000000000..2906204a3ca --- /dev/null +++ b/debug/org.eclipse.cdt.debug.core/src/org/eclipse/cdt/debug/internal/core/sourcelookup/SourceUtils.java @@ -0,0 +1,181 @@ +/* + *(c) Copyright QNX Software Systems Ltd. 2002. + * All Rights Reserved. + * + */ + +package org.eclipse.cdt.debug.internal.core.sourcelookup; + +import java.io.IOException; +import java.io.StringReader; +import java.text.MessageFormat; +import java.util.LinkedList; +import java.util.List; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; + +import org.apache.xerces.dom.DocumentImpl; +import org.eclipse.cdt.debug.core.CDebugCorePlugin; +import org.eclipse.cdt.debug.core.CDebugUtils; +import org.eclipse.cdt.debug.core.sourcelookup.ICSourceLocation; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; + +/** + * Enter type comment. + * + * @since Oct 22, 2003 + */ +public class SourceUtils +{ + private static final String NAME_COMMON_SOURCE_LOCATIONS = "commonSourceLocations"; + private static final String NAME_SOURCE_LOCATION = "sourceLocation"; + private static final String ATTR_CLASS = "class"; + private static final String ATTR_MEMENTO = "memento"; + + public static String getCommonSourceLocationsMemento( ICSourceLocation[] locations ) + { + Document doc = new DocumentImpl(); + Element node = doc.createElement( NAME_COMMON_SOURCE_LOCATIONS ); + doc.appendChild( node ); + + saveSourceLocations( doc, node, locations ); + try + { + return CDebugUtils.serializeDocument( doc, " " ); + } + catch( IOException e ) + { + CDebugCorePlugin.log( new Status( IStatus.ERROR, CDebugCorePlugin.getUniqueIdentifier(), 0, "Error saving common source settings.", e ) ); + } + return null; + } + + private static void saveSourceLocations( Document doc, Element node, ICSourceLocation[] locations ) + { + for ( int i = 0; i < locations.length; i++ ) + { + Element child = doc.createElement( NAME_SOURCE_LOCATION ); + child.setAttribute( ATTR_CLASS, locations[i].getClass().getName() ); + try + { + child.setAttribute( ATTR_MEMENTO, locations[i].getMemento() ); + } + catch( CoreException e ) + { + CDebugCorePlugin.log( e ); + continue; + } + node.appendChild( child ); + } + } + + public static ICSourceLocation[] getCommonSourceLocationsFromMemento( String memento ) + { + ICSourceLocation[] result = new ICSourceLocation[0]; + if ( !isEmpty( memento ) ) + { + try + { + DocumentBuilder parser = DocumentBuilderFactory.newInstance().newDocumentBuilder(); + StringReader reader = new StringReader( memento ); + InputSource source = new InputSource( reader ); + Element root = parser.parse( source ).getDocumentElement(); + + if ( root.getNodeName().equalsIgnoreCase( NAME_COMMON_SOURCE_LOCATIONS ) ) + result = initializeSourceLocations( root ); + } + catch( ParserConfigurationException e ) + { + CDebugCorePlugin.log( new Status( IStatus.ERROR, CDebugCorePlugin.getUniqueIdentifier(), 0, "Error initializing common source settings.", e ) ); + } + catch( SAXException e ) + { + CDebugCorePlugin.log( new Status( IStatus.ERROR, CDebugCorePlugin.getUniqueIdentifier(), 0, "Error initializing common source settings.", e ) ); + } + catch( IOException e ) + { + CDebugCorePlugin.log( new Status( IStatus.ERROR, CDebugCorePlugin.getUniqueIdentifier(), 0, "Error initializing common source settings.", e ) ); + } + } + return result; + } + + public static ICSourceLocation[] initializeSourceLocations( Element root ) + { + List sourceLocations = new LinkedList(); + ClassLoader classLoader = CDebugCorePlugin.getDefault() .getDescriptor().getPluginClassLoader(); + + NodeList list = root.getChildNodes(); + int length = list.getLength(); + for ( int i = 0; i < length; ++i ) + { + Node node = list.item( i ); + short type = node.getNodeType(); + if ( type == Node.ELEMENT_NODE ) + { + Element entry = (Element)node; + if ( entry.getNodeName().equalsIgnoreCase( NAME_SOURCE_LOCATION ) ) + { + String className = entry.getAttribute( ATTR_CLASS ); + String data = entry.getAttribute( ATTR_MEMENTO ); + if ( className == null || className.trim().length() == 0 ) + { + CDebugCorePlugin.log( "Unable to restore common source locations - invalid format." ); + continue; + } + Class clazz = null; + try + { + clazz = classLoader.loadClass( className ); + } + catch( ClassNotFoundException e ) + { + CDebugCorePlugin.log( MessageFormat.format( "Unable to restore source location - class not found {0}", new String[] { className } ) ); + continue; + } + + ICSourceLocation location = null; + try + { + location = (ICSourceLocation)clazz.newInstance(); + } + catch( IllegalAccessException e ) + { + CDebugCorePlugin.log( "Unable to restore source location: " + e.getMessage() ); + continue; + } + catch( InstantiationException e ) + { + CDebugCorePlugin.log( "Unable to restore source location: " + e.getMessage() ); + continue; + } + try + { + location.initializeFrom( data ); + sourceLocations.add( location ); + } + catch( CoreException e ) + { + CDebugCorePlugin.log( "Unable to restore source location: " + e.getMessage() ); + } + } + } + } + return (ICSourceLocation[])sourceLocations.toArray( new ICSourceLocation[sourceLocations.size()] ); + } + + private static boolean isEmpty( String string ) + { + return ( string == null || string.trim().length() == 0 ); + } +}