/* * Copyright (C) 2017 Daniel Dietsch (dietsch@informatik.uni-freiburg.de) * Copyright (C) 2017 University of Freiburg * * This file is part of the Ultimate Delta Debugger plug-in. * * The Ultimate Delta Debugger plug-in is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * The Ultimate Delta Debugger plug-in is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with the Ultimate Delta Debugger plug-in. If not, see . * * Additional permission under GNU GPL version 3 section 7: * If you modify the Ultimate Delta Debugger plug-in, or any covered work, by linking * or combining it with Eclipse RCP (or a modified version of Eclipse RCP), * containing parts covered by the terms of the Eclipse Public License, the * licensors of the Ultimate Delta Debugger plug-in grant you additional permission * to convey the resulting work. */ package de.uni_freiburg.informatik.ultimate.deltadebugger.externaltools; import java.nio.file.Paths; import java.util.ArrayList; import java.util.List; import java.util.function.Predicate; import java.util.regex.Pattern; import de.uni_freiburg.informatik.ultimate.core.model.preferences.IPreferenceProvider; import de.uni_freiburg.informatik.ultimate.core.model.services.IUltimateServiceProvider; import de.uni_freiburg.informatik.ultimate.deltadebugger.Activator; import de.uni_freiburg.informatik.ultimate.deltadebugger.preferences.DeltaDebuggerPreferences; import de.uni_freiburg.informatik.ultimate.util.CoreUtil; /** * * @author Daniel Dietsch (dietsch@informatik.uni-freiburg.de) * */ public class ExternalToolCPAChecker extends ExternalTool { private String mCpaCheckerHome; private final IPreferenceProvider mPrefProvider; public ExternalToolCPAChecker(final IUltimateServiceProvider services) { super(services); mPrefProvider = mServices.getPreferenceProvider(Activator.PLUGIN_ID); } @Override protected ExternalToolResult interpretResult(final String output, final String error, final int returnCode, final boolean killed) { if (killed) { logOutput(output, error, returnCode, killed); return ExternalToolResult.TIMEOUT; } final Predicate isInteresting = getOutputPredicate(DeltaDebuggerPreferences.LABEL_EXTERNAL_TOOL_CPACHECKER_OUTPUT_REGEX_INTERESTING); final Predicate isOOM = getOutputPredicate(DeltaDebuggerPreferences.LABEL_EXTERNAL_TOOL_CPACHECKER_OUTPUT_REGEX_OOM); final Predicate isTimeout = getOutputPredicate(DeltaDebuggerPreferences.LABEL_EXTERNAL_TOOL_CPACHECKER_OUTPUT_REGEX_TIMEOUT); final Predicate isError = getOutputPredicate(DeltaDebuggerPreferences.LABEL_EXTERNAL_TOOL_CPACHECKER_OUTPUT_REGEX_ERROR); ExternalToolResult result = ExternalToolResult.UNKNOWN; for (final String line : output.split(CoreUtil.getPlatformLineSeparator())) { if (isInteresting.test(line)) { result = ExternalToolResult.INTERESTING; break; } else if (isOOM.test(line)) { result = ExternalToolResult.OOM; break; } else if (isTimeout.test(line)) { result = ExternalToolResult.TIMEOUT; break; } else if (isError.test(line)) { result = ExternalToolResult.ERROR; break; } } if (result != ExternalToolResult.INTERESTING) { logOutput(output, error, returnCode, killed); } return result; } private void logOutput(final String output, final String error, final int returnCode, final boolean killed) { mLogger.info("CPAChecker terminated with return code " + returnCode); if (killed) { mLogger.info("CPAChecker was killed due to hard timeout"); } mLogger.info("STDOUT:"); mLogger.info(output); mLogger.info("STDERR:"); mLogger.info(error); } @Override protected String getExitCommand() { return null; } @Override protected String getWorkingDir() { if (mCpaCheckerHome == null) { mCpaCheckerHome = initWorkingDir(); } return mCpaCheckerHome; } @Override protected String[] getCommandline(final String inputFilePath) { final String command = mPrefProvider.getString(DeltaDebuggerPreferences.LABEL_EXTERNAL_TOOL_CPACHECKER_CMD); final String[] args = command.split(" "); final List cmdArgs = new ArrayList<>(); cmdArgs.add(Paths.get(mCpaCheckerHome, args[0]).toFile().getAbsolutePath()); for (int i = 1; i < args.length; ++i) { cmdArgs.add(args[i]); } cmdArgs.add("-timelimit"); cmdArgs.add(String.valueOf(getHardTimeout() / 1000L)); cmdArgs.add(inputFilePath); return cmdArgs.toArray(new String[cmdArgs.size()]); } @Override protected boolean checkAndSetupTool() { if (getWorkingDir() == null) { mLogger.error("CPACHECKER_HOME not set, cannot use CPACHECKER as witness verifier"); return false; } return true; } private String initWorkingDir() { final String rtr = System.getenv().get("CPACHECKER_HOME"); if (rtr == null) { return mPrefProvider.getString(DeltaDebuggerPreferences.LABEL_EXTERNAL_TOOL_WORKING_DIR); } return rtr; } private Predicate getOutputPredicate(final String label) { if (label == null || label.isEmpty()) { return a -> false; } final String regex = mPrefProvider.getString(label); if (regex == null || regex.isEmpty()) { return a -> false; } final Pattern matcher = Pattern.compile(regex); return matcher.asPredicate(); } }