Author: dbaum
Date: Fri Dec 18 19:27:04 2009
New Revision: 892356

URL: http://svn.apache.org/viewvc?rev=892356&view=rev
Log:
change priority of ; and | to match bash. resolves FELIX-1500.

Modified:
    
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/Parser.java
    
felix/trunk/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/shell/Pipe.java
    
felix/trunk/gogo/runtime/src/test/java/org/apache/felix/gogo/runtime/shell/TestParser.java

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=892356&r1=892355&r2=892356&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
 Fri Dec 18 19:27:04 2009
@@ -18,11 +18,15 @@
  */
 package org.apache.felix.gogo.runtime.shell;
 
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
 import org.osgi.service.command.CommandSession;
 import org.osgi.service.command.Function;
 
-import java.util.*;
-
 public class Closure extends Reflective implements Function
 {
     private static final long serialVersionUID = 1L;
@@ -42,65 +46,75 @@
     {
         parms = values;
         Parser parser = new Parser(source);
-        ArrayList<Pipe> pipes = new ArrayList<Pipe>();
         List<List<List<CharSequence>>> program = parser.program();
+        Pipe last = null;
 
-        for (List<List<CharSequence>> statements : program)
+        for (List<List<CharSequence>> pipeline : program)
         {
-            Pipe current = new Pipe(this, statements);
+            ArrayList<Pipe> pipes = new ArrayList<Pipe>();
 
-            if (pipes.isEmpty())
-            {
-               if (current.out == null)
+           for (List<CharSequence> statement : pipeline)
+           {
+               Pipe current = new Pipe(this, statement);
+
+               if (pipes.isEmpty())
                {
-                   current.setIn(session.in);
-                   current.setOut(session.out);
-                   current.setErr(session.err);
+                   if (current.out == null)
+                   {
+                       current.setIn(session.in);
+                       current.setOut(session.out);
+                       current.setErr(session.err);
+                   }
                }
-            }
-            else
-            {
-                Pipe previous = pipes.get(pipes.size() - 1);
-                previous.connect(current);
-            }
-            pipes.add(current);
-        }
-        if (pipes.size() == 0)
-        {
-            return null;
-        }
+               else
+               {
+                   Pipe previous = pipes.get(pipes.size() - 1);
+                   previous.connect(current);
+               }
+               pipes.add(current);
+           }
 
-        if (pipes.size() == 1)
-        {
-            pipes.get(0).run();
-        }
-        else
-        {
-            for (Pipe pipe : pipes)
-            {
-                pipe.start();
-            }
-            for (Pipe pipe : pipes)
-            {
-                pipe.join();
-            }
-        }
+           if (pipes.size() == 1)
+           {
+               pipes.get(0).run();
+           }
+           else if (pipes.size() > 1)
+           {
+               for (Pipe pipe : pipes)
+               {
+                   pipe.start();
+               }
+               for (Pipe pipe : pipes)
+               {
+                   pipe.join();
+               }
+           }
 
-        Pipe last = pipes.remove(pipes.size() - 1);
+           last = pipes.remove(pipes.size() - 1);
 
-        for (Pipe pipe : pipes)
-        {
-            if (pipe.exception != null)
-            {
-                // can't throw exception, as result is defined by last pipe
-                session.err.println("pipe: " + pipe.exception);
-            }
-        }
+           for (Pipe pipe : pipes)
+           {
+               if (pipe.exception != null)
+               {
+                   // can't throw exception, as result is defined by last pipe
+                   session.err.println("pipe: " + pipe.exception);
+                   session.put("pipe-exception", pipe.exception);
+               }
+           }
 
-        if (last.exception != null)
-        {
-            throw last.exception;
-        }
+           if (last.exception != null)
+           {
+               Pipe.reset();
+               throw last.exception;
+           }
+       }
+
+       Pipe.reset();   // reset IO in case sshd uses same thread for new client
+
+       if (last == null)
+       {
+           return null;
+       }
 
         if (last.result instanceof Object[])
         {

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=892356&r1=892355&r2=892356&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
 Fri Dec 18 19:27:04 2009
@@ -137,11 +137,15 @@
         ws();
         if (!eof())
         {
-            program.add(statements());
-            while (peek() == '|')
+            program.add(pipeline());
+            while (peek() == ';')
             {
                 current++;
-                program.add(statements());
+                List<List<CharSequence>> pipeline = pipeline();
+                if (pipeline.get(0).get(0).length() != 0)
+                {
+                    program.add(pipeline);
+                }
             }
         }
         if (!eof())
@@ -157,19 +161,22 @@
         return text.subSequence(Math.max(0, current - 20), 
Math.min(text.length(), current + 4));
     }
 
-    public List<List<CharSequence>> statements()
+    public List<List<CharSequence>> pipeline()
     {
         List<List<CharSequence>> statements = new 
ArrayList<List<CharSequence>>();
         statements.add(statement());
-        while (peek() == ';')
+        while (peek() == '|')
         {
             current++;
-            // derek: BUGFIX: allow trailing ;
             ws();
             if (!eof())
             {
                 statements.add(statement());
             }
+            else
+            {
+                throw new RuntimeException("Eof found after pipe |");
+            }
         }
         return statements;
     }

Modified: 
felix/trunk/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/shell/Pipe.java
URL: 
http://svn.apache.org/viewvc/felix/trunk/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/shell/Pipe.java?rev=892356&r1=892355&r2=892356&view=diff
==============================================================================
--- 
felix/trunk/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/shell/Pipe.java
 (original)
+++ 
felix/trunk/gogo/runtime/src/main/java/org/apache/felix/gogo/runtime/shell/Pipe.java
 Fri Dec 18 19:27:04 2009
@@ -39,18 +39,29 @@
     Closure closure;
     Exception exception;
     Object result;
-    List<List<CharSequence>> statements;
+    List<CharSequence> statement;
+    
+    public static void reset()
+    {
+        tIn.set(null);
+        tOut.set(null);
+        tErr.set(null);
+    }
 
-    public Pipe(Closure closure, List<List<CharSequence>> statements)
+    public Pipe(Closure closure, List<CharSequence> statement)
     {
-        super("pipe-" + statements);
+        super("pipe-" + statement);
         this.closure = closure;
-        this.statements = statements;
+        this.statement = statement;
 
         in = tIn.get();
         out = tOut.get();
         err = tErr.get();
     }
+    
+    public String toString() {
+        return "pipe<" + statement + "> out=" + out;
+    }
 
     public void setIn(InputStream in)
     {
@@ -86,13 +97,10 @@
 
         try
         {
-            for (List<CharSequence> statement : statements)
+            result = closure.executeStatement(statement);
+            if (result != null && pout != null)
             {
-                result = closure.executeStatement(statement);
-                if (result != null && pout != null)
-                {
-                    out.println(closure.session.format(result, 
Converter.INSPECT));
-                }
+                out.println(closure.session.format(result, Converter.INSPECT));
             }
         }
         catch (Exception e)
@@ -119,11 +127,6 @@
             {
                 e.printStackTrace();
             }
-
-            tIn.set(null);
-            tOut.set(null);
-            tErr.set(null);
-
         }
     }
 }

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=892356&r1=892355&r2=892356&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
 Fri Dec 18 19:27:04 2009
@@ -113,9 +113,10 @@
         assertEquals("def", c.execute("echo def|grep d.*|capture"));
         assertEquals("def", c.execute("echoout def|grep d.*|capture"));
         assertEquals("def", c.execute("myecho def|grep d.*|capture"));
-        assertEquals("def", c.execute("echo abc; echo def; echo ghi|grep 
d.*|capture"));
+        assertEquals("def", c.execute("(echoout abc; echoout def; echoout 
ghi)|grep d.*|capture"));
+        assertEquals("", c.execute("echoout def; echoout ghi | grep d.* | 
capture"));
         assertEquals("hello world", c.execute("echo hello world|capture"));
-        assertEquals("defghi", c.execute("echo abc; echo def; echo ghi|grep 
'def|ghi'|capture"));
+        assertEquals("defghi", c.execute("(echoout abc; echoout def; echoout 
ghi)|grep 'def|ghi'|capture"));
     }
 
     public void testAssignment() throws Exception
@@ -320,17 +321,17 @@
         List<List<List<CharSequence>>> x = new Parser("abc def|ghi jkl;mno 
pqr|stu vwx").program();
         assertEquals("abc", x.get(0).get(0).get(0));
         assertEquals("def", x.get(0).get(0).get(1));
-        assertEquals("ghi", x.get(1).get(0).get(0));
-        assertEquals("jkl", x.get(1).get(0).get(1));
-        assertEquals("mno", x.get(1).get(1).get(0));
-        assertEquals("pqr", x.get(1).get(1).get(1));
-        assertEquals("stu", x.get(2).get(0).get(0));
-        assertEquals("vwx", x.get(2).get(0).get(1));
+        assertEquals("ghi", x.get(0).get(1).get(0));
+        assertEquals("jkl", x.get(0).get(1).get(1));
+        assertEquals("mno", x.get(1).get(0).get(0));
+        assertEquals("pqr", x.get(1).get(0).get(1));
+        assertEquals("stu", x.get(1).get(1).get(0));
+        assertEquals("vwx", x.get(1).get(1).get(1));
     }
 
     public void testStatements()
     {
-        List<List<CharSequence>> x = new Parser("abc def;ghi jkl;mno 
pqr").statements();
+        List<List<CharSequence>> x = new Parser("abc def|ghi jkl|mno 
pqr").pipeline();
         assertEquals("abc", x.get(0).get(0));
         assertEquals("def", x.get(0).get(1));
         assertEquals("ghi", x.get(1).get(0));


Reply via email to