You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@asterixdb.apache.org by am...@apache.org on 2016/02/22 23:34:56 UTC

[08/34] incubator-asterixdb git commit: Enabled Feed Tests and Added External Library tests

http://git-wip-us.apache.org/repos/asf/incubator-asterixdb/blob/ac683db0/asterix-external-data/src/test/java/org/apache/asterix/external/classad/test/FunctionalTester.java
----------------------------------------------------------------------
diff --git a/asterix-external-data/src/test/java/org/apache/asterix/external/classad/test/FunctionalTester.java b/asterix-external-data/src/test/java/org/apache/asterix/external/classad/test/FunctionalTester.java
new file mode 100644
index 0000000..88b7a32
--- /dev/null
+++ b/asterix-external-data/src/test/java/org/apache/asterix/external/classad/test/FunctionalTester.java
@@ -0,0 +1,1186 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.asterix.external.classad.test;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.asterix.external.classad.AMutableCharArrayString;
+import org.apache.asterix.external.classad.ClassAd;
+import org.apache.asterix.external.classad.ClassAdUnParser;
+import org.apache.asterix.external.classad.ExprList;
+import org.apache.asterix.external.classad.ExprTree;
+import org.apache.asterix.external.classad.ExprTree.NodeKind;
+import org.apache.asterix.external.classad.ExprTreeHolder;
+import org.apache.asterix.external.classad.Lexer.TokenType;
+import org.apache.asterix.external.classad.PrettyPrint;
+import org.apache.asterix.external.classad.StringLexerSource;
+import org.apache.asterix.external.classad.Value;
+import org.apache.asterix.external.library.ClassAdParser;
+import org.apache.asterix.om.base.AMutableString;
+import org.apache.hyracks.api.exceptions.HyracksDataException;
+
+public class FunctionalTester {
+
+    public static Map<String, Variable> variables = new HashMap<String, FunctionalTester.Variable>();
+    public static boolean haveCachedLine = false;
+    public static String cachedLine = "";
+
+    public static class Variable {
+        public String name;
+        public boolean isTree; // If false, then is value
+        public ExprTreeHolder tree;
+        public Value value;
+
+        public Variable(String name, ExprTree tree) {
+            this.name = name;
+            this.tree = new ExprTreeHolder(tree);
+            this.isTree = true;
+        }
+
+        public Variable() {
+            this.name = null;
+            this.tree = new ExprTreeHolder(null);
+            this.isTree = false;
+        }
+
+        public Variable(String name, Value value) {
+            this.name = name;
+            this.value = value;
+            this.isTree = false;
+            this.tree = null;
+        }
+
+        public void getStringRepresentation(AMutableCharArrayString representation) throws HyracksDataException {
+            ClassAdUnParser unparser = new PrettyPrint();
+
+            if (isTree) {
+                unparser.unparse(representation, tree);
+            } else {
+                unparser.unparse(representation, value);
+            }
+            return;
+        }
+
+    }
+
+    /*--------------------------------------------------------------------
+     *
+     * Private Data Types
+     *
+     *--------------------------------------------------------------------*/
+
+    public enum Command {
+        cmd_NoCommand,
+        cmd_InvalidCommand,
+        cmd_Let,
+        cmd_Eval,
+        cmd_Print,
+        cmd_Same,
+        cmd_Sameq,
+        cmd_Diff,
+        cmd_Diffq,
+        cmd_Set,
+        cmd_Show,
+        cmd_Writexml,
+        cmd_Readxml,
+        cmd_Echo,
+        cmd_Help,
+        cmd_Quit
+    };
+
+    public enum PrintFormat {
+        print_Compact,
+        print_Pretty,
+        print_XML,
+        print_XMLPretty
+    };
+
+    public static class Parameters {
+        public boolean debug;
+        public boolean verbose;
+        public boolean interactive;
+        public BufferedReader inputFile;
+
+        public Parameters() {
+            inputFile = null;
+        }
+
+        /*********************************************************************
+         * Function: Parameters::ParseCommandLine
+         * Purpose: This parses the command line. Note that it will exit
+         * if there are any problems.
+         *
+         * @throws IOException
+         *********************************************************************/
+        public void parseCommandLine(int argc, String[] argv) throws IOException {
+            // First we set up the defaults.
+            debug = false;
+            verbose = false;
+            interactive = true;
+            inputFile = null;
+
+            // Then we parse to see what the user wants.
+            for (int argIndex = 1; argIndex < argc; argIndex++) {
+                if (argv[argIndex].equalsIgnoreCase("-d") || argv[argIndex].equalsIgnoreCase("-debug")) {
+                    debug = true;
+                } else if (argv[argIndex].equalsIgnoreCase("-v") || argv[argIndex].equalsIgnoreCase("-verbose")) {
+                    verbose = true;
+                } else {
+                    if (inputFile == null) {
+                        interactive = false;
+                        inputFile = Files.newBufferedReader(Paths.get(argv[argIndex]), StandardCharsets.UTF_8);
+                    }
+                }
+            }
+            return;
+        }
+    }
+
+    public static class State {
+        public int number_of_errors;
+        public int lineNumber;
+        public PrintFormat format;
+
+        public State() {
+            number_of_errors = 0;
+            lineNumber = 0;
+            format = PrintFormat.print_Compact;
+        }
+    }
+
+    // typedef map<string, Variable *> VariableMap;
+
+    /*--------------------------------------------------------------------
+     *
+     * Private Functions
+     *
+     *--------------------------------------------------------------------*/
+
+    public static int test(int argc, String[] argv) throws IOException {
+        // here
+        boolean quit;
+        AMutableString line = new AMutableString(null);
+        State state = new State();
+        Parameters parameters = new Parameters();
+
+        print_version();
+        parameters.parseCommandLine(argc, argv);
+        quit = false;
+
+        while (!quit && readLine(line, state, parameters) == true) {
+            boolean good_line;
+            Command command;
+
+            good_line = replace_variables(line, state, parameters);
+            if (good_line) {
+                command = get_command(line, parameters);
+                quit = handle_command(command, line, state, parameters);
+            }
+        }
+        print_final_state(state);
+
+        if (!parameters.interactive && parameters.inputFile != null) {
+            parameters.inputFile.close();
+        }
+
+        if (state.number_of_errors == 0) {
+            return 0;
+        } else {
+            return 1;
+        }
+    }
+
+    /*********************************************************************
+     * Function: read_line
+     * Purpose:
+     *
+     * @throws IOException
+     *********************************************************************/
+    public static boolean readLine(AMutableString line, State state, Parameters parameters) throws IOException {
+        boolean haveInput;
+
+        if (parameters.interactive) {
+            haveInput = read_line_stdin(line, state, parameters);
+        } else {
+            haveInput = read_line_file(line, state, parameters);
+        }
+        return haveInput;
+    }
+
+    /*********************************************************************
+     * Function: read_line_stdin
+     * Purpose:
+     *
+     * @throws IOException
+     *********************************************************************/
+    public static boolean read_line_stdin(AMutableString line, State state, Parameters parameters) throws IOException {
+        System.out.print("> ");
+        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
+        String line_segment = br.readLine();
+        if (line_segment.length() == 0 || line_segment.equalsIgnoreCase("q")) {
+            line.setValue("");
+            return false;
+        }
+        if (line_is_comment(line_segment)) {
+            // ignore comments, should we read another line?
+            line.setValue("");
+            return true;
+        } else {
+            line.setValue(line.getStringValue() + line_segment);
+            state.lineNumber++;
+            return true;
+        }
+    }
+
+    /*********************************************************************
+     * Function: read_line_file
+     * Purpose:
+     *
+     * @throws IOException
+     *********************************************************************/
+    public static boolean read_line_file(AMutableString line, State state, Parameters parameters) throws IOException {
+        boolean have_input;
+
+        // We read a line, either from our one-line cache, or the file.
+        if (!haveCachedLine) {
+            cachedLine = parameters.inputFile.readLine();
+            state.lineNumber++;
+            haveCachedLine = true;
+        } else {
+            // We have a cached-line, but we need to increment the line number for it.
+            // We don't increment it until we use it.
+            state.lineNumber++;
+        }
+        if (cachedLine == null) {
+            cachedLine = parameters.inputFile.readLine();
+            if (cachedLine == null) {
+                have_input = false;
+                haveCachedLine = false;
+            } else {
+                line.setValue(cachedLine);
+                have_input = true;
+                haveCachedLine = false;
+                cachedLine = null;
+            }
+        } else {
+            line.setValue(cachedLine);
+            have_input = true;
+            haveCachedLine = false;
+        }
+
+        // If we actually have a non-comment line, we read another line
+        // from the file If it begins with a whitespace character, then we
+        // append it to the previous line, otherwise we cache it for the
+        // next time we call this function.
+        if (have_input) {
+            if (line_is_comment(line.getStringValue())) {
+                line.setValue("");
+            } else {
+                boolean done = false;
+                while (!done) {
+                    cachedLine = parameters.inputFile.readLine();
+                    if (cachedLine != null && line_is_comment(cachedLine)) {
+                        // ignore comments
+                        state.lineNumber++;
+                    } else if (cachedLine != null && cachedLine.length() == 0) {
+                        line.setValue(line.getStringValue() + " ");
+                        state.lineNumber++;
+                    } else if (cachedLine != null && Character.isWhitespace(cachedLine.charAt(0))) {
+                        line.setValue(line.getStringValue() + cachedLine);
+                        state.lineNumber++;
+                    } else {
+                        done = true;
+                        haveCachedLine = cachedLine != null ? true : false;
+                    }
+                }
+            }
+        }
+        return have_input;
+    }
+
+    /*********************************************************************
+     * Function: replace_variables
+     * Purpose:
+     *
+     * @throws HyracksDataException
+     *********************************************************************/
+    public static boolean replace_variables(AMutableString mutableLine, State state, Parameters parameters)
+            throws HyracksDataException {
+        boolean good_line;
+        String error;
+
+        good_line = true;
+        error = "";
+        Variable var = new Variable();
+        for (;;) {
+            int dollar;
+            int current_position;
+            String variable_name;
+            AMutableCharArrayString variable_value = new AMutableCharArrayString();
+            current_position = 0;
+            dollar = mutableLine.getStringValue().indexOf('$', current_position);
+            if (dollar < 0) {
+                break;
+            }
+            current_position = dollar + 1;
+            if (!Character.isAlphabetic(mutableLine.getStringValue().charAt(current_position))) {
+                good_line = false;
+                error = "Bad variable name.";
+                break;
+            }
+            current_position++;
+            while (Character.isLetterOrDigit((mutableLine.getStringValue().charAt(current_position)))
+                    || mutableLine.getStringValue().charAt(current_position) == '_') {
+                current_position++;
+            }
+
+            variable_name = mutableLine.getStringValue().substring(dollar + 1, current_position);
+            var = variables.get(variable_name);
+            if (var == null) {
+                good_line = false;
+                error = "Unknown variable '$";
+                error += variable_name;
+                error += "'";
+                break;
+            }
+            var.getStringRepresentation(variable_value);
+
+            // We have to be careful with substr() because with gcc 2.96, it likes to
+            // assert/except if you give it values that are too large.
+            String end;
+            if (current_position < mutableLine.getStringValue().length()) {
+                end = mutableLine.getStringValue().substring(current_position);
+            } else {
+                end = "";
+            }
+            mutableLine.setValue(mutableLine.getStringValue().substring(0, dollar) + variable_value.toString() + end);
+        }
+
+        if (parameters.debug) {
+            System.err.println("# after replacement: " + mutableLine.getStringValue());
+        }
+
+        if (!good_line) {
+            print_error_message(error, state);
+        }
+        return good_line;
+    }
+
+    /*********************************************************************
+     * Function: get_command
+     * Purpose:
+     *********************************************************************/
+    public static Command get_command(AMutableString line, Parameters parameters) {
+        int current_position;
+        int length;
+        String command_name;
+        Command command;
+
+        current_position = 0;
+        length = line.getStringValue().length();
+        command_name = "";
+        command = Command.cmd_NoCommand;
+
+        // Skip whitespace
+        while (current_position < length && Character.isWhitespace(line.getStringValue().charAt(current_position))) {
+            current_position++;
+        }
+        // Find command name
+        while (current_position < length && Character.isAlphabetic(line.getStringValue().charAt(current_position))) {
+            command_name += line.getStringValue().charAt(current_position);
+            current_position++;
+        }
+        // Figure out what the command is.
+        if (command_name.length() == 0) {
+            command = Command.cmd_NoCommand;
+        } else if (command_name.equalsIgnoreCase("let")) {
+            command = Command.cmd_Let;
+        } else if (command_name.equalsIgnoreCase("eval")) {
+            command = Command.cmd_Eval;
+        } else if (command_name.equalsIgnoreCase("print")) {
+            command = Command.cmd_Print;
+        } else if (command_name.equalsIgnoreCase("same")) {
+            command = Command.cmd_Same;
+        } else if (command_name.equalsIgnoreCase("sameq")) {
+            command = Command.cmd_Sameq;
+        } else if (command_name.equalsIgnoreCase("diff")) {
+            command = Command.cmd_Diff;
+        } else if (command_name.equalsIgnoreCase("diffq")) {
+            command = Command.cmd_Diffq;
+        } else if (command_name.equalsIgnoreCase("set")) {
+            command = Command.cmd_Set;
+        } else if (command_name.equalsIgnoreCase("show")) {
+            command = Command.cmd_Show;
+        } else if (command_name.equalsIgnoreCase("writexml")) {
+            command = Command.cmd_Writexml;
+        } else if (command_name.equalsIgnoreCase("readxml")) {
+            command = Command.cmd_Readxml;
+        } else if (command_name.equalsIgnoreCase("echo")) {
+            command = Command.cmd_Echo;
+        } else if (command_name.equalsIgnoreCase("help")) {
+            command = Command.cmd_Help;
+        } else if (command_name.equalsIgnoreCase("quit")) {
+            command = Command.cmd_Quit;
+        } else {
+            command = Command.cmd_InvalidCommand;
+        }
+        shorten_line(line, current_position);
+        return command;
+    }
+
+    /*********************************************************************
+     * Function: handle_command
+     * Purpose:
+     *
+     * @throws IOException
+     *********************************************************************/
+    public static boolean handle_command(Command command, AMutableString line, State state, Parameters parameters)
+            throws IOException {
+        boolean quit = false;
+
+        switch (command) {
+            case cmd_NoCommand:
+                // Ignore. This isn't a problem.
+                break;
+            case cmd_InvalidCommand:
+                print_error_message("Unknown command on line", state);
+                break;
+            case cmd_Let:
+                handle_let(line, state, parameters);
+                break;
+            case cmd_Eval:
+                handle_eval(line, state, parameters);
+                break;
+            case cmd_Print:
+                handle_print(line, state, parameters);
+                break;
+            case cmd_Same:
+                handle_same(line, state, parameters);
+                break;
+            case cmd_Sameq:
+                handle_sameq(line, state, parameters);
+                break;
+            case cmd_Diff:
+                handle_diff(line, state, parameters);
+                break;
+            case cmd_Diffq:
+                handle_diffq(line, state, parameters);
+                break;
+            case cmd_Set:
+                handle_set(line, state, parameters);
+                break;
+            case cmd_Show:
+                handle_show(line, state, parameters);
+                break;
+            case cmd_Writexml:
+                // handle_writexml(line, state, parameters);
+                break;
+            case cmd_Readxml:
+                // handle_readxml(line, state, parameters);
+                break;
+            case cmd_Echo:
+                handle_echo(line.getStringValue(), state, parameters);
+                break;
+            case cmd_Help:
+                handle_help();
+                break;
+            case cmd_Quit:
+                quit = true;
+                break;
+        }
+        return quit;
+    }
+
+    /*********************************************************************
+     * Function: handle_let
+     * Purpose:
+     *
+     * @throws IOException
+     *********************************************************************/
+    public static void handle_let(AMutableString line, State state, Parameters parameters) throws IOException {
+        AMutableString variable_name = new AMutableString(null);
+        ExprTree tree;
+        Variable variable;
+
+        if (get_variable_name(line, true, variable_name, state, parameters)) {
+            tree = get_expr(line, state, parameters);
+            if (tree != null) {
+                variable = new Variable(variable_name.getStringValue(), tree);
+                variables.put(variable_name.getStringValue(), variable);
+                if (parameters.interactive) {
+                    print_expr(tree, state, parameters);
+                }
+            }
+        }
+        return;
+    }
+
+    /*********************************************************************
+     * Function: handle_eval
+     * Purpose:
+     *
+     * @throws IOException
+     *********************************************************************/
+    public static void handle_eval(AMutableString line, State state, Parameters parameters) throws IOException {
+        AMutableString variable_name = new AMutableString("");
+        ExprTree tree;
+        Variable variable;
+
+        if (get_variable_name(line, true, variable_name, state, parameters)) {
+            tree = get_expr(line, state, parameters);
+            if (tree != null) {
+                Value value = new Value();
+                if (!evaluate_expr(tree, value, parameters)) {
+                    print_error_message("Couldn't evaluate rvalue", state);
+                } else {
+                    variable = new Variable(variable_name.getStringValue(), value);
+                    variables.put(variable_name.getStringValue(), variable);
+                    if (true) {
+                        System.out.println(variable_name.getStringValue() + " = " + value);
+                    }
+                }
+            }
+        }
+        return;
+    }
+
+    /*********************************************************************
+     * Function: handle_print
+     * Purpose:
+     *
+     * @throws IOException
+     *********************************************************************/
+    public static void handle_print(AMutableString line, State state, Parameters parameters) throws IOException {
+        ExprTree tree;
+        tree = get_expr(line, state, parameters);
+        if (tree != null) {
+            print_expr(tree, state, parameters);
+        }
+    }
+
+    /*********************************************************************
+     * Function: handle_same
+     * Purpose:
+     *
+     * @throws IOException
+     *********************************************************************/
+    public static void handle_same(AMutableString line, State state, Parameters parameters) throws IOException {
+        ExprTreeHolder tree = new ExprTreeHolder();
+        ExprTreeHolder tree2 = new ExprTreeHolder();
+        Value value1 = new Value();
+        Value value2 = new Value();
+        try {
+            get_two_exprs(line, tree, tree2, state, parameters);
+            if (tree.getInnerTree() != null || tree2.getInnerTree() != null) {
+
+                if (parameters.debug) {
+                    System.out.println("Sameeval has two trees:");
+                    System.out.print(" ");
+                    print_expr(tree, state, parameters);
+                    System.out.print(" ");
+                    print_expr(tree2, state, parameters);
+                }
+                if (!evaluate_expr(tree, value1, parameters)) {
+                    print_error_message("Couldn't evaluate first expression.\n", state);
+                } else if (!evaluate_expr(tree2, value2, parameters)) {
+                    print_error_message("Couldn't evaluate second expressions.\n", state);
+                } else if (!value1.sameAs(value2)) {
+                    print_error_message("the expressions are different.", state);
+                    assert (false);
+                }
+                if (parameters.debug) {
+                    System.out.println("They evaluated to: ");
+                    System.out.println(" " + value1);
+                    System.out.println(" " + value2);
+                }
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+            assert (false);
+        }
+        return;
+    }
+
+    /*********************************************************************
+     * Function: handle_sameq
+     * Purpose:
+     *
+     * @throws IOException
+     *********************************************************************/
+    public static void handle_sameq(AMutableString line, State state, Parameters parameters) throws IOException {
+        ExprTreeHolder tree = new ExprTreeHolder();
+        ExprTreeHolder tree2 = new ExprTreeHolder();
+
+        get_two_exprs(line, tree, tree2, state, parameters);
+        if (tree.getInnerTree() != null || tree2.getInnerTree() != null) {
+            if (!tree.sameAs(tree2)) {
+                print_error_message("the expressions are different.", state);
+            }
+        }
+        return;
+    }
+
+    /*********************************************************************
+     * Function: handle_diff
+     * Purpose:
+     *
+     * @throws IOException
+     *********************************************************************/
+    public static void handle_diff(AMutableString line, State state, Parameters parameters) throws IOException {
+        ExprTreeHolder tree = new ExprTreeHolder();
+        ExprTreeHolder tree2 = new ExprTreeHolder();
+        Value value1 = new Value();
+        Value value2 = new Value();
+
+        get_two_exprs(line, tree, tree2, state, parameters);
+        if (tree.getInnerTree() != null || tree2.getInnerTree() != null) {
+            if (!evaluate_expr(tree, value1, parameters)) {
+                print_error_message("Couldn't evaluate first expression.\n", state);
+            } else if (!evaluate_expr(tree2, value2, parameters)) {
+                print_error_message("Couldn't evaluate second expressions.\n", state);
+            } else if (value1.sameAs(value2)) {
+                print_error_message("the expressions are the same.", state);
+                assert (false);
+            }
+        }
+        return;
+    }
+
+    /*********************************************************************
+     * Function: handle_diffq
+     * Purpose:
+     *
+     * @throws IOException
+     *********************************************************************/
+    public static void handle_diffq(AMutableString line, State state, Parameters parameters) throws IOException {
+        ExprTreeHolder tree = new ExprTreeHolder();
+        ExprTreeHolder tree2 = new ExprTreeHolder();
+
+        get_two_exprs(line, tree, tree2, state, parameters);
+        if (tree.getInnerTree() != null || tree2.getInnerTree() != null) {
+            if (tree.sameAs(tree2)) {
+                print_error_message("the expressions are the same.", state);
+            }
+        }
+        return;
+    }
+
+    /*********************************************************************
+     * Function: handle_set
+     * Purpose:
+     *********************************************************************/
+    public static void handle_set(AMutableString line, State state, Parameters parameters) {
+        AMutableString option_name = new AMutableString(null);
+        AMutableString option_value = new AMutableString(null);
+
+        if (get_variable_name(line, false, option_name, state, parameters)) {
+            if (get_variable_name(line, false, option_value, state, parameters)) {
+                if (option_name.getStringValue().equalsIgnoreCase("format")) {
+                    if (option_value.getStringValue().equalsIgnoreCase("compact")) {
+                        state.format = PrintFormat.print_Compact;
+                    } else if (option_value.getStringValue().equalsIgnoreCase("pretty")) {
+                        state.format = PrintFormat.print_Pretty;
+                    } else if (option_value.getStringValue().equalsIgnoreCase("xml")) {
+                        state.format = PrintFormat.print_XML;
+                    } else if (option_value.getStringValue().equalsIgnoreCase("xmlpretty")) {
+                        state.format = PrintFormat.print_XMLPretty;
+                    } else {
+                        print_error_message("Unknown print format. Use compact, pretty, xml, or xmlpretty", state);
+                    }
+                } else {
+                    print_error_message("Unknown option. The only option currently available is format", state);
+                }
+            }
+        }
+        return;
+    }
+
+    /*********************************************************************
+     * Function: handle_show
+     * Purpose:
+     *********************************************************************/
+    public static void handle_show(AMutableString line, State state, Parameters parameters) {
+        AMutableString option_name = new AMutableString(null);
+
+        if (get_variable_name(line, false, option_name, state, parameters)) {
+            if (option_name.getStringValue().equalsIgnoreCase("format")) {
+                System.out.print("Format: ");
+                switch (state.format) {
+                    case print_Compact:
+                        System.out.print("Traditional Compact\n");
+                        break;
+                    case print_Pretty:
+                        System.out.print("Traditional Pretty\n");
+                        break;
+                    case print_XML:
+                        System.out.print("XML Compact\n");
+                        break;
+                    case print_XMLPretty:
+                        System.out.print("XML Pretty\n");
+                        break;
+                }
+            } else {
+                print_error_message("Unknown option. The only option currently available is format", state);
+            }
+        }
+
+        return;
+    }
+
+    /*********************************************************************
+     * Function: handle_writexml
+     * Purpose:
+     *
+     * @throws IOException
+     *********************************************************************/
+    /*
+    public static void handle_writexml(AMutableString line, State state, Parameters parameters) throws IOException {
+    AMutableString filename = new AMutableString("");
+    ExprTree expr;
+    BufferedWriter xml_file;
+
+    if (get_file_name(line, filename, state, parameters)) {
+    if ((expr = get_expr(line, state, parameters)) != null) {
+    if (expr_okay_for_xml_file(expr, state, parameters)) {
+    xml_file = Files.newBufferedWriter(Paths.get(filename.getStringValue()));
+    ClassAdXMLUnParser unparser = new ClassAdXMLUnParser();
+    AMutableCharArrayString classad_text = new AMutableCharArrayString();
+    xml_file.write("<classads>\n");
+    if (expr.getKind() == NodeKind.CLASSAD_NODE) {
+    unparser.Unparse(classad_text, expr);
+    xml_file.write(classad_text.toString());
+    } else {
+    ExprList list = (ExprList) expr;
+    for (ExprTree classad : list.getExprList()) {
+    classad_text.setValue("");
+    unparser.Unparse(classad_text, classad);
+    xml_file.write(classad_text.toString());
+    xml_file.newLine();
+    }
+    }
+    xml_file.write("</classads>\n");
+    xml_file.close();
+    }
+    }
+    }
+    return;
+    }
+
+    *//*********************************************************************
+      * Function: handle_readxml
+      * Purpose:
+      *
+      * @throws IOException
+      *********************************************************************/
+
+    /*
+    public static void handle_readxml(AMutableString line, State state, Parameters parameters) throws IOException {
+    AMutableString variable_name = new AMutableString(null);
+    AMutableString file_name = new AMutableString(null);
+
+    if (get_variable_name(line, false, variable_name, state, parameters)) {
+    if (get_file_name(line, file_name, state, parameters)) {
+    InputStream xml_file = Files.newInputStream(Paths.get(file_name.getStringValue()));
+    ExprList list;
+    ClassAd classad;
+    ClassAdXMLParser parser = new ClassAdXMLParser();
+    Variable variable;
+
+    list = new ExprList();
+    do {
+    classad = parser.ParseClassAd(new InputStreamLexerSource(xml_file));
+    if (classad != null) {
+    list.add(classad);
+    }
+    } while (classad != null);
+    variable = new Variable(variable_name.getStringValue(), list);
+    variables.put(variable_name.getStringValue(), variable);
+    if (parameters.interactive) {
+    print_expr(list, state, parameters);
+    }
+    }
+    }
+    }
+
+    *//*********************************************************************
+      * Function: handle_echo
+      * Purpose:
+      *********************************************************************/
+    public static void handle_echo(String line, State state, Parameters parameters) {
+        AMutableCharArrayString new_line = new AMutableCharArrayString();
+        int index;
+
+        index = 0;
+
+        while (index < line.length() && Character.isWhitespace(line.charAt(index))) {
+            index++;
+        }
+        while (index < line.length()) {
+            new_line.appendChar(line.charAt(index));
+            index++;
+        }
+
+        System.out.println(new_line.toString());
+    }
+
+    /*********************************************************************
+     * Function: handle_help
+     * Purpose:
+     *********************************************************************/
+    public static void handle_help() {
+        print_version();
+
+        System.out.println();
+        System.out.println("Commands:");
+        System.out.println("let name = expr   Set a variable to an unevaluated expression.");
+        System.out.println("eval name = expr  Set a variable to an evaluated expression.");
+        System.out.println("same expr1 expr2  Prints a message only if expr1 and expr2 are different.");
+        System.out.println("sameq expr1 expr2 Prints a message only if expr1 and expr2 are different.");
+        System.out.println("                   same evaluates its expressions first, sameq doesn't.");
+        System.out.println("diff expr1 expr2  Prints a message only if expr1 and expr2 are the same.");
+        System.out.println("diffq expr1 expr2 Prints a message only if expr1 and expr2 are the same.");
+        System.out.println("                   diff evaluates its expressions first, diffq doesn't.");
+        System.out.println("set opt value     Sets an option to a particular value.");
+        System.out.println("quit              Exit this program.");
+        System.out.println("help              Print this message.");
+        System.out.println();
+        System.out.println("Options (for the set command):");
+        System.out.println("format              Set the way ClassAds print.");
+        System.out.println("  compact           A compact, traditional style");
+        System.out.println("  pretty            Traditional, with more spaces");
+        System.out.println("  xml               A compact XML representation");
+        System.out.println("  xmlpretty         XML with extra spacing for readability.");
+        return;
+    }
+
+    /*********************************************************************
+     * Function: get_variable_name
+     * Purpose:
+     *********************************************************************/
+    public static boolean get_variable_name(AMutableString line, boolean swallow_equals, AMutableString variable_name,
+            State state, Parameters parameters) {
+        int current_position;
+        int length;
+        boolean have_good_name;
+
+        current_position = 0;
+        length = line.getStringValue().length();
+        variable_name.setValue("");
+        have_good_name = false;
+
+        // Skip whitespace
+        while (current_position < length && Character.isWhitespace(line.getStringValue().charAt(current_position))) {
+            current_position++;
+        }
+        // Find variable name
+        if (current_position < length && Character.isAlphabetic(line.getStringValue().charAt(current_position))) {
+            variable_name.setValue(variable_name.getStringValue() + line.getStringValue().charAt(current_position));
+            current_position++;
+            // As soon as we have at least one character in the name, it's good.
+            have_good_name = true;
+
+            while (current_position < length
+                    && (Character.isLetterOrDigit(line.getStringValue().charAt(current_position))
+                            || line.getStringValue().charAt(current_position) == '_')) {
+                variable_name.setValue(variable_name.getStringValue() + line.getStringValue().charAt(current_position));
+                current_position++;
+            }
+        }
+        if (!have_good_name) {
+            print_error_message("Bad variable name", state);
+        } else if (swallow_equals) {
+            // Skip whitespace
+            while (current_position < length
+                    && Character.isWhitespace(line.getStringValue().charAt(current_position))) {
+                current_position++;
+            }
+            if (line.getStringValue().charAt(current_position) == '=') {
+                current_position++;
+            } else {
+                print_error_message("Missing equal sign", state);
+                have_good_name = false;
+            }
+        }
+
+        if (parameters.debug) {
+            if (have_good_name) {
+                System.out.println("# Got variable name: " + variable_name);
+            } else {
+                System.out.println("# Bad variable name: " + variable_name);
+            }
+        }
+
+        shorten_line(line, current_position);
+        return have_good_name;
+    }
+
+    /*********************************************************************
+     * Function: get_file_name
+     * Purpose:
+     *********************************************************************/
+    public static boolean get_file_name(AMutableString line, AMutableString variable_name, State state,
+            Parameters parameters) {
+        int current_position;
+        int length;
+        boolean have_good_name;
+
+        current_position = 0;
+        length = line.getStringValue().length();
+        variable_name.setValue("");
+        have_good_name = false;
+
+        // Skip whitespace
+        while (current_position < length && Character.isWhitespace(line.getStringValue().charAt(current_position))) {
+            current_position++;
+        }
+        // Find file name
+        while (current_position < length && (!Character.isWhitespace(line.getStringValue().charAt(current_position)))) {
+            have_good_name = true;
+            variable_name.setValue(variable_name.getStringValue() + line.getStringValue().charAt(current_position));
+            current_position++;
+        }
+        if (!have_good_name) {
+            print_error_message("Bad file name", state);
+        }
+
+        if (parameters.debug) {
+            if (have_good_name) {
+                System.out.println("# Got file name: " + variable_name.getStringValue());
+            } else {
+                System.out.println("# Bad file name: " + variable_name.getStringValue());
+            }
+        }
+
+        shorten_line(line, current_position);
+        return have_good_name;
+    }
+
+    /*********************************************************************
+     * Function: get_expr
+     * Purpose:
+     *
+     * @throws IOException
+     *********************************************************************/
+    public static ExprTree get_expr(AMutableString line, State state, Parameters parameters) throws IOException {
+        int offset;
+        ExprTree tree;
+        ClassAdParser parser = new ClassAdParser();
+        StringLexerSource lexer_source = new StringLexerSource(line.getStringValue());
+
+        tree = parser.parseExpression(lexer_source, false);
+        offset = lexer_source.getCurrentLocation();
+        shorten_line(line, offset);
+
+        if (tree == null) {
+            print_error_message("Missing expression", state);
+        }
+
+        return tree;
+    }
+
+    /*********************************************************************
+     * Function: get_two_exprs
+     * Purpose:
+     *
+     * @throws IOException
+     *********************************************************************/
+    public static void get_two_exprs(AMutableString line, ExprTreeHolder tree1, ExprTreeHolder tree2, State state,
+            Parameters parameters) throws IOException {
+        int offset;
+        ClassAdParser parser = new ClassAdParser();
+        StringLexerSource lexer_source = new StringLexerSource(line.getStringValue());
+
+        tree1.setInnerTree(parser.parseExpression(lexer_source, false));
+        if (tree1.getInnerTree() == null) {
+            print_error_message("Couldn't parse first expression.", state);
+            tree2.setInnerTree(null);
+            throw new IOException();
+        } else {
+            if (parameters.debug) {
+                System.out.print("# Tree1: ");
+                print_expr(tree1, state, parameters);
+            }
+
+            if (parser.peekToken() != TokenType.LEX_COMMA) {
+                print_error_message("Missing comma.\n", state);
+                tree1.setInnerTree(null);
+                tree2.setInnerTree(null);;
+            } else {
+                parser.consumeToken();
+                tree2.setInnerTree(parser.parseNextExpression());
+                offset = lexer_source.getCurrentLocation();
+                shorten_line(line, offset);
+                if (tree2.getInnerTree() == null) {
+                    print_error_message("Couldn't parse second expression.", state);
+                    tree1.setInnerTree(null);
+                    throw new IOException();
+                } else if (parameters.debug) {
+                    System.out.print("# Tree2: ");
+                    print_expr(tree2, state, parameters);
+                    System.out.print("# Tree1: ");
+                    print_expr(tree1, state, parameters);
+                    System.out.println();
+                }
+            }
+        }
+
+        return;
+    }
+
+    /*********************************************************************
+     * Function: print_expr
+     * Purpose:
+     *
+     * @throws HyracksDataException
+     *********************************************************************/
+    public static void print_expr(ExprTree tree, State state, Parameters parameters) throws HyracksDataException {
+        AMutableCharArrayString output = new AMutableCharArrayString();
+
+        if (state.format == PrintFormat.print_Compact) {
+            ClassAdUnParser unparser = new ClassAdUnParser();
+            unparser.unparse(output, tree);
+        } else if (state.format == PrintFormat.print_Pretty) {
+            PrettyPrint unparser = new PrettyPrint();
+            unparser.unparse(output, tree);
+        } else if (state.format == PrintFormat.print_XML) {/*
+                                                           ClassAdXMLUnParser unparser = new ClassAdXMLUnParser();
+                                                           unparser.SetCompactSpacing(true);
+                                                           unparser.Unparse(output, tree);
+                                                           } else if (state.format == PrintFormat.print_XMLPretty) {
+                                                           ClassAdXMLUnParser unparser = new ClassAdXMLUnParser();
+                                                           unparser.SetCompactSpacing(false);
+                                                           unparser.Unparse(output, tree);*/
+        }
+        System.out.println(output);
+    }
+
+    /*********************************************************************
+     * Function: evaluate_expr
+     * Purpose:
+     *
+     * @throws HyracksDataException
+     *********************************************************************/
+    public static boolean evaluate_expr(ExprTree tree, Value value, Parameters parameters) throws HyracksDataException {
+        ClassAd classad = new ClassAd();
+        boolean success = false;;
+        classad.insert("internal___", tree);
+        success = classad.evaluateAttr("internal___", value);
+        classad.remove("internal___");
+        return success;
+    }
+
+    /*********************************************************************
+     * Function: shorten_line
+     * Purpose:
+     *********************************************************************/
+    public static void shorten_line(AMutableString line, int offset) {
+        // We have to be careful with substr() because with gcc 2.96, it likes to
+        // assert/except if you give it values that are too large.
+        if (offset < line.getStringValue().length()) {
+            line.setValue(line.getStringValue().substring(offset));
+        } else {
+            line.setValue("");
+        }
+    }
+
+    /*********************************************************************
+     * Function: print_version
+     * Purpose:
+     *********************************************************************/
+    public static void print_version() {
+        AMutableString classad_version = new AMutableString(null);
+        ClassAd.classAdLibraryVersion(classad_version);
+        System.out.println("ClassAd Functional Tester v" + classad_version.getStringValue());
+        return;
+    }
+
+    /*********************************************************************
+     * Function: print_error_message
+     * Purpose:
+     *********************************************************************/
+
+    /*********************************************************************
+     * Function: print_error_message
+     * Purpose:
+     *********************************************************************/
+    public static void print_error_message(String error, State state) {
+        System.out.println("* Line " + state.lineNumber + ": " + error);
+        state.number_of_errors++;
+    }
+
+    /*********************************************************************
+     * Function: print_final_state
+     * Purpose:
+     *********************************************************************/
+    public static void print_final_state(State state) {
+        if (state.number_of_errors == 0) {
+            System.out.println("No errors.");
+        } else if (state.number_of_errors == 1) {
+            System.out.println("1 error.");
+        } else {
+            System.out.println(state.number_of_errors + " errors");
+        }
+        return;
+    }
+
+    public static boolean line_is_comment(String line) {
+        boolean is_comment;
+
+        if (line.length() > 1 && line.charAt(0) == '/' && line.charAt(1) == '/') {
+            is_comment = true;
+        } else {
+            is_comment = false;
+        }
+        return is_comment;
+    }
+
+    public static boolean expr_okay_for_xml_file(ExprTree tree, State state, Parameters parameters) {
+        boolean is_okay;
+
+        if (tree.getKind() == NodeKind.CLASSAD_NODE) {
+            is_okay = true;
+        } else if (tree.getKind() != NodeKind.EXPR_LIST_NODE) {
+            is_okay = false;
+            System.out.println("We have " + tree.getKind().ordinal());
+        } else {
+            ExprList list = (ExprList) tree;
+            is_okay = true;
+            for (ExprTree element : list.getExprList()) {
+
+                if (element.getKind() != NodeKind.CLASSAD_NODE) {
+                    System.out.println("Inside list, we have " + tree.getKind().ordinal());
+                    is_okay = false;
+                    break;
+                }
+            }
+        }
+        if (!is_okay) {
+            print_error_message("writexml requires a ClassAd or list of ClassAds as an argument.", state);
+        }
+        return is_okay;
+    }
+
+}