| /******************************************************************************* |
| * Copyright (c) 2009, 2016 IBM Corporation and others. |
| * |
| * This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License 2.0 |
| * which accompanies this distribution, and is available at |
| * https://www.eclipse.org/legal/epl-2.0/ |
| * |
| * SPDX-License-Identifier: EPL-2.0 |
| * |
| * Contributors: |
| * IBM - Initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.cdt.make.xlc.core.scannerconfig; |
| |
| import java.util.HashMap; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.concurrent.CopyOnWriteArrayList; |
| |
| import org.eclipse.cdt.core.IMarkerGenerator; |
| import org.eclipse.cdt.make.core.scannerconfig.IScannerInfoCollector2; |
| import org.eclipse.cdt.make.core.scannerconfig.ScannerInfoTypes; |
| import org.eclipse.cdt.make.internal.core.MakeMessages; |
| import org.eclipse.cdt.make.internal.core.scannerconfig.util.TraceUtil; |
| import org.eclipse.cdt.make.xlc.core.activator.Activator; |
| import org.eclipse.core.resources.IFile; |
| import org.eclipse.core.resources.IProject; |
| import org.eclipse.core.runtime.CoreException; |
| |
| /** |
| * @author crecoskie |
| * |
| */ |
| public class XLCPerProjectBuildOutputParser extends AbstractXLCBuildOutputParser { |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.cdt.make.xlc.core.scannerconfig.AbstractXLCBuildOutputParser#processCommand(java.lang.String[]) |
| */ |
| @Override |
| protected boolean processCommand(String[] tokens) { |
| int compilerInvocationIdx = findCompilerInvocation(tokens); |
| if (compilerInvocationIdx < 0) { |
| return false; |
| } |
| |
| if (compilerInvocationIdx + 1 >= tokens.length) { |
| return false; |
| } |
| |
| // Recognized gcc or g++ compiler invocation |
| List<String> includes = new CopyOnWriteArrayList<>(); |
| List<String> symbols = new CopyOnWriteArrayList<>(); |
| List<String> targetSpecificOptions = new CopyOnWriteArrayList<>(); |
| |
| String fileName = null; |
| for (int j = compilerInvocationIdx + 1; j < tokens.length; j++) { |
| String token = tokens[j]; |
| if (token.equals(DASHIDASH)) { |
| } else if (token.startsWith(DASHI)) { |
| String candidate = null; |
| if (token.length() > 2) { |
| candidate = token.substring(2).trim(); |
| } else if (j + 1 < tokens.length) { |
| candidate = tokens[j + 1]; |
| if (candidate.startsWith("-")) { //$NON-NLS-1$ |
| candidate = null; |
| } else { |
| j++; |
| } |
| } |
| if (candidate != null && candidate.length() > 0) { |
| if (getUtility() != null) { |
| candidate = getUtility().normalizePath(candidate); |
| } |
| if (!includes.contains(candidate)) { |
| includes.add(candidate); |
| } |
| } |
| } else if (token.startsWith(DASHD)) { |
| String candidate = null; |
| if (token.length() > 2) { |
| candidate = token.substring(2).trim(); |
| } else if (j + 1 < tokens.length) { |
| candidate = tokens[j + 1]; |
| if (candidate.startsWith("-")) { //$NON-NLS-1$ |
| candidate = null; |
| } else { |
| j++; |
| } |
| } |
| if (candidate != null && candidate.length() > 0) { |
| if (candidate.indexOf('=') == -1) { |
| candidate += '=' + getUtility().getDefaultMacroDefinitionValue(); |
| } |
| if (!symbols.contains(candidate)) { |
| symbols.add(candidate); |
| } |
| } |
| } |
| |
| else if (fileName == null) { |
| int extIndex = token.lastIndexOf('.'); |
| String extension = null; |
| |
| if (extIndex != -1) |
| extension = token.substring(extIndex); |
| |
| List<String> extensions = getFileExtensionsList(); |
| if (extension != null && extensions.contains(extension)) |
| fileName = token; |
| } |
| } |
| |
| if (fileName == null) { |
| return false; // return when no file was given (analogous to GCCPerFileBOPConsoleParser) |
| } |
| |
| IProject project = getProject(); |
| IFile file = null; |
| List<String> translatedIncludes = includes; |
| if (includes.size() > 0) { |
| if (fileName != null) { |
| if (getUtility() != null) { |
| file = getUtility().findFile(fileName); |
| if (file != null) { |
| project = file.getProject(); |
| translatedIncludes = getUtility().translateRelativePaths(file, fileName, includes); |
| } |
| } |
| } else { |
| StringBuilder line = new StringBuilder(); |
| for (int j = 0; j < tokens.length; j++) { |
| line.append(tokens[j]); |
| line.append(' '); |
| } |
| final String error = MakeMessages.getString("ConsoleParser.Filename_Missing_Error_Message"); //$NON-NLS-1$ |
| TraceUtil.outputError(error, line.toString()); |
| if (getUtility() != null) { |
| getUtility().generateMarker(getProject(), -1, error + line.toString(), |
| IMarkerGenerator.SEVERITY_WARNING, null); |
| } |
| } |
| if (file == null && getUtility() != null) { // real world case |
| // remove include paths since there was no chance to translate them |
| translatedIncludes.clear(); |
| } |
| } |
| // Contribute discovered includes and symbols to the ScannerInfoCollector |
| if (translatedIncludes.size() > 0 || symbols.size() > 0) { |
| Map<ScannerInfoTypes, List<String>> scannerInfo = new HashMap<>(); |
| scannerInfo.put(ScannerInfoTypes.INCLUDE_PATHS, translatedIncludes); |
| scannerInfo.put(ScannerInfoTypes.SYMBOL_DEFINITIONS, symbols); |
| scannerInfo.put(ScannerInfoTypes.TARGET_SPECIFIC_OPTION, targetSpecificOptions); |
| getCollector().contributeToScannerConfig(project, scannerInfo); |
| if (fCollector != null && fCollector instanceof IScannerInfoCollector2) { |
| IScannerInfoCollector2 collector = (IScannerInfoCollector2) fCollector; |
| try { |
| collector.updateScannerConfiguration(null); |
| } catch (CoreException e) { |
| // TODO Auto-generated catch block |
| Activator.log(e); |
| } |
| } |
| |
| TraceUtil.outputTrace("Discovered scanner info for file \'" + fileName + '\'', //$NON-NLS-1$ |
| "Include paths", includes, translatedIncludes, "Defined symbols", symbols); //$NON-NLS-1$ //$NON-NLS-2$ |
| } |
| return true; |
| |
| } |
| |
| } |