/** * Copyright 2012 Tobias Gierke <tobias.gierke@code-sourcery.de> * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package de.codesourcery.jasm16.ide; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import org.apache.commons.lang.StringUtils; import org.apache.log4j.Logger; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.NodeList; import de.codesourcery.jasm16.Address; import de.codesourcery.jasm16.emulator.Breakpoint; import de.codesourcery.jasm16.emulator.OneShotBreakpoint; import de.codesourcery.jasm16.exceptions.ParseException; /** * Per-project debugger options. * * @author tobias.gierke@code-sourcery.de */ public class DebuggerOptions { public static final Logger LOG = Logger.getLogger(DebuggerOptions.class); private final Map<Address,Breakpoint> breakpoints=new HashMap<>(); public DebuggerOptions() { } public void reset() { breakpoints.clear(); } public void addBreakpoint(Breakpoint bp) { if (bp == null) { throw new IllegalArgumentException("bp must not be NULL"); } // one-shot BPs are for internal use only if ( !(bp instanceof OneShotBreakpoint) ) { this.breakpoints.put(bp.getAddress(),bp); } } public void deleteBreakpoint(Breakpoint bp) { if (bp == null) { throw new IllegalArgumentException("bp must not be NULL"); } // one-shot BPs are for internal use only if ( !(bp instanceof OneShotBreakpoint) ) { this.breakpoints.remove(bp.getAddress()); } } public void breakpointChanged(Breakpoint bp) { if (bp == null) { throw new IllegalArgumentException("bp must not be NULL"); } // one-shot BPs are for internal use only if ( !(bp instanceof OneShotBreakpoint) && this.breakpoints.containsKey( bp.getAddress() ) ) { this.breakpoints.put(bp.getAddress(),bp); } } public void saveDebuggerOptions(Element parentNode,Document doc) { Element root = doc.createElement("breakpoints"); parentNode.appendChild(root); for ( Breakpoint bp : breakpoints.values() ) { Element bpNode = doc.createElement("breakpoint"); root.appendChild( bpNode ); bpNode.setAttribute("enabled", bp.isEnabled() ? "true" : "false" ); bpNode.setAttribute( "address", Integer.toString( bp.getAddress().toWordAddress().getValue() ) ); if ( bp.hasCondition() ) { bpNode.setAttribute( "condition", bp.getCondition() ); } } } public void loadDebuggerOptions(Element parentNode) { reset(); NodeList list = parentNode.getElementsByTagName("breakpoints"); if ( list.getLength() == 1 ) { final NodeList children = list.item(0).getChildNodes(); final int len = children.getLength(); for ( int i = 0 ; i < len ; i++ ) { Element bp = (Element) children.item(i); final Address address = Address.wordAddress( Integer.parseInt( bp.getAttribute( "address" ) ) ); final Breakpoint newBp = new Breakpoint( address ); final String cond = bp.getAttribute("condition"); if ( StringUtils.isNotBlank( cond ) ) { try { newBp.setCondition( cond ); } catch (ParseException e) { LOG.error("populateFromXml(): Breakpoint at "+address+" has unparseable condition >"+cond+"<"); e.printStackTrace(); continue; } } newBp.setEnabled( "true".equalsIgnoreCase( bp.getAttribute("enabled") ) ); addBreakpoint( newBp ); } } } public List<Breakpoint> getBreakpoints() { return new ArrayList<>( this.breakpoints.values() ); } }