//============================================================================== // CommandNode.java //============================================================================== package tribble.net.ftp.shell; import java.io.IOException; import java.io.PrintWriter; import java.lang.Exception; import java.lang.Integer; import java.lang.String; /******************************************************************************* * FTP command script parser. * * *

* Example * *

*  loop1:
*    foreach remote *.tar do begin
*        get $F
*        if $_E != 0
*            continue loop1
*        del $F
*        !tar -xf $F
*        !del $F
*    end
* *

* The example script above parses into the following command parse tree: *

*    1  (label "loop1")
*    2  (foreach "remote" "*.tar")
*    3      (get "$F")
*    4      (if (!= "$_E" "0"))
*    5          (continue 2 "loop1")
*    6      (del "$F")
*    7      (! "tar" "-xf" "$F")
*    8      (! "del" "$F")
* * * @version API 1.1 $Revision: 1.9 $ $Date: 2010/07/12 23:27:13 $ * @since API 1.0, 2007-03-11 * @author David R. Tribble (david@tribble.com). *

* Copyright ©2007-2010 by David R. Tribble, all rights reserved.
* Permission is granted to any person or entity except those designated by * by the United States Department of State as a terrorist, or terrorist * government or agency, to use and distribute this source code provided * that the original copyright notice remains present and unaltered. * * @see CommandParser */ class CommandNode implements CommandCodes { /** Revision information. */ static final String REV = "@(#)tribble/net/ftp/shell/CommandNode.java API 1.1 $Revision: 1.9 $ $Date: 2010/07/12 23:27:13 $\n"; // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // Variables /** Command operator. */ String m_cmd = CMD__UNDEF; /** Arguments (may be null). * Each argument is one of these types:
* - String, containing a name, word token, or literal value;
* - CommandNode, containing a subexpression;
* - BlockDef, containing a begin/end block or func definition. */ Object[] m_args; /** Next command. */ CommandNode m_next; /** Source line number. */ int m_lineNo; // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // Constructors /*************************************************************************** * Constructor. * * @param cmd * Command code, one of the {@link #CMD__UNDEF CMD_XXX} constants. * * @param line * Source line number for this command node. * * @since 1.2, 2007-03-13 */ CommandNode(String cmd, int line) { m_cmd = cmd; m_lineNo = line; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // Methods /*************************************************************************** * Append an argument to this command node. * * @param arg * An argument (usually a String or another {@link CommandNode} * subtree). * * @since 1.1, 2007-03-11 */ int addArg(Object arg) { int n; // Expand the argument array if (m_args != null) { Object[] old; old = m_args; n = old.length; m_args = new Object[n+1]; for (int i = 0; i < n; i++) m_args[i] = old[i]; } else { m_args = new Object[1]; n = 0; } m_args[n] = arg; return (n+1); } /*************************************************************************** * Pretty-print this parse tree. * * @since 1.2, 2007-03-13 */ void print(PrintWriter out) { CommandNode n; if (out == null) return; for (n = this; n != null; n = n.m_next) n.printTree(out, "", -1); } /*************************************************************************** * Pretty-print this parse tree. * This is a helper method. * * @since 1.2, 2007-03-13 */ private void printTree(PrintWriter out, String indent, int lineNo) { if (m_lineNo != lineNo) out.println(m_lineNo + ":"); out.println(indent + "(" + m_cmd + ")"); if (m_args != null) { for (int i = 0; i < m_args.length; i++) { Object arg; arg = m_args[i]; if (arg instanceof CommandNode) { CommandNode n; n = (CommandNode) arg; if (m_cmd == CMD_LABEL || m_cmd == CMD_GOTO || m_cmd == CMD_BREAK || m_cmd == CMD_CONTINUE) { out.print(indent + " -> "); out.print(n.m_cmd); out.print(" @"); out.println(n.m_lineNo); } else { for ( ; n != null; n = n.m_next) n.printTree(out, indent + " ", m_lineNo); } } else { out.print(indent); out.print(" "); if (arg == null) out.println("nil"); else if (arg instanceof String) { String s; char ch; s = (String) arg; ch = s.charAt(0); if (ch == 's' || ch == 'n') { // Note: This is not exactly correct, // but it's good enough for debugging purposes out.print(ch); } else s = 's' + s; ExecFrame.dumpString(s, out); out.println(); } else if (arg instanceof Integer) { int n; n = ((Integer) arg).intValue(); if (n >= 0) out.print('+'); out.println(n); } else if (arg instanceof BlockDef) { BlockDef def; def = (BlockDef) arg; out.print("{\""); out.print(def.m_name); out.print("\" "); out.print(def.m_type); out.println("}"); } else out.println("<" + arg.getClass().getName() + ">"); } } } } } // End CommandNode.java