mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-07-03 15:15:25 +02:00
Support shell output parsing in ssh connections
This commit is contained in:
parent
a604bc4c50
commit
b5e8fe024d
14 changed files with 798 additions and 7 deletions
|
@ -4,6 +4,7 @@ bin.includes = META-INF/,\
|
|||
about.ini,\
|
||||
about.mappings,\
|
||||
about.properties,\
|
||||
patterns.dat,\
|
||||
plugin.properties,\
|
||||
readme.txt,\
|
||||
eclipse32.png
|
||||
|
|
283
rse/plugins/org.eclipse.rse.services.ssh/patterns.dat
Normal file
283
rse/plugins/org.eclipse.rse.services.ssh/patterns.dat
Normal file
|
@ -0,0 +1,283 @@
|
|||
################################################################################
|
||||
# Copyright (c) 2006 IBM Corporation. All rights reserved.
|
||||
# This program and the accompanying materials are made available under the terms
|
||||
# of the Eclipse Public License v1.0 which accompanies this distribution, and is
|
||||
# available at http://www.eclipse.org/legal/epl-v10.html
|
||||
#
|
||||
# Initial Contributors:
|
||||
# The following IBM employees contributed to the Remote System Explorer
|
||||
# component that contains this file: David McKnight, Kushal Munir,
|
||||
# Michael Berger, David Dykstal, Phil Coulthard, Don Yantzi, Eric Simpson,
|
||||
# Emily Bruner, Mazen Faraj, Adrian Storisteanu, Li Ding, and Kent Hawley.
|
||||
#
|
||||
# Contributors:
|
||||
# Martin Oberhuber (Wind River) - Adapted from RSE services.local/patterns.dat
|
||||
################################################################################
|
||||
#
|
||||
# parse command line output.
|
||||
#
|
||||
# CLICK THIS LINE TO EDIT THIS FILE (PATTERNS.DAT). (When viewing from the Output view)
|
||||
|
||||
command: grep -n.*
|
||||
grep file line pattern =([\w,.,/,(,),\\,\-,\+,\d]*):(\d*):.*
|
||||
|
||||
command: grep -.*n.*
|
||||
grep file line pattern =([\w,.,/,(,),\\,\-,\+,\d]*):(\d*):.*
|
||||
|
||||
command: grep .*
|
||||
grep file pattern =([\w,.,/,(,)\\,\-,\+,\d]*):.*
|
||||
|
||||
|
||||
command: pwd
|
||||
directory file pattern=([\w,.,/,(,),\\,\-,\+,\d,:]*)
|
||||
|
||||
command: nmake.*
|
||||
error pattern=NMAKE : .*
|
||||
error file line pattern =([\w,.,\-,\+,(,),\\,:]*)\((\d*):(\d*)\) : error EDC.*
|
||||
error file pattern =[\w,.,\-,\+,(,),\\,:]*\(([\w,.,/,\\]*)\) : error LNK.*
|
||||
error file line pattern=([\w,.,/,\-,\+,(,),\\]*):(\d*):\d*\) : error .*
|
||||
warning file line pattern=([\w,.,/,\-,\+,(,),\\]*)\((\d*):\d*\) : warning .*
|
||||
informational file line pattern=([\w,.,/,\-,\+,(,),\\]*)\((\d*):\d*\) : informational .*
|
||||
|
||||
command: make.*
|
||||
error file line pattern=\"([\w,.,/,(,),\-,\+,\\]*)\", line (\d*)\.\d*: \d*-\d* \(S\).*
|
||||
error file line pattern=\"([\w,.,/,(,),\-,\+,\\]*)\",, line (\d*)\.\d*: \d*-\d* \(E\).*
|
||||
warning file line pattern=\"([\w,.,/,(,),\-,\+,\\]*)\", line (\d*)\.\d*: \d*-\d* \(W\).*
|
||||
informational file line pattern=\"([\w,.,/,(,),\-,\+,\\]*)\", line (\d*)\.\d*: \d*-\d* \(I\).*
|
||||
warning file line pattern =([\w,.,/,(,),\-,\+,\\]*):(\d*): warning: .*
|
||||
warning file line pattern =([\w,.,/,\\,\-,\+,(,)]*):(\d*):\d*: warning: .*
|
||||
error file line pattern =([\w,.,/,\\,\-,\+,(,)]*):(\d*):.*
|
||||
informational file pattern =([\w,.,/,\\,\-,\+,(,)]*):.*
|
||||
informational file line pattern =In file included from ([\w,.,/,\\,\-,\+,(,)]*):(\d*):
|
||||
#iseries c compiler
|
||||
error file line pattern=[\w,.,/,\\]* Line \d* \"([\w,.,/,\\]*)\", line (\d*)\.\d*: .*
|
||||
error file line pattern=([\w,.,/,\\]*) Line (\d*)\s.*
|
||||
#makefile errors
|
||||
error file line pattern=\"([\w,\.,/,(,),\-,\+,\\]*)\", line (\d*): make:.*
|
||||
#xlc Options warnings
|
||||
warning pattern=\(W\) Option .*
|
||||
#c89 errors
|
||||
error file line pattern=ERROR CBC\d* ([\w,.,/,\\,\-,\+,(,)]*):(\d*) .*
|
||||
warning file line pattern=WARNING CBC\d* ([\w,.,/,\\,\-,\+,(,)]*):(\d*) .*
|
||||
informational pattern=CBC\d*\(I\) .*
|
||||
|
||||
command: gmake.*
|
||||
error file line pattern=\"([\w,.,/,(,),\-,\+,\\]*)\", line (\d*)\.\d*: \d*-\d* \(S\).*
|
||||
warning file line pattern=\"([\w,.,/,(,),\-,\+,\\]*)\", line (\d*)\.\d*: \d*-\d* \(W\).*
|
||||
informational file line pattern=\"([\w,.,/,(,),\-,\+,\\]*)\", line (\d*)\.\d*: \d*-\d* \(I\).*
|
||||
warning file line pattern =([\w,.,/,(,),\-,\+,\\]*):(\d*): warning: .*
|
||||
warning file line pattern =([\w,.,/,\\,\-,\+,(,)]*):(\d*):\d*: warning: .*
|
||||
informational file line pattern =In file included from ([\w,.,/,\\,\-,\+,(,)]*):(\d*):
|
||||
# ixlc compiler
|
||||
error file line pattern=[\w,.,/,\\]* Line \d* \"([\w,.,/,\\]*)\", line (\d*)\.\d*: .*
|
||||
error file line pattern=([\w,.,/,\\]*) Line (\d*)\s.*
|
||||
# icc compiler
|
||||
error file line pattern =([\w,.,/,\\,\-,\+,(,)]*),\s(\d*)\.\d*:\s.*
|
||||
error file line pattern =\"([\w,.,/,\\,\-,\+,(,)]*)\",\sline\s(\d*)\.\d*:\s.*
|
||||
#generic
|
||||
error file line pattern =([\w,.,/,\\,\-,\+,(,)]*):(\d*):.*
|
||||
|
||||
command: gcc\s.*
|
||||
error file line pattern=\"([\w,.,/,\\,\-,\+,(,)]*)\", line (\d*)\.\d*: \d*-\d* \(S\).*
|
||||
warning file line pattern=\"([\w,.,/,\\,\-,\+,(,)]*)\", line (\d*)\.\d*: \d*-\d* \(W\).*
|
||||
informational file line pattern=\"([\w,.,/,\\,\-,\+,(,)]*)\", line (\d*)\.\d*: \d*-\d* \(I\).*
|
||||
warning file line pattern =([\w,.,/,\\,\-,\+,(,)]*):(\d*): warning: .*
|
||||
warning file line pattern =([\w,.,/,\\,\-,\+,(,)]*):(\d*):\d*: warning: .*
|
||||
error file line pattern =([\w,.,/,\\,\-,\+,(,)]*):(\d*):.*
|
||||
informational file pattern =([\w,.,/,\\,\-,\+,(,)]*):.*
|
||||
informational file line pattern =In file included from ([\w,.,/,\\,\-,\+,(,)]*):(\d*):
|
||||
|
||||
command: cc\s.*
|
||||
error file line pattern =([\w,.,/,\\,\-,\+,(,)]*):(\d*):.*
|
||||
|
||||
command: CC\s.*
|
||||
error file line pattern =([\w,.,/,\\,\-,\+,(,)]*):(\d*):.*
|
||||
|
||||
command: c89.*
|
||||
error file line pattern=ERROR CBC\d* ([\w,.,/,\\,\-,\+,(,)]*):(\d*) .*
|
||||
warning file line pattern=WARNING CBC\d* ([\w,.,/,\\,\-,\+,(,)]*):(\d*) .*
|
||||
informational pattern=CBC\d*\(I\) .*
|
||||
|
||||
command: icc.*
|
||||
error file line pattern =([\w,.,/,\\,\-,\+,(,)]*),\s(\d*)\.\d*:\s.*
|
||||
error file line pattern =\"([\w,.,/,\\,\-,\+,(,)]*)\",\sline\s(\d*)\.\d*:\s.*
|
||||
|
||||
command: javac.*
|
||||
warning file line pattern=([\w,.,/,\\,\-,\+,(,),:]*):(\d*): warning.*
|
||||
error file line pattern=([\w,.,/,\\,\-,\+,(,),:]*):(\d*):.*
|
||||
|
||||
command: .*bat\s.*
|
||||
error file line pattern=\[javac\]\s([\w,.,/,\\,:]*):(\d*):.*
|
||||
error file line pattern=file:([\w,.,/,\\,:]*):(\d*):.*
|
||||
|
||||
command: dir.*
|
||||
directory file pattern=\d{2}/\d{2}/\d*\s*\d{2}:\d{2}\s[a,p,AM,PM]+\s*<DIR>\s*([\w,.,/,\\,\s,\-,\+,\d]*).*
|
||||
directory file pattern=.*<DIR>\s*([\w,.,/,\\,\s,\-,\+,\d]*).*
|
||||
file file pattern=\d{2}/\d{2}/\d*\s*\d{2}:\d{2}\s[a,p,AM,PM]+\s*[\d,,]*\s*([\w,.,/,\\,\s,\-,\+,\d]*).*
|
||||
directory file pattern=[\d,/,\\,.,-]+.\s*\d{2}[:,.]\d{2}.\s*<DIR>\s*([\w,.,/,\\,\s,\-,\+,\d]*)
|
||||
file file pattern=[\d,/,\\,.,-]+.\s*\d{2}[:,.]\d{2}.\s*[\d,,,.]*\s*([\w,.,/,\\,\s,\-,\+,\d]*)
|
||||
|
||||
command: ls -l.*
|
||||
file file pattern=-[-,r,w,x]+\s.*\s[\d{4},\d{2}:\d{2}]+,\s([\w,.,/,(,),\\,\-,\+\s,\d]*)
|
||||
file file pattern=l[-,r,w,x]+\s.*\s[\d{4},\d{2}:\d{2}]+,\s([\w,.,/,(,),\\,\-,\+\s,\d]*)\s->\s[\w,.,/,(,),\\,\-,\+\s,\d]*
|
||||
file file pattern=-.*\d{2}:\d{2} ([\w,.,/,(,),\\,\-,\+,\s,\d]*)
|
||||
file file pattern=-.* \d{4} ([\w,.,/,(,),\\,\-,\+,\s,\d]*)
|
||||
file file pattern=l.*\d{2}:\d{2} ([\w,.,/,(,),\\,\-,\+,\s,\d]*)\s->\s[\w,.,/,(,),\\,\-,\+\s,\d]*
|
||||
file file pattern=l.* \d{4} ([\w,.,/,(,),\\,\-,\+,\s,\d]*)\s->\s[\w,.,/,(,),\\,\-,\+\s,\d]*
|
||||
directory file pattern=d.*\d{2}:\d{2} ([\w,.,/,(,),\\,\-,\+\s,\d]*)
|
||||
directory file pattern=d.*\d{4} ([\w,.,/,(,),\\,\-,\+,\s,\d]*)
|
||||
|
||||
command: ls -a.*
|
||||
file file pattern=-.*\d{2}:\d{2} ([\w,.,/,(,),\\,\-,\+\s,\d]*)
|
||||
file file pattern=-.* \d{4} ([\w,.,/,(,),\\,\-,\+\s,\d]*)
|
||||
directory file pattern=d.*\d{2}:\d{2} ([\w,.,/,(,),\\,\-,\+\s,\d]*)
|
||||
directory file pattern=d.*\d{4} ([\w,.,/,(,),\\,\-,\+\s,\d]*)
|
||||
|
||||
command: ls
|
||||
file file pattern=([\w,\d,.,(,),\-,\+\s]+)
|
||||
|
||||
command: ls\s.*
|
||||
file file pattern=([\w,\d,.,(,),\-,\+\s]+)
|
||||
|
||||
command: .*
|
||||
prompt file pattern=([\w,.,/,(,),\\,\-,\+,\d,:,\s]*)>.*
|
||||
|
||||
command: find .*
|
||||
file file pattern=([\w,.,/,\\,(,),\-]+)
|
||||
|
||||
command: env
|
||||
pathenvvar file pattern=PATH\=(.*)
|
||||
libpathenvvar file pattern=LIBPATH\=(.*)
|
||||
libpathenvvar file pattern=LIB\=(.*)
|
||||
envvar pattern=[\w\d]+\=.*
|
||||
|
||||
command: ps
|
||||
process pattern=[\s]*[\d]+\s.*
|
||||
|
||||
command: ps .*
|
||||
process pattern=[\s]*[\d]+\s.*
|
||||
|
||||
command: xl[C,c].*
|
||||
error file line pattern=\"([\w,.,/,(,),\-,\+,\\]*)\",, line (\d*)\.\d*: \d*-\d* \(S\).*
|
||||
error file line pattern=\"([\w,.,/,(,),\-,\+,\\]*)\", line (\d*)\.\d*: \d*-\d* \(E\).*
|
||||
warning file line pattern=\"([\w,.,/,(,),\-,\+,\\]*)\", line (\d*)\.\d*: \d*-\d* \(W\).*
|
||||
informational file line pattern=\"([\w,.,/,(,),\-,\+,\\]*)\", line (\d*)\.\d*: \d*-\d* \(I\).*
|
||||
|
||||
command: ixlc.*
|
||||
error file line pattern=([\w,.,/,\\]*) Line (\d*)\s.*
|
||||
error file line pattern=[\w,.,/,\\]* Line \d* \"([\w,.,/,\\]*)\", line (\d*)\.\d*: .*
|
||||
|
||||
command: cat.*patterns.*
|
||||
warning file pattern=# .*(PATTERNS.DAT).*
|
||||
Output pattern=command: .*
|
||||
#statement pattern=#.*
|
||||
statement pattern=.* pattern.*=.*
|
||||
|
||||
# special for autoconf
|
||||
command: ./bootstrap.sc.*
|
||||
error file line pattern=aclocal: ([\w,.,/,\\]*): (\d*):.*
|
||||
warning file line pattern=([\w,.,/,\\]*):(\d*):.*
|
||||
|
||||
command: ./configure.*
|
||||
error file line pattern=./(configure): line (\d*): .*
|
||||
|
||||
# How Patterns Work
|
||||
# -----------------
|
||||
#
|
||||
# Patterns are used by the Output View to allow lines that contain file names and
|
||||
# perhaps line numbers to be clicked to cause the file location to be opened in an Editor.
|
||||
# A line in this file can be 1 of 3 things:
|
||||
# 1. An empty line or a comment line (denoted by a # in column 1)
|
||||
# 2. The start of a command description (denoted by a 'command:' at the beginning of the line)
|
||||
# 3. A pattern description.
|
||||
# A formal description of the syntax of this file is included at the bottom of this file.
|
||||
#
|
||||
#
|
||||
# Command Descriptions
|
||||
# --------------------
|
||||
#
|
||||
# A Command Description consists of 2 things: A regular expression that describes the
|
||||
# command invocation, and a list of Pattern Descriptions. The regular expression
|
||||
# is used to determine what set of Pattern Descriptons to use when parsing command output.
|
||||
# For example, if you type the command 'gmake clean', the Command Descriptions are checked and
|
||||
# .*make.* would match that command. Therefore the Pattern Descriptions for .*make.* would
|
||||
# be used to parse the output of the 'gmake clean'.
|
||||
# Note: The first Command Description that is found to match the command is used, so make
|
||||
# sure you put the most specific patterns first. For example, if the nmake.* Command
|
||||
# Description appeared after .*make.*, then 'nmake install' would be matched by the .*make.*
|
||||
# Command Descripton, which is probably not what was intended.
|
||||
#
|
||||
#
|
||||
# Pattern Descriptions
|
||||
# --------------------
|
||||
#
|
||||
# A Pattern Description has the following form:
|
||||
# <obj-name> <match-info> "pattern="<reg-ex>
|
||||
#
|
||||
# where:
|
||||
# <obj-name>: The type of object that will be created in the Output View if
|
||||
# a line of output matches this pattern.
|
||||
#
|
||||
# <match-info>: This is some combination of the words "file" and "line" or nothing
|
||||
# at all. This is used to define how the backreferences in the
|
||||
# regular expression are to be interpreted. So "file line" means
|
||||
# that the first back-reference is a file, and the second is a
|
||||
# line number. This may seem unnecessary, but we added this capability
|
||||
# in the event that future releases support other types of information
|
||||
# that may be useful, such as column info (once we support it).
|
||||
#
|
||||
# <reg-ex>: A regular expression that describes a line of output. Backreferences
|
||||
# are used to store (instead of just match) the filename and line
|
||||
# number. To store a filename use the backreference ([\w,.,/,\\]*), and
|
||||
# to store a line number, use (\d*)
|
||||
#
|
||||
#
|
||||
# Note: The patterns are checked against command output and only exact matches are dealt with
|
||||
# So as an example, if you forget the .* (match everything) at the end of a pattern,
|
||||
# the match will fail if there are trailing characters in the output not accounted for by
|
||||
# the pattern
|
||||
#
|
||||
#
|
||||
# Pattern File Syntax
|
||||
# -------------------
|
||||
#
|
||||
# The pattern file syntax should be easy to grasp by looking at the ones
|
||||
# above, but for those of you who like formal grammars, here it is:
|
||||
#
|
||||
# patterns-file:
|
||||
# commands
|
||||
#
|
||||
# commands:
|
||||
# command
|
||||
# commands new-line command
|
||||
#
|
||||
# command:
|
||||
# "command:" reg-ex new-line patterns
|
||||
#
|
||||
# patterns:
|
||||
# pattern
|
||||
# patterns new-line pattern
|
||||
#
|
||||
# pattern:
|
||||
# command-name match-list "pattern=" reg-ex
|
||||
#
|
||||
# command-name:
|
||||
# String that denotes what type of object will be created if some output matches this pattern
|
||||
#
|
||||
# match-list:
|
||||
# file-or-line
|
||||
# match-list space file-or-line
|
||||
#
|
||||
# file-or-line:
|
||||
# "file" | "line"
|
||||
#
|
||||
# reg-ex:
|
||||
# A regular expression
|
||||
#
|
||||
# new-line:
|
||||
# The new-line character \n
|
||||
#
|
||||
# space:
|
||||
# The space character
|
||||
|
||||
|
|
@ -15,8 +15,12 @@ import java.text.DateFormat;
|
|||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
|
||||
import org.eclipse.core.runtime.ILog;
|
||||
import org.eclipse.core.runtime.IStatus;
|
||||
import org.eclipse.core.runtime.Platform;
|
||||
import org.eclipse.core.runtime.Plugin;
|
||||
import org.eclipse.core.runtime.Status;
|
||||
import org.eclipse.osgi.util.NLS;
|
||||
import org.osgi.framework.BundleContext;
|
||||
|
||||
|
||||
|
@ -61,7 +65,19 @@ public class Activator extends Plugin {
|
|||
public static Activator getDefault() {
|
||||
return plugin;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Logs an throwable to the log for this plugin.
|
||||
* @param t the Throwable to be logged.
|
||||
*/
|
||||
public void logException(Throwable t) {
|
||||
ILog log = getLog();
|
||||
String id = getBundle().getSymbolicName();
|
||||
String message = NLS.bind(SshServiceResources.SshPlugin_Unexpected_Exception, t.getClass().getName(), t.getLocalizedMessage());
|
||||
IStatus status = new Status(IStatus.ERROR, id, 0, message, t);
|
||||
log.log(status);
|
||||
}
|
||||
|
||||
//<tracing code>----------------------------------------------------
|
||||
|
||||
private static Boolean fTracingOn = null;
|
||||
|
|
|
@ -16,6 +16,8 @@ import org.eclipse.osgi.util.NLS;
|
|||
public class SshServiceResources extends NLS {
|
||||
private static final String BUNDLE_NAME = "org.eclipse.rse.services.ssh.SshServiceResources"; //$NON-NLS-1$
|
||||
|
||||
public static String SshPlugin_Unexpected_Exception;
|
||||
|
||||
public static String SftpFileService_Description;
|
||||
|
||||
public static String SftpFileService_Error_JschSessionLost;
|
||||
|
|
|
@ -9,6 +9,8 @@
|
|||
# Martin Oberhuber (Wind River) - initial API and implementation
|
||||
################################################################################
|
||||
|
||||
SshPlugin_Unexpected_Exception=Unexpected {0}: {1}
|
||||
|
||||
SftpFileService_Name=Ssh / Sftp File Service
|
||||
SftpFileService_Description=Access a remote file system via Ssh / Sftp protocol
|
||||
SftpFileService_Error_JschSessionLost=jsch session lost
|
||||
|
|
|
@ -0,0 +1,60 @@
|
|||
/********************************************************************************
|
||||
* Copyright (c) 2001, 2006 IBM Corporation and International Business Machines Corporation. All rights reserved.
|
||||
* This program and the accompanying materials are made available under the terms
|
||||
* of the Eclipse Public License v1.0 which accompanies this distribution, and is
|
||||
* available at http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Initial Contributors:
|
||||
* The following IBM employees contributed to the Remote System Explorer
|
||||
* component that contains this file: David McKnight, Kushal Munir,
|
||||
* Michael Berger, David Dykstal, Phil Coulthard, Don Yantzi, Eric Simpson,
|
||||
* Emily Bruner, Mazen Faraj, Adrian Storisteanu, Li Ding, and Kent Hawley.
|
||||
*
|
||||
* Contributors:
|
||||
* Martin Oberhuber (WindRiver) - adapted from services.local
|
||||
********************************************************************************/
|
||||
|
||||
package org.eclipse.rse.services.ssh.shell;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class CommandPattern
|
||||
{
|
||||
|
||||
|
||||
private Pattern _pattern;
|
||||
private ArrayList _outputPatterns;
|
||||
|
||||
public CommandPattern(Pattern theCommandPattern)
|
||||
{
|
||||
_pattern = theCommandPattern;
|
||||
_outputPatterns = new ArrayList();
|
||||
}
|
||||
|
||||
public void addOutputPattern(OutputPattern op)
|
||||
{
|
||||
_outputPatterns.add(op);
|
||||
}
|
||||
|
||||
public boolean matchCommand(String theLine)
|
||||
{
|
||||
return _pattern.matcher(theLine).matches();
|
||||
}
|
||||
|
||||
public ParsedOutput matchLine(String theLine)
|
||||
{
|
||||
int patterns = _outputPatterns.size();
|
||||
ParsedOutput matchedOutput;
|
||||
OutputPattern curPattern;
|
||||
for (int i = 0; i < patterns; i++)
|
||||
{
|
||||
curPattern = (OutputPattern) _outputPatterns.get(i);
|
||||
matchedOutput = curPattern.matchLine(theLine);
|
||||
if (matchedOutput != null)
|
||||
return matchedOutput;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,98 @@
|
|||
/********************************************************************************
|
||||
* Copyright (c) 2001, 2006 IBM Corporation and International Business Machines Corporation. All rights reserved.
|
||||
* This program and the accompanying materials are made available under the terms
|
||||
* of the Eclipse Public License v1.0 which accompanies this distribution, and is
|
||||
* available at http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Initial Contributors:
|
||||
* The following IBM employees contributed to the Remote System Explorer
|
||||
* component that contains this file: David McKnight, Kushal Munir,
|
||||
* Michael Berger, David Dykstal, Phil Coulthard, Don Yantzi, Eric Simpson,
|
||||
* Emily Bruner, Mazen Faraj, Adrian Storisteanu, Li Ding, and Kent Hawley.
|
||||
*
|
||||
* Contributors:
|
||||
* Martin Oberhuber (WindRiver) - adapted from services.local
|
||||
********************************************************************************/
|
||||
|
||||
package org.eclipse.rse.services.ssh.shell;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class OutputPattern
|
||||
{
|
||||
|
||||
|
||||
private Pattern _pattern;
|
||||
private String _objType;
|
||||
private ArrayList _matchOrder;
|
||||
|
||||
public OutputPattern(String objType, String matchOrder, Pattern thePattern)
|
||||
{
|
||||
_objType = objType;
|
||||
_pattern = thePattern;
|
||||
|
||||
_matchOrder = new ArrayList();
|
||||
//Here we add a dummy first element to the ArrayList, to mimick how the PatternMatcher stores it's
|
||||
//matches (starting with group 1).
|
||||
_matchOrder.add(null);
|
||||
|
||||
int index = 0;
|
||||
int nextSpace = 0;
|
||||
//Walk the matchOrder string parsing out words and adding them to _matchOrder...Could use StringTokenizer
|
||||
//but this seem much simpler.
|
||||
while ((nextSpace = matchOrder.indexOf(" ", index)) > 0) //$NON-NLS-1$
|
||||
{
|
||||
_matchOrder.add(matchOrder.substring(index, nextSpace).toLowerCase());
|
||||
index = nextSpace;
|
||||
while ((index < matchOrder.length()) && (matchOrder.charAt(index) == ' '))
|
||||
index++;
|
||||
}
|
||||
_matchOrder.add(matchOrder.substring(index, matchOrder.length()).toLowerCase());
|
||||
|
||||
}
|
||||
|
||||
public ParsedOutput matchLine(String theLine)
|
||||
{
|
||||
Matcher matcher = null;
|
||||
try
|
||||
{
|
||||
matcher = _pattern.matcher(theLine);
|
||||
if (!matcher.matches())
|
||||
return null;
|
||||
}
|
||||
catch (StringIndexOutOfBoundsException e)
|
||||
{
|
||||
//Getting an exception here, when theLine is an empty line for some patterns..should probably investigate,
|
||||
//but for now we'll just handle it...
|
||||
return null;
|
||||
}
|
||||
|
||||
String fileString = ""; //$NON-NLS-1$
|
||||
String lineString = ""; //$NON-NLS-1$
|
||||
//Groups start at 1 (group 0 is the entire match).
|
||||
for (int i = 1; i < _matchOrder.size(); i++)
|
||||
{
|
||||
String mStr = (String)_matchOrder.get(i);
|
||||
if (mStr.equals("file")) //$NON-NLS-1$
|
||||
fileString = matcher.group(i);
|
||||
else if (mStr.equals("line")) //$NON-NLS-1$
|
||||
lineString = matcher.group(i);
|
||||
}
|
||||
int line = 1;
|
||||
if (lineString.length() > 0)
|
||||
{
|
||||
try
|
||||
{
|
||||
line = Integer.parseInt(lineString);
|
||||
}
|
||||
catch (NumberFormatException e)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
return new ParsedOutput(_objType, theLine, fileString, line, 1);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
/********************************************************************************
|
||||
* Copyright (c) 2002, 2006 IBM Corporation. All rights reserved.
|
||||
* This program and the accompanying materials are made available under the terms
|
||||
* of the Eclipse Public License v1.0 which accompanies this distribution, and is
|
||||
* available at http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Initial Contributors:
|
||||
* The following IBM employees contributed to the Remote System Explorer
|
||||
* component that contains this file: David McKnight, Kushal Munir,
|
||||
* Michael Berger, David Dykstal, Phil Coulthard, Don Yantzi, Eric Simpson,
|
||||
* Emily Bruner, Mazen Faraj, Adrian Storisteanu, Li Ding, and Kent Hawley.
|
||||
*
|
||||
* Contributors:
|
||||
* Martin Oberhuber (WindRiver) - adapted from services.local
|
||||
********************************************************************************/
|
||||
|
||||
package org.eclipse.rse.services.ssh.shell;
|
||||
|
||||
//This is just a convenience object for storing information parsed out of a line of output.
|
||||
public class ParsedOutput
|
||||
{
|
||||
|
||||
|
||||
public String type;
|
||||
public String text;
|
||||
public String file;
|
||||
public int line;
|
||||
public int col;
|
||||
|
||||
public ParsedOutput (String theType, String theText, String theFile, int theLine, int theColumn)
|
||||
{
|
||||
type = theType;
|
||||
text = theText;
|
||||
file = theFile;
|
||||
line = theLine;
|
||||
col = theColumn;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,121 @@
|
|||
/********************************************************************************
|
||||
* Copyright (c) 2002, 2006 IBM Corporation. All rights reserved.
|
||||
* This program and the accompanying materials are made available under the terms
|
||||
* of the Eclipse Public License v1.0 which accompanies this distribution, and is
|
||||
* available at http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Initial Contributors:
|
||||
* The following IBM employees contributed to the Remote System Explorer
|
||||
* component that contains this file: David McKnight, Kushal Munir,
|
||||
* Michael Berger, David Dykstal, Phil Coulthard, Don Yantzi, Eric Simpson,
|
||||
* Emily Bruner, Mazen Faraj, Adrian Storisteanu, Li Ding, and Kent Hawley.
|
||||
*
|
||||
* Contributors:
|
||||
* Martin Oberhuber (WindRiver) - adapted from services.local
|
||||
********************************************************************************/
|
||||
package org.eclipse.rse.services.ssh.shell;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.osgi.framework.Bundle;
|
||||
|
||||
import org.eclipse.rse.services.ssh.Activator;
|
||||
|
||||
public class Patterns {
|
||||
private ArrayList _theCommands;
|
||||
private String _currentCommand;
|
||||
|
||||
public Patterns() {
|
||||
_theCommands = new ArrayList();
|
||||
parsePatterns();
|
||||
}
|
||||
|
||||
private void parsePatterns() {
|
||||
Bundle bundle = Activator.getDefault().getBundle();
|
||||
URL patterns = bundle.getEntry("/patterns.dat"); //$NON-NLS-1$
|
||||
if (patterns != null) {
|
||||
try {
|
||||
InputStream in = patterns.openStream();
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
|
||||
_theCommands.clear();
|
||||
String curLine;
|
||||
CommandPattern curCommand = null;
|
||||
while ((curLine = reader.readLine()) != null) {
|
||||
curLine = curLine.trim();
|
||||
// Skip the current line if it is empty or starts with a #
|
||||
if ((curLine.length() == 0) || (curLine.charAt(0) == '#')) {
|
||||
continue;
|
||||
}
|
||||
// Check if this line is the start of a new command section
|
||||
if (curLine.startsWith("command")) { //$NON-NLS-1$
|
||||
int colon = curLine.indexOf(":"); //$NON-NLS-1$
|
||||
// Check that there is something after the colon
|
||||
if (colon == (curLine.length() - 1)) {
|
||||
continue;
|
||||
}
|
||||
Pattern thePattern = Pattern.compile(curLine.substring(colon + 1, curLine.length()).trim());
|
||||
curCommand = new CommandPattern(thePattern);
|
||||
_theCommands.add(curCommand);
|
||||
}
|
||||
// If we get here, the line must be an output pattern
|
||||
else {
|
||||
int firstSpace = curLine.indexOf(" "); //$NON-NLS-1$
|
||||
int patternWord = curLine.indexOf("pattern"); //$NON-NLS-1$
|
||||
int firstEquals = curLine.indexOf("="); //$NON-NLS-1$
|
||||
if ((firstEquals == -1) || (firstEquals == (curLine.length() - 1))) {
|
||||
continue;
|
||||
}
|
||||
String objType = curLine.substring(0, firstSpace);
|
||||
String matchOrder = curLine.substring(firstSpace + 1, patternWord).trim();
|
||||
String patternString = curLine.substring(firstEquals + 1, curLine.length());
|
||||
Pattern thePattern = Pattern.compile(patternString.trim());
|
||||
if (curCommand != null) {
|
||||
curCommand.addOutputPattern(new OutputPattern(objType, matchOrder, thePattern));
|
||||
}
|
||||
}
|
||||
}
|
||||
in.close();
|
||||
} catch (IOException e) {
|
||||
Activator.getDefault().logException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void refresh(String theCommand) {
|
||||
_currentCommand = theCommand;
|
||||
parsePatterns();
|
||||
}
|
||||
|
||||
public void update(String theCommand) {
|
||||
_currentCommand = theCommand;
|
||||
}
|
||||
|
||||
public ParsedOutput matchLine(String theLine) {
|
||||
CommandPattern curCommand;
|
||||
ParsedOutput matchedOutput = null;
|
||||
int commands = _theCommands.size();
|
||||
if (_currentCommand != null)
|
||||
{
|
||||
|
||||
for (int i = 0; i < commands; i++)
|
||||
{
|
||||
curCommand = (CommandPattern) _theCommands.get(i);
|
||||
if (curCommand.matchCommand(_currentCommand))
|
||||
{
|
||||
matchedOutput = curCommand.matchLine(theLine);
|
||||
}
|
||||
if (matchedOutput != null)
|
||||
{
|
||||
return matchedOutput;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -20,6 +20,7 @@ import java.io.BufferedReader;
|
|||
import java.io.InputStreamReader;
|
||||
import java.io.OutputStream;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.eclipse.core.runtime.IProgressMonitor;
|
||||
|
||||
|
@ -66,7 +67,10 @@ public class SshHostShell extends AbstractHostShell implements IHostShell {
|
|||
PrintWriter outputWriter = new PrintWriter(outputStream);
|
||||
fShellWriter = new SshShellWriterThread(outputWriter);
|
||||
fChannel.connect();
|
||||
if (initialWorkingDirectory!=null && initialWorkingDirectory.length()>0 && !initialWorkingDirectory.equals(".")) { //$NON-NLS-1$
|
||||
if (initialWorkingDirectory!=null && initialWorkingDirectory.length()>0
|
||||
&& !initialWorkingDirectory.equals(".") //$NON-NLS-1$
|
||||
&& !initialWorkingDirectory.equals("Command Shell") //$NON-NLS-1$ //FIXME workaround for bug 153047
|
||||
) {
|
||||
writeToShell("cd "+initialWorkingDirectory); //$NON-NLS-1$
|
||||
}
|
||||
} catch(Exception e) {
|
||||
|
|
|
@ -20,9 +20,6 @@ package org.eclipse.rse.services.ssh.shell;
|
|||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
|
||||
import org.eclipse.core.runtime.IStatus;
|
||||
import org.eclipse.core.runtime.Status;
|
||||
|
||||
import org.eclipse.rse.services.shells.AbstractHostShellOutputReader;
|
||||
import org.eclipse.rse.services.shells.IHostShell;
|
||||
import org.eclipse.rse.services.shells.IHostShellOutputReader;
|
||||
|
@ -142,8 +139,7 @@ public class SshShellOutputReader extends AbstractHostShellOutputReader
|
|||
//FIXME it's dangerous to return null here since this will end
|
||||
//our reader thread completely... the exception could just be
|
||||
//temporary, and we should keep running!
|
||||
Activator.getDefault().getLog().log(new Status(IStatus.WARNING, Activator.getDefault().getBundle().getSymbolicName(), 0, "IOException in SshShellOutputReader", e));
|
||||
//e.printStackTrace();
|
||||
Activator.getDefault().logException(e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@ Require-Bundle: org.eclipse.ui,
|
|||
org.eclipse.rse.connectorservice.ssh,
|
||||
org.eclipse.rse.services.ssh,
|
||||
org.eclipse.rse.subsystems.shells.core,
|
||||
org.eclipse.rse.subsystems.files.core,
|
||||
org.eclipse.rse.shells.ui,
|
||||
org.eclipse.rse.ui
|
||||
Eclipse-LazyStart: true
|
||||
|
|
|
@ -0,0 +1,161 @@
|
|||
/********************************************************************************
|
||||
* Copyright (c) 2006 IBM Corporation. All rights reserved.
|
||||
* This program and the accompanying materials are made available under the terms
|
||||
* of the Eclipse Public License v1.0 which accompanies this distribution, and is
|
||||
* available at http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Initial Contributors:
|
||||
* The following IBM employees contributed to the Remote System Explorer
|
||||
* component that contains this file: David McKnight, Kushal Munir,
|
||||
* Michael Berger, David Dykstal, Phil Coulthard, Don Yantzi, Eric Simpson,
|
||||
* Emily Bruner, Mazen Faraj, Adrian Storisteanu, Li Ding, and Kent Hawley.
|
||||
*
|
||||
* Contributors:
|
||||
* Martin Oberhuber (Wind River) - Adapted from LocalServiceCommandShell
|
||||
********************************************************************************/
|
||||
|
||||
package org.eclipse.rse.subsystems.shells.ssh;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.eclipse.core.runtime.IPath;
|
||||
import org.eclipse.core.runtime.Path;
|
||||
|
||||
import org.eclipse.rse.core.subsystems.ISubSystem;
|
||||
import org.eclipse.rse.internal.subsystems.shells.servicesubsystem.OutputRefreshJob;
|
||||
import org.eclipse.rse.internal.subsystems.shells.subsystems.RemoteError;
|
||||
import org.eclipse.rse.internal.subsystems.shells.subsystems.RemoteOutput;
|
||||
import org.eclipse.rse.services.shells.IHostShell;
|
||||
import org.eclipse.rse.services.shells.IHostShellChangeEvent;
|
||||
import org.eclipse.rse.services.ssh.shell.ParsedOutput;
|
||||
import org.eclipse.rse.services.ssh.shell.Patterns;
|
||||
import org.eclipse.rse.subsystems.files.core.subsystems.IRemoteFileSubSystem;
|
||||
import org.eclipse.rse.subsystems.shells.core.model.ISystemOutputRemoteTypes;
|
||||
import org.eclipse.rse.subsystems.shells.core.subsystems.IRemoteCmdSubSystem;
|
||||
import org.eclipse.rse.subsystems.shells.core.subsystems.IRemoteOutput;
|
||||
import org.eclipse.rse.subsystems.shells.core.subsystems.servicesubsystem.ServiceCommandShell;
|
||||
|
||||
public class SshServiceCommandShell extends ServiceCommandShell implements ISystemOutputRemoteTypes
|
||||
{
|
||||
private Patterns _patterns;
|
||||
private String _curCommand;
|
||||
private String _workingDir;
|
||||
private IRemoteFileSubSystem _fs;
|
||||
|
||||
public SshServiceCommandShell(IRemoteCmdSubSystem cmdSS, IHostShell hostShell)
|
||||
{
|
||||
super(cmdSS, hostShell);
|
||||
_patterns = new Patterns();
|
||||
_patterns.update("cmd"); //$NON-NLS-1$
|
||||
ISubSystem[] sses = cmdSS.getHost().getSubSystems();
|
||||
for (int i = 0; i < sses.length; i++)
|
||||
{
|
||||
if (sses[i] instanceof IRemoteFileSubSystem)
|
||||
{
|
||||
_fs = (IRemoteFileSubSystem)sses[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Object getContext()
|
||||
{
|
||||
String workingDir = _workingDir;
|
||||
if (workingDir != null && workingDir.length() > 0)
|
||||
{
|
||||
try
|
||||
{
|
||||
return _fs.getRemoteFileObject(workingDir);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
}
|
||||
}
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
public void shellOutputChanged(IHostShellChangeEvent event)
|
||||
{
|
||||
Object[] lines = event.getLines();
|
||||
boolean gotCommand = false;
|
||||
ArrayList outputs = new ArrayList(lines.length);
|
||||
for (int i = 0; i < lines.length; i++)
|
||||
{
|
||||
String line = (String)lines[i];
|
||||
if (line.endsWith(getPromptCommand())) {
|
||||
continue; //ignore our synthetic prompt command
|
||||
}
|
||||
|
||||
ParsedOutput parsedMsg = null;
|
||||
if (!gotCommand && line.equals(_curCommand)) {
|
||||
gotCommand = true;
|
||||
} else {
|
||||
try {
|
||||
parsedMsg = _patterns.matchLine(line);
|
||||
}
|
||||
catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
RemoteOutput output = null;
|
||||
String type = "stdout"; //$NON-NLS-1$
|
||||
if (parsedMsg != null) {
|
||||
type = parsedMsg.type;
|
||||
}
|
||||
if (event.isError()) {
|
||||
output = new RemoteError(this, type);
|
||||
}
|
||||
else {
|
||||
output = new RemoteOutput(this, type);
|
||||
}
|
||||
|
||||
output.setText(line);
|
||||
if (parsedMsg != null)
|
||||
{
|
||||
String file = parsedMsg.file;
|
||||
if (type.equals("prompt")) //$NON-NLS-1$
|
||||
{
|
||||
_workingDir = file;
|
||||
output.setAbsolutePath(_workingDir);
|
||||
}
|
||||
else if(_workingDir!=null)
|
||||
{
|
||||
IPath p = new Path(_workingDir).append(file);
|
||||
output.setAbsolutePath(p.toString());
|
||||
}
|
||||
else
|
||||
{
|
||||
output.setAbsolutePath(file);
|
||||
}
|
||||
}
|
||||
|
||||
addOutput(output);
|
||||
outputs.add(output);
|
||||
}
|
||||
if (_lastRefreshJob == null || _lastRefreshJob.isComplete())
|
||||
{
|
||||
IRemoteOutput[] remoteOutputs = (IRemoteOutput[])outputs.toArray(new IRemoteOutput[outputs.size()]);
|
||||
_lastRefreshJob = new OutputRefreshJob(this, remoteOutputs, false);
|
||||
_lastRefreshJob.schedule();
|
||||
}
|
||||
}
|
||||
|
||||
private static final Pattern cdCommands = Pattern.compile("\\A\\s*(cd|chdir|ls)\\b"); //$NON-NLS-1$
|
||||
|
||||
protected String getPromptCommand() {
|
||||
return "echo $PWD'>'"; //$NON-NLS-1$
|
||||
}
|
||||
|
||||
public void writeToShell(String cmd)
|
||||
{
|
||||
_curCommand = cmd;
|
||||
_patterns.update(cmd);
|
||||
if (cdCommands.matcher(cmd).find()) {
|
||||
cmd += "\r\n" + getPromptCommand(); //$NON-NLS-1$
|
||||
}
|
||||
super.writeToShell(cmd);
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -21,9 +21,12 @@ import org.eclipse.rse.connectorservice.ssh.SshConnectorServiceManager;
|
|||
import org.eclipse.rse.core.subsystems.IConnectorService;
|
||||
import org.eclipse.rse.core.subsystems.ISubSystem;
|
||||
import org.eclipse.rse.model.IHost;
|
||||
import org.eclipse.rse.services.shells.IHostShell;
|
||||
import org.eclipse.rse.services.shells.IShellService;
|
||||
import org.eclipse.rse.services.ssh.ISshService;
|
||||
import org.eclipse.rse.services.ssh.shell.SshShellService;
|
||||
import org.eclipse.rse.subsystems.shells.core.subsystems.IRemoteCmdSubSystem;
|
||||
import org.eclipse.rse.subsystems.shells.core.subsystems.servicesubsystem.IServiceCommandShell;
|
||||
import org.eclipse.rse.subsystems.shells.core.subsystems.servicesubsystem.ShellServiceSubSystem;
|
||||
import org.eclipse.rse.subsystems.shells.core.subsystems.servicesubsystem.ShellServiceSubSystemConfiguration;
|
||||
|
||||
|
@ -72,4 +75,9 @@ public class SshShellSubSystemConfiguration extends
|
|||
return ISshService.class;
|
||||
}
|
||||
|
||||
public IServiceCommandShell createRemoteCommandShell(IRemoteCmdSubSystem cmdSS, IHostShell hostShell)
|
||||
{
|
||||
return new SshServiceCommandShell(cmdSS, hostShell);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue