| /******************************************************************************* |
| * Copyright (c) 2009, 2013 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.make.core.scannerconfig.IScannerInfoCollector2; |
| import org.eclipse.cdt.make.core.scannerconfig.ScannerInfoTypes; |
| import org.eclipse.cdt.make.internal.core.scannerconfig.util.CCommandDSC; |
| 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.runtime.CoreException; |
| import org.eclipse.core.runtime.IPath; |
| |
| /** |
| * @author crecoskie |
| * |
| */ |
| @SuppressWarnings("restriction") |
| public class XLCPerFileBuildOutputParser extends AbstractXLCBuildOutputParser { |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.cdt.make.xlc.core.scannerconfig.AbstractXLCBuildOutputParser#processCommand(java.lang.String[]) |
| */ |
| @Override |
| protected boolean processCommand(String[] tokens) { |
| try { |
| |
| // GCC C/C++ compiler invocation |
| int compilerInvocationIndex = findCompilerInvocation(tokens); |
| if (compilerInvocationIndex < 0) { |
| return false; |
| } |
| |
| // find a file name |
| int extensionsIndex = -1; |
| boolean found = false; |
| String filePath = null; |
| |
| // check for automake format first |
| // e.g. line will start with |
| // source='/some/path/source.cpp' |
| int automakeSrcIndex = findAutoMakeSourceIndex(tokens); |
| if (automakeSrcIndex != -1) { |
| filePath = getAutoMakeSourcePath(tokens[automakeSrcIndex]); |
| int k = filePath.lastIndexOf('.'); |
| if (k != -1 && (filePath.length() - k < 5)) { |
| String fileExtension = filePath.substring(k); |
| extensionsIndex = getFileExtensionsList().indexOf(fileExtension); |
| if (extensionsIndex != -1) { |
| found = true; |
| } |
| } |
| } |
| |
| if (!found) { |
| for (int i = compilerInvocationIndex + 1; i < tokens.length; i++) { |
| String token = tokens[i]; |
| int k = token.lastIndexOf('.'); |
| if (k != -1 && (token.length() - k < 5)) { |
| String fileExtension = token.substring(k); |
| extensionsIndex = getFileExtensionsList().indexOf(fileExtension); |
| if (extensionsIndex != -1) { |
| filePath = token; |
| found = true; |
| break; |
| } |
| } |
| } |
| } |
| |
| if (!found) { |
| TraceUtil.outputTrace("Error identifying file name :1", tokens, TraceUtil.EOL); //$NON-NLS-1$ |
| return false; |
| } |
| // sanity check |
| if (filePath.indexOf(getFileExtensions()[extensionsIndex]) == -1) { |
| TraceUtil.outputTrace("Error identifying file name :2", tokens, TraceUtil.EOL); //$NON-NLS-1$ |
| return false; |
| } |
| if (getUtility() != null) { |
| IPath pFilePath = fUtility.getAbsolutePath(filePath); |
| String shortFileName = pFilePath.removeFileExtension().lastSegment(); |
| |
| // generalize occurrences of the file name |
| for (int i = compilerInvocationIndex + 1; i < tokens.length; i++) { |
| String token = tokens[i]; |
| if (token.equals("-include")) { //$NON-NLS-1$ |
| ++i; |
| } else if (token.equals("-imacros")) { //$NON-NLS-1$ |
| ++i; |
| } else if (token.equals(filePath)) { |
| tokens[i] = "LONG_NAME"; //$NON-NLS-1$ |
| } else if (token.startsWith(shortFileName)) { |
| tokens[i] = token.replaceFirst(shortFileName, "SHORT_NAME"); //$NON-NLS-1$ |
| } |
| } |
| |
| IFile file = null; |
| IPath baseDirectory = fUtility.getBaseDirectory(); |
| if (baseDirectory.isPrefixOf(pFilePath)) { |
| IPath relPath = pFilePath.removeFirstSegments(baseDirectory.segmentCount()); |
| // Note: We add the scanner-config even if the resource doesn't |
| // actually |
| // exist below this project (which may happen when reading |
| // existing |
| // build logs, because resources can be created as part of the |
| // build |
| // and may not exist at the time of analyzing the config but |
| // re-built |
| // later on. |
| // if (getProject().exists(relPath)) { |
| file = getProject().getFile(relPath); |
| } else { |
| file = getUtility().findFileInWorkspace(pFilePath); |
| } |
| if (true /*file != null*/) { |
| CCommandDSC cmd = getUtility().getNewCCommandDSC(tokens, compilerInvocationIndex, |
| extensionsIndex > 0); |
| List<CCommandDSC> cmdList = new CopyOnWriteArrayList<>(); |
| cmdList.add(cmd); |
| Map<ScannerInfoTypes, List<CCommandDSC>> sc = new HashMap<>(1); |
| sc.put(ScannerInfoTypes.COMPILER_COMMAND, cmdList); |
| getCollector().contributeToScannerConfig(file, sc); |
| 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); |
| } |
| } |
| } else { |
| /* |
| //TraceUtil.outputError("Build command for file outside project: " + pFilePath.toString(), tokens); //$NON-NLS-1$ |
| // put the info on the project |
| //CCommandDSC cmd = getUtility().getNewCCommandDSC(tokens, compilerInvocationIndex, extensionsIndex > 0); |
| //List<CCommandDSC> cmdList = new ArrayList<CCommandDSC>(); |
| // cmdList.add(cmd); |
| Map<ScannerInfoTypes, List<?>> sc = new HashMap<ScannerInfoTypes, List<?>>(); |
| // sc.put(ScannerInfoTypes.COMPILER_COMMAND, cmdList); |
| |
| |
| // put in empty info for the other types |
| sc.put(ScannerInfoTypes.INCLUDE_PATHS, new LinkedList<String>()); |
| sc.put(ScannerInfoTypes.SYMBOL_DEFINITIONS, new LinkedList<String>()); |
| |
| getCollector().contributeToScannerConfig(getProject(), sc); |
| 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); |
| } |
| } |
| |
| */ |
| } |
| } |
| return true; |
| |
| } catch (Throwable e) { |
| e.printStackTrace(); |
| return false; |
| } |
| } |
| |
| protected String getAutoMakeSourcePath(String string) { |
| // path may be enclosed in single quotes |
| int firstQuoteIndex = string.indexOf('\''); |
| int lastQuoteIndex = string.lastIndexOf('\''); |
| if (firstQuoteIndex != -1 && lastQuoteIndex != -1) |
| return string.substring(firstQuoteIndex, lastQuoteIndex); |
| else { |
| // just take everything after the equals sign |
| int equalsIndex = string.indexOf('='); |
| if (equalsIndex != -1 && equalsIndex < string.length()) |
| return string.substring(equalsIndex + 1); |
| |
| } |
| return null; |
| } |
| |
| protected int findAutoMakeSourceIndex(String[] tokens) { |
| for (int i = 0; i < tokens.length; i++) { |
| final String token = tokens[i].toLowerCase(); |
| if (token.indexOf("source=") != -1) //$NON-NLS-1$ |
| return i; |
| } |
| return -1; |
| } |
| |
| } |