Commit 5794b520 authored by Andrey Filippov's avatar Andrey Filippov

Implemented run and success/failure for tools, recording and playing

back (through ext. parsers) logs
parent 180a1d4f
......@@ -102,6 +102,8 @@ public class VDT {
public static final String ATTR_TOOL_WARNINGS = ID_VDT + ".ATTR_TOOL_WARNINGS";
public static final String ATTR_TOOL_INFO = ID_VDT + ".ATTR_TOOL_INFO";
public static final String ATTR_LOG_BUILD_STAMP = ID_VDT + ".ATTR_LOG_BUILD_STAMP";
/**
* Identifier for verilog tools launch configuration group. The verilog
......
......@@ -121,8 +121,15 @@ public class VerilogUtils {
public static OutlineElement[] getTopModulesVeditor(IFile file) {
IProject project = file.getProject();
if (project==null){
System.out.println("getTopModulesVeditor(): Projectis null for file="+file.getFullPath());
return null;
}
OutlineDatabase outlineDatabase=getVeditorOutlineDatabase(project);
if (outlineDatabase==null){
System.out.println("getTopModulesVeditor(): outlineDatabase is null for project: "+project+" file="+file.getFullPath());
return null;
}
OutlineContainer outlineContainer=outlineDatabase.getOutlineContainer(file);
if (outlineContainer != null) {
OutlineElement[] allTopElements=outlineContainer.getTopLevelElements();
......
......@@ -56,6 +56,7 @@ import com.elphel.vdt.ui.MessageUI;
import com.elphel.vdt.ui.dialogs.PackageLocationDialog;
import com.elphel.vdt.ui.dialogs.ToolLocationDialog;
import com.elphel.vdt.ui.preferences.PreferencePage;
import com.elphel.vdt.ui.views.DesignFlowView;
/**
* Support for launching verilog development tools programmatically.
......@@ -88,7 +89,7 @@ public class LaunchCore {
{
workingCopy.setAttribute(VDT.ATTR_WORKING_DIRECTORY, project.getLocation().toOSString());
} // setWorkingDirectory()
/* TODO: For now they are the same, implement build directory differnt from project path */
/* TODO: For now they are the same, implement build directory different from project path */
/* Currently project path is only used to find launched project by it */
public static void setProjectPath ( ILaunchConfigurationWorkingCopy workingCopy
, IProject project )
......@@ -108,11 +109,16 @@ public class LaunchCore {
workingCopy.setAttribute(VDT.ATTR_TOOL_ERRORS, tool.getPatternErrors());
workingCopy.setAttribute(VDT.ATTR_TOOL_WARNINGS, tool.getPatternWarnings());
workingCopy.setAttribute(VDT.ATTR_TOOL_INFO, tool.getPatternInfo());
}
public static void setLogBuildStamp( ILaunchConfigurationWorkingCopy workingCopy
, String logBuildStamp ) throws CoreException {
workingCopy.setAttribute(VDT.ATTR_LOG_BUILD_STAMP, logBuildStamp);
}
public static void updateLaunchConfiguration( ILaunchConfigurationWorkingCopy workingCopy
, Tool tool ) throws CoreException
{
......@@ -166,9 +172,11 @@ public class LaunchCore {
OptionsCore.doLoadLocation(tool); // here it resolves condition with OS
} // updateContextOptions()
public static ILaunchConfiguration createLaunchConfiguration( Tool tool
, IProject project
, String resource
public static ILaunchConfiguration createLaunchConfiguration(
Tool tool,
IProject project,
String resource,
String logBuildStamp // null - run tool, "" - log latest, other - with specified buildStamp
) throws CoreException
{
// get tools launch configuration
......@@ -204,18 +212,32 @@ public class LaunchCore {
setResource(workingCopy, resource);
setWorkingDirectory(workingCopy, project);
setProjectPath(workingCopy, project);
setLogBuildStamp(workingCopy,logBuildStamp);
ILaunchConfiguration launchConfig = workingCopy.doSave();
return launchConfig;
} // createLaunchConfiguration()
/*
public static void launch(Tool tool, IProject project) throws CoreException {
launch(tool, project, VDT.VARIABLE_RESOURCE_NAME);
}
*/
public static void launch(
Tool tool,
IProject project,
String resource,
String logBuildStamp) throws CoreException {
if (!saveAllEditors(true)) return; // Andrey: added it here
public static void launch(Tool tool, IProject project, String resource) throws CoreException {
try {
ILaunchConfiguration launchConfig = createLaunchConfiguration(tool, project, resource);
ILaunchConfiguration launchConfig = createLaunchConfiguration(
tool,
project,
resource,
logBuildStamp);
DebugUITools.launch(launchConfig, ILaunchManager.RUN_MODE);
} catch (CoreException e) {
IStatus status = e.getStatus();
......@@ -262,6 +284,7 @@ public class LaunchCore {
* Launches the given run configuration in a background Job with progress
* reported via the Job. Exceptions are reported in the Progress view.
*/
// Never used - where it was supposed to be called from? //
public static void launchInBackground(final VDTRunnerConfiguration configuration) {
if (!saveAllEditors(true)) {
return;
......@@ -289,6 +312,7 @@ public class LaunchCore {
* Launches the given run configuration in the foreground with a progress
* dialog. Reports any exceptions that occur in an error dialog.
*/
// Never used - where it was supposed to be called from? //
public static void launchInForeground(final VDTRunnerConfiguration configuration) {
if (!saveAllEditors(true)) {
return;
......@@ -319,7 +343,7 @@ public class LaunchCore {
// {
// launch(configuration, null);
// }
// Never used - where it was supposed to be called from? //
private static void launch( final VDTRunnerConfiguration configuration
, IProgressMonitor monitor
) throws CoreException
......@@ -327,8 +351,17 @@ public class LaunchCore {
ILaunch launch = new Launch(null, ILaunchManager.RUN_MODE, null);
launch.setAttribute(DebugPlugin.ATTR_CAPTURE_OUTPUT, null);
DebugPlugin.getDefault().getLaunchManager().addLaunch(launch);
VDTRunner runner = VDTLaunchUtil.getRunner();
// VDTRunner runner = VDTLaunchUtil.getRunner();
VDTProgramRunner runner = configuration.getProgramRunner();
int numItem=configuration.getBuildStep();
//getProgramRunner
// Probably wrong thing to launch - what if it starts with console?
// but neither of the callers seem to be used anywhere else
System.out.println("Probably wrong Launching from LaunchCore.java , numItem="+numItem);
MessageUI.error("Probably wrong: Launching from LaunchCore.java , numItem="+numItem +", normally goes through LaunchCOnfigurationDelegate");
System.out.println("just stop here");
runner.run(configuration,
VDTRunner.renderProcessLabel(configuration.getToolName()), // toolname + (date)
launch,
......
/*******************************************************************************
* Copyright (c) 2014 Elphel, Inc.
* This file is a part of Eclipse/VDT plug-in.
* Eclipse/VDT plug-in is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Eclipse/VDT plug-in is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*******************************************************************************/
package com.elphel.vdt.core.launching;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.ByteArrayInputStream;
import java.util.regex.Pattern;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import com.elphel.vdt.ui.MessageUI;
import com.elphel.vdt.ui.variables.SelectedResourceManager;
import com.elphel.vdt.veditor.VerilogPlugin;
import com.elphel.vdt.veditor.preference.PreferenceStrings;
import java.util.regex.Matcher;
public class ToolLogFile {
public static final String DEFAULT_LOG_FOLDER= "tool_logs";
public static final String ERROR_LOG_SUFFIX= "-err";
public static final String OUTPUT_LOG_SUFFIX= "-out";
public static final String LOG_EXTENSION= "log";
public static final String TOOL_TO_LINE_SEPARATOR="_";
public static final String BUILD_STAMP_SEPARATOR="-";
public static final String REGEX_SEP_TO_END="[_\\-].*";
// private String resolvedLogPath;
private FileWriter logOutWriter;
private FileWriter logErrWriter;
private FileReader logOutReader;
private FileReader logErrReader;
private IFile targetOutIFile;
private IFile targetErrIFile;
private boolean hasOut;
private boolean hasErr;
private boolean singleFile;
private boolean debugPrint;
public static IFolder getDir(String logDir){
IProject project = SelectedResourceManager.getDefault().getSelectedProject(); // should not be null when we got here
return project.getFolder((logDir==null)?DEFAULT_LOG_FOLDER:logDir);
}
public static String getBaseLogName(String logTool, String logName){
String baseName=logTool;
if ((logName!=null) && (logName.length()>0))baseName+=TOOL_TO_LINE_SEPARATOR+logName;
return baseName;
}
public static String getBaseLogName(String logTool){
return logTool+TOOL_TO_LINE_SEPARATOR;
}
public static String getBaseRegex(String logTool){
return logTool+REGEX_SEP_TO_END;
}
public static String getTimeStamp(String logTool, String name){
if (name==null) return null;
// remove prefix
int index=name.lastIndexOf(logTool);
if (index<0) return null;
name=name.substring(index+logTool.length());
index=name.lastIndexOf(".");
if (index>0) name=name.substring(0,index);
index=name.lastIndexOf(BUILD_STAMP_SEPARATOR);
if (index<0) return null;
name=name.substring(index+BUILD_STAMP_SEPARATOR.length());
// (\d+)\D*\z - last group of digits
Matcher m=Pattern.compile("(\\d+)\\D*\\z").matcher(name);
if (m.find()){
return m.group(1);
}
return null;
}
/**
* @param logDir Directory path of the log files root directory (or null)
* @param logTool Tool name for which log is created
* @param logName Name specified in the individual output line
* @param extension File extension (like "log") If null, will use default
* @param hasOut Has output log (if no separate error log - no suffix
* @param hasErr Has error log (if no separate output log - no suffix
* @param buildStamp if null - write log mode, "" - read link (latest) file, else - read that build stamp file
*/
public ToolLogFile (
String logDir,
String logTool,
String logName,
String extension, // extension does not include "."
boolean useOut,
boolean useErr,
String buildStamp){
hasOut=useOut;
hasErr=useErr;
logOutWriter= null;
logOutReader= null;
logErrWriter= null;
logErrReader= null;
targetOutIFile=null;
targetErrIFile=null;
debugPrint=VerilogPlugin.getPreferenceBoolean(PreferenceStrings.DEBUG_LAUNCHING);
boolean writeMode=(buildStamp==null);
if (!hasOut && !hasErr){
return; // nothing to do
}
singleFile= !(hasOut && hasErr);
String ext=(extension==null)?LOG_EXTENSION:extension;
if ((ext.length()>0) && !ext.substring(0,1).equals("."))ext="."+ext;
// IProject project = SelectedResourceManager.getDefault().getSelectedProject(); // should not be null when we got here
if (buildStamp==null) buildStamp=SelectedResourceManager.getDefault().getBuildStamp();
// IFolder iLogFolder = project.getFolder((logDir==null)?DEFAULT_LOG_FOLDER:logDir);
IFolder iLogFolder =getDir(logDir);
if (!iLogFolder.exists()){
if (writeMode){
try {
iLogFolder.create(IResource.NONE, true, null); // should it be IResource.DERIVED ?
} catch (CoreException e){
MessageUI.error("Failed to create directory "+iLogFolder.toString()+" for writing logs");
return;
}
} else {
MessageUI.error(iLogFolder.toString()+" log directory does not exist");
return;
}
}
// String baseName=logTool;
// if ((logName!=null) && (logName.length()>0))baseName+=TOOL_TO_LINE_SEPARATOR+logName;
String baseName=getBaseLogName(logTool, logName);
String baseNameOut=baseName;
String baseNameErr=baseName;
String buildStampWithSep=(buildStamp.length()>0)?(BUILD_STAMP_SEPARATOR+buildStamp):"";
if (!singleFile){
baseNameOut+=OUTPUT_LOG_SUFFIX;
baseNameErr+=ERROR_LOG_SUFFIX;
}
targetOutIFile = iLogFolder.getFile(baseNameOut+buildStampWithSep+ext);
targetErrIFile = singleFile? targetOutIFile : iLogFolder.getFile(baseNameErr+buildStampWithSep+ext);
if (writeMode) {
byte [] emptyBA={};
IFile linkOutIFile= iLogFolder.getFile(baseNameOut+ext);
IFile linkErrIFile= singleFile ? linkOutIFile : iLogFolder.getFile(baseNameErr+ext);
if (!targetOutIFile.exists()){
try {
targetOutIFile.create(new ByteArrayInputStream(emptyBA), IResource.NONE, null);
} catch (CoreException e) {
MessageUI.error("Failed to create log file "+targetOutIFile.toString());
return;
}
}
if (!singleFile && !targetErrIFile.exists()){
try {
targetErrIFile.create(new ByteArrayInputStream(emptyBA), IResource.NONE, null);
} catch (CoreException e) {
MessageUI.error("Failed to create error log file "+targetErrIFile.toString());
return;
}
}
// Create logWriter(s)
try {
logOutWriter=new FileWriter(targetOutIFile.getLocation().toFile(),true); // append
} catch (IOException e) {
MessageUI.error("Failed to open "+targetOutIFile.toString()+" for writing log");
}
if (!singleFile){
try {
logErrWriter=new FileWriter(targetErrIFile.getLocation().toFile(),true); // append
} catch (IOException e) {
MessageUI.error("Failed to open "+targetErrIFile.toString()+" for writing log");
}
}
// Create links to the latest logs
try {
linkOutIFile.createLink(
targetOutIFile.getLocation(),
IResource.ALLOW_MISSING_LOCAL | IResource.REPLACE,
null);
} catch (CoreException e) {
MessageUI.error("Failed to create link "+linkOutIFile.toString()+" to the target log "+
targetOutIFile.toString());
}
if (!singleFile){
try {
linkErrIFile.createLink(
targetErrIFile.getLocation(),
IResource.ALLOW_MISSING_LOCAL | IResource.REPLACE,
null);
} catch (CoreException e) {
MessageUI.error("Failed to create link "+linkErrIFile.toString()+" to the target error log "+
targetErrIFile.toString());
}
}
} else { // read logs mode
if (!targetOutIFile.exists()){
if(debugPrint) System.out.println("Skipping non-existent log file:"+targetOutIFile.toString());
} else {
try {
logOutReader=new FileReader(targetOutIFile.getLocation().toFile());
} catch (FileNotFoundException e) {
if(debugPrint) System.out.println("- Skipping non-existent log file:"+targetOutIFile.toString());
}
}
if (!singleFile) {
if (!targetErrIFile.exists()){
if(debugPrint) System.out.println("Skipping non-existent error log file:"+targetErrIFile.toString());
} else {
try {
logErrReader=new FileReader(targetErrIFile.getLocation().toFile());
} catch (FileNotFoundException e) {
if(debugPrint) System.out.println("- Skipping non-existent error log file:"+targetErrIFile.toString());
}
}
} else if (hasErr){ // single error log, no out log
// reconnect out to err (for name and reader)
logErrReader=logOutReader;
logOutReader=null;
targetErrIFile=targetOutIFile;
targetOutIFile=null;
}
}
}
public void appendOut(String string) { // no \n added, should be provided
if (!hasOut ||(logOutWriter==null)) return; // do nothing
try {
logOutWriter.append(string);
// if(debugPrint) System.out.println("out->out: "+string);
} catch (IOException e) {
System.out.println("Failed to append log file "+targetOutIFile.toString());
closeOut();
}
}
public void appendErr(String string) { // no \n added, should be provided
// if (!hasErr) return;
if (singleFile?(logOutWriter==null):(logErrWriter==null)) return;
try {
if (singleFile) {
logOutWriter.append(string);
// if(debugPrint) System.out.println("err->out: "+string);
} else {
logErrWriter.append(string);
// if(debugPrint) System.out.println("err->err: "+string);
}
} catch (IOException e) {
System.out.println("Failed to append error log file "+
(singleFile?targetOutIFile:targetErrIFile).toString());
if (singleFile) closeOut();
else closeErr();
// close();
}
}
public void closeOut(){
if (logOutWriter!=null)
try {
logOutWriter.close();
if(debugPrint) System.out.println("closeOut()");
} catch (IOException e) {
System.out.println("Failed to close log file "+targetOutIFile.toString());
}
}
public void closeErr(){
if (logErrWriter!=null)
try {
logErrWriter.close();
if(debugPrint) System.out.println("closeErr()");
} catch (IOException e) {
System.out.println("Failed to close error log file "+targetErrIFile.toString());
}
}
public FileReader getOutReader(){
return logOutReader;
}
public FileReader getErrReader(){
return logErrReader;
}
public String getOutLogName(){
return (targetOutIFile!=null) ? targetOutIFile.getName():"";
}
public String getErrLogName(){
return (targetErrIFile!=null) ? targetErrIFile.getName():"";
}
public void close(){
closeOut();
closeErr();
}
public void finalize() throws Throwable{
close();
super.finalize();
}
}
/*******************************************************************************
* Copyright (c) 2014 Elphel, Inc.
* This file is a part of Eclipse/VDT plug-in.
* Eclipse/VDT plug-in is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Eclipse/VDT plug-in is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*******************************************************************************/
package com.elphel.vdt.core.launching;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.model.IProcess;
import org.eclipse.debug.core.model.IStreamsProxy2;
import org.eclipse.swt.widgets.Display;
import com.elphel.vdt.core.tools.contexts.BuildParamsItem;
import com.elphel.vdt.veditor.VerilogPlugin;
import com.elphel.vdt.veditor.preference.PreferenceStrings;
public class VDTConsolePlayback{
private final VDTRunnerConfiguration runConfig;
public VDTConsolePlayback (VDTRunnerConfiguration runConfig){
this.runConfig=runConfig;
}
private int getParserIndex( String parserName){
if (parserName==null) return -1;
BuildParamsItem[] buildParamsItems = runConfig.getArgumentsItemsArray(); // uses already calculated
if (buildParamsItems==null) return -1;
for (int i=0;i<buildParamsItems.length;i++){
if (parserName.equals(buildParamsItems[i].getNameAsParser()))
return i;
}
return -1;
}
public boolean runConsole(String consolePrefix
, ILaunch launch
, IProgressMonitor monitor
) throws CoreException{
final boolean debugPrint=VerilogPlugin.getPreferenceBoolean(PreferenceStrings.DEBUG_LAUNCHING);
VDTProgramRunner programRunner = runConfig.getProgramRunner();
int numItem=runConfig.getBuildStep();
// TODO: process - null- normal run, "" - playback latest log, or timestamp - play selected log file(s)
String playBackStamp=runConfig.getPlayBackStamp();
if (playBackStamp==null){
System.out.println("Wrong, it is not playback as playBackStamp==null ");
return false;
}
BuildParamsItem buildParamsItem = runConfig.getArgumentsItemsArray()[numItem]; // uses already calculated
// try to send
String[] arguments = runConfig.getToolArguments();
if (arguments == null) arguments=new String[0];
if (debugPrint) {
if (arguments!=null){
for (int i=0;i<arguments.length;i++){
System.out.println("Console line "+i+" = \""+arguments[i]+"\"");
}
}
}
// See if any parsers are configured
int stderrParserIndex=getParserIndex(buildParamsItem.getStderr());
int stdoutParserIndex=getParserIndex(buildParamsItem.getStdout());
BuildParamsItem stderrParser=(stderrParserIndex>=0)?runConfig.getArgumentsItemsArray()[stderrParserIndex]:null;
BuildParamsItem stdoutParser=(stdoutParserIndex>=0)?runConfig.getArgumentsItemsArray()[stdoutParserIndex]:null;
if (debugPrint) {
System.out.println("Using parser for stderr: "+((stderrParser!=null)?stderrParser.getNameAsParser():"none")); // actually may be the same as stdout
System.out.println("Using parser for stdout: "+((stdoutParser!=null)?stdoutParser.getNameAsParser():"none"));
}
if ((stderrParser==null) && (stdoutParser==null)){
return false; // no parsers, no playback
}
// Open logfiles for reading (if available)
boolean twoFiles=(stdoutParser!=null) && (stderrParser!=null);
ToolLogFile toolLogFile=new ToolLogFile (
runConfig.getLogDir(),
runConfig.getToolName(),
buildParamsItem.getLogName(),
null, // extension - use default
(stdoutParser!=null), //boolean useOut,
(stderrParser!=null), //boolean useErr,
playBackStamp);//String buildStamp
FileReader outLogReader=toolLogFile.getOutReader();
FileReader errLogReader=toolLogFile.getErrReader();
if ((outLogReader==null) && (errLogReader==null)){
if (debugPrint) {
System.out.println(
"No logs available in "+runConfig.getLogDir()+
" for tool "+runConfig.getToolName()+
((buildParamsItem.getLogName()!=null)?(" ("+buildParamsItem.getLogName()+")"):"")+
((playBackStamp.length()>0)?(" timestamp: "+playBackStamp):""));
}
return false; // no parsers, no playback
}
if (twoFiles){
if (outLogReader==null) stdoutParser=null; // no log available
if (errLogReader==null) stderrParser=null; // no log available
}
final String outLogName=toolLogFile.getOutLogName();
final String errLogName=toolLogFile.getErrLogName();
VDTRunner runner = VDTLaunchUtil.getRunner();
String msg="Playing back log file from "+runConfig.getLogDir()+
" for tool "+runConfig.getToolName()+
((buildParamsItem.getLogName()!=null)?(" ("+buildParamsItem.getLogName()+")"):"")+
((playBackStamp.length()>0)?(" timestamp: "+playBackStamp):"");
runner.log(msg, null, null, false, true); // Appears in the console of the target Eclipse (may be immediately erased)
runner.log(msg, null, null, false, false); // Appears in the console of the parent Eclipse
IProcess processErr=null;
IProcess processOut=null;
IStreamsProxy2 stdoutStreamProxy=null;
IStreamsProxy2 stderrStreamProxy=null;
if (stdoutParser!=null){
List<String> toolArgumentsStdout = new ArrayList<String>();
List<String> stdoutArguments=stdoutParser.getParamsAsList();
if (stdoutArguments != null)
toolArgumentsStdout.addAll(stdoutArguments);
// overwriting runConfig, but this is done sequentially, so OK
runConfig.setToolArguments((String[])toolArgumentsStdout.toArray(new String[toolArgumentsStdout.size()]));
processOut=programRunner.run(runConfig,
"replay log "+outLogName,
launch,
null, //monitor
stdoutParserIndex);
stdoutStreamProxy= (IStreamsProxy2) processOut.getStreamsProxy();
}
if (stderrParser!=null){
List<String> toolArgumentsStderr = new ArrayList<String>();
List<String> stderrArguments=stderrParser.getParamsAsList();
if (stderrArguments != null)
toolArgumentsStderr.addAll(stderrArguments);
// overwriting runConfig, but this is done sequentially, so OK
runConfig.setToolArguments((String[])toolArgumentsStderr.toArray(new String[toolArgumentsStderr.size()]));
processErr=programRunner.run(runConfig,
"replay err log "+errLogName,
launch,
null, //monitor);
stderrParserIndex);
stderrStreamProxy= (IStreamsProxy2) processErr.getStreamsProxy();
//TODO: Add error parsers
}
IStreamsProxy2 sendErrorsToStreamProxy=(stderrStreamProxy!=null)?stderrStreamProxy:stdoutStreamProxy;
final IStreamsProxy2 fSendErrorsToStreamProxy=sendErrorsToStreamProxy;
final IStreamsProxy2 fSendOutputToStreamProxy= stdoutStreamProxy;
BufferedReader outBufReader=null;
BufferedReader errBufReader=null;
try {
outBufReader=((outLogReader!=null) && (fSendOutputToStreamProxy!=null))? (new BufferedReader(outLogReader)):null;
errBufReader=((errLogReader!=null) && (fSendErrorsToStreamProxy!=null))? (new BufferedReader(errLogReader)):null;
} catch (Exception e) {
System.out.println ("Failed to create BufferedReader");
}
// Read logs should be fast, not sure how much will be buffered in IStreamsProxy2, so sending logs
// one after another in the same thread
if (errBufReader!=null){
String line;
try {
while ((line = errBufReader.readLine()) != null){
fSendErrorsToStreamProxy.write(line+"\n");
//if(debugPrint) System.out.println ("err->>"+line);
}
} catch (IOException e) {
System.out.println ("Failed to replay "+errLogName+" to error parser");
} finally {
try {
errBufReader.close();
// if(debugPrint) System.out.println ("err->>CLOSED");
} catch (IOException e) {
System.out.println ("Failed to close "+errLogName+" BufferedReader");
}
}
}
if (outBufReader!=null){
String line;
try {
while ((line = outBufReader.readLine()) != null){
fSendOutputToStreamProxy.write(line+"\n");
// if(debugPrint) System.out.println ("out->>"+line);
}
} catch (IOException e) {
System.out.println ("Failed to replay "+outLogName+" to output parser");
} finally {
try {
outBufReader.close();
// if(debugPrint) System.out.println ("out->>CLOSED");
} catch (IOException e) {
System.out.println ("Failed to close "+outLogName+" BufferedReader");
}
}
}
try {
if (stdoutStreamProxy!=null) stdoutStreamProxy.closeInputStream();
} catch (IOException e){
System.out.println ("Failed to close output stream proxy");
}
// next uses stderrStreamProxy, not fSendErrorsToStreamProxy as it can be the same as fSendOutputToStreamProxy
try {
if (stderrStreamProxy!=null) stderrStreamProxy.closeInputStream();
} catch (IOException e){
System.out.println ("Failed to close error stream proxy");
}
return true;
}
} // class VDTConsolePlayback
......@@ -28,31 +28,24 @@ import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.debug.core.DebugException;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.IStreamListener;
//import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.model.IProcess;
//import org.eclipse.debug.ui.DebugUITools;
//import org.eclipse.ui.console.ConsolePlugin;
//import org.eclipse.ui.console.IConsoleManager;
//import org.eclipse.ui.console.IPatternMatchListener;
//import org.eclipse.ui.console.MessageConsole;
import org.eclipse.debug.core.model.IStreamMonitor;
//import org.eclipse.debug.core.model.IStreamListener;
import org.eclipse.debug.core.model.IStreamsProxy;
import org.eclipse.debug.core.model.IStreamsProxy2;
import org.eclipse.swt.graphics.Color;
import org.eclipse.ui.console.IConsole;
//import org.eclipse.debug.ui.console.IConsole;
import org.eclipse.ui.console.ConsolePlugin;
import org.eclipse.ui.console.IConsoleManager;
import org.eclipse.ui.console.IOConsole;
import org.eclipse.ui.console.IOConsoleOutputStream;
import com.elphel.vdt.core.tools.ToolsCore;
import com.elphel.vdt.core.tools.contexts.BuildParamsItem;
import com.elphel.vdt.core.tools.params.Tool;
import com.elphel.vdt.core.tools.params.Tool.TOOL_STATE;
import com.elphel.vdt.ui.MessageUI;
import com.elphel.vdt.veditor.VerilogPlugin;
import com.elphel.vdt.veditor.preference.PreferenceStrings;
import com.sun.net.ssl.internal.www.protocol.https.Handler;
public class VDTConsoleRunner{
private final VDTRunnerConfiguration runConfig; //*
......@@ -65,6 +58,7 @@ public class VDTConsoleRunner{
private Timer timer;
private IStreamsProxy2 stdoutStreamProxy=null;
private IStreamsProxy2 stderrStreamProxy=null;
private ToolLogFile toolLogFile =null;
public VDTConsoleRunner (VDTRunnerConfiguration runConfig){
......@@ -83,14 +77,24 @@ public class VDTConsoleRunner{
}
public IOConsole runConsole(String consolePrefix
, ILaunch launch
, IProgressMonitor monitor
public IOConsole runConsole(
String consolePrefix,
ILaunch launch,
IProgressMonitor monitor
) throws CoreException{
final boolean debugPrint=VerilogPlugin.getPreferenceBoolean(PreferenceStrings.DEBUG_LAUNCHING);
VDTRunner runner = VDTLaunchUtil.getRunner();
VDTProgramRunner programRunner = runConfig.getProgramRunner();
int numItem=runConfig.getBuildStep();
// TODO: process - null- normal run, "" - playback latest log, or timestamp - play selected log file(s)
String playBackStamp=runConfig.getPlayBackStamp();
if (playBackStamp!=null){
System.out.println("Wrong, it should be playback, not run, as playBackStamp = "+playBackStamp+ "(not null)");
return null;
}
BuildParamsItem buildParamsItem = runConfig.getArgumentsItemsArray()[numItem]; // uses already calculated
//TODO: Handle monitor
// Find console with name starting with consolePrefix
......@@ -108,23 +112,28 @@ public class VDTConsoleRunner{
}
if (iCons==null) {
MessageUI.error("Specified console: "+consolePrefix+" is not found (was looking for \""+consoleStartsWith+"\"");
Tool tool=ToolsCore.getTool(runConfig.getToolName());
tool.setDirty(false);
tool.setState(TOOL_STATE.FAILURE);
tool.setRunning(false);
tool.setFinishTimeStamp();
tool.updateViewStateIcon();
//removeConfiguration
VDTLaunchUtil.getRunner().getRunningBuilds().removeConfiguration(runConfig.getOriginalConsoleName());
return null;
}
// try to send
String[] arguments = runConfig.getToolArguments();
if (arguments == null) arguments=new String[0];
if (debugPrint) {
// System.out.println("patternErrors= \""+ runConfig.getPatternErrors()+"\"");
// System.out.println("patternWarnings= \""+runConfig.getPatternWarnings()+"\"");
// System.out.println("patternInfo= \"" +runConfig.getPatternInfo()+"\"");
if (arguments!=null){
for (int i=0;i<arguments.length;i++){
System.out.println("Console line "+i+" = \""+arguments[i]+"\"");
}
}
}
runner.log("Writing to console "+iCons.getName()+":", arguments, null, false, true); /* Appears in the console of the target Eclipse (immediately erased) */
runner.log("Writing to console "+iCons.getName()+":", arguments, null, false, false); /* Appears in the console of the parent Eclipse */
runner.log("Writing to console "+iCons.getName()+":", arguments, null, false, true); // Appears in the console of the target Eclipse (may be immediately erased)
runner.log("Writing to console "+iCons.getName()+":", arguments, null, false, false); // Appears in the console of the parent Eclipse
IOConsoleOutputStream outStream= iCons.newOutputStream();
IProcess process=((ProcessConsole)iCons).getProcess();
consoleInStreamProxy= (IStreamsProxy2)process.getStreamsProxy();
......@@ -132,14 +141,13 @@ public class VDTConsoleRunner{
int stdoutParserIndex=getParserIndex(buildParamsItem.getStdout());
BuildParamsItem stderrParser=(stderrParserIndex>=0)?runConfig.getArgumentsItemsArray()[stderrParserIndex]:null;
BuildParamsItem stdoutParser=(stdoutParserIndex>=0)?runConfig.getArgumentsItemsArray()[stdoutParserIndex]:null;
if (debugPrint) {
System.out.println("Using parser for stderr: "+((stderrParser!=null)?stderrParser.getNameAsParser():"none")); // actually may be the same as stdout
System.out.println("Using parser for stdout: "+((stdoutParser!=null)?stdoutParser.getNameAsParser():"none"));
}
processErr=null;
processOut=null;
// IStreamsProxy2 stdoutStreamProxy=null;
// IStreamsProxy2 stderrStreamProxy=null;
stdoutStreamProxy=null;
stderrStreamProxy=null;
if (stdoutParser!=null){
......@@ -149,7 +157,7 @@ public class VDTConsoleRunner{
toolArgumentsStdout.addAll(stdoutArguments);
// overwriting runConfig, but this is done sequentially, so OK
runConfig.setToolArguments((String[])toolArgumentsStdout.toArray(new String[toolArgumentsStdout.size()]));
processOut=runner.run(runConfig,
processOut=programRunner.run(runConfig,
"OUT for "+iCons.getName(),
launch,
null, //monitor
......@@ -164,7 +172,7 @@ public class VDTConsoleRunner{
toolArgumentsStderr.addAll(stderrArguments);
// overwriting runConfig, but this is done sequentially, so OK
runConfig.setToolArguments((String[])toolArgumentsStderr.toArray(new String[toolArgumentsStderr.size()]));
processErr=runner.run(runConfig,
processErr=programRunner.run(runConfig,
"ERR for "+iCons.getName(),
launch,
null, //monitor);
......@@ -172,6 +180,8 @@ public class VDTConsoleRunner{
stderrStreamProxy= (IStreamsProxy2) processErr.getStreamsProxy();
//TODO: Add error parsers
}
final boolean fHasStdout=(stdoutParser!=null);
final boolean fHasStderr=(stderrParser!=null);
sendErrorsToStreamProxy=(stderrStreamProxy!=null)?stderrStreamProxy:stdoutStreamProxy;
final IStreamsProxy2 fSendErrorsToStreamProxy=sendErrorsToStreamProxy;
......@@ -183,21 +193,46 @@ public class VDTConsoleRunner{
runConfig.resetConsoleText();
String interrupt=buildParamsItem.getInterrupt(); // Not yet used
runConfig.setConsoleFinish(buildParamsItem.getPrompt());
runConfig.setConsoleBad(buildParamsItem.getFailureString());
runConfig.setConsoleGood(buildParamsItem.getSuccessString());
boolean keepOpen= buildParamsItem.keepOpen();
if (keepOpen){
// TODO: Reuse keepOpen for other meaning?
MessageUI.error("keep-open is not supported for termonal scripts (it always keeps it open, ignoring");
}
if (debugPrint) {
System.out.println("Using console program termination string: \""+buildParamsItem.getPrompt()+"\"");
}
errorListener=null;
System.out.println("Using success string: \""+buildParamsItem.getSuccessString()+"\"");
System.out.println("Using failure string: \""+buildParamsItem.getFailureString()+"\"");
}
toolLogFile=(((fSendOutputToStreamProxy!=null) || (fSendErrorsToStreamProxy!=null)))?
(new ToolLogFile (
runConfig.getLogDir(),
runConfig.getToolName(),
buildParamsItem.getLogName(),
null, // extension - use default
fHasStdout, // fSendOutputToStreamProxy!=null, //boolean useOut,
fHasStderr, // fSendErrorsToStreamProxy!=null, //boolean useErr, WRONG
null)) : null;//String buildStamp
if (fSendErrorsToStreamProxy!=null){
//final ToolLogFile fToolLogFile=toolLogFile;
//errorListener=null;
// if (fSendErrorsToStreamProxy!=null){
consoleErrStreamMonitor=consoleInStreamProxy.getErrorStreamMonitor();
errorListener=new IStreamListener(){
public void streamAppended(String text, IStreamMonitor monitor){
if (fSendErrorsToStreamProxy!=null) {
try {
fSendErrorsToStreamProxy.write(text);
} catch (IOException e) {
if (debugPrint) System.out.println("Can not write errors"); //happens for the last prompt got after finish marker
}
}
if (toolLogFile!=null){
toolLogFile.appendErr(text);
}
if (runConfig.addConsoleText(text)){
if (debugPrint) System.out.println("Got finish sequence");
// TODO: launch continuation of the build process
......@@ -206,17 +241,22 @@ public class VDTConsoleRunner{
}
};
consoleErrStreamMonitor.addListener((IStreamListener) errorListener);
}
// }
outputListener=null;
if (fSendOutputToStreamProxy!=null){
// if (fSendOutputToStreamProxy!=null){
consoleOutStreamMonitor=consoleInStreamProxy.getOutputStreamMonitor();
outputListener=new IStreamListener(){
public void streamAppended(String text, IStreamMonitor monitor){
if (fSendOutputToStreamProxy!=null){
try {
fSendOutputToStreamProxy.write(text);
} catch (IOException e) {
if (debugPrint) System.out.println("Can not write output");
}
}
if (toolLogFile!=null){
toolLogFile.appendOut(text);
}
if (runConfig.addConsoleText(text)){
if (debugPrint) System.out.println("Got finish sequence");
// TODO: launch continuation of the build process
......@@ -225,7 +265,7 @@ public class VDTConsoleRunner{
}
};
consoleOutStreamMonitor.addListener((IStreamListener) outputListener );
}
// }
//Problems occurred when invoking code from plug-in: "org.eclipse.ui.console".
//Exception occurred during console property change notification.
outStream.setColor(new Color(null, 128, 128, 255));
......@@ -261,11 +301,15 @@ public class VDTConsoleRunner{
// TODO: remove unneeded global vars
public void finishConsolescript() {
if (VerilogPlugin.getPreferenceBoolean(PreferenceStrings.DEBUG_LAUNCHING))
System.out.println("finishConsolescript()");
final boolean debugPrint=VerilogPlugin.getPreferenceBoolean(PreferenceStrings.DEBUG_LAUNCHING);
if (debugPrint) System.out.println("finishConsolescript()");
if (timer!=null){
timer.cancel();
}
if (toolLogFile!=null){
toolLogFile.close();
if (debugPrint) System.out.println("Closing log file writers");
}
if (consoleInStreamProxy==null) {
System.out.println("Bug: consoleInStreamProxy == null");
return; // or continue other commands?
......@@ -313,26 +357,39 @@ public class VDTConsoleRunner{
}
}
/*
if (processErr!=null){
try {
processErr.terminate();
int thisStep=runConfig.getBuildStep();
if (debugPrint) System.out.println("Finished console task, step was "+thisStep);
// Update tool status - until it is running there will be no actual changes on the icon view - will still spin
Tool tool=ToolsCore.getTool(runConfig.getToolName());
BuildParamsItem buildParamsItem = runConfig.getArgumentsItemsArray()[thisStep];
} catch (DebugException e) {
System.out.println("Failed to terminate processErr parser process");
}
}
if (processOut!=null){
try {
processOut.terminate();
} catch (DebugException e) {
System.out.println("Failed to terminate processOut parser process");
}
if (debugPrint) {
System.out.println("gotBad()="+runConfig.gotBad()+" gotGood()="+runConfig.gotGood());
System.out.println("consoleBuffer=\""+runConfig.getConsoluBuffer()+"\"");
}
*/
int thisStep=runConfig.getBuildStep();
if (VerilogPlugin.getPreferenceBoolean(PreferenceStrings.DEBUG_LAUNCHING))
System.out.println("Finished console task, step was "+thisStep);
if (runConfig.gotBad()|| (
!runConfig.gotGood() &&
(buildParamsItem.getSuccessString()!=null) &&
(buildParamsItem.getFailureString()==null))){
tool.setDirty(false);
tool.setState(TOOL_STATE.FAILURE);
tool.setRunning(false);
tool.setFinishTimeStamp();
tool.updateViewStateIcon();
//removeConfiguration
VDTLaunchUtil.getRunner().getRunningBuilds().removeConfiguration(runConfig.getOriginalConsoleName());
return;
}
if (runConfig.gotGood()){
tool.setDirty(false);
tool.setState(TOOL_STATE.SUCCESS);
} else if (buildParamsItem.getSuccessString()!=null){
tool.setDirty(false);
tool.setState(TOOL_STATE.UNKNOWN);
}
// Go on, continue with the sequence (maybe nothing is left
runConfig.setBuildStep(thisStep+1); // next task to run
VDTLaunchUtil.getRunner().getRunningBuilds().saveUnfinished(runConfig.getOriginalConsoleName(), runConfig );
try {
......@@ -342,4 +399,7 @@ public class VDTConsoleRunner{
e.printStackTrace();
}
}
} // class VDTConsoleRunner
......@@ -103,6 +103,8 @@ public class VDTLaunchConfigurationDelegate implements ILaunchConfigurationDeleg
runConfig.setToolName(VDTLaunchUtil.getToolName(configuration));
runConfig.setPatternWarnings(VDTLaunchUtil.getPatternWarnings(configuration));
runConfig.setPatternInfo(VDTLaunchUtil.getPatternInfo(configuration));
runConfig.setToolLogDir(VDTLaunchUtil.getToolLogDir(configuration));
runConfig.setToolProjectPath(VDTLaunchUtil.getToolProjectPath(configuration));
runConfig.setBuildStep(0);
List<String> controlFiles = VDTLaunchUtil.getControlFiles(configuration);
......@@ -110,9 +112,16 @@ public class VDTLaunchConfigurationDelegate implements ILaunchConfigurationDeleg
// String consoleName=VDTRunner.renderProcessLabel(runConfig.getToolName());
String consoleName=runConfig.getOriginalConsoleName();
runner.getRunningBuilds().saveUnfinished(consoleName, runConfig );
runner.resumeLaunch(consoleName);
String playBackStamp=VDTLaunchUtil.getLogBuildStamp(configuration); // got null
runConfig.setPlayBackStamp(playBackStamp); // null
if (playBackStamp==null){
runner.resumeLaunch(consoleName); // actual run of the tools
} else {
runner.logPlaybackLaunch(consoleName); // tool logs playback with parsing
}
return;
}
......
......@@ -158,15 +158,7 @@ public class VDTLaunchUtil {
try {
String location = getWorkingDirectory(configuration);
tool.setWorkingDirectory(location);
/*
String[] paramArray = tool.buildParams();
System.out.println("Andrey: called tool.buildParams() here (from VDTLaunchUtils.java");
List<String> arguments = new ArrayList<String>(paramArray.length);
for(int i = 0; i < paramArray.length; i++) {
arguments.add(paramArray[i]);
}
return arguments;
*/
BuildParamsItem[] paramItemsArray = tool.buildParams();
if (VerilogPlugin.getPreferenceBoolean(PreferenceStrings.DEBUG_LAUNCHING)) {
System.out.println("called tool.buildParams() here (from VDTLaunchUtils.java)");
......@@ -212,6 +204,11 @@ public class VDTLaunchUtil {
return tool.getPatternInfo();
}
public static String getToolLogDir(ILaunchConfiguration configuration) throws CoreException {
Tool tool = obtainTool(configuration);
return tool.getLogDir();
}
public static List<String> getControlFiles(ILaunchConfiguration configuration) throws CoreException {
Tool tool = obtainTool(configuration);
......@@ -325,11 +322,14 @@ public class VDTLaunchUtil {
return tool;
}
private static IStringVariableManager getStringVariableManager() {
return VariablesPlugin.getDefault().getStringVariableManager();
}
public static String getLogBuildStamp(ILaunchConfiguration configuration) throws CoreException{
return configuration.getAttribute(VDT.ATTR_LOG_BUILD_STAMP, (String) null);
}
/**
* Throws a core exception with an error status object built from
* the given message, lower level exception, and error code.
......
/*******************************************************************************
* Copyright (c) 2014 Elphel, Inc.
* Copyright (c) 2006 Elphel, Inc and Excelsior, LLC.
* This file is a part of Eclipse/VDT plug-in.
* Eclipse/VDT plug-in is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Eclipse/VDT plug-in is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*******************************************************************************/
package com.elphel.vdt.core.launching;
import java.io.File;
import java.util.HashMap;
import java.util.Map;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.SubProgressMonitor;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.model.IProcess;
import org.eclipse.ui.console.IConsole;
//import org.eclipse.debug.ui.console.IConsole;
import org.eclipse.ui.console.ConsolePlugin;
import org.eclipse.ui.console.IConsoleManager;
import com.elphel.vdt.Txt;
import com.elphel.vdt.core.tools.contexts.BuildParamsItem;
//import com.elphel.vdt.ui.MessageUI;
import com.elphel.vdt.veditor.VerilogPlugin;
import com.elphel.vdt.veditor.preference.PreferenceStrings;
//import com.elphel.vdt.core.Utils;
//import org.eclipse.ui.console.IConsoleListener;
/**
* Verilog development tool runner.
*
* Created: 22.12.2005
* @author Lvov Konstantin
*/
public class VDTProgramRunner {
/**
* Returns a new process aborting if the process could not be created.
* @param launch the launch the process is contained in
* @param p the system process to wrap
* @param label the label assigned to the process
* @param attributes values for the attribute map
* @return the new process
* @throws CoreException problems occurred creating the process
*/
protected IProcess newProcess(ILaunch launch, Process p, String label, Map<String, String> attributes) throws CoreException {
IProcess process= DebugPlugin.newProcess(launch, p, label, attributes);
if (process == null) {
p.destroy();
abort(Txt.s("Launch.Process.Error"), null, IStatus.ERROR);
}
return process;
}
/** @see DebugPlugin#exec(String[], File, String[]) */
// before actual launching?
protected Process exec(String[] cmdLine, File workingDirectory, String[] envp) throws CoreException {
return DebugPlugin.exec(cmdLine, workingDirectory, envp);
}
private String combinePatterns (String thisPattern, String toolPattern){
String pattern=thisPattern;
if (pattern==null) pattern=toolPattern;
if ((pattern!=null) && (pattern.length()==0)) pattern=null;
return pattern;
}
/**
* Launches a Verilog development tool as specified in the given
* configuration, contributing results (processes), to the given
* launch.
*
* @param configuration the configuration settings for this run
* @param launch the launch to contribute to
* @param monitor progress monitor or <code>null</code>
* @exception CoreException if an exception occurs while launching
*/
public IProcess run( VDTRunnerConfiguration configuration
, String consoleLabel
, ILaunch launch
, IProgressMonitor monitor
, int numItem
) throws CoreException
{
if (monitor == null) {
monitor = new NullProgressMonitor();
}
// int numItem=configuration.getBuildStep();
VDTRunner runner = VDTLaunchUtil.getRunner();
BuildParamsItem buildParamsItem = configuration.getArgumentsItemsArray()[numItem]; // uses already calculated
String patternErrors= combinePatterns(buildParamsItem.getErrors(), configuration.getPatternErrors()) ;
String patternWarnings=combinePatterns(buildParamsItem.getWarnings(),configuration.getPatternWarnings()) ;
String patternInfo= combinePatterns(buildParamsItem.getInfo(), configuration.getPatternInfo()) ;
IProgressMonitor subMonitor = new SubProgressMonitor(monitor, 1);
subMonitor.beginTask(Txt.s("Launch.Message.Launching"), 2);
subMonitor.subTask(Txt.s("Launch.Message.ConstructingCommandLine"));
String toolTolaunch = configuration.getToolToLaunch();
String[] arguments = configuration.getToolArguments();
boolean isShell= configuration.getIsShell();
if (VerilogPlugin.getPreferenceBoolean(PreferenceStrings.DEBUG_LAUNCHING)) {
System.out.println("patternErrors= \""+ patternErrors+"\"");
System.out.println("patternWarnings= \""+patternWarnings+"\"");
System.out.println("patternInfo= \"" +patternInfo+"\"");
System.out.println((isShell?"Shell":"Tool")+" to launch=\""+toolTolaunch+"\"");
if (arguments!=null){
for (int i=0;i<arguments.length;i++){
System.out.println("Argument "+i+" = \""+arguments[i]+"\"");
}
}
}
String[] cmdLine;
if (isShell && (arguments != null) && (arguments.length > 0)){ /* first argument is passed as a parameter to shell*/
StringBuilder builder = new StringBuilder();
cmdLine = new String[3];
cmdLine[0]=toolTolaunch;
cmdLine[1]=(arguments[0].equals("@EMPTY"))?"":arguments[0]; // Can not be set to empty
for (int i=1;i<arguments.length;i++) {
builder.append(" ");
builder.append(arguments[i]);
}
cmdLine[2]=builder.toString().trim();
} else {
int cmdLineLength = 1;
if (arguments != null) {
cmdLineLength += arguments.length;
}
cmdLine = new String[cmdLineLength];
cmdLine[0] = toolTolaunch;
if (arguments != null) {
System.arraycopy(arguments, 0, cmdLine, 1, arguments.length);
}
}
if (VerilogPlugin.getPreferenceBoolean(PreferenceStrings.DEBUG_LAUNCHING)) {
for (int i=0;i<cmdLine.length;i++){
System.out.println("cmdLine["+i+"] = \""+cmdLine[i]+"\"");
}
}
String[] controlFiles = configuration.getControlFiles();
runner.log(null,cmdLine, controlFiles, false, true); /* Appears in the console of the target Eclipse (immediately erased) */
runner.log(null,cmdLine, controlFiles, false, false); /* Appears in the console of the parent Eclipse */
String[] envp = configuration.getEnvironment();
subMonitor.worked(1);
// check for cancellation
if (monitor.isCanceled()) {
return null;
}
subMonitor.subTask(Txt.s("Launch.Message.Starting"));
File workingDir = getWorkingDir(configuration); /* /data/vdt/runtime-EclipseApplication/x353 */
Process p = exec(cmdLine, workingDir, envp);
if (p == null) {
return null;
}
// check for cancellation
if (monitor.isCanceled()) {
p.destroy();
return null;
}
VDTErrorParser parser= VerilogPlugin.getVDTErrorParser();
/* next actually launches the process */
/* IProcess may set/get client parameters */
IProcess process= newProcess( launch
, p
, consoleLabel // renderProcessLabel(configuration.getToolName())
, getDefaultProcessAttrMap(configuration));
parser.parserSetup(
configuration,
process,
patternErrors,
patternWarnings,
patternInfo
);
subMonitor.worked(1);
subMonitor.done();
if (VerilogPlugin.getPreferenceBoolean(PreferenceStrings.DEBUG_LAUNCHING)){
IConsoleManager man = ConsolePlugin.getDefault().getConsoleManager(); // debugging
IConsole[] consoles=(IConsole[]) man.getConsoles();
System.out.println(consoles.length+" consoles, processes="+launch.getChildren().length);
}
return process;
} // run()
/**
* Returns the default process attribute map for tool processes.
*
* @return default process attribute map for Java processes
*/
protected Map<String, String> getDefaultProcessAttrMap(VDTRunnerConfiguration config) {
Map<String, String> map = new HashMap<String, String>();
// map.put(IProcess.ATTR_PROCESS_TYPE, Utils.getPureFileName(config.getToolToLaunch()));
map.put(IProcess.ATTR_PROCESS_TYPE,config.getToolName());
return map;
}
/**
* Returns the working directory to use for the launched tool,
* or <code>null</code> if the working directory is to be inherited
* from the current process.
*
* @return the working directory to use
* @exception CoreException if the working directory specified by
* the configuration does not exist or is not a directory
*/
protected File getWorkingDir(VDTRunnerConfiguration config) throws CoreException {
String path = config.getWorkingDirectory();
if (path == null) {
return null;
}
File dir = new File(path);
if (!dir.isDirectory()) {
abort(Txt.s("Launch.Error.InvalidWorkingDir", new String[] {path}), null, IStatus.ERROR);
}
return dir;
}
/**
* Throws a core exception with an error status object built from
* the given message, lower level exception, and error code.
*
* @param message the status message
* @param exception lower level exception associated with the
* error, or <code>null</code> if none
* @param code error code
* @throws CoreException The exception encapsulating the reason for the abort
*/
protected void abort(String message, Throwable exception, int code) throws CoreException {
throw new CoreException(new Status(IStatus.ERROR, VerilogPlugin.getVdtId(), code, message, exception));
}
} // class VDTProgramRunner
/*******************************************************************************
* Copyright (c) 2014 Elphel, Inc.
* Copyright (c) 2006 Elphel, Inc and Excelsior, LLC.
* This file is a part of Eclipse/VDT plug-in.
* Eclipse/VDT plug-in is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your option)
* any later version.
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Eclipse/VDT plug-in is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
* Eclipse/VDT plug-in is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with Eclipse VDT plug-in; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*******************************************************************************/
package com.elphel.vdt.core.launching;
......@@ -57,6 +57,7 @@ import org.eclipse.debug.ui.DebugUITools;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.console.IConsole;
//import org.eclipse.debug.ui.console.IConsole;
import org.eclipse.ui.console.ConsolePlugin;
......@@ -66,6 +67,7 @@ import org.eclipse.ui.console.IOConsoleInputStream;
import org.eclipse.ui.console.IOConsoleOutputStream;
import com.elphel.vdt.Txt;
import com.elphel.vdt.core.tools.ToolsCore;
import com.elphel.vdt.core.tools.contexts.BuildParamsItem;
import com.elphel.vdt.ui.MessageUI;
//import com.elphel.vdt.VDTPlugin;
......@@ -76,13 +78,6 @@ import com.elphel.vdt.veditor.preference.PreferenceStrings;
//import com.elphel.vdt.core.Utils;
import org.eclipse.ui.console.IConsoleListener;
......@@ -103,6 +98,16 @@ public class VDTRunner {
return runningBuilds;
}
public void resumeLaunch(String consoleName) throws CoreException {
try {
doResumeLaunch(consoleName);
} catch(Exception e) {
MessageUI.error(e);
if(e instanceof CoreException)
throw (CoreException)e;
}
}
// make call it when console is closed
private void doResumeLaunch(String consoleName ) throws CoreException {
final VDTRunnerConfiguration runConfig=runningBuilds.resumeConfiguration(consoleName);
......@@ -112,7 +117,17 @@ public class VDTRunner {
System.out.println("Turned out nothing to do. Probably a bug");
return;
}
String playBackStamp=runConfig.getPlayBackStamp();
if (playBackStamp!=null){
System.out.println("doResumeLaunch(): wrong, it should be playback, not run, as playBackStamp = "+playBackStamp+ "(not null)");
return;
}
BuildParamsItem[] argumentsItemsArray = runConfig.getArgumentsItemsArray(); // uses already calculated
runConfig.canceTimers(); // If some timers were set, but a task finished earlier
int numItem=runConfig.getBuildStep();
if (debugPrint) System.out.println("--------- resuming "+ consoleName+", numItem="+numItem+" ------------");
ILaunch launch=runConfig.getLaunch();
......@@ -139,9 +154,9 @@ public class VDTRunner {
}
// Launch the configuration - 1 unit of work
// VDTRunner runner = VDTLaunchUtil.getRunner();
IProcess process=run(
// IProcess process=run(
IProcess process=runConfig.getProgramRunner().run(
runConfig,
// renderProcessLabel(runConfig.getToolName()), // toolname + (date)
runConfig.getOriginalConsoleName(),
launch,
monitor,
......@@ -157,13 +172,17 @@ public class VDTRunner {
}
// if (numItem<(argumentsItemsArray.length-1)){ // Not for the last
// find out if there are any non-parsers left
/*
boolean moreToProcess=false;
for (int i=numItem+1;i<argumentsItemsArray.length;numItem++)
if (argumentsItemsArray[numItem].getNameAsParser()==null) {
moreToProcess=true;
break;
}
moreToProcess=true; // TODO: remove later - should always wait if keep is not set
if (moreToProcess){
*/
IOConsole iCons= (IOConsole) DebugUITools.getConsole(process); // had non-null fPatternMatcher , fType="org.eclipse.debug.ui.ProcessConsoleType"
if (iCons==null){
System.out.println("Could not get console for the specified process");
......@@ -172,9 +191,9 @@ public class VDTRunner {
if (debugPrint) System.out.println("originalConsoleName="+consoleName+
"\nprocessConsole name="+iCons.getName());
final IOConsole fiCons=iCons;
// final String fConsoleName=fiCons.getName(); // actual console name - may be already "<terminated> ... "
// final String fConsoleName=fiCons.getName(); // actual console name - may be already "<terminated> ... "
final String fConsoleName=consoleName; // calculated console name - used for launching external program
// if (!fConsoleName.equals(consoleName)){ // terminated before we added listeners
// if (!fConsoleName.equals(consoleName)){ // terminated before we added listeners
if (!fConsoleName.equals(fiCons.getName())){ // terminated before we added listeners
if (debugPrint) System.out.println("Already terminated, proceed to the next item");
continue; // proceed with the next item without pausing
......@@ -183,58 +202,85 @@ public class VDTRunner {
runConfig.setBuildStep(numItem+1);
runningBuilds.saveUnfinished(consoleName, runConfig );
iCons.addPropertyChangeListener( new IPropertyChangeListener() {
final IPropertyChangeListener fListener =new IPropertyChangeListener() {
public void propertyChange(PropertyChangeEvent event) {
if (!fConsoleName.equals(fiCons.getName())){
fiCons.removePropertyChangeListener(this);
if (debugPrint) System.out.println(">>> "+fConsoleName+" -> "+fiCons.getName());
try {
resumeLaunch(fConsoleName); // replace with console
resumeLaunch(fConsoleName); //, fiCons, this); // replace with console
} catch (CoreException e) {
System.out.println ("Failed to resume launch sequence");
}
}
}
});
};
fiCons.addPropertyChangeListener(fListener);
if (debugPrint) System.out.println("fiCons.getName()="+fiCons.getName()+"addPropertyChangeListener()");
if (!fConsoleName.equals(consoleName)){ // terminated before we added listeners
if (debugPrint) System.out.println("Fire!");
iCons.firePropertyChange(fiCons,"org.eclipse.jface.text", consoleName, fConsoleName);
fiCons.firePropertyChange(fiCons,"org.eclipse.jface.text", consoleName, fConsoleName);
}
if (debugPrint) System.out.println("return - waiting to be awaken");
int timeout=argumentsItemsArray[numItem].getTimeout();
//keepOpen()
final boolean fKeepOpen=argumentsItemsArray[numItem].keepOpen();
if (fKeepOpen && (timeout<1)) timeout=1; // some minimal timeout
if (timeout>0){
System.out.println ("timeout is only implemented for console scripts");
if (debugPrint) System.out.println ("timeout="+timeout+"s, keep-open="+ fKeepOpen);
// implementation will require keeping track of it and canceling if program terminated earlier.
// And for the programs it is easy to kill them manually with a red square button
if (timeout>100000) { //never with no warnings
if (timeout>0) { //never with no warnings
final int fTimeout = timeout;
final IProcess fProcess=process;
new Timer().schedule(new TimerTask() {
// new Timer().schedule(new TimerTask() {
argumentsItemsArray[numItem].getTimer().schedule(new TimerTask() {
@Override
public void run() {
System.out.println(">>Timeout<<");
if (debugPrint) System.out.println(">> Got timeout after "+fTimeout+"sec <<");
if (fKeepOpen) {
fiCons.removePropertyChangeListener(fListener);
if (debugPrint) System.out.println("Timeout-initialted firePropertyChange on "+fConsoleName);
Display.getDefault().syncExec(new Runnable() {
public void run() {
try {
resumeLaunch(fConsoleName);
} catch (CoreException e) {
System.out.println("Failed to resumeLaunch after timer"+fConsoleName);
} //, fiCons, this); // replace with console
}
});
} else {
try {
fProcess.terminate();
if (debugPrint) System.out.println(">> "+fConsoleName+": terminated by timeout <<");
} catch (DebugException e) {
System.out.println("Failed to terminate process on "+fConsoleName);
}
}
}
}, fTimeout*1000);
}
}
return;
}
}
// }
} //for (;numItem<argumentsItemsArray.length;numItem++){
if (debugPrint) System.out.println("All finished");
monitor.done();
ToolsCore.getTool(runConfig.getToolName()).setRunning(false);
ToolsCore.getTool(runConfig.getToolName()).setFinishTimeStamp();
ToolsCore.getTool(runConfig.getToolName()).updateViewStateIcon();
}
public void resumeLaunch(String consoleName) throws CoreException
{
public void logPlaybackLaunch(String consoleName) throws CoreException {
try {
doResumeLaunch(consoleName);
doLogPlaybackLaunch(consoleName);
} catch(Exception e) {
MessageUI.error(e);
......@@ -242,177 +288,55 @@ public class VDTRunner {
throw (CoreException)e;
}
}
// make call it when console is closed
private void doLogPlaybackLaunch(String consoleName ) throws CoreException {
final VDTRunnerConfiguration runConfig=runningBuilds.resumeConfiguration(consoleName);
final boolean debugPrint=VerilogPlugin.getPreferenceBoolean(PreferenceStrings.DEBUG_LAUNCHING);
/**
* Returns a new process aborting if the process could not be created.
* @param launch the launch the process is contained in
* @param p the system process to wrap
* @param label the label assigned to the process
* @param attributes values for the attribute map
* @return the new process
* @throws CoreException problems occurred creating the process
*/
protected IProcess newProcess(ILaunch launch, Process p, String label, Map attributes) throws CoreException {
IProcess process= DebugPlugin.newProcess(launch, p, label, attributes);
if (process == null) {
p.destroy();
abort(Txt.s("Launch.Process.Error"), null, IStatus.ERROR);
}
return process;
}
/** @see DebugPlugin#exec(String[], File, String[]) */
// before actual launching?
protected Process exec(String[] cmdLine, File workingDirectory, String[] envp) throws CoreException {
return DebugPlugin.exec(cmdLine, workingDirectory, envp);
}
private String combinePatterns (String thisPattern, String toolPattern){
String pattern=thisPattern;
if (pattern==null) pattern=toolPattern;
if ((pattern!=null) && (pattern.length()==0)) pattern=null;
return pattern;
}
/**
* Launches a Verilog development tool as specified in the given
* configuration, contributing results (processes), to the given
* launch.
*
* @param configuration the configuration settings for this run
* @param launch the launch to contribute to
* @param monitor progress monitor or <code>null</code>
* @exception CoreException if an exception occurs while launching
*/
public IProcess run( VDTRunnerConfiguration configuration
, String consoleLabel
, ILaunch launch
, IProgressMonitor monitor
, int numItem
) throws CoreException
{
if (monitor == null) {
monitor = new NullProgressMonitor();
}
// int numItem=configuration.getBuildStep();
BuildParamsItem buildParamsItem = configuration.getArgumentsItemsArray()[numItem]; // uses already calculated
String patternErrors= combinePatterns(buildParamsItem.getErrors(), configuration.getPatternErrors()) ;
String patternWarnings=combinePatterns(buildParamsItem.getWarnings(),configuration.getPatternWarnings()) ;
String patternInfo= combinePatterns(buildParamsItem.getInfo(), configuration.getPatternInfo()) ;
IProgressMonitor subMonitor = new SubProgressMonitor(monitor, 1);
subMonitor.beginTask(Txt.s("Launch.Message.Launching"), 2);
subMonitor.subTask(Txt.s("Launch.Message.ConstructingCommandLine"));
String toolTolaunch = configuration.getToolToLaunch();
String[] arguments = configuration.getToolArguments();
boolean isShell= configuration.getIsShell();
if (VerilogPlugin.getPreferenceBoolean(PreferenceStrings.DEBUG_LAUNCHING)) {
System.out.println("patternErrors= \""+ patternErrors+"\"");
System.out.println("patternWarnings= \""+patternWarnings+"\"");
System.out.println("patternInfo= \"" +patternInfo+"\"");
System.out.println((isShell?"Shell":"Tool")+" to launch=\""+toolTolaunch+"\"");
if (arguments!=null){
for (int i=0;i<arguments.length;i++){
System.out.println("Argument "+i+" = \""+arguments[i]+"\"");
if (runConfig==null){
System.out.println("Turned out nothing to do. Probably a bug");
return;
}
}
String playBackStamp=runConfig.getPlayBackStamp();
if (playBackStamp==null){
System.out.println("doResumeLaunch(): wrong, it should be run, not playback, as playBackStamp = null");
return;
}
String[] cmdLine;
if (isShell && (arguments != null) && (arguments.length > 0)){ /* first argument is passed as a parameter to shell*/
StringBuilder builder = new StringBuilder();
cmdLine = new String[3];
cmdLine[0]=toolTolaunch;
cmdLine[1]=(arguments[0].equals("@EMPTY"))?"":arguments[0]; // Can not be set to empty
for (int i=1;i<arguments.length;i++) {
builder.append(" ");
builder.append(arguments[i]);
}
cmdLine[2]=builder.toString().trim();
} else {
int cmdLineLength = 1;
if (arguments != null) {
cmdLineLength += arguments.length;
}
cmdLine = new String[cmdLineLength];
cmdLine[0] = toolTolaunch;
if (arguments != null) {
System.arraycopy(arguments, 0, cmdLine, 1, arguments.length);
}
}
if (VerilogPlugin.getPreferenceBoolean(PreferenceStrings.DEBUG_LAUNCHING)) {
for (int i=0;i<cmdLine.length;i++){
System.out.println("cmdLine["+i+"] = \""+cmdLine[i]+"\"");
}
BuildParamsItem[] argumentsItemsArray = runConfig.getArgumentsItemsArray(); // uses already calculated
runConfig.canceTimers(); // If some timers were set, but a task finished earlier
int numItem=runConfig.getBuildStep();
if (debugPrint) System.out.println("--------- re-playing log from "+ consoleName+", numItem="+numItem+" ------------");
ILaunch launch=runConfig.getLaunch();
IProgressMonitor monitor=runConfig.getMonitor();
for (;numItem<argumentsItemsArray.length;numItem++){
runConfig.setBuildStep(numItem); // was not updated if was not sleeping
List<String> toolArguments = new ArrayList<String>();
List<String> arguments=argumentsItemsArray[numItem].getParamsAsList();
if (arguments != null)
toolArguments.addAll(arguments);
runConfig.setToolArguments((String[])toolArguments.toArray(new String[toolArguments.size()]));
if (argumentsItemsArray[numItem].getConsoleName()!=null){
VDTConsolePlayback consolePlayback= runConfig.getConsolePlayback();
consolePlayback.runConsole(argumentsItemsArray[numItem].getConsoleName(), launch, monitor);
continue; // No wait, will get back here
//continue;
}
String[] controlFiles = configuration.getControlFiles();
log(null,cmdLine, controlFiles, false, true); /* Appears in the console of the target Eclipse (immediately erased) */
log(null,cmdLine, controlFiles, false, false); /* Appears in the console of the parent Eclipse */
String[] envp = configuration.getEnvironment();
subMonitor.worked(1);
// check for cancellation
if (monitor.isCanceled()) {
return null;
if (argumentsItemsArray[numItem].getNameAsParser()!=null){
// parsers should be launched by the console scripts, in parallel to them
if (debugPrint) System.out.println("Skipping parser "+argumentsItemsArray[numItem].getNameAsParser());
continue;
}
subMonitor.subTask(Txt.s("Launch.Message.Starting"));
File workingDir = getWorkingDir(configuration); /* /data/vdt/runtime-EclipseApplication/x353 */
Process p = exec(cmdLine, workingDir, envp);
if (p == null) {
return null;
if (debugPrint) System.out.println("Skipping program runner as playback is not implemented, arguments were "+argumentsItemsArray[numItem].getNameAsParser());
} //for (;numItem<argumentsItemsArray.length;numItem++){
System.out.println("All playbacks finished");
monitor.done();
ToolsCore.getTool(runConfig.getToolName()).setRunning(false);
ToolsCore.getTool(runConfig.getToolName()).updateViewStateIcon();
}
// check for cancellation
if (monitor.isCanceled()) {
p.destroy();
return null;
}
VDTErrorParser parser= VerilogPlugin.getVDTErrorParser();
IConsoleManager man = ConsolePlugin.getDefault().getConsoleManager(); // debugging
IConsole[] consoles=(IConsole[]) man.getConsoles();
//[Lorg.eclipse.ui.console.IConsole; cannot be cast to [Lorg.eclipse.debug.ui.console.IConsole;
/* next actually launches the process */
/* IProcess may set/get client parameters */
IProcess process= newProcess( launch
, p
// , renderProcessLabel(cmdLine)
, consoleLabel // renderProcessLabel(configuration.getToolName())
, getDefaultProcessAttrMap(configuration));
parser.parserSetup(
configuration,
process,
patternErrors,
patternWarnings,
patternInfo
);
subMonitor.worked(1);
subMonitor.done();
man = ConsolePlugin.getDefault().getConsoleManager(); // debugging
consoles=(IConsole[]) man.getConsoles();
if (consoles.length>1){
// ((IConsole) consoles[1]).setName("Python Consloe");
}
if (VerilogPlugin.getPreferenceBoolean(PreferenceStrings.DEBUG_LAUNCHING)){
System.out.println(consoles.length+" consoles, processes="+launch.getChildren().length);
}
return process;
//= consoles
//setImageDescriptor
// getImageDescriptor()
} // run()
public void log(String header,
String[] strings,
......@@ -437,13 +361,13 @@ public class VDTRunner {
if(formatColumn)
println(printToUser);
if (strings!=null){
for(int i = 0; i < strings.length; i++)
if(formatColumn)
println("#" + i + ": '" + strings[i] + "'", printToUser);
else
print(strings[i] + " ", printToUser);
}
if(!formatColumn)
println(printToUser);
......@@ -467,53 +391,6 @@ public class VDTRunner {
System.out.print(msg);
}
/**
* Returns the default process attribute map for tool processes.
*
* @return default process attribute map for Java processes
*/
protected Map<String, String> getDefaultProcessAttrMap(VDTRunnerConfiguration config) {
Map<String, String> map = new HashMap<String, String>();
// map.put(IProcess.ATTR_PROCESS_TYPE, Utils.getPureFileName(config.getToolToLaunch()));
map.put(IProcess.ATTR_PROCESS_TYPE,config.getToolName());
return map;
}
/**
* Returns the working directory to use for the launched tool,
* or <code>null</code> if the working directory is to be inherited
* from the current process.
*
* @return the working directory to use
* @exception CoreException if the working directory specified by
* the configuration does not exist or is not a directory
*/
protected File getWorkingDir(VDTRunnerConfiguration config) throws CoreException {
String path = config.getWorkingDirectory();
if (path == null) {
return null;
}
File dir = new File(path);
if (!dir.isDirectory()) {
abort(Txt.s("Launch.Error.InvalidWorkingDir", new String[] {path}), null, IStatus.ERROR);
}
return dir;
}
/**
* Throws a core exception with an error status object built from
* the given message, lower level exception, and error code.
*
* @param message the status message
* @param exception lower level exception associated with the
* error, or <code>null</code> if none
* @param code error code
* @throws CoreException The exception encapsulating the reason for the abort
*/
protected void abort(String message, Throwable exception, int code) throws CoreException {
throw new CoreException(new Status(IStatus.ERROR, VerilogPlugin.getVdtId(), code, message, exception));
}
public static String renderProcessLabel(String[] commandLine) {
String timestamp= DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.MEDIUM).format(new Date(System.currentTimeMillis()));
return Txt.s("Launch.Process.LabelFormat", new String[] {commandLine[0], timestamp});
......@@ -522,11 +399,4 @@ public class VDTRunner {
String timestamp= DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.MEDIUM).format(new Date(System.currentTimeMillis()));
return Txt.s("Launch.Process.LabelFormat", new String[] {toolName, timestamp});
}
protected static String renderCommandLine(String[] commandLine) {
if (commandLine.length == 0)
return "";
return " " + new File(commandLine[0]).getName();
}
} // class VDTRunner
......@@ -19,6 +19,8 @@ package com.elphel.vdt.core.launching;
import java.util.HashSet;
import java.util.Set;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.debug.core.ILaunch;
......@@ -28,6 +30,7 @@ import org.eclipse.ui.console.IConsole;
import com.elphel.vdt.Txt;
import com.elphel.vdt.core.tools.contexts.BuildParamsItem;
import com.elphel.vdt.ui.MessageUI;
/**
......@@ -55,6 +58,8 @@ public class VDTRunnerConfiguration {
private String toolErrors;
private String toolWarnings;
private String toolInfo;
private String toolLogDir;
private int buildStep;
private ILaunchConfiguration configuration;
private ILaunch launch;
......@@ -62,18 +67,41 @@ public class VDTRunnerConfiguration {
private BuildParamsItem[] argumentsItemsArray; // calculate once for the launch of the sequence
private String consoleFinish; // double prompt? - string to look for in consoleBuffer to finish
private String consoleGood; // output console sequence meaning success of the tool
private String consoleBad; // output console sequence meaning failure of the tool
private boolean hasGood; // at least one "good" sequence was received
private boolean hasBad; // at least one "bad" sequence was received
private String consoleBuffer; // accumulates stdout & stderr, looking for consoleFinish (endsWith() )
private int extraChars=100; // Allow these chars to appear in the output after consoleFinish (user pressed smth.?)
// private int extraChars=100; // Allow these chars to appear in the output after consoleFinish (user pressed smth.?)
private int extraChars=1000; // Allow these chars to appear in the output after consoleFinish (user pressed smth.?)
private String originalConsoleName=null; // will replace
private String buildDateTime=null;
private int maxLength=extraChars;
private Pattern patternGood=null;
private Pattern patternBad=null;
private String playBackStamp=null; // timestamp of the logs to play back ("" for latest), or
// null for normal running tools
private Set<IConsole> consoles=null; // parser consoles opened for this console
private VDTConsoleRunner consoleRunner=null;
private VDTProgramRunner programRunner=null;
private VDTConsolePlayback consolePlayback=null;
public BuildParamsItem[] getArgumentsItemsArray(){
return argumentsItemsArray;
}
public void canceTimers(){
if (argumentsItemsArray!=null) for (int i=0;i<buildStep;i++){
argumentsItemsArray[i].cancelTimer();
}
}
public void setArgumentsItemsArray(BuildParamsItem[] argumentsItemsArray){
this.argumentsItemsArray=argumentsItemsArray;
}
......@@ -93,15 +121,37 @@ public class VDTRunnerConfiguration {
}
this.toolToLaunch = toolToLaunch;
this.consoleFinish=null;
this.consoleGood=null;
this.consoleBad=null;
this.playBackStamp=null;
this.consoleBuffer="";
this.consoles= new HashSet<IConsole>();
this.consoleRunner= new VDTConsoleRunner(this); // arguments here?
this.programRunner=new VDTProgramRunner(); // arguments here?
this.consolePlayback=new VDTConsolePlayback(this);
}
public void setPlayBackStamp(String str){
playBackStamp=str;
}
public String getPlayBackStamp(){
return playBackStamp;
}
public VDTConsoleRunner getConsoleRunner(){
return this.consoleRunner;
}
public VDTConsolePlayback getConsolePlayback(){
return this.consolePlayback;
}
public VDTProgramRunner getProgramRunner(){
return this.programRunner;
}
public void addConsole(IConsole console){
consoles.add(console);
}
......@@ -117,19 +167,112 @@ public class VDTRunnerConfiguration {
public void setConsoleFinish(String consoleFinish){
this.consoleFinish=consoleFinish;
if ((this.consoleFinish!=null) && ((this.consoleFinish.length()+extraChars) > maxLength)){
maxLength=this.consoleFinish.length()+extraChars;
}
}
public void setConsoleBad(String consoleBad){
this.consoleBad=consoleBad;
this.hasBad=false;
if ((consoleBad!=null) && (consoleBad.length()==0)) this.consoleBad=null;
if ((this.consoleBad!=null) && ((this.consoleBad.length()+extraChars) > maxLength)){
maxLength=this.consoleBad.length()+extraChars;
}
// Patterns that start with "!" are always treated as not being regexp, "!" removed
// "\" in the first position escapes "!" (only in the first and on;y "!")
patternBad=null;
if (this.consoleBad!=null) {
if ((this.consoleBad.length()>=2) && (this.consoleBad.substring(0,2).equals("\\!"))){
this.consoleBad=this.consoleBad.substring(1);
} else if ((this.consoleBad.length()>=1) && (this.consoleBad.substring(0,1).equals("!"))){
this.consoleBad=this.consoleBad.substring(1);
} else {
try {
patternBad=Pattern.compile(this.consoleBad);
} catch (PatternSyntaxException e){
MessageUI.error("Invalid regular expression: \""+this.consoleBad+"\" - using is as a literal string");
// just use string, not pattern
}
}
public boolean addConsoleText(String text){
if (consoleFinish==null){
System.out.println("Dinish console sequence is not defined");
return false;
}
}
public void setConsoleGood(String consoleGood){
if ((consoleGood!=null) && (consoleGood.length()==0)){ // empty but not null - no need to check, considered always to happen
this.hasGood=true;
this.consoleGood=null;
} else {
this.consoleGood=consoleGood;
this.hasGood=false;
}
if ((this.consoleGood!=null) && ((this.consoleGood.length()+extraChars) > maxLength)){
maxLength=this.consoleGood.length()+extraChars;
}
patternGood=null;
// Patterns that start with "!" are always treated as not being regexp, "!" removed
// "\" in the first position escapes "!" (only in the first and on;y "!")
if (this.consoleGood!=null) {
if ((this.consoleGood.length()>=2) && (this.consoleGood.substring(0,2).equals("\\!"))){
this.consoleGood=this.consoleGood.substring(1);
} else if ((this.consoleGood.length()>=1) && (this.consoleGood.substring(0,1).equals("!"))){
this.consoleGood=this.consoleGood.substring(1);
} else {
try {
patternGood=Pattern.compile(this.consoleGood);
} catch (PatternSyntaxException e){
MessageUI.error("Invalid regular expression: \""+this.consoleGood+"\" - using is as a literal string");
patternGood=null;
// just use string, not pattern
}
}
}
}
public boolean gotBad(){
return hasBad;
}
public boolean gotGood(){
return hasGood;
}
public String getConsoluBuffer(){
return consoleBuffer; // just for debugging
}
public boolean addConsoleText(String text){
// if (consoleFinish==null){
// System.out.println("Finish console sequence is not defined");
// return false;
// }
consoleBuffer=consoleBuffer+text;
int maxLength=consoleFinish.length()+extraChars;
if (consoleBuffer.length()>(maxLength)){
consoleBuffer=consoleBuffer.substring(consoleBuffer.length()-maxLength);
}
if ((patternBad!=null) && patternBad.matcher(consoleBuffer).matches()){
hasBad=true;
return true;
} else {
if ((consoleBad!=null) && (consoleBuffer.indexOf(consoleBad)>=0)) {
hasBad=true;
// Should we return true immediately or still wait for consoleFinish?
// Or only return true if (consoleFinish==null) ??
// resetConsoleText();
return true; // return as soon as got failure - anyway there will be no next tools running
}
}
if ((patternGood!=null) && patternGood.matcher(consoleBuffer).matches()){
hasGood=true;
} else {
if ((consoleGood!=null) && (consoleBuffer.indexOf(consoleGood)>=0)) {
hasGood=true;
}
}
if (consoleFinish==null){
return false;
}
if (consoleBuffer.indexOf(consoleFinish)>=0){
resetConsoleText();
// resetConsoleText();
return true;
}
return false;
......@@ -243,7 +386,13 @@ public class VDTRunnerConfiguration {
this.toolInfo=str;
}
public void setToolLogDir(String str) {
this.toolLogDir=str;
}
public String getLogDir(){
return this.toolLogDir;
}
/**
* Returns the arguments to the tool.
......
......@@ -69,17 +69,27 @@ public class CommandLinesNodeReader extends AbstractConditionNodeReader {
String stdout = XMLConfig.getAttributeValue(node, XMLConfig.CONTEXT_LINEBLOCK_STDOUT_ATTR);
String timeout = XMLConfig.getAttributeValue(node, XMLConfig.CONTEXT_LINEBLOCK_TIMEOUT_ATTR);
String success = XMLConfig.getAttributeValue(node, XMLConfig.CONTEXT_LINEBLOCK_SUCCESS_ATTR);
String failure = XMLConfig.getAttributeValue(node, XMLConfig.CONTEXT_LINEBLOCK_FAILURE_ATTR);
String s_keep_open =XMLConfig.getAttributeValue(node, XMLConfig.CONTEXT_LINEBLOCK_KEEP_OPEN_ATTR);
String logPath = XMLConfig.getAttributeValue(node, XMLConfig.CONTEXT_LINEBLOCK_LOGPATH_ATTR);
boolean keep_open=false;
if(s_keep_open != null) {
XMLConfig.checkBoolAttr(s_keep_open, XMLConfig.CONTEXT_LINEBLOCK_KEEP_OPEN_ATTR);
keep_open = XMLConfig.getBoolAttrValue(s_keep_open);
}
if(name == null)
throw new ConfigException("Unnamed lines block definition in context '" +
context.getName() + "' definition");
ConditionalStringsList lines =
config.readConditionalStringsNode(node, context, condition);
ConditionalStringsList deleteLines =
config.readDeleteStringsNode(node, context, condition);
List<NamedConditionalStringsList> insertLines =
config.readInsertStringsNode(node, context, condition);
return new CommandLinesBlock(context.getName(),
name,
dest,
......@@ -94,6 +104,10 @@ public class CommandLinesNodeReader extends AbstractConditionNodeReader {
stderr,
stdout,
timeout,
success,
failure,
keep_open,
logPath,
lines,
deleteLines,
insertLines);
......
......@@ -110,7 +110,10 @@ public class XMLConfig extends Config {
static final String CONTEXT_TOOL_ACTION_CHECK_EXTENSION = "check-extension";
static final String CONTEXT_TOOL_ACTION_CHECK_EXISTENCE = "check-existence";
static final String CONTEXT_TOOL_ACTION_ICON = "icon";
static final String CONTEXT_TOOL_DEPENDS_LIST_TAG = "depends-list";
static final String CONTEXT_TOOL_DEPENDS_TAG = "depends";
static final String CONTEXT_TOOL_DEPENDS_TOOL_TAG = "tool";
// TODO: May add other types of dependencies
static final String CONTEXT_TOOL_DFLT_ACTION_LABEL = "Run for";
static final String CONTEXT_TOOL_DFLT_ACTION_RESOURCE = "%%CurrentFile";
......@@ -122,6 +125,7 @@ public class XMLConfig extends Config {
static final String CONTEXT_TOOL_SYNTAX_WARNINGS= "warnings";
static final String CONTEXT_TOOL_SYNTAX_INFO = "info";
static final String CONTEXT_TOOL_IGNORE_FILTER = "ignore"; // file path regular expression to remove libraries from source list
static final String CONTEXT_TOOL_LOG_DIRECTORY = "log-dir"; // folder to store the tool log files
static final String CONTEXT_LINEBLOCK_TAG = "line";
static final String CONTEXT_LINEBLOCK_NAME_ATTR = "name";
......@@ -138,6 +142,11 @@ public class XMLConfig extends Config {
static final String CONTEXT_LINEBLOCK_STDOUT_ATTR = "stdout";
static final String CONTEXT_LINEBLOCK_TIMEOUT_ATTR = "timeout";
static final String CONTEXT_LINEBLOCK_SUCCESS_ATTR = "success";
static final String CONTEXT_LINEBLOCK_FAILURE_ATTR = "failure";
static final String CONTEXT_LINEBLOCK_KEEP_OPEN_ATTR ="keep-open";
static final String CONTEXT_LINEBLOCK_LOGPATH_ATTR = "log";
static final String CONTEXT_STRINGS_DELETE_TAG = "delete";
static final String CONTEXT_STRINGS_INSERT_TAG = "insert";
static final String CONTEXT_STRINGS_INSERT_AFTER_ATTR = "after";
......@@ -613,6 +622,7 @@ public class XMLConfig extends Config {
String toolWarnings = getAttributeValue(contextNode, CONTEXT_TOOL_SYNTAX_WARNINGS);
String toolInfo = getAttributeValue(contextNode, CONTEXT_TOOL_SYNTAX_INFO);
String ignoreFilter = getAttributeValue(contextNode, CONTEXT_TOOL_IGNORE_FILTER);
String logDir = getAttributeValue(contextNode, CONTEXT_TOOL_LOG_DIRECTORY);
boolean isShell=false;
if (toolShell != null){
......@@ -625,7 +635,7 @@ public class XMLConfig extends Config {
List<String> toolExtensionsList = readToolExtensionsList(contextNode, contextName);
List<RunFor> toolRunfor= readToolRunForList(contextNode, contextName);
List<String> toolDepends= readToolDependsList(contextNode, contextName);
if (VerilogPlugin.getPreferenceBoolean(PreferenceStrings.DEBUG_OTHER)) {
System.out.println("contextNode.getNodeValue()="+contextNode.getNodeValue());
......@@ -654,6 +664,8 @@ public class XMLConfig extends Config {
toolInfo,
toolRunfor,
ignoreFilter,
toolDepends,
logDir,
null,
null,
null);
......@@ -979,15 +991,10 @@ public class XMLConfig extends Config {
if(extListNodes.isEmpty())
return null;
// throw new ConfigException(toolInfo +
// " definition doesn't contain '" +
// CONTEXT_OUTPUT_SECTION_TAG +
// "' node");
if(extListNodes.size() > 1)
throw new ConfigException(toolInfo +
" definition cannot contain several '" +
CONTEXT_OUTPUT_SECTION_TAG +
CONTEXT_TOOL_EXTENSIONS_LIST_TAG +
"' nodes");
Node extListNode = extListNodes.get(0);
......@@ -1002,10 +1009,37 @@ public class XMLConfig extends Config {
extList.add(ext);
}
return extList;
}
private List<String> readToolDependsList(Node toolNode, String toolName)
throws ConfigException
{
String toolInfo = "Tool '" + toolName + "'";
List<String> depList = new ArrayList<String>();
List<Node> depListNodes = findChildNodes(toolNode, CONTEXT_TOOL_DEPENDS_LIST_TAG);
if(depListNodes.isEmpty())
return null;
if(depListNodes.size() > 1)
throw new ConfigException(toolInfo +
" definition cannot contain several '" +
CONTEXT_TOOL_DEPENDS_LIST_TAG +
"' nodes");
Node depListNode = depListNodes.get(0);
List<Node> depNodes = findChildNodes(depListNode, CONTEXT_TOOL_DEPENDS_TAG);
// TODO: allow here other types of dependencies (conditionals(source files)
for(Iterator<Node> n = depNodes.iterator(); n.hasNext();) {
Node node = (Node)n.next();
String dep = getAttributeValue(node, CONTEXT_TOOL_DEPENDS_TOOL_TAG);
if(dep == null)
throw new ConfigException(toolInfo + ": Attribute '" + CONTEXT_TOOL_DEPENDS_TOOL_TAG + "' is absent");
depList.add(dep);
}
return depList;
}
private List<RunFor> readToolRunForList(Node toolNode, String toolName) throws ConfigException {
String toolInfo = "Tool '" + toolName + "'";
......
......@@ -18,12 +18,13 @@
package com.elphel.vdt.core.tools.contexts;
import java.util.Iterator;
import java.util.Timer;
import java.util.TimerTask;
import java.util.List;
public class BuildParamsItem implements Cloneable{
private String [] params;
private String consoleName; // null for external tools running in a new console
// private String nameAsParser; // name as a parser, null if not used as a parser
private String name; // name of a block
private boolean is_parser;
......@@ -39,13 +40,18 @@ public class BuildParamsItem implements Cloneable{
// and connect to stderr of the terminal session
private int timeout; // timeout for console tasks, in seconds
private String success;
private String failure;
private boolean keep_open;
private String logFile;
private Timer timer=null;
public BuildParamsItem (
String [] params,
String consoleName,
// String nameAsParser,
String name,
// boolean is_parser,
String toolErrors,
String toolWarnings,
String toolInfo,
......@@ -53,11 +59,14 @@ public class BuildParamsItem implements Cloneable{
String interrupt,
String stderr,
String stdout,
int timeout
int timeout,
String success,
String failure,
boolean keep_open,
String logFile
) {
this.consoleName=consoleName;
this.params=params; // no need to clone?
// this.nameAsParser=nameAsParser;
this.name=name;
this.is_parser=(name!=null); // true
this.toolErrors=toolErrors;
......@@ -68,15 +77,17 @@ public class BuildParamsItem implements Cloneable{
this.stderr=stderr;
this.stdout=stdout;
this.timeout=timeout;
this.success=success;
this.failure=failure;
this.keep_open=keep_open;
this.logFile=logFile;
}
public BuildParamsItem (BuildParamsItem item){
this (
item.params,
item.consoleName,
// item.nameAsParser,
item.name,
// item.is_parser,
item.toolErrors,
item.toolWarnings,
item.toolInfo,
......@@ -84,7 +95,11 @@ public class BuildParamsItem implements Cloneable{
item.interrupt,
item.stderr,
item.stdout,
item.timeout
item.timeout,
item.success,
item.failure,
item.keep_open,
item.logFile
);
this.is_parser=item.is_parser;
}
......@@ -107,17 +122,6 @@ public class BuildParamsItem implements Cloneable{
public String getConsoleName(){
return consoleName;
}
/*
public void applyMark(){
if ((mark==null) || (mark.length()==0)) return;
if (params!=null) {
for (int i=0;i<params.length;i++){
params[i].replace(mark, "");
}
}
if (prompt!=null) prompt.replace(mark, "");
}
*/
public void removeNonParser(List<BuildParamsItem> items){
// if (nameAsParser==null) return;
if (!is_parser) return;
......@@ -125,10 +129,7 @@ public class BuildParamsItem implements Cloneable{
Iterator<BuildParamsItem> itemsIter = items.iterator(); // command lines block is empty (yes, there is nothing in project output)
while(itemsIter.hasNext()) {
BuildParamsItem item = (BuildParamsItem)itemsIter.next();
if(
// nameAsParser.equals(item.stderr) ||
// nameAsParser.equals(item.stdout)){
name.equals(item.stderr) ||
if( name.equals(item.stderr) ||
name.equals(item.stdout)){
return; // do nothing - keep nameAsParser
}
......@@ -137,10 +138,8 @@ public class BuildParamsItem implements Cloneable{
is_parser=false;
}
// public String getNameAsParser(){ return nameAsParser; }
public String getNameAsParser(){ return is_parser?name:null; }
public String getNameAsParser() { return is_parser?name:null; }
public String getName() { return name; }
// public String getMark() { return mark; }
public String getErrors() { return toolErrors; }
public String getWarnings() { return toolWarnings; }
public String getInfo() { return toolInfo; }
......@@ -149,4 +148,29 @@ public class BuildParamsItem implements Cloneable{
public String getStderr() { return stderr; }
public String getStdout() { return stdout; }
public int getTimeout() { return timeout; }
public String getSuccessString(){ return success; }
public String getFailureString(){ return failure; }
public boolean keepOpen() { return keep_open; }
public String getLogName() { return logFile; }
// String logFile
public Timer getTimer(){
if (timer==null){
timer=new Timer();
}
return timer;
}
public void cancelTimer(){
if (timer==null) return;
timer.cancel();
timer=null;
}
public void finalize() throws Throwable{
cancelTimer();
super.finalize();
}
}
......@@ -235,6 +235,12 @@ public abstract class Context {
timeout=Integer.parseInt(sTimeout);
} catch(Exception e){
}
String successString= subsitutePattern(commandLinesBlock.getSuccessString());
String failureString= subsitutePattern(commandLinesBlock.getFailureString());
boolean keepOpen= commandLinesBlock.isKeepOpen();
String logFile= subsitutePattern(commandLinesBlock.getLogPath());
prompt=CommandLinesBlock.parseCntrl(prompt); // replace control character codes (\n,\t,\x)
prompt=commandLinesBlock.applyMark(prompt); // remove mark sequence
String interrupt=commandLinesBlock.getInterrupt();
......@@ -272,7 +278,11 @@ public abstract class Context {
interrupt,
stderr,
stdout,
timeout
timeout,
successString,
failureString,
keepOpen,
logFile
)
);
} else { // processing command file
......@@ -309,10 +319,13 @@ public abstract class Context {
interrupt,
stderr,
stdout,
timeout
timeout,
successString,
failureString,
keepOpen,
logFile
)
);
}
}
......
......@@ -52,6 +52,10 @@ public class CommandLinesBlock extends UpdateableStringsContainer
private String interrupt; // send this to remote terminal to interrupt execution (parses use \xNN)
private String timeout; // timeout for console tasks, in seconds
private String success;
private String failure;
private boolean keep_open;
private String logPath;
public CommandLinesBlock(String contextName,
String name,
......@@ -67,6 +71,10 @@ public class CommandLinesBlock extends UpdateableStringsContainer
String stderr,
String stdout,
String timeout,
String success,
String failure,
boolean keep_open,
String logPath,
ConditionalStringsList lines,
ConditionalStringsList deleteLines,
List<NamedConditionalStringsList> insertLines)
......@@ -87,20 +95,13 @@ public class CommandLinesBlock extends UpdateableStringsContainer
this.stderr=stderr;
this.stdout=stdout;
this.timeout=timeout;
this.success=success;
this.failure=failure;
this.keep_open=keep_open;
this.logPath=logPath;
if(this.separator != null) {
// separator = separator.replace("\\n", "\n");
// separator = separator.replace("\\t", "\t");
this.separator = parseCntrl(this.separator);
}
/*
if (this.prompt!=null){
this.prompt=parseCntrl(this.prompt);
if (this.mark!=null){
this.prompt=this.prompt.replace(this.mark,"");
}
}
*/
if(this.interrupt != null) {
this.interrupt = parseCntrl(this.interrupt);
}
......@@ -140,6 +141,10 @@ public class CommandLinesBlock extends UpdateableStringsContainer
block.stderr,
block.stdout,
block.timeout,
block.success,
block.failure,
block.keep_open,
block.logPath,
block.strings != null?
(ConditionalStringsList)block.strings.clone() : null,
block.deleteStrings != null?
......@@ -213,6 +218,10 @@ public class CommandLinesBlock extends UpdateableStringsContainer
public String getStdout() { return stdout; }
public String getTimeout() { return timeout; }
public String getSuccessString() { return success; }
public String getFailureString() { return failure; }
public boolean isKeepOpen() { return keep_open; }
public String getLogPath() { return logPath; }
public boolean isEnabled() {
if(destination == null) // command line
......
......@@ -21,6 +21,7 @@ import java.util.*;
import java.io.*;
import org.eclipse.core.resources.IProject;
import org.eclipse.swt.widgets.Display;
import com.elphel.vdt.VDT;
import com.elphel.vdt.core.options.OptionsCore;
......@@ -31,6 +32,7 @@ import com.elphel.vdt.core.tools.params.conditions.ConditionUtils;
import com.elphel.vdt.core.tools.params.recognizers.*;
import com.elphel.vdt.core.tools.params.types.RunFor;
import com.elphel.vdt.ui.VDTPluginImages;
import com.elphel.vdt.ui.views.DesignFlowView;
public class Tool extends Context implements Cloneable, Inheritable {
......@@ -63,6 +65,17 @@ public class Tool extends Context implements Cloneable, Inheritable {
private boolean initialized = false;
private String [] imageKeysActions = null;
private List<String> depends=null; // list of tools this one depends on
private String logDir=null; // directory to store this tool log files
private boolean dirty=false; // tool ran before its sources (runtime value)
private long runStamp=0; // timestamp of the tool last ran (0 - never)
private TOOL_STATE state=TOOL_STATE.NEW; // tool state (succ, fail,new, running)
private boolean running=false;
private long finishTimeStamp=0;
private DesignFlowView designFlowView;
public Tool(String name,
String controlInterfaceName,
String label,
......@@ -79,6 +92,8 @@ public class Tool extends Context implements Cloneable, Inheritable {
String toolInfo,
List<RunFor> runfor,
String ignoreFilter,
List<String> depends,
String logDir,
/* never used ??? */
List<Parameter> params,
List<ParamGroup> paramGroups,
......@@ -104,9 +119,70 @@ public class Tool extends Context implements Cloneable, Inheritable {
this.toolErrors = toolErrors;
this.toolWarnings = toolWarnings;
this.toolInfo = toolInfo;
this.depends= depends;
this.logDir= logDir;
this.choice=0;
this.designFlowView =null;
this.finishTimeStamp=0;
}
public enum TOOL_STATE {
NEW,
UNKNOWN,
FAILURE,
SUCCESS //,
// RUNNING
}
public void setRunStamp(long runStamp) { this.runStamp=runStamp; }
public List<String> getDepends() { return depends; }
public boolean isDirty() { return dirty; }
public boolean isRunning() { return running; }
public long getRunStamp() { return runStamp; }
public TOOL_STATE getState() { return state; }
public String getLogDir() { return logDir; }
public void setFinishTimeStamp(){
finishTimeStamp=System.nanoTime();
}
public long getFinishTimeStamp(){
return finishTimeStamp;
}
public void setDirty(boolean dirty) {
this.dirty=dirty;
// updateViewStateIcon();
System.out.println("SetDirty("+dirty+")");
}
public void setRunning(boolean running) {
this.running=running;
// updateViewStateIcon();
System.out.println("SetRunning("+running+")");
}
public void setState(TOOL_STATE state) {
this.state=state;
// updateViewStateIcon();
System.out.println("SetState("+state+")");
}
public void setDesignFlowView (DesignFlowView designFlowView){
this.designFlowView = designFlowView; // to be able to update actions and so the state icons
}
public void updateViewStateIcon(){
if (designFlowView!=null){
Display.getDefault().syncExec(new Runnable() {
public void run() {
designFlowView.updateLaunchAction(); // Run from Display thread to prevent "invalid thread access" when called from Runner
}
});
}
}
public void initIcons(boolean force) {
if (!force && (imageKeysActions!=null)) return;
if (runfor!=null){
......@@ -124,6 +200,7 @@ public class Tool extends Context implements Cloneable, Inheritable {
} // ToolUI()
public String getImageKey(int actionIndex) {
if (imageKeysActions==null) return null;
return imageKeysActions[actionIndex];
......
......@@ -19,21 +19,27 @@ package com.elphel.vdt.ui;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.eclipse.core.runtime.FileLocator;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.resource.ImageRegistry;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.ImageData;
import org.eclipse.swt.graphics.ImageLoader;
// TODO: remove this import?
import org.eclipse.debug.internal.ui.DebugPluginImages;
import com.elphel.vdt.VDT;
//import com.elphel.vdt.VDTPlugin;
import com.elphel.vdt.veditor.VerilogPlugin;
import com.elphel.vdt.core.tools.contexts.Context;
import com.elphel.vdt.core.tools.contexts.PackageContext;
import com.elphel.vdt.core.tools.contexts.ProjectContext;
......@@ -58,7 +64,10 @@ public class VDTPluginImages {
public static final ImageDescriptor DESC_VERILOG_FILE = create(ICONS_PATH, "eview16"+File.separator+"verilog_file.gif", null);
public static final ImageDescriptor DESC_RUN_TOOL = create(ICONS_PATH, "obj16"+File.separator+"run_tool.gif", null);
// public static final ImageDescriptor DESC_RUN_TOOL = create(ICONS_PATH, "obj16"+File.separator+"run_tool.gif", null);
public static final ImageDescriptor DESC_RUN_TOOL = create(ICONS_PATH, "obj16"+File.separator+"run_tool.png", null);
public static final ImageDescriptor DESC_PLAY_BACK = create(ICONS_PATH, "obj16"+File.separator+"play_back.png", null);
public static final ImageDescriptor DESC_PLAY_BACK_SELECT = create(ICONS_PATH, "obj16"+File.separator+"play_back_select.png", null);
public static final ImageDescriptor DESC_TOOL_PROPERTIES = create(ICONS_PATH, "obj16"+File.separator+"tool_prop.gif", null);
public static final ImageDescriptor DESC_LAUNCH_CONFIG = create(ICONS_PATH, "obj16"+File.separator+"vdt_tools.gif", null);
public static final ImageDescriptor DESC_INSTALL_PROPERTIES = create(ICONS_PATH, "obj16"+File.separator+"install_prop.gif", null);
......@@ -67,6 +76,25 @@ public class VDTPluginImages {
public static final ImageDescriptor DESC_DESIGM_MENU = create(ICONS_PATH, "obj16"+File.separator+"design_menu.gif", null);
public static final String ICON_TOOLSTATE_NEW = "obj16"+File.separator+"white.png";
public static final String ICON_TOOLSTATE_BAD = "obj16"+File.separator+"cross.png";
public static final String ICON_TOOLSTATE_BAD_OLD = "obj16"+File.separator+"cross_dim.png";
public static final String ICON_TOOLSTATE_GOOD = "obj16"+File.separator+"check.png";
public static final String ICON_TOOLSTATE_GOOD_OLD = "obj16"+File.separator+"check_dim.png";
public static final String ICON_TOOLSTATE_WTF = "obj16"+File.separator+"question.png";
public static final String ICON_TOOLSTATE_WTF_OLD = "obj16"+File.separator+"question_dim.png";
public static final String ICON_TOOLSTATE_RUNNING = "obj16"+File.separator+"spinning.gif";
public static final String KEY_TOOLSTATE_NEW = "TOOLSTATE_NEW";
public static final String KEY_TOOLSTATE_BAD = "TOOLSTATE_BAD";
public static final String KEY_TOOLSTATE_BAD_OLD = "TOOLSTATE_BAD_OLD";
public static final String KEY_TOOLSTATE_GOOD = "TOOLSTATE_GOOD";
public static final String KEY_TOOLSTATE_GOOD_OLD = "TOOLSTATE_GOOD_OLD";
public static final String KEY_TOOLSTATE_WTF = "TOOLSTATE_WTF";
public static final String KEY_TOOLSTATE_WTF_OLD = "TOOLSTATE_WTF_OLD";
public static final String KEY_TOOLSTATE_RUNNING = "TOOLSTATE_RUNNING";
public static final String CHECKBOX_ON = "CHECKBOX_ON";
public static final String CHECKBOX_OFF = "CHECKBOX_OFF";
public static final String CHECKBOX_ON_DISABLE = "CHECKBOX_ON_DISABLE";
......@@ -85,6 +113,9 @@ public class VDTPluginImages {
public static final ImageDescriptor DESC_CHECKBOX_ON_DEFAULT_DISABLE = create(ICONS_PATH, "obj16"+File.separator+"cb_on_disable_default.gif", CHECKBOX_ON_DEFAULT_DISABLE);
public static final ImageDescriptor DESC_CHECKBOX_OFF_DEFAULT_DISABLE = create(ICONS_PATH, "obj16"+File.separator+"cb_off_disable_default.gif", CHECKBOX_OFF_DEFAULT_DISABLE);
private static Map<ImageDescriptor,ImageData[]> animatedGifMap = new HashMap<ImageDescriptor,ImageData[]>();
private static ImageDescriptor create (String prefix, String name, String key) {
ImageDescriptor desc = ImageDescriptor.createFromURL(makeImageURL(prefix, name));
if (key != null)
......@@ -95,10 +126,12 @@ public class VDTPluginImages {
public static void addImage(String fileName, String key, String launchType) {
ImageDescriptor desc = null;
File file = new File(fileName);
URL url=null;
if (file.isAbsolute()) {
desc = ImageDescriptor.createFromFile(null, fileName);
} else {
desc = ImageDescriptor.createFromURL(makeImageURL(ICONS_PATH, fileName));
url=makeImageURL(ICONS_PATH, fileName);
desc = ImageDescriptor.createFromURL(url);
}
if (key != null)
......@@ -106,14 +139,36 @@ public class VDTPluginImages {
if ((launchType != null) && !VDT.ID_DEFAULT_LAUNCH_TYPE.equals(launchType))
DebugPluginImages.getImageRegistry().put(launchType, desc);
// ImageData [] imageData = new ImageLoader().load(new FileInputStream(fileName));
ImageData [] imageData = null;
if (url!=null){
try {
imageData = new ImageLoader().load(url.openStream());
} catch (IOException e) {
System.out.println("Failed to open url "+url.toString());
return;
}
} else {
try {
imageData = new ImageLoader().load(file.getAbsolutePath());
} catch (Exception e) {
System.out.println("Failed to open absolute path "+file.getAbsolutePath());
return;
}
}
if (imageData.length>1){
animatedGifMap.put(desc,imageData);
// System.out.println("animatedGifMap.size()="+animatedGifMap.size());
// System.out.println("imageData.length="+imageData.length);
}
} // addImage()
private static URL makeImageURL(String prefix, String name) {
String path = "$nl$/" + prefix + name; //$NON-NLS-1$
/* TODO: fix deprecation */
URL url_try= org.eclipse.core.runtime.FileLocator.find(VerilogPlugin.getDefault().getBundle(), new Path(path), null);
return Platform.find(VerilogPlugin.getDefault().getBundle(), new Path(path));
// URL url_try= org.eclipse.core.runtime.FileLocator.find(VerilogPlugin.getDefault().getBundle(), new Path(path), null);
// return Platform.find(VerilogPlugin.getDefault().getBundle(), new Path(path));
return FileLocator.find(VerilogPlugin.getDefault().getBundle(), new Path(path), null);
}
/**
......@@ -132,6 +187,14 @@ public class VDTPluginImages {
return getImageRegistry().getDescriptor(key);
}
public static ImageData [] getImageData(String key) {
ImageDescriptor imageDescriptor=getImageRegistry().getDescriptor(key);
return animatedGifMap.get(imageDescriptor);
}
/**
* Returns the VDTPlugin ImageRegistry.
*/
......
......@@ -58,7 +58,8 @@ public class LaunchShortcut implements ILaunchShortcut {
public static void launch(Tool tool) {
IProject project = getActiveProject();
try {
LaunchCore.launch(tool, project, project.getName());
MessageUI.error("This type of tool launching is not supported");
LaunchCore.launch(tool, project, project.getName(),null);
} catch (CoreException e) {
MessageUI.error(Txt.s("Action.ToolLaunch.Error",
new String[] {tool.getName(), e.getMessage()}),
......
/*******************************************************************************
* Copyright (c) 2014 Elphel, Inc.
* This file is a part of Eclipse/VDT plug-in.
* Eclipse/VDT plug-in is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Eclipse/VDT plug-in is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*******************************************************************************/
package com.elphel.vdt.ui.options;
import java.awt.Component;
import java.io.File;
import java.util.regex.Pattern;
import javax.swing.JFileChooser;
import javax.swing.filechooser.FileFilter;
public class FilteredFileSelector{
private String approveText;
private JFileChooser fileChooser;
private Component parent;
public FilteredFileSelector(
File dir,
String title,
Component parent,
String approveText,
String approveToolTip,
String filterRegex,
String filterDescription,
boolean allowDirs
){
this.parent=parent;
fileChooser = new JFileChooser(dir);
FileFilter filter1 = new RegexFileFilter(filterRegex, filterDescription,allowDirs);
fileChooser.setFileFilter(filter1);
if (title!=null) fileChooser.setDialogTitle(title);
this.approveText=approveText;
if (this.approveText==null) this.approveText="Select";
if (approveToolTip!=null) fileChooser.setApproveButtonToolTipText(approveToolTip);
fileChooser.setApproveButtonText(this.approveText);
}
public File openDialog() {
if (fileChooser.showDialog(parent, approveText) == JFileChooser.APPROVE_OPTION) {
return fileChooser.getSelectedFile();
} else {
return null;
}
}
private class RegexFileFilter extends FileFilter {
private String regex;
private String description;
private boolean allowDirs;
private Pattern pattern;
public RegexFileFilter(
String filter,
String description,
boolean allowDirs){
this.regex=filter;
this.description=description;
this.allowDirs=allowDirs;
pattern=Pattern.compile(this.regex);
// System.out.println("RegexFileFilter regex=\""+this.regex+"\"");
}
@Override
public boolean accept(File file) {
if (file.isDirectory()) {
return allowDirs;
} else {
String name = file.getName();
// System.out.println("filename="+name+", matches()="+pattern.matcher(name).matches());
return pattern.matcher(name).matches();
}
}
@Override
public String getDescription() {
return description;
}
}
}
......@@ -20,11 +20,16 @@ package com.elphel.vdt.ui.views;
import java.util.List;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeItem;
import org.eclipse.ui.part.*;
import org.eclipse.jface.viewers.*;
import org.eclipse.jface.window.Window;
import org.eclipse.swt.graphics.Image;
//import org.eclipse.swt.graphics.ImageData;
import org.eclipse.jface.action.*;
import org.eclipse.ui.*;
import org.eclipse.swt.widgets.Menu;
......@@ -36,9 +41,9 @@ 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 com.elphel.vdt.core.Utils;
import java.io.File;
import com.elphel.vdt.core.launching.LaunchCore;
import com.elphel.vdt.core.launching.ToolLogFile;
import com.elphel.vdt.core.options.OptionsCore;
import com.elphel.vdt.core.options.ValueBasedOption;
import com.elphel.vdt.core.tools.ToolsCore;
......@@ -48,7 +53,6 @@ import com.elphel.vdt.core.tools.params.Tool;
import com.elphel.vdt.core.tools.params.types.RunFor;
import com.elphel.vdt.Txt;
import com.elphel.vdt.VDT;
//import com.elphel.vdt.VDTPlugin;
import com.elphel.vdt.veditor.VerilogPlugin;
import com.elphel.vdt.veditor.preference.PreferenceStrings;
import com.elphel.vdt.ui.MessageUI;
......@@ -57,9 +61,9 @@ import com.elphel.vdt.ui.variables.SelectedResourceManager;
import com.elphel.vdt.ui.views.DesignMenuModel;
import com.elphel.vdt.ui.dialogs.DesignMenuSelectionDialog;
import com.elphel.vdt.ui.options.ContextOptionsDialog;
import com.elphel.vdt.ui.options.FilteredFileSelector;
import com.elphel.vdt.ui.options.SetupOptionsDialog;
import com.elphel.vdt.ui.options.SetupOptionsManager;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.ui.DebugUITools;
......@@ -119,6 +123,10 @@ public class DesignFlowView extends ViewPart implements ISelectionListener {
private IMemento memento;
private Action playbackLogLatestAction;
private Action playbackLogSelectAction;
IDoubleClickListener doubleClickListener=null;
private Action [] launchActions;
......@@ -165,7 +173,20 @@ public class DesignFlowView extends ViewPart implements ISelectionListener {
// viewer.setInput(getViewSite());
// viewer.setInput(ToolsCore.getDesignMenu());
viewer.addSelectionChangedListener(new ToolSelectionChangedListener());
// Draw tool state (running, success, failure, ...) icon after the label in the tree
final Tree tree= viewer.getTree();
tree.addListener(SWT.MeasureItem, new Listener() {
public void handleEvent(Event event) {
((DesignMenuModel.Item) ((TreeItem)event.item).getData()).measureItem (event);
}
});
tree.addListener(SWT.PaintItem, new Listener() {
public void handleEvent(Event event) {
TreeItem item = (TreeItem)event.item;
((DesignMenuModel.Item) item.getData()).showStateIcon(event,tree,item);
}
});
makeActions();
hookContextMenu();
/**+ hookDoubleClickAction(); */
......@@ -247,6 +268,11 @@ public class DesignFlowView extends ViewPart implements ISelectionListener {
// manager.add(new Separator());
// drillDownAdapter.addNavigationActions(manager);
// Other plug-ins can contribute their actions here
if ((playbackLogLatestAction!=null) || (playbackLogSelectAction!=null) ) {
manager.add(new Separator());
if (playbackLogLatestAction!=null) manager.add(playbackLogLatestAction);
if (playbackLogSelectAction!=null) manager.add(playbackLogSelectAction);
}
manager.add(new Separator());
manager.add(showInstallationPropertiesAction);
manager.add(showPackagePropertiesAction);
......@@ -392,7 +418,9 @@ public class DesignFlowView extends ViewPart implements ISelectionListener {
showLaunchConfigAction = new Action() {
public void run() {
try {
int result = openToolLaunchDialog(selectedItem);
int result = openToolLaunchDialog(
selectedItem,
fDesignFlowView);
if (VerilogPlugin.getPreferenceBoolean(PreferenceStrings.DEBUG_OTHER)) {
System.out.println("Ran openToolLaunchDialog() ->"+result);
}
......@@ -410,26 +438,6 @@ public class DesignFlowView extends ViewPart implements ISelectionListener {
launchActions=null;
doubleClickListener=null;
/**+
launchAction = new Action() {
public void run() {
try {
launchTool(selectedItem,0);
} catch (Exception e) {
MessageUI.error( Txt.s("Action.ToolLaunch.Error",
new String[] {selectedItem.getLabel(), e.getMessage()})
, e);
}
}
};
launchAction.setText(Txt.s("Action.ToolLaunch.Caption.Default"));
launchAction.setToolTipText(Txt.s("Action.ToolLaunch.ToolTip.Default")+" **DEBUGGING**");
launchAction.setImageDescriptor(VDTPluginImages.DESC_RUN_TOOL);
launchAction.setEnabled(false);
*/
// launchAction.setImageDescriptor(PlatformUI.getWorkbench().getSharedImages().
// getImageDescriptor(ISharedImages.IMG_OBJS_INFO_TSK));
} // makeActions()
private void removeDoubleClickAction() {
......@@ -447,16 +455,6 @@ public class DesignFlowView extends ViewPart implements ISelectionListener {
};
viewer.addDoubleClickListener(doubleClickListener);
}
/**+
private void hookDoubleClickAction() {
viewer.addDoubleClickListener(new IDoubleClickListener() {
public void doubleClick(DoubleClickEvent event) {
launchAction.run(); // Andrey: will go to launchAction[0].run
}
});
}
*/
// private void showMessage(String message) {
// MessageDialog.openInformation( viewer.getControl().getShell()
......@@ -544,6 +542,8 @@ public class DesignFlowView extends ViewPart implements ISelectionListener {
// removeLaunchActions();
removeDoubleClickAction();
launchActions=null;
playbackLogLatestAction=null;
playbackLogSelectAction=null;
if ((runFor!=null) && (project!=null)){
launchActions=new Action [runFor.length];
for (int i=0;i<runFor.length;i++){
......@@ -589,11 +589,17 @@ public class DesignFlowView extends ViewPart implements ISelectionListener {
final int finalI=i;
final String fFullPath=fullPath;
final String fIgnoreFilter=ignoreFilter;
final DesignFlowView fDesignFlowView=this;
launchActions[i] = new Action() {
public void run() {
try {
launchTool(selectedItem,finalI,fFullPath,fIgnoreFilter);
launchTool(
fDesignFlowView, // to be able to launch update when build state of the tool changes
// selectedItem, // is it needed?
finalI,
fFullPath,
fIgnoreFilter);
} catch (Exception e) {
MessageUI.error( Txt.s("Action.ToolLaunch.Error",
new String[] {selectedItem.getLabel(), e.getMessage()})
......@@ -617,30 +623,56 @@ public class DesignFlowView extends ViewPart implements ISelectionListener {
launchActions[i].setImageDescriptor(VDTPluginImages.getImageDescriptor(actionIconKey));
else
launchActions[i].setImageDescriptor(VDTPluginImages.DESC_RUN_TOOL);
if (i==0) { // set log play-back (always for default tool only)
boolean logEnabled=(tool.getLogDir()!=null);
// see if tool has log-dir
playbackLogLatestAction=new Action() {
public void run() {
try {
playLogs(
fDesignFlowView, // to be able to launch update when build state of the tool changes
false,
fFullPath,
fIgnoreFilter);
} catch (Exception e) {
MessageUI.error( Txt.s("Action.ToolLaunch.Error",
new String[] {selectedItem.getLabel(), e.getMessage()})
, e);
}
}
};
playbackLogSelectAction=new Action() {
public void run() {
try {
playLogs(
fDesignFlowView, // to be able to launch update when build state of the tool changes
true,
fFullPath,
fIgnoreFilter);
} catch (Exception e) {
MessageUI.error( Txt.s("Action.ToolLaunch.Error",
new String[] {selectedItem.getLabel(), e.getMessage()})
, e);
}
}
};
playbackLogLatestAction.setText("Playback latest log for "+tool.getName());
playbackLogSelectAction.setText("Select/playback log for "+tool.getName());
playbackLogLatestAction.setToolTipText("Playback latest log for "+runFor[i].getLabel()+" "+shortName);
playbackLogSelectAction.setToolTipText("Select and playback log for "+runFor[i].getLabel()+" "+shortName);
playbackLogLatestAction.setEnabled(logEnabled);
playbackLogSelectAction.setEnabled(logEnabled);
playbackLogLatestAction.setImageDescriptor(VDTPluginImages.DESC_PLAY_BACK);
playbackLogSelectAction.setImageDescriptor(VDTPluginImages.DESC_PLAY_BACK_SELECT);
}
}
IToolBarManager toolbarManager= getViewSite().getActionBars().getToolBarManager();
toolbarManager.removeAll();
fillLocalToolBar(toolbarManager);
hookDoubleClickAction();
}
/**+
launchAction.setEnabled(enabled);
if (enabled){
// Andrey: Next appears on right-click (context) menu for selected tool
launchAction.setText(Txt.s("Action.ToolLaunch.Caption", new String[]{selectedResource.getName()})+"<<<<<");
// Andrey: below sets tooltip on the horizontal bar
launchAction.setToolTipText(Txt.s("Action.ToolLaunch.ToolTip", new String[]{selectedItem.getLabel(), selectedResource.getName()}));
Tool tool = selectedItem.getTool();
if (tool!=null){
System.out.println("Tool:"+tool.getName()); // Not yet parsed
}
} else {
launchAction.setText(Txt.s("Action.ToolLaunch.Caption.Default"));
launchAction.setToolTipText(Txt.s("Action.ToolLaunch.ToolTip.Default"));
}
*/
enabled = (selectedItem != null)
&& (selectedResource != null)
&& (selectedItem.getPackageContext() != null);
......@@ -675,16 +707,26 @@ public class DesignFlowView extends ViewPart implements ISelectionListener {
clearToolPropertiesAction.setEnabled(enabled);
} // updateLaunchAction()
private void launchTool(DesignMenuModel.Item item, int choice, String fullPath, String ignoreFilter) throws CoreException {
private void launchTool(
final DesignFlowView designFlowView,
// DesignMenuModel.Item item,
int choice,
String fullPath,
String ignoreFilter) throws CoreException {
Tool tool = selectedItem.getTool();
if (tool != null) {
tool.setDesignFlowView(designFlowView);
tool.setRunning(true);
tool.updateViewStateIcon();
tool.setChoice(0);
SelectedResourceManager.getDefault().updateActionChoice(fullPath, choice, ignoreFilter); // Andrey
SelectedResourceManager.getDefault().setBuildStamp(); // Andrey
LaunchCore.launch( tool
, selectedResource.getProject()
// apply designFlowView to the tool itself
LaunchCore.launch( tool,
selectedResource.getProject(),
// , selectedResource.getFullPath().toString() );
, fullPath);
fullPath,
null); // run, not playback
} else if (selectedItem.hasChildren()) {
if (viewer.getExpandedState(selectedItem))
......@@ -694,6 +736,67 @@ public class DesignFlowView extends ViewPart implements ISelectionListener {
}
} // launchTool()
private void playLogs(
final DesignFlowView designFlowView,
boolean select, // select log file
String fullPath,
String ignoreFilter) throws CoreException {
Tool tool = selectedItem.getTool();
if (tool != null) {
String logBuildStamp=select?selectBuildStamp(tool):""; // "" - latest (link)
if (logBuildStamp==null) return; // cancelled selection
if (VerilogPlugin.getPreferenceBoolean(PreferenceStrings.DEBUG_OTHER)) {
System.out.println("logBuildStamp="+logBuildStamp);
}
tool.setDesignFlowView(designFlowView);
tool.setRunning(true);
tool.updateViewStateIcon();
tool.setChoice(0);
SelectedResourceManager.getDefault().updateActionChoice(fullPath, 0, ignoreFilter); // Andrey
SelectedResourceManager.getDefault().setBuildStamp(); // OK - even for log? Or use old/selected one?
// apply designFlowView to the tool itself
LaunchCore.launch(tool,
selectedResource.getProject(),
fullPath,
logBuildStamp);
// probably should not get here if not a tool
} else if (selectedItem.hasChildren()) {
if (viewer.getExpandedState(selectedItem))
viewer.collapseToLevel(selectedItem, AbstractTreeViewer.ALL_LEVELS);
else
viewer.expandToLevel(selectedItem, 1);
}
} // launchTool()
private String selectBuildStamp(Tool tool){
// System.out.println("tool.getLogDir()="+tool.getLogDir());
// System.out.println("ToolLogFile.getDir(tool.getLogDir()).getLocation()="+ToolLogFile.getDir(tool.getLogDir()).getLocation());
FilteredFileSelector selector= new FilteredFileSelector(
ToolLogFile.getDir(tool.getLogDir()).getLocation().toFile() , //File dir,
"Select log file", //String title,
null, // Component parent, or convert from SHell VerilogPlugin.getActiveWorkbenchShell()
"Select", //String approveText,
"Select timestamp by selecting available log file", //String approveToolTip,
ToolLogFile.getBaseRegex(tool.getName()), // String filterRegex,
"Matchig log files for "+tool.getName(), //String filterDescription,
false //boolean allowDirs
);
File result=selector.openDialog();
if (result == null) {
if (VerilogPlugin.getPreferenceBoolean(PreferenceStrings.DEBUG_OTHER))
System.out.println("Selection canceled");
return null;
}
// System.out.println("Got file "+result.toString());
// System.out.println("Timestamp="+ToolLogFile.getTimeStamp(
// tool.getName(),
// result.getName()));
return ToolLogFile.getTimeStamp(
tool.getName(),
result.getName());
}
private int openInstallationPropertiesDialog() {
Shell shell = VerilogPlugin.getActiveWorkbenchShell();
SetupOptionsDialog dialog = new SetupOptionsDialog(shell);
......@@ -723,7 +826,7 @@ public class DesignFlowView extends ViewPart implements ISelectionListener {
dialog.create();
int result=dialog.open();
if (result == Window.OK) {
System.out.println("openDesignMenuSelectionDialog()-> OK");
// System.out.println("openDesignMenuSelectionDialog()-> OK");
DesignMenu newDesignMenu = dialog.getSelectedDesignMenu();
String newDesignMenuName = newDesignMenu == null ? null
: newDesignMenu.getName();
......@@ -752,13 +855,18 @@ public class DesignFlowView extends ViewPart implements ISelectionListener {
}
private int openToolLaunchDialog(DesignMenuModel.Item item) throws CoreException {
private int openToolLaunchDialog(
DesignMenuModel.Item item,
DesignFlowView designFlowView
) throws CoreException {
System.out.println("openToolLaunchDialog()");
Shell shell = VerilogPlugin.getActiveWorkbenchShell();
ILaunchConfiguration launchConfig = LaunchCore.createLaunchConfiguration( item.getTool()
, selectedResource.getProject()
, null );
ILaunchConfiguration launchConfig = LaunchCore.createLaunchConfiguration(
item.getTool(),
selectedResource.getProject(),
null,
null);
IStructuredSelection selection = new StructuredSelection(launchConfig);
return DebugUITools.openLaunchConfigurationDialogOnGroup( shell
, selection
......
......@@ -17,12 +17,27 @@
*******************************************************************************/
package com.elphel.vdt.ui.views;
//import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Rectangle;
import java.io.File;
import java.util.List;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.atomic.AtomicBoolean;
import org.eclipse.core.resources.IResource;
//import org.eclipse.jface.viewers.TreeViewer;
//import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.ImageData;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
//import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeItem;
import com.elphel.vdt.VDT;
import com.elphel.vdt.core.tools.ToolsCore;
......@@ -47,7 +62,7 @@ public class DesignMenuModel {
private Config config;
private MenuItem root;
private final int IMAGE_MARGIN=2;
public DesignMenuModel(DesignMenu menu) {
config = ToolsCore.getConfig();
root = new MenuItem(null, menu);
......@@ -62,12 +77,21 @@ public class DesignMenuModel {
private static final String ICON_ID_PREFIX = VDT.ID_VDT + ".DesignMenu.Image.";
private String imageKey = null;
protected String imageKeyState = null;
private DesignMenuItem source;
private Item parent;
private int animN;
private Rectangle animBounds=null;
private ImageData[] imageData=null;
// private boolean animEn=true; // just testing, fill be false;
final private AtomicBoolean animBusy=new AtomicBoolean(false);
private Timer timer=null;
// private int updateWidth=16;
private Item(Item parent, DesignMenuItem source) {
this.parent = parent;
this.source = source;
this.timer=null;
String image = source.getIcon();
if (image != null) {
......@@ -104,10 +128,92 @@ public class DesignMenuModel {
public String getLabel() {
return toString();
}
public String getImageKey() {
return imageKey;
}
public void measureItem (Event event){
if (imageKeyState==null) return;
Image image=VDTPluginImages.getImage(imageKeyState);
if (image!=null) event.width+=IMAGE_MARGIN+image.getBounds().width;
}
public void showStateIcon(Event event, final Tree tree, final TreeItem item){
if ((imageKeyState==null) || (item.isDisposed())) return;
int x = event.x + event.width + IMAGE_MARGIN;
int itemHeight = tree.getItemHeight();
imageData=VDTPluginImages.getImageData(imageKeyState);
Image frameImage;
boolean isAnimation=false;
if ((imageData!=null) && (imageData.length>1) && animBusy.compareAndSet(false,true)){
isAnimation=true;
animN=animN % imageData.length;
frameImage = new Image(Display.getDefault(),imageData[animN]);
} else {
frameImage = VDTPluginImages.getImage(imageKeyState); // do not dispose() !
}
int imageHeight = frameImage.getBounds().height;
int y = event.y + (itemHeight - imageHeight) / 2;
event.gc.drawImage(frameImage, x, y);
if (isAnimation){
animBounds=frameImage.getBounds();
frameImage.dispose();
final int fDelayTime=imageData[animN].delayTime*10; // ms
animN++;
// item does not include our animation on the right of it, so we need to store image location
// relative to the top right corner of the item (height does not change)
Rectangle r=item.getBounds();
animBounds.x=x-(r.x+r.width);
animBounds.y=y-(r.y);
TimerTask timerTask=new TimerTask() {
@Override
public void run() {
refresh(item, tree); // threw on shutdown -
}
};
if (timer==null) timer=new Timer();
try {
timer.schedule(timerTask, fDelayTime);
} catch (IllegalStateException e){
System.out.println("DesignMenuModel(): Timer was somewhere canceled, recovering");
timer.cancel();
timer=new Timer();
timer.schedule(timerTask, fDelayTime);
}
/*
timer.schedule(new TimerTask() {
@Override
public void run() {
refresh(item, tree); // threw on shutdown -
}
}, fDelayTime);
*/
}
}
public void refresh(final TreeItem item, final Tree tree) {
Display.getDefault().syncExec(new Runnable() {
public void run() {
if (item.isDisposed()) {
animBusy.compareAndSet(true, false);
return;
}
Rectangle r=item.getBounds();
// System.out.println("animBounds="+animBounds.toString()+" item.getBounds()="+item.getBounds().toString());
tree.redraw(
animBounds.x+r.x+r.width,
animBounds.y+r.y,
animBounds.width,
animBounds.height,true);
animBusy.compareAndSet(true, false);
}
});
}
public Tool getTool() {
return null;
}
......@@ -192,6 +298,59 @@ public class DesignMenuModel {
else
return null;
}
public void measureItem (Event event){
super.measureItem (event);
boolean dirty=tool.isDirty();
String iconName,key;
if (tool.isRunning()){
iconName=VDTPluginImages.ICON_TOOLSTATE_RUNNING;
key= VDTPluginImages.KEY_TOOLSTATE_RUNNING;
} else {
switch (tool.getState()){
case NEW:
iconName=VDTPluginImages.ICON_TOOLSTATE_NEW;
key= VDTPluginImages.KEY_TOOLSTATE_NEW;
break;
case FAILURE:
if (dirty){
iconName=VDTPluginImages.ICON_TOOLSTATE_BAD_OLD;
key= VDTPluginImages.KEY_TOOLSTATE_BAD_OLD;
} else {
iconName=VDTPluginImages.ICON_TOOLSTATE_BAD;
key= VDTPluginImages.KEY_TOOLSTATE_BAD;
}
break;
case SUCCESS:
if (dirty){
iconName=VDTPluginImages.ICON_TOOLSTATE_GOOD_OLD;
key= VDTPluginImages.KEY_TOOLSTATE_GOOD_OLD;
} else {
iconName=VDTPluginImages.ICON_TOOLSTATE_GOOD;
key= VDTPluginImages.KEY_TOOLSTATE_GOOD;
}
break;
default:
if (dirty){
iconName=VDTPluginImages.ICON_TOOLSTATE_WTF_OLD;
key= VDTPluginImages.KEY_TOOLSTATE_WTF_OLD;
} else {
iconName=VDTPluginImages.ICON_TOOLSTATE_WTF;
key= VDTPluginImages.KEY_TOOLSTATE_WTF;
}
}
}
key = Item.ICON_ID_PREFIX + key;
if (VDTPluginImages.getImage(key) == null){
VDTPluginImages.addImage(iconName, key, null);
}
super.imageKeyState=key;
// System.out.println("iconName="+iconName+", key="+key+" imageKeyState="+super.imageKeyState);
/*
*/
//TODO: Save tool state in memento
}
} // class ToolItem
// ------------------------------------------------------------------------
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment