| #!/usr/bin/env python | 
 |  | 
 | r""" | 
 | This module provides valuable argument processing functions like | 
 | gen_get_options and sprint_args. | 
 | """ | 
 |  | 
 | import os | 
 | import gen_print as gp | 
 |  | 
 | exit_on_error = False | 
 |  | 
 |  | 
 | def set_exit_on_error(value): | 
 |     r""" | 
 |     Set the exit_on_error value to either True or False. | 
 |  | 
 |     If exit_on_error is set, validation functions like valid_value will exit | 
 |     the program on error instead of returning False. | 
 |  | 
 |     Description of argument(s): | 
 |     value                           Value to set global exit_on_error to. | 
 |     """ | 
 |  | 
 |     global exit_on_error | 
 |     exit_on_error = value | 
 |  | 
 |  | 
 | def get_var_name(var_name): | 
 |     r""" | 
 |     If var_name has a value, simply return it.  Otherwise, get the variable | 
 |     name of the first argument used to call the validation function (e.g. | 
 |     valid_value, valid_integer, etc.) and return it. | 
 |  | 
 |     This function is designed solely for use by other functions in this file. | 
 |  | 
 |     Example: | 
 |  | 
 |     A programmer codes this: | 
 |  | 
 |     valid_value(last_name) | 
 |  | 
 |     Which results in the following call stack: | 
 |  | 
 |     valid_value(last_name) | 
 |       -> svalid_value(var_value...) | 
 |         -> get_var_name(var_name) | 
 |  | 
 |     In this example, this function will return "last_name". | 
 |  | 
 |     Example: | 
 |  | 
 |     err_msg = svalid_value(last_name, var_name="some_other_name") | 
 |  | 
 |     Which results in the following call stack: | 
 |  | 
 |     svalid_value(var_value, var_name="some_other_name") | 
 |       -> get_var_name(var_name) | 
 |  | 
 |     In this example, this function will return "some_other_name". | 
 |  | 
 |     Description of argument(s): | 
 |     var_name                        The name of the variable. | 
 |     """ | 
 |  | 
 |     if var_name != "": | 
 |         return var_name | 
 |     # Calculate stack_frame_ix.  The validation functions in this file come | 
 |     # in pairs.  There is an "s" version of each validation function (e.g. | 
 |     # svalid_value) whose job is to return an error message string.  Then | 
 |     # there is a wrapper function (e.g. valid_value) that will call the "s" | 
 |     # version and print the result if there is an error.  See examples 1 and 2 | 
 |     # above for illustration.  This function must be cognizant of both | 
 |     # scenarios to accurately determine the name of the variable being | 
 |     # validated.  Where the "s" function is being called directly, the | 
 |     # stack_frame_ix should be set to 3.  Where the wrapper function is being | 
 |     # called, the stack_frame_ix should be incremented to 4. | 
 |     stack_frame_ix = 3 | 
 |     parent_func_name = gp.sprint_func_name(2) | 
 |     grandparent_func_name = gp.sprint_func_name(3) | 
 |     if parent_func_name == "s" + grandparent_func_name: | 
 |         stack_frame_ix += 1 | 
 |     var_name = gp.get_arg_name(0, 1, stack_frame_ix) | 
 |     return var_name | 
 |  | 
 |  | 
 | def process_error_message(error_message): | 
 |     r""" | 
 |     Process the error_message as follows: | 
 |     - If the error_message is blank, return True. | 
 |     - If the error_message contains a value: | 
 |         - Print the error_message as part of a full error report. | 
 |         - If global exit_on_error is set, then exit the program with a return | 
 |           code of 1. | 
 |         - If exit_on_error is not set, return False. | 
 |  | 
 |     This function is designed solely for use by wrapper functions in this file | 
 |     (e.g. "valid_value"). | 
 |  | 
 |     Description of argument(s): | 
 |     error_message                   An error message. | 
 |     """ | 
 |  | 
 |     if error_message == "": | 
 |         return True | 
 |  | 
 |     gp.print_error_report(error_message) | 
 |     if exit_on_error: | 
 |         exit(1) | 
 |     return False | 
 |  | 
 |  | 
 | def svalid_value(var_value, | 
 |                  invalid_values=[], | 
 |                  valid_values=[], | 
 |                  var_name=""): | 
 |     r""" | 
 |     Return an empty string if var_value is a valid value.  Otherwise, return | 
 |     an error string. | 
 |  | 
 |     Description of arguments: | 
 |     var_value                       The value being validated. | 
 |     invalid_values                  A list of invalid values.  If var_value is | 
 |                                     equal to any of these, it is invalid. | 
 |                                     Note that if you specify anything for | 
 |                                     invalid_values (below), the valid_values | 
 |                                     list is not even processed.  If you | 
 |                                     specify nothing for both invalid_values | 
 |                                     and valid_values, invalid_values will be | 
 |                                     set to a default value of [""]. | 
 |     valid_values                    A list of valid values.  var_value must be | 
 |                                     equal to one of these values to be | 
 |                                     considered valid. | 
 |     var_name                        The name of the variable whose value is | 
 |                                     passed in var_value.  This parameter is | 
 |                                     normally unnecessary as this function can | 
 |                                     figure out the var_name.  This is provided | 
 |                                     for Robot callers.  In this scenario, we | 
 |                                     are unable to get the variable name | 
 |                                     ourselves. | 
 |     """ | 
 |  | 
 |     success_message = "" | 
 |     error_message = "" | 
 |  | 
 |     # Validate this function's arguments. | 
 |     len_valid_values = len(valid_values) | 
 |     len_invalid_values = len(invalid_values) | 
 |     if len_valid_values > 0 and len_invalid_values > 0: | 
 |         error_message += "Programmer error - You must provide either an" +\ | 
 |                          " invalid_values list or a valid_values" +\ | 
 |                          " list but NOT both.\n" +\ | 
 |                          gp.sprint_var(invalid_values) +\ | 
 |                          gp.sprint_var(valid_values) | 
 |         return error_message | 
 |  | 
 |     show_blanks = 1 | 
 |     if len_valid_values > 0: | 
 |         # Processing the valid_values list. | 
 |         if var_value in valid_values: | 
 |             return success_message | 
 |         error_message += "The following variable has an invalid" +\ | 
 |                          " value:\n" +\ | 
 |                          gp.sprint_varx(get_var_name(var_name), var_value, | 
 |                                         show_blanks) +\ | 
 |                          "\nIt must be one of the following values:\n" +\ | 
 |                          gp.sprint_varx("valid_values", valid_values, | 
 |                                         show_blanks) | 
 |         return error_message | 
 |  | 
 |     if len_invalid_values == 0: | 
 |         # Assign default value. | 
 |         invalid_values = [""] | 
 |  | 
 |     # Assertion: We have an invalid_values list.  Processing it now. | 
 |     if var_value not in invalid_values: | 
 |         return success_message | 
 |  | 
 |     error_message += "The following variable has an invalid value:\n" +\ | 
 |                      gp.sprint_varx(get_var_name(var_name), var_value, | 
 |                                     show_blanks) +\ | 
 |                      "\nIt must NOT be one of the following values:\n" +\ | 
 |                      gp.sprint_varx("invalid_values", invalid_values, | 
 |                                     show_blanks) | 
 |     return error_message | 
 |  | 
 |  | 
 | def valid_value(var_value, | 
 |                 invalid_values=[], | 
 |                 valid_values=[], | 
 |                 var_name=""): | 
 |     r""" | 
 |     Return True if var_value is valid.  Otherwise, print an error message and | 
 |     either return False or exit(1) depending on the value of exit_on_error. | 
 |  | 
 |     Description of arguments: | 
 |     (See description of arguments for svalid_value (above)). | 
 |     """ | 
 |  | 
 |     error_message = svalid_value(var_value, invalid_values, valid_values, | 
 |                                  var_name) | 
 |     return process_error_message(error_message) | 
 |  | 
 |  | 
 | def svalid_integer(var_value, | 
 |                    var_name=""): | 
 |     r""" | 
 |     Return an empty string if var_value is a valid integer.  Otherwise, return | 
 |     an error string. | 
 |  | 
 |     Description of arguments: | 
 |     var_value                       The value being validated. | 
 |     var_name                        The name of the variable whose value is | 
 |                                     passed in var_value.  This parameter is | 
 |                                     normally unnecessary as this function can | 
 |                                     figure out the var_name.  This is provided | 
 |                                     for Robot callers.  In this scenario, we | 
 |                                     are unable to get the variable name | 
 |                                     ourselves. | 
 |     """ | 
 |  | 
 |     success_message = "" | 
 |     error_message = "" | 
 |     try: | 
 |         if isinstance(int(str(var_value), 0), int): | 
 |             return success_message | 
 |     except ValueError: | 
 |         pass | 
 |  | 
 |     # If we get to this point, the validation has failed. | 
 |     show_blanks = 1 | 
 |     error_message +=\ | 
 |         "Invalid integer value:\n" +\ | 
 |         gp.sprint_varx(get_var_name(var_name), var_value, show_blanks) | 
 |  | 
 |     return error_message | 
 |  | 
 |  | 
 | def valid_integer(var_value, | 
 |                   var_name=""): | 
 |     r""" | 
 |     Return True if var_value is a valid integer.  Otherwise, print an error | 
 |     message and either return False or exit(1) depending on the value of | 
 |     exit_on_error. | 
 |  | 
 |     Description of arguments: | 
 |     (See description of arguments for svalid_integer (above)). | 
 |     """ | 
 |  | 
 |     error_message = svalid_integer(var_value, var_name) | 
 |     return process_error_message(error_message) | 
 |  | 
 |  | 
 | def svalid_dir_path(var_value, | 
 |                     var_name=""): | 
 |     r""" | 
 |     Return an empty string if var_value is a valid directory path.  Otherwise, | 
 |     return an error string. | 
 |  | 
 |     Description of arguments: | 
 |     var_value                       The value being validated. | 
 |     var_name                        The name of the variable whose value is | 
 |                                     passed in var_value.  This parameter is | 
 |                                     normally unnecessary as this function can | 
 |                                     figure out the var_name.  This is provided | 
 |                                     for Robot callers.  In this scenario, we | 
 |                                     are unable to get the variable name | 
 |                                     ourselves. | 
 |     """ | 
 |  | 
 |     error_message = "" | 
 |     if not os.path.isdir(str(var_value)): | 
 |         error_message += "The following directory does not exist:\n" +\ | 
 |             gp.sprint_varx(get_var_name(var_name), var_value) | 
 |  | 
 |     return error_message | 
 |  | 
 |  | 
 | def valid_dir_path(var_value, | 
 |                    var_name=""): | 
 |     r""" | 
 |     Return True if var_value is a valid directory path.  Otherwise, print an | 
 |     error message and either return False or exit(1) depending on the value of | 
 |     exit_on_error. | 
 |  | 
 |     Valid means that the directory path exists. | 
 |  | 
 |     Description of arguments: | 
 |     (See description of arguments for svalid_dir_path (above)). | 
 |     """ | 
 |  | 
 |     error_message = svalid_dir_path(var_value, var_name) | 
 |     return process_error_message(error_message) | 
 |  | 
 |  | 
 | def svalid_file_path(var_value, | 
 |                      var_name=""): | 
 |     r""" | 
 |     Return an empty string if var_value is a valid file path.  Otherwise, | 
 |     return an error string. | 
 |  | 
 |     Description of arguments: | 
 |     var_value                       The value being validated. | 
 |     var_name                        The name of the variable whose value is | 
 |                                     passed in var_value.  This parameter is | 
 |                                     normally unnecessary as this function can | 
 |                                     figure out the var_name.  This is provided | 
 |                                     for Robot callers.  In this scenario, we | 
 |                                     are unable to get the variable name | 
 |                                     ourselves. | 
 |     """ | 
 |  | 
 |     error_message = "" | 
 |     if not os.path.isfile(str(var_value)): | 
 |         error_message += "Invalid file (does not exist):\n" +\ | 
 |             gp.sprint_varx(get_var_name(var_name), var_value) | 
 |  | 
 |     return error_message | 
 |  | 
 |  | 
 | def valid_file_path(var_value, | 
 |                     var_name=""): | 
 |     r""" | 
 |     Return True if var_value is a valid file path.  Otherwise, print an error | 
 |     message and either return False or exit(1) depending on the value of | 
 |     exit_on_error. | 
 |  | 
 |     Valid means that the file exists. | 
 |  | 
 |     Description of arguments: | 
 |     (See description of arguments for svalid_file_path (above)). | 
 |     """ | 
 |  | 
 |     error_message = svalid_file_path(var_value, var_name) | 
 |     return process_error_message(error_message) | 
 |  | 
 |  | 
 | def svalid_path(var_value, | 
 |                 var_name=""): | 
 |     r""" | 
 |     Return an empty string if var_value is either a valid file path or | 
 |     directory path.  Otherwise, return an error string. | 
 |  | 
 |     Description of arguments: | 
 |     var_value                       The value being validated. | 
 |     var_name                        The name of the variable whose value is | 
 |                                     passed in var_value.  This parameter is | 
 |                                     normally unnecessary as this function can | 
 |                                     figure out the var_name.  This is provided | 
 |                                     for Robot callers.  In this scenario, we | 
 |                                     are unable to get the variable name | 
 |                                     ourselves. | 
 |     """ | 
 |  | 
 |     error_message = "" | 
 |     if not (os.path.isfile(str(var_value)) or os.path.isdir(str(var_value))): | 
 |         error_message = "Invalid path (file or directory does not exist):\n" +\ | 
 |             gp.sprint_varx(get_var_name(var_name), var_value) | 
 |  | 
 |     return error_message | 
 |  | 
 |  | 
 | def valid_path(var_value, | 
 |                var_name=""): | 
 |     r""" | 
 |     Return True if var_value is a valid file path.  Otherwise, print an error | 
 |     message and either return False or exit(1) depending on the value of | 
 |     exit_on_error. | 
 |  | 
 |     Valid means that the file exists. | 
 |  | 
 |     Description of arguments: | 
 |     (See description of arguments for svalid_path (above)). | 
 |     """ | 
 |  | 
 |     error_message = svalid_path(var_value, var_name) | 
 |     return process_error_message(error_message) | 
 |  | 
 |  | 
 | def svalid_range(var_value, | 
 |                  valid_range=[], | 
 |                  var_name=""): | 
 |     r""" | 
 |     Return an empty string if var_value is within the range.  Otherwise, | 
 |     return an error string. | 
 |  | 
 |     Description of arguments: | 
 |     var_value                       The value being validated.  This value | 
 |                                     must be an integer. | 
 |     valid_range                     A list comprised of one or two elements | 
 |                                     which are the lower and upper ends of a | 
 |                                     range.  These values must be integers | 
 |                                     except where noted.  Valid specifications | 
 |                                     may be of the following forms: [lower, | 
 |                                     upper], [lower] or [None, upper]. | 
 |     var_name                        The name of the variable whose value is | 
 |                                     passed in var_value.  This parameter is | 
 |                                     normally unnecessary as this function can | 
 |                                     figure out the var_name.  This is provided | 
 |                                     for Robot callers.  In this scenario, we | 
 |                                     are unable to get the variable name | 
 |                                     ourselves. | 
 |     """ | 
 |  | 
 |     error_message = "" | 
 |  | 
 |     # Validate this function's parms: | 
 |     # First, ensure that the value is an integer. | 
 |     error_message = svalid_integer(var_value, var_name) | 
 |     if not error_message == "": | 
 |         return error_message | 
 |     var_value = int(var_value) | 
 |  | 
 |     len_valid_range = len(valid_range) | 
 |     if len_valid_range == 0 or len_valid_range > 2: | 
 |         error_message += "Programmer error - For the valid_range parameter," +\ | 
 |                          " you must provide a list consisting of one or two" +\ | 
 |                          " elements.\n" +\ | 
 |                          gp.sprint_var(valid_range) | 
 |         return error_message | 
 |  | 
 |     if len_valid_range == 1 or valid_range[0] is not None: | 
 |         # Make sure lower valid_range value is an integer. | 
 |         error_message = svalid_integer(valid_range[0], "valid_range[0]") | 
 |         if not error_message == "": | 
 |             error_message = "Programmer error:\n" + error_message | 
 |             return error_message | 
 |     if valid_range[0] is not None: | 
 |         valid_range[0] = int(valid_range[0]) | 
 |     if len_valid_range == 2: | 
 |         # Make sure upper valid_range value is an integer. | 
 |         error_message = svalid_integer(valid_range[1], "valid_range[1]") | 
 |         if not error_message == "": | 
 |             error_message = "Programmer error:\n" + error_message | 
 |             return error_message | 
 |         valid_range[1] = int(valid_range[1]) | 
 |         if valid_range[0] is not None and valid_range[0] > valid_range[1]: | 
 |             error_message = "Programmer error - In the following range, the" +\ | 
 |                             " lower limit is greater than the upper" +\ | 
 |                             " limit:\n" + gp.sprint_varx("valid_range", | 
 |                                                          valid_range) | 
 |             return error_message | 
 |  | 
 |     if len_valid_range == 1: | 
 |         if var_value < valid_range[0]: | 
 |             error_message += "The following variable is not within the" +\ | 
 |                              " expected range:\n" +\ | 
 |                              gp.sprint_varx(get_var_name(var_name), | 
 |                                             var_value) +\ | 
 |                              gp.sprint_varx("valid_range", | 
 |                                             str(valid_range[0]) + "..") | 
 |             return error_message | 
 |         return error_message | 
 |  | 
 |     if valid_range[0] is None: | 
 |         if var_value > valid_range[1]: | 
 |             error_message += "The following variable is not within the" +\ | 
 |                              " expected range:\n" +\ | 
 |                              gp.sprint_varx(get_var_name(var_name), | 
 |                                             var_value) +\ | 
 |                              gp.sprint_varx("valid_range", | 
 |                                             ".." + str(valid_range[1])) | 
 |             return error_message | 
 |  | 
 |     if var_value < valid_range[0] or var_value > valid_range[1]: | 
 |         error_message += "The following variable is not within the expected" +\ | 
 |                          " range:\n" +\ | 
 |                          gp.sprint_varx(get_var_name(var_name), var_value) +\ | 
 |                          gp.sprint_varx("valid_range", | 
 |                                         str(valid_range[0]) + ".." | 
 |                                         + str(valid_range[1])) | 
 |         return error_message | 
 |  | 
 |     return error_message | 
 |  | 
 |  | 
 | def valid_range(var_value, | 
 |                 valid_range=[], | 
 |                 var_name=""): | 
 |     r""" | 
 |     Return True if var_value is within range.  Otherwise, print an error | 
 |     message and either return False or exit(1) depending on the value of | 
 |     exit_on_error. | 
 |  | 
 |     Description of arguments: | 
 |     (See description of arguments for svalid_range (above)). | 
 |     """ | 
 |  | 
 |     error_message = svalid_range(var_value, valid_range, var_name) | 
 |     return process_error_message(error_message) | 
 |  | 
 |  | 
 | def svalid_list(var_value, | 
 |                 valid_values=[], | 
 |                 var_name=""): | 
 |     r""" | 
 |     Return an empty string if var_value is a valid list.  Otherwise, return an | 
 |     error string. | 
 |  | 
 |     Description of arguments: | 
 |     var_value                       The value (i.e. list) being validated. | 
 |     valid_values                    A list of valid values.  Each element in | 
 |                                     the var_value list must be equal to one of | 
 |                                     these values to be considered valid. | 
 |     var_name                        The name of the variable whose value is | 
 |                                     passed in var_value.  This parameter is | 
 |                                     normally unnecessary as this function can | 
 |                                     figure out the var_name.  This is provided | 
 |                                     for Robot callers.  In this scenario, we | 
 |                                     are unable to get the variable name | 
 |                                     ourselves. | 
 |     """ | 
 |  | 
 |     error_message = "" | 
 |     if len(var_value) == 0: | 
 |         show_blanks = 1 | 
 |         error_message += "The \"" + get_var_name(var_name) | 
 |         error_message += "\" list is empty and is therefore invalid:\n" | 
 |         return error_message | 
 |  | 
 |     found_error = 0 | 
 |     display_var_value = list(var_value) | 
 |     for ix in range(0, len(var_value)): | 
 |         if var_value[ix] not in valid_values: | 
 |             found_error = 1 | 
 |             display_var_value[ix] = var_value[ix] + "*" | 
 |  | 
 |     if found_error: | 
 |         show_blanks = 1 | 
 |         error_message += "The list entries marked with \"*\" are not valid:\n" | 
 |         error_message += gp.sprint_varx(get_var_name(var_name), | 
 |                                         display_var_value, show_blanks) | 
 |         error_message += gp.sprint_var(valid_values) | 
 |         return error_message | 
 |  | 
 |     return "" | 
 |  | 
 |  | 
 | def valid_list(var_value, | 
 |                valid_values=[], | 
 |                var_name=""): | 
 |     r""" | 
 |     Return True if var_value is a valid list.  Otherwise, print an error | 
 |     message and either return False or exit(1) depending on the value of | 
 |     exit_on_error. | 
 |  | 
 |     Description of arguments: | 
 |     (See description of arguments for svalid_list (above)). | 
 |     """ | 
 |  | 
 |     error_message = svalid_list(var_value, valid_values, var_name) | 
 |     return process_error_message(error_message) | 
 |  | 
 |  | 
 | def svalid_dict(var_value, | 
 |                 required_keys=[], | 
 |                 var_name=""): | 
 |     r""" | 
 |     Return an empty string if var_value is a valid dictionary.  Otherwise, | 
 |     return an error string. | 
 |  | 
 |     Description of arguments: | 
 |     var_value                       The value (i.e. dictionary) being | 
 |                                     validated. | 
 |     required_keys                   A list of keys which must be found in the | 
 |                                     dictionary for it to be considered valid. | 
 |     var_name                        The name of the variable whose value is | 
 |                                     passed in var_value.  This parameter is | 
 |                                     normally unnecessary as this function can | 
 |                                     figure out the var_name.  This is provided | 
 |                                     for Robot callers.  In this scenario, we | 
 |                                     are unable to get the variable name | 
 |                                     ourselves. | 
 |     """ | 
 |  | 
 |     error_message = "" | 
 |  | 
 |     keys_missing = list(set(required_keys) - set(var_value.keys())) | 
 |     if len(keys_missing) > 0: | 
 |         show_blanks = 1 | 
 |         var_name = get_var_name(var_name) | 
 |         error_message = "The following key fields are missing from " | 
 |         error_message += var_name + ":\n" | 
 |         error_message += gp.sprint_var(keys_missing) | 
 |         error_message += gp.sprint_varx(var_name, var_value, show_blanks) | 
 |         return error_message | 
 |  | 
 |     return "" | 
 |  | 
 |  | 
 | def valid_dict(var_value, | 
 |                required_keys=[], | 
 |                var_name=""): | 
 |     r""" | 
 |     Return True if var_value is a valid dictionary.  Otherwise, print an error | 
 |     message and either return False or exit(1) depending on the value of | 
 |     exit_on_error. | 
 |  | 
 |     Description of arguments: | 
 |     (See description of arguments for svalid_list (above)). | 
 |     """ | 
 |  | 
 |     error_message = svalid_dict(var_value, required_keys, var_name) | 
 |     return process_error_message(error_message) |