| /******************************************************************************* |
| * Copyright (c) 2005, 2016 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 Corporation - initial API and implementation |
| * Sergey Prigogin (Google) |
| * James Blackburn (Broadcom) - Bug 247838 |
| * Andrew Gvozdev (Quoin Inc) |
| * Dmitry Kozlov (CodeSourcery) - Build error highlighting and navigation |
| * Alex Ruiz (Google) |
| * Serge Beauchamp (Freescale Semiconductor) - Bug 417926 |
| *******************************************************************************/ |
| package org.eclipse.cdt.core; |
| |
| import java.io.IOException; |
| import java.io.OutputStream; |
| import java.net.URI; |
| import java.util.ArrayList; |
| import java.util.LinkedHashMap; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.Vector; |
| |
| import org.eclipse.cdt.core.errorparsers.ErrorParserNamedWrapper; |
| import org.eclipse.cdt.core.language.settings.providers.IWorkingDirectoryTracker; |
| import org.eclipse.cdt.core.resources.ACBuilder; |
| import org.eclipse.cdt.internal.core.Cygwin; |
| import org.eclipse.cdt.internal.core.IErrorMarkeredOutputStream; |
| import org.eclipse.cdt.internal.core.ProblemMarkerFilterManager; |
| import org.eclipse.cdt.internal.core.resources.ResourceLookup; |
| import org.eclipse.cdt.internal.errorparsers.ErrorParserExtensionManager; |
| import org.eclipse.cdt.utils.EFSExtensionManager; |
| import org.eclipse.core.resources.IFile; |
| import org.eclipse.core.resources.IProject; |
| import org.eclipse.core.resources.IResource; |
| import org.eclipse.core.resources.IResourceProxy; |
| import org.eclipse.core.resources.IResourceProxyVisitor; |
| import org.eclipse.core.resources.ResourcesPlugin; |
| import org.eclipse.core.runtime.CoreException; |
| import org.eclipse.core.runtime.IPath; |
| import org.eclipse.core.runtime.Path; |
| import org.eclipse.core.runtime.URIUtil; |
| import org.osgi.service.prefs.BackingStoreException; |
| |
| /** |
| * The purpose of ErrorParserManager is to delegate the work of error parsing |
| * build output to {@link IErrorParser}s, assist in finding {@link IResource}s, and |
| * help create appropriate error/warning/info markers to be displayed |
| * by the Problems view. |
| * |
| * @noextend This class is not intended to be subclassed by clients. |
| */ |
| public class ErrorParserManager extends OutputStream implements IConsoleParser, IWorkingDirectoryTracker { |
| /** |
| * The list of error parsers stored in .project for 3.X projects |
| * as key/value pair with key="org.eclipse.cdt.core.errorOutputParser" |
| * @deprecated since CDT 4.0. |
| */ |
| @Deprecated |
| public final static String PREF_ERROR_PARSER = CCorePlugin.PLUGIN_ID + ".errorOutputParser"; //$NON-NLS-1$ |
| |
| /** |
| * Delimiter for error parsers presented in one string. |
| * @since 5.2 |
| */ |
| public final static char ERROR_PARSER_DELIMITER = ';'; |
| |
| /** |
| * @since 5.4 |
| */ |
| public static final String BUILD_CONTEXT = "build"; //$NON-NLS-1$ |
| |
| private int nOpens; |
| private int lineCounter=0; |
| |
| private final IProject fProject; |
| private final IMarkerGenerator fMarkerGenerator; |
| |
| private Map<String, IErrorParser[]> fErrorParsers; |
| private final List<ProblemMarkerInfo> fErrors; |
| |
| private final Vector<URI> fDirectoryStack; |
| private final URI fBaseDirectoryURI; |
| |
| private String previousLine; |
| private OutputStream outputStream; |
| private final StringBuilder currentLine = new StringBuilder(); |
| |
| private final StringBuilder scratchBuffer = new StringBuilder(); |
| |
| private boolean hasErrors = false; |
| |
| private String cachedFileName = null; |
| private URI cachedWorkingDirectory = null; |
| private IFile cachedFile = null; |
| |
| private static boolean isCygwin = true; |
| |
| /** |
| * Constructor. |
| * |
| * @param builder - project builder. |
| */ |
| public ErrorParserManager(ACBuilder builder) { |
| this(builder.getProject(), builder); |
| } |
| |
| /** |
| * Constructor. |
| * |
| * @param project - project being built. |
| * @param markerGenerator - marker generator able to create markers. |
| */ |
| public ErrorParserManager(IProject project, IMarkerGenerator markerGenerator) { |
| this(project, markerGenerator, null); |
| } |
| |
| /** |
| * Constructor. |
| * |
| * @param project - project being built. |
| * @param markerGenerator - marker generator able to create markers. |
| * @param parsersIDs - array of error parsers' IDs. |
| */ |
| public ErrorParserManager(IProject project, IMarkerGenerator markerGenerator, String[] parsersIDs) { |
| this(project, (URI)null, markerGenerator, parsersIDs); |
| } |
| |
| /** |
| * Constructor. |
| * |
| * @param project - project being built. |
| * @param workingDirectory - IPath location of the working directory of where the build is performed. |
| * @param markerGenerator - marker generator able to create markers. |
| * @param parsersIDs - array of error parsers' IDs. |
| * @deprecated use {@link #ErrorParserManager(IProject, URI, IMarkerGenerator, String[])} instead |
| */ |
| @Deprecated |
| public ErrorParserManager(IProject project, IPath workingDirectory, IMarkerGenerator markerGenerator, String[] parsersIDs) { |
| this(project, (workingDirectory == null || workingDirectory.isEmpty()) ? null : org.eclipse.core.filesystem.URIUtil.toURI(workingDirectory), |
| markerGenerator, parsersIDs); |
| } |
| |
| /** |
| * URI based constructor. |
| * |
| * @param project - project being built. |
| * @param baseDirectoryURI - absolute location URI of working directory of where the build is performed. |
| * @param markerGenerator - marker generator able to create markers. |
| * @param parsersIDs - array of error parsers' IDs. |
| * @since 5.1 |
| */ |
| public ErrorParserManager(IProject project, URI baseDirectoryURI, IMarkerGenerator markerGenerator, String[] parsersIDs) { |
| fProject = project; |
| fMarkerGenerator = markerGenerator; |
| fDirectoryStack = new Vector<URI>(); |
| fErrors = new ArrayList<ProblemMarkerInfo>(); |
| enableErrorParsers(parsersIDs); |
| |
| if (baseDirectoryURI != null) { |
| fBaseDirectoryURI = baseDirectoryURI; |
| } else if (project != null) { |
| fBaseDirectoryURI = project.getLocationURI(); |
| } |
| else { |
| fBaseDirectoryURI = org.eclipse.core.filesystem.URIUtil.toURI(System.getProperty("user.dir")); // CWD //$NON-NLS-1$ |
| } |
| } |
| |
| private void enableErrorParsers(String[] parserIDs) { |
| if (parserIDs == null) { |
| parserIDs = ErrorParserExtensionManager.getDefaultErrorParserIds(); |
| } |
| fErrorParsers = new LinkedHashMap<String, IErrorParser[]>(parserIDs.length); |
| for (String parsersID : parserIDs) { |
| IErrorParser errorParser = getErrorParserCopy(parsersID); |
| if (errorParser!=null) { |
| fErrorParsers.put(parsersID, new IErrorParser[] {errorParser} ); |
| } |
| } |
| } |
| |
| /** |
| * @return current project. |
| */ |
| public IProject getProject() { |
| return fProject; |
| } |
| |
| /** |
| * @return current working directory location where build is being performed. |
| * @deprecated use {@link #getWorkingDirectoryURI()} instead |
| */ |
| @Deprecated |
| public IPath getWorkingDirectory() { |
| return org.eclipse.core.filesystem.URIUtil.toPath(getWorkingDirectoryURI()); |
| } |
| |
| /** |
| * @return the current URI location where the build is being performed |
| * @since 5.1 |
| */ |
| @Override |
| public URI getWorkingDirectoryURI() { |
| if (!fDirectoryStack.isEmpty()) { |
| return fDirectoryStack.lastElement(); |
| } |
| |
| // Fall back to the Project Location / Build directory |
| return fBaseDirectoryURI; |
| } |
| |
| /** |
| * {@link #pushDirectory} and {@link #popDirectory} are used to change working directory |
| * from where file name is searched (see {@link #findFileInWorkspace}). |
| * The intention is to handle make output of commands "pushd dir" and "popd". |
| * |
| * @param dir - another directory level to keep in stack -- corresponding to 'pushd'. |
| */ |
| public void pushDirectory(IPath dir) { |
| if (dir != null) { |
| URI uri = toURI(dir); |
| pushDirectoryURI(uri); |
| } |
| } |
| |
| /** |
| * {@link #pushDirectoryURI} and {@link #popDirectoryURI} are used to change working directory |
| * from where file name is searched (see {@link #findFileInWorkspace}). |
| * The intention is to handle make output of commands "pushd dir" and "popd". |
| * |
| * @param dir - another directory level to keep in stack -- corresponding to 'pushd'. |
| * @since 5.1 |
| */ |
| public void pushDirectoryURI(URI dir) { |
| if (dir != null) { |
| if (dir.isAbsolute()) { |
| fDirectoryStack.addElement(dir); |
| } else { |
| fDirectoryStack.addElement(URIUtil.makeAbsolute(dir, getWorkingDirectoryURI())); |
| } |
| } |
| } |
| |
| /** |
| * {@link #pushDirectory} and {@link #popDirectory} are used to change working directory |
| * from where file name is searched (see {@link #findFileInWorkspace}). |
| * The intention is to handle make output of commands "pushd" and "popd". |
| * |
| * @return previous build directory location corresponding 'popd' command. |
| * @deprecated use {@link #popDirectoryURI()} instead |
| */ |
| @Deprecated |
| public IPath popDirectory() { |
| return org.eclipse.core.filesystem.URIUtil.toPath(popDirectoryURI()); |
| } |
| |
| /** |
| * {@link #pushDirectoryURI(URI)} and {@link #popDirectoryURI()} are used to change working directory |
| * from where file name is searched (see {@link #findFileInWorkspace(IPath)}). |
| * The intention is to handle make output of commands "pushd" and "popd". |
| * |
| * @return previous build directory location corresponding 'popd' command. |
| * @since 5.1 |
| */ |
| public URI popDirectoryURI() { |
| int i = fDirectoryStack.size(); |
| if (i != 0) { |
| URI dir = fDirectoryStack.lastElement(); |
| fDirectoryStack.removeElementAt(i - 1); |
| return dir; |
| } |
| return fBaseDirectoryURI; |
| } |
| |
| /** |
| * @return number of directories in the stack. |
| */ |
| public int getDirectoryLevel() { |
| return fDirectoryStack.size(); |
| } |
| |
| /** |
| * This function used to populate member fFilesInProject which is not necessary |
| * anymore. Now {@link ResourceLookup} is used for search and not collection of files |
| * kept by {@code ErrorParserManager}. |
| * @param parent - project. |
| * @param result - resulting collection of files. |
| * |
| * @deprecated Use {@link #findFileName} for searches. |
| */ |
| @Deprecated |
| protected void collectFiles(IProject parent, final List<IResource> result) { |
| try { |
| parent.accept(new IResourceProxyVisitor() { |
| @Override |
| public boolean visit(IResourceProxy proxy) { |
| if (proxy.getType() == IResource.FILE) { |
| result.add(proxy.requestResource()); |
| return false; |
| } |
| return true; |
| } |
| }, IResource.NONE); |
| } catch (CoreException e) { |
| CCorePlugin.log(e.getStatus()); |
| } |
| } |
| |
| /** |
| * Parses one line of output and generates error or warning markers. |
| * @since 5.4 |
| */ |
| @Override |
| public boolean processLine(String line) { |
| String lineTrimmed = line.trim(); |
| lineCounter++; |
| |
| ProblemMarkerInfo marker=null; |
| |
| outer: |
| for (IErrorParser[] parsers : fErrorParsers.values()) { |
| for (IErrorParser parser : parsers) { |
| IErrorParser curr = parser; |
| if (parser instanceof ErrorParserNamedWrapper) { |
| curr = ((ErrorParserNamedWrapper)parser).getErrorParser(); |
| } |
| int types = IErrorParser2.NONE; |
| if (curr instanceof IErrorParser2) { |
| types = ((IErrorParser2) curr).getProcessLineBehaviour(); |
| } |
| if ((types & IErrorParser2.KEEP_LONGLINES) == 0) { |
| // long lines are not given to parsers, unless it wants it |
| if (lineTrimmed.length() > 1000) { |
| continue; |
| } |
| } |
| // standard behavior (pre 5.1) is to trim the line |
| String lineToParse = lineTrimmed; |
| if ((types & IErrorParser2.KEEP_UNTRIMMED) !=0 ) { |
| // untrimmed lines |
| lineToParse = line; |
| } |
| |
| boolean consume = false; |
| // Protect against rough parsers who may accidentally |
| // throw an exception on a line they can't handle. |
| // It should not stop parsing of the rest of output. |
| try { |
| consume = curr.processLine(lineToParse, this); |
| } catch (Exception e){ |
| String id = ""; //$NON-NLS-1$ |
| if (parser instanceof IErrorParserNamed) { |
| id = ((IErrorParserNamed) parser).getId(); |
| } |
| @SuppressWarnings("nls") |
| String message = "Errorparser " + id + " failed parsing line [" + lineToParse + "]"; |
| CCorePlugin.log(message, e); |
| } finally { |
| if (fErrors.size() > 0) { |
| if (marker==null) { |
| marker = fErrors.get(0); |
| } |
| fErrors.clear(); |
| } |
| } |
| |
| if (consume) { |
| break outer; |
| } |
| } |
| } |
| outputLine(line, marker); |
| |
| return false; |
| } |
| |
| /** |
| * Conditionally output line to outputStream. If stream |
| * supports error markers, use it, otherwise use conventional stream |
| */ |
| private void outputLine(String line, ProblemMarkerInfo marker) { |
| String l = line + "\n"; //$NON-NLS-1$ |
| if ( outputStream == null ) { |
| return; |
| } |
| try { |
| if ( marker != null && outputStream instanceof IErrorMarkeredOutputStream ) { |
| IErrorMarkeredOutputStream s = (IErrorMarkeredOutputStream) outputStream; |
| s.write(l, marker); |
| } else { |
| byte[] b = l.getBytes(); |
| outputStream.write(b, 0, b.length); |
| } |
| } catch (IOException e) { |
| CCorePlugin.log(e); |
| } |
| } |
| |
| /** |
| * @return counter counting processed lines of output |
| * @since 5.2 |
| */ |
| public int getLineCounter() { |
| return lineCounter; |
| } |
| |
| /** |
| * Returns the file with the given (partial) location if that file can be uniquely identified. |
| * Otherwise returns {@code null}. |
| * <br><br> |
| * The passed in String 'partialLoc' is treated as a partial filesystem location for the |
| * resource. Resolution is attempted with the following precedence:<br> |
| * If partialLoc is an absolute fs location:<br> |
| * - Resolve it to an IFile in the Project<br> |
| * - Resolve it to an IFile in the Workspace<br> |
| * If partialLoc is a relative path:<br> |
| * - Resolve it relative to the Current Working Directory<br> |
| * - Resolve just the segments provided<br> |
| * |
| * @param partialLoc - file name could be plain file name, absolute path or partial path |
| * @return - file in the workspace or {@code null}. |
| */ |
| public IFile findFileName(String partialLoc) { |
| if (partialLoc.equals(cachedFileName) && cachedWorkingDirectory != null && |
| org.eclipse.core.filesystem.URIUtil.equals(getWorkingDirectoryURI(), cachedWorkingDirectory)) { |
| return cachedFile; |
| } |
| |
| // To be able to parse Windows paths on Linux systems, see bug 263977 |
| IPath path = new Path(partialLoc.replace('\\', IPath.SEPARATOR)); |
| |
| // Try to find exact match. If path is not absolute - searching in working directory. |
| IFile file = findFileInWorkspace(path); |
| |
| // Try to find best match considering known partial path |
| if (file==null) { |
| path = path.setDevice(null); |
| IFile[] files = null; |
| if (fProject != null) { |
| IProject[] prjs = new IProject[] { fProject }; |
| files = ResourceLookup.findFilesByName(path, prjs, false); |
| if (files.length == 0) { |
| files = ResourceLookup.findFilesByName(path, prjs, /* ignoreCase */ true); |
| } |
| } |
| if (files == null || files.length == 0) { |
| IProject[] prjs = ResourcesPlugin.getWorkspace().getRoot().getProjects(); |
| files = ResourceLookup.findFilesByName(path, prjs, false); |
| if (files.length == 0) { |
| files = ResourceLookup.findFilesByName(path, prjs, /* ignoreCase */ true); |
| } |
| } |
| if (files.length == 1) { |
| file = files[0]; |
| } |
| } |
| |
| // Could be cygwin path |
| if (file==null && isCygwin && path.isAbsolute()) { |
| file = findCygwinFile(partialLoc); |
| } |
| |
| cachedFileName = partialLoc; |
| cachedWorkingDirectory = getWorkingDirectoryURI(); |
| cachedFile = file; |
| return file; |
| } |
| |
| /** |
| * Find exact match in the workspace. If path is not absolute search is done in working directory. |
| * |
| * @param path - file path. |
| * @return - file in the workspace or {@code null} if such a file doesn't exist |
| */ |
| protected IFile findFileInWorkspace(IPath path) { |
| URI uri = toURI(path); |
| IFile file = findFileInWorkspace(uri); |
| return file; |
| } |
| |
| /** |
| * Find exact match in the workspace. If path is not absolute search is done in the current working directory. |
| * |
| * @param uri - absolute or relative URI to resolve. |
| * @return - file in the workspace or {@code null} if such a file doesn't exist |
| * @since 5.1 |
| */ |
| protected IFile findFileInWorkspace(URI uri) { |
| if (!uri.isAbsolute()) { |
| uri = URIUtil.makeAbsolute(uri, getWorkingDirectoryURI()); |
| } |
| |
| IFile f = ResourceLookup.selectFileForLocationURI(uri, fProject); |
| if (f != null && f.isAccessible()) { |
| return f; |
| } |
| return null; |
| } |
| |
| /** |
| * @param fileName - file name. |
| * @return {@code true} if the project contains more than one file with the given name. |
| * |
| * @deprecated Use {@link #findFileName} for searches. |
| */ |
| @Deprecated |
| public boolean isConflictingName(String fileName) { |
| return ResourceLookup.findFilesByName(new Path(fileName), new IProject[] {fProject}, false).length > 1; |
| } |
| |
| /** |
| * Called by the error parsers to find an IFile for a given |
| * external filesystem 'location' |
| * |
| * @param filePath - file path. |
| * @return IFile representing the external location, or null if one |
| * couldn't be found. |
| * |
| * @deprecated Use {@link #findFileName} for searches. |
| */ |
| @Deprecated |
| public IFile findFilePath(String filePath) { |
| IPath path = new Path(filePath); |
| IFile file = findFileInWorkspace(path); |
| |
| // That didn't work, see if it is a cygpath |
| if (file == null && isCygwin) { |
| file = findCygwinFile(filePath); |
| } |
| |
| return (file != null && file.exists()) ? file : null; |
| } |
| |
| private IFile findCygwinFile(String filePath) { |
| IFile file=null; |
| try { |
| IPath path = new Path(Cygwin.cygwinToWindowsPath(filePath)); |
| file = findFileInWorkspace(path); |
| } catch (UnsupportedOperationException e) { |
| isCygwin = false; |
| } catch (Exception e) { |
| } |
| return file; |
| } |
| |
| /** |
| * Add marker to the list of error markers. |
| * |
| * @param file - resource to add the new marker. |
| * @param lineNumber - line number of the error. |
| * @param desc - description of the error. |
| * @param severity - severity of the error. |
| * @param varName - variable name. |
| */ |
| public void generateMarker(IResource file, int lineNumber, String desc, int severity, String varName) { |
| generateExternalMarker(file, lineNumber, desc, severity, varName, null); |
| } |
| |
| /** |
| * Add marker to the list of error markers. |
| * |
| * @param file - resource to add the new marker. |
| * @param lineNumber - line number of the error. |
| * @param desc - description of the error. |
| * @param severity - severity of the error, one of |
| * <br>{@link IMarkerGenerator#SEVERITY_INFO}, |
| * <br>{@link IMarkerGenerator#SEVERITY_WARNING}, |
| * <br>{@link IMarkerGenerator#SEVERITY_ERROR_RESOURCE}, |
| * <br>{@link IMarkerGenerator#SEVERITY_ERROR_BUILD} |
| * @param varName - variable name. |
| * @param externalPath - external path pointing to a file outside the workspace. |
| */ |
| public void generateExternalMarker(IResource file, int lineNumber, String desc, int severity, String varName, IPath externalPath) { |
| if (file == null) |
| file = fProject; |
| ProblemMarkerInfo problemMarkerInfo = new ProblemMarkerInfo(file, lineNumber, desc, severity, varName, externalPath); |
| this.addProblemMarker(problemMarkerInfo); |
| } |
| |
| /** |
| * Add the given marker to the list of error markers. |
| * |
| * @param problemMarkerInfo - The marker to be added. |
| * @since 5.4 |
| */ |
| public void addProblemMarker(ProblemMarkerInfo problemMarkerInfo){ |
| if ( ! ProblemMarkerFilterManager.getInstance().acceptMarker(problemMarkerInfo) ) |
| return; |
| fErrors.add(problemMarkerInfo); |
| fMarkerGenerator.addMarker(problemMarkerInfo); |
| if (problemMarkerInfo.severity == IMarkerGenerator.SEVERITY_ERROR_RESOURCE) { |
| hasErrors = true; |
| } |
| } |
| |
| /** |
| * Called by the error parsers. |
| * @return the previous line, save in the working buffer. |
| */ |
| public String getPreviousLine() { |
| return previousLine == null ? "" : previousLine; //$NON-NLS-1$ |
| } |
| |
| /** |
| * Method setOutputStream. |
| * Note: you have to close this stream explicitly |
| * don't rely on ErrorParserManager.close(). |
| * @param os - output stream |
| */ |
| public void setOutputStream(OutputStream os) { |
| outputStream = os; |
| } |
| |
| /** |
| * Method getOutputStream. |
| * Note: you have to close this stream explicitly |
| * don't rely on ErrorParserManager.close(). |
| * @return OutputStream |
| */ |
| public OutputStream getOutputStream() { |
| nOpens++; |
| return this; |
| } |
| |
| /** |
| * @see java.io.OutputStream#close() |
| * Note: don't rely on this method to close underlying OutputStream, |
| * close it explicitly |
| */ |
| @Override |
| public synchronized void close() throws IOException { |
| if (nOpens > 0 && --nOpens == 0) { |
| checkLine(true); |
| fDirectoryStack.removeAllElements(); |
| } |
| } |
| |
| /** |
| * @see java.io.OutputStream#flush() |
| */ |
| @Override |
| public void flush() throws IOException { |
| if (outputStream != null) { |
| outputStream.flush(); |
| } |
| } |
| |
| /** |
| * @see java.io.OutputStream#write(int) |
| */ |
| @Override |
| public synchronized void write(int b) throws IOException { |
| currentLine.append((char) b); |
| checkLine(false); |
| } |
| |
| @Override |
| public synchronized void write(byte[] b, int off, int len) throws IOException { |
| if (b == null) { |
| throw new NullPointerException(); |
| } else if (off != 0 || (len < 0) || (len > b.length)) { |
| throw new IndexOutOfBoundsException(); |
| } else if (len == 0) { |
| return; |
| } |
| currentLine.append(new String(b, 0, len)); |
| checkLine(false); |
| } |
| |
| // This method examines contents of currentLine buffer |
| // if it contains whole line this line is checked by error |
| // parsers (processLine method). |
| // If flush is true rest of line is checked by error parsers. |
| private void checkLine(boolean flush) { |
| String buffer = currentLine.toString(); |
| int i = 0; |
| while ((i = buffer.indexOf('\n')) != -1) { |
| String line = buffer.substring(0, i); |
| // get rid of any trailing '\r' |
| if (line.endsWith("\r")) { //$NON-NLS-1$ |
| line=line.substring(0,line.length()-1); |
| } |
| processLine(line); |
| previousLine = line; |
| buffer = buffer.substring(i + 1); // skip the \n and advance |
| } |
| currentLine.setLength(0); |
| if (flush) { |
| if (buffer.length() > 0) { |
| processLine(buffer); |
| previousLine = buffer; |
| } |
| } else { |
| currentLine.append(buffer); |
| } |
| } |
| |
| /** |
| * @deprecated as of 5.2. This method is no longer reporting problems. |
| * The problem markers are generated after processing each line. |
| * |
| * @return {@code true} if detected a problem indicating that build failed. |
| * The semantics of the return code is inconsistent. As far as build is concerned |
| * there is no difference between errors |
| * {@link IMarkerGenerator#SEVERITY_ERROR_RESOURCE} and |
| * {@link IMarkerGenerator#SEVERITY_ERROR_BUILD} |
| */ |
| @Deprecated |
| public boolean reportProblems() { |
| return false; |
| } |
| |
| /** |
| * Converts a location {@link IPath} to an {@link URI}. |
| * The returned URI uses the scheme and authority of the current working directory |
| * as returned by {@link #getWorkingDirectoryURI()} |
| * |
| * @param path - the path to convert to URI. |
| * @return URI |
| * @since 5.1 |
| */ |
| private URI toURI(IPath path) { |
| URI uri = null; |
| URI workingDirectoryURI = getWorkingDirectoryURI(); |
| if (path.isAbsolute()) { |
| uri = EFSExtensionManager.getDefault().createNewURIFromPath(workingDirectoryURI, path.toString()); |
| } else { |
| uri = EFSExtensionManager.getDefault().append(workingDirectoryURI, path.toString()); |
| } |
| |
| return uri; |
| } |
| |
| /** |
| * @return scratch buffer. |
| * @deprecated Use IErrorParser2 interface to handle multiline messages rather than scratch buffer. |
| */ |
| @Deprecated |
| public String getScratchBuffer() { |
| return scratchBuffer.toString(); |
| } |
| |
| /** |
| * @param line - input line. |
| * @deprecated Use IErrorParser2 interface to handle multiline messages rather than scratch buffer. |
| */ |
| @Deprecated |
| public void appendToScratchBuffer(String line) { |
| scratchBuffer.append(line); |
| } |
| |
| /** |
| * @deprecated Use IErrorParser2 interface to handle multiline messages rather than scratch buffer. |
| */ |
| @Deprecated |
| public void clearScratchBuffer() { |
| scratchBuffer.setLength(0); |
| } |
| |
| /** |
| * @return {@code true} if errors attributed to resources detected |
| * |
| * @deprecated The semantics of this function is inconsistent. As far as build is concerned |
| * there is no difference between errors |
| * {@link IMarkerGenerator#SEVERITY_ERROR_RESOURCE} and |
| * {@link IMarkerGenerator#SEVERITY_ERROR_BUILD} |
| */ |
| @Deprecated |
| public boolean hasErrors() { |
| return hasErrors; |
| } |
| |
| /** |
| * @return default error parsers IDs to be used if error parser list is empty. |
| * @since 5.3 |
| */ |
| public static String[] getUserDefinedErrorParserIds() { |
| return ErrorParserExtensionManager.getUserDefinedErrorParserIds(); |
| } |
| |
| /** |
| * Set and store in workspace area user defined error parsers. |
| * |
| * @param errorParsers - array of user defined error parsers |
| * @throws CoreException in case of problems |
| * @since 5.2 |
| */ |
| public static void setUserDefinedErrorParsers(IErrorParserNamed[] errorParsers) throws CoreException { |
| ErrorParserExtensionManager.setUserDefinedErrorParsers(errorParsers); |
| } |
| |
| /** |
| * @return available error parsers IDs which include contributed through extension + user defined ones |
| * from workspace |
| * @since 5.2 |
| */ |
| public static String[] getErrorParserAvailableIds() { |
| return ErrorParserExtensionManager.getErrorParserAvailableIds(); |
| } |
| |
| /** |
| * @param context - indicates the context in which an error parser can be used. |
| * @return available error parsers ID, which include contributed through extension and user- |
| * defined ones from workspace, that can be used in the given context. |
| * @since 5.4 |
| */ |
| public static String[] getErrorParserAvailableIdsInContext(String context) { |
| return ErrorParserExtensionManager.getErrorParserAvailableIdsInContext(context); |
| } |
| |
| /** |
| * @return IDs of error parsers contributed through error parser extension point. |
| * @since 5.2 |
| */ |
| public static String[] getErrorParserExtensionIds() { |
| return ErrorParserExtensionManager.getErrorParserExtensionIds(); |
| } |
| |
| /** |
| * Set and store default error parsers IDs to be used if error parser list is empty. |
| * |
| * @param ids - default error parsers IDs |
| * @throws BackingStoreException in case of problem with storing |
| * @since 5.2 |
| */ |
| public static void setDefaultErrorParserIds(String[] ids) throws BackingStoreException { |
| ErrorParserExtensionManager.setDefaultErrorParserIds(ids); |
| } |
| |
| /** |
| * @return default error parsers IDs to be used if error parser list is empty. |
| * @since 5.2 |
| */ |
| public static String[] getDefaultErrorParserIds() { |
| return ErrorParserExtensionManager.getDefaultErrorParserIds(); |
| } |
| |
| /** |
| * @param id - ID of error parser |
| * @return cloned copy of error parser or {@code null}. |
| * Note that {@link ErrorParserNamedWrapper} returns shallow copy with the same instance |
| * of underlying error parser. |
| * @since 5.2 |
| */ |
| public static IErrorParserNamed getErrorParserCopy(String id) { |
| return ErrorParserExtensionManager.getErrorParserCopy(id, false); |
| } |
| |
| /** |
| * @param id - ID of error parser |
| * @return cloned copy of error parser as defined by its extension point or {@code null}. |
| * @since 5.3 |
| */ |
| public static IErrorParserNamed getErrorParserExtensionCopy(String id) { |
| return ErrorParserExtensionManager.getErrorParserCopy(id, true); |
| } |
| |
| /** |
| * @param ids - array of error parser IDs |
| * @return error parser IDs delimited with error parser delimiter ";" |
| * @since 5.2 |
| */ |
| public static String toDelimitedString(String[] ids) { |
| String result=""; //$NON-NLS-1$ |
| for (String id : ids) { |
| if (result.length()==0) { |
| result = id; |
| } else { |
| result += ERROR_PARSER_DELIMITER + id; |
| } |
| } |
| return result; |
| } |
| |
| /** |
| * @since 5.4 |
| */ |
| @Override |
| public void shutdown() { |
| for (IErrorParser[] parsers : fErrorParsers.values()) { |
| for (IErrorParser parser : parsers) { |
| if (parser instanceof IErrorParser3) { |
| ((IErrorParser3) parser).shutdown(); |
| } |
| } |
| } |
| } |
| } |