| /* |
| * 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.classad.object.pool.ClassAdObjectPool; |
| 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, ClassAdObjectPool objectPool) { |
| this.name = name; |
| this.tree = new ExprTreeHolder(tree, objectPool); |
| this.isTree = true; |
| } |
| |
| public Variable(ClassAdObjectPool objectPool) { |
| this.name = null; |
| this.tree = new ExprTreeHolder(objectPool); |
| 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, ClassAdObjectPool objectPool) |
| throws HyracksDataException { |
| ClassAdUnParser unparser = new PrettyPrint(objectPool); |
| |
| 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 = false; |
| } 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, ClassAdObjectPool objectPool) 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, objectPool); |
| if (good_line) { |
| command = get_command(line, parameters); |
| quit = handle_command(command, line, state, parameters, objectPool); |
| } |
| } |
| 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, |
| ClassAdObjectPool objectPool) throws HyracksDataException { |
| boolean good_line; |
| String error; |
| |
| good_line = true; |
| error = ""; |
| Variable var = new Variable(objectPool); |
| 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, objectPool); |
| |
| // 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, |
| ClassAdObjectPool objectPool) 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, objectPool); |
| break; |
| case cmd_Eval: |
| handle_eval(line, state, parameters, objectPool); |
| break; |
| case cmd_Print: |
| handle_print(line, state, parameters, objectPool); |
| break; |
| case cmd_Same: |
| handle_same(line, state, parameters, objectPool); |
| break; |
| case cmd_Sameq: |
| handle_sameq(line, state, parameters, objectPool); |
| break; |
| case cmd_Diff: |
| handle_diff(line, state, parameters, objectPool); |
| break; |
| case cmd_Diffq: |
| handle_diffq(line, state, parameters, objectPool); |
| break; |
| case cmd_Set: |
| handle_set(line, state, parameters, objectPool); |
| break; |
| case cmd_Show: |
| handle_show(line, state, parameters, objectPool); |
| 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, ClassAdObjectPool objectPool) |
| 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, objectPool); |
| if (tree != null) { |
| variable = new Variable(variable_name.getStringValue(), tree, objectPool); |
| variables.put(variable_name.getStringValue(), variable); |
| if (parameters.interactive) { |
| print_expr(tree, state, parameters, objectPool); |
| } |
| } |
| } |
| return; |
| } |
| |
| /********************************************************************* |
| * Function: handle_eval |
| * Purpose: |
| * |
| * @throws IOException |
| *********************************************************************/ |
| public static void handle_eval(AMutableString line, State state, Parameters parameters, |
| ClassAdObjectPool objectPool) 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, objectPool); |
| if (tree != null) { |
| Value value = new Value(objectPool); |
| if (!evaluate_expr(tree, value, parameters, objectPool)) { |
| print_error_message("Couldn't evaluate rvalue", state); |
| } else { |
| variable = new Variable(variable_name.getStringValue(), value); |
| variables.put(variable_name.getStringValue(), variable); |
| } |
| } |
| } |
| return; |
| } |
| |
| /********************************************************************* |
| * Function: handle_print |
| * Purpose: |
| * |
| * @throws IOException |
| *********************************************************************/ |
| public static void handle_print(AMutableString line, State state, Parameters parameters, |
| ClassAdObjectPool objectPool) throws IOException { |
| ExprTree tree; |
| tree = get_expr(line, state, parameters, objectPool); |
| if (tree != null) { |
| print_expr(tree, state, parameters, objectPool); |
| } |
| } |
| |
| /********************************************************************* |
| * Function: handle_same |
| * Purpose: |
| * |
| * @throws IOException |
| *********************************************************************/ |
| public static void handle_same(AMutableString line, State state, Parameters parameters, |
| ClassAdObjectPool objectPool) throws IOException { |
| ExprTreeHolder tree = new ExprTreeHolder(objectPool); |
| ExprTreeHolder tree2 = new ExprTreeHolder(objectPool); |
| Value value1 = new Value(objectPool); |
| Value value2 = new Value(objectPool); |
| try { |
| get_two_exprs(line, tree, tree2, state, parameters, objectPool); |
| 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, objectPool); |
| System.out.print(" "); |
| print_expr(tree2, state, parameters, objectPool); |
| } |
| if (!evaluate_expr(tree, value1, parameters, objectPool)) { |
| print_error_message("Couldn't evaluate first expression.\n", state); |
| } else if (!evaluate_expr(tree2, value2, parameters, objectPool)) { |
| 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: |
| * @param objectPool |
| * |
| * @throws IOException |
| *********************************************************************/ |
| public static void handle_sameq(AMutableString line, State state, Parameters parameters, |
| ClassAdObjectPool objectPool) throws IOException { |
| ExprTreeHolder tree = new ExprTreeHolder(objectPool); |
| ExprTreeHolder tree2 = new ExprTreeHolder(objectPool); |
| |
| get_two_exprs(line, tree, tree2, state, parameters, objectPool); |
| 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, |
| ClassAdObjectPool objectPool) throws IOException { |
| ExprTreeHolder tree = new ExprTreeHolder(objectPool); |
| ExprTreeHolder tree2 = new ExprTreeHolder(objectPool); |
| Value value1 = new Value(objectPool); |
| Value value2 = new Value(objectPool); |
| |
| get_two_exprs(line, tree, tree2, state, parameters, objectPool); |
| if (tree.getInnerTree() != null || tree2.getInnerTree() != null) { |
| if (!evaluate_expr(tree, value1, parameters, objectPool)) { |
| print_error_message("Couldn't evaluate first expression.\n", state); |
| } else if (!evaluate_expr(tree2, value2, parameters, objectPool)) { |
| 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: |
| * @param objectPool |
| * |
| * @throws IOException |
| *********************************************************************/ |
| public static void handle_diffq(AMutableString line, State state, Parameters parameters, |
| ClassAdObjectPool objectPool) throws IOException { |
| ExprTreeHolder tree = new ExprTreeHolder(objectPool); |
| ExprTreeHolder tree2 = new ExprTreeHolder(objectPool); |
| |
| get_two_exprs(line, tree, tree2, state, parameters, objectPool); |
| 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: |
| * @param objectPool |
| *********************************************************************/ |
| public static void handle_set(AMutableString line, State state, Parameters parameters, |
| ClassAdObjectPool objectPool) { |
| 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: |
| * @param objectPool |
| *********************************************************************/ |
| public static void handle_show(AMutableString line, State state, Parameters parameters, |
| ClassAdObjectPool objectPool) { |
| 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_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, |
| ClassAdObjectPool objectPool) throws IOException { |
| int offset; |
| ExprTree tree; |
| ClassAdParser parser = new ClassAdParser(objectPool); |
| 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, ClassAdObjectPool objectPool) throws IOException { |
| int offset; |
| ClassAdParser parser = new ClassAdParser(objectPool); |
| 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, objectPool); |
| } |
| |
| 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, objectPool); |
| System.out.print("# Tree1: "); |
| print_expr(tree1, state, parameters, objectPool); |
| System.out.println(); |
| } |
| } |
| } |
| |
| return; |
| } |
| |
| /********************************************************************* |
| * Function: print_expr |
| * Purpose: |
| * |
| * @throws HyracksDataException |
| *********************************************************************/ |
| public static void print_expr(ExprTree tree, State state, Parameters parameters, ClassAdObjectPool objectPool) |
| throws HyracksDataException { |
| AMutableCharArrayString output = new AMutableCharArrayString(); |
| |
| if (state.format == PrintFormat.print_Compact) { |
| ClassAdUnParser unparser = new ClassAdUnParser(objectPool); |
| unparser.unparse(output, tree); |
| } else if (state.format == PrintFormat.print_Pretty) { |
| PrettyPrint unparser = new PrettyPrint(objectPool); |
| 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, ClassAdObjectPool objectPool) |
| throws HyracksDataException { |
| ClassAd classad = new ClassAd(objectPool); |
| 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; |
| } |
| |
| } |