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
This diff is collapsed.
......@@ -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.
......
......@@ -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