New run_keyword programs.

  - New programs to run the caller's keyword string.  This is useful for
    programs which need to call keywords from the command line.

Change-Id: Ie856910d1ff491e5eb2c764fdf494d875ecf474b
Signed-off-by: Michael Walsh <micwalsh@us.ibm.com>
diff --git a/extended/run_keyword.py b/extended/run_keyword.py
new file mode 100755
index 0000000..3f1a10b
--- /dev/null
+++ b/extended/run_keyword.py
@@ -0,0 +1,99 @@
+#!/usr/bin/env python
+
+r"""
+This module is the python counterpart to run_keyword.robot.
+"""
+
+import gen_print as gp
+import gen_robot_print as grp
+import gen_robot_valid as grv
+
+from robot.libraries.BuiltIn import BuiltIn
+
+
+###############################################################################
+def main_py():
+
+    r"""
+    Do main program processing.
+    """
+
+    setup()
+
+    keyword_string = BuiltIn().get_variable_value("${keyword_string}")
+    lib_file_path = BuiltIn().get_variable_value("${lib_file_path}")
+
+    cmd_buf = keyword_string.split("  ")
+
+    if lib_file_path != "":
+        # We don't want global variable getting changed when an import is done
+        # so we'll save it and restore it.
+        quiet = int(BuiltIn().get_variable_value("${quiet}"))
+        if lib_file_path.endswith(".py"):
+            grp.rdprint_issuing("import_library(\"" + lib_file_path + "\")")
+            BuiltIn().import_library(lib_file_path)
+        else:
+            grp.rdprint_issuing("import_resource(\"" + lib_file_path + "\")")
+            BuiltIn().import_resource(lib_file_path)
+        BuiltIn().set_global_variable("${quiet}", quiet)
+
+    error_message = grp.sprint_error_report("Keyword \"" + cmd_buf[0] +
+                                            "\" does not exist.\n")
+    BuiltIn().keyword_should_exist(cmd_buf[0], msg=error_message)
+
+    grp.rqprint_issuing_keyword(cmd_buf)
+    status, output = BuiltIn().run_keyword_and_ignore_error(*cmd_buf)
+    if status != "PASS":
+        error_message = grp.sprint_error_report("\"" + cmd_buf[0] +
+                                                "\" failed with the" +
+                                                " following error:\n" + output)
+        if not quiet:
+            grp.rprint(error_message, 'STDERR')
+        BuiltIn().fail(error_message)
+
+    if output is not None:
+        grp.rprint(output)
+
+###############################################################################
+
+
+###############################################################################
+def setup():
+
+    r"""
+    Do general program setup tasks.
+    """
+
+    grp.rqprintn()
+
+    validate_parms()
+
+    grp.rqprint_pgm_header()
+
+###############################################################################
+
+
+###############################################################################
+def validate_parms():
+
+    r"""
+    Validate all program parameters.
+    """
+
+    grv.rvalid_value("keyword_string")
+
+    return True
+
+###############################################################################
+
+
+###############################################################################
+def program_teardown():
+
+    r"""
+    Clean up after this program.
+    """
+
+    grp.rqprint_pgm_footer()
+
+###############################################################################