blob: 2981668b62ac3272aa8c17dc7a4d93f4319809f9 [file] [log] [blame]
Michael Walsh7423c012016-10-04 10:27:21 -05001#!/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 __builtin__
10import atexit
11import signal
12import argparse
13
14import gen_print as gp
15
16default_string = ' The default value is "%(default)s".'
17
18
Michael Walsh7423c012016-10-04 10:27:21 -050019def gen_get_options(parser,
20 stock_list=[]):
21
22 r"""
23 Parse the command line arguments using the parser object passed and return
24 True/False (i.e. pass/fail). Also set the following built in values:
25
26 __builtin__.quiet This value is used by the qprint functions.
27 __builtin__.test_mode This value is used by command processing functions.
28 __builtin__.debug This value is used by the dprint functions.
29 __builtin__.arg_obj This value is used by print_program_header, etc.
30 __builtin__.parser This value is used by print_program_header, etc.
31
32 Description of arguments:
33 parser A parser object. See argparse module
34 documentation for details.
35 stock_list The caller can use this parameter to
36 request certain stock parameters offered
37 by this function. For example, this
38 function will define a "quiet" option upon
39 request. This includes stop help text and
40 parm checking. The stock_list is a list
41 of tuples each of which consists of an
42 arg_name and a default value. Example:
43 stock_list = [("test_mode", 0), ("quiet",
44 1), ("debug", 0)]
45 """
46
47 # This is a list of stock parms that we support.
48 master_stock_list = ["quiet", "test_mode", "debug", "loglevel"]
49
50 # Process stock_list.
51 for ix in range(0, len(stock_list)):
52 if len(stock_list[ix]) < 1:
53 gp.print_error_report("Programmer error - stock_list[" + str(ix) +
54 "] is supposed to be a tuple containing at" +
55 " least one element which is the name of" +
56 " the desired stock parameter:\n" +
57 gp.sprint_var(stock_list))
58 return False
59 if type(stock_list[ix]) is tuple:
60 arg_name = stock_list[ix][0]
61 default = stock_list[ix][1]
62 else:
63 arg_name = stock_list[ix]
64 default = None
65
66 if arg_name not in master_stock_list:
67 gp.pvar(arg_name)
68 gp.print_error_report("Programmer error - \"" + arg_name +
69 "\" not found found in stock list:\n" +
70 gp.sprint_var(master_stock_list))
71 return False
72
73 if arg_name == "quiet":
74 if default is None:
75 default = 0
76 parser.add_argument(
77 '--quiet',
78 default=default,
79 type=int,
80 choices=[1, 0],
81 help='If this parameter is set to "1", %(prog)s' +
82 ' will print only essential information, i.e. it will' +
83 ' not echo parameters, echo commands, print the total' +
Michael Walshc33ef372017-01-10 11:46:29 -060084 ' run time, etc.' + default_string)
Michael Walsh7423c012016-10-04 10:27:21 -050085 elif arg_name == "test_mode":
86 if default is None:
87 default = 0
88 parser.add_argument(
89 '--test_mode',
90 default=default,
91 type=int,
92 choices=[1, 0],
93 help='This means that %(prog)s should go through all the' +
94 ' motions but not actually do anything substantial.' +
95 ' This is mainly to be used by the developer of' +
Michael Walshc33ef372017-01-10 11:46:29 -060096 ' %(prog)s.' + default_string)
Michael Walsh7423c012016-10-04 10:27:21 -050097 elif arg_name == "debug":
98 if default is None:
99 default = 0
100 parser.add_argument(
101 '--debug',
102 default=default,
103 type=int,
104 choices=[1, 0],
105 help='If this parameter is set to "1", %(prog)s will print' +
106 ' additional debug information. This is mainly to be' +
Michael Walshc33ef372017-01-10 11:46:29 -0600107 ' used by the developer of %(prog)s.' + default_string)
Michael Walsh7423c012016-10-04 10:27:21 -0500108 elif arg_name == "loglevel":
109 if default is None:
110 default = "info"
111 parser.add_argument(
112 '--loglevel',
113 default=default,
114 type=str,
115 choices=['DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL',
116 'debug', 'info', 'warning', 'error', 'critical'],
117 help='If this parameter is set to "1", %(prog)s will print' +
118 ' additional debug information. This is mainly to be' +
Michael Walshc33ef372017-01-10 11:46:29 -0600119 ' used by the developer of %(prog)s.' + default_string)
Michael Walsh7423c012016-10-04 10:27:21 -0500120
121 arg_obj = parser.parse_args()
122
123 __builtin__.quiet = 0
124 __builtin__.test_mode = 0
125 __builtin__.debug = 0
126 __builtin__.loglevel = 'WARNING'
127 for ix in range(0, len(stock_list)):
128 if type(stock_list[ix]) is tuple:
129 arg_name = stock_list[ix][0]
130 default = stock_list[ix][1]
131 else:
132 arg_name = stock_list[ix]
133 default = None
134 if arg_name == "quiet":
135 __builtin__.quiet = arg_obj.quiet
136 elif arg_name == "test_mode":
137 __builtin__.test_mode = arg_obj.test_mode
138 elif arg_name == "debug":
139 __builtin__.debug = arg_obj.debug
140 elif arg_name == "loglevel":
141 __builtin__.loglevel = arg_obj.loglevel
142
143 __builtin__.arg_obj = arg_obj
144 __builtin__.parser = parser
145
146 # For each command line parameter, create a corresponding global variable
147 # and assign it the appropriate value. For example, if the command line
148 # contained "--last_name='Smith', we'll create a global variable named
149 # "last_name" with the value "Smith".
150 module = sys.modules['__main__']
151 for key in arg_obj.__dict__:
152 setattr(module, key, getattr(__builtin__.arg_obj, key))
153
154 return True
155
Michael Walsh7423c012016-10-04 10:27:21 -0500156
Michael Walshc33ef372017-01-10 11:46:29 -0600157def set_pgm_arg(var_value,
158 var_name=None):
159
160 r"""
161 Set the value of the arg_obj.__dict__ entry named in var_name with the
162 var_value provided. Also, set corresponding global variable.
163
164 Description of arguments:
165 var_value The value to set in the variable.
166 var_name The name of the variable to set. This
167 defaults to the name of the variable used
168 for var_value when calling this function.
169 """
170
171 if var_name is None:
172 var_name = gp.get_arg_name(None, 1, 2)
173
174 arg_obj.__dict__[var_name] = var_value
175 module = sys.modules['__main__']
176 setattr(module, var_name, var_value)
177 if var_name == "quiet":
178 __builtin__.quiet = var_value
179 elif var_name == "debug":
180 __builtin__.debug = var_value
181 elif var_name == "test_mode":
182 __builtin__.test_mode = var_value
183
Michael Walshc33ef372017-01-10 11:46:29 -0600184
Michael Walsh7423c012016-10-04 10:27:21 -0500185# Put this in gen_opt.py or gen_parm.py or gen_arg.py.
Michael Walsh7423c012016-10-04 10:27:21 -0500186def sprint_args(arg_obj,
187 indent=0):
188
189 r"""
190 sprint_var all of the arguments found in arg_obj and return the result as
191 a string.
192
193 Description of arguments:
194 arg_obj An argument object such as is returned by
195 the argparse parse_args() method.
196 indent The number of spaces to indent each line
197 of output.
198 """
199
Michael Walshbec416d2016-11-10 08:54:52 -0600200 loc_col1_width = gp.col1_width + indent
201
Michael Walsh7423c012016-10-04 10:27:21 -0500202 buffer = ""
203
204 for key in arg_obj.__dict__:
Michael Walshbec416d2016-11-10 08:54:52 -0600205 buffer += gp.sprint_varx(key, getattr(arg_obj, key), 0, indent,
206 loc_col1_width)
Michael Walsh7423c012016-10-04 10:27:21 -0500207
208 return buffer
209
Michael Walsh7423c012016-10-04 10:27:21 -0500210
Michael Walsh7423c012016-10-04 10:27:21 -0500211def gen_post_validation(exit_function=None,
212 signal_handler=None):
213
214 r"""
215 Do generic post-validation processing. By "post", we mean that this is to
216 be called from a validation function after the caller has done any
217 validation desired. If the calling program passes exit_function and
218 signal_handler parms, this function will register them. In other words,
219 it will make the signal_handler functions get called for SIGINT and
220 SIGTERM and will make the exit_function function run prior to the
221 termination of the program.
222
223 Description of arguments:
224 exit_function A function object pointing to the caller's
225 exit function.
226 signal_handler A function object pointing to the caller's
227 signal_handler function.
228 """
229
230 if exit_function is not None:
231 atexit.register(exit_function)
232 if signal_handler is not None:
233 signal.signal(signal.SIGINT, signal_handler)
234 signal.signal(signal.SIGTERM, signal_handler)