aboutsummaryrefslogtreecommitdiff
path: root/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/RenderScriptLauncher.java
diff options
context:
space:
mode:
Diffstat (limited to 'eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/RenderScriptLauncher.java')
-rw-r--r--eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/RenderScriptLauncher.java244
1 files changed, 244 insertions, 0 deletions
diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/RenderScriptLauncher.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/RenderScriptLauncher.java
new file mode 100644
index 000000000..1d3c7bd3a
--- /dev/null
+++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/build/RenderScriptLauncher.java
@@ -0,0 +1,244 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Eclipse Public License, Version 1.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.eclipse.org/org/documents/epl-v10.php
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ide.eclipse.adt.internal.build;
+
+import com.android.annotations.NonNull;
+import com.android.ide.eclipse.adt.AdtConstants;
+import com.android.ide.eclipse.adt.AdtPlugin;
+import com.android.ide.eclipse.adt.internal.project.BaseProjectHelper;
+import com.android.sdklib.build.RenderScriptProcessor.CommandLineLauncher;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Path;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * A {@link SourceProcessor} for RenderScript files.
+ */
+public class RenderScriptLauncher implements CommandLineLauncher {
+
+ /**
+ * Single line llvm-rs-cc error: {@code <path>:<line>:<col>: <error>}
+ */
+ private static Pattern sLlvmPattern1 = Pattern.compile("^(.+?):(\\d+):(\\d+):\\s(.+)$"); //$NON-NLS-1$
+
+ @NonNull
+ private final IProject mProject;
+ @NonNull
+ private final IFolder mSourceOutFolder;
+ @NonNull
+ private final IFolder mResOutFolder;
+ @NonNull
+ private final IProgressMonitor mMonitor;
+ private final boolean mVerbose;
+
+ public RenderScriptLauncher(
+ @NonNull IProject project,
+ @NonNull IFolder sourceOutFolder,
+ @NonNull IFolder resOutFolder,
+ @NonNull IProgressMonitor monitor,
+ boolean verbose) {
+ mProject = project;
+ mSourceOutFolder = sourceOutFolder;
+ mResOutFolder = resOutFolder;
+ mMonitor = monitor;
+ mVerbose = verbose;
+ }
+
+ @Override
+ public void launch(File executable, List<String> arguments, Map<String, String> envVariableMap)
+ throws IOException, InterruptedException {
+ // do the exec
+ try {
+ if (mVerbose) {
+ StringBuilder sb = new StringBuilder(executable.getAbsolutePath());
+ for (String c : arguments) {
+ sb.append(' ').append(c);
+ }
+ String cmd_line = sb.toString();
+ AdtPlugin.printToConsole(mProject, cmd_line);
+ }
+
+ String[] commandArray = new String[1 + arguments.size()];
+ commandArray[0] = executable.getAbsolutePath();
+ System.arraycopy(arguments.toArray(), 0, commandArray, 1, arguments.size());
+
+ ProcessBuilder processBuilder = new ProcessBuilder(commandArray);
+ Map<String, String> processEnvs = processBuilder.environment();
+ for (Map.Entry<String, String> entry : envVariableMap.entrySet()) {
+ processEnvs.put(entry.getKey(), entry.getValue());
+ }
+
+ Process p = processBuilder.start();
+
+ // list to store each line of stderr
+ ArrayList<String> stdErr = new ArrayList<String>();
+
+ // get the output and return code from the process
+ int returnCode = BuildHelper.grabProcessOutput(mProject, p, stdErr);
+
+ if (stdErr.size() > 0) {
+ // attempt to parse the error output
+ boolean parsingError = parseLlvmOutput(stdErr);
+
+ // If the process failed and we couldn't parse the output
+ // we print a message, mark the project and exit
+ if (returnCode != 0) {
+
+ if (parsingError || mVerbose) {
+ // display the message in the console.
+ if (parsingError) {
+ AdtPlugin.printErrorToConsole(mProject, stdErr.toArray());
+
+ // mark the project
+ BaseProjectHelper.markResource(mProject,
+ AdtConstants.MARKER_RENDERSCRIPT,
+ "Unparsed Renderscript error! Check the console for output.",
+ IMarker.SEVERITY_ERROR);
+ } else {
+ AdtPlugin.printToConsole(mProject, stdErr.toArray());
+ }
+ }
+ return;
+ }
+ } else if (returnCode != 0) {
+ // no stderr output but exec failed.
+ String msg = String.format("Error executing Renderscript: Return code %1$d",
+ returnCode);
+
+ BaseProjectHelper.markResource(mProject, AdtConstants.MARKER_AIDL,
+ msg, IMarker.SEVERITY_ERROR);
+
+ return;
+ }
+ } catch (IOException e) {
+ // mark the project and exit
+ String msg = String.format(
+ "Error executing Renderscript. Please check %1$s is present at %2$s",
+ executable.getName(), executable.getAbsolutePath());
+ AdtPlugin.log(IStatus.ERROR, msg);
+ BaseProjectHelper.markResource(mProject, AdtConstants.MARKER_RENDERSCRIPT, msg,
+ IMarker.SEVERITY_ERROR);
+ throw e;
+ } catch (InterruptedException e) {
+ // mark the project and exit
+ String msg = String.format(
+ "Error executing Renderscript. Please check %1$s is present at %2$s",
+ executable.getName(), executable.getAbsolutePath());
+ AdtPlugin.log(IStatus.ERROR, msg);
+ BaseProjectHelper.markResource(mProject, AdtConstants.MARKER_RENDERSCRIPT, msg,
+ IMarker.SEVERITY_ERROR);
+ throw e;
+ }
+
+ try {
+ mSourceOutFolder.refreshLocal(IResource.DEPTH_ONE, mMonitor);
+ mResOutFolder.refreshLocal(IResource.DEPTH_ONE, mMonitor);
+ } catch (CoreException e) {
+ AdtPlugin.log(e, "failed to refresh folders");
+ }
+
+ return;
+ }
+
+ /**
+ * Parse the output of llvm-rs-cc and mark the file with any errors.
+ * @param lines The output to parse.
+ * @return true if the parsing failed, false if success.
+ */
+ private boolean parseLlvmOutput(ArrayList<String> lines) {
+ // nothing to parse? just return false;
+ if (lines.size() == 0) {
+ return false;
+ }
+
+ // get the root folder for the project as we're going to ignore everything that's
+ // not in the project
+ String rootPath = mProject.getLocation().toOSString();
+ int rootPathLength = rootPath.length();
+
+ Matcher m;
+
+ boolean parsing = false;
+
+ for (int i = 0; i < lines.size(); i++) {
+ String p = lines.get(i);
+
+ m = sLlvmPattern1.matcher(p);
+ if (m.matches()) {
+ // get the file path. This may, or may not be the main file being compiled.
+ String filePath = m.group(1);
+ if (filePath.startsWith(rootPath) == false) {
+ // looks like the error in a non-project file. Keep parsing, but
+ // we'll return true
+ parsing = true;
+ continue;
+ }
+
+ // get the actual file.
+ filePath = filePath.substring(rootPathLength);
+ // remove starting separator since we want the path to be relative
+ if (filePath.startsWith(File.separator)) {
+ filePath = filePath.substring(1);
+ }
+
+ // get the file
+ IFile f = mProject.getFile(new Path(filePath));
+
+ String lineStr = m.group(2);
+ // ignore group 3 for now, this is the col number
+ String msg = m.group(4);
+
+ // get the line number
+ int line = 0;
+ try {
+ line = Integer.parseInt(lineStr);
+ } catch (NumberFormatException e) {
+ // looks like the string we extracted wasn't a valid
+ // file number. Parsing failed and we return true
+ return true;
+ }
+
+ // mark the file
+ BaseProjectHelper.markResource(f, AdtConstants.MARKER_RENDERSCRIPT, msg, line,
+ IMarker.SEVERITY_ERROR);
+
+ // success, go to the next line
+ continue;
+ }
+
+ // invalid line format, flag as error, and keep going
+ parsing = true;
+ }
+
+ return parsing;
+ }
+}