1e7e9171eSGeorge Keishing#!/usr/bin/env python3
218176322SMichael Walsh
318176322SMichael Walshr"""
4410b1787SMichael WalshThis module provides validation functions like valid_value(), valid_integer(), etc. for robot programs.
518176322SMichael Walsh"""
618176322SMichael Walsh
784230c20SMichael Walshimport re
820f38712SPatrick Williams
920f38712SPatrick Williamsimport func_args as fa
10c108e429SMichael Walshimport gen_print as gp
1118176322SMichael Walshimport gen_valid as gv
1218176322SMichael Walshfrom robot.libraries.BuiltIn import BuiltIn
1318176322SMichael Walsh
1418176322SMichael Walsh
1584230c20SMichael Walshdef valid_var_name(var_name):
1618176322SMichael Walsh    r"""
1784230c20SMichael Walsh    Validate the robot variable name and return its value.
183e26e109SMichael Walsh
19410b1787SMichael Walsh    If the variable is undefined, this function will print an error message and call BuiltIn().fail().
2018176322SMichael Walsh
2184230c20SMichael Walsh    Description of arguments():
22410b1787SMichael Walsh    var_name                        The name of the robot variable (e.g. "var1").  Do not include "${}" (e.g.
23410b1787SMichael Walsh                                    "${var1}".  Just provide the simple name of the variable.
2418176322SMichael Walsh    """
2518176322SMichael Walsh
2618176322SMichael Walsh    # Note: get_variable_value() seems to have no trouble with local variables.
2718176322SMichael Walsh    var_value = BuiltIn().get_variable_value("${" + var_name + "}")
2818176322SMichael Walsh    if var_value is None:
2984230c20SMichael Walsh        var_value = "<undefined>"
3020f38712SPatrick Williams        error_message = gv.valid_value(
3120f38712SPatrick Williams            var_value, invalid_values=[var_value], var_name=var_name
3220f38712SPatrick Williams        )
3318176322SMichael Walsh        BuiltIn().fail(error_message)
3418176322SMichael Walsh
3584230c20SMichael Walsh    return var_value
3618176322SMichael Walsh
3784230c20SMichael Walsh
3884230c20SMichael Walshdef valid_init(var_name, *args, **kwargs):
3918176322SMichael Walsh    r"""
40410b1787SMichael Walsh    Do initialization for variable validation and return var_name, args and kwargs.
413e26e109SMichael Walsh
42410b1787SMichael Walsh    This function is to be called by all of the various validation functions in this module.
4318176322SMichael Walsh
4484230c20SMichael Walsh    This function is designed solely for use by other functions in this file.
4518176322SMichael Walsh
4684230c20SMichael Walsh    Description of argument(s):
4784230c20SMichael Walsh    var_name                        The name of the variable to be validated.
48410b1787SMichael Walsh    args                            The positional arguments to be passed to a validation function.
49410b1787SMichael Walsh    kwargs                          The keyword arguments to be passed to a validation function.
5018176322SMichael Walsh    """
5118176322SMichael Walsh
5284230c20SMichael Walsh    var_value = valid_var_name(var_name)
53410b1787SMichael Walsh    # Convert python string object definitions to objects (useful for robot callers).
5484230c20SMichael Walsh    args = fa.args_to_objects(args)
5584230c20SMichael Walsh    kwargs = fa.args_to_objects(kwargs)
5684230c20SMichael Walsh    return var_value, args, kwargs
572c687e98SMichael Walsh
582c687e98SMichael Walsh
5984230c20SMichael Walshdef process_error_message(error_message):
602c687e98SMichael Walsh    r"""
6184230c20SMichael Walsh    Process an error message.
622c687e98SMichael Walsh
6384230c20SMichael Walsh    If error_message is non-blank, fail.  Otherwise, do nothing.
642c687e98SMichael Walsh
6584230c20SMichael Walsh    This function is designed solely for use by other functions in this file.
662c687e98SMichael Walsh
6784230c20SMichael Walsh    Description of argument(s):
6884230c20SMichael Walsh    error_message                   The error message to be processed.
692c687e98SMichael Walsh    """
702c687e98SMichael Walsh
7184230c20SMichael Walsh    if error_message:
72c108e429SMichael Walsh        error_message = gp.sprint_error_report(error_message)
732c687e98SMichael Walsh        BuiltIn().fail(error_message)
7484230c20SMichael Walsh
7584230c20SMichael Walsh
76*e16f158fSGeorge Keishing# The docstring header will be prepended to each validation function's existing docstring.
7720f38712SPatrick Williamsdocstring_header = r"""
7884230c20SMichael Walsh    Fail if the variable named by var_name is invalid.
7984230c20SMichael Walsh    """
8084230c20SMichael Walsh
8184230c20SMichael Walsh
8284230c20SMichael Walshdef customize_doc_string(doc_string):
8384230c20SMichael Walsh    r"""
8484230c20SMichael Walsh    Customize a gen_valid function docstring and return the result.
8584230c20SMichael Walsh
8684230c20SMichael Walsh    This function is designed solely for use by other functions in this file.
8784230c20SMichael Walsh
88410b1787SMichael Walsh    The caller should pass a docstring from a gen_valid.py validation function.  This docstring will be
89410b1787SMichael Walsh    changed to make a suitable docstring for this module's corresponding validation function.
9084230c20SMichael Walsh
9184230c20SMichael Walsh    For example:
9284230c20SMichael Walsh
93410b1787SMichael Walsh    Let's suppose that gen_valid.py has a function called "valid_value()".  This module could make the
94410b1787SMichael Walsh    following call to essentially copy gen_valid's "valid_value()" function, modify it and then assign it to
95410b1787SMichael Walsh    the local version of the valid_value() function.
9684230c20SMichael Walsh
9784230c20SMichael Walsh    valid.__doc__ = customize_doc_string(gv.valid.__doc__)
9884230c20SMichael Walsh
9984230c20SMichael Walsh    Description of argument(s):
10084230c20SMichael Walsh    doc_string                      The docstring to be customized.
10184230c20SMichael Walsh    """
10284230c20SMichael Walsh
10384230c20SMichael Walsh    doc_string = docstring_header + doc_string
10484230c20SMichael Walsh    doc_string = doc_string.split("\n")
10584230c20SMichael Walsh
10684230c20SMichael Walsh    start_ix = 0
10784230c20SMichael Walsh    # Find the "var_value" line.
10820f38712SPatrick Williams    start_ix = next(
10920f38712SPatrick Williams        (
11020f38712SPatrick Williams            index
11120f38712SPatrick Williams            for index, value in enumerate(doc_string[start_ix:], start_ix)
11220f38712SPatrick Williams            if re.match("[ ]+var_value  ", value)
11320f38712SPatrick Williams        ),
11420f38712SPatrick Williams        None,
11520f38712SPatrick Williams    )
11684230c20SMichael Walsh    # Replace the "var_value" line with our "var_name" line.
11720f38712SPatrick Williams    doc_string[start_ix] = (
11820f38712SPatrick Williams        "    var_name                        "
11984230c20SMichael Walsh        + "The name of the variable to be validated."
12020f38712SPatrick Williams    )
12184230c20SMichael Walsh
12284230c20SMichael Walsh    return "\n".join(doc_string)
12384230c20SMichael Walsh
12484230c20SMichael Walsh
125410b1787SMichael Walsh# All of the following functions are robot wrappers for the equivalent functions defined in gen_valid.py.
126410b1787SMichael Walsh# Note that the only difference between any two of these locally defined functions is the function name and
127410b1787SMichael Walsh# the gv.<function name> which they call.  Also, note that the docstring for each is created by modifying the
128410b1787SMichael Walsh# docstring from the supporting gen_valid.py function.
12984230c20SMichael Walsh
130e635ddc0SGeorge Keishing
13120f38712SPatrick Williamsdef valid_type(var_name, *args, **kwargs):
13284230c20SMichael Walsh    var_value, args, kwargs = valid_init(var_name, *args, **kwargs)
13320f38712SPatrick Williams    error_message = gv.valid_type(
13420f38712SPatrick Williams        var_value, *args, var_name=var_name, **kwargs
13520f38712SPatrick Williams    )
13684230c20SMichael Walsh    process_error_message(error_message)
13784230c20SMichael Walsh
13884230c20SMichael Walsh
13984230c20SMichael Walshdef valid_value(var_name, *args, **kwargs):
14084230c20SMichael Walsh    var_value, args, kwargs = valid_init(var_name, *args, **kwargs)
14120f38712SPatrick Williams    error_message = gv.valid_value(
14220f38712SPatrick Williams        var_value, *args, var_name=var_name, **kwargs
14320f38712SPatrick Williams    )
14484230c20SMichael Walsh    process_error_message(error_message)
14584230c20SMichael Walsh
14684230c20SMichael Walsh
14784230c20SMichael Walshdef valid_range(var_name, *args, **kwargs):
14884230c20SMichael Walsh    var_value, args, kwargs = valid_init(var_name, *args, **kwargs)
14920f38712SPatrick Williams    error_message = gv.valid_range(
15020f38712SPatrick Williams        var_value, *args, var_name=var_name, **kwargs
15120f38712SPatrick Williams    )
15284230c20SMichael Walsh    process_error_message(error_message)
15384230c20SMichael Walsh
15484230c20SMichael Walsh
15584230c20SMichael Walshdef valid_integer(var_name, *args, **kwargs):
15684230c20SMichael Walsh    var_value, args, kwargs = valid_init(var_name, *args, **kwargs)
15720f38712SPatrick Williams    error_message = gv.valid_integer(
15820f38712SPatrick Williams        var_value, *args, var_name=var_name, **kwargs
15920f38712SPatrick Williams    )
16084230c20SMichael Walsh    process_error_message(error_message)
16184230c20SMichael Walsh
16284230c20SMichael Walsh
1638333a18dSMichael Walshdef valid_float(var_name, *args, **kwargs):
1648333a18dSMichael Walsh    var_value, args, kwargs = valid_init(var_name, *args, **kwargs)
16520f38712SPatrick Williams    error_message = gv.valid_float(
16620f38712SPatrick Williams        var_value, *args, var_name=var_name, **kwargs
16720f38712SPatrick Williams    )
1688333a18dSMichael Walsh    process_error_message(error_message)
1698333a18dSMichael Walsh
1708333a18dSMichael Walsh
1718333a18dSMichael Walshdef valid_date_time(var_name, *args, **kwargs):
1728333a18dSMichael Walsh    var_value, args, kwargs = valid_init(var_name, *args, **kwargs)
17320f38712SPatrick Williams    error_message = gv.valid_date_time(
17420f38712SPatrick Williams        var_value, *args, var_name=var_name, **kwargs
17520f38712SPatrick Williams    )
1768333a18dSMichael Walsh    process_error_message(error_message)
1778333a18dSMichael Walsh
1788333a18dSMichael Walsh
17984230c20SMichael Walshdef valid_dir_path(var_name, *args, **kwargs):
18084230c20SMichael Walsh    var_value, args, kwargs = valid_init(var_name, *args, **kwargs)
18120f38712SPatrick Williams    error_message = gv.valid_dir_path(
18220f38712SPatrick Williams        var_value, *args, var_name=var_name, **kwargs
18320f38712SPatrick Williams    )
18484230c20SMichael Walsh    process_error_message(error_message)
18584230c20SMichael Walsh
18684230c20SMichael Walsh
18784230c20SMichael Walshdef valid_file_path(var_name, *args, **kwargs):
18884230c20SMichael Walsh    var_value, args, kwargs = valid_init(var_name, *args, **kwargs)
18920f38712SPatrick Williams    error_message = gv.valid_file_path(
19020f38712SPatrick Williams        var_value, *args, var_name=var_name, **kwargs
19120f38712SPatrick Williams    )
19284230c20SMichael Walsh    process_error_message(error_message)
19384230c20SMichael Walsh
19484230c20SMichael Walsh
19584230c20SMichael Walshdef valid_path(var_name, *args, **kwargs):
19684230c20SMichael Walsh    var_value, args, kwargs = valid_init(var_name, *args, **kwargs)
19720f38712SPatrick Williams    error_message = gv.valid_path(
19820f38712SPatrick Williams        var_value, *args, var_name=var_name, **kwargs
19920f38712SPatrick Williams    )
20084230c20SMichael Walsh    process_error_message(error_message)
20184230c20SMichael Walsh
20284230c20SMichael Walsh
20384230c20SMichael Walshdef valid_list(var_name, *args, **kwargs):
20484230c20SMichael Walsh    var_value, args, kwargs = valid_init(var_name, *args, **kwargs)
20520f38712SPatrick Williams    error_message = gv.valid_list(
20620f38712SPatrick Williams        var_value, *args, var_name=var_name, **kwargs
20720f38712SPatrick Williams    )
20884230c20SMichael Walsh    process_error_message(error_message)
20984230c20SMichael Walsh
21084230c20SMichael Walsh
21184230c20SMichael Walshdef valid_dict(var_name, *args, **kwargs):
21284230c20SMichael Walsh    var_value, args, kwargs = valid_init(var_name, *args, **kwargs)
21320f38712SPatrick Williams    error_message = gv.valid_dict(
21420f38712SPatrick Williams        var_value, *args, var_name=var_name, **kwargs
21520f38712SPatrick Williams    )
21684230c20SMichael Walsh    process_error_message(error_message)
21784230c20SMichael Walsh
21884230c20SMichael Walsh
219be3a8150SMichael Walshdef valid_program(var_name, *args, **kwargs):
220be3a8150SMichael Walsh    var_value, args, kwargs = valid_init(var_name, *args, **kwargs)
22120f38712SPatrick Williams    error_message = gv.valid_program(
22220f38712SPatrick Williams        var_value, *args, var_name=var_name, **kwargs
22320f38712SPatrick Williams    )
224be3a8150SMichael Walsh    process_error_message(error_message)
225be3a8150SMichael Walsh
226be3a8150SMichael Walsh
227b9d8dfd2SMichael Walshdef valid_length(var_name, *args, **kwargs):
228b9d8dfd2SMichael Walsh    var_value, args, kwargs = valid_init(var_name, *args, **kwargs)
22920f38712SPatrick Williams    error_message = gv.valid_length(
23020f38712SPatrick Williams        var_value, *args, var_name=var_name, **kwargs
23120f38712SPatrick Williams    )
232b9d8dfd2SMichael Walsh    process_error_message(error_message)
233b9d8dfd2SMichael Walsh
234b9d8dfd2SMichael Walsh
235410b1787SMichael Walsh# Modify the validation function docstrings by calling customize_doc_string for each function in the
236410b1787SMichael Walsh# func_names list.
23784230c20SMichael Walshfunc_names = [
23820f38712SPatrick Williams    "valid_type",
23920f38712SPatrick Williams    "valid_value",
24020f38712SPatrick Williams    "valid_range",
24120f38712SPatrick Williams    "valid_integer",
24220f38712SPatrick Williams    "valid_dir_path",
24320f38712SPatrick Williams    "valid_file_path",
24420f38712SPatrick Williams    "valid_path",
24520f38712SPatrick Williams    "valid_list",
24620f38712SPatrick Williams    "valid_dict",
24720f38712SPatrick Williams    "valid_program",
24820f38712SPatrick Williams    "valid_length",
24920f38712SPatrick Williams    "valid_float",
25020f38712SPatrick Williams    "valid_date_time",
25184230c20SMichael Walsh]
25284230c20SMichael Walsh
25384230c20SMichael Walshfor func_name in func_names:
25420f38712SPatrick Williams    cmd_buf = (
25520f38712SPatrick Williams        func_name
25620f38712SPatrick Williams        + ".__doc__ = customize_doc_string(gv.raw_doc_strings['"
25720f38712SPatrick Williams        + func_name
25820f38712SPatrick Williams        + "'])"
25920f38712SPatrick Williams    )
26084230c20SMichael Walsh    exec(cmd_buf)
261