/*******************************************************************************
* Copyright (c) 2013 Ericsson AB and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Alvaro Sanchez-Leon (Ericsson AB) - Support for Step into selection (bug 244865)
*******************************************************************************/
package org.eclipse.cdt.dsf.gdb.internal.service.control;
import org.eclipse.cdt.dsf.gdb.IGdbDebugConstants;
import org.eclipse.cdt.dsf.gdb.internal.GdbPlugin;
import org.eclipse.cdt.dsf.gdb.internal.Messages;
import org.eclipse.cdt.dsf.mi.service.command.output.MIArg;
import org.eclipse.cdt.dsf.mi.service.command.output.MIFrame;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.IStatusHandler;
import org.eclipse.osgi.util.NLS;
public class StepIntoSelectionUtils {
public static final String cppSep = "::"; //$NON-NLS-1$
public static boolean sameSignature(MIFrame currentFrame, StepIntoSelectionActiveOperation stepOperation) {
String currentFunctionName = currentFrame.getFunction();
String targetFunctionName = stepOperation.getTargetFunctionSignature();
if (!sameNumberOfArgumets(currentFrame, stepOperation)) {
return false;
}
// Simplified validation
if (currentFunctionName.equals(targetFunctionName)) {
return true;
}
// Check if the last segment of the function name match
String[] currentFunctTokens = currentFunctionName.split(cppSep);
String[] targetFunctTokens = targetFunctionName.split(cppSep);
if (currentFunctTokens.length > 1) {
currentFunctionName = currentFunctTokens[currentFunctTokens.length - 1];
}
if (targetFunctTokens.length > 1) {
targetFunctionName = targetFunctTokens[targetFunctTokens.length - 1];
}
if (currentFunctionName.equals(targetFunctionName)) {
// Function name matches and parent name does not. One of the parents may be a super class
// Simple enough for initial implementation.
return true;
}
// TODO: A more detailed check can be implemented in order to cover for parameter types return types, etc..
// This with the intention to avoid early stops, however this implementation need to be tested extensively in
// order to avoid missing the target due to unexpected formatting mismatch between declaration and GDB representation.
return false;
}
private static boolean sameNumberOfArgumets(MIFrame currentFrame, StepIntoSelectionActiveOperation stepOperation) {
int argSizeAdjustment = 0;
MIArg[] args = currentFrame.getArgs();
if (args.length > 0) {
// GDB may add the argument "this" e.g. in c++ programs
if (args[0].getName().equals("this")) { //$NON-NLS-1$
argSizeAdjustment = 1;
}
}
return ((currentFrame.getArgs().length - argSizeAdjustment) == stepOperation.getTargetFunctionDeclaration().getNumberOfParameters());
}
public static void missedSelectedTarget(StepIntoSelectionActiveOperation stepOperation) {
final String functionName = stepOperation.getTargetFunctionDeclaration().getElementName();
IStatus status = new Status(IStatus.INFO, GdbPlugin.PLUGIN_ID, IGdbDebugConstants.STATUS_HANDLER_CODE, Messages.StepIntoSelection + "\n" + NLS.bind(Messages.StepIntoSelection_Execution_did_not_enter_function, functionName), null); //$NON-NLS-1$
IStatusHandler statusHandler = DebugPlugin.getDefault().getStatusHandler(status);
if (statusHandler != null) {
try {
statusHandler.handleStatus(status, null);
} catch (CoreException ex) {
GdbPlugin.getDefault().getLog().log(ex.getStatus());
}
}
}
}