/******************************************************************************* * Copyright (c) 2015 Ericsson 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 *******************************************************************************/ package org.eclipse.cdt.cmake; import java.net.URI; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.eclipse.cdt.core.ErrorParserManager; import org.eclipse.cdt.core.IErrorParser; import org.eclipse.cdt.core.IMarkerGenerator; import org.eclipse.cdt.utils.EFSExtensionManager; import org.eclipse.core.filesystem.URIUtil; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.Path; /** * Error Parser for CMake command on stderr */ public class CMakeErrorParserStdErr implements IErrorParser/*, IErrorParser4 */{ public static final String ID = "org.eclipse.cdt.cmake.errorParserStderr"; //$NON-NLS-1$ enum ErrorParserState { NONE, INTRO, FIlE_PATH, } private ErrorParserState state = ErrorParserState.NONE; /* * CMake Error: Error in cmake code at * /Users/mark/Documents/dev/eclipse-old/workspace/runtime-CDT/testCMake2/ * CMakeLists.txt:32: Parse error. Function missing ending ")". End of file * reached. */ private static Pattern multiLineErrorIntro = Pattern.compile("CMake Error:.*"); private static Pattern multiLineErrorFilePath = Pattern.compile("(.*):(\\d+):"); /* * CMake Error at CMakeLists.txt:10 (seasdt): * Unknown CMake command "seasdt". */ private static Pattern multiLineErrorIntroAndFilePath = Pattern.compile("CMake Error at (.*):(\\d+)\\s*.*:"); private static Pattern multiLineErrorMessage = Pattern.compile(".*");; private String currentError = ""; private String filePath = ""; private int lineNumber = 0; @Override public boolean processLine(String line, ErrorParserManager eoParser) { switch (state) { case NONE: { if (multiLineErrorIntro.matcher(line).matches()) { currentError = line; state = ErrorParserState.INTRO; } else { Matcher matcher = multiLineErrorIntroAndFilePath.matcher(line); if (matcher.matches()) { filePath = matcher.group(1); try { lineNumber = Integer.parseInt(matcher.group(2)); } catch (NumberFormatException e) { break; } currentError = ""; state = ErrorParserState.FIlE_PATH; } } break; } case INTRO: { state = ErrorParserState.NONE; Matcher matcher = multiLineErrorFilePath.matcher(line); if (matcher.matches()) { filePath = matcher.group(1); try { lineNumber = Integer.parseInt(matcher.group(2)); } catch (NumberFormatException e) { break; } currentError = ""; state = ErrorParserState.FIlE_PATH; } break; } case FIlE_PATH: state = ErrorParserState.NONE; Matcher matcher = multiLineErrorMessage.matcher(line); if (matcher.matches()) { currentError += line; IPath path = new Path(filePath); URI uri = toURI(path, eoParser); path = URIUtil.toPath(uri); IFile[] foundFiles = ResourcesPlugin.getWorkspace().getRoot().findFilesForLocationURI(URIUtil.toURI(path)); IFile resource = foundFiles.length > 0 && foundFiles[0] != null && foundFiles[0].exists() ? foundFiles[0] : null; IPath externalPath = resource == null ? path : null; eoParser.generateExternalMarker(resource, lineNumber, currentError, IMarkerGenerator.SEVERITY_ERROR_RESOURCE, "", externalPath); return true; } break; } 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. * @param errParserManager * @return URI */ private URI toURI(IPath path, ErrorParserManager errParserManager) { URI uri = null; URI workingDirectoryURI = errParserManager.getWorkingDirectoryURI(); if (path.isAbsolute()) { uri = EFSExtensionManager.getDefault().createNewURIFromPath(workingDirectoryURI, path.toString()); } else { uri = EFSExtensionManager.getDefault().append(workingDirectoryURI, path.toString()); } return uri; } // TODO: Uncomment once CDT contains IErrorParser4 // @Override // public int getStreamType() { // return IErrorParser4.PARSE_STDERR; // } }