From af85d93c297b0dcc87e2e4f5dead8867eddf81c4 Mon Sep 17 00:00:00 2001 From: Vladimir Hirsl Date: Wed, 26 Jan 2005 16:10:52 +0000 Subject: [PATCH] New Scanner Config Discovery work in preparation for per file SC discovery. Added GCCPerFile console parser and utility and PerFile scanner info collector. --- .../plugin.properties | 3 + build/org.eclipse.cdt.make.core/plugin.xml | 12 +- .../IScannerInfoConsoleParser.java | 14 +- .../IScannerInfoConsoleParserUtility.java | 24 -- .../ScannerInfoConsoleParserFactory.java | 19 +- .../gnu/AbstractGCCBOPConsoleParser.java | 113 ++++++++++ .../AbstractGCCBOPConsoleParserUtility.java | 199 ++++++++++++++++ .../gnu/GCCPerFileBOPConsoleParser.java | 131 +++++++++++ .../GCCPerFileBOPConsoleParserUtility.java | 212 ++++++++++++++++++ .../gnu/GCCScannerInfoConsoleParser.java | 123 +++------- .../gnu/GCCSpecsConsoleParser.java | 20 +- .../ScannerInfoConsoleParserUtility.java | 169 ++------------ .../core/scannerconfig/util/CCommandDSC.java | 133 +++++++++++ .../core/scannerconfig/util/KVList.java | 45 ++++ .../core/scannerconfig/util/KVPair.java | 59 +++++ .../scannerconfig/util/SCDOptionsEnum.java | 87 +++++++ .../scannerconfig2/PerFileSICollector.java | 70 ++++++ .../ScannerConfigConsoleParserTests.java | 6 +- 18 files changed, 1128 insertions(+), 311 deletions(-) delete mode 100644 build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/scannerconfig/IScannerInfoConsoleParserUtility.java create mode 100644 build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/gnu/AbstractGCCBOPConsoleParser.java create mode 100644 build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/gnu/AbstractGCCBOPConsoleParserUtility.java create mode 100644 build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/gnu/GCCPerFileBOPConsoleParser.java create mode 100644 build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/gnu/GCCPerFileBOPConsoleParserUtility.java rename build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/{util => gnu}/ScannerInfoConsoleParserUtility.java (64%) create mode 100644 build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/util/CCommandDSC.java create mode 100644 build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/util/KVList.java create mode 100644 build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/util/KVPair.java create mode 100644 build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/util/SCDOptionsEnum.java create mode 100644 build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig2/PerFileSICollector.java diff --git a/build/org.eclipse.cdt.make.core/plugin.properties b/build/org.eclipse.cdt.make.core/plugin.properties index a16be0c90b2..6471d3f5ed7 100644 --- a/build/org.eclipse.cdt.make.core/plugin.properties +++ b/build/org.eclipse.cdt.make.core/plugin.properties @@ -24,3 +24,6 @@ epDefaultExternalScannerInfoProvider.name=Default External Scanner Info Provider extensionScannerInfoConsoleParser.name=GNU C/C++ Scanner Info Console Parser Extension epGCCCommandLineParser.name=GNU C/C++ Scanner Info Parser epGCCSpecsParser.name=GNU C/C++ Compiler Specs Parser + +extensionGCCPerProjectProfile.name=GNU C/C++ Scanner Info per project profile +extensionGCCPerFileProfile.name=GNU C/C++ Scanner Info per file profile diff --git a/build/org.eclipse.cdt.make.core/plugin.xml b/build/org.eclipse.cdt.make.core/plugin.xml index 877074440f6..7b35b67148b 100644 --- a/build/org.eclipse.cdt.make.core/plugin.xml +++ b/build/org.eclipse.cdt.make.core/plugin.xml @@ -127,7 +127,7 @@ @@ -142,5 +142,15 @@ + + + + + + + diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/scannerconfig/IScannerInfoConsoleParser.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/scannerconfig/IScannerInfoConsoleParser.java index f53099ed7d9..b1f10562b52 100644 --- a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/scannerconfig/IScannerInfoConsoleParser.java +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/scannerconfig/IScannerInfoConsoleParser.java @@ -10,7 +10,9 @@ **********************************************************************/ package org.eclipse.cdt.make.core.scannerconfig; +import org.eclipse.cdt.core.IMarkerGenerator; import org.eclipse.core.resources.IProject; +import org.eclipse.core.runtime.IPath; /** * Parses a line of command output looking for scanner info entries. @@ -19,17 +21,15 @@ import org.eclipse.core.resources.IProject; */ public interface IScannerInfoConsoleParser { /** - * Get a utility object to be initialized - */ - public IScannerInfoConsoleParserUtility getUtility(); - - /** - * Optional one time initialization of a console parser. + * One time initialization of a console parser. * * @param project + * @param workingDirectory * @param collector - scanner info collector + * @param markerGenerator */ - public void startup(IProject project, IScannerInfoCollector collector); + public void startup(IProject project, IPath workingDirectory, + IScannerInfoCollector collector, IMarkerGenerator markerGenerator); /** * Parse one line of output. diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/scannerconfig/IScannerInfoConsoleParserUtility.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/scannerconfig/IScannerInfoConsoleParserUtility.java deleted file mode 100644 index f9f63ffd34f..00000000000 --- a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/core/scannerconfig/IScannerInfoConsoleParserUtility.java +++ /dev/null @@ -1,24 +0,0 @@ -/********************************************************************** - * Copyright (c) 2004 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html - * - * Contributors: - * IBM - Initial API and implementation - **********************************************************************/ -package org.eclipse.cdt.make.core.scannerconfig; - -import org.eclipse.cdt.core.IMarkerGenerator; -import org.eclipse.core.resources.IProject; -import org.eclipse.core.runtime.IPath; - -/** - * Common work required by the scanner info console parsers - * - * @author vhirsl - */ -public interface IScannerInfoConsoleParserUtility { - public void initialize(IProject project, IPath workingDirectory, IMarkerGenerator markerGenerator); -} diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/ScannerInfoConsoleParserFactory.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/ScannerInfoConsoleParserFactory.java index 9bc0c6f1c89..7e5480b4c4e 100644 --- a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/ScannerInfoConsoleParserFactory.java +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/ScannerInfoConsoleParserFactory.java @@ -17,7 +17,6 @@ import org.eclipse.cdt.make.core.MakeCorePlugin; import org.eclipse.cdt.make.core.scannerconfig.IScannerConfigBuilderInfo2; import org.eclipse.cdt.make.core.scannerconfig.IScannerInfoCollector; import org.eclipse.cdt.make.core.scannerconfig.IScannerInfoConsoleParser; -import org.eclipse.cdt.make.core.scannerconfig.IScannerInfoConsoleParserUtility; import org.eclipse.cdt.make.core.scannerconfig.ScannerConfigNature; import org.eclipse.cdt.make.internal.core.scannerconfig2.SCProfileInstance; import org.eclipse.cdt.make.internal.core.scannerconfig2.ScannerConfigProfileManager; @@ -57,13 +56,8 @@ public class ScannerInfoConsoleParserFactory { SCProfileInstance profileInstance = ScannerConfigProfileManager.getInstance(). getSCProfileInstance(currentProject, scBuildInfo.getSelectedProfileId()); IScannerInfoConsoleParser clParser = profileInstance.createExternalScannerInfoParser(providerId); - // initialize the utility object - IScannerInfoConsoleParserUtility util = clParser.getUtility(); - if (util != null) { - util.initialize(currentProject, currentProject.getLocation(), markerGenerator); - } IScannerInfoCollector collector = profileInstance.getScannerInfoCollector(); - clParser.startup(currentProject, collector); + clParser.startup(currentProject, currentProject.getLocation(), collector, markerGenerator); // create an output stream sniffer return new ConsoleOutputSniffer(outputStream, errorStream, new IScannerInfoConsoleParser[] {clParser}); @@ -114,15 +108,8 @@ public class ScannerInfoConsoleParserFactory { if (collector == null) { collector = profileInstance.getScannerInfoCollector(); } - - // initialize the utility object - IScannerInfoConsoleParserUtility util = clParser.getUtility(); - if (util != null) { - util.initialize(currentProject, workingDirectory, - scBuildInfo.isProblemReportingEnabled() ? - markerGenerator : null); - } - clParser.startup(currentProject, collector); + clParser.startup(currentProject, workingDirectory, collector, + scBuildInfo.isProblemReportingEnabled() ? markerGenerator : null); // create an output stream sniffer return new ConsoleOutputSniffer(outputStream, errorStream, new IScannerInfoConsoleParser[] {clParser}); diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/gnu/AbstractGCCBOPConsoleParser.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/gnu/AbstractGCCBOPConsoleParser.java new file mode 100644 index 00000000000..789a24e7f2f --- /dev/null +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/gnu/AbstractGCCBOPConsoleParser.java @@ -0,0 +1,113 @@ +/*********************************************************************** + * Copyright (c) 2004 IBM Corporation 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: + * IBM - Initial API and implementation + ***********************************************************************/ +package org.eclipse.cdt.make.internal.core.scannerconfig.gnu; + +import org.eclipse.cdt.make.core.scannerconfig.IScannerInfoCollector; +import org.eclipse.cdt.make.core.scannerconfig.IScannerInfoConsoleParser; +import org.eclipse.cdt.make.internal.core.scannerconfig.util.TraceUtil; +import org.eclipse.core.resources.IProject; + +/** + * Common stuff for all GNU build output parsers + * + * @author vhirsl + */ +public abstract class AbstractGCCBOPConsoleParser implements IScannerInfoConsoleParser { + private IProject project; + private IScannerInfoCollector collector; + + private boolean bMultiline = false; + private String sMultiline = ""; //$NON-NLS-1$ + + /** + * @return Returns the project. + */ + protected IProject getProject() { + return project; + } + /** + * @return Returns the collector. + */ + protected IScannerInfoCollector getCollector() { + return collector; + } + + public void startup(IProject project, IScannerInfoCollector collector) { + this.project = project; + this.collector = collector; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.make.core.scannerconfig.IScannerInfoConsoleParser#processLine(java.lang.String) + */ + public boolean processLine(String line) { + boolean rc = false; + // check for multiline commands (ends with '\') + if (line.endsWith("\\")) { //$NON-NLS-1$ + sMultiline += line.substring(0, line.length()-1);// + " "; //$NON-NLS-1$ + bMultiline = true; + return rc; + } + if (bMultiline) { + line = sMultiline + line; + bMultiline = false; + sMultiline = ""; //$NON-NLS-1$ + } + TraceUtil.outputTrace("AbstractGCCBOPConsoleParser parsing line:", TraceUtil.EOL, line); //$NON-NLS-1$ //$NON-NLS-2$ + // make\[[0-9]*\]: error_desc + int firstColon= line.indexOf(':'); + String make = line.substring(0, firstColon + 1); + if (firstColon != -1 && make.indexOf("make") != -1) { //$NON-NLS-1$ + boolean enter = false; + String msg = line.substring(firstColon + 1).trim(); + if ((enter = msg.startsWith("Entering directory")) || //$NON-NLS-1$ + (msg.startsWith("Leaving directory"))) { //$NON-NLS-1$ + int s = msg.indexOf('`'); + int e = msg.indexOf('\''); + if (s != -1 && e != -1) { + String dir = msg.substring(s+1, e); + if (getUtility() != null) { + getUtility().changeMakeDirectory(dir, getDirectoryLevel(line), enter); + } + return rc; + } + } + } + // call sublclass to process a single line + return processSingleLine(line); + } + + private int getDirectoryLevel(String line) { + int s = line.indexOf('['); + int num = 0; + if (s != -1) { + int e = line.indexOf(']'); + String number = line.substring(s + 1, e).trim(); + try { + num = Integer.parseInt(number); + } catch (NumberFormatException exc) { + } + } + return num; + } + + protected abstract boolean processSingleLine(String line); + protected abstract AbstractGCCBOPConsoleParserUtility getUtility(); + + /* (non-Javadoc) + * @see org.eclipse.cdt.make.core.scannerconfig.IScannerInfoConsoleParser#shutdown() + */ + public void shutdown() { + if (getUtility() != null) { + getUtility().reportProblems(); + } + } +} diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/gnu/AbstractGCCBOPConsoleParserUtility.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/gnu/AbstractGCCBOPConsoleParserUtility.java new file mode 100644 index 00000000000..a664c16d5e7 --- /dev/null +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/gnu/AbstractGCCBOPConsoleParserUtility.java @@ -0,0 +1,199 @@ +/*********************************************************************** + * Copyright (c) 2004 IBM Corporation 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: + * IBM - Initial API and implementation + ***********************************************************************/ +package org.eclipse.cdt.make.internal.core.scannerconfig.gnu; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.Vector; + +import org.eclipse.cdt.core.IMarkerGenerator; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.Path; + +/** + * Common utilities for GCC build output console parsers + * + * @author vhirsl + */ +public abstract class AbstractGCCBOPConsoleParserUtility { + private IProject project; + private IPath fBaseDirectory; + private Vector fDirectoryStack; + private IMarkerGenerator fMarkerGenerator; + private ArrayList fErrors; + + /** + * + */ + public AbstractGCCBOPConsoleParserUtility(IProject project, IPath workingDirectory, + IMarkerGenerator markerGenerator) { + fDirectoryStack = new Vector(); + fErrors = new ArrayList(); + this.project = project; + fBaseDirectory = project.getLocation(); + if (workingDirectory != null) { + pushDirectory(workingDirectory); + } + } + + /** + * @return Returns the fBaseDirectory. + */ + protected IPath getBaseDirectory() { + return fBaseDirectory; + } + /** + * @return Returns the fDirectoryStack. + */ + protected Vector getDirectoryStack() { + return fDirectoryStack; + } + /** + * @return Returns the fErrors. + */ + protected ArrayList getErrors() { + return fErrors; + } + /** + * @return Returns the fMarkerGenerator. + */ + protected IMarkerGenerator getMarkerGenerator() { + return fMarkerGenerator; + } + /** + * @return Returns the project. + */ + protected IProject getProject() { + return project; + } + + public IPath getWorkingDirectory() { + if (fDirectoryStack.size() != 0) { + return (IPath) fDirectoryStack.lastElement(); + } + // Fallback to the Project Location + // FIXME: if the build did not start in the Project ? + return fBaseDirectory; + } + + protected void pushDirectory(IPath dir) { + if (dir != null) { + IPath pwd = null; + if (fBaseDirectory.isPrefixOf(dir)) { + pwd = dir.removeFirstSegments(fBaseDirectory.segmentCount()); + } else { + // check if it is a cygpath + if (dir.toString().startsWith("/cygdrive/")) { //$NON-NLS-1$ + char driveLetter = dir.toString().charAt(10); + driveLetter = (Character.isLowerCase(driveLetter)) ? Character.toUpperCase(driveLetter) : driveLetter; + StringBuffer buf = new StringBuffer(); + buf.append(driveLetter); + buf.append(':'); + String drive = buf.toString(); + pwd = dir.removeFirstSegments(2); + pwd = pwd.setDevice(drive); + pwd = pwd.makeAbsolute(); + } + else { + pwd = dir; + } + } + fDirectoryStack.addElement(pwd); + } + } + + protected IPath popDirectory() { + int i = getDirectoryLevel(); + if (i != 0) { + IPath dir = (IPath) fDirectoryStack.lastElement(); + fDirectoryStack.removeElementAt(i - 1); + return dir; + } + return new Path(""); //$NON-NLS-1$ + } + + protected int getDirectoryLevel() { + return fDirectoryStack.size(); + } + + public void changeMakeDirectory(String dir, int dirLevel, boolean enterDir) { + if (enterDir) { + /* Sometimes make screws up the output, so + * "leave" events can't be seen. Double-check level + * here. + */ + for (int parseLevel = getDirectoryLevel(); dirLevel < parseLevel; parseLevel = getDirectoryLevel()) { + popDirectory(); + } + pushDirectory(new Path(dir)); + } else { + popDirectory(); + /* Could check to see if they match */ + } + } + + public boolean reportProblems() { + boolean reset = false; + for (Iterator iter = fErrors.iterator(); iter.hasNext(); ) { + Problem problem = (Problem) iter.next(); + if (problem.severity == IMarkerGenerator.SEVERITY_ERROR_BUILD) { + reset = true; + } + if (problem.file == null) { + fMarkerGenerator.addMarker( + project, + problem.lineNumber, + problem.description, + problem.severity, + problem.variableName); + } else { + fMarkerGenerator.addMarker( + problem.file, + problem.lineNumber, + problem.description, + problem.severity, + problem.variableName); + } + } + fErrors.clear(); + return reset; + } + + protected class Problem { + protected IResource file; + protected int lineNumber; + protected String description; + protected int severity; + protected String variableName; + + public Problem(IResource file, int lineNumber, String desciption, int severity, String variableName) { + this.file = file; + this.lineNumber = lineNumber; + this.description = desciption; + this.severity = severity; + this.variableName = variableName; + } + } + + /** + * Called by the console line parsers to generate a problem marker. + */ + public void generateMarker(IResource file, int lineNumber, String desc, int severity, String varName) { + // No need to collect markers if marker generator is not present + if (fMarkerGenerator != null) { + Problem problem = new Problem(file, lineNumber, desc, severity, varName); + fErrors.add(problem); + } + } + +} diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/gnu/GCCPerFileBOPConsoleParser.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/gnu/GCCPerFileBOPConsoleParser.java new file mode 100644 index 00000000000..a184cbaed7c --- /dev/null +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/gnu/GCCPerFileBOPConsoleParser.java @@ -0,0 +1,131 @@ +/*********************************************************************** + * Copyright (c) 2004 IBM Corporation 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: + * IBM - Initial API and implementation + ***********************************************************************/ +package org.eclipse.cdt.make.internal.core.scannerconfig.gnu; + +import java.util.Arrays; +import java.util.List; + +import org.eclipse.cdt.core.IMarkerGenerator; +import org.eclipse.cdt.make.core.scannerconfig.IScannerInfoCollector; +import org.eclipse.cdt.make.internal.core.scannerconfig.util.TraceUtil; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.runtime.IPath; + + +/** + * GCC per file build output parser + * + * @author vhirsl + */ +public class GCCPerFileBOPConsoleParser extends AbstractGCCBOPConsoleParser { + private final static String[] FILE_EXTENSIONS = { + ".c", ".cc", ".cpp", ".cxx", ".C", ".CC", ".CPP", ".CXX" + }; + private final static String[] COMPILER_INVOCATION = { + "gcc", "g++", "cc", "c++" + }; + private final static List FILE_EXTENSIONS_LIST = Arrays.asList(FILE_EXTENSIONS); + + private GCCPerFileBOPConsoleParserUtility fUtil; + + /* (non-Javadoc) + * @see org.eclipse.cdt.make.core.scannerconfig.IScannerInfoConsoleParser#startup(org.eclipse.core.resources.IProject, org.eclipse.core.runtime.IPath, org.eclipse.cdt.make.core.scannerconfig.IScannerInfoCollector, org.eclipse.cdt.core.IMarkerGenerator) + */ + public void startup(IProject project, IPath workingDirectory, IScannerInfoCollector collector, IMarkerGenerator markerGenerator) { + fUtil = (project != null && workingDirectory != null && markerGenerator != null) ? + new GCCPerFileBOPConsoleParserUtility(project, workingDirectory, markerGenerator) : null; + super.startup(project, collector); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.make.internal.core.scannerconfig.gnu.AbstractGCCBOPConsoleParser#getUtility() + */ + protected AbstractGCCBOPConsoleParserUtility getUtility() { + return fUtil; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.make.internal.core.scannerconfig.gnu.AbstractGCCBOPConsoleParser#processSingleLine(java.lang.String) + */ + protected boolean processSingleLine(String line) { + boolean rc = false; + // GCC C/C++ compiler invocation + int compilerInvocationIndex = -1; + for (int cii = 0; cii < COMPILER_INVOCATION.length; ++cii) { + compilerInvocationIndex = line.indexOf(COMPILER_INVOCATION[cii]); + if (compilerInvocationIndex != -1) + break; + } + if (compilerInvocationIndex == -1) + return rc; + + // expecting that compiler invocation is the first token in the line + String[] split = line.split("\\s+"); + String command = split[0]; + // verify that it is compiler invocation + int cii2 = -1; + for (int cii = 0; cii < COMPILER_INVOCATION.length; ++cii) { + cii2 = command.indexOf(COMPILER_INVOCATION[cii]); + if (cii2 != -1) + break; + } + if (cii2 == -1) { + TraceUtil.outputTrace("Error identifying compiler command", line, TraceUtil.EOL); + return rc; + } + // find a file name + int extensionsIndex = -1; + boolean found = false; + String filePath = null; + for (int i = 1; i < split.length; ++i) { + int k = split[i].lastIndexOf('.'); + if (k != -1 && (split[i].length() - k < 5)) { + String fileExtension = split[i].substring(k); + extensionsIndex = FILE_EXTENSIONS_LIST.indexOf(fileExtension); + if (extensionsIndex != -1) { + filePath = split[i]; + found = true; + break; + } + } + } +// for (int j = 0; j < FILE_EXTENSIONS.length; ++j) { +// if (split[i].endsWith(FILE_EXTENSIONS[j])) { +// filePath = split[i]; +// extensionsIndex = j; +// found = true; +// break; +// } +// } +// if (found) break; + if (!found) { + TraceUtil.outputTrace("Error identifying file name :1", line, TraceUtil.EOL); + return rc; + } + // sanity check + if (filePath.indexOf(FILE_EXTENSIONS[extensionsIndex]) == -1) { + TraceUtil.outputTrace("Error identifying file name :2", line, TraceUtil.EOL); + return rc; + } + if (getUtility() != null) { + IPath pFilePath = ((GCCPerFileBOPConsoleParserUtility) getUtility()).getAbsolutePath(filePath); + String longFileName = pFilePath.toString(); + String shortFileName = pFilePath.removeFileExtension().lastSegment(); + String genericLine = line.replaceAll(filePath, "LONG_NAME"); + genericLine = genericLine.replaceAll(shortFileName+"\\.", "SHORT_NAME\\."); + // getUtility().addGenericCommandForFile(longFileName, genericLine); + // alternative + ((GCCPerFileBOPConsoleParserUtility) getUtility()).addGenericCommandForFile2(longFileName, genericLine); + } + return rc; + } + +} diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/gnu/GCCPerFileBOPConsoleParserUtility.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/gnu/GCCPerFileBOPConsoleParserUtility.java new file mode 100644 index 00000000000..0f4dd41992a --- /dev/null +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/gnu/GCCPerFileBOPConsoleParserUtility.java @@ -0,0 +1,212 @@ +/*********************************************************************** + * Copyright (c) 2004 IBM Corporation 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: + * IBM - Initial API and implementation + ***********************************************************************/ +package org.eclipse.cdt.make.internal.core.scannerconfig.gnu; + +import java.io.PrintWriter; +import java.io.StringWriter; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import org.eclipse.cdt.core.IMarkerGenerator; +import org.eclipse.cdt.make.internal.core.scannerconfig.util.CCommandDSC; +import org.eclipse.cdt.make.internal.core.scannerconfig.util.KVPair; +import org.eclipse.cdt.make.internal.core.scannerconfig.util.SCDOptionsEnum; +import org.eclipse.cdt.make.internal.core.scannerconfig.util.TraceUtil; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.Path; + +/** + * TODO Provide description + * + * @author vhirsl + */ +public class GCCPerFileBOPConsoleParserUtility extends AbstractGCCBOPConsoleParserUtility { + private Map directoryCommandListMap; + private List compiledFileList; + + private List commandsList2; + + private int workingDirsN = 0; + private int commandsN = 0; + private int filesN = 0; + + + /** + * @param markerGenerator + * @param workingDirectory + * @param project + */ + public GCCPerFileBOPConsoleParserUtility(IProject project, IPath workingDirectory, IMarkerGenerator markerGenerator) { + super(project, workingDirectory, markerGenerator); + } + + /** + * Adds a mapping filename, generic_command + * @param longFileName + * @param genericLine + */ + void addGenericCommandForFile(String longFileName, String genericCommand) { + // if a file name has already been added once, return + if (compiledFileList.contains(longFileName)) + return; + compiledFileList.add(longFileName); + + String workingDir = getWorkingDirectory().toString(); + List directoryCommandList = (List) directoryCommandListMap.get(workingDir); + if (directoryCommandList == null) { + directoryCommandList = new ArrayList(); + directoryCommandListMap.put(workingDir, directoryCommandList); + ++workingDirsN; + } + Map command21FileListMap = null; + for (Iterator i = directoryCommandList.iterator(); i.hasNext(); ) { + command21FileListMap = (Map) i.next(); + List fileList = (List) command21FileListMap.get(genericCommand); + if (fileList != null) { + if (!fileList.contains(longFileName)) { + fileList.add(longFileName); + ++filesN; + } + return; + } + } + command21FileListMap = new HashMap(1); + directoryCommandList.add(command21FileListMap); + ++commandsN; + List fileList = new ArrayList(); + command21FileListMap.put(genericCommand, fileList); + fileList.add(longFileName); + ++filesN; + } + + /** + * + */ + void generateReport() { + TraceUtil.metricsTrace("Stats for directory ", + "Generic command: '", "' applicable for:", + directoryCommandListMap); + TraceUtil.summaryTrace("Discovery summary", workingDirsN, commandsN, filesN); + } + + /** + * Adds a mapping command line -> file, this time without a dir + * @param longFileName + * @param genericLine + */ + void addGenericCommandForFile2(String longFileName, String genericLine) { + // if a file name has already been added once, return + if (compiledFileList.contains(longFileName)) + return; + compiledFileList.add(longFileName); + + CCommandDSC command = getDSCCommand(genericLine); + int index = commandsList2.indexOf(command); + if (index == -1) { + commandsList2.add(command); + ++commandsN; + } + else { + command = (CCommandDSC) commandsList2.get(index); + } + // add a file + command.addFile(longFileName); + ++filesN; + } + + /** + * @param genericLine + */ + private CCommandDSC getDSCCommand(String genericLine) { + CCommandDSC command = new CCommandDSC(); + String[] tokens = genericLine.split("\\s+"); + command.addSCOption(new KVPair(SCDOptionsEnum.COMMAND, tokens[0])); + for (int i = 1; i < tokens.length; ++i) { + for (int j = SCDOptionsEnum.MIN; j <= SCDOptionsEnum.MAX; ++j) { + if (tokens[i].startsWith(SCDOptionsEnum.getSCDOptionsEnum(j).toString())) { + String option = tokens[i].substring( + SCDOptionsEnum.getSCDOptionsEnum(j).toString().length()).trim(); + if (option.length() > 0) { + // ex. -I/dir + } + else { + // ex. -I /dir + // take a next token + ++i; + if (i < tokens.length && !tokens[i].startsWith("-")) { + option = tokens[i]; + } + else break; + } + if (SCDOptionsEnum.getSCDOptionsEnum(j).equals(SCDOptionsEnum.INCLUDE) || + SCDOptionsEnum.getSCDOptionsEnum(j).equals(SCDOptionsEnum.INCLUDE_FILE) || + SCDOptionsEnum.getSCDOptionsEnum(j).equals(SCDOptionsEnum.IMACROS_FILE) || + SCDOptionsEnum.getSCDOptionsEnum(j).equals(SCDOptionsEnum.IDIRAFTER) || + SCDOptionsEnum.getSCDOptionsEnum(j).equals(SCDOptionsEnum.ISYSTEM)) { + option = (getAbsolutePath(option)).toString(); + } + // add the pair + command.addSCOption(new KVPair(SCDOptionsEnum.getSCDOptionsEnum(j), option)); + break; + } + } + } + return command; + } + + /** + * @param filePath : String + * @return filePath : IPath - not null + */ + IPath getAbsolutePath(String filePath) { + IPath pFilePath; + if (filePath.startsWith("/") || filePath.startsWith("\\") || + (!filePath.startsWith(".") && + filePath.length() > 2 && filePath.charAt(1) == ':' && + (filePath.charAt(2) == '\\' || filePath.charAt(2) == '/'))) { + // absolute path + pFilePath = new Path(filePath); + } + else { + // relative path + pFilePath = getWorkingDirectory().append(filePath); + } + return pFilePath; + } + + /** + * + */ + void generateReport2() { + StringWriter buffer = new StringWriter(); + PrintWriter writer = new PrintWriter(buffer); + for (Iterator i = commandsList2.iterator(); i.hasNext(); ) { + CCommandDSC cmd = (CCommandDSC)i.next(); + writer.println("Stats for generic command: '" + cmd.getCommandAsString() + "' applicable for " + + Integer.toString(cmd.getNumberOfFiles()) + " files: "); + List filesList = cmd.getFilesList(); + if (filesList != null) { + for (Iterator j = filesList.iterator(); j.hasNext(); ) { + writer.println(" " + (String)j.next()); + } + } + } + writer.close(); + + TraceUtil.metricsTrace(buffer.toString()); + TraceUtil.summaryTrace("Discovery summary", workingDirsN, commandsN, filesN); + } + +} diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/gnu/GCCScannerInfoConsoleParser.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/gnu/GCCScannerInfoConsoleParser.java index a34dcc590a7..fe4a0eef3b1 100644 --- a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/gnu/GCCScannerInfoConsoleParser.java +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/gnu/GCCScannerInfoConsoleParser.java @@ -10,17 +10,6 @@ **********************************************************************/ package org.eclipse.cdt.make.internal.core.scannerconfig.gnu; -import org.eclipse.core.resources.IFile; -import org.eclipse.core.resources.IProject; -import org.eclipse.cdt.core.IMarkerGenerator; -import org.eclipse.cdt.make.core.scannerconfig.IScannerInfoCollector; -import org.eclipse.cdt.make.core.scannerconfig.ScannerInfoTypes; -import org.eclipse.cdt.make.core.scannerconfig.IScannerInfoConsoleParser; -import org.eclipse.cdt.make.core.scannerconfig.IScannerInfoConsoleParserUtility; -import org.eclipse.cdt.make.internal.core.MakeMessages; -import org.eclipse.cdt.make.internal.core.scannerconfig.util.ScannerInfoConsoleParserUtility; -import org.eclipse.cdt.make.internal.core.scannerconfig.util.TraceUtil; - import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; @@ -28,75 +17,48 @@ import java.util.Iterator; import java.util.List; import java.util.Map; +import org.eclipse.cdt.core.IMarkerGenerator; +import org.eclipse.cdt.make.core.scannerconfig.IScannerInfoCollector; +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.core.resources.IFile; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.runtime.IPath; + /** * Parses gcc and g++ output for -I and -D parameters. * * @author vhirsl */ -public class GCCScannerInfoConsoleParser implements IScannerInfoConsoleParser { +public class GCCScannerInfoConsoleParser extends AbstractGCCBOPConsoleParser { private final static String SINGLE_QUOTE_STRING = "\'"; //$NON-NLS-1$ private final static String DOUBLE_QUOTE_STRING = "\""; //$NON-NLS-1$ private final static char[] matchingChars = {'`', '\'', '\"'}; - private IProject fProject = null; private ScannerInfoConsoleParserUtility fUtil = null; - private IScannerInfoCollector fCollector = null; - private boolean bMultiline = false; - private String sMultiline = ""; //$NON-NLS-1$ - - /* (non-Javadoc) - * @see org.eclipse.cdt.make.core.scannerconfig.IScannerInfoConsoleParser#getUtility() - */ - public IScannerInfoConsoleParserUtility getUtility() { - fUtil = new ScannerInfoConsoleParserUtility(); - return fUtil; - } + /* (non-Javadoc) + * @see org.eclipse.cdt.make.core.scannerconfig.IScannerInfoConsoleParser#startup(org.eclipse.core.resources.IProject, org.eclipse.core.runtime.IPath, org.eclipse.cdt.make.core.scannerconfig.IScannerInfoCollector, org.eclipse.cdt.core.IMarkerGenerator) + */ + public void startup(IProject project, IPath workingDirectory, IScannerInfoCollector collector, IMarkerGenerator markerGenerator) { + fUtil = (project != null && workingDirectory != null && markerGenerator != null) ? + new ScannerInfoConsoleParserUtility(project, workingDirectory, markerGenerator) : null; + super.startup(project, collector); + } - /* (non-Javadoc) - * @see org.eclipse.cdt.make.core.scannerconfig.IScannerInfoConsoleParser#startup(org.eclipse.core.resources.IProject, org.eclipse.cdt.make.internal.core.scannerconfig.IScannerInfoConsoleParserUtility, org.eclipse.cdt.make.core.scannerconfig.ScannerInfoTypes) - */ - public void startup(IProject project, IScannerInfoCollector collector) { - fProject = project; - fCollector = collector; - } + /* (non-Javadoc) + * @see org.eclipse.cdt.make.internal.core.scannerconfig.gnu.AbstractGCCBOPConsoleParser#getUtility() + */ + protected AbstractGCCBOPConsoleParserUtility getUtility() { + return fUtil; + } - /* (non-Javadoc) - * @see org.eclipse.cdt.make.core.scannerconfig.ScannerInfoConsoleParserUtility#processLine(java.lang.String) - */ - public boolean processLine(String line) { + /* (non-Javadoc) + * @see org.eclipse.cdt.make.internal.core.scannerconfig.gnu.AbstractGCCBOPConsoleParser#processSingleLine(java.lang.String) + */ + protected boolean processSingleLine(String line) { boolean rc = false; - // check for multiline commands (ends with '\') - if (line.endsWith("\\")) { //$NON-NLS-1$ - sMultiline += line.substring(0, line.length()-1);// + " "; //$NON-NLS-1$ - bMultiline = true; - return rc; - } - if (bMultiline) { - line = sMultiline + line; - bMultiline = false; - sMultiline = ""; //$NON-NLS-1$ - } - TraceUtil.outputTrace("GCCScannerInfoConsoleParser parsing line:", TraceUtil.EOL, line); //$NON-NLS-1$ //$NON-NLS-2$ - // make\[[0-9]*\]: error_desc - int firstColon= line.indexOf(':'); - String make = line.substring(0, firstColon + 1); - if (firstColon != -1 && make.indexOf("make") != -1) { //$NON-NLS-1$ - boolean enter = false; - String msg = line.substring(firstColon + 1).trim(); - if ((enter = msg.startsWith("Entering directory")) || //$NON-NLS-1$ - (msg.startsWith("Leaving directory"))) { //$NON-NLS-1$ - int s = msg.indexOf('`'); - int e = msg.indexOf('\''); - if (s != -1 && e != -1) { - String dir = msg.substring(s+1, e); - if (fUtil != null) { - fUtil.changeMakeDirectory(dir, getDirectoryLevel(line), enter); - } - return rc; - } - } - } // Known patterns: // (a) gcc|g++ ... -Dxxx -Iyyy ... List allTokens = tokenize(line); @@ -151,7 +113,7 @@ public class GCCScannerInfoConsoleParser implements IScannerInfoConsoleParser { } } - IProject project = fProject; + IProject project = getProject(); IFile file = null; List translatedIncludes = includes; if (includes.size() > 0) { @@ -168,7 +130,7 @@ public class GCCScannerInfoConsoleParser implements IScannerInfoConsoleParser { final String error = MakeMessages.getString("ConsoleParser.Filename_Missing_Error_Message"); //$NON-NLS-1$ TraceUtil.outputError(error, line); if (fUtil != null) { - fUtil.generateMarker(fProject, -1, error + line, IMarkerGenerator.SEVERITY_WARNING, null); + fUtil.generateMarker(getProject(), -1, error + line, IMarkerGenerator.SEVERITY_WARNING, null); } } if (file == null && fUtil != null) { // real world case @@ -182,7 +144,7 @@ public class GCCScannerInfoConsoleParser implements IScannerInfoConsoleParser { scannerInfo.put(ScannerInfoTypes.INCLUDE_PATHS, translatedIncludes); scannerInfo.put(ScannerInfoTypes.SYMBOL_DEFINITIONS, symbols); scannerInfo.put(ScannerInfoTypes.TARGET_SPECIFIC_OPTION, targetSpecificOptions); - fCollector.contributeToScannerConfig(project, scannerInfo); + getCollector().contributeToScannerConfig(project, scannerInfo); TraceUtil.outputTrace("Discovered scanner info for file \'" + fileName + '\'', //$NON-NLS-1$ "Include paths", includes, translatedIncludes, "Defined symbols", symbols); //$NON-NLS-1$ //$NON-NLS-2$ @@ -348,27 +310,4 @@ public class GCCScannerInfoConsoleParser implements IScannerInfoConsoleParser { } } - /* (non-Javadoc) - * @see org.eclipse.cdt.make.core.scannerconfig.IScannerInfoConsoleParser#shutdown() - */ - public void shutdown() { - if (fUtil != null) { - fUtil.reportProblems(); - } - } - - private int getDirectoryLevel(String line) { - int s = line.indexOf('['); - int num = 0; - if (s != -1) { - int e = line.indexOf(']'); - String number = line.substring(s + 1, e).trim(); - try { - num = Integer.parseInt(number); - } catch (NumberFormatException exc) { - } - } - return num; - } - } diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/gnu/GCCSpecsConsoleParser.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/gnu/GCCSpecsConsoleParser.java index ae95acecb65..0bdb11e6d2e 100644 --- a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/gnu/GCCSpecsConsoleParser.java +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/gnu/GCCSpecsConsoleParser.java @@ -15,12 +15,13 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import org.eclipse.cdt.core.IMarkerGenerator; import org.eclipse.cdt.make.core.scannerconfig.IScannerInfoCollector; import org.eclipse.cdt.make.core.scannerconfig.IScannerInfoConsoleParser; -import org.eclipse.cdt.make.core.scannerconfig.IScannerInfoConsoleParserUtility; import org.eclipse.cdt.make.core.scannerconfig.ScannerInfoTypes; import org.eclipse.cdt.make.internal.core.scannerconfig.util.TraceUtil; import org.eclipse.core.resources.IProject; +import org.eclipse.core.runtime.IPath; /** * Parses output of gcc -c -v specs.c or @@ -34,24 +35,16 @@ public class GCCSpecsConsoleParser implements IScannerInfoConsoleParser { private final String DEFINE = "#define"; //$NON-NLS-1$ private IProject fProject = null; - private IScannerInfoConsoleParserUtility fUtil = null; private IScannerInfoCollector fCollector = null; private boolean expectingIncludes = false; private List symbols = new ArrayList(); private List includes = new ArrayList(); - /* (non-Javadoc) - * @see org.eclipse.cdt.make.core.scannerconfig.IScannerInfoConsoleParser#getUtility() - */ - public IScannerInfoConsoleParserUtility getUtility() { - return null; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.make.core.scannerconfig.IScannerInfoConsoleParser#startup(org.eclipse.core.resources.IProject, org.eclipse.cdt.make.core.scannerconfig.IScannerInfoCollector) - */ - public void startup(IProject project, IScannerInfoCollector collector) { + /* (non-Javadoc) + * @see org.eclipse.cdt.make.core.scannerconfig.IScannerInfoConsoleParser#startup(org.eclipse.core.resources.IProject, org.eclipse.core.runtime.IPath, org.eclipse.cdt.make.core.scannerconfig.IScannerInfoCollector, org.eclipse.cdt.core.IMarkerGenerator) + */ + public void startup(IProject project, IPath workingDirectory, IScannerInfoCollector collector, IMarkerGenerator markerGenerator) { this.fProject = project; this.fCollector = collector; } @@ -107,4 +100,5 @@ public class GCCSpecsConsoleParser implements IScannerInfoConsoleParser { TraceUtil.outputTrace("Scanner info from \'specs\' file", //$NON-NLS-1$ "Include paths", includes, new ArrayList(), "Defined symbols", symbols); //$NON-NLS-1$ //$NON-NLS-2$); } + } diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/util/ScannerInfoConsoleParserUtility.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/gnu/ScannerInfoConsoleParserUtility.java similarity index 64% rename from build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/util/ScannerInfoConsoleParserUtility.java rename to build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/gnu/ScannerInfoConsoleParserUtility.java index 02406dc4ded..ced4454668b 100644 --- a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/util/ScannerInfoConsoleParserUtility.java +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/gnu/ScannerInfoConsoleParserUtility.java @@ -8,7 +8,7 @@ * Contributors: * IBM - Initial API and implementation **********************************************************************/ -package org.eclipse.cdt.make.internal.core.scannerconfig.util; +package org.eclipse.cdt.make.internal.core.scannerconfig.gnu; import java.io.File; import java.io.IOException; @@ -17,12 +17,11 @@ import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; -import java.util.Vector; import org.eclipse.cdt.core.IMarkerGenerator; import org.eclipse.cdt.make.core.MakeCorePlugin; -import org.eclipse.cdt.make.core.scannerconfig.IScannerInfoConsoleParserUtility; import org.eclipse.cdt.make.internal.core.MakeMessages; +import org.eclipse.cdt.make.internal.core.scannerconfig.util.TraceUtil; import org.eclipse.core.resources.IContainer; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IProject; @@ -38,38 +37,22 @@ import org.eclipse.core.runtime.Path; * * @author vhirsl */ -public class ScannerInfoConsoleParserUtility implements IScannerInfoConsoleParserUtility { - private IProject fProject; - private IPath fBaseDirectory; - private IMarkerGenerator fMarkerGenerator; - private ArrayList fErrors; - +public class ScannerInfoConsoleParserUtility extends AbstractGCCBOPConsoleParserUtility { /* * For tracking the location of files being compiled */ private Map fFilesInProject; private List fCollectedFiles; private List fNameConflicts; - private Vector fDirectoryStack; - private boolean fInitialized = false; - - /* (non-Javadoc) - * @see org.eclipse.cdt.make.core.scannerconfig.IScannerInfoConsoleParserUtility#initialize(org.eclipse.core.resources.IProject, org.eclipse.core.runtime.IPath, org.eclipse.cdt.core.IMarkerGenerator) - */ - public void initialize(IProject project, IPath workingDirectory, IMarkerGenerator markerGenerator) { - fInitialized = true; - fProject = project; - fMarkerGenerator = markerGenerator; - fBaseDirectory = fProject.getLocation(); - fErrors = new ArrayList(); - + public ScannerInfoConsoleParserUtility(IProject project, IPath workingDirectory, IMarkerGenerator markerGenerator) { + super(project, workingDirectory, markerGenerator); + fFilesInProject = new HashMap(); fCollectedFiles = new ArrayList(); fNameConflicts = new ArrayList(); - fDirectoryStack = new Vector(); - collectFiles(fProject, fCollectedFiles); + collectFiles(getProject(), fCollectedFiles); for (int i = 0; i < fCollectedFiles.size(); i++) { IFile curr = (IFile) fCollectedFiles.get(i); @@ -78,67 +61,8 @@ public class ScannerInfoConsoleParserUtility implements IScannerInfoConsoleParse fNameConflicts.add(curr.getName()); } } - if (workingDirectory != null) { - pushDirectory(workingDirectory); - } } - public boolean reportProblems() { - if (!fInitialized) - return false; - boolean reset = false; - for (Iterator iter = fErrors.iterator(); iter.hasNext(); ) { - Problem problem = (Problem) iter.next(); - if (problem.severity == IMarkerGenerator.SEVERITY_ERROR_BUILD) { - reset = true; - } - if (problem.file == null) { - fMarkerGenerator.addMarker( - fProject, - problem.lineNumber, - problem.description, - problem.severity, - problem.variableName); - } else { - fMarkerGenerator.addMarker( - problem.file, - problem.lineNumber, - problem.description, - problem.severity, - problem.variableName); - } - } - fErrors.clear(); - return reset; - } - - protected class Problem { - protected IResource file; - protected int lineNumber; - protected String description; - protected int severity; - protected String variableName; - - public Problem(IResource file, int lineNumber, String desciption, int severity, String variableName) { - this.file = file; - this.lineNumber = lineNumber; - this.description = desciption; - this.severity = severity; - this.variableName = variableName; - } - } - - /** - * Called by the console line parsers to generate a problem marker. - */ - public void generateMarker(IResource file, int lineNumber, String desc, int severity, String varName) { - // No need to collect markers if marker generator is not present - if (fMarkerGenerator != null) { - Problem problem = new Problem(file, lineNumber, desc, severity, varName); - fErrors.add(problem); - } - } - /** * Called by the console line parsers to find a file with a given name. * @param fileName @@ -157,7 +81,7 @@ public class ScannerInfoConsoleParserUtility implements IScannerInfoConsoleParse // Create a problem marker final String error = MakeMessages.getString("ConsoleParser.Ambiguous_Filepath_Error_Message"); //$NON-NLS-1$ TraceUtil.outputError(error, fileName); - generateMarker(fProject, -1, error+fileName, IMarkerGenerator.SEVERITY_WARNING, null); + generateMarker(getProject(), -1, error+fileName, IMarkerGenerator.SEVERITY_WARNING, null); } } } @@ -172,8 +96,8 @@ public class ScannerInfoConsoleParserUtility implements IScannerInfoConsoleParse IPath path = null; IPath fp = new Path(filePath); if (fp.isAbsolute()) { - if (fBaseDirectory.isPrefixOf(fp)) { - int segments = fBaseDirectory.matchingFirstSegments(fp); + if (getBaseDirectory().isPrefixOf(fp)) { + int segments = getBaseDirectory().matchingFirstSegments(fp); path = fp.removeFirstSegments(segments); } else { path = fp; @@ -216,13 +140,13 @@ public class ScannerInfoConsoleParserUtility implements IScannerInfoConsoleParse protected IFile findFileInWorkspace(IPath path) { IFile file = null; if (path.isAbsolute()) { - IWorkspaceRoot root = fProject.getWorkspace().getRoot(); + IWorkspaceRoot root = getProject().getWorkspace().getRoot(); file = root.getFileForLocation(path); // It may be a link resource so we must check it also. if (file == null) { IFile[] files = root.findFilesForLocation(path); for (int i = 0; i < files.length; i++) { - if (files[i].getProject().equals(fProject)) { + if (files[i].getProject().equals(getProject())) { file = files[i]; break; } @@ -230,7 +154,7 @@ public class ScannerInfoConsoleParserUtility implements IScannerInfoConsoleParse } } else { - file = fProject.getFile(path); + file = getProject().getFile(path); } return file; } @@ -256,71 +180,6 @@ public class ScannerInfoConsoleParserUtility implements IScannerInfoConsoleParse return fNameConflicts.contains(path.lastSegment()); } - public IPath getWorkingDirectory() { - if (fDirectoryStack.size() != 0) { - return (IPath) fDirectoryStack.lastElement(); - } - // Fallback to the Project Location - // FIXME: if the build did not start in the Project ? - return fBaseDirectory; - } - - protected void pushDirectory(IPath dir) { - if (dir != null) { - IPath pwd = null; - if (fBaseDirectory.isPrefixOf(dir)) { - pwd = dir.removeFirstSegments(fBaseDirectory.segmentCount()); - } else { - // check if it is a cygpath - if (dir.toString().startsWith("/cygdrive/")) { //$NON-NLS-1$ - char driveLetter = dir.toString().charAt(10); - driveLetter = (Character.isLowerCase(driveLetter)) ? Character.toUpperCase(driveLetter) : driveLetter; - StringBuffer buf = new StringBuffer(); - buf.append(driveLetter); - buf.append(':'); - String drive = buf.toString(); - pwd = dir.removeFirstSegments(2); - pwd = pwd.setDevice(drive); - pwd = pwd.makeAbsolute(); - } - else { - pwd = dir; - } - } - fDirectoryStack.addElement(pwd); - } - } - - protected IPath popDirectory() { - int i = getDirectoryLevel(); - if (i != 0) { - IPath dir = (IPath) fDirectoryStack.lastElement(); - fDirectoryStack.removeElementAt(i - 1); - return dir; - } - return new Path(""); //$NON-NLS-1$ - } - - protected int getDirectoryLevel() { - return fDirectoryStack.size(); - } - - public void changeMakeDirectory(String dir, int dirLevel, boolean enterDir) { - if (enterDir) { - /* Sometimes make screws up the output, so - * "leave" events can't be seen. Double-check level - * here. - */ - for (int parseLevel = getDirectoryLevel(); dirLevel < parseLevel; parseLevel = getDirectoryLevel()) { - popDirectory(); - } - pushDirectory(new Path(dir)); - } else { - popDirectory(); - /* Could check to see if they match */ - } - } - public List translateRelativePaths(IFile file, String fileName, List includes) { List translatedIncludes = new ArrayList(includes.size()); for (Iterator i = includes.iterator(); i.hasNext(); ) { @@ -330,7 +189,7 @@ public class ScannerInfoConsoleParserUtility implements IScannerInfoConsoleParse // First try the current working directory IPath cwd = getWorkingDirectory(); if (!cwd.isAbsolute()) { - cwd = fProject.getLocation().append(cwd); + cwd = getProject().getLocation().append(cwd); } IPath filePath = new Path(fileName); diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/util/CCommandDSC.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/util/CCommandDSC.java new file mode 100644 index 00000000000..45e2955813f --- /dev/null +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/util/CCommandDSC.java @@ -0,0 +1,133 @@ +/*********************************************************************** + * Copyright (c) 2004 IBM Corporation 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: + * IBM - Initial API and implementation + ***********************************************************************/ +package org.eclipse.cdt.make.internal.core.scannerconfig.util; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +/** + * Class that represents a compiler command and related scanner configuration + * + * @author vhirsl + */ +public class CCommandDSC { + + private static int ids = 0; + private int commandId; + private List compilerCommand; // members are KVPair objects + private boolean discovered; + private List files; // list of files this command applies to + private boolean cppFileType; // C or C++ file type + // TODO add discovered scanner config + /** + * + */ + public CCommandDSC() { + compilerCommand = new ArrayList(); + discovered = false; + files = null; + cppFileType = false; // assume C file type + commandId = ++ids; + } + + public void addSCOption(KVPair option) { + compilerCommand.add(option); + } + + public void addFile(String fileName) { + if (files == null) { + files = new ArrayList(); + } + if (!files.contains(fileName)) { + files.add(fileName); + if (!cppFileType && !fileName.endsWith(".c")) { + cppFileType = true; + } + } + } + + public int getNumberOfFiles() { + if (files == null) return 0; + return files.size(); + } + + public String getCommandAsString() { + String commandAsString = new String(); + for (Iterator i = compilerCommand.iterator(); i.hasNext(); ) { + KVPair optionPair = (KVPair)i.next(); + commandAsString += optionPair.getKey().toString() + " " + optionPair.getValue() + " "; + } + return commandAsString.trim(); + } + + public int getId() { + return commandId; + } + + /** + * Returns a command where -imacros and -include options have been removed + * @return + */ + public String getSCDRunnableCommand() { + String commandAsString = new String(); + for (Iterator i = compilerCommand.iterator(); i.hasNext(); ) { + KVPair optionPair = (KVPair)i.next(); + if (optionPair.getKey().equals(SCDOptionsEnum.IMACROS_FILE) || + optionPair.getKey().equals(SCDOptionsEnum.INCLUDE_FILE)) + continue; + commandAsString += optionPair.getKey().toString() + " " + optionPair.getValue() + " "; + } + return commandAsString.trim(); + } + + public String[] getImacrosFile() { + List imacrosFiles = new ArrayList(); + for (Iterator i = compilerCommand.iterator(); i.hasNext(); ) { + KVPair optionPair = (KVPair)i.next(); + if (optionPair.getKey().equals(SCDOptionsEnum.IMACROS_FILE)) { + imacrosFiles.add(optionPair.getValue()); + } + } + return (String[]) imacrosFiles.toArray(new String[imacrosFiles.size()]); + } + + public String[] getIncludeFile() { + List includeFiles = new ArrayList(); + for (Iterator i = compilerCommand.iterator(); i.hasNext(); ) { + KVPair optionPair = (KVPair)i.next(); + if (optionPair.getKey().equals(SCDOptionsEnum.INCLUDE_FILE)) { + includeFiles.add(optionPair.getValue()); + } + } + return (String[]) includeFiles.toArray(new String[includeFiles.size()]); + } + + public List getFilesList() { + return files; + } + + /* (non-Javadoc) + * @see java.lang.Object#equals(java.lang.Object) + */ + public boolean equals(Object arg0) { + if (arg0 != null && arg0.getClass().equals(this.getClass())) { + return compilerCommand.equals(((CCommandDSC)arg0).compilerCommand); + } + return false; + } + /* (non-Javadoc) + * @see java.lang.Object#hashCode() + */ + public int hashCode() { + return compilerCommand.hashCode(); + } +} diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/util/KVList.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/util/KVList.java new file mode 100644 index 00000000000..d9bdd2842c4 --- /dev/null +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/util/KVList.java @@ -0,0 +1,45 @@ +/*********************************************************************** + * Copyright (c) 2004 IBM Corporation 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: + * IBM - Initial API and implementation + ***********************************************************************/ +package org.eclipse.cdt.make.internal.core.scannerconfig.util; + +import java.util.ArrayList; +import java.util.List; + +/** + * Key - Value (List) pair + * + * @author vhirsl + */ +public class KVList { + String key; + List value; + + public KVList(String key) { + this.key = key; + this.value = new ArrayList(); + } + + /** + * List must not be null. + */ + public KVList(String key, List value) { + this.key = key; + this.value = value; + } + + String getKey() { + return key; + } + + List getValue() { + return value; + } +} diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/util/KVPair.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/util/KVPair.java new file mode 100644 index 00000000000..a57d9af68ee --- /dev/null +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/util/KVPair.java @@ -0,0 +1,59 @@ +/*********************************************************************** + * Copyright (c) 2004 IBM Corporation 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: + * IBM - Initial API and implementation + ***********************************************************************/ +package org.eclipse.cdt.make.internal.core.scannerconfig.util; + +/** + * Key - Value Pair + * + * @author vhirsl + */ +public class KVPair { + private SCDOptionsEnum key; + private String value; + + /** + * + */ + public KVPair(SCDOptionsEnum key, String value) { + this.key = key; + this.value = value; + } + + public SCDOptionsEnum getKey() { + return key; + } + + public String getValue() { + return value; + } + /* (non-Javadoc) + * @see java.lang.Object#equals(java.lang.Object) + */ + public boolean equals(Object arg0) { + if (arg0 != null && arg0.getClass().equals(this.getClass())) { + KVPair arg = (KVPair) arg0; + return (key.equals(arg.getKey()) && value.equals(arg.getValue())); + } + return false; + } + /* (non-Javadoc) + * @see java.lang.Object#hashCode() + */ + public int hashCode() { + return 17 * key.hashCode() + value.hashCode(); + } + /* (non-Javadoc) + * @see java.lang.Object#toString() + */ + public String toString() { + return key + " -> " + value; + } +} diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/util/SCDOptionsEnum.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/util/SCDOptionsEnum.java new file mode 100644 index 00000000000..0554a52cfc6 --- /dev/null +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/util/SCDOptionsEnum.java @@ -0,0 +1,87 @@ +/*********************************************************************** + * Copyright (c) 2004 IBM Corporation 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: + * IBM - Initial API and implementation + ***********************************************************************/ +package org.eclipse.cdt.make.internal.core.scannerconfig.util; + +/** + * Enumeration class for scanner configuration affecting command line options + * + * @author vhirsl + */ +public final class SCDOptionsEnum { + + public static final SCDOptionsEnum COMMAND = new SCDOptionsEnum(0); // gcc or similar command + public static final int MIN = 1; + public static final SCDOptionsEnum DEFINE = new SCDOptionsEnum(1); // -D name + public static final SCDOptionsEnum UNDEFINE = new SCDOptionsEnum(2); // -U name + public static final SCDOptionsEnum INCLUDE = new SCDOptionsEnum(3); // -I dir + public static final SCDOptionsEnum IDASH = new SCDOptionsEnum(4); // -I- + public static final SCDOptionsEnum NOSTDINC = new SCDOptionsEnum(5); // -nostdinc + public static final SCDOptionsEnum NOSTDINCPP = new SCDOptionsEnum(6); // -nostdinc++ + public static final SCDOptionsEnum INCLUDE_FILE = new SCDOptionsEnum(7); // -include file + public static final SCDOptionsEnum IMACROS_FILE = new SCDOptionsEnum(8); // -imacros file + public static final SCDOptionsEnum IDIRAFTER = new SCDOptionsEnum(9); // -idirafter dir + public static final SCDOptionsEnum ISYSTEM = new SCDOptionsEnum(10); // -isystem dir + public static final SCDOptionsEnum IPREFIX = new SCDOptionsEnum(11); // -iprefix prefix + public static final SCDOptionsEnum IWITHPREFIX = new SCDOptionsEnum(12); // -iwithprefix dir + public static final SCDOptionsEnum IWITHPREFIXBEFORE = new SCDOptionsEnum(13); // -iwithprefixbefore dir + public static final int MAX = 13; + + private static final String[] SCDOPTION_STRING_VALS = { + "", "-D", "-U", "-I", "-I-", "-nostdinc", "-nostdinc++", "-include", "-imacros", + "-idirafter", "-isystem", "-iprefix", "-iwithprefix", "-iwithprefixbefore" + }; + private static final SCDOptionsEnum SCDOPTIONS[] = { + COMMAND, DEFINE, UNDEFINE, INCLUDE, IDASH, NOSTDINC, NOSTDINCPP, INCLUDE_FILE, IMACROS_FILE, + IDIRAFTER, ISYSTEM, IPREFIX, IWITHPREFIX, IWITHPREFIXBEFORE + }; + + /** + * + */ + public SCDOptionsEnum(int val) { + this._enum = val; + } + + public int getEnumValue() { + return _enum; + } + + public static SCDOptionsEnum getSCDOptionsEnum(int val) { + if (val >= 0 && val <= MAX) { + return SCDOPTIONS[val]; + } + return null; + } + + /* (non-Javadoc) + * @see java.lang.Object#equals(java.lang.Object) + */ + public boolean equals(Object arg0) { + if (arg0 == null) return false; + if (arg0 == this) return true; + if (arg0 instanceof SCDOptionsEnum) return (_enum == ((SCDOptionsEnum)arg0)._enum); + return false; + } + /* (non-Javadoc) + * @see java.lang.Object#hashCode() + */ + public int hashCode() { + return _enum*17 + 11; + } + /* (non-Javadoc) + * @see java.lang.Object#toString() + */ + public String toString() { + return SCDOPTION_STRING_VALS[_enum]; + } + + private final int _enum; +} diff --git a/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig2/PerFileSICollector.java b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig2/PerFileSICollector.java new file mode 100644 index 00000000000..3cd7d8bbe7f --- /dev/null +++ b/build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig2/PerFileSICollector.java @@ -0,0 +1,70 @@ +/*********************************************************************** + * Copyright (c) 2004 IBM Corporation 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: + * IBM - Initial API and implementation + ***********************************************************************/ +package org.eclipse.cdt.make.internal.core.scannerconfig2; + +import java.util.List; +import java.util.Map; + +import org.eclipse.cdt.make.core.scannerconfig.IScannerInfoCollector2; +import org.eclipse.cdt.make.core.scannerconfig.ScannerInfoTypes; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; + +/** + * TODO Provide description + * + * @author vhirsl + */ +public class PerFileSICollector implements IScannerInfoCollector2 { + + /** + * + */ + public PerFileSICollector() { + super(); + // TODO Auto-generated constructor stub + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.make.core.scannerconfig.IScannerInfoCollector2#setProject(org.eclipse.core.resources.IProject) + */ + public void setProject(IProject project) { + // TODO Auto-generated method stub + + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.make.core.scannerconfig.IScannerInfoCollector2#updateScannerConfiguration(org.eclipse.core.runtime.IProgressMonitor) + */ + public void updateScannerConfiguration(IProgressMonitor monitor) + throws CoreException { + // TODO Auto-generated method stub + + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.make.core.scannerconfig.IScannerInfoCollector#contributeToScannerConfig(java.lang.Object, java.util.Map) + */ + public void contributeToScannerConfig(Object resource, Map scannerInfo) { + // TODO Auto-generated method stub + + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.make.core.scannerconfig.IScannerInfoCollector#getCollectedScannerInfo(java.lang.Object, org.eclipse.cdt.make.core.scannerconfig.ScannerInfoTypes) + */ + public List getCollectedScannerInfo(Object resource, ScannerInfoTypes type) { + // TODO Auto-generated method stub + return null; + } + +} diff --git a/build/org.eclipse.cdt.managedbuilder.core.tests/suite/org/eclipse/cdt/standardbuilder/core/tests/ScannerConfigConsoleParserTests.java b/build/org.eclipse.cdt.managedbuilder.core.tests/suite/org/eclipse/cdt/standardbuilder/core/tests/ScannerConfigConsoleParserTests.java index eadf218b403..98c543723b0 100644 --- a/build/org.eclipse.cdt.managedbuilder.core.tests/suite/org/eclipse/cdt/standardbuilder/core/tests/ScannerConfigConsoleParserTests.java +++ b/build/org.eclipse.cdt.managedbuilder.core.tests/suite/org/eclipse/cdt/standardbuilder/core/tests/ScannerConfigConsoleParserTests.java @@ -71,7 +71,7 @@ public class ScannerConfigConsoleParserTests extends TestCase { } }; // initialize it with the utility - clParser.startup(null, collector); + clParser.startup(null, null, collector, null); clParser.processLine("gcc -I /dir/include -I C:\\dir\\include -ID:/dir/include -c test.c"); // absolute paths clParser.processLine("gcc -I -I /dir2/include -c test.c"); // empty -I @@ -129,7 +129,7 @@ public class ScannerConfigConsoleParserTests extends TestCase { } }; // initialize it with the utility - clParser.startup(null, collector); + clParser.startup(null, null, collector, null); clParser.processLine("gcc -DMACRO1 -D MACRO2=value2 -c test.c"); // simple definitions clParser.processLine("gcc -D -DMACRO3 -c test.c"); // empty -D @@ -175,7 +175,7 @@ public class ScannerConfigConsoleParserTests extends TestCase { } }; // initialize it with the utility - clParser.startup(null, collector); + clParser.startup(null, null, collector, null); clParser.processLine("gcc -DMACRO1 -I ..\\inc -c ..\\source\\source.c"); // PR 80271