diff options
Diffstat (limited to 'build/org.eclipse.cdt.autotools.core/src/org/eclipse/cdt/internal/autotools/core/ErrorParser.java')
-rw-r--r-- | build/org.eclipse.cdt.autotools.core/src/org/eclipse/cdt/internal/autotools/core/ErrorParser.java | 233 |
1 files changed, 233 insertions, 0 deletions
diff --git a/build/org.eclipse.cdt.autotools.core/src/org/eclipse/cdt/internal/autotools/core/ErrorParser.java b/build/org.eclipse.cdt.autotools.core/src/org/eclipse/cdt/internal/autotools/core/ErrorParser.java new file mode 100644 index 00000000000..b35599bc99a --- /dev/null +++ b/build/org.eclipse.cdt.autotools.core/src/org/eclipse/cdt/internal/autotools/core/ErrorParser.java @@ -0,0 +1,233 @@ +/******************************************************************************* + * Copyright (c) 2010 Red Hat Inc. + * 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: + * Red Hat Inc. - initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.autotools.core; + +import java.io.File; +import java.io.FileReader; +import java.io.LineNumberReader; +import java.lang.reflect.Method; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.eclipse.cdt.autotools.core.AutotoolsPlugin; +import org.eclipse.cdt.core.IErrorParser; +import org.eclipse.cdt.core.ProblemMarkerInfo; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.Path; + +// This class would normally extend IErrorParser and use the CDT error parser +// extension. However, we want an extended IMarker that contains library info and +// possibly other data in the future. The standard CDT ErrorParserManager doesn't allow +// us to pass an extended ProblemMarkerInfo, so we are forced to have our own mechanism +// which is similar to the CDT one. +public class ErrorParser extends MarkerGenerator implements IErrorParser{ + + public static final String ID = AutotoolsPlugin.PLUGIN_ID + ".errorParser"; //$NON-NLS-1$ + private Pattern pkgconfigError = + Pattern.compile(".*?(configure:\\s+error:\\s+Package requirements\\s+\\((.*?)\\)\\s+were not met).*"); //$NON-NLS-1$ + private Pattern genconfigError = + Pattern.compile(".*?configure:\\s+error:\\s+(.*)"); //$NON-NLS-1$ + private Pattern checkingFail = + Pattern.compile("checking for (.*)\\.\\.\\. no"); //$NON-NLS-1$ + + private Pattern changingConfigDirectory = + Pattern.compile("Configuring in (.*)"); //$NON-NLS-1$ + + private IPath buildDir; + private IPath sourcePath; + private IProject project; + + public ErrorParser(){ + } + + public ErrorParser(IPath sourcePath, IPath buildPath) { + this.buildDir = buildPath; + this.sourcePath = sourcePath; + } + + public boolean processLine(String line, + org.eclipse.cdt.core.ErrorParserManager eoParser) { + + if (this.project == null) + this.project = eoParser.getProject(); + + if (this.buildDir == null) + this.buildDir = new Path(eoParser.getWorkingDirectoryURI().getPath()); + + if (this.sourcePath == null) + this.sourcePath = eoParser.getProject().getLocation(); + + AutotoolsProblemMarkerInfo marker = processLine(line); + if ( marker != null){ + // Check to see if addProblemMarker exists. + try { + Method method = eoParser.getClass().getMethod("addProblemMarker", ProblemMarkerInfo.class); + try { + method.invoke(eoParser, marker); + return true; + } catch (Exception e) { + throw new RuntimeException(e); + } + } catch (SecurityException e) { + return false; + } catch (NoSuchMethodException e) { + return false; + } + } + return false; + } + + public boolean processLine(String line, ErrorParserManager eoParser) { + if (this.project == null) + this.project = eoParser.getProject(); + + AutotoolsProblemMarkerInfo marker = processLine(line); + if ( marker != null){ + eoParser.addProblemMarker(marker); + return true; + } + return false; + } + + public AutotoolsProblemMarkerInfo processLine(String line) { + Matcher m; + + m = changingConfigDirectory.matcher(line); + if(m.matches()){ + // set configuration directory. + this.buildDir = this.buildDir.append(m.group(1)); + this.sourcePath = this.sourcePath.append(m.group(1)); + return null; + } + + m = pkgconfigError.matcher(line); + if (m.matches()) { + return new AutotoolsProblemMarkerInfo(getProject(), -1, m.group(1), SEVERITY_ERROR_BUILD, null, null, m.group(2), AutotoolsProblemMarkerInfo.Type.PACKAGE); + } + + m = genconfigError.matcher(line); + if (m.matches()) { + return new AutotoolsProblemMarkerInfo(getProject(), -1, m.group(1), SEVERITY_ERROR_BUILD, null, + AutotoolsProblemMarkerInfo.Type.GENERIC); + } + + m = checkingFail.matcher(line); + if (m.matches()) { + // We know that there is a 'checking for ...' fail. + // Find the log file containing this check + AutotoolsProblemMarkerInfo.Type type = getCheckType(m.group(1)); + if (type != null) + return new AutotoolsProblemMarkerInfo(getProject(), "Missing " + type + " " + m.group(1), SEVERITY_INFO, m.group(1), type); + } + + return null; + } + + /** + * Given the name of the filed check object, look for it in the log file + * file and then examine the configure script to figure out what the type of + * the check was. + * + * @param name + * @return + */ + private AutotoolsProblemMarkerInfo.Type getCheckType(String name) { + int lineNumber = getErrorConfigLineNumber(name); + + // now open configure file. + File file = new File(sourcePath + "/configure"); + // If the log file is not present there is nothing we can do. + if (!file.exists()) + return null; + + FileReader stream; + try { + stream = new FileReader(file); + LineNumberReader reader = new LineNumberReader(stream); + + // look for something like: + // if test "${ac_cv_prog_WINDRES+set}" = set; then : + Pattern errorPattern = Pattern.compile(".*ac_cv_([a-z]*)_.*"); //$NON-NLS-1$ + + // skip to the line + String line = reader.readLine(); + for (int i = 0; i < lineNumber + 10 && line != null; i++) { + if (i < lineNumber) { + line = reader.readLine(); + continue; + } + Matcher m = errorPattern.matcher(line); + if (m.matches()) { + String typeString = m.group(1); + if (typeString.equals("prog")) + return AutotoolsProblemMarkerInfo.Type.PROG; + if (typeString.equals("header")) + return AutotoolsProblemMarkerInfo.Type.HEADER; + if (typeString.equals("file")) + return AutotoolsProblemMarkerInfo.Type.FILE; + + return null; + } + line = reader.readLine(); + } + stream.close(); + + } catch (Exception e) { + throw new RuntimeException(e); + } + + return null; + } + + /** + * Check the log file for the check for the given name and return the line + * number in configure where the check occurs. + * + * @param name + * @return + */ + private int getErrorConfigLineNumber(String name) { + try { + File file = new File(buildDir + "/config.log"); + // If the log file is not present there is nothing we can do. + if (!file.exists()) + return -1; + + FileReader stream = new FileReader(file); + LineNumberReader reader = new LineNumberReader(stream); + + Pattern errorPattern = Pattern + .compile("configure:(\\d+): checking for " + name); //$NON-NLS-1$ + String line = reader.readLine(); + while (line != null) { + Matcher m = errorPattern.matcher(line); + + if (m.matches()) { + return Integer.parseInt(m.group(1)); + } + + line = reader.readLine(); + } + stream.close(); + + } catch (Exception e) { + return -1; + } + return -1; + } + + @Override + public IProject getProject() { + return this.project; + } + +} |