1#!/usr/bin/env python
2
3r"""
4This module provides valuable argument processing functions like
5gen_get_options and sprint_args.
6"""
7
8import sys
9import os
10
11import gen_print as gp
12
13
14def svalid_value(var_value,
15                 invalid_values=[],
16                 valid_values=[],
17                 var_name=""):
18    r"""
19    Return an empty string if var_value is a valid value.  Otherwise, return
20    an error string.
21
22    Description of arguments:
23    var_value                       The value being validated.
24    invalid_values                  A list of invalid values.  If var_value is
25                                    equal to any of these, it is invalid.
26                                    Note that if you specify anything for
27                                    invalid_values (below), the valid_values
28                                    list is not even processed.
29    valid_values                    A list of invalid values.  var_value must
30                                    be equal to one of these values to be
31                                    considered valid.
32    var_name                        The name of the variable whose value is
33                                    passed in var_value.  This parameter is
34                                    normally unnecessary as this function can
35                                    figure out the var_name.  This is provided
36                                    for Robot callers.  In this scenario, we
37                                    are unable to get the variable name
38                                    ourselves.
39    """
40
41    success_message = ""
42    error_message = ""
43    stack_frame_ix = 3
44
45    len_valid_values = len(valid_values)
46    len_invalid_values = len(invalid_values)
47    if len_valid_values > 0 and len_invalid_values > 0:
48        error_message += "Programmer error - You must provide either an" +\
49                         " invalid_values list or a valid_values" +\
50                         " list but NOT both.\n" +\
51                         gp.sprint_var(invalid_values) +\
52                         gp.sprint_var(valid_values)
53        return error_message
54
55    show_blanks = 1
56    if len_valid_values > 0:
57        # Processing the valid_values list.
58        if var_value in valid_values:
59            return success_message
60        if var_name == "":
61            var_name = gp.get_arg_name(0, 1, stack_frame_ix)
62        error_message += "The following variable has an invalid" +\
63                         " value:\n" +\
64                         gp.sprint_varx(var_name, var_value, show_blanks) +\
65                         "\nIt must be one of the following values:\n" +\
66                         gp.sprint_varx("valid_values", valid_values,
67                                        show_blanks)
68        return error_message
69
70    if len_invalid_values == 0:
71        # Assign default value.
72        invalid_values = [""]
73
74    # Assertion: We have an invalid_values list.  Processing it now.
75    if var_value not in invalid_values:
76        return success_message
77
78    if var_name == "":
79        var_name = gp.get_arg_name(0, 1, stack_frame_ix)
80    error_message += "The following variable has an invalid value:\n" +\
81                     gp.sprint_varx(var_name, var_value, show_blanks) +\
82                     "\nIt must NOT be one of the following values:\n" +\
83                     gp.sprint_varx("invalid_values", invalid_values,
84                                    show_blanks)
85    return error_message
86
87
88def valid_value(var_value,
89                invalid_values=[],
90                valid_values=[],
91                var_name=""):
92    r"""
93    Return True if var_value is a valid value.  Otherwise, return False and
94    print an error message to stderr.
95
96    Description of arguments:
97    (See description of arguments for svalid_value (above)).
98    """
99
100    error_message = svalid_value(var_value, invalid_values, valid_values,
101                                 var_name)
102
103    if not error_message == "":
104        gp.print_error_report(error_message)
105        return False
106    return True
107
108
109def svalid_integer(var_value,
110                   var_name=""):
111    r"""
112    Return an empty string if var_value is a valid integer.  Otherwise, return
113    an error string.
114
115    Description of arguments:
116    var_value                       The value being validated.
117    var_name                        The name of the variable whose value is
118                                    passed in var_value.  This parameter is
119                                    normally unnecessary as this function can
120                                    figure out the var_name.  This is provided
121                                    for Robot callers.  In this scenario, we
122                                    are unable to get the variable name
123                                    ourselves.
124    """
125
126    success_message = ""
127    error_message = ""
128    try:
129        if type(int(str(var_value), 0)) is int:
130            return success_message
131    except ValueError:
132        pass
133
134    # If we get to this point, the validation has failed.
135    if var_name is "":
136        stack_index = 3
137        var_name = gp.get_arg_name(0, 1, stack_index)
138
139    show_blanks = 1
140    error_message += "Invalid integer value:\n" +\
141                     gp.sprint_varx(var_name, var_value, show_blanks)
142
143    return error_message
144
145
146def valid_integer(var_value,
147                  var_name=""):
148    r"""
149    Return True if var_value is a valid integer.  Otherwise, return False and
150    print an error message to stderr.
151
152    Description of arguments:
153    (See description of arguments for svalid_value (above)).
154    """
155
156    error_message = svalid_integer(var_value, var_name)
157
158    if not error_message == "":
159        gp.print_error_report(error_message)
160        return False
161    return True
162
163
164def svalid_dir_path(var_value,
165                    var_name=""):
166    r"""
167    Return an empty string if var_value is a valid directory path.  Otherwise,
168    return an error string.
169
170    Description of arguments:
171    var_value                       The value being validated.
172    var_name                        The name of the variable whose value is
173                                    passed in var_value.  This parameter is
174                                    normally unnecessary as this function can
175                                    figure out the var_name.  This is provided
176                                    for Robot callers.  In this scenario, we
177                                    are unable to get the variable name
178                                    ourselves.
179    """
180
181    error_message = ""
182    if not os.path.isdir(str(var_value)):
183        if var_name is "":
184            stack_index = 3
185            var_name = gp.get_arg_name(0, 1, stack_index)
186        error_message += "The following directory does not exist:\n" +\
187                         gp.sprint_varx(var_name, var_value)
188
189    return error_message
190
191
192def valid_dir_path(var_value,
193                   var_name=""):
194    r"""
195    Return True if var_value is a valid integer.  Otherwise, return False and
196    print an error message to stderr.
197
198    Description of arguments:
199    (See description of arguments for svalid_value (above)).
200    """
201
202    error_message = svalid_dir_path(var_value, var_name)
203
204    if not error_message == "":
205        gp.print_error_report(error_message)
206        return False
207
208    return True
209
210
211def svalid_file_path(var_value,
212                     var_name=""):
213    r"""
214    Return an empty string if var_value is a valid file path.  Otherwise,
215    return an error string.
216
217    Description of arguments:
218    var_value                       The value being validated.
219    var_name                        The name of the variable whose value is
220                                    passed in var_value.  This parameter is
221                                    normally unnecessary as this function can
222                                    figure out the var_name.  This is provided
223                                    for Robot callers.  In this scenario, we
224                                    are unable to get the variable name
225                                    ourselves.
226    """
227
228    error_message = ""
229    if not os.path.isfile(str(var_value)):
230        if var_name is "":
231            stack_index = 3
232            var_name = gp.get_arg_name(0, 1, stack_index)
233        error_message += "Invalid file (does not exist):\n" +\
234                         gp.sprint_varx(var_name, var_value)
235
236    return error_message
237
238
239def valid_file_path(var_value,
240                    var_name=""):
241    r"""
242    Return True if var_value is a valid integer.  Otherwise, return False and
243    print an error message to stderr.
244
245    Description of arguments:
246    (See description of arguments for svalid_value (above)).
247    """
248
249    error_message = svalid_file_path(var_value, var_name)
250
251    if not error_message == "":
252        gp.print_error_report(error_message)
253        return False
254
255    return True
256
257
258def svalid_range(var_value,
259                 range=[],
260                 var_name=""):
261    r"""
262    Return an empty string if var_value is within the range.  Otherwise,
263    return an error string.
264
265    Description of arguments:
266    var_value                       The value being validated.  This value
267                                    must be an integer.
268    range                           A list comprised of one or two elements
269                                    which are the lower and upper ends of a
270                                    range.  These values must be integers
271                                    except where noted.  Valid specifications
272                                    may be of the following forms: [lower,
273                                    upper], [lower] or [None, upper].
274    var_name                        The name of the variable whose value is
275                                    passed in var_value.  This parameter is
276                                    normally unnecessary as this function can
277                                    figure out the var_name.  This is provided
278                                    for Robot callers.  In this scenario, we
279                                    are unable to get the variable name
280                                    ourselves.
281    """
282
283    error_message = ""
284    if var_name == "":
285        var_name = gp.get_arg_name(0, 1, stack_frame_ix=3)
286
287    # Validate this function's parms:
288    # First, ensure that the value is an integer.
289    error_message = svalid_integer(var_value, var_name)
290    if not error_message == "":
291        return error_message
292    var_value = int(var_value)
293
294    len_range = len(range)
295    if len_range > 2:
296        error_message += "Programmer error - For the range parameter, you" +\
297                         " must provide a list consisting of one or two" +\
298                         " elements.\n" +\
299                         gp.sprint_var(range)
300        return error_message
301
302    if len_range == 1 or range[0] is not None:
303        # Make sure lower range value is an integer.
304        error_message = svalid_integer(range[0], "range[0]")
305        if not error_message == "":
306            error_message = "Programmer error:\n" + error_message
307            return error_message
308    if range[0] is not None:
309        range[0] = int(range[0])
310    if len_range == 2:
311        # Make sure upper range value is an integer.
312        error_message = svalid_integer(range[1], "range[1]")
313        if not error_message == "":
314            error_message = "Programmer error:\n" + error_message
315            return error_message
316        range[1] = int(range[1])
317
318    if len_range == 1:
319        if var_value < range[0]:
320            error_message += "The following variable is not within the" +\
321                             " expected range:\n" +\
322                             gp.sprint_varx(var_name, var_value) +\
323                             gp.sprint_varx("valid_range",
324                                            str(range[0]) + "..")
325            return error_message
326
327    if range[0] is None:
328        if var_value > range[1]:
329            error_message += "The following variable is not within the" +\
330                             " expected range:\n" +\
331                             gp.sprint_varx(var_name, var_value) +\
332                             gp.sprint_varx("valid_range",
333                                            ".." + str(range[1]))
334            return error_message
335
336    if var_value < range[0] or var_value > range[1]:
337        error_message += "The following variable is not within the expected" +\
338                         " range:\n" +\
339                         gp.sprint_varx(var_name, var_value) +\
340                         gp.sprint_varx("valid_range",
341                                        str(range[0]) + ".." +
342                                        str(range[1]))
343        return error_message
344
345    return error_message
346
347
348def valid_range(var_value,
349                range=[],
350                var_name=""):
351    r"""
352    Return True if var_value is within the range.  Otherwise, return False and
353    print an error message to stderr.
354
355    Description of arguments:
356    (See description of arguments for svalid_range (above)).
357    """
358
359    error_message = svalid_range(var_value, range, var_name)
360
361    if not error_message == "":
362        gp.print_error_report(error_message)
363        return False
364
365    return True
366