Commit 9871fcb2 authored by Andrey Filippov's avatar Andrey Filippov

more on remote console applications

parent 743b1642
/*******************************************************************************
* 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.File;
import java.io.IOException;
import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.eclipse.debug.internal.ui.views.console.ProcessConsole;
//import org.eclipse.core.resources.IProject;
//import org.eclipse.core.resources.ResourcesPlugin;
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.ILaunchConfiguration;
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.IStreamsProxy;
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.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.IOConsoleInputStream;
import org.eclipse.ui.console.IOConsoleOutputStream;
import com.elphel.vdt.Txt;
import com.elphel.vdt.core.tools.contexts.BuildParamsItem;
import com.elphel.vdt.ui.MessageUI;
//import com.elphel.vdt.VDTPlugin;
import com.elphel.vdt.veditor.VerilogPlugin;
import com.elphel.vdt.veditor.parser.OutlineContainer;
import com.elphel.vdt.veditor.preference.PreferenceStrings;
//import com.elphel.vdt.core.Utils;
import org.eclipse.ui.console.IConsoleListener;
public class RunningBuilds {
// int nextBuildStep=0;
private final Map<String, VDTRunnerConfiguration> unfinishedBuilds;
public RunningBuilds(){
unfinishedBuilds = new ConcurrentHashMap<String, VDTRunnerConfiguration>();
IConsoleManager manager = ConsolePlugin.getDefault().getConsoleManager();
// This is not used, just for testing
System.out.println("***Addded console listeners");
manager.addConsoleListener(new IConsoleListener(){
public void consolesAdded(IConsole[] consoles){
for (int i=0;i<consoles.length;i++){
System.out.println("+++ Added: "+consoles[i].getName());
// Only shows added consoles
}
}
public void consolesRemoved(IConsole[] consoles){
for (int i=0;i<consoles.length;i++){
System.out.println("--- Removed: "+consoles[i].getName());
// unfinishedBuilds.remove(consoles[i]);
removeConsole(consoles[i]);
}
}
});
}
public String findConsoleParent(IConsole console){
Iterator<String> iter=unfinishedBuilds.keySet().iterator();
System.out.println("findConsoleParent("+console.getName()+")");
while (iter.hasNext()) {
String consoleName=iter.next();
System.out.print("Got console name:"+consoleName);
VDTRunnerConfiguration runConfig=unfinishedBuilds.get(consoleName);
if (runConfig.hasConsole(console)){
System.out.println(consoleName+" -> GOT IT");
return consoleName;
}
System.out.println(consoleName+" -> no luck");
}
return null;
}
public void removeConsole(IConsole console){
String consoleName=findConsoleParent(console);
if (consoleName!=null){
VDTRunnerConfiguration runConfig=unfinishedBuilds.get(consoleName);
runConfig.removeConsole(console);
System.out.println("Removing console "+console.getName()+" from runConfig for "+consoleName);
if (runConfig.noConsoles()){
System.out.println("No consoles left in unfinished "+consoleName+" - removing it too");
unfinishedBuilds.remove(consoleName);
}
} else {
System.out.println("Console "+console.getName()+" did not belong here");
}
}
public boolean isUnfinished(IConsole console){
return unfinishedBuilds.containsKey(console);
}
public VDTRunnerConfiguration resumeConfiguration(String consoleName){
VDTRunnerConfiguration conf=unfinishedBuilds.get(consoleName);
unfinishedBuilds.remove(consoleName);
return conf;
}
public VDTRunnerConfiguration getConfiguration(String consoleName){
VDTRunnerConfiguration conf=unfinishedBuilds.get(consoleName);
return conf;
}
public void removeConfiguration(String consoleName){
unfinishedBuilds.remove(consoleName);
}
public void saveUnfinished(String consoleName, VDTRunnerConfiguration configuration ){
unfinishedBuilds.put(consoleName, configuration);
}
} // class RunningBuilds
/*******************************************************************************
* 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.IOException;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.debug.internal.ui.views.console.ProcessConsole;
import org.eclipse.core.runtime.CoreException;
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.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.contexts.BuildParamsItem;
import com.elphel.vdt.ui.MessageUI;
import com.elphel.vdt.veditor.VerilogPlugin;
import com.elphel.vdt.veditor.preference.PreferenceStrings;
public class VDTConsoleRunner{
private final VDTRunnerConfiguration runConfig;
private IProcess processErr=null;
private IProcess processOut=null;
private IStreamsProxy stdoutStreamProxy=null;
private IStreamsProxy stderrStreamProxy=null;
private IStreamsProxy sendErrorsToStreamProxy=null;
private Object errorListener=null; //+
private Object outputListener=null; //+
private IOConsole iCons=null;
private IProcess process=null;
private IStreamsProxy consoleInStreamProxy= null;
public VDTConsoleRunner (VDTRunnerConfiguration runConfig){
this.runConfig=runConfig;
}
private BuildParamsItem getParser( String parserName){
if (parserName==null) return null;
BuildParamsItem[] buildParamsItems = runConfig.getArgumentsItemsArray(); // uses already calculated
if (buildParamsItems==null) return null;
for (int i=0;i<buildParamsItems.length;i++){
if (parserName.equals(buildParamsItems[i].getNameAsParser()))
return buildParamsItems[i];
}
return null;
}
public IOConsole runConsole(String consolePrefix
, ILaunch launch
, IProgressMonitor monitor
) throws CoreException{
VDTRunner runner = VDTLaunchUtil.getRunner();
int numItem=runConfig.getBuildStep();
BuildParamsItem buildParamsItem = runConfig.getArgumentsItemsArray()[numItem]; // uses already calculated
//TODO: Handle monitor
// Find console with name starting with consolePrefix
IConsoleManager man = ConsolePlugin.getDefault().getConsoleManager(); // debugging
IConsole[] consoles=(IConsole[]) man.getConsoles();
// IOConsole iCons=null;
iCons=null;
consoleInStreamProxy=null;
for (int i=0;i<consoles.length;i++){
if (consoles[i].getName().startsWith(consolePrefix)){
iCons=(IOConsole) consoles[i];
break;
}
}
if (iCons==null) {
MessageUI.error("Specified console: "+consolePrefix+" is not found");
return null;
}
// try to send
String[] arguments = runConfig.getToolArguments();
if (arguments == null) arguments=new String[0];
if (VerilogPlugin.getPreferenceBoolean(PreferenceStrings.DEBUG_LAUNCHING)) {
// 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 */
// IOConsoleInputStream inStream= iCons.getInputStream();
IOConsoleOutputStream outStream= iCons.newOutputStream();
// IProcess process=((ProcessConsole)iCons).getProcess();
process=((ProcessConsole)iCons).getProcess();
// IStreamsProxy consoleInStreamProxy= process.getStreamsProxy();
consoleInStreamProxy= process.getStreamsProxy();
BuildParamsItem stderrParser=getParser(buildParamsItem.getStderr()); // re-parses all - why?
BuildParamsItem stdoutParser=getParser(buildParamsItem.getStdout());
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;
stdoutStreamProxy=null;
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=runner.run(runConfig,
"OUT for "+iCons.getName(),
launch,
null); //monitor);
stdoutStreamProxy= processOut.getStreamsProxy();
//TODO: Add error parsers
}
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=runner.run(runConfig,
"ERR for "+iCons.getName(),
launch,
null); //monitor);
stderrStreamProxy= processErr.getStreamsProxy();
//TODO: Add error parsers
}
sendErrorsToStreamProxy=(stderrStreamProxy!=null)?stderrStreamProxy:stdoutStreamProxy;
final IStreamsProxy fSendErrorsToStreamProxy=sendErrorsToStreamProxy;
final IStreamsProxy fSendOutputToStreamProxy= stdoutStreamProxy;
// connect input streams of the parsers to the out from the console process
IStreamMonitor consoleOutStreamMonitor=null;
IStreamMonitor consoleErrStreamMonitor=null;
runConfig.resetConsoleText();
String interrupt=buildParamsItem.getInterrupt(); // Not yet used
runConfig.setConsoleFinish(buildParamsItem.getPrompt());
System.out.println("Using console program termination string: \""+buildParamsItem.getPrompt()+"\"");
errorListener=null;
if (fSendErrorsToStreamProxy!=null){
consoleErrStreamMonitor=consoleInStreamProxy.getErrorStreamMonitor();
// IStreamListener errorListener=null;
errorListener=new IStreamListener(){
public void streamAppended(String text, IStreamMonitor monitor){
// System.out.println("Err:'"+text+"'");
try {
fSendErrorsToStreamProxy.write(text);
} catch (IOException e) {
System.out.println("Can not write errors"); //happens for the last prompt got after finish marker
}
if (runConfig.addConsoleText(text)){
System.out.println("Got finish sequence");
// TODO: launch continuation of the build process
finishConsolescript();
}
}
};
consoleErrStreamMonitor.addListener((IStreamListener) errorListener);
}
outputListener=null;
if (fSendOutputToStreamProxy!=null){
consoleOutStreamMonitor=consoleInStreamProxy.getOutputStreamMonitor();
outputListener=new IStreamListener(){
public void streamAppended(String text, IStreamMonitor monitor){
// System.out.println("Out:'"+text+"'");
try {
fSendOutputToStreamProxy.write(text);
} catch (IOException e) {
System.out.println("Can not write output");
}
if (runConfig.addConsoleText(text)){
System.out.println("Got finish sequence");
// TODO: launch continuation of the build process
finishConsolescript();
}
}
};
consoleOutStreamMonitor.addListener((IStreamListener) outputListener );
}
outStream.setColor(new Color(null, 128, 128, 255));
try {
for (int i=0;i<arguments.length;i++){
if (VerilogPlugin.getPreferenceBoolean(PreferenceStrings.LOCAL_ECHO)) {
outStream.write(arguments[i]+"\n"); // writes to console itself
}
consoleInStreamProxy.write(arguments[i]+"\n");
}
} catch (IOException e) {
System.out.println("Can not write to outStream of console "+iCons.getName());
}
return iCons;
}
// TODO: remove unneeded global vars
public void finishConsolescript() {
System.out.println("finishConsolescript()");
if (consoleInStreamProxy==null) {
System.out.println("Bug: consoleInStreamProxy == null");
return; // or continue other commands?
}
if (errorListener !=null) { // disconnect error stream listener
IStreamMonitor consoleErrorStreamMonitor=consoleInStreamProxy.getOutputStreamMonitor();
consoleErrorStreamMonitor.removeListener((IStreamListener) errorListener);
}
if (outputListener !=null) { // disconnect output stream listener
IStreamMonitor consoleOutStreamMonitor=consoleInStreamProxy.getOutputStreamMonitor();
consoleOutStreamMonitor.removeListener((IStreamListener) outputListener);
}
// terminate parser(s). Do those console listeners (parsers) have to be removed too?
if (processErr!=null){
try {
processErr.terminate();
} catch (DebugException e) {
System.out.println("Failed to reminate processErr parser process");
}
}
if (processOut!=null){
try {
processOut.terminate();
} catch (DebugException e) {
System.out.println("Failed to reminate processOut parser process");
}
}
// Is that all?
// runConfig.setBuildStep(runConfig.getBuildStep()+1); // next task to run
int thisStep=runConfig.getBuildStep();
System.out.println("Finished console task, step was "+thisStep);
runConfig.setBuildStep(thisStep+1); // next task to run
VDTLaunchUtil.getRunner().getRunningBuilds().saveUnfinished(runConfig.getOriginalConsoleName(), runConfig );
try {
VDTLaunchUtil.getRunner().resumeLaunch(runConfig.getOriginalConsoleName()); // replace with console
} catch (CoreException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
} // class VDTConsoleRunner
......@@ -107,9 +107,11 @@ public class VDTLaunchConfigurationDelegate implements ILaunchConfigurationDeleg
runConfig.setBuildStep(0);
List<String> controlFiles = VDTLaunchUtil.getControlFiles(configuration);
runConfig.setControlFiles((String[])controlFiles.toArray(new String[controlFiles.size()]));
String consoleName=VDTRunner.renderProcessLabel(runConfig.getToolName());
runner.saveUnfinished(consoleName, runConfig );
// String consoleName=VDTRunner.renderProcessLabel(runConfig.getToolName());
String consoleName=runConfig.getOriginalConsoleName();
runner.getRunningBuilds().saveUnfinished(consoleName, runConfig );
runner.resumeLaunch(consoleName);
return;
}
......
......@@ -72,7 +72,7 @@ public class VDTLaunchUtil {
}
return toolRunner;
}
//runningBuilds
/**
* Construct attribute name for command line representations of
* tool parameter.
......
......@@ -74,6 +74,10 @@ import com.elphel.vdt.veditor.preference.PreferenceStrings;
//import com.elphel.vdt.core.Utils;
import org.eclipse.ui.console.IConsoleListener;
......@@ -85,70 +89,27 @@ import org.eclipse.ui.console.IConsoleListener;
*/
public class VDTRunner {
// TODO:Remove
VDTRunnerConfiguration runningConfiguration; // multi-step configuration currently active
int nextBuildStep=0;
private Map<String, VDTRunnerConfiguration> unfinishedBuilds;
private RunningBuilds runningBuilds;
public VDTRunner(){
unfinishedBuilds = new HashMap<String, VDTRunnerConfiguration>();
IConsoleManager manager = ConsolePlugin.getDefault().getConsoleManager();
// This is not used, just for testing
System.out.println("***Addded console listeners");
manager.addConsoleListener(new IConsoleListener(){
public void consolesAdded(IConsole[] consoles){
for (int i=0;i<consoles.length;i++){
System.out.println("+++ Added: "+consoles[i].getName());
// Only shows added consoles
}
}
public void consolesRemoved(IConsole[] consoles){
for (int i=0;i<consoles.length;i++){
System.out.println("--- Removed: "+consoles[i].getName());
}
}
});
}
public boolean isUnfinished(String consoleName){
return unfinishedBuilds.containsKey(consoleName);
runningBuilds = new RunningBuilds();
}
public VDTRunnerConfiguration resumeConfiguration(String consoleName){
VDTRunnerConfiguration conf=unfinishedBuilds.get(consoleName);
unfinishedBuilds.remove(consoleName);
return conf;
}
public void removeConfiguration(String consoleName){
unfinishedBuilds.remove(consoleName);
}
public void saveUnfinished(String consoleName, VDTRunnerConfiguration configuration ){
unfinishedBuilds.put(consoleName, configuration);
public RunningBuilds getRunningBuilds(){
return runningBuilds;
}
// make call it when console is closed
private void doResumeLaunch( String consoleName ) throws CoreException {
// System.out.println("--------- resuming "+ consoleName+" ------------");
VDTRunnerConfiguration runConfig=resumeConfiguration(consoleName);
private void doResumeLaunch(String consoleName ) throws CoreException {
final VDTRunnerConfiguration runConfig=runningBuilds.resumeConfiguration(consoleName);
if (runConfig==null){
System.out.println("Turned out nothing to do. Probably a bug");
return;
}
// ILaunchConfiguration configuration=runConfig.getConfiguration();
// BuildParamsItem[] argumentsItemsArray = VDTLaunchUtil.getArguments(configuration); // calculates all parameters
BuildParamsItem[] argumentsItemsArray = runConfig.getArgumentsItemsArray(); // uses already calculated
int numItem=runConfig.getBuildStep();
System.out.println("--------- resuming "+ 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>();
......@@ -159,20 +120,22 @@ public class VDTRunner {
// toolArguments.addAll(resources);
runConfig.setToolArguments((String[])toolArguments.toArray(new String[toolArguments.size()]));
if (argumentsItemsArray[numItem].getConsoleName()!=null){
runConsole(argumentsItemsArray[numItem].getConsoleName(),runConfig, launch, monitor);
continue;
VDTConsoleRunner consoleRunner= runConfig.getConsoleRunner();
consoleRunner.runConsole(argumentsItemsArray[numItem].getConsoleName(), launch, monitor);
return; // Should be awaken by listener when the finish sequence will be output to console
//continue;
}
if (argumentsItemsArray[numItem].getNameAsParser()!=null){
// parsers should be launched by the console scripts, in parallel to them
System.out.println("Skipping parser "+argumentsItemsArray[numItem].getNameAsParser());
continue;
}
// Launch the configuration - 1 unit of work
// VDTRunner runner = VDTLaunchUtil.getRunner();
IProcess process=run(
runConfig,
renderProcessLabel(runConfig.getToolName()), // toolname + (date)
// renderProcessLabel(runConfig.getToolName()), // toolname + (date)
runConfig.getOriginalConsoleName(),
launch,
monitor);
......@@ -182,7 +145,7 @@ public class VDTRunner {
// check for cancellation
if (monitor.isCanceled() || (process==null)) {
removeConfiguration(consoleName);
runningBuilds.removeConfiguration(consoleName);
return;
}
if (numItem<(argumentsItemsArray.length-1)){ // Not for the last
......@@ -194,7 +157,7 @@ public class VDTRunner {
System.out.println("Could not get a console for the specified process");
continue;
}
System.out.println("consoleName="+consoleName+
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> ... "
......@@ -206,16 +169,16 @@ public class VDTRunner {
}
/* Prepare to postpone next commands to be resumed by event*/
runConfig.setBuildStep(numItem+1);
saveUnfinished(consoleName, runConfig );
runningBuilds.saveUnfinished(consoleName, runConfig );
iCons.addPropertyChangeListener( new IPropertyChangeListener() {
public void propertyChange(PropertyChangeEvent event) {
if (!fConsoleName.equals(fiCons.getName())){
fiCons.removePropertyChangeListener(this);
System.out.println(">>> "+fConsoleName+" -> "+fiCons.getName());
VDTRunner runner = VDTLaunchUtil.getRunner();
// VDTRunner runner = VDTLaunchUtil.getRunner();
try {
runner.resumeLaunch(fConsoleName);
resumeLaunch(fConsoleName); // replace with console
} catch (CoreException e) {
// TODO Auto-generated catch block
e.printStackTrace();
......@@ -234,158 +197,8 @@ public class VDTRunner {
}
monitor.done();
}
private BuildParamsItem getParser(VDTRunnerConfiguration configuration, String parserName){
if (parserName==null) return null;
BuildParamsItem[] buildParamsItems = configuration.getArgumentsItemsArray(); // uses already calculated
if (buildParamsItems==null) return null;
for (int i=0;i<buildParamsItems.length;i++){
if (parserName.equals(buildParamsItems[i].getNameAsParser()))
return buildParamsItems[i];
}
return null;
}
public IOConsole runConsole(String consolePrefix
, VDTRunnerConfiguration configuration
, ILaunch launch
, IProgressMonitor monitor
) throws CoreException{
int numItem=configuration.getBuildStep();
// BuildParamsItem buildParamsItem= VDTLaunchUtil.getArguments(configuration.getConfiguration())[numItem];
BuildParamsItem buildParamsItem = configuration.getArgumentsItemsArray()[numItem]; // uses already calculated
//TODO: Handle monitor
// Find console with name starting with consolePrefix
IConsoleManager man = ConsolePlugin.getDefault().getConsoleManager(); // debugging
IConsole[] consoles=(IConsole[]) man.getConsoles();
IOConsole iCons=null;
for (int i=0;i<consoles.length;i++){
if (consoles[i].getName().startsWith(consolePrefix)){
iCons=(IOConsole) consoles[i];
break;
}
}
if (iCons==null) {
MessageUI.error("Specified console: "+consolePrefix+" is not found");
return null;
}
// try to send
String[] arguments = configuration.getToolArguments();
if (arguments == null) arguments=new String[0];
if (VerilogPlugin.getPreferenceBoolean(PreferenceStrings.DEBUG_LAUNCHING)) {
// System.out.println("patternErrors= \""+ configuration.getPatternErrors()+"\"");
// System.out.println("patternWarnings= \""+configuration.getPatternWarnings()+"\"");
// System.out.println("patternInfo= \"" +configuration.getPatternInfo()+"\"");
if (arguments!=null){
for (int i=0;i<arguments.length;i++){
System.out.println("Console line "+i+" = \""+arguments[i]+"\"");
}
}
}
log("Writing to console "+iCons.getName()+":", arguments, null, false, true); /* Appears in the console of the target Eclipse (immediately erased) */
log("Writing to console "+iCons.getName()+":", arguments, null, false, false); /* Appears in the console of the parent Eclipse */
// IOConsoleInputStream inStream= iCons.getInputStream();
IOConsoleOutputStream outStream= iCons.newOutputStream();
IProcess process=((ProcessConsole)iCons).getProcess();
IStreamsProxy consoleInStreamProxy= process.getStreamsProxy();
BuildParamsItem stderrParser=getParser(configuration, buildParamsItem.getStderr()); // re-parses all - why?
BuildParamsItem stdoutParser=getParser(configuration, buildParamsItem.getStdout());
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"));
// basically use
// IProcess process=run(configuration, launch, monitor);
// renderProcessLabel(configuration.getToolName()+":out")
IProcess processErr=null;
IProcess processOut=null;
IStreamsProxy stdoutStreamProxy=null;
IStreamsProxy stderrStreamProxy=null;
if (stdoutParser!=null){
List<String> toolArgumentsStdout = new ArrayList<String>();
List<String> stdoutArguments=stdoutParser.getParamsAsList();
if (stdoutArguments != null)
toolArgumentsStdout.addAll(stdoutArguments);
// overwriting configuration, but this is done sequentially, so OK
configuration.setToolArguments((String[])toolArgumentsStdout.toArray(new String[toolArgumentsStdout.size()]));
processOut=run(configuration,
renderProcessLabel(configuration.getToolName()+":out"),
launch,
null); //monitor);
stdoutStreamProxy= processOut.getStreamsProxy();
//TODO: Add error parsers
}
if (stderrParser!=null){
List<String> toolArgumentsStderr = new ArrayList<String>();
List<String> stderrArguments=stderrParser.getParamsAsList();
if (stderrArguments != null)
toolArgumentsStderr.addAll(stderrArguments);
// overwriting configuration, but this is done sequentially, so OK
configuration.setToolArguments((String[])toolArgumentsStderr.toArray(new String[toolArgumentsStderr.size()]));
processErr=run(configuration,
renderProcessLabel(configuration.getToolName()+":err"),
launch,
null); //monitor);
stderrStreamProxy= processErr.getStreamsProxy();
//TODO: Add error parsers
}
final IStreamsProxy fSendErrorsToStreamProxy=(stderrStreamProxy!=null)?stderrStreamProxy:stdoutStreamProxy;
final IStreamsProxy fSendOutputToStreamProxy= stdoutStreamProxy;
// connect input streams of the parsers to the out from the console process
IStreamMonitor consoleOutStreamMonitor=null;
IStreamMonitor consoleErrStreamMonitor=null;
if (fSendErrorsToStreamProxy!=null){
consoleErrStreamMonitor=consoleInStreamProxy.getErrorStreamMonitor();
consoleErrStreamMonitor.addListener(new IStreamListener(){
public void streamAppended(String text, IStreamMonitor monitor){
System.out.println("Err:'"+text+"'");
try {
fSendErrorsToStreamProxy.write(text);
} catch (IOException e) {
System.out.println("Can not write errors");
}
}
});
}
if (fSendOutputToStreamProxy!=null){
consoleOutStreamMonitor=consoleInStreamProxy.getOutputStreamMonitor();
consoleOutStreamMonitor.addListener(new IStreamListener(){
public void streamAppended(String text, IStreamMonitor monitor){
System.out.println("Out:'"+text+"'");
try {
fSendOutputToStreamProxy.write(text);
} catch (IOException e) {
System.out.println("Can not write output");
}
}
});
}
try {
for (int i=0;i<arguments.length;i++){
if (VerilogPlugin.getPreferenceBoolean(PreferenceStrings.LOCAL_ECHO)) {
outStream.setColor(new Color(null, 128, 128, 255));
outStream.write(arguments[i]+"\n"); // writes to console itself
outStream.setColor(null);
}
consoleInStreamProxy.write(arguments[i]+"\n");
}
} catch (IOException e) {
System.out.println("Can not write to outStream of console "+iCons.getName());
}
return iCons;
}
public void resumeLaunch( String consoleName ) throws CoreException
public void resumeLaunch(String consoleName) throws CoreException
{
try {
doResumeLaunch(consoleName);
......@@ -565,7 +378,7 @@ public class VDTRunner {
} // run()
private void log(String header,
public void log(String header,
String[] strings,
String[] controlFiles,
boolean formatColumn,
......
......@@ -17,9 +17,14 @@
*******************************************************************************/
package com.elphel.vdt.core.launching;
import java.util.HashSet;
import java.util.Set;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.ILaunchConfiguration;
//import org.eclipse.debug.ui.console.IConsole;
import org.eclipse.ui.console.IConsole;
import com.elphel.vdt.Txt;
import com.elphel.vdt.core.tools.contexts.BuildParamsItem;
......@@ -55,8 +60,15 @@ public class VDTRunnerConfiguration {
private ILaunch launch;
private IProgressMonitor monitor;
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 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 String originalConsoleName=null;
private Set<IConsole> consoles=null; // parser consoles opened for this console
private VDTConsoleRunner consoleRunner=null;
public BuildParamsItem[] getArgumentsItemsArray(){
return argumentsItemsArray;
}
......@@ -78,8 +90,52 @@ public class VDTRunnerConfiguration {
throw new IllegalArgumentException(Txt.s("Launch.Error.ToolNotNull"));
}
this.toolToLaunch = toolToLaunch;
this.consoleFinish=null;
this.consoleBuffer="";
this.consoles= new HashSet<IConsole>();
this.consoleRunner= new VDTConsoleRunner(this); // arguments here?
}
public VDTConsoleRunner getConsoleRunner(){
return this.consoleRunner;
}
public void addConsole(IConsole console){
consoles.add(console);
}
public void removeConsole(IConsole console){
consoles.remove(console);
}
public boolean noConsoles(){
return consoles.isEmpty();
}
public boolean hasConsole(IConsole console){
return consoles.contains(console);
}
public void setConsoleFinish(String consoleFinish){
this.consoleFinish=consoleFinish;
}
public boolean addConsoleText(String text){
if (consoleFinish==null){
System.out.println("Dinish 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 (consoleBuffer.indexOf(consoleFinish)>=0){
resetConsoleText();
return true;
}
return false;
}
public void resetConsoleText(){
consoleBuffer="";
}
public void setConfiguration(ILaunchConfiguration configuration){
this.configuration=configuration;
}
......@@ -160,7 +216,12 @@ public class VDTRunnerConfiguration {
}
public void setToolName(String str) {
this.toolName=str;
this.originalConsoleName=VDTRunner.renderProcessLabel(this.toolName); //
}
public String getOriginalConsoleName() {
return originalConsoleName;
}
public String getToolName() {
return toolName;
}
......
......@@ -55,16 +55,18 @@ public class CommandLinesNodeReader extends AbstractConditionNodeReader {
private CommandLinesBlock readCommandLinesBlock(Node node, Condition condition)
throws ConfigException
{
String name = XMLConfig.getAttributeValue(node, XMLConfig.CONTEXT_LINEBLOCK_NAME_ATTR);
String dest = XMLConfig.getAttributeValue(node, XMLConfig.CONTEXT_LINEBLOCK_DEST_ATTR);
String sep = XMLConfig.getAttributeValue(node, XMLConfig.CONTEXT_LINEBLOCK_SEP_ATTR);
String mark = XMLConfig.getAttributeValue(node, XMLConfig.CONTEXT_LINEBLOCK_MARK_ATTR);
String errors = XMLConfig.getAttributeValue(node, XMLConfig.CONTEXT_LINEBLOCK_ERRORS_ATTR);
String warnings = XMLConfig.getAttributeValue(node, XMLConfig.CONTEXT_LINEBLOCK_WARNINGS_ATTR);
String info = XMLConfig.getAttributeValue(node, XMLConfig.CONTEXT_LINEBLOCK_INFO_ATTR);
String prompt = XMLConfig.getAttributeValue(node, XMLConfig.CONTEXT_LINEBLOCK_PROMPT_ATTR);
String stderr = XMLConfig.getAttributeValue(node, XMLConfig.CONTEXT_LINEBLOCK_STDERR_ATTR);
String stdout = XMLConfig.getAttributeValue(node, XMLConfig.CONTEXT_LINEBLOCK_STDOUT_ATTR);
String name = XMLConfig.getAttributeValue(node, XMLConfig.CONTEXT_LINEBLOCK_NAME_ATTR);
String dest = XMLConfig.getAttributeValue(node, XMLConfig.CONTEXT_LINEBLOCK_DEST_ATTR);
String sep = XMLConfig.getAttributeValue(node, XMLConfig.CONTEXT_LINEBLOCK_SEP_ATTR);
String mark = XMLConfig.getAttributeValue(node, XMLConfig.CONTEXT_LINEBLOCK_MARK_ATTR);
String errors = XMLConfig.getAttributeValue(node, XMLConfig.CONTEXT_LINEBLOCK_ERRORS_ATTR);
String warnings = XMLConfig.getAttributeValue(node, XMLConfig.CONTEXT_LINEBLOCK_WARNINGS_ATTR);
String info = XMLConfig.getAttributeValue(node, XMLConfig.CONTEXT_LINEBLOCK_INFO_ATTR);
String prompt = XMLConfig.getAttributeValue(node, XMLConfig.CONTEXT_LINEBLOCK_PROMPT_ATTR);
String interrupt = XMLConfig.getAttributeValue(node, XMLConfig.CONTEXT_LINEBLOCK_INTERRUPT_ATTR);
String stderr = XMLConfig.getAttributeValue(node, XMLConfig.CONTEXT_LINEBLOCK_STDERR_ATTR);
String stdout = XMLConfig.getAttributeValue(node, XMLConfig.CONTEXT_LINEBLOCK_STDOUT_ATTR);
if(name == null)
throw new ConfigException("Unnamed lines block definition in context '" +
......@@ -86,7 +88,8 @@ public class CommandLinesNodeReader extends AbstractConditionNodeReader {
errors,
warnings,
info,
prompt,
prompt,
interrupt,
stderr,
stdout,
lines,
......
......@@ -132,6 +132,7 @@ public class XMLConfig extends Config {
static final String CONTEXT_LINEBLOCK_WARNINGS_ATTR = "warnings";
static final String CONTEXT_LINEBLOCK_INFO_ATTR = "info";
static final String CONTEXT_LINEBLOCK_PROMPT_ATTR = "prompt";
static final String CONTEXT_LINEBLOCK_INTERRUPT_ATTR ="interrupt";
static final String CONTEXT_LINEBLOCK_STDERR_ATTR = "stderr";
static final String CONTEXT_LINEBLOCK_STDOUT_ATTR = "stdout";
......
......@@ -30,6 +30,7 @@ public class BuildParamsItem implements Cloneable{
private String toolInfo; // Eclipse pattern for pattern recognizer
// for commands being sent to opened remote console:
private String prompt; // relevant for commands sent to remote console - double prompt means "done" (extra separator on input)
private String interrupt; // control character(s) to interrupt console command
private String stderr; // name of the command to (command line block) to launch in a separate process/console
// and connect to stderr of the terminal session
private String stdout; // name of the command to (command line block) to launch in a separate process/console
......@@ -46,6 +47,7 @@ public class BuildParamsItem implements Cloneable{
String toolWarnings,
String toolInfo,
String prompt,
String interrupt,
String stderr,
String stdout
) {
......@@ -57,6 +59,7 @@ public class BuildParamsItem implements Cloneable{
this.toolWarnings=toolWarnings;
this.toolInfo=toolInfo;
this.prompt=prompt;
this.interrupt=interrupt;
this.stderr=stderr;
this.stdout=stdout;
......@@ -70,7 +73,8 @@ public class BuildParamsItem implements Cloneable{
item.toolErrors,
item.toolWarnings,
item.toolInfo,
item.prompt,
item.prompt,
item.interrupt,
item.stderr,
item.stdout
);
......@@ -128,6 +132,7 @@ public class BuildParamsItem implements Cloneable{
public String getWarnings() { return toolWarnings; }
public String getInfo() { return toolInfo; }
public String getPrompt() { return prompt; }
public String getInterrupt() { return interrupt; }
public String getStderr() { return stderr; }
public String getStdout() { return stdout; }
}
......@@ -215,8 +215,10 @@ public abstract class Context {
String toolInfo=commandLinesBlock.getInfo();
String stderr=commandLinesBlock.getStderr();
String stdout=commandLinesBlock.getStdout();
String prompt=buildSimpleString(commandLinesBlock.getPrompt());
if ((prompt !=null ) && (mark!=null)) prompt=prompt.replace(mark, "");
String prompt=buildSimpleString(commandLinesBlock.getPrompt()); // evaluate string
prompt=commandLinesBlock.parseCntrl(prompt); // replace control character codes (\n,\t,\x)
prompt=commandLinesBlock.applyMark(prompt); // remove mark sequence
String interrupt=commandLinesBlock.getInterrupt();
List<String> lines = commandLinesBlock.getLines(); // [%Param_Shell_Options, echo BuildDir=%BuildDir ;, echo SimulationTopFile=%SimulationTopFile ;, echo SimulationTopModule=%SimulationTopModule ;, echo BuildDir=%BuildDir;, %Param_PreExe, %Param_Exe, %Param_TopModule, %TopModulesOther, %ModuleLibrary, %LegacyModel, %NoSpecify, %v, %SourceList, %ExtraFiles, %Filter_String]
List<List<String>> commandSequence = new ArrayList<List<String>>();
for(Iterator<String> lineIter = lines.iterator(); lineIter.hasNext();) {
......@@ -224,8 +226,6 @@ public abstract class Context {
commandSequence.add(buildCommandString(line)); // TODO: parses them here? VERIFY
}
// parse prompt?
// Here - already resolved to empty
List<String> commandLineParams = new ArrayList<String>();
if(destName != null) {
......@@ -244,7 +244,8 @@ public abstract class Context {
toolErrors,
toolWarnings,
toolInfo,
prompt,
prompt,
interrupt,
stderr,
stdout)
);
......@@ -278,7 +279,8 @@ public abstract class Context {
toolErrors,
toolWarnings,
toolInfo,
prompt,
prompt,
interrupt,
stderr,
stdout)
);
......
......@@ -17,6 +17,7 @@
*******************************************************************************/
package com.elphel.vdt.core.tools.params;
import java.nio.charset.StandardCharsets;
import java.util.*;
import com.elphel.vdt.core.tools.Updateable;
......@@ -48,6 +49,7 @@ public class CommandLinesBlock extends UpdateableStringsContainer
// and connect to stderr of the terminal session
// If both are specified and pointing to the same command block - two instances/consoles will be launched.
// if only stdout - both stdout and stdin of a session will go to the same process/console
private String interrupt; // send this to remote terminal to interrupt execution (parses use \xNN)
public CommandLinesBlock(String contextName,
......@@ -60,6 +62,7 @@ public class CommandLinesBlock extends UpdateableStringsContainer
String toolWarnings,
String toolInfo,
String prompt,
String interrupt,
String stderr,
String stdout,
ConditionalStringsList lines,
......@@ -78,15 +81,47 @@ public class CommandLinesBlock extends UpdateableStringsContainer
this.toolWarnings=toolWarnings;
this.toolInfo=toolInfo;
this.prompt=prompt;
this.interrupt=interrupt;
this.stderr=stderr;
this.stdout=stdout;
if(separator != null) {
separator = separator.replace("\\n", "\n");
separator = separator.replace("\\t", "\t");
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);
}
}
public String parseCntrl(String str){
if (str==null) return null;
str=str.replace("\\n" ,"\n");
str=str.replace("\\t", "\t");
while (true){
int start=str.indexOf("\\x");
if (start<0) break;
String s= new String(new byte[]{ Byte.parseByte(str.substring(start+2,start+4),16) }, StandardCharsets.US_ASCII);
str=str.replace(str.subSequence(start,start+4),s);
}
return str;
}
public String applyMark(String str){
if ((mark!=null) && (str!=null)){
str=str.replace(mark, "");
}
return str;
}
public CommandLinesBlock(CommandLinesBlock block) {
this(block.contextName,
block.name,
......@@ -98,6 +133,7 @@ public class CommandLinesBlock extends UpdateableStringsContainer
block.toolWarnings,
block.toolInfo,
block.prompt,
block.interrupt,
block.stderr,
block.stdout,
block.strings != null?
......@@ -166,6 +202,7 @@ public class CommandLinesBlock extends UpdateableStringsContainer
public String getWarnings() { return toolWarnings; }
public String getInfo() { return toolInfo; }
public String getPrompt() { return prompt; }
public String getInterrupt() { return prompt; }
public String getStderr() { return stderr; }
public String getStdout() { return stdout; }
......
......@@ -34,9 +34,7 @@ public class SimpleGeneratorRecognizer implements Recognizer {
new CurrentFileGenerator(),
new CurrentFileBaseGenerator(),
new ChosenActionGenerator(),
new BuildStampGenerator(),
new BlankGenerator(),
new NewLineGenerator()
new BuildStampGenerator()
};
public SimpleGeneratorRecognizer(){
......
......@@ -54,10 +54,12 @@
</input>
<output>
<line name="command_line">
<line name="command_line"
interrupt="\x03">
"%ShellSwitches"
"%PreSSH"
"ssh"
"-t"
"-l"
"%RemoteUser"
"%RemoteHost"
......@@ -108,10 +110,11 @@
dest="python_console_name"
mark="``"
sep="\n"
prompt=">>>"
prompt="@@FINISH@@"
stdout="parser_001">
"%RemoteCommand"
"``" <!-- two new lines should generate a pair of prompts from the remote -->
"print '@@FINISH@@'"
"``"`" <!-- two new lines should generate a pair of prompts from the remote -->
</line>
<line name="command_line_02">
"-c"
......@@ -132,3 +135,4 @@
</tool>
</vdt-project>
<!-- /opt/Xilinx/Vivado/2013.4/bin/vivado -mode tcl -->
\ No newline at end of file
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