From: <chr...@us...> - 2009-04-30 03:13:39
|
Revision: 5368 http://jnode.svn.sourceforge.net/jnode/?rev=5368&view=rev Author: chrisboertien Date: 2009-04-30 03:13:37 +0000 (Thu, 30 Apr 2009) Log Message: ----------- Implemented -n/-b/-s/-E flags for cat Signed-off-by: chrisboertien <chr...@gm...> Modified Paths: -------------- trunk/cli/descriptors/org.jnode.command.file.xml trunk/cli/src/commands/org/jnode/command/file/CatCommand.java Modified: trunk/cli/descriptors/org.jnode.command.file.xml =================================================================== --- trunk/cli/descriptors/org.jnode.command.file.xml 2009-04-29 22:41:40 UTC (rev 5367) +++ trunk/cli/descriptors/org.jnode.command.file.xml 2009-04-30 03:13:37 UTC (rev 5368) @@ -43,21 +43,28 @@ <alias name="tail" class="org.jnode.command.file.TailCommand"/> <alias name="touch" class="org.jnode.command.file.TouchCommand"/> <alias name="wc" class="org.jnode.command.file.WcCommand"/> - <!-- can't find org.jnode.command.file.WcCommand --> </extension> <extension point="org.jnode.shell.syntaxes"> <syntax alias="cat"> <empty description="copy standard input to standard output"/> + <sequence description="concatenate files to standard output"> + <optionSet> + <option argLabel="num-nonblank" shortName="b" longName="number-nonblank"/> + <option argLabel="num" shortName="n" longName="number"/> + <option argLabel="squeeze" shortName="s" longName="sqeeze-blank"/> + <option argLabel="show-ends" shortName="E" longName="show-ends"/> + </optionSet> + <repeat minCount="1"> + <argument argLabel="file"/> + </repeat> + </sequence> <sequence description="fetch and concatenate urls to standard output"> <option argLabel="urls" shortName="u" longName="urls"/> <repeat minCount="1"> <argument argLabel="url"/> </repeat> </sequence> - <repeat minCount="1" description="concatenate files to standard output"> - <argument argLabel="file"/> - </repeat> </syntax> <syntax alias="cd"> <empty description="change the current directory to the 'user.home' directory"/> @@ -105,7 +112,7 @@ <argument argLabel="directory" description="directory to start printing sizes recursively"/> </repeat> <optionSet> - <option argLabel="sum" shortName="s" longName="summarize"/> + <option argLabel="sum" shortName="s" longName="summarize"/> <option argLabel="all" shortName="a" longName="all"/> <option argLabel="human-readable" shortName="h" longName="human-readable"/> </optionSet> Modified: trunk/cli/src/commands/org/jnode/command/file/CatCommand.java =================================================================== --- trunk/cli/src/commands/org/jnode/command/file/CatCommand.java 2009-04-29 22:41:40 UTC (rev 5367) +++ trunk/cli/src/commands/org/jnode/command/file/CatCommand.java 2009-04-30 03:13:37 UTC (rev 5368) @@ -20,15 +20,18 @@ package org.jnode.command.file; +import java.io.BufferedReader; import java.io.File; -import java.io.FileInputStream; import java.io.FileNotFoundException; +import java.io.FileReader; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.PrintWriter; +import java.io.Reader; import java.net.URL; +import org.jnode.command.util.IOUtils; import org.jnode.shell.AbstractCommand; import org.jnode.shell.syntax.Argument; import org.jnode.shell.syntax.FileArgument; @@ -53,115 +56,240 @@ private static final String help_file = "the files to be concatenated"; private static final String help_url = "the urls to be concatenated"; private static final String help_urls = "If set, arguments will be urls"; + private static final String help_num_nb = "If set, number nonempty output lines"; + private static final String help_num = "If set, number all output lines"; + private static final String help_ends = "If set, print a $ at the end of each lines"; + private static final String help_squeeze = "If set, supress printing of sequential blank lines"; private static final String help_super = "Concatenate the contents of files, urls or standard input"; private static final String err_url = "Cannot fetch %s: %s%n"; - private static final String err_file = "Cannot open %s: %s%n"; + private static final String err_file = "Cannot open %sn"; private final FileArgument argFile; + private final FlagArgument argNumNB; + private final FlagArgument argNumAll; + private final FlagArgument argEnds; + private final FlagArgument argSqueeze; + private final URLArgument argUrl; private final FlagArgument argUrls; private PrintWriter err; + private PrintWriter out; + private Reader in; + private InputStream stdin; + private OutputStream stdout; + private File[] files; + private String end; + private int rc = 0; + private boolean squeeze; + private boolean numAll; + private boolean numNB; + private boolean useStreams; public CatCommand() { super(help_super); - argFile = new FileArgument("file", Argument.OPTIONAL | Argument.MULTIPLE | Argument.EXISTING, help_file); - argUrl = new URLArgument("url", Argument.OPTIONAL | Argument.MULTIPLE | Argument.EXISTING, help_url); + int fileFlags = Argument.MULTIPLE | Argument.EXISTING | FileArgument.HYPHEN_IS_SPECIAL; + argFile = new FileArgument("file", fileFlags, help_file); + argNumNB = new FlagArgument("num-nonblank", 0, help_num_nb); + argNumAll = new FlagArgument("num", 0, help_num); + argEnds = new FlagArgument("show-ends", 0, help_ends); + argSqueeze = new FlagArgument("squeeze", 0, help_squeeze); + registerArguments(argFile, argNumNB, argNumAll, argEnds, argSqueeze); + + argUrl = new URLArgument("url", Argument.MULTIPLE | Argument.EXISTING, help_url); argUrls = new FlagArgument("urls", Argument.OPTIONAL, help_urls); - registerArguments(argFile, argUrl, argUrls); + registerArguments(argUrl, argUrls); } - + private static final int BUFFER_SIZE = 8192; - - + public static void main(String[] args) throws Exception { new CatCommand().execute(args); } public void execute() throws IOException { - this.err = getError().getPrintWriter(); - OutputStream out = getOutput().getOutputStream(); - File[] files = argFile.getValues(); - URL[] urls = argUrl.getValues(); + in = getInput().getReader(); + stdin = getInput().getInputStream(); + out = getOutput().getPrintWriter(); + stdout = getOutput().getOutputStream(); + err = getError().getPrintWriter(); - boolean ok = true; + parseOptions(); + + if (files != null && files.length > 0) { + handleFiles(); + out.flush(); + exit(rc); + } + + // FIXME remove this url code once wget is more complete + URL[] urls = argUrl.getValues(); if (urls != null && urls.length > 0) { + byte[] buffer = new byte[BUFFER_SIZE]; for (URL url : urls) { InputStream is = null; try { is = url.openStream(); } catch (IOException ex) { err.format(err_url, url, ex.getLocalizedMessage()); - ok = false; + rc = 1; } if (is != null) { try { - process(is, out); + IOUtils.copyStream(is, stdout, buffer); } finally { - try { - is.close(); - } catch (IOException ex) { - /* ignore */ - } + IOUtils.close(is); } } } - } else if (files != null && files.length > 0) { - for (File file : files) { - InputStream is = null; - try { - is = openFile(file); - if (is == null) { - ok = false; + out.flush(); + exit(rc); + } + + // should not reach this + throw new IllegalStateException("Nothing to process"); + } + + private boolean handleFiles() { + InputStream in = null; + BufferedReader reader = null; + byte[] buffer = new byte[BUFFER_SIZE]; + boolean ok = true; + + for (File file : files) { + try { + if (useStreams) { + if ((in = openFileStream(file)) != null) { + IOUtils.copyStream(in, stdout, buffer); } else { - process(is, out); + rc = 1; } - } finally { - if (is != null) { - try { - is.close(); - } catch (IOException ex) { - /* ignore */ - } + } else { + if ((reader = openFileReader(file)) != null) { + processReader(reader); + } else { + rc = 1; } } + } catch (IOException e) { + rc = 1; + } finally { + IOUtils.close(in, reader); } - } else { - process(getInput().getInputStream(), out); } - out.flush(); - if (!ok) { - exit(1); - } + + return ok; } - + /** - * Copy all of stream 'in' to stream 'out' - * @param in - * @param out - * @throws IOException + * Process the input through a BufferedReader. + * + * Instead of doing a straight stream->stream copy, we process line by line + * in order to do some per-line editing before we send to stdout. */ - private void process(InputStream in, OutputStream out) throws IOException { - int len; - final byte[] buf = new byte[BUFFER_SIZE]; - while ((len = in.read(buf)) > 0) { - out.write(buf, 0, len); + private void processReader(BufferedReader reader) throws IOException { + String line; + boolean haveBlank = false; + int lineCount = 0; + + while ((line = reader.readLine()) != null) { + if (line.length() == 0) { + if (!haveBlank) { + haveBlank = true; + } else if (squeeze) { + continue; + } + } else { + haveBlank = false; + } + + if (numAll) { + println(line, ++lineCount); + } else if (numNB) { + println(line, (haveBlank ? -1 : ++lineCount)); + } else { + println(line, 0); + } } } /** - * Attempt to open a file, writing an error message on failure. + * Attempt to open a file, writing an error message on failure. If the file + * is '-', return stdin. + * * @param fname the filename of the file to be opened * @return An open stream, or <code>null</code>. - * @throws FileNotFoundException */ - private InputStream openFile(File file) throws FileNotFoundException { - try { - return new FileInputStream(file); - } catch (IOException ex) { - err.format(err_file, file, ex.getLocalizedMessage()); - return null; + private InputStream openFileStream(File file) { + InputStream ret = null; + + if (file.getName().equals("-")) { + ret = stdin; + } else { + ret = IOUtils.openInputStream(file, true, BUFFER_SIZE); + if (ret == null) { + err.format(err_file, file); + } } + + return ret; } - + + private BufferedReader openFileReader(File file) { + BufferedReader ret = null; + + if (file.getName().equals("-")) { + ret = new BufferedReader(in, BUFFER_SIZE); + } else { + try { + ret = new BufferedReader(new FileReader(file), BUFFER_SIZE); + } catch (FileNotFoundException e) { + err.format(err_file, file); + } + } + + return ret; + } + + private void parseOptions() { + files = argFile.getValues(); + + if (files == null || files.length == 0) { + files = new File[] {new File("-")}; + } + + useStreams = true; + + if (argNumNB.isSet()) { + numNB = true; + useStreams = false; + } else if (argNumAll.isSet()) { + numAll = true; + useStreams = false; + } + + if (argEnds.isSet()) { + end = "$"; + useStreams = false; + } else { + end = ""; + } + + if (argSqueeze.isSet()) { + squeeze = true; + useStreams = false; + } + } + + private void println(String s, int line) { + if (numNB || numAll) { + if (line == -1) { + out.format(" %s%s%n", s, end); + } else { + out.format("%6d %s%s%n", line, s, end); + } + } else { + out.format("%s%s%n", s, end); + } + } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <chr...@us...> - 2009-05-01 00:27:44
|
Revision: 5374 http://jnode.svn.sourceforge.net/jnode/?rev=5374&view=rev Author: chrisboertien Date: 2009-05-01 00:27:40 +0000 (Fri, 01 May 2009) Log Message: ----------- Rewrite of rm/del to better match the POSIX spec Signed-off-by: chrisboertien <chr...@gm...> Modified Paths: -------------- trunk/cli/descriptors/org.jnode.command.file.xml trunk/cli/src/commands/org/jnode/command/file/DeleteCommand.java trunk/cli/src/commands/org/jnode/command/util/IOUtils.java Modified: trunk/cli/descriptors/org.jnode.command.file.xml =================================================================== --- trunk/cli/descriptors/org.jnode.command.file.xml 2009-04-30 14:11:06 UTC (rev 5373) +++ trunk/cli/descriptors/org.jnode.command.file.xml 2009-05-01 00:27:40 UTC (rev 5374) @@ -92,6 +92,7 @@ <option argLabel="force" shortName="f" longName="force" /> <option argLabel="interactive" shortName="i" longName="interactive" /> <option argLabel="verbose" shortName="v" longName="verbose" /> + <option argLabel="one-fs" longName="one-file-system"/> </optionSet> <repeat minCount="1"> <argument argLabel="paths"/> Modified: trunk/cli/src/commands/org/jnode/command/file/DeleteCommand.java =================================================================== --- trunk/cli/src/commands/org/jnode/command/file/DeleteCommand.java 2009-04-30 14:11:06 UTC (rev 5373) +++ trunk/cli/src/commands/org/jnode/command/file/DeleteCommand.java 2009-05-01 00:27:40 UTC (rev 5374) @@ -27,13 +27,13 @@ import javax.naming.NameNotFoundException; +import org.jnode.command.util.IOUtils; import org.jnode.fs.service.FileSystemService; import org.jnode.naming.InitialNaming; import org.jnode.shell.AbstractCommand; import org.jnode.shell.syntax.Argument; import org.jnode.shell.syntax.FileArgument; import org.jnode.shell.syntax.FlagArgument; - /** * Delete a file or a empty directory * @@ -42,6 +42,8 @@ * @author Levente S\u00e1ntha * @author Martin Husted Hartvig (hagar at jnode.org) * @author cr...@jn... + * @author chris boertien + * @see {@link http://www.opengroup.org/onlinepubs/009695399/utilities/rm.html} */ public class DeleteCommand extends AbstractCommand { @@ -50,30 +52,38 @@ private static final String help_force = "ignore non-existant files, never prompt"; private static final String help_interact = "prompt before every delete"; private static final String help_verbose = "give information on what is happening"; + private static final String help_onefs = "If recursively deleting, do not recurse into directories that reside" + + "on a different file system"; private static final String help_super = "Delete files or directories"; - private static final String fmt_not_exist = "'%s' does not exist%n"; - private static final String fmt_is_dir = "Cannot remove '%s': Is a directory%n"; - private static final String fmt_ask_overwrite = "Remove regular file '%s'?"; - private static final String fmt_ask_descend = "Descend into directory '%s'?"; - private static final String fmt_ask_remove = "Remove directory '%s'?"; + private static final String str_not_exist = "File or Directory does not exist"; + private static final String str_is_dir = "Is a directory"; + private static final String str_is_dot = "Directory is '.' or '..'"; + private static final String str_is_mount = "Directory is a mount point"; + private static final String str_not_empty = "Directory is not empty"; + private static final String fmt_skip = "Skipping '%s' %s%n"; private static final String fmt_removed_file = "Removed '%s'"; private static final String fmt_removed_dir = "Removed directory '%s'"; private static final String fmt_not_removed = "'%s' was not removed"; + private static final String fmt_ask_remove_file = "Remove regular file '%s'? [yes/no] "; + private static final String fmt_ask_descend = "Descend into directory '%s'? [yes/no]"; + private static final String fmt_ask_remove_dir = "Remove directory '%s'? [yes/no]"; private final FileArgument argPaths; private final FlagArgument flagRecurse; private final FlagArgument flagForce; private final FlagArgument flagInteract; private final FlagArgument flagVerbose; + private final FlagArgument flagOneFS; private FileSystemService fss; + private PrintWriter err; + private PrintWriter out; + private Reader in; private boolean recursive; private boolean force; private boolean interactive; private boolean verbose; - private PrintWriter err; - private PrintWriter out; - private Reader in; + private boolean onefs; public DeleteCommand() { super(help_super); @@ -82,7 +92,8 @@ flagForce = new FlagArgument("force", Argument.OPTIONAL, help_force); flagInteract = new FlagArgument("interactive", Argument.OPTIONAL, help_interact); flagVerbose = new FlagArgument("verbose", Argument.OPTIONAL, help_verbose); - registerArguments(argPaths, flagRecurse, flagForce, flagInteract, flagVerbose); + flagOneFS = new FlagArgument("onefs", 0, help_onefs); + registerArguments(argPaths, flagRecurse, flagForce, flagInteract, flagVerbose, flagOneFS); } public static void main(String[] args) throws Exception { @@ -97,6 +108,7 @@ force = flagForce.isSet(); interactive = flagInteract.isSet(); verbose = flagVerbose.isSet(); + onefs = flagOneFS.isSet(); File[] paths = argPaths.getValues(); err = getError().getPrintWriter(); @@ -113,72 +125,134 @@ } private boolean deleteFile(File file) { + // We have to be careful about how we handle race conditions, especially + // considering the depth-first nature of recursive file deletion. If this + // method gets called on a file, and the file does not exist, then we assume + // some other process has beat us to it. The command line only allows existing + // files to be input. + + boolean deleteOk; + boolean prompt; + if (!file.exists()) { - if (!force) { - err.format(fmt_not_exist, file); - } - return false; + // someone beat us to the delete() call, return gracefully. + return skip(str_not_exist, file) || true; } - if (file.isDirectory() && !recursive) { - err.format(fmt_is_dir, file); - return false; - } - if (file.isFile() && interactive && !prompt_yn(String.format(fmt_ask_overwrite, file))) { - return false; - } - boolean deleteOk = true; - - // FIXME the following doesn't handle mounted filesystems correctly (I think). - // Recursive delete should not recurse >>into<< a mounted filesystem, but should - // give an error message and then refuse to delete the parent directory because - // it cannot be emptied. - if (file.isDirectory() && !fss.isMount(file.getAbsolutePath())) { - if (interactive && !prompt_yn(String.format(fmt_ask_descend, file))) { - return false; + // A note about 'interactive' mode. It is _not_ an error + // if stdin is not a tty. It is possible to send responses + // via a pipe. This is why we only check for a tty stdin + // if interactive was not set. + prompt = (!force && (interactive || (!isWriteable(file) && getInput().isTTY()))); + + if (file.isDirectory()) { + // This is written to match the POSIX behavior in rm Description Section 2 + if (!recursive) { + return skip(str_is_dir, file); } + if (file.getName().equals("..") || file.getName().equals(".")) { + return skip(str_is_dot, file); + } + if (prompt) { + if (!prompt(String.format(fmt_ask_descend, file))) { + return skip("", file); + } + } + // According to the POSIX spec, there is no provision for recursive deletion + // that spans into another file system. The GNU rm utility provides the ability + // to stop recursive deleting from entering another file system. If that flag + // is not set, then we will continue to delete files within that file system + // but the deleting of the directory that is the mount will probably fail because + // it is in use. + if (!checkMount(file)) { + return skip(str_is_mount, file); + } + deleteOk = true; for (File f : file.listFiles()) { - final String name = f.getName(); - + String name = f.getName(); if (!name.equals(".") && !name.equals("..")) { deleteOk &= deleteFile(f); } } - if (deleteOk && interactive && !prompt_yn(String.format(fmt_ask_remove, file))) { - return false; + if (!deleteOk) { + return skip(str_not_empty, file); } - } - - if (deleteOk) { - // FIXME ... this is going to attempt to delete "directories" that are - // mounted filesystems. Is this right? What will it do? - // FIXME ... this does not report the reason that the delete failed. - // How should we do that? - if (verbose) { - if (file.isFile()) out.format(fmt_removed_file, file); - if (file.isDirectory()) out.format(fmt_removed_dir, file); + if (prompt) { + if (!prompt(String.format(fmt_ask_remove_dir, file))) { + return skip("", file); + } } - deleteOk = file.delete(); - if (!deleteOk) { - err.format(fmt_not_removed, file); + return rmdir(file); + } else { + if (prompt) { + if (!prompt(String.format(fmt_ask_remove_file, file))) { + return skip("", file); + } } + return unlink(file); } - return deleteOk; } - private boolean prompt_yn(String s) { - int choice; - for (;;) { - out.print(s + " [y/n]"); + private boolean prompt(String s) { + return IOUtils.promptYesOrNo(in, out, s); + } + + private boolean checkMount(File file) { + // This is wrong, as the directory might have been given on the + // command line, which means regardless of the value of onefs, we will continue. + // The proper way would be to check that this directory resides on the same file + // system as the directory given on the command line. + if (onefs) { try { - choice = in.read(); - } catch (IOException _) { - choice = 0; + if (fss.isMount(file.getCanonicalPath())) { + return false; + } + } catch (IOException e) { + return false; } - out.println(); - if (choice == 'y' || choice == 'n') break; } - - return choice == 'y'; + return true; } + + private boolean isWriteable(File file) { + try { + return file.canWrite(); + } catch (SecurityException e) { + return false; + } + } + + private boolean rmdir(File file) { + if (!file.delete()) { + return error(fmt_not_removed, file); + } + if (verbose) { + out.format(fmt_removed_dir, file); + } + return true; + } + + private boolean unlink(File file) { + if (!file.delete()) { + return error(fmt_not_removed, file); + } + if (verbose) { + out.format(fmt_removed_file, file); + } + return true; + } + + private boolean skip(String msg, File file) { + if (!force) { + err.format(fmt_skip, file, msg); + } + return false; + } + + private boolean error(String msg, Object... args) { + if (verbose) { + err.format(msg, args); + } + return false; + } } Modified: trunk/cli/src/commands/org/jnode/command/util/IOUtils.java =================================================================== --- trunk/cli/src/commands/org/jnode/command/util/IOUtils.java 2009-04-30 14:11:06 UTC (rev 5373) +++ trunk/cli/src/commands/org/jnode/command/util/IOUtils.java 2009-05-01 00:27:40 UTC (rev 5374) @@ -462,8 +462,6 @@ input = reader.readLine(); } catch (IOException e) { return null; - } finally { - out.println(); } return input; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <chr...@us...> - 2009-05-01 07:09:30
|
Revision: 5376 http://jnode.svn.sourceforge.net/jnode/?rev=5376&view=rev Author: chrisboertien Date: 2009-05-01 07:09:28 +0000 (Fri, 01 May 2009) Log Message: ----------- Improved df impl Support for -h/-H/-B/-k switches Signed-off-by: chrisboertien <chr...@gm...> Modified Paths: -------------- trunk/cli/descriptors/org.jnode.command.file.xml trunk/cli/src/commands/org/jnode/command/file/DFCommand.java Modified: trunk/cli/descriptors/org.jnode.command.file.xml =================================================================== --- trunk/cli/descriptors/org.jnode.command.file.xml 2009-05-01 06:59:13 UTC (rev 5375) +++ trunk/cli/descriptors/org.jnode.command.file.xml 2009-05-01 07:09:28 UTC (rev 5376) @@ -100,8 +100,31 @@ </sequence> </syntax> <syntax alias="df"> - <empty description="display disk usage for all filesystems"/> - <argument argLabel="device" description="display disk usage for the filesystem on a device"/> + <sequence description="display disk usage for file systems"> + <optionSet> + <option argLabel="human-read-bin" shortName="h" longName="human-readable"/> + <option argLabel="human-read-dec" shortName="H" longName="si"/> + <option argLabel="show-all" shortName="a" longName="all"/> + <option argLabel="block-size" shortName="B" longName="block-size"/> + <option argLabel="block-size-1k" shortName="k"/> + <!-- + <option argLabel="posix" shortName="P" longName="portability"/> + <option argLabel="inodes" shortName="i" longName="inodes"/> + <option argLabel="local" shortName="l" longName="local"/> + <option argLabel="sync" longName="sync"/> + <option argLabel="no-sync" longName="no-sync"/> + <option argLabel="fs-type" shortName="t" longName="type"/> + <option argLabel="print-type" shortName="T" longName="print-type"/> + <option argLabel="ex-type" shortName="x" longName="exclude-type"/> + --> + </optionSet> + <optional> + <alternatives> + <argument argLabel="path"/> + <argument argLabel="device"/> + </alternatives> + </optional> + </sequence> </syntax> <syntax alias="dir"> <empty description="list the current directory"/> @@ -231,7 +254,9 @@ <optional eager="true"> <option argLabel="recursive" shortName="r" longName="recursive"/> </optional> - <repeat minCount="1"><argument argLabel="paths"/></repeat> + <repeat minCount="1"> + <argument argLabel="paths"/> + </repeat> </sequence> </syntax> <syntax alias="mkdir"> @@ -297,5 +322,14 @@ <permission class="java.io.RuntimePermission" name="writeFileDescriptor"/> <permission class="java.util.PropertyPermission" name="user.dir" actions="read,write"/> <permission class="java.util.PropertyPermission" name="user.home" actions="read,write"/> + <permission class="java.lang.RuntimePermission" name="getenv.*" actions="read"/> + <!-- + <permission class="java.lang.RuntimePermission" name="getenv.POSIXLY_CORRECT" actions="read"/> + <permission class="java.lang.RuntimePermission" name="getenv.DF_BLOCK_SIZE" actions="read"/> + <permission class="java.lang.RuntimePermission" name="genenv.DU_BLOCK_SIZE" actions="read"/> + <permission class="java.lang.RuntimePermission" name="getenv.LS_BLOCK_SIZE" actions="read"/> + <permission class="java.lang.RuntimePermission" name="getenv.BLOCK_SIZE" actions="read"/> + <permission class="java.lang.RuntimePermission" name="getenv.BLOCKSIZE" actions="read"/> + --> </extension> </plugin> Modified: trunk/cli/src/commands/org/jnode/command/file/DFCommand.java =================================================================== --- trunk/cli/src/commands/org/jnode/command/file/DFCommand.java 2009-05-01 06:59:13 UTC (rev 5375) +++ trunk/cli/src/commands/org/jnode/command/file/DFCommand.java 2009-05-01 07:09:28 UTC (rev 5376) @@ -26,6 +26,8 @@ import javax.naming.NameNotFoundException; +import java.io.File; + import org.jnode.driver.Device; import org.jnode.driver.DeviceManager; import org.jnode.fs.FileSystem; @@ -34,6 +36,10 @@ import org.jnode.shell.AbstractCommand; import org.jnode.shell.syntax.Argument; import org.jnode.shell.syntax.DeviceArgument; +import org.jnode.shell.syntax.FileArgument; +import org.jnode.shell.syntax.FlagArgument; +import org.jnode.shell.syntax.IntegerArgument; +import org.jnode.util.NumberUtils; /** * The DF command prints disk usage information for devices with filesystems. @@ -41,13 +47,21 @@ * @author ga...@jn... * @author cr...@jn... * @author Levente S\u00e1ntha + * @author chris boertien */ public class DFCommand extends AbstractCommand { private static final String help_device = "The device for which disk usage information should be displayed"; + private static final String help_path = "Display disk usage info for the file system that contains this path"; + private static final String help_read_dec = "Print output in human readable decimal form (1000)"; + private static final String help_read_bin = "Print output in human readable binary form (1024)"; + private static final String help_all = "Show all file systems, even pseudo file systems"; + private static final String help_block_1k = "Same as -B 1024"; + private static final String help_block = "Print output with a specified block size"; private static final String help_super = "Print file system usage information"; private static final String str_id = "ID"; private static final String str_size = "Size"; + private static final String str_blocks = "blocks"; private static final String str_used = "Used"; private static final String str_free = "Free"; private static final String str_mount = "Mount"; @@ -55,44 +69,110 @@ private static final String str_unknown = "unknown"; private static final String err_get_info = "\tError getting disk usage information for %s on %s : %s%n"; + private static final int OUT_BINARY = 1; + private static final int OUT_DECIMAL = 2; + private static final int OUT_BLOCKS = 3; + + private static final int DEFAULT_BLOCK_SIZE = 1024; + private final DeviceArgument argDevice; - + private final FileArgument argPath; + private final FlagArgument argReadDec; + private final FlagArgument argReadBin; + private final FlagArgument argAll; + private final FlagArgument argBlock1k; + private final IntegerArgument argBlock; + + private StringBuilder line; + private FileSystemService fss; + private DeviceManager dm; + private Map<String, String> mountPoints; + private PrintWriter out; + private int outputType; + private int blockSize; + private boolean all; + public DFCommand() { super(help_super); - argDevice = new DeviceArgument("device", Argument.OPTIONAL | Argument.EXISTING, help_device); - registerArguments(argDevice); + argDevice = new DeviceArgument("device", Argument.EXISTING, help_device); + argPath = new FileArgument("path", Argument.EXISTING, help_path); + argReadDec = new FlagArgument("human-read-dec", 0, help_read_dec); + argReadBin = new FlagArgument("human-read-bin", 0, help_read_bin); + argAll = new FlagArgument("show-all", 0, help_all); + argBlock1k = new FlagArgument("block-size-1k", 0, help_block_1k); + argBlock = new IntegerArgument("block-size", 0, help_block); + registerArguments(argDevice, argPath, argReadDec, argReadBin, argAll, argBlock1k, argBlock); } - - public void execute() throws NameNotFoundException { - final FileSystemService fss = InitialNaming.lookup(FileSystemService.NAME); - final Map<String, String> mountPoints = fss.getDeviceMountPoints(); - PrintWriter out = getOutput().getPrintWriter(false); - format(out, str_id, true); - format(out, str_size, false); - format(out, str_used, false); - format(out, str_free, false); - out.println(str_mount); - out.println(); - if (argDevice.isSet()) { - final Device dev = argDevice.getValue(); - FileSystem<?> fs = fss.getFileSystem(dev); - if (fs == null) { - out.println(str_no_fs); - } else { - displayInfo(out, dev, fs, mountPoints.get(fs.getDevice().getId())); - } + + public void execute() throws NameNotFoundException, IOException { + parseOptions(); + fss = InitialNaming.lookup(FileSystemService.NAME); + dm = InitialNaming.lookup(DeviceManager.NAME); + mountPoints = fss.getDeviceMountPoints(); + out = getOutput().getPrintWriter(true); + line = new StringBuilder(); + + Device device = null; + + printHeader(); + + if (argPath.isSet()) { + device = getDeviceForPath(argPath.getValue()); + } else if (argDevice.isSet()) { + device = argDevice.getValue(); } else { - final DeviceManager dm = InitialNaming.lookup(DeviceManager.NAME); for (Device dev : dm.getDevices()) { FileSystem<?> fs = fss.getFileSystem(dev); if (fs != null) { displayInfo(out, dev, fs, mountPoints.get(fs.getDevice().getId())); } } + out.flush(); + exit(0); } - out.flush(); + if (device != null) { + FileSystem<?> fs = fss.getFileSystem(device); + if (fs == null) { + out.println(str_no_fs); + } else { + displayInfo(out, device, fs, mountPoints.get(fs.getDevice().getId())); + } + out.flush(); + exit(0); + } } - + + private Device getDeviceForPath(File file) throws IOException { + String path = file.getCanonicalPath(); + String mp = null; + for (String mountPoint : fss.getMountPoints().keySet()) { + if (path.startsWith(mountPoint)) { + if (mp != null) { + if (!mp.startsWith(mountPoint)) { + continue; + } + } + mp = mountPoint; + } + } + if (mp == null) { + throw new AssertionError("No fs device for " + path); + } + return fss.getMountPoints().get(mp).getDevice(); + } + + private void printHeader() { + format(out, str_id, true); + if (outputType == OUT_BLOCKS) { + format(out, String.format("%s-%s", NumberUtils.toBinaryByte(blockSize), str_blocks), false); + } else { + format(out, str_size, false); + } + format(out, str_used, false); + format(out, str_free, false); + out.println(str_mount); + } + /** * @param out * @param dev @@ -101,27 +181,27 @@ */ private void displayInfo(PrintWriter out, Device dev, FileSystem<?> fs, String mountPoint) { try { - String str = dev.getId(); + long total = fs.getTotalSpace(); + long free = fs.getFreeSpace(); + format(out, str, true); - - final long total = fs.getTotalSpace(); - str = total < 0 ? str_unknown : String.valueOf(total); + + str = total < 0 ? str_unknown : valueOf(total, true); format(out, str, false); - - final long free = fs.getFreeSpace(); - str = total < 0 ? str_unknown : String.valueOf(total - free); + + str = total < 0 ? str_unknown : valueOf(total - free, true); format(out, str, false); - - str = free < 0 ? str_unknown : String.valueOf(free); + + str = free < 0 ? str_unknown : valueOf(free, false); format(out, str, false); - + out.println(mountPoint); } catch (IOException ex) { out.format(err_get_info, mountPoint, dev.getId(), ex.getLocalizedMessage()); } } - + private void format(PrintWriter out, String str, boolean left) { int ln; ln = 15 - str.length(); @@ -138,4 +218,70 @@ } out.print(' '); } + + private String valueOf(long size, boolean up) { + switch(outputType) { + case OUT_DECIMAL : + return NumberUtils.toDecimalByte(size, 0); + case OUT_BINARY : + return NumberUtils.toBinaryByte(size, 0); + case OUT_BLOCKS : + return toBlock(size, blockSize, up); + default : + return String.valueOf(size); + } + } + + private String toBlock(long size, long blockSize, boolean up) { + return String.valueOf(size / blockSize + ((up && ((size % blockSize) > 0)) ? 1 : 0)); + } + + private void parseOptions() { + if (argReadDec.isSet()) { + outputType = OUT_DECIMAL; + } else if (argReadBin.isSet()) { + outputType = OUT_BINARY; + } else { + outputType = OUT_BLOCKS; + } + + all = argAll.isSet(); + + if (argBlock1k.isSet()) { + blockSize = 1024; + } else if (argBlock.isSet()) { + blockSize = argBlock.getValue(); + } else { + blockSize = getDefaultBlock(); + } + } + + private int getDefaultBlock() { + /* Env vars are broken + String DF_BLOCK_SIZE = System.getenv("DF_BLOCK_SIZE"); + String BLOCK_SIZE = System.getenv("BLOCK_SIZE"); + String BLOCKSIZE = System.getenv("BLOCKSIZE"); + String POSIXLY_CORRECT = System.getenv("POSIXLY_CORRECT"); + + String size = null; + if (DF_BLOCK_SIZE != null) { + size = DF_BLOCK_SIZE; + } else if (BLOCK_SIZE != null) { + size = BLOCK_SIZE; + } else if (BLOCKSIZE != null) { + size = BLOCKSIZE; + } else if (POSIXLY_CORRECT != null) { + return 512; + } else { + return DEFAULT_BLOCK_SIZE; + } + + try { + return Integer.parseInt(size); + } catch (NumberFormatException e) { + return DEFAULT_BLOCK_SIZE; + } + */ + return DEFAULT_BLOCK_SIZE; + } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <chr...@us...> - 2009-05-05 21:20:44
|
Revision: 5427 http://jnode.svn.sourceforge.net/jnode/?rev=5427&view=rev Author: chrisboertien Date: 2009-05-05 21:20:25 +0000 (Tue, 05 May 2009) Log Message: ----------- New Argument that represents a list of integers and number ranges. Signed-off-by: chrisboertien <chr...@gm...> Added Paths: ----------- trunk/cli/descriptors/org.jnode.command.argument.xml trunk/cli/src/commands/org/jnode/command/argument/ trunk/cli/src/commands/org/jnode/command/argument/NumberListArgument.java trunk/cli/src/commands/org/jnode/command/util/NumberRange.java Added: trunk/cli/descriptors/org.jnode.command.argument.xml =================================================================== --- trunk/cli/descriptors/org.jnode.command.argument.xml (rev 0) +++ trunk/cli/descriptors/org.jnode.command.argument.xml 2009-05-05 21:20:25 UTC (rev 5427) @@ -0,0 +1,20 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plugin SYSTEM "jnode.dtd"> + +<plugin id="org.jnode.command.argument" + name="JNode command arguments" + version="@VERSION@" + provider-name="@PROVIDER@" + license-name="lgpl"> + + <requires> + <import plugin="org.jnode.shell.syntax"/> + <import plugin="org.jnode.command.util"/> + </requires> + + <runtime> + <library name="jnode-cli.jar"> + <export name="org.jnode.command.argument.*"/> + </library> + </runtime> +</plugin> Added: trunk/cli/src/commands/org/jnode/command/argument/NumberListArgument.java =================================================================== --- trunk/cli/src/commands/org/jnode/command/argument/NumberListArgument.java (rev 0) +++ trunk/cli/src/commands/org/jnode/command/argument/NumberListArgument.java 2009-05-05 21:20:25 UTC (rev 5427) @@ -0,0 +1,193 @@ +/* + * $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.argument; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import org.jnode.command.util.NumberRange; +import org.jnode.driver.console.CompletionInfo; +import org.jnode.shell.CommandLine.Token; +import org.jnode.shell.syntax.CommandSyntaxException; +import org.jnode.shell.syntax.Argument; + +/** + * Captures a list of multiple number ranges. + * + * A number list is represented by a comma delimited list of integers + * and ranges. A range is represented by two integers separated by a hyphen. + * Either of the integers may be omitted (but not both), to represent a range + * that spans from a single point, to the minimum or maximum values of the range. + * + * In other words, this argument captures the following syntax: + * <code> + * list ::= range | list,range + * range ::= integer | -integer | integer- | integer-integer + * <code> + * Note that integer is any number in the range 0-Integer.MAX_VALUE, and may be limited + * to a smaller range via constructor arguments. + * + * When a number list has been captured, it may be altered from the form and order + * it was found in on the command line. The Command can be certain that the ranges + * returned by this argument will have the following properties. + * + * <ul> + * <li>Ranges will never span beyond min/max + * <li>Ranges will be in sorted order. + * <li>Individual ranges will not overlap, or be sequential. Such ranges will be concatenated + * to form a single range. This means that 3-5,4-7 and 3,4,5,6,7 will form the range 3-7. + * </ul> + * + * @author chris boertien + */ +public class NumberListArgument extends Argument<NumberRange> { + + private final String listDelim; + private final String rangeDelim; + private final int min; + private final int max; + + public NumberListArgument(String label, int flags, int min, int max, String desc) { + super(label, flags | Argument.MULTIPLE, new NumberRange[0], desc); + this.rangeDelim = "-"; + this.listDelim = ","; + this.min = min; + this.max = max; + } + + public NumberListArgument(String label, int flags, String desc) { + this(label, flags, Integer.MIN_VALUE + 1, Integer.MAX_VALUE - 1, desc); + } + + @Override + protected NumberRange doAccept(Token token, int flags) throws CommandSyntaxException { + NumberRange[] ranges = parseList(token.text); + if (ranges.length == 1) { + return ranges[0]; + } + + Arrays.sort(ranges); + + // concat + for (int i = 1; i < ranges.length;) { + if (ranges[i - 1].end() >= (ranges[i].start() - 1)) { + ranges = concat(ranges, i - 1, i); + } else { + i++; + } + } + for (int i = 0; i < (ranges.length - 1); i++ ) { + values.add(ranges[i]); + } + return ranges[ranges.length - 1]; + } + + private NumberRange[] concat(NumberRange[] ranges, int i, int j) { + NumberRange[] newRanges = new NumberRange[ranges.length - (j - i)]; + System.arraycopy(ranges, 0, newRanges, 0, i); + if (j < (ranges.length - 1)) { + System.arraycopy(ranges, j + 1, newRanges, j, newRanges.length - j); + } + newRanges[i] = new NumberRange(ranges[i].start(), ranges[j].end(), min - 1, max + 1); + return newRanges; + } + + private static final boolean debug = false; + + private void error(String s) { + if (debug) System.err.println(s); + } + + /** + * Parse a number list + * + * list ::= range | list,range + */ + private NumberRange[] parseList(String text) throws CommandSyntaxException { + int delimPos = text.indexOf(listDelim); + if (delimPos == -1) { + return new NumberRange[] { parseRange(text) }; + } else { + String[] rangesText = text.split(listDelim); + NumberRange[] ranges = new NumberRange[rangesText.length]; + for (int i = 0; i < ranges.length; i++) { + ranges[i] = parseRange(rangesText[i]); + } + return ranges; + } + } + + /** + * Parse a number range. + * + * range ::= integer | -integer | integer- | integer-integer + */ + private NumberRange parseRange(String text) throws CommandSyntaxException { + int delimPos = text.indexOf(rangeDelim); + int start; + int end; + if (text.equals(rangeDelim)) { + throw new CommandSyntaxException("Invalid number range"); + } + if (delimPos == -1) { + // this is ok, as we allow a single integer to represent the range n-n + start = end = parseInt(text); + } else if (delimPos == 0) { + start = min; + end = parseInt(text.substring(rangeDelim.length(), text.length())); + } else if (delimPos == (text.length() - rangeDelim.length())) { + start = parseInt(text.substring(0, delimPos)); + end = max; + } else { + start = parseInt(text.substring(0, delimPos)); + end = parseInt(text.substring(delimPos + rangeDelim.length(), text.length())); + } + try { + return new NumberRange(start, end, min - 1, max + 1); + } catch (IllegalArgumentException ex) { + throw new CommandSyntaxException("Invalid number range"); + } + } + + private int parseInt(String text) throws CommandSyntaxException { + int n; + try { + n = Integer.parseInt(text); + } catch (NumberFormatException ex) { + throw new CommandSyntaxException("Invalid number range"); + } + if (n < min || n > max) { + throw new CommandSyntaxException("Number out of range"); + } + return n; + } + + @Override + protected String state() { + return "min=" + min + ",max=" + max; + } + + @Override + protected String argumentKind() { + return "number-list"; + } +} Added: trunk/cli/src/commands/org/jnode/command/util/NumberRange.java =================================================================== --- trunk/cli/src/commands/org/jnode/command/util/NumberRange.java (rev 0) +++ trunk/cli/src/commands/org/jnode/command/util/NumberRange.java 2009-05-05 21:20:25 UTC (rev 5427) @@ -0,0 +1,204 @@ +/* + * $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.util; + +/** + * An immutable representation of a sequential number range. + * + * A number range uses two number of values to denote points of + * positive and negative infinity. By default, these values are + * Integer.MAX_VALUE and Integer.MIN_VALUE respectively. If start + * or end are equal to or beyond the infinity values, then the + * range is considered to be infinite in that direction. + * + * It is worth noting that the Comparable interface is sensitive + * to the points of positive and negative infinity. Two number ranges + * can have different start and end points and be considered equal if + * both ranges are also infinite in that direction. + * + * @author chris boertien + * @see {@link org.jnode.command.argument.NumberRangeArgument} + */ +public final class NumberRange implements Comparable<NumberRange> { + + private final int start; + private final int end; + private final int negativeInfinity; + private final int positiveInfinity; + + /** + * Creates a number range. + * + * This number range uses posInf and negInf to denote positive and negative + * infinity respectively. + * + * @param start the start of the range + * @param end the end of the range + * @param posInf the point of positive infinity + * @param negInf the point of negative infinity + * @throws IllegalArgumentException if start > end or negInf >= posInf + */ + public NumberRange(int start, int end, int negInf, int posInf) { + if (start > end) { + throw new IllegalArgumentException("start > end"); + } + if (negInf >= posInf) { + throw new IllegalArgumentException("negInf >= posInf"); + } + this.start = start; + this.end = end; + this.negativeInfinity = negInf; + this.positiveInfinity = posInf; + } + + /** + * Creates a number range. + * + * This number range uses Integer.MAX_VALUE and Integer.MIN_VALUE to denote + * positive and negative infinity respectively. + * + * @param start the start of the range + * @param end the end of the range + * @throws IllegalArgumentException if start > end + */ + public NumberRange(int start, int end) { + this(start, end, Integer.MIN_VALUE, Integer.MAX_VALUE); + } + + /** + * Compares this NumberRange to another NumberRange for order. + * + * NumberRanges are ordered first by their start position, and second + * by their end position. + * + * A NumberRange that is negatively infinite is considered less than one that + * is not negatively infinite. Also a NumberRange that is not positively infinite + * is considered less than one that is positively infinite. + * + * @param that the NumberRange to compare this one to + * @return -1 if this comes before that, 1 if that comes before this, 0 if they are equal + * @see {@link #equals} + */ + public int compareTo(NumberRange that) { + if (equals(that)) { + return 0; + } + + boolean a1 = isStartInfinite(); + boolean a2 = isEndInfinite(); + boolean b1 = that.isStartInfinite(); + boolean b2 = that.isEndInfinite(); + + if (a1 ^ b1) { + return a1 ? -1 : 1; + } + if ((a1 && b1) || (start == that.start)) { + if (a2 ^ b2) { + return a2 ? -1 : 1; + } + return end - that.end; + } + return start - that.start; + } + + /** + * Tests this NumberRange for equivalence to that NumberRange. + * + * Two NumberRanges are considered equal if: + * <ul> + * <li>if both are negatively infinite AND both are positively infinite + * <li>if both are negatively infinite AND neither are positively infinite AND both have the same end point. + * <li>if neither are negatively infinite AND both have the same start point AND both are positvely infinite + * <li>if neither are negatively infinite AND both have the same start point AND + * neither are positively infinite AND both have the same end point. + * </ul> + * + * @param that the NumberRage to compare with + * @return true if both NumberRanges are equal + */ + public boolean equals(NumberRange that) { + boolean a1 = isStartInfinite(); + boolean a2 = isEndInfinite(); + boolean b1 = that.isStartInfinite(); + boolean b2 = that.isEndInfinite(); + + return ((a1 && b1) || (!(a1 ^ b1) && (start == that.start))) + && ((a2 && b2) || (!(a2 ^ b2) && (end == that.end))); + } + + @Override + public boolean equals(Object that) { + if (this == that) { + return true; + } + if (!(that instanceof NumberRange)) { + return false; + } + return equals((NumberRange) that); + } + + @Override + public String toString() { + return start + "-" + end; + } + + /** + * The starting position of this number range. + * + * Even if the start value is beyond the negative infinity point + * this will still return the value of the start position. + * + * @return the start + */ + public int start() { + return start; + } + + /** + * The ending position of this number range. + * + * Even if the end value is beyond the positive infinity point + * this will still return the value of the start position. + * + * @return the end + */ + public int end() { + return end; + } + + /** + * Does this NumberRange represent a range that is positively infinite. + * + * @return true if the end position is >= positive infinity. + */ + public boolean isEndInfinite() { + return end >= positiveInfinity; + } + + /** + * Does this NumberRange represent a range that is negatively infinite. + * + * @return true if the start positition is <= negative infinity + */ + public boolean isStartInfinite() { + return start <= negativeInfinity; + } +} This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <chr...@us...> - 2009-05-05 21:24:13
|
Revision: 5429 http://jnode.svn.sourceforge.net/jnode/?rev=5429&view=rev Author: chrisboertien Date: 2009-05-05 21:24:04 +0000 (Tue, 05 May 2009) Log Message: ----------- Blackbox tests for cut and the new argument. Signed-off-by: chrisboertien <chr...@gm...> Modified Paths: -------------- trunk/cli/build-tests.xml trunk/cli/src/test/org/jnode/test/command/all-tests.xml trunk/cli/src/test/org/jnode/test/command/file/all-file-tests.xml Added Paths: ----------- trunk/cli/src/test/org/jnode/test/command/argument/ trunk/cli/src/test/org/jnode/test/command/argument/all-argument-tests.xml trunk/cli/src/test/org/jnode/test/command/file/cut-command-tests.xml Modified: trunk/cli/build-tests.xml =================================================================== --- trunk/cli/build-tests.xml 2009-05-05 21:22:20 UTC (rev 5428) +++ trunk/cli/build-tests.xml 2009-05-05 21:24:04 UTC (rev 5429) @@ -5,20 +5,50 @@ <target name="help" description="output target descriptions"> <echo> The main targets (tests) for this build are as follows: -all Runs all tests for the 'cli' project -help Output these messages +all Runs all tests for the 'cli' project +all-junit Runs all JUnit tests for the 'cli' project +blackbox-common Runs all blackbox tests in the 'common' package of the 'cli' project +blackbox-file Runs all blackbox tests in the 'file' package of the 'cli' project +all-blackbox Runs all blackbox tests for the 'cli' project +help Output these messages </echo> </target> - <target name="all"> - <java classpathref="cp-test" classname="org.jnode.test.shell.harness.TestHarness"> + <target name="all-junit"> + <junit showoutput="on" printsummary="on" fork="on"> + <classpath refid="cp-test"/> + <test name="org.jnode.test.cli.CLITestSuite"/> + </junit> + </target> + + <target name="blackbox-common"> + <java classpathref="cp-test" classname="org.jnode.test.shell.harness.TestHarness"> + <arg value="-E"/> + <arg value="-s"/> + <arg value="${root.dir}"/> + <arg value="${basedir}/src/test/org/jnode/test/command/common/all-common-tests.xml"/> + </java> + </target> + + <target name="blackbox-file"> + <java classpathref="cp-test" classname="org.jnode.test.shell.harness.TestHarness"> + <arg value="-E"/> + <arg value="-s"/> + <arg value="${root.dir}"/> + <arg value="${basedir}/src/test/org/jnode/test/command/file/all-file-tests.xml"/> + </java> + </target> + + <target name="all-blackbox"> + <java classpathref="cp-test" classname="org.jnode.test.shell.harness.TestHarness"> <arg value="-E"/> <arg value="-s"/> <arg value="${root.dir}"/> <arg value="${basedir}/src/test/org/jnode/test/command/all-tests.xml"/> </java> </target> - + + <target name="all" depends="all-junit,all-blackbox"/> </project> Modified: trunk/cli/src/test/org/jnode/test/command/all-tests.xml =================================================================== --- trunk/cli/src/test/org/jnode/test/command/all-tests.xml 2009-05-05 21:22:20 UTC (rev 5428) +++ trunk/cli/src/test/org/jnode/test/command/all-tests.xml 2009-05-05 21:24:04 UTC (rev 5429) @@ -1,4 +1,5 @@ <testSet title="All command tests"> + <include setName="argument/all-argument-tests.xml"/> <include setName="common/all-common-tests.xml"/> <include setName="file/all-file-tests.xml"/> </testSet> Added: trunk/cli/src/test/org/jnode/test/command/argument/all-argument-tests.xml =================================================================== --- trunk/cli/src/test/org/jnode/test/command/argument/all-argument-tests.xml (rev 0) +++ trunk/cli/src/test/org/jnode/test/command/argument/all-argument-tests.xml 2009-05-05 21:24:04 UTC (rev 5429) @@ -0,0 +1,83 @@ +<testSet title="argument tests"> + <plugin id="org.jnode.command.file"/> + <testSpec title="num-list concat 1" command="cut" runMode="AS_ALIAS" rc="0"> + <arg>-b</arg> + <arg>3,5,7</arg> + <input>1234567890 +</input> + <output>357 +</output> + </testSpec> + <testSpec title="num-list concat 2" command="cut" runMode="AS_ALIAS" rc="0"> + <arg>-b</arg> + <arg>-3,7-</arg> + <input>1234567890 +</input> + <output>1237890 +</output> + </testSpec> + <testSpec title="num-list concat 3" command="cut" runMode="AS_ALIAS" rc="0"> + <arg>-b</arg> + <arg>3,4-6,7</arg> + <input>1234567890 +</input> + <output>34567 +</output> + </testSpec> + <testSpec title="num-list concat 4" command="cut" runMode="AS_ALIAS" rc="0"> + <arg>-b</arg> + <arg>1-2,3,5,6-7,9-10</arg> + <input>1234567890 +</input> + <output>12356790 +</output> + </testSpec> + <testSpec title="num-list concat 5" command="cut" runMode="AS_ALIAS" rc="0"> + <arg>-b</arg> + <arg>-3,-2</arg> + <input>1234567890 +</input> + <output>123 +</output> + </testSpec> + <testSpec title="num-list concat 6" command="cut" runMode="AS_ALIAS" rc="0"> + <arg>-b</arg> + <arg>9-,5-,7-8,6</arg> + <input>1234567890 +</input> + <output>567890 +</output> + </testSpec> + <testSpec title="num-list sort 1" command="cut" runMode="AS_ALIAS" rc="0"> + <arg>-b</arg> + <arg>7,1,5,9,3</arg> + <input>1234567890 +</input> + <output>13579 +</output> + </testSpec> + <arg>-b</arg> + <testSpec title="num-list sort 2" command="cut" runMode="AS_ALIAS" rc="0"> + <arg>6-7,5,9-10,2,3,1</arg> + <input>1234567890 +</input> + <output>12356790 +</output> + </testSpec> + <testSpec title="num-list sort 3" command="cut" runMode="AS_ALIAS" rc="0"> + <arg>-b</arg> + <arg>7-,-3</arg> + <input>1234567890 +</input> + <output>1237890 +</output> + </testSpec> + <testSpec title="num-list sort 4" command="cut" runMode="AS_ALIAS" rc="0"> + <arg>-b</arg> + <arg>5,-4,6-</arg> + <input>1234567890 +</input> + <output>1234567890 +</output> + </testSpec> +</testSet> 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-05-05 21:22:20 UTC (rev 5428) +++ trunk/cli/src/test/org/jnode/test/command/file/all-file-tests.xml 2009-05-05 21:24:04 UTC (rev 5429) @@ -1,3 +1,4 @@ <testSet title="All file command tests"> <include setName="wc-command-tests.xml"/> + <include setName="cut-command-tests.xml"/> </testSet> Added: trunk/cli/src/test/org/jnode/test/command/file/cut-command-tests.xml =================================================================== --- trunk/cli/src/test/org/jnode/test/command/file/cut-command-tests.xml (rev 0) +++ trunk/cli/src/test/org/jnode/test/command/file/cut-command-tests.xml 2009-05-05 21:24:04 UTC (rev 5429) @@ -0,0 +1,133 @@ +<testSet title="POSIX cut command tests"> + <plugin id="org.jnode.command.file"/> + <testSpec title="cut byte-range 1" command="cut" runMode="AS_ALIAS" rc="0"> + <arg>-b</arg> + <arg>3-7</arg> + <input>1234567890 +</input> + <output>34567 +</output> + </testSpec> + <testSpec title="cut byte-range 2" command="cut" runMode="AS_ALIAS" rc="0"> + <arg>-b</arg> + <arg>-7</arg> + <input>1234567890 +</input> + <output>1234567 +</output> + </testSpec> + <testSpec title="cut byte-range 3" command="cut" runMode="AS_ALIAS" rc="0"> + <arg>-b</arg> + <arg>3-</arg> + <input>1234567890 +</input> + <output>34567890 +</output> + </testSpec> + <testSpec title="cut char-range 1" command="cut" runMode="AS_ALIAS" rc="0"> + <arg>-c</arg> + <arg>3-7</arg> + <input>1234567890 +</input> + <output>34567 +</output> + </testSpec> + <testSpec title="cut char-range 2" command="cut" runMode="AS_ALIAS" rc="0"> + <arg>-c</arg> + <arg>-7</arg> + <input>1234567890 +</input> + <output>1234567 +</output> + </testSpec> + <testSpec title="cut char-range 3" command="cut" runMode="AS_ALIAS" rc="0"> + <arg>-c</arg> + <arg>3-</arg> + <input>1234567890 +</input> + <output>34567890 +</output> + </testSpec> + <!-- The next 3 tests have <TAB>s in the input/output, make sure an editor does not + expand them to spaces! --> + <testSpec title="cut field-range default 1" command="cut" runMode="AS_ALIAS" rc="0"> + <arg>-f</arg> + <arg>3-7</arg> + <input>1 2 3 4 5 6 7 8 9 0 +</input> + <output>3 4 5 6 7 +</output> + </testSpec> + <testSpec title="cut field-range default 2" command="cut" runMode="AS_ALIAS" rc="0"> + <arg>-f</arg> + <arg>3-</arg> + <input>1 2 3 4 5 6 7 8 9 0 +</input> + <output>3 4 5 6 7 8 9 0 +</output> + </testSpec> + <testSpec title="cut field-range default 3" command="cut" runMode="AS_ALIAS" rc="0"> + <arg>-f</arg> + <arg>-7</arg> + <input>1 2 3 4 5 6 7 8 9 0 +</input> + <output>1 2 3 4 5 6 7 +</output> + </testSpec> + <testSpec title="cut field-range alt-delim 1" command="cut" runMode="AS_ALIAS" rc="0"> + <arg>-d</arg> + <arg>;</arg> + <arg>-f</arg> + <arg>3-7</arg> + <input>1;2;3;4;5;6;7;8;9;0 +</input> + <output>3;4;5;6;7 +</output> + </testSpec> + <testSpec title="cut field-range alt-delim 2" command="cut" runMode="AS_ALIAS" rc="0"> + <arg>-d</arg> + <arg>;</arg> + <arg>-f</arg> + <arg>3-</arg> + <input>1;2;3;4;5;6;7;8;9;0 +</input> + <output>3;4;5;6;7;8;9;0 +</output> + </testSpec> + <testSpec title="cut field-range alt-delim 3" command="cut" runMode="AS_ALIAS" rc="0"> + <arg>-d</arg> + <arg>;</arg> + <arg>-f</arg> + <arg>-7</arg> + <input>1;2;3;4;5;6;7;8;9;0 +</input> + <output>1;2;3;4;5;6;7 +</output> + </testSpec> + <testSpec title="cut field-range out-delim" command="cut" runMode="AS_ALIAS" rc="0"> + <arg>-d</arg> + <arg>;</arg> + <arg>-f</arg> + <arg>3-7</arg> + <arg>--output-delimiter</arg> + <arg>:</arg> + <input>1;2;3;4;5;6;7;8;9;0 +</input> + <output>3:4:5:6:7 +</output> + </testSpec> + <testSpec title="cut suppress" command="cut" runMode="AS_ALIAS" rc="0"> + <arg>-d</arg> + <arg>;</arg> + <arg>-f</arg> + <arg>3-7</arg> + <arg>-s</arg> + <input>1;2;3;4;5;6;7;8;9;0 +1:2:3:4:5:6:7:8:9:0 +1;2;3;4;5;6;7;8;9;0 +</input> + <output>3;4;5;6;7 +3;4;5;6;7 +</output> + </testSpec> +</testSet> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <chr...@us...> - 2009-05-11 22:52:47
|
Revision: 5480 http://jnode.svn.sourceforge.net/jnode/?rev=5480&view=rev Author: chrisboertien Date: 2009-05-11 22:52:39 +0000 (Mon, 11 May 2009) Log Message: ----------- Unix 'paste' command + blackbox tests Signed-off-by: chrisboertien <chr...@gm...> Modified Paths: -------------- trunk/cli/descriptors/org.jnode.command.file.xml trunk/cli/src/commands/org/jnode/command/util/IOUtils.java trunk/cli/src/test/org/jnode/test/command/argument/all-argument-tests.xml trunk/cli/src/test/org/jnode/test/command/file/all-file-tests.xml Added Paths: ----------- trunk/cli/src/commands/org/jnode/command/file/PasteCommand.java trunk/cli/src/test/org/jnode/test/command/file/paste-command-tests.xml Modified: trunk/cli/descriptors/org.jnode.command.file.xml =================================================================== --- trunk/cli/descriptors/org.jnode.command.file.xml 2009-05-11 20:26:47 UTC (rev 5479) +++ trunk/cli/descriptors/org.jnode.command.file.xml 2009-05-11 22:52:39 UTC (rev 5480) @@ -38,8 +38,8 @@ <alias name="hexdump" class="org.jnode.command.file.HexdumpCommand"/> <alias name="ls" class="org.jnode.command.file.DirCommand"/> <alias name="md5sum" class="org.jnode.command.file.Md5SumCommand"/> - <!-- NoSuchAlgorithmException: md5 Message Digest not available --> <alias name="mkdir" class="org.jnode.command.file.MkdirCommand"/> + <alias name="paste" class="org.jnode.command.file.PasteCommand"/> <alias name="pwd" class="org.jnode.command.file.PwdCommand"/> <alias name="rm" class="org.jnode.command.file.DeleteCommand"/> <alias name="tail" class="org.jnode.command.file.TailCommand"/> @@ -280,6 +280,18 @@ <syntax alias="mkdir"> <argument argLabel="directory" description="create a new directory"/> </syntax> + <syntax alias="paste"> + <empty /> + <sequence> + <optionSet> + <option argLabel="serial" shortName="s" longName="serial"/> + <option argLabel="delims" shortName="d" longName="delimiters"/> + </optionSet> + <repeat> + <argument argLabel="files"/> + </repeat> + </sequence> + </syntax> <syntax alias="pwd"> <empty description="show the pathname for the current directory"/> </syntax> Added: trunk/cli/src/commands/org/jnode/command/file/PasteCommand.java =================================================================== --- trunk/cli/src/commands/org/jnode/command/file/PasteCommand.java (rev 0) +++ trunk/cli/src/commands/org/jnode/command/file/PasteCommand.java 2009-05-11 22:52:39 UTC (rev 5480) @@ -0,0 +1,191 @@ +/* + * $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.BufferedReader; +import java.io.File; +import java.io.IOException; +import java.io.PrintWriter; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import org.jnode.command.argument.NumberListArgument; +import org.jnode.command.util.IOUtils; +import org.jnode.command.util.NumberRange; +import org.jnode.shell.AbstractCommand; +import org.jnode.shell.syntax.Argument; +import org.jnode.shell.syntax.FileArgument; +import org.jnode.shell.syntax.FlagArgument; +import org.jnode.shell.syntax.StringArgument; + +/** + * Unix 'paste' command + * + * @author chris boertien + */ +public class PasteCommand extends AbstractCommand { + + private static final String help_files = "list of files to be operated on"; + private static final String help_serial = "if set, paste files one at a time, instead of in parallel"; + private static final String help_delims = "use the supplied characters as delimiters instead of <TAB>"; + private static final String help_super = "merge lines of files"; + + private final FileArgument argFiles; + private final FlagArgument argSerial; + private final StringArgument argDelims; + private PrintWriter out; + + private List<File> files; + private char[] delims; + private int delimPos; + private int rc = 0; + private boolean serial; + + public PasteCommand() { + super(help_super); + int filesFlags = Argument.MULTIPLE | Argument.EXISTING | FileArgument.HYPHEN_IS_SPECIAL; + argFiles = new FileArgument("files", filesFlags, help_files); + argSerial = new FlagArgument("serial", 0, help_serial); + argDelims = new StringArgument("delims", 0, help_delims); + registerArguments(argFiles, argSerial, argDelims); + } + + public void execute() { + out = getOutput().getPrintWriter(); + parseOptions(); + try { + if (serial) { + pasteSerial(); + } else { + pasteParallel(); + } + } finally { + exit(rc); + } + } + + private void pasteParallel() { + List<BufferedReader> readers = new ArrayList<BufferedReader>(files.size()); + List<String> names = new ArrayList<String>(files.size()); + List<String> lines = new ArrayList<String>(files.size()); + try { + for (File file : files) { + String name = file.getName(); + int i = names.indexOf(name); + if (i != -1) { + readers.add(readers.get(i)); + } else { + if (name.equals("-")) { + readers.add(IOUtils.openBufferedReader(getInput().getReader())); + } else { + readers.add(IOUtils.openBufferedReader(file)); + } + } + names.add(name); + } + while (true) { + int num = readLines(lines, readers); + if (num == 0) break; + writeLines(lines, num); + lines.clear(); + } + } finally { + for (BufferedReader reader : readers) { + IOUtils.close(reader); + } + } + } + + private void pasteSerial() { + BufferedReader reader = null; + for (File file : files) { + try { + List<String> lines = null; + if (file.getName().equals("-")) { + reader = IOUtils.openBufferedReader(getInput().getReader()); + } else { + reader = IOUtils.openBufferedReader(file); + } + if (reader != null) { + lines = IOUtils.readLines(reader); + if (lines != null) { + writeLines(lines, lines.size()); + } + } + } finally { + IOUtils.close(reader); + } + } + } + + private int readLines(List<String> lines, List<BufferedReader> readers) { + int count = 0; + String line = null; + for (BufferedReader reader : readers) { + try { + line = reader.readLine(); + } catch (IOException e) { + rc = 1; + return 0; + } + if (line != null) { + lines.add(line); + count++; + } + } + return count; + } + + private void writeLines(List<String> lines, int max) { + boolean first = true; + for (int i = 0; i < max; i++) { + if (!first) { + out.write(nextDelim()); + } + first = false; + out.write(lines.get(i)); + } + out.println(); + delimPos = 0; + } + + private char nextDelim() { + char c = delims[delimPos++]; + if (delimPos == delims.length) delimPos = 0; + return c; + } + + private void parseOptions() { + if (argFiles.isSet()) { + files = Arrays.asList(argFiles.getValues()); + } else { + files = new ArrayList(1); + files.add(new File("-")); + } + + if (argDelims.isSet()) { + delims = argDelims.getValue().toCharArray(); + } else { + delims = new char[]{'\t'}; + } + serial = argSerial.isSet(); + } +} Modified: trunk/cli/src/commands/org/jnode/command/util/IOUtils.java =================================================================== --- trunk/cli/src/commands/org/jnode/command/util/IOUtils.java 2009-05-11 20:26:47 UTC (rev 5479) +++ trunk/cli/src/commands/org/jnode/command/util/IOUtils.java 2009-05-11 22:52:39 UTC (rev 5480) @@ -298,6 +298,30 @@ } /** + * Wraps a {@code Reader} with a {@code BufferedReader}. + * + * @param reader the reader to wrap + * @return a {@code BufferedReader} + * @throws NullPointerException if reader is null + */ + public static BufferedReader openBufferedReader(Reader reader) { + return openBufferedReader(reader, BUFFER_SIZE); + } + + /** + * Wraps a {@code Reader} with a {@code BufferedReader}. + * + * @param reader the reader to wrap + * @param bufferSize the size of buffer to use + * @return a {@code BufferedReader} + * @throws NullPointerException if reader is null + */ + public static BufferedReader openBufferedReader(Reader reader, int bufferSize) { + checkNull(reader); + return new BufferedReader(reader, bufferSize); + } + + /** * Opens a LineNumberReader on a file. * * This method will not throw a FileNotFoundException like the FileReader Modified: trunk/cli/src/test/org/jnode/test/command/argument/all-argument-tests.xml =================================================================== --- trunk/cli/src/test/org/jnode/test/command/argument/all-argument-tests.xml 2009-05-11 20:26:47 UTC (rev 5479) +++ trunk/cli/src/test/org/jnode/test/command/argument/all-argument-tests.xml 2009-05-11 22:52:39 UTC (rev 5480) @@ -56,8 +56,8 @@ <output>13579 </output> </testSpec> + <testSpec title="num-list sort 2" command="cut" runMode="AS_ALIAS" rc="0"> <arg>-b</arg> - <testSpec title="num-list sort 2" command="cut" runMode="AS_ALIAS" rc="0"> <arg>6-7,5,9-10,2,3,1</arg> <input>1234567890 </input> 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-05-11 20:26:47 UTC (rev 5479) +++ trunk/cli/src/test/org/jnode/test/command/file/all-file-tests.xml 2009-05-11 22:52:39 UTC (rev 5480) @@ -1,5 +1,6 @@ <testSet title="All file command tests"> + <include setName="cut-command-tests.xml"/> + <include setName="paste-command-tests.xml"/> <include setName="wc-command-tests.xml"/> - <include setName="cut-command-tests.xml"/> </testSet> Added: trunk/cli/src/test/org/jnode/test/command/file/paste-command-tests.xml =================================================================== --- trunk/cli/src/test/org/jnode/test/command/file/paste-command-tests.xml (rev 0) +++ trunk/cli/src/test/org/jnode/test/command/file/paste-command-tests.xml 2009-05-11 22:52:39 UTC (rev 5480) @@ -0,0 +1,131 @@ +<testSet title="POSIX paste command tests"> + <plugin id="org.jnode.command.file"/> + <plugin id="org.jnode.shell.bjorne" class="org.jnode.test.shell.bjorne.BjornePseudoPlugin"/> + <testSpec title="serial stdin default-delim" command="paste" runMode="AS_ALIAS" rc="0"> + <arg>-s</arg> + <input>1 +2 +3 +4 +</input> + <output>1 2 3 4 +</output> + </testSpec> + <testSpec title="title serial stdin single-delim" command="paste" runMode="AS_ALIAS" rc="0"> + <arg>-s</arg> + <arg>-d</arg> + <arg>;</arg> + <input>1 +2 +3 +4 +</input> + <output>1;2;3;4 +</output> + </testSpec> + <testSpec title="serial stdin multi-delim 1" command="paste" runMode="AS_ALIAS" rc="0"> + <arg>-s</arg> + <arg>-d</arg> + <arg>;:,</arg> + <input>1 +2 +3 +4 +</input> + <output>1;2:3,4 +</output> + </testSpec> + <testSpec title="serial stdin multi-delim 2" command="paste" runMode="AS_ALIAS" rc="0"> + <arg>-s</arg> + <arg>-d</arg> + <arg>;:</arg> + <input>1 +2 +3 +4 +</input> + <output>1;2:3;4 +</output> + </testSpec> + <testSpec title="parallel stdin default-delim" command="paste" runMode="AS_ALIAS" rc="0"> + <input>1 +2 +3 +4 +</input> + <output>1 +2 +3 +4 +</output> + </testSpec> + <testSpec title="parallel stdin-multi single-delim" command="paste" runMode="AS_ALIAS" rc="0"> + <arg>-d</arg> + <arg>;</arg> + <arg>-</arg> + <arg>-</arg> + <input>1 +2 +3 +4 +</input> + <output>1;2 +3;4 +</output> + </testSpec> + <testSpec title="parallel stdin-multi multi-delim" command="paste" runMode="AS_ALIAS" rc="0"> + <arg>-d</arg> + <arg>;:,</arg> + <arg>-</arg> + <arg>-</arg> + <arg>-</arg> + <arg>-</arg> + <input>1 +2 +3 +4 +</input> + <output>1;2:3,4 +</output> + </testSpec> + <testSpec title="parallel file-dup sync" command="run" runMode="AS_SCRIPT" rc="0"> + <script>#!bjorne + paste -d ";" @TEMP_DIR@/a @TEMP_DIR@/a + </script> + <file name="a" input="true">1 +2 +3 +4 +</file> + <output>1;2 +3;4 +</output> + </testSpec> + <testSpec title="parallel file-dup async" command="run" runMode="AS_SCRIPT" rc="0"> + <script>#!bjorne + paste -d ";" @TEMP_DIR@/a @TEMP_DIR@/a @TEMP_DIR@/a + </script> + <file name="a" input="true">1 +2 +3 +4 +</file> + <output>1;2;3 +4 +</output> + </testSpec> + <testSpec title="parallel file-dup async multi-delim" command="run" runMode="AS_SCRIPT" rc="0"> + <script>#!bjorne + paste -d ";:" @TEMP_DIR@/a @TEMP_DIR@/a @TEMP_DIR@/a + </script> + <file name="a" input="true">1 +2 +3 +4 +5 +</file> + <output>1;2:3 +4;5 +</output> + </testSpec> +</testSet> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <chr...@us...> - 2009-05-18 22:26:17
|
Revision: 5497 http://jnode.svn.sourceforge.net/jnode/?rev=5497&view=rev Author: chrisboertien Date: 2009-05-18 22:26:09 +0000 (Mon, 18 May 2009) Log Message: ----------- Checkin of sort command + blackbox tests Signed-off-by: chrisboertien <chr...@gm...> Modified Paths: -------------- trunk/cli/descriptors/org.jnode.command.file.xml trunk/cli/src/commands/org/jnode/command/util/IOUtils.java trunk/cli/src/test/org/jnode/test/command/file/all-file-tests.xml Added Paths: ----------- trunk/cli/src/commands/org/jnode/command/file/SortCommand.java trunk/cli/src/test/org/jnode/test/command/file/sort-command-tests.xml Modified: trunk/cli/descriptors/org.jnode.command.file.xml =================================================================== --- trunk/cli/descriptors/org.jnode.command.file.xml 2009-05-18 13:15:53 UTC (rev 5496) +++ trunk/cli/descriptors/org.jnode.command.file.xml 2009-05-18 22:26:09 UTC (rev 5497) @@ -42,6 +42,7 @@ <alias name="paste" class="org.jnode.command.file.PasteCommand"/> <alias name="pwd" class="org.jnode.command.file.PwdCommand"/> <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="touch" class="org.jnode.command.file.TouchCommand"/> <alias name="wc" class="org.jnode.command.file.WcCommand"/> @@ -308,6 +309,29 @@ </repeat> </sequence> </syntax> + <syntax alias="sort"> + <sequence> + <optionSet> + <option argLabel="field" shortName="k"/> + <option argLabel="output" shortName="o"/> + <option argLabel="field-sep" shortName="t"/> + <option argLabel="check" shortName="c"/> + <option argLabel="merge" shortName="m"/> + <option argLabel="unique" shortName="u"/> + <option argLabel="reverse" shortName="r"/> + <option argLabel="cmp-print" shortName="i"/> + <option argLabel="cmp-alpha" shortName="d"/> + <option argLabel="cmp-icase" shortName="i"/> + <option argLabel="no-blanks" shortName="b"/> + <option argLabel="numeric" shortName="n"/> + <!-- debugging options --> + <option argLabel="sort" longName="sort"/> + </optionSet> + <repeat> + <argument argLabel="files"/> + </repeat> + </sequence> + </syntax> <syntax alias="tail"> <sequence> <optionSet label="globals"> Added: trunk/cli/src/commands/org/jnode/command/file/SortCommand.java =================================================================== --- trunk/cli/src/commands/org/jnode/command/file/SortCommand.java (rev 0) +++ trunk/cli/src/commands/org/jnode/command/file/SortCommand.java 2009-05-18 22:26:09 UTC (rev 5497) @@ -0,0 +1,435 @@ +/* + * $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.PrintWriter; +import java.io.IOException; +import java.util.Arrays; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; +import java.util.LinkedList; + +import org.jnode.command.util.IOUtils; +import org.jnode.shell.AbstractCommand; +import org.jnode.shell.CommandLine; +import org.jnode.shell.syntax.Argument; +import org.jnode.shell.syntax.CommandSyntaxException; +import org.jnode.shell.syntax.FileArgument; +import org.jnode.shell.syntax.FlagArgument; +import org.jnode.shell.syntax.IntegerArgument; +import org.jnode.shell.syntax.StringArgument; +import static org.jnode.shell.syntax.Argument.EXISTING; +import static org.jnode.shell.syntax.Argument.MULTIPLE; +import static org.jnode.shell.syntax.Argument.NONEXISTENT; +import static org.jnode.shell.syntax.FileArgument.HYPHEN_IS_SPECIAL; + +public class SortCommand extends AbstractCommand { + + private static final boolean DEBUG = true; + + private static final String help_files = "files to sort"; + private static final String help_output = "send output to this file, instead of stdout"; + private static final String help_field = "The field or field range to sort on"; + private static final String help_field_sep = "Use a specific character as the field separator"; + private static final String help_merge = "Assume the input is sorted and merge only"; + private static final String help_check = "Instead of sorting, check that the input is sorted."; + private static final String help_numeric = "When sorting, sort numerically instead of lexicographically"; + private static final String help_reverse = "Reverse the sense of ordering"; + private static final String help_unique = "If sorting, do not insert lines with keys that already exist. If " + + "checking, make sure all keys are unique"; + private static final String help_cmp_print = "For comparisons, ignore non-printing characters"; + private static final String help_cmp_alpha = "For comparisons, use only blank and alphanumeric characters"; + private static final String help_cmp_icase = "For comparisons, ignore case of keys when comparing"; + private static final String help_no_blanks = "Ignore leading blanks when determining that start and end " + + "positions of a key"; + private static final String help_super = "sort/merge files, or check that files are sorted"; + + private static class Field { + private int field; + private int offset; + private boolean ignoreBlanks; + private boolean sortNumeric; + private boolean cmpPrint; + private boolean cmpAlpha; + private boolean cmpICase; + private boolean reverse; + } + + private static class FieldRange { + private Field start; + private Field end; + } + + private static class Key { + String[] parts; + FieldRange[] ranges; + } + + private static class Entry { + Key key; + String value; + } + + private static class KeyFieldArgument extends Argument<FieldRange> { + private KeyFieldArgument(String label, int flags, String desc) { + super(label, flags, new FieldRange[0], desc); + } + + @Override + protected FieldRange doAccept(CommandLine.Token token, int flags) throws CommandSyntaxException { + String text = token.text; + FieldRange range = new FieldRange(); + int i = text.indexOf(","); + if (i == -1) { + range.start = parseField(text, false); + range.end = new Field(); + range.end.field = -1; + range.end.offset = -1; + } else { + range.start = parseField(text.substring(0, i), false); + range.end = parseField(text.substring(i + 1), true); + } + return range; + } + + @Override + protected String argumentKind() { + return "sort-field"; + } + + private static Field parseField(String text, boolean end) throws CommandSyntaxException { + Field field = new Field(); + int i = text.length() - 1; + LOOP: + while (true) { + switch (text.charAt(i)) { + case 'b': + field.ignoreBlanks = true; + break; + case 'd': + field.cmpAlpha = true; + break; + case 'f': + field.cmpICase = true; + break; + case 'i': + field.cmpPrint = true; + break; + case 'n': + field.sortNumeric = true; + break; + case 'r': + field.reverse = true; + break; + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + case '0': + break LOOP; + default: + throw new CommandSyntaxException("Invalid field: " + text); + } + i--; + } + text = text.substring(0, i + 1); + i = text.indexOf("."); + if (i == 0) { + throw new CommandSyntaxException("Field offset cannot be empty"); + } + if (i == (text.length() - 1)) { + throw new CommandSyntaxException("Character offset cannot be empty if '.' is given"); + } + try { + if (i == -1) { + field.field = Integer.parseInt(text) - 1; + field.offset = end ? -1 : 0; + } else { + field.field = Integer.parseInt(text.substring(0, i)) - 1; + field.offset = Integer.parseInt(text.substring(i + 1)) - 1; + } + } catch (NumberFormatException e) { + throw new CommandSyntaxException("Invalid number: " + text); + } + if (field.field < 0) { + throw new CommandSyntaxException("Field offset cannot be less than one: " + field.field); + } + if (field.offset < 0 && !end) { + throw new CommandSyntaxException("Start character offset cannot be less than one: " + field.offset); + } + if (field.offset < -1 && end) { + throw new CommandSyntaxException("End character offset cannot be less than zero"); + } + return field; + } + } + + private class FieldComparator implements Comparator<String> { + + private boolean trim = false; + + @Override + public boolean equals(Object o) { + return o instanceof FieldComparator; + } + + @Override + public int compare(String a, String b) { + for (FieldRange range : ranges) { + trim = range.start.ignoreBlanks; + String aKey = getKey(a, range); + String bKey = getKey(b, range); + int diff = aKey.compareTo(bKey); + if (diff != 0) { + return diff; + } + } + return 0; + } + + // TODO + // Refactor this out and calculate the keys before sorting + private String getKey(String text, FieldRange range) { + Field start = range.start; + Field end = range.end; + String[] fields = (fieldSep != null) ? splitSep(text, fieldSep) : splitDefault(text); + if (start.field >= fields.length) { + return ""; + } else { + if (end.field == -1) { + end.field = fields.length - 1; + } + if (start.field == end.field) { + int startPos = start.offset; + int field = start.field; + if ((end.offset == -1) || (end.offset >= fields[field].length())) { + return fields[field].substring(startPos); + } else { + return fields[field].substring(startPos, end.offset + 1); + } + } + StringBuilder capture = new StringBuilder(); + capture.append(fields[start.field].substring(start.offset)); + for (int i = start.field + 1; i < end.field; i++) { + capture.append(fields[i]); + } + if ((end.offset == -1) || (end.offset >= fields[end.field].length())) { + capture.append(fields[end.field]); + } else { + capture.append(fields[end.field].substring(0, end.offset + 1)); + } + return capture.toString(); + } + } + + private String[] splitSep(String text, String sep) { + List<String> fields = new LinkedList<String>(); + int mark = 0; + int i; + while((i = text.indexOf(sep, mark)) != -1) { + fields.add(text.substring(mark, i)); + mark = i + 1; + } + fields.add(text.substring(mark, text.length())); + return fields.toArray(new String[fields.size()]); + } + + private String[] splitDefault(String text) { + List<String> fields = new LinkedList<String>(); + boolean haveField = false; + int mark = 0; + int i; + for (i = 0; i < text.length(); i++) { + if (isBlank(text.charAt(i))) { + if (haveField) { + fields.add(text.substring(mark, i)); + mark = i; + haveField = false; + } else { + if (trim) { + mark = i; + } + } + } else { + haveField = true; + } + } + if (i > mark) { + fields.add(text.substring(mark, i)); + } + return fields.toArray(new String[fields.size()]); + } + + private boolean isBlank(char c) { + return c == ' ' || c == '\t'; + } + } + + private final FileArgument argFile = new FileArgument("files", MULTIPLE | EXISTING | HYPHEN_IS_SPECIAL, help_files); + private final FileArgument argOut = new FileArgument("output", NONEXISTENT, help_output); + private final FlagArgument argCheck = new FlagArgument("check", 0, help_check); + private final FlagArgument argMerge = new FlagArgument("merge", 0, help_merge); + private final FlagArgument argUnique = new FlagArgument("unique", 0, help_unique); + private final FlagArgument argNumeric = new FlagArgument("numeric", 0, help_numeric); + private final FlagArgument argReverse = new FlagArgument("reverse", 0, help_reverse); + private final FlagArgument argCmpPrint = new FlagArgument("cmp-print", 0, help_cmp_print); + private final FlagArgument argCmpAlpha = new FlagArgument("cmp-alpha", 0, help_cmp_alpha); + private final FlagArgument argCmpICase = new FlagArgument("cmp-icase", 0, help_cmp_icase); + private final FlagArgument argNoBlanks = new FlagArgument("no-blanks", 0, help_no_blanks); + private final KeyFieldArgument argField = new KeyFieldArgument("field", MULTIPLE, help_field); + private final StringArgument argFieldSep = new StringArgument("field-sep", 0, help_field_sep); + + private final IntegerArgument argSort = new IntegerArgument("sort", 0, " "); + private static final int SORT_ONE = 1; + private static final int SORT_TWO = 2; + private static final int SORT_LAST = 1; + + private List<File> files; + private File outputFile; + private PrintWriter out; + private PrintWriter err; + private FieldRange[] ranges; + private String fieldSep; + private int rc; + private int sort; + private boolean check; + private boolean merge; + private boolean unique; + private boolean reverse; + private boolean numeric; + private boolean cmpPrint; + private boolean cmpAlpha; + private boolean cmpICase; + private boolean noBlanks; + + public SortCommand() { + super(help_super); + registerArguments(argFile, argOut, argField, argFieldSep, argMerge, argUnique, argNumeric, argReverse); + registerArguments(argCmpPrint, argCmpAlpha, argCmpICase, argNoBlanks, argCheck); + + registerArguments(argSort); + } + + public void execute() { + err = getError().getPrintWriter(); + parseOptions(); + + try { + if (outputFile != null) { + out = new PrintWriter(outputFile); + } else { + out = getOutput().getPrintWriter(); + } + sortOne(); + } catch (IOException e) { + // + } finally { + //IOUtils.close(true, out); + exit(rc); + } + } + + private void sortOne() { + // OPTIMIZE + // This is probably effecient enough for most use cases, but alot + // can be done to make this run faster, and not do so much buffering. + // But it works for now... + // Also of note, the -m (merge only) option is basically ignore, as + // we're blindly sorting and merging all in one shot with Collections + // merge sort. Again, not effecient, but it works. + Comparator<String> cmp = new FieldComparator(); + List<String> allLines = new LinkedList(); + + for (File file : files) { + List<String> lines; + if (file.getName().equals("-")) { + lines = IOUtils.readLines(getInput().getReader()); + } else { + lines = IOUtils.readLines(file); + } + if (lines == null) { + error("Problem reading file: " + file.getName()); + rc = 1; + continue; + } + allLines.addAll(lines); + } + + if (argField.isSet()) { + Collections.sort(allLines, cmp); + } else { + Collections.sort(allLines); + } + for (String line : allLines) { + out.println(line); + } + } + + private void sortTwo() { + + } + + private void parseOptions(){ + if (argFile.isSet()) { + files = Arrays.asList(argFile.getValues()); + } else { + files = new ArrayList<File>(1); + files.add(new File("-")); + } + if (argField.isSet()) { + ranges = argField.getValues(); + } + if (argFieldSep.isSet()) { + fieldSep = argFieldSep.getValue(); + } + if (argOut.isSet()) { + outputFile = argOut.getValue(); + } + check = argCheck.isSet(); + merge = argMerge.isSet(); + unique = argUnique.isSet(); + numeric = argNumeric.isSet(); + reverse = argReverse.isSet(); + cmpPrint = argCmpPrint.isSet(); + cmpAlpha = argCmpAlpha.isSet(); + cmpICase = argCmpICase.isSet(); + noBlanks = argNoBlanks.isSet(); + + sort = argSort.isSet() ? argSort.getValue() : SORT_LAST; + } + + private void error(String s) { + err.println(s); + } + + private void debug(String s) { + if (DEBUG) { + error(s); + } + } +} Modified: trunk/cli/src/commands/org/jnode/command/util/IOUtils.java =================================================================== --- trunk/cli/src/commands/org/jnode/command/util/IOUtils.java 2009-05-18 13:15:53 UTC (rev 5496) +++ trunk/cli/src/commands/org/jnode/command/util/IOUtils.java 2009-05-18 22:26:09 UTC (rev 5497) @@ -529,6 +529,18 @@ return input; } + public static List<String> readLines(File file) { + BufferedReader reader = openBufferedReader(file); + if (reader == null) { + return null; + } + try { + return readLines(reader); + } finally { + close(reader); + } + } + public static List<String> readLines(Reader reader) { return readLines(new BufferedReader(reader, BUFFER_SIZE), -1); } 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-05-18 13:15:53 UTC (rev 5496) +++ trunk/cli/src/test/org/jnode/test/command/file/all-file-tests.xml 2009-05-18 22:26:09 UTC (rev 5497) @@ -4,6 +4,7 @@ <include setName="grep-command-tests.xml"/> <include setName="head-command-tests.xml"/> <include setName="paste-command-tests.xml"/> + <include setName="sort-command-tests.xml"/> <include setName="tail-command-tests.xml"/> <include setName="wc-command-tests.xml"/> </testSet> Added: trunk/cli/src/test/org/jnode/test/command/file/sort-command-tests.xml =================================================================== --- trunk/cli/src/test/org/jnode/test/command/file/sort-command-tests.xml (rev 0) +++ trunk/cli/src/test/org/jnode/test/command/file/sort-command-tests.xml 2009-05-18 22:26:09 UTC (rev 5497) @@ -0,0 +1,131 @@ +<testSet title="sort command tests"> + <!-- + First some tests for the default paramaters + --> + <testSpec title="whole-line 1" command="sort" runMode="AS_ALIAS" rc="0"> + <input>d +c +b +a +</input> + <output>a +b +c +d +</output> + </testSpec> + <testSpec title="single-field full default-sep" command="sort" runMode="AS_ALIAS" rc="0"> + <arg>-k</arg> + <arg>2,2</arg> + <input>1 d +3 b +2 c +4 a +</input> + <output>4 a +3 b +2 c +1 d +</output> + </testSpec> + + <!-- + The next few tests are aimed at the various combinations of key-field selection + --> + <testSpec title="single-field full custom-sep" command="sort" runMode="AS_ALIAS" rc="0"> + <arg>-t</arg> + <arg>;</arg> + <arg>-k</arg> + <arg>2,2</arg> + <input>c;j;2 +k;h;4 +i;q;1 +p;f;3 +</input> + <output>p;f;3 +k;h;4 +c;j;2 +i;q;1 +</output> + </testSpec> + <testSpec title="single-field partial custom-sep 1" command="sort" runMode="AS_ALIAS" rc="0"> + <arg>-t</arg> + <arg>;</arg> + <arg>-k</arg> + <arg>2.2,2.2</arg> + <input>k;jc;4 +o;ad;9 +i;la;2 +w;xb;5 +</input> + <output>i;la;2 +w;xb;5 +k;jc;4 +o;ad;9 +</output> + </testSpec> + <testSpec title="single-field partial custom-sep 2" command="sort" runMode="AS_ALIAS" rc="0"> + <arg>-t</arg> + <arg>;</arg> + <arg>-k</arg> + <arg>1.1,1.2</arg> + <input>awq;1 +ajk;4 +aon;2 +alm;3 +</input> + <output>ajk;4 +alm;3 +aon;2 +awq;1 +</output> + </testSpec> + <testSpec title="multi-field full custom-sep 1" command="sort" runMode="AS_ALIAS" rc="0"> + <arg>-t</arg> + <arg>;</arg> + <arg>-k</arg> + <arg>2,3</arg> + <input>3;a;b +2;b;a +4;a;a +1;b;b +</input> + <output>4;a;a +3;a;b +2;b;a +1;b;b +</output> + </testSpec> + <testSpec title="multi-field full custom-sep 2" command="sort" runMode="AS_ALIAS" rc="0"> + <arg>-t</arg> + <arg>;</arg> + <arg>-k</arg> + <arg>2,3</arg> + <input>2;;ba +4;aa; +1;b;b +3;a;b +</input> + <output>4;aa; +3;a;b +2;;ba +1;b;b +</output> + </testSpec> + <testSpec title="multi-field partial 1" command="sort" runMode="AS_ALIAS" rc="0"> + <arg>-t</arg> + <arg>;</arg> + <arg>-k</arg> + <arg>2.2,3.2</arg> + <input>2;yab;aay +3;xaa;abx +4;zaa;aaz +1;wba;aaw +</input> + <output>4;zaa;aaz +3;xaa;abx +2;yab;aay +1;wba;aaw +</output> + </testSpec> +</testSet> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <fd...@us...> - 2009-08-15 09:25:03
|
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. |
From: <ls...@us...> - 2009-10-20 21:23:10
|
Revision: 5684 http://jnode.svn.sourceforge.net/jnode/?rev=5684&view=rev Author: lsantha Date: 2009-10-20 21:23:04 +0000 (Tue, 20 Oct 2009) Log Message: ----------- Applied patch by Mark Kokish. Modified Paths: -------------- trunk/cli/descriptors/org.jnode.command.file.xml trunk/cli/src/commands/org/jnode/command/file/DirCommand.java Modified: trunk/cli/descriptors/org.jnode.command.file.xml =================================================================== --- trunk/cli/descriptors/org.jnode.command.file.xml 2009-10-15 14:50:26 UTC (rev 5683) +++ trunk/cli/descriptors/org.jnode.command.file.xml 2009-10-20 21:23:04 UTC (rev 5684) @@ -262,7 +262,8 @@ <option argLabel="url" shortName="u" longName="url" description="print a hex dump of a URL"/> </syntax> <syntax alias="ls"> - <empty description="list the current directory"/> + <empty description="with -l, print sizes in human readable format (e.g., 1K 234M 2G)"/> + <option argLabel="humanReadable" shortName="h" longName="human-readable"/> <repeat> <argument argLabel="path" description="list files or directories"/> </repeat> Modified: trunk/cli/src/commands/org/jnode/command/file/DirCommand.java =================================================================== --- trunk/cli/src/commands/org/jnode/command/file/DirCommand.java 2009-10-15 14:50:26 UTC (rev 5683) +++ trunk/cli/src/commands/org/jnode/command/file/DirCommand.java 2009-10-20 21:23:04 UTC (rev 5684) @@ -23,6 +23,7 @@ import java.io.File; import java.io.IOException; import java.io.PrintWriter; +import java.text.DecimalFormat; import java.text.SimpleDateFormat; import java.util.Arrays; import java.util.Comparator; @@ -31,6 +32,7 @@ import org.jnode.shell.AbstractCommand; import org.jnode.shell.syntax.Argument; import org.jnode.shell.syntax.FileArgument; +import org.jnode.shell.syntax.FlagArgument; /** * @author epr @@ -44,15 +46,18 @@ private static final SimpleDateFormat df = new SimpleDateFormat("yyyy.MM.dd HH:mm"); private static final String help_path = "the file or directory to list"; + private static final String help_humanReadable = "with -l, print sizes in human readable format (e.g., 1K 234M 2G)"; private static final String help_super = "List files or directories"; private static final String fmt_no_path = "No such path: %s%n"; - + private final FileArgument argPath; - + private final FlagArgument humanReadableArg; + public DirCommand() { super(help_super); + humanReadableArg = new FlagArgument("humanReadable", Argument.OPTIONAL, help_humanReadable); argPath = new FileArgument("path", Argument.OPTIONAL | Argument.MULTIPLE | Argument.EXISTING, help_path); - registerArguments(argPath); + registerArguments(argPath, humanReadableArg); } public static void main(String[] args) throws Exception { @@ -102,10 +107,9 @@ sb.setLength(0); lastModified.setTime(f.lastModified()); if (f.isFile()) { - String ln = String.valueOf(f.length()).concat("B"); + String ln = formatSize(f.length()); int cnt = LEFT_MARGIN - ln.length(); - for (int j = 0; j < cnt; j++, sb.append(' ')) - ; + for (int j = 0; j < cnt; j++) sb.append(' '); sb.append(ln); sb.append(" "); sb.append(df.format(lastModified)); @@ -125,4 +129,16 @@ out.println(); } } + + private static final String[] units = {"B", "K", "M", "G", "T", "P", "E", "Z", "Y"}; + + protected String formatSize(double bytes) { + if (humanReadableArg.isSet()) { + int index; + for (index = 0; bytes >= 1024; index++) bytes = bytes / 1024; + DecimalFormat df = new DecimalFormat("###0.0"); + return df.format(bytes) + units[index]; + } else + return bytes + "B"; + } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ls...@us...> - 2009-11-23 17:09:15
|
Revision: 5688 http://jnode.svn.sourceforge.net/jnode/?rev=5688&view=rev Author: lsantha Date: 2009-11-23 17:09:02 +0000 (Mon, 23 Nov 2009) Log Message: ----------- Extensions to du command. Applied patch by Mario Zsilak. Modified Paths: -------------- trunk/cli/descriptors/org.jnode.command.file.xml trunk/cli/src/commands/org/jnode/command/file/DuCommand.java Modified: trunk/cli/descriptors/org.jnode.command.file.xml =================================================================== --- trunk/cli/descriptors/org.jnode.command.file.xml 2009-10-23 08:21:09 UTC (rev 5687) +++ trunk/cli/descriptors/org.jnode.command.file.xml 2009-11-23 17:09:02 UTC (rev 5688) @@ -151,14 +151,29 @@ <argument argLabel="path" description="list a file or directory"/> </syntax> <syntax alias="du"> - <sequence description="print file sizes"> + <sequence description="Disk Usage - report the amount of disk space used by the specified directory and for each subdirectory."> <repeat minCount="0"> <argument argLabel="directory" description="directory to start printing sizes recursively"/> </repeat> <optionSet> - <option argLabel="sum" shortName="s" longName="summarize"/> - <option argLabel="all" shortName="a" longName="all"/> - <option argLabel="human-readable" shortName="h" longName="human-readable"/> + <option argLabel="all" shortName="a" longName="all"/> + <option argLabel="block-size-1" shortName="b" longName="bytes"/> + <option argLabel="total" shortName="c" longName="total"/> + <option argLabel="derefArgs" shortName="D" longName="dereference-args"/> + <option argLabel="human-readable-1024" shortName="h" longName="human-readable"/> + <option argLabel="human-readable-1000" shortName="H" longName="si"/> + <option argLabel="block-size-1024" shortName="k" longName="kilobytes"/> + <option argLabel="count-links" shortName="l" longName="count-links"/> + <option argLabel="dereference" shortName="L" longName="dereference"/> + <option argLabel="max-depth" shortName="" longName="max-depth"/> <!-- max-depth has no shortname --> + <option argLabel="block-size-1024x1024" shortName="m" longName="megabytes"/> + <option argLabel="summarize" shortName="s" longName="summarize"/> + <option argLabel="separate-dirs" shortName="S" longName="separate-dirs"/> + <option argLabel="one-file-system" shortName="x" longName="one-file-system"/> <!-- can't test this currently --> + <option argLabel="exclude" shortName="" longName="exclude"/> <!-- exclude has no shortname --> + <option argLabel="exclude-from" shortName="X" longName="exclude-from"/> + <option argLabel="block-size-custom" shortName="B" longName="block-size"/> <!-- not in man page, but works on unix like systems --> + <option argLabel="filesystem-block-size" shortName="" longName="fs-block-size"/> <!-- not in man page, but works on unix like systems --> </optionSet> </sequence> </syntax> Modified: trunk/cli/src/commands/org/jnode/command/file/DuCommand.java =================================================================== --- trunk/cli/src/commands/org/jnode/command/file/DuCommand.java 2009-10-23 08:21:09 UTC (rev 5687) +++ trunk/cli/src/commands/org/jnode/command/file/DuCommand.java 2009-11-23 17:09:02 UTC (rev 5688) @@ -1,5 +1,5 @@ /* - * $Id: CdCommand.java 4975 2009-02-02 08:30:52Z lsantha $ + * $Id: DuCommand.java 4975 2009-02-02 08:30:52Z lsantha $ * * Copyright (C) 2003-2009 JNode.org * @@ -22,175 +22,475 @@ import java.io.File; import java.io.IOException; import java.io.PrintWriter; -import java.util.Map; -import java.util.NavigableMap; -import java.util.TreeMap; -import java.util.Map.Entry; +import java.util.Stack; +import javax.naming.NameNotFoundException; + +import org.apache.log4j.Logger; import org.jnode.command.util.AbstractDirectoryWalker; +import org.jnode.driver.Device; +import org.jnode.driver.block.FSBlockDeviceAPI; +import org.jnode.fs.service.FileSystemService; +import org.jnode.naming.InitialNaming; import org.jnode.shell.AbstractCommand; import org.jnode.shell.syntax.Argument; import org.jnode.shell.syntax.FileArgument; import org.jnode.shell.syntax.FlagArgument; +import org.jnode.shell.syntax.IntegerArgument; +import org.jnode.shell.syntax.StringArgument; import org.jnode.util.NumberUtils; +import org.jnode.vm.VmExit; -/* +/** * @author Alexander Kerner + * @author Mario Zsilak */ public class DuCommand extends AbstractCommand { - - private static final String err_perm = "Permission denied for '%s'%n"; - - private abstract class Walker extends AbstractDirectoryWalker { - protected final TreeMap<File, Long> map = new TreeMap<File, Long>(); - protected final boolean humanReadable; + private static final String HELP_SUPER = + "With no arguments, `du' reports the disk space for the current directory. Normally the disk space is printed in units of 1024 bytes, but this can be overridden"; + private static final String HELP_DIR = "directory to start printing sizes recursively"; + private static final String HELP_ALL = "Show counts for all files, not just directories."; + private static final String HELP_BLOCK_SIZE_1 = + "Print sizes in bytes, overriding the default block size"; + private static final String HELP_TOTAL = + "Print a grand total of all arguments after all arguments have been processed. This can be used to find out the total disk usage of a given set of files or directories."; + private static final String HELP_DEREF_ARGS = + "Dereference symbolic links that are command line arguments. Does not affect other symbolic links. This is helpful for finding out the disk usage of directories, such as `/usr/tmp', which are often symbolic links."; + private static final String HELP_HUMAN_READABLE_1024 = + "Append a size letter such as `M' for megabytes to each size. Powers of 1024 are used, not 1000; `M' stands for 1,048,576 bytes. Use the `-H' or `--si' option if you prefer powers of 1000."; + private static final String HELP_HUMAN_READABLE_1000 = + "Append a size letter such as `M' for megabytes to each size. (SI is the International System of Units, which defines these letters as prefixes.) Powers of 1000 are used, not 1024; `M' stands for 1,000,000 bytes. Use the `-h' or `--human-readable' option if you prefer powers of 1024."; + private static final String HELP_BLOCK_SIZE_1024 = + "Print sizes in 1024-byte blocks, overriding the default block size"; + private static final String HELP_COUNT_LINKS = + "Count the size of all files, even if they have appeared already (as a hard link)."; + private static final String HELP_DEREF = + "Dereference symbolic links (show the disk space used by the file or directory that the link points to instead of the space used by the link)."; + private static final String HELP_MAX_DEPTH = + "Show the total for each directory (and file if -all) that is at most MAX_DEPTH levels down from the root of the hierarchy. The root is at level 0, so `du --max-depth=0' is equivalent to `du -s'."; + private static final String HELP_BLOCK_SIZE_1024x1024 = + "Print sizes in megabyte (that is, 1,048,576-byte) blocks."; + private static final String HELP_SUM = "Display only a total for each argument."; + private static final String HELP_SEPERATE_DIRS = + "Report the size of each directory separately, not including the sizes of subdirectories."; + private static final String HELP_ONE_FS = + "Skip directories that are on different filesystems from the one that the argument being processed is on."; + private static final String HELP_EXCLUDE = + "When recursing, skip subdirectories or files matching PAT. For example, `du --exclude='*.o'' excludes files whose names end in `.o'."; + private static final String HELP_EXCLUDE_FROM = + "Like `--exclude', except take the patterns to exclude from FILE, one per line. If FILE is `-', take the patterns from standard input."; + private static final String HELP_BLOCK_SIZE_CUSTOM = + "Print sizes in the user defined block size, overriding the default block size"; + private static final String HELP_FS_BLOCK_SIZE = + "Overrides the filesystem block size -- use it for testing"; - Walker(boolean humanReadable) { - this.humanReadable = humanReadable; + private final FileArgument argDir = + new FileArgument("directory", + Argument.OPTIONAL | Argument.MULTIPLE | Argument.EXISTING, HELP_DIR); + private final FlagArgument argAll = new FlagArgument("all", Argument.OPTIONAL, HELP_ALL); + private final FlagArgument argBlockSize_1 = + new FlagArgument("block-size-1", Argument.OPTIONAL, HELP_BLOCK_SIZE_1); + private final FlagArgument argTotal = new FlagArgument("total", Argument.OPTIONAL, HELP_TOTAL); + private final FlagArgument argDerefArgs = + new FlagArgument("derefArgs", Argument.OPTIONAL, HELP_DEREF_ARGS); + private final FlagArgument argHumanReadable_1024 = + new FlagArgument("human-readable-1024", Argument.OPTIONAL, HELP_HUMAN_READABLE_1024); + private final FlagArgument argHumanReadable_1000 = + new FlagArgument("human-readable-1000", Argument.OPTIONAL, HELP_HUMAN_READABLE_1000); + private final FlagArgument argBlockSize_1024 = + new FlagArgument("block-size-1024", Argument.OPTIONAL, HELP_BLOCK_SIZE_1024); + private final FlagArgument argCountLinks = + new FlagArgument("count-links", Argument.OPTIONAL, HELP_COUNT_LINKS); + private final FlagArgument argDereference = + new FlagArgument("dereference", Argument.OPTIONAL, HELP_DEREF); + private final IntegerArgument argMaxDepth = + new IntegerArgument("max-depth", Argument.OPTIONAL, HELP_MAX_DEPTH); + private final FlagArgument argBlockSize_1024x1024 = + new FlagArgument("block-size-1024x1024", Argument.OPTIONAL, HELP_BLOCK_SIZE_1024x1024); + private final FlagArgument argSum = new FlagArgument("summarize", Argument.OPTIONAL, HELP_SUM); + private final FlagArgument argSeperateDirs = + new FlagArgument("separate-dirs", Argument.OPTIONAL, HELP_SEPERATE_DIRS); + private static final FlagArgument argOneFS = + new FlagArgument("one-file-system", Argument.OPTIONAL, HELP_ONE_FS); + private final StringArgument argExclude = + new StringArgument("exclude", Argument.OPTIONAL, HELP_EXCLUDE); + private static final StringArgument argExcludeFrom = + new StringArgument("exclude-from", Argument.OPTIONAL, HELP_EXCLUDE_FROM); + private final IntegerArgument argBlockSize_Custom = + new IntegerArgument("block-size-custom", Argument.OPTIONAL, HELP_BLOCK_SIZE_CUSTOM); + private final IntegerArgument argFilesystemBlockSize = + new IntegerArgument("filesystem-block-size", Argument.OPTIONAL, HELP_FS_BLOCK_SIZE); + + private static final String ERR_PERMISSION = "Permission denied for '%s'%n"; + + private static final int DEFAULT_FILESYSTEM_BLOCK_SIZE = 1024; + private static final int DEFAULT_DISPLAY_BLOCK_SIZE = 1024; + + private Logger logger = Logger.getLogger(getClass()); + + private int fsBlockSize; + private int displayBlockSize; + private PrintWriter out; + private PrintWriter err; + + public static void main(String[] args) throws IOException { + new DuCommand().execute(); + } + + public DuCommand() { + super(HELP_SUPER); + registerArguments(argDir, argAll, argBlockSize_1, argTotal, argDerefArgs, + argHumanReadable_1024, argHumanReadable_1000, argBlockSize_1024, argCountLinks, + argDereference, argMaxDepth, argBlockSize_1024x1024, argSum, argSeperateDirs, + argOneFS, argExclude, argExcludeFrom, argBlockSize_Custom, argFilesystemBlockSize); + } + + public void execute() throws IOException { + + Walker walker = null; + File[] startPoints = null; + + out = getOutput().getPrintWriter(); + err = getError().getPrintWriter(); + + if (argAll.isSet() && argSum.isSet()) { + err.println("Summarize and show all not possible at the some time!"); + throw new VmExit(1); } - @Override - public void handleDir(File file) { - handleAll(file); + if (argDerefArgs.isSet()) { + logger.warn(argDerefArgs.getLabel() + " is currently not supported"); } - @Override - public void handleFile(File file) { - handleAll(file); + if (argOneFS.isSet()) { + logger.warn(argOneFS.getLabel() + " is currently not supported"); } - - @Override - protected void handleRestrictedFile(File file) throws IOException { - err.format(err_perm, file); + + if (argExcludeFrom.isSet()) { + logger.warn(argExcludeFrom.getLabel() + " is currently not supported"); } - private void handleAll(File file) { - map.put(file, file.length()); + if (argDereference.isSet()) { + logger.warn(argDereference.getLabel() + " is currently not supported"); } - protected TreeMap<File, Long> summariseIt(TreeMap<File, Long> map) { - TreeMap<File, Long> result = new TreeMap<File, Long>(); - NavigableMap<File, Long> navMap = map.descendingMap(); - Long tmpSize = 0L; - while (navMap.size() != 0) { - Entry<File, Long> e = navMap.pollFirstEntry(); - File key = e.getKey(); - Long value = e.getValue(); - tmpSize += key.length(); + if (argCountLinks.isSet()) { + logger.warn(argCountLinks.getLabel() + " is currently not supported"); + } - if (key.isFile()) { - result.put(key, value); - } else if (key.isDirectory()) { - result.put(key, tmpSize); - } else { - // ignore unknown file type - } + startPoints = argDir.getValues(); + + if (startPoints.length == 0) { + startPoints = new File[] {new File(System.getProperty("user.dir"))}; + } + + if (argFilesystemBlockSize.isSet()) + fsBlockSize = argFilesystemBlockSize.getValue(); + else { + fsBlockSize = getFsBlockSize(startPoints[0]); + } + + if (argBlockSize_Custom.isSet()) { + displayBlockSize = argBlockSize_Custom.getValue(); + } else if (argBlockSize_1024x1024.isSet()) { + displayBlockSize = 1024 * 1024; + } else if (argBlockSize_1024.isSet()) { + displayBlockSize = 1024; + } else if (argBlockSize_1.isSet()) { + displayBlockSize = 1; + } else { + displayBlockSize = DEFAULT_DISPLAY_BLOCK_SIZE; + } + + if (argSum.isSet() || argTotal.isSet()) { + + long total = 0; + + for (File start : startPoints) { + walker = new Walker(argMaxDepth, argExclude); + walker.walk(start); + + printSize(start.getAbsolutePath(), walker.getSize()); + total += walker.getSize(); } - return result; + + if (argTotal.isSet()) { + printSize("Total", total); + } + } else { + new Walker(argMaxDepth, argExclude).walk(startPoints); } } - private class AllWalker extends Walker { + private void printFileSize(final File filename, final long size) { + if (argAll.isSet()) { + out.println(size + "\t" + filename); + } + } - AllWalker(boolean humanReadable) { - super(humanReadable); + private void printDirSize(final File filename, final long dirSizeOnly, final long subDirSize) { + if (!argSum.isSet()) { + if (argSeperateDirs.isSet()) { + out.println(sizeToString(dirSizeOnly) + "\t" + filename); + } else { + out.println(sizeToString(dirSizeOnly + subDirSize) + "\t" + filename); + } } + } - @Override - protected void lastAction(boolean wasCancelled) { - Map<File, Long> summarisedMap = summariseIt(map); - for (Entry<File, Long> e : summarisedMap.entrySet()) { - if (humanReadable) - out.println(NumberUtils.toBinaryByte(e.getValue()) + "\t" + e.getKey()); - else - out.println(e.getValue() + "\t" + e.getKey()); + private void printSize(final String filename, final long size) { + out.println(sizeToString(size) + "\t" + filename); + } + + private void log(String message) { + // logger.debug(message); + } + + /** + * should be in NumberUtils I guess + * + * @param lenght in bytes of the file / directory + * @return the number of blocks it uses up depending on the int + * displayBlockSize + */ + private long calc(long bytes) { + + double factor = fsBlockSize / displayBlockSize; + long ret = -1; + + if (fsBlockSize > displayBlockSize) { + if (bytes % displayBlockSize == 0) { + ret = bytes / displayBlockSize; + } else { + ret = (long) ((bytes / (fsBlockSize) + 1) * factor); } + } else { + if (bytes % displayBlockSize == 0) { + ret = bytes / displayBlockSize; + } else { + ret = (long) ((bytes / (displayBlockSize) + 1)); + } } + + return ret; } - private class OnlyDirsWalker extends Walker { + private String sizeToString(long size) { - OnlyDirsWalker(boolean humanReadable) { - super(humanReadable); + String retValue = null; + + if (argHumanReadable_1024.isSet()) { + retValue = NumberUtils.toBinaryByte(size); + } else if (argHumanReadable_1000.isSet()) { + retValue = NumberUtils.toDecimalByte(size); + } else { + retValue = String.valueOf(size); } - @Override - protected void lastAction(boolean wasCancelled) { - Map<File, Long> summarisedMap = summariseIt(map); - for (Entry<File, Long> e : summarisedMap.entrySet()) { - if (e.getKey().isDirectory()) { - if (humanReadable) - out.println(NumberUtils.toBinaryByte(e.getValue()) + "\t" + e.getKey()); - else - out.println(e.getValue() + "\t" + e.getKey()); + return retValue; + } + + /** + * taken from the DfCommand + */ + private int getFsBlockSize(File file) throws IOException { + + int retValue = DEFAULT_FILESYSTEM_BLOCK_SIZE; // default block size + FileSystemService fss = null; + Device device = null; + String path = null; + String mp = null; + + try { + fss = InitialNaming.lookup(FileSystemService.NAME); + path = file.getCanonicalPath(); + mp = null; + + for (String mountPoint : fss.getMountPoints().keySet()) { + if (path.startsWith(mountPoint)) { + if (mp != null) { + if (!mp.startsWith(mountPoint)) { + continue; + } + } + mp = mountPoint; } } + + if (mp != null) { + device = fss.getMountPoints().get(mp).getDevice(); + + if (device instanceof FSBlockDeviceAPI) { + retValue = ((FSBlockDeviceAPI) device).getSectorSize(); + + } else { + logger.warn("No FSBlockDeviceAPI device for device" + device); + logger.info("Using default block-size: " + DEFAULT_FILESYSTEM_BLOCK_SIZE); + logger.info("override with --fs-block-size"); + } + } else { + + logger.warn("No mount point found for " + path); + + for (String mountPoint : fss.getMountPoints().keySet()) { + logger.warn("mountpoints on system: " + mountPoint); + } + + logger.info("Using default block-size: " + DEFAULT_FILESYSTEM_BLOCK_SIZE); + logger.info("override with --fs-block-size"); + } + + } catch (NameNotFoundException e) { + logger.warn("FileSystemService lookup failed ...", e); + logger.info("Using default block-size: " + DEFAULT_FILESYSTEM_BLOCK_SIZE); + logger.info("override with --fs-block-size"); } + + return retValue; } - private class TotalWalker extends Walker { + private class Directory { + private Directory parent = null; + private File directory = null; + private Stack<Directory> subDirs = null; + private long size = 0; - TotalWalker(boolean humanReadable) { - super(humanReadable); + public Directory(Directory parent, File directory) { + this.parent = parent; + this.directory = directory; + subDirs = new Stack<Directory>(); } - @Override - protected void lastAction(boolean wasCancelled) { - TreeMap<File, Long> summarisedMap = summariseIt(map); - Entry<File, Long> e = summarisedMap.firstEntry(); - if (humanReadable) - out.println(NumberUtils.toBinaryByte(e.getValue()) + "\t" + e.getKey()); - else - out.println(e.getValue() + "\t" + e.getKey()); + public Directory addDirectory(File file) { + Directory retValue = null; + if (file.getParentFile().equals(directory)) { + retValue = new Directory(this, file); + subDirs.push(retValue); + } else { + logger.warn("addDirectory: tried to add " + file + " to " + directory); + } + + return retValue; } - } - private PrintWriter out; - private PrintWriter err; + public void addFile(File file) { + if (!file.getParentFile().equals(directory)) { + logger.warn("addFile: tried to add " + file + " to " + directory); + } - private static final String HELP_TOTAL = "display only a total for each argument"; - private static final String HELP_ALL = "write counts for all files, not just directories"; - private static final String HELP_SUPER = "print file sizes"; - private static final String HELP_DIR = "directory to start printing sizes"; - private static final String HELP_HUMAN_READABLE = "print sizes in human readable format (e.g., 1K 234M 2G)"; + printFileSize(file, calc(file.length())); + size += calc(file.length()); + } - private final FlagArgument totalArg; - private final FlagArgument allArg; - private final FileArgument dirArg; - private final FlagArgument humanReadableArg; + public Directory getParent() { - public DuCommand() { - super(HELP_SUPER); - totalArg = new FlagArgument("sum", Argument.OPTIONAL, HELP_TOTAL); - allArg = new FlagArgument("all", Argument.OPTIONAL, HELP_ALL); - dirArg = new FileArgument("directory", Argument.OPTIONAL | Argument.MULTIPLE, HELP_DIR); - humanReadableArg = new FlagArgument("human-readable", Argument.OPTIONAL, HELP_HUMAN_READABLE); - registerArguments(totalArg, allArg, humanReadableArg, dirArg); - } + long dirSize = size + calc(directory.length()); // only the size for + // this directory + + // files (in other + // words: excludes + // the size of + // subDirs) + long subDirSize = 0; - public static void main(String[] args) throws IOException { - new DuCommand().execute(); + while (!subDirs.isEmpty()) { + subDirSize += subDirs.pop().getSize(); + } + + printDirSize(directory, dirSize, subDirSize); + + size = dirSize + subDirSize; + + return parent; + } + + public long getSize() { + return size; + } + + public boolean equals(Object other) { + boolean retValue = false; + + if (other instanceof Directory) { + retValue = (other != null && ((Directory) other).directory.equals(this.directory)); + } else if (other instanceof File) { + retValue = (other != null && ((File) other).equals(this.directory)); + } + + return retValue; + } + + @Override + public String toString() { + return directory.toString(); + } } - public void execute() throws IOException { - out = getOutput().getPrintWriter(); - err = getError().getPrintWriter(); - Walker walker = null; - if (totalArg.isSet()) { - walker = new TotalWalker(humanReadableArg.isSet()); - } else if (allArg.isSet()) { - walker = new AllWalker(humanReadableArg.isSet()); - } else { - walker = new OnlyDirsWalker(humanReadableArg.isSet()); + private class Walker extends AbstractDirectoryWalker { + + long totalSize; + protected Directory root = null; + protected Directory currentDir = null; + + private Walker(IntegerArgument argMaxDepth, StringArgument argExclude) { + super(); + + if (argMaxDepth.isSet()) { + super.setMaxDepth(argMaxDepth.getValue().longValue()); + } + + if (argExclude.isSet()) { + super.addFilter(new RegexPatternFilter(argExclude.getValue(), true)); + } } - - if (dirArg.isSet()) { - walker.walk(dirArg.getValues()); - } else { - walker.walk(new File(System.getProperty("user.dir"))); + + public long getSize() { + return totalSize; } + + @Override + protected void handleStartingDir(File file) throws IOException { + log("starting dir: " + file); + root = new Directory(null, file); + } + + @Override + protected void lastAction(boolean wasCancelled) { + root.getParent(); + totalSize = root.getSize(); + } + + @Override + public void handleDir(File file) { + log("handleDir: " + file); + + if (currentDir == null || currentDir.equals(file)) { + currentDir = root; + return; + } + + while (!currentDir.equals(file.getParentFile())) { + log("in while"); + currentDir = currentDir.getParent(); + } + + currentDir = currentDir.addDirectory(file); + } + + @Override + public void handleFile(File file) { + log("handleFile: " + file); + + while (!currentDir.equals(file.getParentFile())) { + currentDir = currentDir.getParent(); + } + currentDir.addFile(file); + } + + @Override + protected void handleRestrictedFile(File file) throws IOException { + err.format(ERR_PERMISSION, file); + } } } - This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ls...@us...> - 2009-12-03 21:19:08
|
Revision: 5689 http://jnode.svn.sourceforge.net/jnode/?rev=5689&view=rev Author: lsantha Date: 2009-12-03 21:18:57 +0000 (Thu, 03 Dec 2009) Log Message: ----------- Fixed NPE. Improved help. Applied patch by Mario Zsilak. Modified Paths: -------------- trunk/cli/descriptors/org.jnode.command.file.xml trunk/cli/src/commands/org/jnode/command/file/DuCommand.java Modified: trunk/cli/descriptors/org.jnode.command.file.xml =================================================================== --- trunk/cli/descriptors/org.jnode.command.file.xml 2009-11-23 17:09:02 UTC (rev 5688) +++ trunk/cli/descriptors/org.jnode.command.file.xml 2009-12-03 21:18:57 UTC (rev 5689) @@ -173,10 +173,10 @@ <option argLabel="exclude" shortName="" longName="exclude"/> <!-- exclude has no shortname --> <option argLabel="exclude-from" shortName="X" longName="exclude-from"/> <option argLabel="block-size-custom" shortName="B" longName="block-size"/> <!-- not in man page, but works on unix like systems --> - <option argLabel="filesystem-block-size" shortName="" longName="fs-block-size"/> <!-- not in man page, but works on unix like systems --> + <option argLabel="filesystem-block-size" shortName="" longName="fs-block-size"/> <!-- testing --> </optionSet> </sequence> - </syntax> + </syntax> <syntax alias="find"> <sequence description="find files or directories"> <repeat minCount="0"> Modified: trunk/cli/src/commands/org/jnode/command/file/DuCommand.java =================================================================== --- trunk/cli/src/commands/org/jnode/command/file/DuCommand.java 2009-11-23 17:09:02 UTC (rev 5688) +++ trunk/cli/src/commands/org/jnode/command/file/DuCommand.java 2009-12-03 21:18:57 UTC (rev 5689) @@ -56,7 +56,7 @@ private static final String HELP_TOTAL = "Print a grand total of all arguments after all arguments have been processed. This can be used to find out the total disk usage of a given set of files or directories."; private static final String HELP_DEREF_ARGS = - "Dereference symbolic links that are command line arguments. Does not affect other symbolic links. This is helpful for finding out the disk usage of directories, such as `/usr/tmp', which are often symbolic links."; + "Dereference symbolic links that are command line arguments. Does not affect other symbolic links. This is helpful for finding out the disk usage of directories, such as `/usr/tmp', which are often symbolic links. (not implemented"; private static final String HELP_HUMAN_READABLE_1024 = "Append a size letter such as `M' for megabytes to each size. Powers of 1024 are used, not 1000; `M' stands for 1,048,576 bytes. Use the `-H' or `--si' option if you prefer powers of 1000."; private static final String HELP_HUMAN_READABLE_1000 = @@ -64,22 +64,22 @@ private static final String HELP_BLOCK_SIZE_1024 = "Print sizes in 1024-byte blocks, overriding the default block size"; private static final String HELP_COUNT_LINKS = - "Count the size of all files, even if they have appeared already (as a hard link)."; + "Count the size of all files, even if they have appeared already (as a hard link). (not implemented"; private static final String HELP_DEREF = - "Dereference symbolic links (show the disk space used by the file or directory that the link points to instead of the space used by the link)."; + "Dereference symbolic links (show the disk space used by the file or directory that the link points to instead of the space used by the link). (not implemented"; private static final String HELP_MAX_DEPTH = - "Show the total for each directory (and file if -all) that is at most MAX_DEPTH levels down from the root of the hierarchy. The root is at level 0, so `du --max-depth=0' is equivalent to `du -s'."; + "Show the total for each directory (and file if -all) that is at most MAX_DEPTH levels down from the root of the hierarchy. The root is at level 0, so `du --max-depth=0' is equivalent to `du -s'. (not tested)"; private static final String HELP_BLOCK_SIZE_1024x1024 = "Print sizes in megabyte (that is, 1,048,576-byte) blocks."; private static final String HELP_SUM = "Display only a total for each argument."; private static final String HELP_SEPERATE_DIRS = "Report the size of each directory separately, not including the sizes of subdirectories."; private static final String HELP_ONE_FS = - "Skip directories that are on different filesystems from the one that the argument being processed is on."; + "Skip directories that are on different filesystems from the one that the argument being processed is on. (not implemented)"; private static final String HELP_EXCLUDE = - "When recursing, skip subdirectories or files matching PAT. For example, `du --exclude='*.o'' excludes files whose names end in `.o'."; + "When recursing, skip subdirectories or files matching PAT. For example, `du --exclude='*.o'' excludes files whose names end in `.o'. (not tested)"; private static final String HELP_EXCLUDE_FROM = - "Like `--exclude', except take the patterns to exclude from FILE, one per line. If FILE is `-', take the patterns from standard input."; + "Like `--exclude', except take the patterns to exclude from FILE, one per line. If FILE is `-', take the patterns from standard input. (not implemented)"; private static final String HELP_BLOCK_SIZE_CUSTOM = "Print sizes in the user defined block size, overriding the default block size"; private static final String HELP_FS_BLOCK_SIZE = @@ -225,7 +225,7 @@ private void printFileSize(final File filename, final long size) { if (argAll.isSet()) { - out.println(size + "\t" + filename); + out.println(sizeToString(size) + "\t" + filename); } } @@ -325,7 +325,7 @@ retValue = ((FSBlockDeviceAPI) device).getSectorSize(); } else { - logger.warn("No FSBlockDeviceAPI device for device" + device); + logger.warn("No FSBlockDeviceAPI device for device: " + device); logger.info("Using default block-size: " + DEFAULT_FILESYSTEM_BLOCK_SIZE); logger.info("override with --fs-block-size"); } @@ -386,12 +386,9 @@ public Directory getParent() { - long dirSize = size + calc(directory.length()); // only the size for - // this directory + - // files (in other - // words: excludes - // the size of - // subDirs) + long dirSize = size + calc(directory.length()); + // only the size for this directory + files + // (in other words: excludes the size of subDirs) long subDirSize = 0; while (!subDirs.isEmpty()) { @@ -408,6 +405,11 @@ public long getSize() { return size; } + + @Override + public int hashCode() { + return directory.hashCode(); + } public boolean equals(Object other) { boolean retValue = false; @@ -450,18 +452,28 @@ } @Override + /** + * Set the "root" Directory to the Starting Dir + */ protected void handleStartingDir(File file) throws IOException { log("starting dir: " + file); root = new Directory(null, file); } @Override + /** + * Calculate the "root" directory and reset the "current" directory .. we are done for now + */ protected void lastAction(boolean wasCancelled) { root.getParent(); + currentDir = null; totalSize = root.getSize(); } @Override + /** + * add the currently handled directory/file to the correct position in the hierarchy + */ public void handleDir(File file) { log("handleDir: " + file); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ls...@us...> - 2011-08-07 08:53:47
|
Revision: 5844 http://jnode.svn.sourceforge.net/jnode/?rev=5844&view=rev Author: lsantha Date: 2011-08-07 08:53:41 +0000 (Sun, 07 Aug 2011) Log Message: ----------- Added default mode to 'thread' command to show a flat thread list sorted by id. Modified Paths: -------------- trunk/cli/descriptors/org.jnode.command.system.xml trunk/cli/src/commands/org/jnode/command/system/ThreadCommand.java Modified: trunk/cli/descriptors/org.jnode.command.system.xml =================================================================== --- trunk/cli/descriptors/org.jnode.command.system.xml 2011-08-04 12:57:47 UTC (rev 5843) +++ trunk/cli/descriptors/org.jnode.command.system.xml 2011-08-07 08:53:41 UTC (rev 5844) @@ -288,6 +288,9 @@ <optional description="Display all extant JNode Threads"> <option argLabel="groupDump" shortName="g" longName="groupDump"/> </optional> + <optional description="Display all threads in thread groups"> + <option argLabel="verbose" shortName="v"/> + </optional> <argument argLabel="threadName" description="Display the named Thread"/> </syntax> <syntax alias="vminfo"> Modified: trunk/cli/src/commands/org/jnode/command/system/ThreadCommand.java =================================================================== --- trunk/cli/src/commands/org/jnode/command/system/ThreadCommand.java 2011-08-04 12:57:47 UTC (rev 5843) +++ trunk/cli/src/commands/org/jnode/command/system/ThreadCommand.java 2011-08-07 08:53:41 UTC (rev 5844) @@ -24,6 +24,8 @@ import java.security.AccessController; import java.security.PrivilegedAction; +import java.util.Comparator; +import java.util.TreeSet; import org.jnode.shell.AbstractCommand; import org.jnode.shell.syntax.Argument; import org.jnode.shell.syntax.FlagArgument; @@ -36,11 +38,13 @@ * @author Ewout Prangsma (ep...@us...) * @author Martin Husted Hartvig (ha...@jn...) * @author cr...@jn... + * @author Levente S\u00e1ntha */ public class ThreadCommand extends AbstractCommand { private static final String help_name = "the name of a specific thread to be printed"; - private static final String help_group = "if set, output a ThreadGroup dump"; + private static final String help_group = "output a ThreadGroup dump"; + private static final String help_verbose = "show all threads in thread groups"; private static final String help_super = "View info about all threads, or a specific thread"; private static final String SEPARATOR = ", "; @@ -50,12 +54,14 @@ private final ThreadNameArgument argName; private final FlagArgument argDump; + private final FlagArgument argVerbose; public ThreadCommand() { super(help_super); argName = new ThreadNameArgument("threadName", Argument.OPTIONAL, help_name); argDump = new FlagArgument("groupDump", Argument.OPTIONAL, help_group); - registerArguments(argName, argDump); + argVerbose = new FlagArgument("verbose", Argument.OPTIONAL, help_verbose); + registerArguments(argName, argVerbose, argDump); } public static void main(String[] args) throws Exception { @@ -82,11 +88,57 @@ // standard API. grp.list(); } else { - // Show the threads in the ThreadGroup tree. - showThreads(grp, getOutput().getPrintWriter(), threadName); + if(!argVerbose.isSet() && !argName.isSet()) { + showDefaultInfo(grp); + } else { + // Show the threads in the ThreadGroup tree. + showThreads(grp, getOutput().getPrintWriter(), threadName); + } } } + private void showDefaultInfo(ThreadGroup grp) { + TreeSet<Thread> threadSet = new TreeSet<Thread>(new Comparator<Thread>() { + @Override + public int compare(Thread t1, Thread t2) { + return Long.valueOf(t1.getId()).compareTo(t2.getId()); + } + }); + findThreads(grp, threadSet); + + PrintWriter out = getOutput().getPrintWriter(); + for(final Thread thread : threadSet) { + VmThread vmThread = AccessController.doPrivileged(new PrivilegedAction<VmThread>() { + public VmThread run() { + return ThreadHelper.getVmThread(thread); + } + }); + out.println(" " + thread.getId() + SEPARATOR + thread.getName() + SEPARATOR + thread.getPriority() + + SEPARATOR + vmThread.getThreadStateName()); + } + } + + private void findThreads(ThreadGroup grp, TreeSet<Thread> threadSet) { + final int max = grp.activeCount() * 2; + final Thread[] ts = new Thread[max]; + grp.enumerate(ts); + for (int i = 0; i < max; i++) { + final Thread t = ts[i]; + if (t != null) { + threadSet.add(t); + } + } + final int gmax = grp.activeGroupCount() * 2; + final ThreadGroup[] tgs = new ThreadGroup[gmax]; + grp.enumerate(tgs); + for (int i = 0; i < gmax; i++) { + final ThreadGroup tg = tgs[i]; + if (tg != null) { + findThreads(tg, threadSet); + } + } + } + /** * Traverse the ThreadGroups threads and its child ThreadGroups printing * information for each thread found. If 'threadName' is non-null, only This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ls...@us...> - 2011-08-17 19:41:34
|
Revision: 5851 http://jnode.svn.sourceforge.net/jnode/?rev=5851&view=rev Author: lsantha Date: 2011-08-17 19:41:28 +0000 (Wed, 17 Aug 2011) Log Message: ----------- Added shell command: cmp. Modified Paths: -------------- trunk/cli/descriptors/org.jnode.command.file.xml Added Paths: ----------- trunk/cli/src/commands/org/jnode/command/file/CmpCommand.java Modified: trunk/cli/descriptors/org.jnode.command.file.xml =================================================================== --- trunk/cli/descriptors/org.jnode.command.file.xml 2011-08-16 21:16:00 UTC (rev 5850) +++ trunk/cli/descriptors/org.jnode.command.file.xml 2011-08-17 19:41:28 UTC (rev 5851) @@ -26,6 +26,7 @@ <extension point="org.jnode.shell.aliases"> <alias name="cat" class="org.jnode.command.file.CatCommand"/> <alias name="cd" class="org.jnode.command.file.CdCommand" internal="yes"/> + <alias name="cmp" class="org.jnode.command.file.CmpCommand"/> <alias name="cp" class="org.jnode.command.file.CpCommand"/> <alias name="cut" class="org.jnode.command.file.CutCommand"/> <alias name="del" class="org.jnode.command.file.DeleteCommand"/> @@ -74,6 +75,12 @@ <empty description="change the current directory to the 'user.home' directory"/> <argument argLabel="directory" description="change the current directory to 'directory'"/> </syntax> + <syntax alias="cmp"> + <sequence description="compare two files"> + <argument argLabel="file1"/> + <argument argLabel="file2"/> + </sequence> + </syntax> <syntax alias="cp"> <sequence description="copy files or directories"> <optionSet> Added: trunk/cli/src/commands/org/jnode/command/file/CmpCommand.java =================================================================== --- trunk/cli/src/commands/org/jnode/command/file/CmpCommand.java (rev 0) +++ trunk/cli/src/commands/org/jnode/command/file/CmpCommand.java 2011-08-17 19:41:28 UTC (rev 5851) @@ -0,0 +1,123 @@ +package org.jnode.command.file; + +import java.io.BufferedInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.PrintWriter; +import org.jnode.shell.AbstractCommand; +import org.jnode.shell.syntax.Argument; +import org.jnode.shell.syntax.FileArgument; + +/** + * Compare two files and report the first difference. + * + * @author Levente S\u00e1ntha + */ +public class CmpCommand extends AbstractCommand { + + private static final int BUFFER_SIZE = 64 * 1024; + + private static final String HELP_SUPER = "Compare two files"; + private static final String HELP_FILE = "a file to compare"; + private static final String ERR_FILE_INVALID = "%s is not a file%n"; + private static final String MSG_DIFFER = "%s %s differ: byte %d, line %d%n"; + private static final String MSG_EOF = "cmp: EOF on %s%n"; + + private final FileArgument file1Arg; + private final FileArgument file2Arg; + + public CmpCommand() { + super(HELP_SUPER); + + file1Arg = new FileArgument("file1", Argument.MANDATORY | Argument.EXISTING, HELP_FILE); + file2Arg = new FileArgument("file2", Argument.MANDATORY | Argument.EXISTING, HELP_FILE); + + registerArguments(file1Arg, file2Arg); + } + + public static void main(String[] args) throws Exception { + new CmpCommand().execute(args); + } + + @Override + public void execute() throws IOException { + + File file1 = file1Arg.getValue(); + File file2 = file2Arg.getValue(); + + PrintWriter err = getError().getPrintWriter(); + + if (!file1.isFile()) { + err.format(ERR_FILE_INVALID, file1); + exit(1); + } + + if (!file2.isFile()) { + err.format(ERR_FILE_INVALID, file2); + exit(1); + } + + BufferedInputStream bis1 = null; + BufferedInputStream bis2 = null; + + try { + bis1 = new BufferedInputStream(new FileInputStream(file1), BUFFER_SIZE); + bis2 = new BufferedInputStream(new FileInputStream(file2), BUFFER_SIZE); + + long bc = 1; + long lc = 1; + + while (true) { + int b1 = bis1.read(); + int b2 = bis2.read(); + + if (b1 == -1 && b2 == -1) + //done + break; + + if (b1 == -1) { + PrintWriter out = getOutput().getPrintWriter(); + out.format(MSG_EOF, file1.toString()); + exit(1); + return; + } + + if (b2 == -1) { + PrintWriter out = getOutput().getPrintWriter(); + out.format(MSG_EOF, file2.toString()); + exit(1); + return; + } + + if (b1 != b2) { + PrintWriter out = getOutput().getPrintWriter(); + out.format(MSG_DIFFER, file1.toString(), file2.toString(), bc, lc); + exit(1); + return; + } + + bc++; + + if (b1 == (byte) '\n') + lc++; + } + } finally { + if (bis1 != null) { + try { + bis1.close(); + } catch (IOException x) { + //ignore + } + } + + if (bis2 != null) { + try { + bis2.close(); + } catch (IOException x) { + //ignore + } + } + } + } +} This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ls...@us...> - 2013-02-13 20:12:40
|
Revision: 5947 http://jnode.svn.sourceforge.net/jnode/?rev=5947&view=rev Author: lsantha Date: 2013-02-13 20:12:29 +0000 (Wed, 13 Feb 2013) Log Message: ----------- Applied patch by Sebastian Ritter, implementing the uname command. Modified Paths: -------------- trunk/cli/descriptors/org.jnode.command.system.xml Added Paths: ----------- trunk/cli/src/commands/org/jnode/command/system/UnameCommand.java Modified: trunk/cli/descriptors/org.jnode.command.system.xml =================================================================== --- trunk/cli/descriptors/org.jnode.command.system.xml 2013-01-25 11:33:00 UTC (rev 5946) +++ trunk/cli/descriptors/org.jnode.command.system.xml 2013-02-13 20:12:29 UTC (rev 5947) @@ -15,13 +15,13 @@ <import plugin="org.jnode.shell.syntax"/> <import plugin="org.jnode.util"/> </requires> - + <runtime> <library name="jnode-cli.jar"> <export name="org.jnode.command.system.*"/> </library> </runtime> - + <extension point="org.jnode.shell.aliases"> <alias name="alias" class="org.jnode.command.system.AliasCommand"/> <alias name="bindkeys" class="org.jnode.command.system.BindKeysCommand"/> @@ -50,9 +50,10 @@ <alias name="syntax" class="org.jnode.command.system.SyntaxCommand"/> <alias name="terminate" class="org.jnode.command.system.TerminateCommand"/> <alias name="thread" class="org.jnode.command.system.ThreadCommand"/> + <alias name="uname" class="org.jnode.command.system.UnameCommand"/> <alias name="vminfo" class="org.jnode.command.system.VmInfoCommand"/> </extension> - + <extension point="org.jnode.shell.syntaxes"> <syntax alias="alias"> <empty description="List all aliases"/> @@ -222,7 +223,7 @@ <option argLabel="minTotalSize" longName="minTotalSize"/> <option argLabel="className" longName="className"/> </optionSet> - </syntax> + </syntax> <syntax alias="page"> <empty description="Filter standard input a page (screen) at a time"/> <argument argLabel="file" description="Output the file a page (screen) at a time"/> @@ -294,13 +295,25 @@ </optional> <argument argLabel="threadName" description="Display the named Thread"/> </syntax> + <syntax alias="uname" description="Print operating system informations."> + <empty description="Print the hardware type on witch system is running; same like argument -m"/> + <optionSet> + <option argLabel="a" shortName="a"/> + <option argLabel="m" shortName="m"/> + <option argLabel="n" shortName="n"/> + <option argLabel="r" shortName="r"/> + <option argLabel="s" shortName="s"/> + <option argLabel="v" shortName="v"/> + </optionSet> + </syntax> + <syntax alias="vminfo"> <optional description="dump IRQ handler information"> <option argLabel="reset" longName="reset"/> </optional> </syntax> </extension> - + <extension point="org.jnode.security.permissions"> <permission class="java.util.PropertyPermission" name="*" actions="read,write"/> <permission class="java.lang.RuntimePermission" name="getProtectionDomain"/> @@ -317,5 +330,5 @@ <permission class="org.jnode.permission.JNodePermission" name="getVmClass"/> <permission class="java.lang.reflect.ReflectPermission" name="suppressAccessChecks"/> </extension> - + </plugin> Added: trunk/cli/src/commands/org/jnode/command/system/UnameCommand.java =================================================================== --- trunk/cli/src/commands/org/jnode/command/system/UnameCommand.java (rev 0) +++ trunk/cli/src/commands/org/jnode/command/system/UnameCommand.java 2013-02-13 20:12:29 UTC (rev 5947) @@ -0,0 +1,145 @@ +/** + * Copyright (C) 2013 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.system; + +import gnu.java.security.action.GetPropertiesAction; + +import java.security.AccessController; +import java.util.Properties; + +import org.jnode.shell.AbstractCommand; +import org.jnode.shell.syntax.Argument; +import org.jnode.shell.syntax.FlagArgument; + +/** + * <code>uname</code> command prints informations about the operation system. + * With <code>a</code> argument the return syntax of uname posix is: + * <pre>sysname<SPACE>nodename<SPACE>release<SPACE>version<SPACE>machine<NL></pre> + * For example: + * + * <table border='1'> + * <tr><th rowspan='2'>Argument</th><th colspan='3'>Output</th></tr> + * <tr><th>JNode</th><th>MacOS 10.8.2</th><th>OpenSUSE 12</th></tr> + * <tr><td>m</td><td>${os.arch}</td><td>x86_64</td><td>i686</td></tr> + * <tr><td>n</td><td>${os.name}</td><td>my_mac</td><td>suse12</td></tr> + * <tr><td>r</td><td>${os.version}</td><td>12.2.0</td><td>3.1.0-1.2-default</td></tr> + * <tr><td>s</td><td>${os.name}</td><td>Darwin</td><td>Linux</td></tr> + * <tr><td>v</td><td>${os.name} ${os.version}</td><td>Darwin Kernel Version 12.2.0: Sat Aug 25 00:48:52 PDT 2012; root:xnu-2050.18.24~1/RELEASE_X86_64</td><td>#1 SMP Thu Nov 3 14:45:45 UTC 2011 (187dde0)</td></tr> + * </table> + * @author bastie + * + */ +public final class UnameCommand extends AbstractCommand { + + /** + * Command description + */ + private static final String HELP_UNAME = "Print operating system informations."; + /** + * Description of <code>a</code> argument. + */ + private static final String HELP_ALL = "Same as all params [mnrsv] using."; + /** + * Description of <code>m</code> argument. + */ + private static final String HELP_M = "Print the hardware type on witch system is running."; + /** + * Description of <code>n</code> argument. + */ + private static final String HELP_N = "Print the name of network implementation."; + /** + * Description of <code>r</code> argument. + */ + private static final String HELP_R = "Print the current release level of os implementation."; + /** + * Description of <code>s</code> argument. + */ + private static final String HELP_S = "Print the name of implementation."; + /** + * Description of <code>v</code> argument. + */ + private static final String HELP_V = "Print the current version level of release level of os implementation."; + + /** + * Flag for argument 'a'. + */ + private final FlagArgument allArg; + /** + * Flag for argument 'm'. + */ + private final FlagArgument hardwareMaschineArg; + /** + * Flag for argument 'n'. + */ + private final FlagArgument networkImplNameArg; + /** + * Flag for argument 'r'. + */ + private final FlagArgument releaseLevelArg; + /** + * Flag for argument 's'. + */ + private final FlagArgument implNameArg; + /** + * Flag for argument 'v'. + */ + private final FlagArgument versionArg; + + + /** + * Construct new uname command implementation with "amnrsv" arguments. + */ + public UnameCommand() { + super (HELP_UNAME); + allArg = new FlagArgument("a", Argument.OPTIONAL | Argument.SINGLE, HELP_ALL); + hardwareMaschineArg = new FlagArgument("m", Argument.OPTIONAL | Argument.SINGLE, HELP_M); + networkImplNameArg = new FlagArgument("n", Argument.OPTIONAL | Argument.SINGLE, HELP_N); + releaseLevelArg = new FlagArgument("r", Argument.OPTIONAL | Argument.SINGLE, HELP_R); + implNameArg = new FlagArgument("s", Argument.OPTIONAL | Argument.SINGLE, HELP_S); + versionArg = new FlagArgument("v", Argument.OPTIONAL | Argument.SINGLE, HELP_V); + registerArguments(allArg, hardwareMaschineArg, networkImplNameArg,releaseLevelArg, implNameArg, versionArg); + } + + @Override + public void execute() throws Exception { + Properties ps = AccessController.doPrivileged(new GetPropertiesAction()); + + String sysname = allArg.isSet() || hardwareMaschineArg.isSet() ? ps.getProperty("os.arch") : ""; + final String nodename = allArg.isSet() || networkImplNameArg.isSet() ? ps.getProperty("os.name"): ""; + final String release = allArg.isSet() || releaseLevelArg.isSet() ? ps.getProperty("os.version") :""; + final String version = allArg.isSet() || implNameArg.isSet() ? ps.getProperty("os.name") : ""; + final String machine = allArg.isSet() || versionArg.isSet() ? ps.getProperty("os.name") + + " " + + ps.getProperty("os.version"): ""; + // If no argument specific, set the default + if (!allArg.isSet() && + !hardwareMaschineArg.isSet() && + !networkImplNameArg.isSet() && + !releaseLevelArg.isSet() && + !implNameArg.isSet() && + !versionArg.isSet()) { + sysname = ps.getProperty("os.arch");// ps.getProperty("os.arch"); + } + + // Description for more than one arguments contains: + // "separated by one or more <blank>s." + final String result = String.format("%s %s %s %s %s", sysname, nodename, release, version, machine).trim() +'\n'; + + getOutput().getPrintWriter().write(result); + } +} This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ls...@us...> - 2013-02-23 16:41:20
|
Revision: 5977 http://jnode.svn.sourceforge.net/jnode/?rev=5977&view=rev Author: lsantha Date: 2013-02-23 16:41:08 +0000 (Sat, 23 Feb 2013) Log Message: ----------- Updated headers. Modified Paths: -------------- trunk/cli/build-tests.xml trunk/cli/build.xml trunk/cli/descriptors/org.apache.tools.archive.xml trunk/cli/descriptors/org.jnode.command.archive.xml trunk/cli/descriptors/org.jnode.command.argument.xml trunk/cli/descriptors/org.jnode.command.common.xml trunk/cli/descriptors/org.jnode.command.dev.ant.xml trunk/cli/descriptors/org.jnode.command.dev.xml trunk/cli/descriptors/org.jnode.command.file.xml trunk/cli/descriptors/org.jnode.command.net.xml trunk/cli/descriptors/org.jnode.command.system.xml trunk/cli/descriptors/org.jnode.command.util.xml Modified: trunk/cli/build-tests.xml =================================================================== --- trunk/cli/build-tests.xml 2013-02-23 16:39:45 UTC (rev 5976) +++ trunk/cli/build-tests.xml 2013-02-23 16:41:08 UTC (rev 5977) @@ -1,3 +1,23 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + $Id$ + + Copyright (C) 2003-2013 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. +--> <project name="JNode-CLI-Tests" default="all" basedir="."> <import file="${basedir}/../all/build.xml"/> Modified: trunk/cli/build.xml =================================================================== --- trunk/cli/build.xml 2013-02-23 16:39:45 UTC (rev 5976) +++ trunk/cli/build.xml 2013-02-23 16:41:08 UTC (rev 5977) @@ -1,3 +1,23 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + $Id$ + + Copyright (C) 2003-2013 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. +--> <project name="JNode-CoreUtils" default="all" basedir="."> <typedef file="${basedir}/../all/lib/jnode.xml"/> Modified: trunk/cli/descriptors/org.apache.tools.archive.xml =================================================================== --- trunk/cli/descriptors/org.apache.tools.archive.xml 2013-02-23 16:39:45 UTC (rev 5976) +++ trunk/cli/descriptors/org.apache.tools.archive.xml 2013-02-23 16:41:08 UTC (rev 5977) @@ -1,4 +1,23 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- + $Id$ + + Copyright (C) 2003-2013 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. +--> <!DOCTYPE plugin SYSTEM "jnode.dtd"> <plugin id="org.apache.tools.archive" Modified: trunk/cli/descriptors/org.jnode.command.archive.xml =================================================================== --- trunk/cli/descriptors/org.jnode.command.archive.xml 2013-02-23 16:39:45 UTC (rev 5976) +++ trunk/cli/descriptors/org.jnode.command.archive.xml 2013-02-23 16:41:08 UTC (rev 5977) @@ -1,4 +1,23 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- + $Id$ + + Copyright (C) 2003-2013 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. +--> <!DOCTYPE plugin SYSTEM "jnode.dtd"> <plugin id="org.jnode.command.archive" Modified: trunk/cli/descriptors/org.jnode.command.argument.xml =================================================================== --- trunk/cli/descriptors/org.jnode.command.argument.xml 2013-02-23 16:39:45 UTC (rev 5976) +++ trunk/cli/descriptors/org.jnode.command.argument.xml 2013-02-23 16:41:08 UTC (rev 5977) @@ -1,4 +1,23 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- + $Id$ + + Copyright (C) 2003-2013 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. +--> <!DOCTYPE plugin SYSTEM "jnode.dtd"> <plugin id="org.jnode.command.argument" Modified: trunk/cli/descriptors/org.jnode.command.common.xml =================================================================== --- trunk/cli/descriptors/org.jnode.command.common.xml 2013-02-23 16:39:45 UTC (rev 5976) +++ trunk/cli/descriptors/org.jnode.command.common.xml 2013-02-23 16:41:08 UTC (rev 5977) @@ -1,4 +1,23 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- + $Id$ + + Copyright (C) 2003-2013 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. +--> <!DOCTYPE plugin SYSTEM "jnode.dtd"> <plugin id="org.jnode.command.common" Modified: trunk/cli/descriptors/org.jnode.command.dev.ant.xml =================================================================== --- trunk/cli/descriptors/org.jnode.command.dev.ant.xml 2013-02-23 16:39:45 UTC (rev 5976) +++ trunk/cli/descriptors/org.jnode.command.dev.ant.xml 2013-02-23 16:41:08 UTC (rev 5977) @@ -1,4 +1,23 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- + $Id$ + + Copyright (C) 2003-2013 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. +--> <!DOCTYPE plugin SYSTEM "jnode.dtd"> <plugin id="org.jnode.command.dev.ant" Modified: trunk/cli/descriptors/org.jnode.command.dev.xml =================================================================== --- trunk/cli/descriptors/org.jnode.command.dev.xml 2013-02-23 16:39:45 UTC (rev 5976) +++ trunk/cli/descriptors/org.jnode.command.dev.xml 2013-02-23 16:41:08 UTC (rev 5977) @@ -1,4 +1,23 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- + $Id$ + + Copyright (C) 2003-2013 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. +--> <!DOCTYPE plugin SYSTEM "jnode.dtd"> <plugin id="org.jnode.command.dev" Modified: trunk/cli/descriptors/org.jnode.command.file.xml =================================================================== --- trunk/cli/descriptors/org.jnode.command.file.xml 2013-02-23 16:39:45 UTC (rev 5976) +++ trunk/cli/descriptors/org.jnode.command.file.xml 2013-02-23 16:41:08 UTC (rev 5977) @@ -1,4 +1,23 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- + $Id$ + + Copyright (C) 2003-2013 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. +--> <!DOCTYPE plugin SYSTEM "jnode.dtd"> <plugin id="org.jnode.command.file" Modified: trunk/cli/descriptors/org.jnode.command.net.xml =================================================================== --- trunk/cli/descriptors/org.jnode.command.net.xml 2013-02-23 16:39:45 UTC (rev 5976) +++ trunk/cli/descriptors/org.jnode.command.net.xml 2013-02-23 16:41:08 UTC (rev 5977) @@ -1,4 +1,23 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- + $Id$ + + Copyright (C) 2003-2013 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. +--> <!DOCTYPE plugin SYSTEM "jnode.dtd"> <plugin id="org.jnode.command.net" Modified: trunk/cli/descriptors/org.jnode.command.system.xml =================================================================== --- trunk/cli/descriptors/org.jnode.command.system.xml 2013-02-23 16:39:45 UTC (rev 5976) +++ trunk/cli/descriptors/org.jnode.command.system.xml 2013-02-23 16:41:08 UTC (rev 5977) @@ -1,4 +1,23 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- + $Id$ + + Copyright (C) 2003-2013 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. +--> <!DOCTYPE plugin SYSTEM "jnode.dtd"> <plugin id="org.jnode.command.system" Modified: trunk/cli/descriptors/org.jnode.command.util.xml =================================================================== --- trunk/cli/descriptors/org.jnode.command.util.xml 2013-02-23 16:39:45 UTC (rev 5976) +++ trunk/cli/descriptors/org.jnode.command.util.xml 2013-02-23 16:41:08 UTC (rev 5977) @@ -1,4 +1,23 @@ <?xml version="1.0" encoding="UTF-8"?> +<!-- + $Id$ + + Copyright (C) 2003-2013 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. +--> <!DOCTYPE plugin SYSTEM "jnode.dtd"> <plugin id="org.jnode.command.util" This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |