blob: 7c82ece4dfb95816bc40ead29f92eb0c1f7befdc [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
George Keishing3b7115a2018-08-02 10:48:17 -05009try:
10 import __builtin__
11except ImportError:
12 import builtins as __builtin__
Michael Walsh7423c012016-10-04 10:27:21 -050013import atexit
14import signal
15import argparse
16
17import gen_print as gp
Michael Walsh69d58ae2018-06-01 15:18:57 -050018import gen_valid as gv
Michael Walsh7423c012016-10-04 10:27:21 -050019
20default_string = ' The default value is "%(default)s".'
21
22
Michael Walsh7423c012016-10-04 10:27:21 -050023def gen_get_options(parser,
24 stock_list=[]):
Michael Walsh7423c012016-10-04 10:27:21 -050025 r"""
26 Parse the command line arguments using the parser object passed and return
Michael Walsh69d58ae2018-06-01 15:18:57 -050027 True/False (i.e. pass/fail). However, if gv.exit_on_error is set, simply
28 exit the program on failure. Also set the following built in values:
Michael Walsh7423c012016-10-04 10:27:21 -050029
30 __builtin__.quiet This value is used by the qprint functions.
31 __builtin__.test_mode This value is used by command processing functions.
32 __builtin__.debug This value is used by the dprint functions.
33 __builtin__.arg_obj This value is used by print_program_header, etc.
34 __builtin__.parser This value is used by print_program_header, etc.
35
36 Description of arguments:
37 parser A parser object. See argparse module
38 documentation for details.
39 stock_list The caller can use this parameter to
40 request certain stock parameters offered
41 by this function. For example, this
42 function will define a "quiet" option upon
43 request. This includes stop help text and
44 parm checking. The stock_list is a list
45 of tuples each of which consists of an
46 arg_name and a default value. Example:
47 stock_list = [("test_mode", 0), ("quiet",
48 1), ("debug", 0)]
49 """
50
51 # This is a list of stock parms that we support.
52 master_stock_list = ["quiet", "test_mode", "debug", "loglevel"]
53
54 # Process stock_list.
55 for ix in range(0, len(stock_list)):
56 if len(stock_list[ix]) < 1:
Michael Walsh69d58ae2018-06-01 15:18:57 -050057 error_message = "Programmer error - stock_list[" + str(ix) +\
58 "] is supposed to be a tuple containing at" +\
59 " least one element which is the name of" +\
60 " the desired stock parameter:\n" +\
61 gp.sprint_var(stock_list)
62 return gv.process_error_message(error_message)
Joy Onyerikwu004ad3c2018-06-11 16:29:56 -050063 if isinstance(stock_list[ix], tuple):
Michael Walsh7423c012016-10-04 10:27:21 -050064 arg_name = stock_list[ix][0]
65 default = stock_list[ix][1]
66 else:
67 arg_name = stock_list[ix]
68 default = None
69
70 if arg_name not in master_stock_list:
Michael Walsh69d58ae2018-06-01 15:18:57 -050071 error_message = "Programmer error - arg_name \"" + arg_name +\
72 "\" not found found in stock list:\n" +\
73 gp.sprint_var(master_stock_list)
74 return gv.process_error_message(error_message)
Michael Walsh7423c012016-10-04 10:27:21 -050075
76 if arg_name == "quiet":
77 if default is None:
78 default = 0
79 parser.add_argument(
80 '--quiet',
81 default=default,
82 type=int,
83 choices=[1, 0],
Joy Onyerikwu004ad3c2018-06-11 16:29:56 -050084 help='If this parameter is set to "1", %(prog)s'
85 + ' will print only essential information, i.e. it will'
86 + ' not echo parameters, echo commands, print the total'
87 + ' run time, etc.' + default_string)
Michael Walsh7423c012016-10-04 10:27:21 -050088 elif arg_name == "test_mode":
89 if default is None:
90 default = 0
91 parser.add_argument(
92 '--test_mode',
93 default=default,
94 type=int,
95 choices=[1, 0],
Joy Onyerikwu004ad3c2018-06-11 16:29:56 -050096 help='This means that %(prog)s should go through all the'
97 + ' motions but not actually do anything substantial.'
98 + ' This is mainly to be used by the developer of'
99 + ' %(prog)s.' + default_string)
Michael Walsh7423c012016-10-04 10:27:21 -0500100 elif arg_name == "debug":
101 if default is None:
102 default = 0
103 parser.add_argument(
104 '--debug',
105 default=default,
106 type=int,
107 choices=[1, 0],
Joy Onyerikwu004ad3c2018-06-11 16:29:56 -0500108 help='If this parameter is set to "1", %(prog)s will print'
109 + ' additional debug information. This is mainly to be'
110 + ' used by the developer of %(prog)s.' + default_string)
Michael Walsh7423c012016-10-04 10:27:21 -0500111 elif arg_name == "loglevel":
112 if default is None:
113 default = "info"
114 parser.add_argument(
115 '--loglevel',
116 default=default,
117 type=str,
118 choices=['DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL',
119 'debug', 'info', 'warning', 'error', 'critical'],
Joy Onyerikwu004ad3c2018-06-11 16:29:56 -0500120 help='If this parameter is set to "1", %(prog)s will print'
121 + ' additional debug information. This is mainly to be'
122 + ' used by the developer of %(prog)s.' + default_string)
Michael Walsh7423c012016-10-04 10:27:21 -0500123
124 arg_obj = parser.parse_args()
125
126 __builtin__.quiet = 0
127 __builtin__.test_mode = 0
128 __builtin__.debug = 0
129 __builtin__.loglevel = 'WARNING'
130 for ix in range(0, len(stock_list)):
Joy Onyerikwu004ad3c2018-06-11 16:29:56 -0500131 if isinstance(stock_list[ix], tuple):
Michael Walsh7423c012016-10-04 10:27:21 -0500132 arg_name = stock_list[ix][0]
133 default = stock_list[ix][1]
134 else:
135 arg_name = stock_list[ix]
136 default = None
137 if arg_name == "quiet":
138 __builtin__.quiet = arg_obj.quiet
139 elif arg_name == "test_mode":
140 __builtin__.test_mode = arg_obj.test_mode
141 elif arg_name == "debug":
142 __builtin__.debug = arg_obj.debug
143 elif arg_name == "loglevel":
144 __builtin__.loglevel = arg_obj.loglevel
145
146 __builtin__.arg_obj = arg_obj
147 __builtin__.parser = parser
148
149 # For each command line parameter, create a corresponding global variable
150 # and assign it the appropriate value. For example, if the command line
151 # contained "--last_name='Smith', we'll create a global variable named
152 # "last_name" with the value "Smith".
153 module = sys.modules['__main__']
154 for key in arg_obj.__dict__:
155 setattr(module, key, getattr(__builtin__.arg_obj, key))
156
157 return True
158
Michael Walsh7423c012016-10-04 10:27:21 -0500159
Michael Walshc33ef372017-01-10 11:46:29 -0600160def set_pgm_arg(var_value,
161 var_name=None):
Michael Walshc33ef372017-01-10 11:46:29 -0600162 r"""
163 Set the value of the arg_obj.__dict__ entry named in var_name with the
164 var_value provided. Also, set corresponding global variable.
165
166 Description of arguments:
167 var_value The value to set in the variable.
168 var_name The name of the variable to set. This
169 defaults to the name of the variable used
170 for var_value when calling this function.
171 """
172
173 if var_name is None:
174 var_name = gp.get_arg_name(None, 1, 2)
175
176 arg_obj.__dict__[var_name] = var_value
177 module = sys.modules['__main__']
178 setattr(module, var_name, var_value)
179 if var_name == "quiet":
180 __builtin__.quiet = var_value
181 elif var_name == "debug":
182 __builtin__.debug = var_value
183 elif var_name == "test_mode":
184 __builtin__.test_mode = var_value
185
Michael Walshc33ef372017-01-10 11:46:29 -0600186
Michael Walsh7423c012016-10-04 10:27:21 -0500187def sprint_args(arg_obj,
188 indent=0):
Michael Walsh7423c012016-10-04 10:27:21 -0500189 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):
Michael Walsh7423c012016-10-04 10:27:21 -0500213 r"""
214 Do generic post-validation processing. By "post", we mean that this is to
215 be called from a validation function after the caller has done any
216 validation desired. If the calling program passes exit_function and
217 signal_handler parms, this function will register them. In other words,
218 it will make the signal_handler functions get called for SIGINT and
219 SIGTERM and will make the exit_function function run prior to the
220 termination of the program.
221
222 Description of arguments:
223 exit_function A function object pointing to the caller's
224 exit function.
225 signal_handler A function object pointing to the caller's
226 signal_handler function.
227 """
228
229 if exit_function is not None:
230 atexit.register(exit_function)
231 if signal_handler is not None:
232 signal.signal(signal.SIGINT, signal_handler)
233 signal.signal(signal.SIGTERM, signal_handler)