You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@felix.apache.org by gn...@apache.org on 2009/07/07 19:18:27 UTC

svn commit: r791913 - in /felix/trunk/gogo: commands/src/main/java/org/apache/felix/gogo/commands/basic/ commands/src/test/java/org/apache/felix/gogo/commands/ runtime/src/main/java/org/apache/felix/gogo/runtime/osgi/ runtime/src/main/java/org/apache/f...

Author: gnodet
Date: Tue Jul  7 17:18:26 2009
New Revision: 791913

URL: http://svn.apache.org/viewvc?rev=791913&view=rev
Log:
FELIX-1304: Better support for variables evaluation in arguments

Added:
    felix/trunk/gogo/commands/src/test/java/org/apache/felix/gogo/commands/Context.java
      - copied, changed from r791864, felix/trunk/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/shell/Context.java
    felix/trunk/gogo/runtime/src/test/java/org/apache/felix/gogo/runtime/shell/Context.java
      - copied, changed from r791864, felix/trunk/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/shell/Context.java
Removed:
    felix/trunk/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/shell/Context.java
Modified:
    felix/trunk/gogo/commands/src/main/java/org/apache/felix/gogo/commands/basic/AbstractCommand.java
    felix/trunk/gogo/commands/src/main/java/org/apache/felix/gogo/commands/basic/ActionPreparator.java
    felix/trunk/gogo/commands/src/main/java/org/apache/felix/gogo/commands/basic/DefaultActionPreparator.java
    felix/trunk/gogo/commands/src/test/java/org/apache/felix/gogo/commands/TestCommands.java
    felix/trunk/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/osgi/OSGiCommands.java
    felix/trunk/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/osgi/OSGiShell.java
    felix/trunk/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/osgi/ServiceCommand.java
    felix/trunk/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/shell/Closure.java
    felix/trunk/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/shell/CommandSessionImpl.java
    felix/trunk/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/shell/CommandShellImpl.java
    felix/trunk/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/shell/Parser.java
    felix/trunk/gogo/runtime/src/test/java/org/apache/felix/gogo/runtime/shell/TestParser.java

Modified: felix/trunk/gogo/commands/src/main/java/org/apache/felix/gogo/commands/basic/AbstractCommand.java
URL: http://svn.apache.org/viewvc/felix/trunk/gogo/commands/src/main/java/org/apache/felix/gogo/commands/basic/AbstractCommand.java?rev=791913&r1=791912&r2=791913&view=diff
==============================================================================
--- felix/trunk/gogo/commands/src/main/java/org/apache/felix/gogo/commands/basic/AbstractCommand.java (original)
+++ felix/trunk/gogo/commands/src/main/java/org/apache/felix/gogo/commands/basic/AbstractCommand.java Tue Jul  7 17:18:26 2009
@@ -30,8 +30,11 @@
 
     public Object execute(CommandSession session, List<Object> arguments) throws Exception {
         Action action = createNewAction();
-        getPreparator().prepare(action, session, arguments);
-        return action.execute(session);
+        if (getPreparator().prepare(action, session, arguments)) {
+            return action.execute(session);
+        } else {
+            return null;
+        }
     }
 
     protected abstract Action createNewAction() throws Exception;

Modified: felix/trunk/gogo/commands/src/main/java/org/apache/felix/gogo/commands/basic/ActionPreparator.java
URL: http://svn.apache.org/viewvc/felix/trunk/gogo/commands/src/main/java/org/apache/felix/gogo/commands/basic/ActionPreparator.java?rev=791913&r1=791912&r2=791913&view=diff
==============================================================================
--- felix/trunk/gogo/commands/src/main/java/org/apache/felix/gogo/commands/basic/ActionPreparator.java (original)
+++ felix/trunk/gogo/commands/src/main/java/org/apache/felix/gogo/commands/basic/ActionPreparator.java Tue Jul  7 17:18:26 2009
@@ -7,6 +7,6 @@
 
 public interface ActionPreparator {
 
-    void prepare(Action action, CommandSession session, List<Object> arguments) throws Exception;
+    boolean prepare(Action action, CommandSession session, List<Object> arguments) throws Exception;
 
 }

Modified: felix/trunk/gogo/commands/src/main/java/org/apache/felix/gogo/commands/basic/DefaultActionPreparator.java
URL: http://svn.apache.org/viewvc/felix/trunk/gogo/commands/src/main/java/org/apache/felix/gogo/commands/basic/DefaultActionPreparator.java?rev=791913&r1=791912&r2=791913&view=diff
==============================================================================
--- felix/trunk/gogo/commands/src/main/java/org/apache/felix/gogo/commands/basic/DefaultActionPreparator.java (original)
+++ felix/trunk/gogo/commands/src/main/java/org/apache/felix/gogo/commands/basic/DefaultActionPreparator.java Tue Jul  7 17:18:26 2009
@@ -72,7 +72,7 @@
         }
     };
 
-    public void prepare(Action action, CommandSession session, List<Object> params) throws Exception
+    public boolean prepare(Action action, CommandSession session, List<Object> params) throws Exception
     {
         Map<Option, Field> options = new HashMap<Option, Field>();
         Map<Argument, Field> arguments = new HashMap<Argument, Field>();
@@ -114,7 +114,7 @@
             // Check for help
             if (HELP.name().equals(param) || Arrays.asList(HELP.aliases()).contains(param)) {
                 printUsage(action.getClass().getAnnotation(Command.class), options.keySet(), arguments.keySet(), System.out);
-                return;
+                return false;
             }
             if (processOptions && param instanceof String && ((String) param).startsWith("-")) {
                 boolean isKeyValuePair = ((String) param).indexOf('=') != -1;
@@ -201,6 +201,7 @@
             field.setAccessible(true);
             field.set(action, value);
         }
+        return true;
     }
 
     protected void printUsage(Command command, Set<Option> options, Set<Argument> arguments, PrintStream out)

Copied: felix/trunk/gogo/commands/src/test/java/org/apache/felix/gogo/commands/Context.java (from r791864, felix/trunk/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/shell/Context.java)
URL: http://svn.apache.org/viewvc/felix/trunk/gogo/commands/src/test/java/org/apache/felix/gogo/commands/Context.java?p2=felix/trunk/gogo/commands/src/test/java/org/apache/felix/gogo/commands/Context.java&p1=felix/trunk/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/shell/Context.java&r1=791864&r2=791913&rev=791913&view=diff
==============================================================================
--- felix/trunk/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/shell/Context.java (original)
+++ felix/trunk/gogo/commands/src/test/java/org/apache/felix/gogo/commands/Context.java Tue Jul  7 17:18:26 2009
@@ -16,9 +16,11 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.felix.gogo.runtime.shell;
+package org.apache.felix.gogo.commands;
 
 import org.apache.felix.gogo.runtime.threadio.ThreadIOImpl;
+import org.apache.felix.gogo.runtime.shell.CommandShellImpl;
+import org.apache.felix.gogo.runtime.shell.CommandSessionImpl;
 
 public class Context extends CommandShellImpl
 {
@@ -48,5 +50,10 @@
         put("test:" + name, target);
     }
 
+    public void set(String name, Object value)
+    {
+        session.put(name, value);
+    }
+
 
-}
+}
\ No newline at end of file

Modified: felix/trunk/gogo/commands/src/test/java/org/apache/felix/gogo/commands/TestCommands.java
URL: http://svn.apache.org/viewvc/felix/trunk/gogo/commands/src/test/java/org/apache/felix/gogo/commands/TestCommands.java?rev=791913&r1=791912&r2=791913&view=diff
==============================================================================
--- felix/trunk/gogo/commands/src/test/java/org/apache/felix/gogo/commands/TestCommands.java (original)
+++ felix/trunk/gogo/commands/src/test/java/org/apache/felix/gogo/commands/TestCommands.java Tue Jul  7 17:18:26 2009
@@ -27,12 +27,21 @@
 
 import junit.framework.TestCase;
 import org.osgi.service.command.CommandSession;
-import org.apache.felix.gogo.runtime.shell.Context;
 import org.apache.felix.gogo.commands.basic.SimpleCommand;
 
 public class TestCommands extends TestCase {
 
 
+    public void testPrompt() throws Exception {
+        Context c = new Context();
+        c.addCommand("echo", this);
+        c.set("USER", "gnodet");
+        c.set("APPLICATION", "karaf");
+        //c.set("SCOPE", "");
+        Object p = c.execute("\"@|bold ${USER}|@${APPLICATION}:@|bold ${SCOPE}|> \"");
+        System.out.println("Prompt: " + p);
+    }
+
     public void testCommand() throws Exception {
         Context c= new Context();
         c.addCommand("capture", this);
@@ -85,6 +94,27 @@
         return sw.toString();
     }
 
+    public CharSequence echo(Object args[])
+    {
+        if (args == null)
+        {
+            return "";
+        }
+
+        StringBuilder sb = new StringBuilder();
+        String del = "";
+        for (Object arg : args)
+        {
+            sb.append(del);
+            if (arg != null)
+            {
+                sb.append(arg);
+                del = " ";
+            }
+        }
+        return sb;
+    }
+
     @Command(scope = "test", name = "my-action", description = "My Action")
     public static class MyAction implements Action
     {

Modified: felix/trunk/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/osgi/OSGiCommands.java
URL: http://svn.apache.org/viewvc/felix/trunk/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/osgi/OSGiCommands.java?rev=791913&r1=791912&r2=791913&view=diff
==============================================================================
--- felix/trunk/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/osgi/OSGiCommands.java (original)
+++ felix/trunk/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/osgi/OSGiCommands.java Tue Jul  7 17:18:26 2009
@@ -48,7 +48,8 @@
 
     public BundleContext getContext()
     {
-        if (bundle.getState() != Bundle.ACTIVE)
+        if (bundle.getState() != Bundle.ACTIVE && bundle.getState() != Bundle.STARTING
+                && bundle.getState() != Bundle.STOPPING)
         {
             throw new IllegalStateException("Framework is not started yet");
         }

Modified: felix/trunk/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/osgi/OSGiShell.java
URL: http://svn.apache.org/viewvc/felix/trunk/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/osgi/OSGiShell.java?rev=791913&r1=791912&r2=791913&view=diff
==============================================================================
--- felix/trunk/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/osgi/OSGiShell.java (original)
+++ felix/trunk/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/osgi/OSGiShell.java Tue Jul  7 17:18:26 2009
@@ -40,7 +40,7 @@
         addCommand("osgi", this.bundle);
         addCommand("osgi", commands);
         setConverter(commands);
-        if (bundle.getState() == Bundle.ACTIVE)
+        if (bundle.getState() == Bundle.ACTIVE || bundle.getState() == Bundle.STARTING)
         {
             addCommand("osgi", commands.service(PackageAdmin.class.getName(), null), PackageAdmin.class);
             addCommand("osgi", commands.getContext(), BundleContext.class);

Modified: felix/trunk/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/osgi/ServiceCommand.java
URL: http://svn.apache.org/viewvc/felix/trunk/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/osgi/ServiceCommand.java?rev=791913&r1=791912&r2=791913&view=diff
==============================================================================
--- felix/trunk/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/osgi/ServiceCommand.java (original)
+++ felix/trunk/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/osgi/ServiceCommand.java Tue Jul  7 17:18:26 2009
@@ -44,13 +44,19 @@
         try
         {
             Object target = shell.bundle.getBundleContext().getService(ref);
-            Object result = method(session, target, name, arguments);
-            if (result != CommandShellImpl.NO_SUCH_COMMAND)
+            if (target instanceof Function)
             {
-                return result;
+                return ((Function) target).execute(session, arguments);
+            }
+            else
+            {
+                Object result = method(session, target, name, arguments);
+                if (result != CommandShellImpl.NO_SUCH_COMMAND)
+                {
+                    return result;
+                }
+                throw new IllegalArgumentException("Service does not implement promised command " + ref + " " + name);
             }
-
-            throw new IllegalArgumentException("Service does not implement promised command " + ref + " " + name);
         }
         finally
         {

Modified: felix/trunk/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/shell/Closure.java
URL: http://svn.apache.org/viewvc/felix/trunk/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/shell/Closure.java?rev=791913&r1=791912&r2=791913&view=diff
==============================================================================
--- felix/trunk/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/shell/Closure.java (original)
+++ felix/trunk/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/shell/Closure.java Tue Jul  7 17:18:26 2009
@@ -106,22 +106,23 @@
         CharSequence statement0 = statement.remove(0);
 
         // derek: FEATURE: add set -x facility if echo is set
-        StringBuilder buf = new StringBuilder("+ ");
-        buf.append(statement0);
+        if (Boolean.TRUE.equals(session.get("echo"))) {
+            StringBuilder buf = new StringBuilder("+ ");
+            buf.append(statement0);
+            for (CharSequence token : statement)
+            {
+                buf.append(' ');
+                buf.append(token);
+            }
+            System.err.println(buf);
+        }
 
         Object cmd = eval(statement0);
         for (CharSequence token : statement)
         {
-            buf.append(' ');
-            buf.append(token);
             values.add(eval(token));
         }
 
-        if (Boolean.TRUE.equals(session.get("echo")))
-        {
-            System.err.println(buf);
-        }
-
         result = execute(cmd, values);
         return result;
     }
@@ -207,36 +208,87 @@
 
     private Object eval(CharSequence seq) throws Exception
     {
-        int end = seq.length();
-        switch (seq.charAt(0))
-        {
-            case '$':
-                return var(seq);
-            case '<':
-                Closure c = new Closure(session, this, seq.subSequence(1, end - 1));
-                return c.execute(session, parms);
-            case '[':
-                return array(seq.subSequence(1, end - 1));
-
-            case '{':
-                return new Closure(session, this, seq.subSequence(1, end - 1));
-
-            default:
-                String result = new Parser(seq).unescape();
-                if ("null".equals(result))
-                {
-                    return null;
-                }
-                if ("true".equalsIgnoreCase(result))
-                {
-                    return true;
+        Object res = null;
+        StringBuilder sb = null;
+        Parser p = new Parser(seq);
+        int start = p.current;
+        while (!p.eof()) {
+            char c = p.peek();
+            if (!p.escaped) {
+                if (c == '$' || c == '<' || c == '\'' || c == '"' || c == '[' || c == '{') {
+                    if (start != p.current || res != null) {
+                        if (sb == null) {
+                            sb = new StringBuilder();
+                            if (res != null) {
+                                sb.append(res);
+                                res = null;
+                            }
+                        }
+                        if (start != p.current) {
+                            sb.append(new Parser(p.text.subSequence(start, p.current)).unescape());
+                            start = p.current;
+                            continue;
+                        }
+                    }
+                    switch (c) {
+                        case '\'':
+                            p.next();
+                            p.quote(c);
+                            res = new Parser(p.text.subSequence(start + 1, p.current - 1)).unescape();
+                            start = p.current;
+                            continue;
+                        case '\"':
+                            p.next();
+                            p.quote(c);
+                            res = eval(p.text.subSequence(start + 1, p.current - 1));
+                            start = p.current;
+                            continue;
+                        case '[':
+                            p.next();
+                            res = array(seq.subSequence(start + 1, p.find(']', '[') - 1));
+                            start = p.current;
+                            continue;
+                        case '<':
+                            p.next();
+                            Closure cl = new Closure(session, this, p.text.subSequence(start + 1, p.find('>', '<') - 1));
+                            res = cl.execute(session, parms);
+                            start = p.current;
+                            continue;
+                        case '{':
+                            p.next();
+                            res = new Closure(session, this, p.text.subSequence(start + 1, p.find('}', '{') - 1));
+                            start = p.current;
+                            continue;
+                        case '$':
+                            p.next();
+                            res = var(p.findVar());
+                            start = p.current;
+                            continue;
+                    }
                 }
-                if ("false".equalsIgnoreCase(result))
-                {
-                    return false;
+            }
+            p.next();
+        }
+        if (start != p.current) {
+            if (sb == null) {
+                sb = new StringBuilder();
+                if (res != null) {
+                    sb.append(res);
+                    res = null;
                 }
-                return result;
+            }
+            sb.append(new Parser(p.text.subSequence(start, p.current)).unescape());
+        }
+        if (sb != null) {
+            if (res != null) {
+                sb.append(res);
+            }
+            return sb.toString();
+        }
+        if (res instanceof CharSequence) {
+            return res.toString();
         }
+        return res;
     }
 
     private Object array(CharSequence array) throws Exception
@@ -294,7 +346,11 @@
 
     private Object var(CharSequence var) throws Exception
     {
-        String name = eval(var.subSequence(1, var.length())).toString();
+        Object v = eval(var);
+        if (v instanceof Closure) {
+            v = ((Closure) v).execute(session, null);
+        }
+        String name = v.toString();
         return get(name);
     }
 

Modified: felix/trunk/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/shell/CommandSessionImpl.java
URL: http://svn.apache.org/viewvc/felix/trunk/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/shell/CommandSessionImpl.java?rev=791913&r1=791912&r2=791913&view=diff
==============================================================================
--- felix/trunk/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/shell/CommandSessionImpl.java (original)
+++ felix/trunk/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/shell/CommandSessionImpl.java Tue Jul  7 17:18:26 2009
@@ -32,12 +32,16 @@
 
 public class CommandSessionImpl implements CommandSession, Converter
 {
-    String COLUMN = "%-20s %s\n";
+    public static final String VARIABLES = ".variables";
+    public static final String COMMANDS = ".commands";
+
+    private static final String COLUMN = "%-20s %s\n";
+
     InputStream in;
     PrintStream out;
     PrintStream err;
     CommandShellImpl service;
-    Map<Object, Object> variables = new HashMap<Object, Object>();
+    final Map<Object, Object> variables = new HashMap<Object, Object>();
     private boolean closed;    // derek
 
     CommandSessionImpl(CommandShellImpl service, InputStream in, PrintStream out, PrintStream err)
@@ -77,12 +81,16 @@
     {
         // XXX: derek.baum@paremus.com
         // there is no API to list all variables, so overload name == null
-        if (name == null)
+        if (name == null || VARIABLES.equals(name))
         {
             return variables.keySet();
         }
+        if (COMMANDS.equals(name))
+        {
+            return service.get(null);
+        }
 
-        if (variables != null && variables.containsKey(name))
+        if (variables.containsKey(name))
         {
             return variables.get(name);
         }

Modified: felix/trunk/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/shell/CommandShellImpl.java
URL: http://svn.apache.org/viewvc/felix/trunk/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/shell/CommandShellImpl.java?rev=791913&r1=791912&r2=791913&view=diff
==============================================================================
--- felix/trunk/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/shell/CommandShellImpl.java (original)
+++ felix/trunk/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/shell/CommandShellImpl.java Tue Jul  7 17:18:26 2009
@@ -68,6 +68,10 @@
 
     public Object get(String name)
     {
+        if (name == null)
+        {
+            return commands.keySet();
+        }
         name = name.toLowerCase();
         int n = name.indexOf(':');
         if (n < 0)

Modified: felix/trunk/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/shell/Parser.java
URL: http://svn.apache.org/viewvc/felix/trunk/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/shell/Parser.java?rev=791913&r1=791912&r2=791913&view=diff
==============================================================================
--- felix/trunk/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/shell/Parser.java (original)
+++ felix/trunk/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/shell/Parser.java Tue Jul  7 17:18:26 2009
@@ -39,9 +39,9 @@
     {
         // derek: BUGFIX: loop if comment  at beginning of input
         //while (!eof() && Character.isWhitespace(peek())) {
-        while (!eof() && (Character.isWhitespace(peek()) || current == 0))
+        while (!eof() && (!escaped && Character.isWhitespace(peek()) || current == 0))
         {
-            if (current != 0 || Character.isWhitespace(peek()))
+            if (current != 0 || !escaped && Character.isWhitespace(peek()))
             {
                 current++;
             }
@@ -203,7 +203,7 @@
             while (!eof())
             {
                 c = peek();
-                if (c == ';' || c == '|' || Character.isWhitespace(c))
+                if (!escaped && (c == ';' || c == '|' || Character.isWhitespace(c)))
                 {
                     break;
                 }
@@ -232,17 +232,13 @@
                     return text.subSequence(start, find(')', '('));
                 case '[':
                     return text.subSequence(start, find(']', '['));
-                case '"':
-                    return text.subSequence(start + 1, quote('"'));
-                case '\'':
-                    return text.subSequence(start + 1, quote('\''));
                 case '<':
                     return text.subSequence(start, find('>', '<'));
-                case '$':
-                    value();
-                    return text.subSequence(start, current);
                 case '=':
                     return text.subSequence(start, current);
+                case '"':
+                case '\'':
+                    quote(c); break;
             }
         }
 
@@ -250,15 +246,35 @@
         while (!eof())
         {
             c = peek();
-            if ((!escaped && SPECIAL.indexOf(c) >= 0) || Character.isWhitespace(c))
+            if (!escaped)
             {
-                break;
+                if (Character.isWhitespace(c) || c == ';' || c =='|' || c == '=') {
+                    break;
+                } else if (c == '{') {
+                    next(); find('}', '{');
+                } else if (c == '(') {
+                    next(); find(')', '(');
+                } else if (c == '<') {
+                    next(); find('>', '<');
+                } else if (c == '[') {
+                    next(); find(']', '[');
+                } else if (c == '\'' || c == '"') {
+                    next(); quote(c); next();
+                } else {
+                    next();
+                }
+            } else {
+                next();
             }
-            next();
         }
         return text.subSequence(start, current);
     }
 
+    boolean escaped()
+    {
+        return escaped;
+    }
+
     char next()
     {
         return peek(true);
@@ -276,7 +292,7 @@
         return (char) n;
     }
 
-    private int find(char target, char deeper)
+    int find(char target, char deeper)
     {
         int start = current;
         int level = 1;
@@ -340,7 +356,7 @@
 
     CharSequence findVar()
     {
-        int start = current - 1;
+        int start = current;
         char c = peek();
 
         if (c == '{')
@@ -349,12 +365,22 @@
             int end = find('}', '{');
             return text.subSequence(start, end);
         }
+        if (c == '<')
+        {
+            next();
+            int end = find('>', '<');
+            return text.subSequence(start, end);
+        }
 
         if (Character.isJavaIdentifierStart(c))
         {
-            while (!eof() && Character.isJavaIdentifierPart(c) || c == '.')
+            while (c == '$') {
+                c = next();
+            }
+            while (!eof() && (Character.isJavaIdentifierPart(c) || c == '.') && c != '$')
             {
                 next();
+                c = peek();
             }
             return text.subSequence(start, current);
         }

Copied: felix/trunk/gogo/runtime/src/test/java/org/apache/felix/gogo/runtime/shell/Context.java (from r791864, felix/trunk/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/shell/Context.java)
URL: http://svn.apache.org/viewvc/felix/trunk/gogo/runtime/src/test/java/org/apache/felix/gogo/runtime/shell/Context.java?p2=felix/trunk/gogo/runtime/src/test/java/org/apache/felix/gogo/runtime/shell/Context.java&p1=felix/trunk/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/shell/Context.java&r1=791864&r2=791913&rev=791913&view=diff
==============================================================================
--- felix/trunk/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/shell/Context.java (original)
+++ felix/trunk/gogo/runtime/src/test/java/org/apache/felix/gogo/runtime/shell/Context.java Tue Jul  7 17:18:26 2009
@@ -48,5 +48,10 @@
         put("test:" + name, target);
     }
 
+    public void set(String name, Object value)
+    {
+        session.put(name, value);
+    }
+
 
 }

Modified: felix/trunk/gogo/runtime/src/test/java/org/apache/felix/gogo/runtime/shell/TestParser.java
URL: http://svn.apache.org/viewvc/felix/trunk/gogo/runtime/src/test/java/org/apache/felix/gogo/runtime/shell/TestParser.java?rev=791913&r1=791912&r2=791913&view=diff
==============================================================================
--- felix/trunk/gogo/runtime/src/test/java/org/apache/felix/gogo/runtime/shell/TestParser.java (original)
+++ felix/trunk/gogo/runtime/src/test/java/org/apache/felix/gogo/runtime/shell/TestParser.java Tue Jul  7 17:18:26 2009
@@ -35,9 +35,32 @@
 {
     int beentheredonethat = 0;
 
+    public void testQuotes() throws Exception {
+        Context c = new Context();
+        c.addCommand("echo", this);
+        c.addCommand("capture", this);
+        c.set("c", "a");
+        assertEquals("a  b", c.execute("echo \"$c  b\" | capture"));
+
+        assertEquals("a b", c.execute("echo a b | capture"));
+        assertEquals("a b", c.execute("echo 'a b' | capture"));
+        assertEquals("a b", c.execute("echo \"a b\" | capture"));
+        assertEquals("a b", c.execute("echo a  b | capture"));
+        assertEquals("a  b", c.execute("echo 'a  b' | capture"));
+        assertEquals("a  b", c.execute("echo \"a  b\" | capture"));
+        assertEquals("a b", c.execute("echo $c  b | capture"));
+        assertEquals("$c  b", c.execute("echo '$c  b' | capture"));
+        assertEquals("a  b", c.execute("echo \"$c  b\" | capture"));
+        assertEquals("a b", c.execute("echo ${c}  b | capture"));
+        assertEquals("${c}  b", c.execute("echo '${c}  b' | capture"));
+        assertEquals("a  b", c.execute("echo \"${c}  b\" | capture"));
+        assertEquals("aa", c.execute("echo $c$c | capture"));
+        assertEquals("a ;a", c.execute("echo a\\ \\;a | capture"));
+    }
+
     public void testScope() throws Exception
     {
-        Context c= new Context();
+        Context c = new Context();
         c.addCommand("echo", this);
         c.addCommand("capture", this);
         assertEquals("$a", c.execute("test:echo \\$a | capture"));
@@ -62,6 +85,8 @@
         c.addCommand("echo", this);
         c.addCommand("capture", this);
         c.addCommand("grep", this);
+        assertEquals("a", c.execute("a = a; echo $$a").toString());
+
         assertEquals("hello", c.execute("echo hello|capture").toString());
         assertEquals("hello", c.execute("a = <echo hello|capture>").toString());
         assertEquals("a", c.execute("a = a; echo $<echo a>").toString());
@@ -105,8 +130,8 @@
     {
         Parser parser = new Parser("'a|b;c'");
         CharSequence cs = parser.messy();
-        assertEquals("a|b;c", cs.toString());
-        assertEquals("a|b;c", new Parser(cs).unescape());
+        assertEquals("'a|b;c'", cs.toString());
+        assertEquals("'a|b;c'", new Parser(cs).unescape());
         assertEquals("$a", new Parser("\\$a").unescape());
     }
 
@@ -164,6 +189,7 @@
 
         assertEquals("", c.execute("echo ${very.likely.that.this.does.not.exist}").toString());
         assertNotNull(c.execute("echo ${java.shell.name}"));
+        assertEquals("a", c.execute("a = a; echo ${a}").toString());
     }
 
     public void testFunny() throws Exception
@@ -278,7 +304,7 @@
         assertEquals("<immediate>", x.get(5));
         assertEquals("{'{{{{{'}", x.get(6));
         assertEquals("{\\}}", x.get(7));
-        assertEquals("abc{}", x.get(8));
+        assertEquals("'abc{}'", x.get(8));
     }
 
     void each(CommandSession session, Collection<Object> list, Function closure) throws Exception