17423c01aSMichael Walsh#!/usr/bin/env python
27423c01aSMichael Walsh
37423c01aSMichael Walshr"""
47423c01aSMichael WalshThis module provides valuable argument processing functions like
57423c01aSMichael Walshgen_get_options and sprint_args.
67423c01aSMichael Walsh"""
77423c01aSMichael Walsh
878bdfdd6SMichael Walshimport os
97423c01aSMichael Walshimport gen_print as gp
107423c01aSMichael Walsh
11e23b5ad3SMichael Walshexit_on_error = False
12e23b5ad3SMichael Walsh
13e23b5ad3SMichael Walsh
14e23b5ad3SMichael Walshdef set_exit_on_error(value):
15e23b5ad3SMichael Walsh    r"""
16e23b5ad3SMichael Walsh    Set the exit_on_error value to either True or False.
17e23b5ad3SMichael Walsh
18e23b5ad3SMichael Walsh    If exit_on_error is set, validation functions like valid_value will exit
19e23b5ad3SMichael Walsh    the program on error instead of returning False.
20e23b5ad3SMichael Walsh
21e23b5ad3SMichael Walsh    Description of argument(s):
22e23b5ad3SMichael Walsh    value                           Value to set global exit_on_error to.
23e23b5ad3SMichael Walsh    """
24e23b5ad3SMichael Walsh
25e23b5ad3SMichael Walsh    global exit_on_error
26e23b5ad3SMichael Walsh    exit_on_error = value
27e23b5ad3SMichael Walsh
28e23b5ad3SMichael Walsh
29e23b5ad3SMichael Walshdef get_var_name(var_name):
30e23b5ad3SMichael Walsh    r"""
31e23b5ad3SMichael Walsh    If var_name has a value, simply return it.  Otherwise, get the variable
32e23b5ad3SMichael Walsh    name of the first arguement used to call the validation function (e.g.
33e23b5ad3SMichael Walsh    valid_value, valid_integer, etc.) and return it.
34e23b5ad3SMichael Walsh
35e23b5ad3SMichael Walsh    This function is designed solely for use by other functions in this file.
36e23b5ad3SMichael Walsh
37e23b5ad3SMichael Walsh    Example:
38e23b5ad3SMichael Walsh
39e23b5ad3SMichael Walsh    A programmer codes this:
40e23b5ad3SMichael Walsh
41e23b5ad3SMichael Walsh    valid_value(last_name)
42e23b5ad3SMichael Walsh
43e23b5ad3SMichael Walsh    Which results in the following call stack:
44e23b5ad3SMichael Walsh
45e23b5ad3SMichael Walsh    valid_value(last_name)
46e23b5ad3SMichael Walsh      -> svalid_value(var_value...)
47e23b5ad3SMichael Walsh        -> get_var_name(var_name)
48e23b5ad3SMichael Walsh
49e23b5ad3SMichael Walsh    In this example, this function will return "last_name".
50e23b5ad3SMichael Walsh
51e23b5ad3SMichael Walsh    Example:
52e23b5ad3SMichael Walsh
53e23b5ad3SMichael Walsh    err_msg = svalid_value(last_name, var_name="some_other_name")
54e23b5ad3SMichael Walsh
55e23b5ad3SMichael Walsh    Which results in the following call stack:
56e23b5ad3SMichael Walsh
57e23b5ad3SMichael Walsh    svalid_value(var_value, var_name="some_other_name")
58e23b5ad3SMichael Walsh      -> get_var_name(var_name)
59e23b5ad3SMichael Walsh
60e23b5ad3SMichael Walsh    In this example, this function will return "some_other_name".
61e23b5ad3SMichael Walsh
62e23b5ad3SMichael Walsh    Description of argument(s):
63e23b5ad3SMichael Walsh    var_name                        The name of the variable.
64e23b5ad3SMichael Walsh    """
65e23b5ad3SMichael Walsh
66e23b5ad3SMichael Walsh    if var_name != "":
67e23b5ad3SMichael Walsh        return var_name
68e23b5ad3SMichael Walsh    # Calculate stack_frame_ix.  The validation functions in this file come
69e23b5ad3SMichael Walsh    # in pairs.  There is an "s" version of each validation function (e.g.
70e23b5ad3SMichael Walsh    # svalid_value) whose job is to return an error message string.  Then
71e23b5ad3SMichael Walsh    # there is a wrapper function (e.g. valid_value) that will call the "s"
72e23b5ad3SMichael Walsh    # version and print the result if there is an error.  See examples 1 and 2
73e23b5ad3SMichael Walsh    # above for illustration.  This function must be cognizant of both
74e23b5ad3SMichael Walsh    # scenarios to accurately determine the name of the variable being
75e23b5ad3SMichael Walsh    # validated.  Where the "s" function is being called directly, the
76e23b5ad3SMichael Walsh    # stack_frame_ix should be set to 3.  Where the wrapper function is being
77e23b5ad3SMichael Walsh    # called, the stack_frame_ix should be incremented to 4.
78e23b5ad3SMichael Walsh    stack_frame_ix = 3
79e23b5ad3SMichael Walsh    parent_func_name = gp.sprint_func_name(2)
80e23b5ad3SMichael Walsh    grandparent_func_name = gp.sprint_func_name(3)
81e23b5ad3SMichael Walsh    if parent_func_name == "s" + grandparent_func_name:
82e23b5ad3SMichael Walsh        stack_frame_ix += 1
83e23b5ad3SMichael Walsh    var_name = gp.get_arg_name(0, 1, stack_frame_ix)
84e23b5ad3SMichael Walsh    return var_name
85e23b5ad3SMichael Walsh
86e23b5ad3SMichael Walsh
87e23b5ad3SMichael Walshdef process_error_message(error_message):
88e23b5ad3SMichael Walsh    r"""
89e23b5ad3SMichael Walsh    Process the error_message as follows:
90e23b5ad3SMichael Walsh    - If the error_message is blank, return True.
91e23b5ad3SMichael Walsh    - If the error_message contains a value:
92e23b5ad3SMichael Walsh        - Print the error_message as part of a full error report.
93e23b5ad3SMichael Walsh        - If global exit_on_error is set, then exit the program with a return
94e23b5ad3SMichael Walsh          code of 1.
95e23b5ad3SMichael Walsh        - If exit_on_error is not set, return False.
96e23b5ad3SMichael Walsh
97e23b5ad3SMichael Walsh    This function is designed solely for use by wrapper functions in this file
98e23b5ad3SMichael Walsh    (e.g. "valid_value").
99e23b5ad3SMichael Walsh
100e23b5ad3SMichael Walsh    Description of argument(s):
101e23b5ad3SMichael Walsh    error_message                   An error message.
102e23b5ad3SMichael Walsh    """
103e23b5ad3SMichael Walsh
104e23b5ad3SMichael Walsh    if error_message == "":
105e23b5ad3SMichael Walsh        return True
106e23b5ad3SMichael Walsh
107e23b5ad3SMichael Walsh    gp.print_error_report(error_message)
108e23b5ad3SMichael Walsh    if exit_on_error:
109e23b5ad3SMichael Walsh        exit(0)
110e23b5ad3SMichael Walsh    return False
111e23b5ad3SMichael Walsh
1127423c01aSMichael Walsh
113bec416ddSMichael Walshdef svalid_value(var_value,
114bec416ddSMichael Walsh                 invalid_values=[],
115bec416ddSMichael Walsh                 valid_values=[],
116bec416ddSMichael Walsh                 var_name=""):
1177423c01aSMichael Walsh    r"""
118bec416ddSMichael Walsh    Return an empty string if var_value is a valid value.  Otherwise, return
119bec416ddSMichael Walsh    an error string.
1207423c01aSMichael Walsh
1217423c01aSMichael Walsh    Description of arguments:
1227423c01aSMichael Walsh    var_value                       The value being validated.
1237423c01aSMichael Walsh    invalid_values                  A list of invalid values.  If var_value is
1247423c01aSMichael Walsh                                    equal to any of these, it is invalid.
1257423c01aSMichael Walsh                                    Note that if you specify anything for
1267423c01aSMichael Walsh                                    invalid_values (below), the valid_values
127e23b5ad3SMichael Walsh                                    list is not even processed.  If you
128e23b5ad3SMichael Walsh                                    specify nothing for both invalid_values
129e23b5ad3SMichael Walsh                                    and valid_values, invalid_values will be
130e23b5ad3SMichael Walsh                                    set to a default value of [""].
131*ca193993SMichael Walsh    valid_values                    A list of valid values.  var_value must be
132*ca193993SMichael Walsh                                    equal to one of these values to be
1337423c01aSMichael Walsh                                    considered valid.
134bec416ddSMichael Walsh    var_name                        The name of the variable whose value is
135bec416ddSMichael Walsh                                    passed in var_value.  This parameter is
136bec416ddSMichael Walsh                                    normally unnecessary as this function can
137bec416ddSMichael Walsh                                    figure out the var_name.  This is provided
138bec416ddSMichael Walsh                                    for Robot callers.  In this scenario, we
139bec416ddSMichael Walsh                                    are unable to get the variable name
140bec416ddSMichael Walsh                                    ourselves.
1417423c01aSMichael Walsh    """
1427423c01aSMichael Walsh
143bec416ddSMichael Walsh    success_message = ""
144bec416ddSMichael Walsh    error_message = ""
145bec416ddSMichael Walsh
146e23b5ad3SMichael Walsh    # Validate this function's arguments.
1477423c01aSMichael Walsh    len_valid_values = len(valid_values)
1487423c01aSMichael Walsh    len_invalid_values = len(invalid_values)
1497423c01aSMichael Walsh    if len_valid_values > 0 and len_invalid_values > 0:
150bec416ddSMichael Walsh        error_message += "Programmer error - You must provide either an" +\
151bec416ddSMichael Walsh                         " invalid_values list or a valid_values" +\
152bec416ddSMichael Walsh                         " list but NOT both.\n" +\
153bec416ddSMichael Walsh                         gp.sprint_var(invalid_values) +\
154bec416ddSMichael Walsh                         gp.sprint_var(valid_values)
155bec416ddSMichael Walsh        return error_message
1567423c01aSMichael Walsh
157bec416ddSMichael Walsh    show_blanks = 1
1587423c01aSMichael Walsh    if len_valid_values > 0:
1597423c01aSMichael Walsh        # Processing the valid_values list.
1607423c01aSMichael Walsh        if var_value in valid_values:
161bec416ddSMichael Walsh            return success_message
162bec416ddSMichael Walsh        error_message += "The following variable has an invalid" +\
163bec416ddSMichael Walsh                         " value:\n" +\
164e23b5ad3SMichael Walsh                         gp.sprint_varx(get_var_name(var_name), var_value,
165e23b5ad3SMichael Walsh                                        show_blanks) +\
166bec416ddSMichael Walsh                         "\nIt must be one of the following values:\n" +\
167bec416ddSMichael Walsh                         gp.sprint_varx("valid_values", valid_values,
168bec416ddSMichael Walsh                                        show_blanks)
169bec416ddSMichael Walsh        return error_message
1707423c01aSMichael Walsh
1717423c01aSMichael Walsh    if len_invalid_values == 0:
172bec416ddSMichael Walsh        # Assign default value.
173bec416ddSMichael Walsh        invalid_values = [""]
1747423c01aSMichael Walsh
1757423c01aSMichael Walsh    # Assertion: We have an invalid_values list.  Processing it now.
1767423c01aSMichael Walsh    if var_value not in invalid_values:
177bec416ddSMichael Walsh        return success_message
178bec416ddSMichael Walsh
179bec416ddSMichael Walsh    error_message += "The following variable has an invalid value:\n" +\
180e23b5ad3SMichael Walsh                     gp.sprint_varx(get_var_name(var_name), var_value,
181e23b5ad3SMichael Walsh                                    show_blanks) +\
182bec416ddSMichael Walsh                     "\nIt must NOT be one of the following values:\n" +\
183bec416ddSMichael Walsh                     gp.sprint_varx("invalid_values", invalid_values,
184bec416ddSMichael Walsh                                    show_blanks)
185bec416ddSMichael Walsh    return error_message
186bec416ddSMichael Walsh
187bec416ddSMichael Walsh
188bec416ddSMichael Walshdef valid_value(var_value,
189bec416ddSMichael Walsh                invalid_values=[],
190bec416ddSMichael Walsh                valid_values=[],
191bec416ddSMichael Walsh                var_name=""):
192bec416ddSMichael Walsh    r"""
193e23b5ad3SMichael Walsh    Return True if var_value is valid.  Otherwise, print an error message and
194e23b5ad3SMichael Walsh    either return False or exit(1) depending on the value of exit_on_error.
195bec416ddSMichael Walsh
196bec416ddSMichael Walsh    Description of arguments:
19778bdfdd6SMichael Walsh    (See description of arguments for svalid_value (above)).
198bec416ddSMichael Walsh    """
199bec416ddSMichael Walsh
200bec416ddSMichael Walsh    error_message = svalid_value(var_value, invalid_values, valid_values,
201bec416ddSMichael Walsh                                 var_name)
202e23b5ad3SMichael Walsh    return process_error_message(error_message)
2037423c01aSMichael Walsh
204bec416ddSMichael Walsh
205bec416ddSMichael Walshdef svalid_integer(var_value,
206bec416ddSMichael Walsh                   var_name=""):
207bec416ddSMichael Walsh    r"""
208bec416ddSMichael Walsh    Return an empty string if var_value is a valid integer.  Otherwise, return
209bec416ddSMichael Walsh    an error string.
210bec416ddSMichael Walsh
211bec416ddSMichael Walsh    Description of arguments:
212bec416ddSMichael Walsh    var_value                       The value being validated.
213bec416ddSMichael Walsh    var_name                        The name of the variable whose value is
214bec416ddSMichael Walsh                                    passed in var_value.  This parameter is
215bec416ddSMichael Walsh                                    normally unnecessary as this function can
216bec416ddSMichael Walsh                                    figure out the var_name.  This is provided
217bec416ddSMichael Walsh                                    for Robot callers.  In this scenario, we
218bec416ddSMichael Walsh                                    are unable to get the variable name
219bec416ddSMichael Walsh                                    ourselves.
220bec416ddSMichael Walsh    """
221bec416ddSMichael Walsh
222bec416ddSMichael Walsh    success_message = ""
223bec416ddSMichael Walsh    error_message = ""
224bec416ddSMichael Walsh    try:
225004ad3c9SJoy Onyerikwu        if isinstance(int(str(var_value), 0), int):
226bec416ddSMichael Walsh            return success_message
227bec416ddSMichael Walsh    except ValueError:
228bec416ddSMichael Walsh        pass
229bec416ddSMichael Walsh
230bec416ddSMichael Walsh    # If we get to this point, the validation has failed.
231bec416ddSMichael Walsh    show_blanks = 1
232e23b5ad3SMichael Walsh    error_message +=\
233e23b5ad3SMichael Walsh        "Invalid integer value:\n" +\
234e23b5ad3SMichael Walsh        gp.sprint_varx(get_var_name(var_name), var_value, show_blanks)
235bec416ddSMichael Walsh
236bec416ddSMichael Walsh    return error_message
2377423c01aSMichael Walsh
2387423c01aSMichael Walsh
239bec416ddSMichael Walshdef valid_integer(var_value,
240bec416ddSMichael Walsh                  var_name=""):
2417423c01aSMichael Walsh    r"""
242e23b5ad3SMichael Walsh    Return True if var_value is a valid integer.  Otherwise, print an error
243e23b5ad3SMichael Walsh    message and either return False or exit(1) depending on the value of
244e23b5ad3SMichael Walsh    exit_on_error.
2457423c01aSMichael Walsh
2467423c01aSMichael Walsh    Description of arguments:
247e23b5ad3SMichael Walsh    (See description of arguments for svalid_integer (above)).
2487423c01aSMichael Walsh    """
2497423c01aSMichael Walsh
250bec416ddSMichael Walsh    error_message = svalid_integer(var_value, var_name)
251e23b5ad3SMichael Walsh    return process_error_message(error_message)
2527423c01aSMichael Walsh
25378bdfdd6SMichael Walsh
25478bdfdd6SMichael Walshdef svalid_dir_path(var_value,
25578bdfdd6SMichael Walsh                    var_name=""):
25678bdfdd6SMichael Walsh    r"""
25778bdfdd6SMichael Walsh    Return an empty string if var_value is a valid directory path.  Otherwise,
25878bdfdd6SMichael Walsh    return an error string.
25978bdfdd6SMichael Walsh
26078bdfdd6SMichael Walsh    Description of arguments:
26178bdfdd6SMichael Walsh    var_value                       The value being validated.
26278bdfdd6SMichael Walsh    var_name                        The name of the variable whose value is
26378bdfdd6SMichael Walsh                                    passed in var_value.  This parameter is
26478bdfdd6SMichael Walsh                                    normally unnecessary as this function can
26578bdfdd6SMichael Walsh                                    figure out the var_name.  This is provided
26678bdfdd6SMichael Walsh                                    for Robot callers.  In this scenario, we
26778bdfdd6SMichael Walsh                                    are unable to get the variable name
26878bdfdd6SMichael Walsh                                    ourselves.
26978bdfdd6SMichael Walsh    """
27078bdfdd6SMichael Walsh
27178bdfdd6SMichael Walsh    error_message = ""
27278bdfdd6SMichael Walsh    if not os.path.isdir(str(var_value)):
27378bdfdd6SMichael Walsh        error_message += "The following directory does not exist:\n" +\
274e23b5ad3SMichael Walsh            gp.sprint_varx(get_var_name(var_name), var_value)
27578bdfdd6SMichael Walsh
27678bdfdd6SMichael Walsh    return error_message
27778bdfdd6SMichael Walsh
27878bdfdd6SMichael Walsh
27978bdfdd6SMichael Walshdef valid_dir_path(var_value,
28078bdfdd6SMichael Walsh                   var_name=""):
28178bdfdd6SMichael Walsh    r"""
282e23b5ad3SMichael Walsh    Return True if var_value is a valid directory path.  Otherwise, print an
283e23b5ad3SMichael Walsh    error message and either return False or exit(1) depending on the value of
284e23b5ad3SMichael Walsh    exit_on_error.
285e23b5ad3SMichael Walsh
286e23b5ad3SMichael Walsh    Valid means that the directory path exists.
28778bdfdd6SMichael Walsh
28878bdfdd6SMichael Walsh    Description of arguments:
289e23b5ad3SMichael Walsh    (See description of arguments for svalid_dir_path (above)).
29078bdfdd6SMichael Walsh    """
29178bdfdd6SMichael Walsh
29278bdfdd6SMichael Walsh    error_message = svalid_dir_path(var_value, var_name)
293e23b5ad3SMichael Walsh    return process_error_message(error_message)
29478bdfdd6SMichael Walsh
29578bdfdd6SMichael Walsh
29678bdfdd6SMichael Walshdef svalid_file_path(var_value,
29778bdfdd6SMichael Walsh                     var_name=""):
29878bdfdd6SMichael Walsh    r"""
29978bdfdd6SMichael Walsh    Return an empty string if var_value is a valid file path.  Otherwise,
30078bdfdd6SMichael Walsh    return an error string.
30178bdfdd6SMichael Walsh
30278bdfdd6SMichael Walsh    Description of arguments:
30378bdfdd6SMichael Walsh    var_value                       The value being validated.
30478bdfdd6SMichael Walsh    var_name                        The name of the variable whose value is
30578bdfdd6SMichael Walsh                                    passed in var_value.  This parameter is
30678bdfdd6SMichael Walsh                                    normally unnecessary as this function can
30778bdfdd6SMichael Walsh                                    figure out the var_name.  This is provided
30878bdfdd6SMichael Walsh                                    for Robot callers.  In this scenario, we
30978bdfdd6SMichael Walsh                                    are unable to get the variable name
31078bdfdd6SMichael Walsh                                    ourselves.
31178bdfdd6SMichael Walsh    """
31278bdfdd6SMichael Walsh
31378bdfdd6SMichael Walsh    error_message = ""
31478bdfdd6SMichael Walsh    if not os.path.isfile(str(var_value)):
31578bdfdd6SMichael Walsh        error_message += "Invalid file (does not exist):\n" +\
316e23b5ad3SMichael Walsh            gp.sprint_varx(get_var_name(var_name), var_value)
31778bdfdd6SMichael Walsh
31878bdfdd6SMichael Walsh    return error_message
31978bdfdd6SMichael Walsh
32078bdfdd6SMichael Walsh
32178bdfdd6SMichael Walshdef valid_file_path(var_value,
32278bdfdd6SMichael Walsh                    var_name=""):
32378bdfdd6SMichael Walsh    r"""
324e23b5ad3SMichael Walsh    Return True if var_value is a valid file path.  Otherwise, print an error
325e23b5ad3SMichael Walsh    message and either return False or exit(1) depending on the value of
326e23b5ad3SMichael Walsh    exit_on_error.
327e23b5ad3SMichael Walsh
328e23b5ad3SMichael Walsh    Valid means that the file exists.
32978bdfdd6SMichael Walsh
33078bdfdd6SMichael Walsh    Description of arguments:
331e23b5ad3SMichael Walsh    (See description of arguments for svalid_file_path (above)).
33278bdfdd6SMichael Walsh    """
33378bdfdd6SMichael Walsh
33478bdfdd6SMichael Walsh    error_message = svalid_file_path(var_value, var_name)
335e23b5ad3SMichael Walsh    return process_error_message(error_message)
33678bdfdd6SMichael Walsh
33778bdfdd6SMichael Walsh
338e23b5ad3SMichael Walshdef svalid_path(var_value,
339e23b5ad3SMichael Walsh                var_name=""):
340e23b5ad3SMichael Walsh    r"""
341e23b5ad3SMichael Walsh    Return an empty string if var_value is either a valid file path or
342e23b5ad3SMichael Walsh    directory path.  Otherwise, return an error string.
343e23b5ad3SMichael Walsh
344e23b5ad3SMichael Walsh    Description of arguments:
345e23b5ad3SMichael Walsh    var_value                       The value being validated.
346e23b5ad3SMichael Walsh    var_name                        The name of the variable whose value is
347e23b5ad3SMichael Walsh                                    passed in var_value.  This parameter is
348e23b5ad3SMichael Walsh                                    normally unnecessary as this function can
349e23b5ad3SMichael Walsh                                    figure out the var_name.  This is provided
350e23b5ad3SMichael Walsh                                    for Robot callers.  In this scenario, we
351e23b5ad3SMichael Walsh                                    are unable to get the variable name
352e23b5ad3SMichael Walsh                                    ourselves.
353e23b5ad3SMichael Walsh    """
354e23b5ad3SMichael Walsh
355e23b5ad3SMichael Walsh    error_message = ""
356e23b5ad3SMichael Walsh    if not (os.path.isfile(str(var_value)) or os.path.isdir(str(var_value))):
357e23b5ad3SMichael Walsh        error_message = "Invalid path (file or directory does not exist):\n" +\
358e23b5ad3SMichael Walsh            gp.sprint_varx(get_var_name(var_name), var_value)
359e23b5ad3SMichael Walsh
360e23b5ad3SMichael Walsh    return error_message
361e23b5ad3SMichael Walsh
362e23b5ad3SMichael Walsh
363e23b5ad3SMichael Walshdef valid_path(var_value,
364e23b5ad3SMichael Walsh               var_name=""):
365e23b5ad3SMichael Walsh    r"""
366e23b5ad3SMichael Walsh    Return True if var_value is a valid file path.  Otherwise, print an error
367e23b5ad3SMichael Walsh    message and either return False or exit(1) depending on the value of
368e23b5ad3SMichael Walsh    exit_on_error.
369e23b5ad3SMichael Walsh
370e23b5ad3SMichael Walsh    Valid means that the file exists.
371e23b5ad3SMichael Walsh
372e23b5ad3SMichael Walsh    Description of arguments:
373e23b5ad3SMichael Walsh    (See description of arguments for svalid_path (above)).
374e23b5ad3SMichael Walsh    """
375e23b5ad3SMichael Walsh
376e23b5ad3SMichael Walsh    error_message = svalid_path(var_value, var_name)
377e23b5ad3SMichael Walsh    return process_error_message(error_message)
3782c687e98SMichael Walsh
3792c687e98SMichael Walsh
3802c687e98SMichael Walshdef svalid_range(var_value,
381e23b5ad3SMichael Walsh                 valid_range=[],
3822c687e98SMichael Walsh                 var_name=""):
3832c687e98SMichael Walsh    r"""
3842c687e98SMichael Walsh    Return an empty string if var_value is within the range.  Otherwise,
3852c687e98SMichael Walsh    return an error string.
3862c687e98SMichael Walsh
3872c687e98SMichael Walsh    Description of arguments:
3882c687e98SMichael Walsh    var_value                       The value being validated.  This value
3892c687e98SMichael Walsh                                    must be an integer.
390e23b5ad3SMichael Walsh    valid_range                     A list comprised of one or two elements
3912c687e98SMichael Walsh                                    which are the lower and upper ends of a
3922c687e98SMichael Walsh                                    range.  These values must be integers
3932c687e98SMichael Walsh                                    except where noted.  Valid specifications
3942c687e98SMichael Walsh                                    may be of the following forms: [lower,
3952c687e98SMichael Walsh                                    upper], [lower] or [None, upper].
3962c687e98SMichael Walsh    var_name                        The name of the variable whose value is
3972c687e98SMichael Walsh                                    passed in var_value.  This parameter is
3982c687e98SMichael Walsh                                    normally unnecessary as this function can
3992c687e98SMichael Walsh                                    figure out the var_name.  This is provided
4002c687e98SMichael Walsh                                    for Robot callers.  In this scenario, we
4012c687e98SMichael Walsh                                    are unable to get the variable name
4022c687e98SMichael Walsh                                    ourselves.
4032c687e98SMichael Walsh    """
4042c687e98SMichael Walsh
4052c687e98SMichael Walsh    error_message = ""
4062c687e98SMichael Walsh
4072c687e98SMichael Walsh    # Validate this function's parms:
4082c687e98SMichael Walsh    # First, ensure that the value is an integer.
4092c687e98SMichael Walsh    error_message = svalid_integer(var_value, var_name)
4102c687e98SMichael Walsh    if not error_message == "":
4112c687e98SMichael Walsh        return error_message
4122c687e98SMichael Walsh    var_value = int(var_value)
4132c687e98SMichael Walsh
414e23b5ad3SMichael Walsh    len_valid_range = len(valid_range)
415e23b5ad3SMichael Walsh    if len_valid_range == 0 or len_valid_range > 2:
416e23b5ad3SMichael Walsh        error_message += "Programmer error - For the valid_range parameter," +\
417e23b5ad3SMichael Walsh                         " you must provide a list consisting of one or two" +\
4182c687e98SMichael Walsh                         " elements.\n" +\
419e23b5ad3SMichael Walsh                         gp.sprint_var(valid_range)
4202c687e98SMichael Walsh        return error_message
4212c687e98SMichael Walsh
422e23b5ad3SMichael Walsh    if len_valid_range == 1 or valid_range[0] is not None:
423e23b5ad3SMichael Walsh        # Make sure lower valid_range value is an integer.
424e23b5ad3SMichael Walsh        error_message = svalid_integer(valid_range[0], "valid_range[0]")
4252c687e98SMichael Walsh        if not error_message == "":
4262c687e98SMichael Walsh            error_message = "Programmer error:\n" + error_message
4272c687e98SMichael Walsh            return error_message
428e23b5ad3SMichael Walsh    if valid_range[0] is not None:
429e23b5ad3SMichael Walsh        valid_range[0] = int(valid_range[0])
430e23b5ad3SMichael Walsh    if len_valid_range == 2:
431e23b5ad3SMichael Walsh        # Make sure upper valid_range value is an integer.
432e23b5ad3SMichael Walsh        error_message = svalid_integer(valid_range[1], "valid_range[1]")
4332c687e98SMichael Walsh        if not error_message == "":
4342c687e98SMichael Walsh            error_message = "Programmer error:\n" + error_message
4352c687e98SMichael Walsh            return error_message
436e23b5ad3SMichael Walsh        valid_range[1] = int(valid_range[1])
437e23b5ad3SMichael Walsh        if valid_range[0] is not None and valid_range[0] > valid_range[1]:
438e23b5ad3SMichael Walsh            error_message = "Programmer error - In the following range, the" +\
439e23b5ad3SMichael Walsh                            " lower limit is greater than the upper" +\
440e23b5ad3SMichael Walsh                            " limit:\n" + gp.sprint_varx("valid_range",
441e23b5ad3SMichael Walsh                                                         valid_range)
4422c687e98SMichael Walsh            return error_message
4432c687e98SMichael Walsh
444e23b5ad3SMichael Walsh    if len_valid_range == 1:
445e23b5ad3SMichael Walsh        if var_value < valid_range[0]:
4462c687e98SMichael Walsh            error_message += "The following variable is not within the" +\
4472c687e98SMichael Walsh                             " expected range:\n" +\
448e23b5ad3SMichael Walsh                             gp.sprint_varx(get_var_name(var_name),
449e23b5ad3SMichael Walsh                                            var_value) +\
4502c687e98SMichael Walsh                             gp.sprint_varx("valid_range",
451e23b5ad3SMichael Walsh                                            str(valid_range[0]) + "..")
452e23b5ad3SMichael Walsh            return error_message
4532c687e98SMichael Walsh        return error_message
4542c687e98SMichael Walsh
455e23b5ad3SMichael Walsh    if valid_range[0] is None:
456e23b5ad3SMichael Walsh        if var_value > valid_range[1]:
457e23b5ad3SMichael Walsh            error_message += "The following variable is not within the" +\
458e23b5ad3SMichael Walsh                             " expected range:\n" +\
459e23b5ad3SMichael Walsh                             gp.sprint_varx(get_var_name(var_name),
460e23b5ad3SMichael Walsh                                            var_value) +\
461e23b5ad3SMichael Walsh                             gp.sprint_varx("valid_range",
462e23b5ad3SMichael Walsh                                            ".." + str(valid_range[1]))
463e23b5ad3SMichael Walsh            return error_message
464e23b5ad3SMichael Walsh
465e23b5ad3SMichael Walsh    if var_value < valid_range[0] or var_value > valid_range[1]:
4662c687e98SMichael Walsh        error_message += "The following variable is not within the expected" +\
4672c687e98SMichael Walsh                         " range:\n" +\
468e23b5ad3SMichael Walsh                         gp.sprint_varx(get_var_name(var_name), var_value) +\
4692c687e98SMichael Walsh                         gp.sprint_varx("valid_range",
470004ad3c9SJoy Onyerikwu                                        str(valid_range[0]) + ".."
471004ad3c9SJoy Onyerikwu                                        + str(valid_range[1]))
4722c687e98SMichael Walsh        return error_message
4732c687e98SMichael Walsh
4742c687e98SMichael Walsh    return error_message
4752c687e98SMichael Walsh
4762c687e98SMichael Walsh
4772c687e98SMichael Walshdef valid_range(var_value,
478e23b5ad3SMichael Walsh                valid_range=[],
4792c687e98SMichael Walsh                var_name=""):
4802c687e98SMichael Walsh    r"""
481e23b5ad3SMichael Walsh    Return True if var_value is within range.  Otherwise, print an error
482e23b5ad3SMichael Walsh    message and either return False or exit(1) depending on the value of
483e23b5ad3SMichael Walsh    exit_on_error.
4842c687e98SMichael Walsh
4852c687e98SMichael Walsh    Description of arguments:
4862c687e98SMichael Walsh    (See description of arguments for svalid_range (above)).
4872c687e98SMichael Walsh    """
4882c687e98SMichael Walsh
489e23b5ad3SMichael Walsh    error_message = svalid_range(var_value, valid_range, var_name)
490e23b5ad3SMichael Walsh    return process_error_message(error_message)
491*ca193993SMichael Walsh
492*ca193993SMichael Walsh
493*ca193993SMichael Walshdef svalid_list(var_value,
494*ca193993SMichael Walsh                valid_values=[],
495*ca193993SMichael Walsh                var_name=""):
496*ca193993SMichael Walsh    r"""
497*ca193993SMichael Walsh    Return an empty string if var_value is a valid list.  Otherwise, return an
498*ca193993SMichael Walsh    error string.
499*ca193993SMichael Walsh
500*ca193993SMichael Walsh    Description of arguments:
501*ca193993SMichael Walsh    var_value                       The value (i.e. list) being validated.
502*ca193993SMichael Walsh    valid_values                    A list of valid values.  Each element in
503*ca193993SMichael Walsh                                    the var_value list must be equal to one of
504*ca193993SMichael Walsh                                    these values to be considered valid.
505*ca193993SMichael Walsh    var_name                        The name of the variable whose value is
506*ca193993SMichael Walsh                                    passed in var_value.  This parameter is
507*ca193993SMichael Walsh                                    normally unnecessary as this function can
508*ca193993SMichael Walsh                                    figure out the var_name.  This is provided
509*ca193993SMichael Walsh                                    for Robot callers.  In this scenario, we
510*ca193993SMichael Walsh                                    are unable to get the variable name
511*ca193993SMichael Walsh                                    ourselves.
512*ca193993SMichael Walsh    """
513*ca193993SMichael Walsh
514*ca193993SMichael Walsh    error_message = ""
515*ca193993SMichael Walsh    if len(var_value) == 0:
516*ca193993SMichael Walsh        show_blanks = 1
517*ca193993SMichael Walsh        error_message += "The \"" + get_var_name(var_name)
518*ca193993SMichael Walsh        error_message += "\" list is empty and is therefore invalid:\n"
519*ca193993SMichael Walsh        return error_message
520*ca193993SMichael Walsh
521*ca193993SMichael Walsh    found_error = 0
522*ca193993SMichael Walsh    display_var_value = list(var_value)
523*ca193993SMichael Walsh    for ix in range(0, len(var_value)):
524*ca193993SMichael Walsh        if var_value[ix] not in valid_values:
525*ca193993SMichael Walsh            found_error = 1
526*ca193993SMichael Walsh            display_var_value[ix] = var_value[ix] + "*"
527*ca193993SMichael Walsh
528*ca193993SMichael Walsh    if found_error:
529*ca193993SMichael Walsh        show_blanks = 1
530*ca193993SMichael Walsh        error_message += "The list entries marked with \"*\" are not valid:\n"
531*ca193993SMichael Walsh        error_message += gp.sprint_varx(get_var_name(var_name),
532*ca193993SMichael Walsh                                        display_var_value, show_blanks)
533*ca193993SMichael Walsh        error_message += gp.sprint_var(valid_values)
534*ca193993SMichael Walsh        return error_message
535*ca193993SMichael Walsh
536*ca193993SMichael Walsh    return ""
537*ca193993SMichael Walsh
538*ca193993SMichael Walsh
539*ca193993SMichael Walshdef valid_list(var_value,
540*ca193993SMichael Walsh               valid_values=[],
541*ca193993SMichael Walsh               var_name=""):
542*ca193993SMichael Walsh    r"""
543*ca193993SMichael Walsh    Return True if var_value is a valid list.  Otherwise, print an error
544*ca193993SMichael Walsh    message and either return False or exit(1) depending on the value of
545*ca193993SMichael Walsh    exit_on_error.
546*ca193993SMichael Walsh
547*ca193993SMichael Walsh    Description of arguments:
548*ca193993SMichael Walsh    (See description of arguments for svalid_list (above)).
549*ca193993SMichael Walsh    """
550*ca193993SMichael Walsh
551*ca193993SMichael Walsh    error_message = svalid_list(var_value, valid_values, var_name)
552*ca193993SMichael Walsh    return process_error_message(error_message)
553