//============================================================================== // 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