Revision: 5642
          http://jnode.svn.sourceforge.net/jnode/?rev=5642&view=rev
Author:   fduminy
Date:     2009-08-15 09:24:53 +0000 (Sat, 15 Aug 2009)

Log Message:
-----------
committed patch from zephyr (http://www.jnode.org/user/9083) for the 'tee' 
command (http://www.jnode.org/node/3061)

Modified Paths:
--------------
    trunk/cli/descriptors/org.jnode.command.file.xml
    trunk/cli/src/test/org/jnode/test/command/file/all-file-tests.xml

Added Paths:
-----------
    trunk/cli/src/commands/org/jnode/command/file/TeeCommand.java
    trunk/cli/src/test/org/jnode/test/command/file/tee-command-tests.xml

Modified: trunk/cli/descriptors/org.jnode.command.file.xml
===================================================================
--- trunk/cli/descriptors/org.jnode.command.file.xml    2009-08-14 16:59:45 UTC 
(rev 5641)
+++ trunk/cli/descriptors/org.jnode.command.file.xml    2009-08-15 09:24:53 UTC 
(rev 5642)
@@ -44,6 +44,7 @@
     <alias name="rm"      class="org.jnode.command.file.DeleteCommand"/>
     <alias name="sort"    class="org.jnode.command.file.SortCommand"/>
     <alias name="tail"    class="org.jnode.command.file.TailCommand"/>
+    <alias name="tee"     class="org.jnode.command.file.TeeCommand"/>
     <alias name="touch"   class="org.jnode.command.file.TouchCommand"/>
     <alias name="wc"      class="org.jnode.command.file.WcCommand"/>
   </extension>
@@ -351,6 +352,16 @@
         </repeat>
       </sequence>
     </syntax>
+    <syntax alias="tee">
+      <sequence>
+        <optionSet label="globals">
+          <option argLabel="append"    shortName="a" longName="append"/>
+        </optionSet>
+        <repeat>
+          <argument argLabel="files"/>
+        </repeat>
+      </sequence>
+    </syntax>
     <syntax alias="touch">
       <argument argLabel="file" description="touch the given file"/>
     </syntax>

Added: trunk/cli/src/commands/org/jnode/command/file/TeeCommand.java
===================================================================
--- trunk/cli/src/commands/org/jnode/command/file/TeeCommand.java               
                (rev 0)
+++ trunk/cli/src/commands/org/jnode/command/file/TeeCommand.java       
2009-08-15 09:24:53 UTC (rev 5642)
@@ -0,0 +1,170 @@
+/*
+ * $Id$
+ *
+ * Copyright (C) 2003-2009 JNode.org
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library 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 Lesser General Public 
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; If not, write to the Free Software Foundation, 
Inc., 
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+package org.jnode.command.file;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import org.jnode.command.util.IOUtils;
+import org.jnode.shell.AbstractCommand;
+import org.jnode.shell.syntax.Argument;
+import org.jnode.shell.syntax.FileArgument;
+import org.jnode.shell.syntax.FlagArgument;
+
+/**
+ * Copy standard input to standard output, making a copy in zero or more 
files.<br>
+ * Implementation based on:
+ * http://www.opengroup.org/onlinepubs/9699919799/utilities/tee.html.
+ */
+public class TeeCommand extends AbstractCommand {
+
+    /** Help text for the parameter. */
+    private static final String HELP_FILE = "One or more files that will 
receive the \"tee-d\" output";
+
+    /** Help text for the append switch. */
+    private static final String HELP_APPEND = "Append to the given FILEs, do 
not overwrite";
+
+    /** Help text for the command. */
+    private static final String HELP_SUPER = "Copy standard input to each 
FILE, and also to standard outputd";
+
+    /** The file argument. */
+    private final FileArgument argFile;
+
+    /** The append switch. */
+    private final FlagArgument argAppend;
+
+    /** The standard input. */
+    private InputStream stdin;
+
+    /** The standard output. */
+    private OutputStream stdout;
+
+    /** The files that will receive the output. */
+    private File[] files;
+
+    /** The return code of the command. */
+    private int returnCode = 0;
+
+    /** Flag to indicate if the files should be appended. */
+    private boolean appendFiles;
+
+    /**
+     * In the documentation it is stated that a minimum of 13 files must be
+     * supported. Limit the command to only accept a maximum of 13 files to
+     * limit resource usage.
+     */
+    private static final int MAX_NUMBER_OF_FILES = 13;
+
+    /** Buffer used in stream copies. */
+    private static final int BUFFER_SIZE = 8192;
+
+    /**
+     * Default constructor.
+     */
+    public TeeCommand() {
+        super(HELP_SUPER);
+        int fileFlags = Argument.MULTIPLE;
+        argFile = new FileArgument("files", fileFlags, HELP_FILE);
+        argAppend = new FlagArgument("append", 0, HELP_APPEND);
+        registerArguments(argFile, argAppend);
+    }
+
+    /**
+     * Used to run this command independently.
+     * 
+     * @param args the arguments passed to the command
+     * @throws Exception if an error occurs
+     */
+    public static void main(String[] args) throws Exception {
+        new TeeCommand().execute(args);
+    }
+
+    @Override
+    public void execute() throws IOException {
+        OutputStream out = null;
+        byte[] buffer = new byte[BUFFER_SIZE];
+
+        stdin = getInput().getInputStream();
+        stdout = getOutput().getOutputStream();
+
+        // Parse the command arguments
+        files = argFile.getValues();
+
+        if (files == null || files.length == 0) {
+            // The command is simply ignored if there are no files
+            // Just copy the input to the output and return
+            IOUtils.copyStream(stdin, stdout, buffer);
+            exit(returnCode);
+        }
+
+        if (argAppend.isSet()) {
+            appendFiles = true;
+        }
+
+        // A maximum of MAX_NUMBER_OF_FILES will be used
+        int numberOfFiles = files.length > MAX_NUMBER_OF_FILES ? 
MAX_NUMBER_OF_FILES : files.length;
+
+        int successfullOpenFiles = 0;
+
+        // Create an array to hold all output files
+        OutputStream[] outFiles = new OutputStream[numberOfFiles];
+
+        try {
+            // Open all output files
+            for (int i = 0; i < numberOfFiles; i++) {
+                if ((out = IOUtils.openOutputstream(files[i], appendFiles)) != 
null) {
+                    outFiles[successfullOpenFiles++] = out;
+                }
+            }
+
+            int count = 0;
+            do {
+                count = stdin.read(buffer);
+                for (int i = 0; i < successfullOpenFiles; i++) {
+                    try {
+                        outFiles[i].write(buffer, 0, count);
+                    } catch (IOException e) {
+                        // Only the return code is updated
+                        returnCode++;
+                    }
+
+                }
+                stdout.write(buffer, 0, count);
+            } while (!(count < BUFFER_SIZE));
+
+        } finally {
+            // Close all open output files
+            for (int i = 0; i < successfullOpenFiles; i++) {
+                try {
+                    outFiles[i].close();
+                } catch (IOException e) {
+                    // Nothing to do in this case
+                    // Just continue closing the files
+                }
+            }
+        }
+
+        // Returns the code
+        exit(returnCode);
+    }
+}

Modified: trunk/cli/src/test/org/jnode/test/command/file/all-file-tests.xml
===================================================================
--- trunk/cli/src/test/org/jnode/test/command/file/all-file-tests.xml   
2009-08-14 16:59:45 UTC (rev 5641)
+++ trunk/cli/src/test/org/jnode/test/command/file/all-file-tests.xml   
2009-08-15 09:24:53 UTC (rev 5642)
@@ -6,5 +6,6 @@
     <include setName="paste-command-tests.xml"/>
     <include setName="sort-command-tests.xml"/>
     <include setName="tail-command-tests.xml"/>
+    <include setName="tee-command-tests.xml"/>
     <include setName="wc-command-tests.xml"/>
 </testSet>

Added: trunk/cli/src/test/org/jnode/test/command/file/tee-command-tests.xml
===================================================================
--- trunk/cli/src/test/org/jnode/test/command/file/tee-command-tests.xml        
                        (rev 0)
+++ trunk/cli/src/test/org/jnode/test/command/file/tee-command-tests.xml        
2009-08-15 09:24:53 UTC (rev 5642)
@@ -0,0 +1,255 @@
+<testSet title="tee command tests">
+    <plugin id="org.jnode.command.file"/>
+    <plugin id="org.jnode.shell.bjorne" 
class="org.jnode.test.shell.bjorne.BjornePseudoPlugin"/>
+    <testSpec title="no file" command="tee" runMode="AS_ALIAS" rc="0">
+        <input>1234
+</input>
+        <output>1234
+</output>
+    </testSpec>
+    <testSpec title="single-file" command="run" runMode="AS_SCRIPT" rc="0">
+        <script>#!bjorne
+                echo 1234 | tee @TEMP_DIR@/out
+        </script>
+        <file name="out" input="false">1234
+</file>
+        <output>1234
+</output>
+    </testSpec>
+    <testSpec title="max-files" command="run" runMode="AS_SCRIPT" rc="0">
+        <script>#!bjorne
+                echo 1234 | tee @TEMP_DIR@/out @TEMP_DIR@/out_1 
@TEMP_DIR@/out_2 @TEMP_DIR@/out_3 @TEMP_DIR@/out_4 @TEMP_DIR@/out_5 
@TEMP_DIR@/out_6 @TEMP_DIR@/out_7 @TEMP_DIR@/out_8 @TEMP_DIR@/out_9 
@TEMP_DIR@/out_10 @TEMP_DIR@/out_11 @TEMP_DIR@/out_12
+        </script>
+        <file name="out" input="false">1234
+</file>
+        <file name="out_1" input="false">1234
+</file>
+        <file name="out_2" input="false">1234
+</file>
+        <file name="out_3" input="false">1234
+</file>
+        <file name="out_4" input="false">1234
+</file>
+        <file name="out_5" input="false">1234
+</file>
+        <file name="out_6" input="false">1234
+</file>
+        <file name="out_7" input="false">1234
+</file>
+        <file name="out_8" input="false">1234
+</file>
+        <file name="out_9" input="false">1234
+</file>
+        <file name="out_10" input="false">1234
+</file>
+        <file name="out_11" input="false">1234
+</file>
+        <file name="out_12" input="false">1234
+</file>
+        <output>1234
+</output>
+    </testSpec>
+    <testSpec title="more-then-max-files" command="run" runMode="AS_SCRIPT" 
rc="0">
+        <script>#!bjorne
+                echo 1234 | tee @TEMP_DIR@/out @TEMP_DIR@/out_1 
@TEMP_DIR@/out_2 @TEMP_DIR@/out_3 @TEMP_DIR@/out_4 @TEMP_DIR@/out_5 
@TEMP_DIR@/out_6 @TEMP_DIR@/out_7 @TEMP_DIR@/out_8 @TEMP_DIR@/out_9 
@TEMP_DIR@/out_10 @TEMP_DIR@/out_11 @TEMP_DIR@/out_12 @TEMP_DIR@/out_13
+        </script>
+        <file name="out" input="false">1234
+</file>
+        <file name="out_1" input="false">1234
+</file>
+        <file name="out_2" input="false">1234
+</file>
+        <file name="out_3" input="false">1234
+</file>
+        <file name="out_4" input="false">1234
+</file>
+        <file name="out_5" input="false">1234
+</file>
+        <file name="out_6" input="false">1234
+</file>
+        <file name="out_7" input="false">1234
+</file>
+        <file name="out_8" input="false">1234
+</file>
+        <file name="out_9" input="false">1234
+</file>
+        <file name="out_10" input="false">1234
+</file>
+        <file name="out_11" input="false">1234
+</file>
+        <file name="out_12" input="false">1234
+</file>
+        <output>1234
+</output>
+    </testSpec>
+    
+    
+    <testSpec title="append-single-file" command="run" runMode="AS_SCRIPT" 
rc="0">
+        <script>#!bjorne
+                echo 1234 | tee -a @TEMP_DIR@/out
+        </script>
+        <file name="out" input="true">Already in File out
+</file>
+        <file name="out" input="false">Already in File out
+1234
+</file>
+        <output>1234
+</output>
+    </testSpec>
+    <testSpec title="append-max-files" command="run" runMode="AS_SCRIPT" 
rc="0">
+        <script>#!bjorne
+                echo 1234 | tee -a @TEMP_DIR@/out @TEMP_DIR@/out_1 
@TEMP_DIR@/out_2 @TEMP_DIR@/out_3 @TEMP_DIR@/out_4 @TEMP_DIR@/out_5 
@TEMP_DIR@/out_6 @TEMP_DIR@/out_7 @TEMP_DIR@/out_8 @TEMP_DIR@/out_9 
@TEMP_DIR@/out_10 @TEMP_DIR@/out_11 @TEMP_DIR@/out_12
+        </script>
+        
+        <!-- Exiting files -->
+        <file name="out" input="true">Already in File out
+</file>
+        <file name="out_1" input="true">Already in File out_1
+</file>
+        <file name="out_2" input="true">Already in File out_2
+</file>
+        <file name="out_3" input="true">Already in File out_3
+</file>
+        <file name="out_4" input="true">Already in File out_4
+</file>
+        <file name="out_5" input="true">Already in File out_5
+</file>
+        <file name="out_6" input="true">Already in File out_6
+</file>
+        <file name="out_7" input="true">Already in File out_7
+</file>
+        <file name="out_8" input="true">Already in File out_8
+</file>
+        <file name="out_9" input="true">Already in File out_9
+</file>
+        <file name="out_10" input="true">Already in File out_10
+</file>
+        <file name="out_11" input="true">Already in File out_11
+</file>
+        <file name="out_12" input="true">Already in File out_12
+</file>
+
+        <!-- Output files -->
+        <file name="out" input="false">Already in File out
+1234
+</file>
+        <file name="out_1" input="false">Already in File out_1
+1234
+</file>
+        <file name="out_2" input="false">Already in File out_2
+1234
+</file>
+        <file name="out_3" input="false">Already in File out_3
+1234
+</file>
+        <file name="out_4" input="false">Already in File out_4
+1234
+</file>
+        <file name="out_5" input="false">Already in File out_5
+1234
+</file>
+        <file name="out_6" input="false">Already in File out_6
+1234
+</file>
+        <file name="out_7" input="false">Already in File out_7
+1234
+</file>
+        <file name="out_8" input="false">Already in File out_8
+1234
+</file>
+        <file name="out_9" input="false">Already in File out_9
+1234
+</file>
+        <file name="out_10" input="false">Already in File out_10
+1234
+</file>
+        <file name="out_11" input="false">Already in File out_11
+1234
+</file>
+        <file name="out_12" input="false">Already in File out_12
+1234
+</file>
+        <output>1234
+</output>
+    </testSpec>
+    <testSpec title="append-more-than-max-files" command="run" 
runMode="AS_SCRIPT" rc="0">
+        <script>#!bjorne
+                echo 1234 | tee -a @TEMP_DIR@/out @TEMP_DIR@/out_1 
@TEMP_DIR@/out_2 @TEMP_DIR@/out_3 @TEMP_DIR@/out_4 @TEMP_DIR@/out_5 
@TEMP_DIR@/out_6 @TEMP_DIR@/out_7 @TEMP_DIR@/out_8 @TEMP_DIR@/out_9 
@TEMP_DIR@/out_10 @TEMP_DIR@/out_11 @TEMP_DIR@/out_12 @TEMP_DIR@/out_13
+        </script>
+        
+        <!-- Exiting files -->
+        <file name="out" input="true">Already in File out
+</file>
+        <file name="out_1" input="true">Already in File out_1
+</file>
+        <file name="out_2" input="true">Already in File out_2
+</file>
+        <file name="out_3" input="true">Already in File out_3
+</file>
+        <file name="out_4" input="true">Already in File out_4
+</file>
+        <file name="out_5" input="true">Already in File out_5
+</file>
+        <file name="out_6" input="true">Already in File out_6
+</file>
+        <file name="out_7" input="true">Already in File out_7
+</file>
+        <file name="out_8" input="true">Already in File out_8
+</file>
+        <file name="out_9" input="true">Already in File out_9
+</file>
+        <file name="out_10" input="true">Already in File out_10
+</file>
+        <file name="out_11" input="true">Already in File out_11
+</file>
+        <file name="out_12" input="true">Already in File out_12
+</file>
+        <file name="out_13" input="true">Already in File out_13
+</file>
+
+        <!-- Output files -->
+        <file name="out" input="false">Already in File out
+1234
+</file>
+        <file name="out_1" input="false">Already in File out_1
+1234
+</file>
+        <file name="out_2" input="false">Already in File out_2
+1234
+</file>
+        <file name="out_3" input="false">Already in File out_3
+1234
+</file>
+        <file name="out_4" input="false">Already in File out_4
+1234
+</file>
+        <file name="out_5" input="false">Already in File out_5
+1234
+</file>
+        <file name="out_6" input="false">Already in File out_6
+1234
+</file>
+        <file name="out_7" input="false">Already in File out_7
+1234
+</file>
+        <file name="out_8" input="false">Already in File out_8
+1234
+</file>
+        <file name="out_9" input="false">Already in File out_9
+1234
+</file>
+        <file name="out_10" input="false">Already in File out_10
+1234
+</file>
+        <file name="out_11" input="false">Already in File out_11
+1234
+</file>
+        <file name="out_12" input="false">Already in File out_12
+1234
+</file>
+        <file name="out_13" input="false">Already in File out_13
+</file>
+        <output>1234
+</output>
+    </testSpec>
+</testSet>


This was sent by the SourceForge.net collaborative development platform, the 
world's largest Open Source development site.

------------------------------------------------------------------------------
Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day 
trial. Simplify your report design, integration and deployment - and focus on 
what you do best, core application coding. Discover what's new with 
Crystal Reports now.  http://p.sf.net/sfu/bobj-july
_______________________________________________
Jnode-svn-commits mailing list
Jnode-svn-commits@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/jnode-svn-commits

Reply via email to