1#!/usr/bin/env python 2 3r""" 4This module provides many valuable functions such as my_parm_file. 5""" 6 7# sys and os are needed to get the program dir path and program name. 8import sys 9import os 10import ConfigParser 11import StringIO 12import re 13 14import gen_print as gp 15import gen_cmd as gc 16 17 18robot_env = 1 19try: 20 from robot.libraries.BuiltIn import BuiltIn 21except ImportError: 22 robot_env = 0 23 24 25############################################################################### 26def add_trailing_slash(dir_path): 27 28 r""" 29 Add a trailing slash to the directory path if it doesn't already have one 30 and return it. 31 32 Description of arguments: 33 dir_path A directory path. 34 """ 35 36 return os.path.normpath(dir_path) + os.path.sep 37 38############################################################################### 39 40 41############################################################################### 42def which(file_path): 43 44 r""" 45 Find the full path of an executable file and return it. 46 47 The PATH environment variable dictates the results of this function. 48 49 Description of arguments: 50 file_path The relative file path (e.g. "my_file" or 51 "lib/my_file"). 52 """ 53 54 shell_rc, out_buf = gc.cmd_fnc_u("which " + file_path, quiet=1, 55 print_output=0, show_err=0) 56 if shell_rc != 0: 57 error_message = "Failed to find complete path for file \"" +\ 58 file_path + "\".\n" 59 error_message += gp.sprint_var(shell_rc, 1) 60 error_message += out_buf 61 if robot_env: 62 BuiltIn().fail(gp.sprint_error(error_message)) 63 else: 64 gp.print_error_report(error_message) 65 return False 66 67 file_path = out_buf.rstrip("\n") 68 69 return file_path 70 71############################################################################### 72 73 74############################################################################### 75def dft(value, default): 76 77 r""" 78 Return default if value is None. Otherwise, return value. 79 80 This is really just shorthand as shown below. 81 82 dft(value, default) 83 84 vs 85 86 default if value is None else value 87 88 Description of arguments: 89 value The value to be returned. 90 default The default value to return if value is 91 None. 92 """ 93 94 return default if value is None else value 95 96############################################################################### 97 98 99############################################################################### 100def get_mod_global(var_name, 101 default=None, 102 mod_name="__main__"): 103 104 r""" 105 Get module global variable value and return it. 106 107 If we are running in a robot environment, the behavior will default to 108 calling get_variable_value. 109 110 Description of arguments: 111 var_name The name of the variable whose value is 112 sought. 113 default The value to return if the global does not 114 exist. 115 mod_name The name of the module containing the 116 global variable. 117 """ 118 119 if robot_env: 120 return BuiltIn().get_variable_value("${" + var_name + "}", default) 121 122 try: 123 module = sys.modules[mod_name] 124 except KeyError: 125 gp.print_error_report("Programmer error - The mod_name passed to" + 126 " this function is invalid:\n" + 127 gp.sprint_var(mod_name)) 128 raise ValueError('Programmer error.') 129 130 if default is None: 131 return getattr(module, var_name) 132 else: 133 return getattr(module, var_name, default) 134 135############################################################################### 136 137 138############################################################################### 139def global_default(var_value, 140 default=0): 141 142 r""" 143 If var_value is not None, return it. Otherwise, return the global 144 variable of the same name, if it exists. If not, return default. 145 146 This is meant for use by functions needing help assigning dynamic default 147 values to their parms. Example: 148 149 def func1(parm1=None): 150 151 parm1 = global_default(parm1, 0) 152 153 Description of arguments: 154 var_value The value being evaluated. 155 default The value to be returned if var_value is 156 None AND the global variable of the same 157 name does not exist. 158 """ 159 160 var_name = gp.get_arg_name(0, 1, stack_frame_ix=2) 161 162 return dft(var_value, get_mod_global(var_name, 0)) 163 164############################################################################### 165 166 167############################################################################### 168def set_mod_global(var_value, 169 mod_name="__main__", 170 var_name=None): 171 172 r""" 173 Set a global variable for a given module. 174 175 Description of arguments: 176 var_value The value to set in the variable. 177 mod_name The name of the module whose variable is 178 to be set. 179 var_name The name of the variable to set. This 180 defaults to the name of the variable used 181 for var_value when calling this function. 182 """ 183 184 try: 185 module = sys.modules[mod_name] 186 except KeyError: 187 gp.print_error_report("Programmer error - The mod_name passed to" + 188 " this function is invalid:\n" + 189 gp.sprint_var(mod_name)) 190 raise ValueError('Programmer error.') 191 192 if var_name is None: 193 var_name = gp.get_arg_name(None, 1, 2) 194 195 setattr(module, var_name, var_value) 196 197############################################################################### 198 199 200############################################################################### 201def my_parm_file(prop_file_path): 202 203 r""" 204 Read a properties file, put the keys/values into a dictionary and return 205 the dictionary. 206 207 The properties file must have the following format: 208 var_name<= or :>var_value 209 Comment lines (those beginning with a "#") and blank lines are allowed and 210 will be ignored. Leading and trailing single or double quotes will be 211 stripped from the value. E.g. 212 var1="This one" 213 Quotes are stripped so the resulting value for var1 is: 214 This one 215 216 Description of arguments: 217 prop_file_path The caller should pass the path to the 218 properties file. 219 """ 220 221 # ConfigParser expects at least one section header in the file (or you 222 # get ConfigParser.MissingSectionHeaderError). Properties files don't 223 # need those so I'll write a dummy section header. 224 225 string_file = StringIO.StringIO() 226 # Write the dummy section header to the string file. 227 string_file.write('[dummysection]\n') 228 # Write the entire contents of the properties file to the string file. 229 string_file.write(open(prop_file_path).read()) 230 # Rewind the string file. 231 string_file.seek(0, os.SEEK_SET) 232 233 # Create the ConfigParser object. 234 config_parser = ConfigParser.ConfigParser() 235 # Make the property names case-sensitive. 236 config_parser.optionxform = str 237 # Read the properties from the string file. 238 config_parser.readfp(string_file) 239 # Return the properties as a dictionary. 240 return dict(config_parser.items('dummysection')) 241 242############################################################################### 243 244 245############################################################################### 246def file_to_list(file_path, 247 newlines=0, 248 comments=1, 249 trim=0): 250 251 r""" 252 Return the contents of a file as a list. Each element of the resulting 253 list is one line from the file. 254 255 Description of arguments: 256 file_path The path to the file (relative or 257 absolute). 258 newlines Include newlines from the file in the 259 results. 260 comments Include comment lines and blank lines in 261 the results. Comment lines are any that 262 begin with 0 or more spaces followed by 263 the pound sign ("#"). 264 trim Trim white space from the beginning and 265 end of each line. 266 """ 267 268 lines = [] 269 file = open(file_path) 270 for line in file: 271 if not comments: 272 if re.match(r"[ ]*#|^$", line): 273 continue 274 if not newlines: 275 line = line.rstrip("\n") 276 if trim: 277 line = line.strip() 278 lines.append(line) 279 280 return lines 281 282############################################################################### 283 284 285############################################################################### 286def return_path_list(): 287 288 r""" 289 This function will split the PATH environment variable into a PATH_LIST 290 and return it. Each element in the list will be normalized and have a 291 trailing slash added. 292 """ 293 294 PATH_LIST = os.environ['PATH'].split(":") 295 PATH_LIST = [os.path.normpath(path) + os.sep for path in PATH_LIST] 296 297 return PATH_LIST 298 299############################################################################### 300 301 302############################################################################### 303def quote_bash_parm(parm): 304 305 r""" 306 Return the bash command line parm with single quotes if they are needed. 307 308 Description of arguments: 309 parm The string to be quoted. 310 """ 311 312 # If any of these characters are found in the parm string, then the 313 # string should be quoted. This list is by no means complete and should 314 # be expanded as needed by the developer of this function. 315 bash_special_chars = set(' $') 316 317 if any((char in bash_special_chars) for char in parm): 318 return "'" + parm + "'" 319 320 return parm 321 322############################################################################### 323