1#!/usr/bin/env python 2 3r""" 4Define variable manipulation functions. 5""" 6 7import os 8import re 9 10try: 11 from robot.utils import DotDict 12except ImportError: 13 pass 14 15import collections 16 17import gen_print as gp 18import gen_misc as gm 19 20 21def create_var_dict(*args): 22 23 r""" 24 Create a dictionary whose keys/values are the arg names/arg values passed 25 to it and return it to the caller. 26 27 Note: The resulting dictionary will be ordered. 28 29 Description of argument(s): 30 *args An unlimited number of arguments to be processed. 31 32 Example use: 33 34 first_name = 'Steve' 35 last_name = 'Smith' 36 var_dict = create_var_dict(first_name, last_name) 37 38 gp.print_var(var_dict) 39 40 The print-out of the resulting var dictionary is: 41 var_dict: 42 var_dict[first_name]: Steve 43 var_dict[last_name]: Smith 44 """ 45 46 try: 47 result_dict = collections.OrderedDict() 48 except AttributeError: 49 result_dict = DotDict() 50 51 arg_num = 1 52 for arg in args: 53 arg_name = gp.get_arg_name(None, arg_num, stack_frame_ix=2) 54 result_dict[arg_name] = arg 55 arg_num += 1 56 57 return result_dict 58 59 60default_record_delim = ':' 61default_key_val_delim = '.' 62 63 64def join_dict(dict, 65 record_delim=default_record_delim, 66 key_val_delim=default_key_val_delim): 67 68 r""" 69 Join a dictionary's keys and values into a string and return the string. 70 71 Description of argument(s): 72 dict The dictionary whose keys and values are 73 to be joined. 74 record_delim The delimiter to be used to separate 75 dictionary pairs in the resulting string. 76 key_val_delim The delimiter to be used to separate keys 77 from values in the resulting string. 78 79 Example use: 80 81 gp.print_var(var_dict) 82 str1 = join_dict(var_dict) 83 gp.pvar(str1) 84 85 Program output. 86 var_dict: 87 var_dict[first_name]: Steve 88 var_dict[last_name]: Smith 89 str1: 90 first_name.Steve:last_name.Smith 91 """ 92 93 format_str = '%s' + key_val_delim + '%s' 94 return record_delim.join([format_str % (key, value) for (key, value) in 95 dict.items()]) 96 97 98def split_to_dict(string, 99 record_delim=default_record_delim, 100 key_val_delim=default_key_val_delim): 101 102 r""" 103 Split a string into a dictionary and return it. 104 105 This function is the complement to join_dict. 106 107 Description of argument(s): 108 string The string to be split into a dictionary. 109 The string must have the proper delimiters 110 in it. A string created by join_dict 111 would qualify. 112 record_delim The delimiter to be used to separate 113 dictionary pairs in the input string. 114 key_val_delim The delimiter to be used to separate 115 keys/values in the input string. 116 117 Example use: 118 119 gp.print_var(str1) 120 new_dict = split_to_dict(str1) 121 gp.print_var(new_dict) 122 123 124 Program output. 125 str1: 126 first_name.Steve:last_name.Smith 127 new_dict: 128 new_dict[first_name]: Steve 129 new_dict[last_name]: Smith 130 """ 131 132 try: 133 result_dict = collections.OrderedDict() 134 except AttributeError: 135 result_dict = DotDict() 136 137 raw_keys_values = string.split(record_delim) 138 for key_value in raw_keys_values: 139 key_value_list = key_value.split(key_val_delim) 140 try: 141 result_dict[key_value_list[0]] = key_value_list[1] 142 except IndexError: 143 result_dict[key_value_list[0]] = "" 144 145 return result_dict 146 147 148def create_file_path(file_name_dict, 149 dir_path="/tmp/", 150 file_suffix=""): 151 152 r""" 153 Create a file path using the given parameters and return it. 154 155 Description of argument(s): 156 file_name_dict A dictionary with keys/values which are to 157 appear as part of the file name. 158 dir_path The dir_path that is to appear as part of 159 the file name. 160 file_suffix A suffix to be included as part of the 161 file name. 162 """ 163 164 dir_path = gm.add_trailing_slash(dir_path) 165 return dir_path + join_dict(file_name_dict) + file_suffix 166 167 168def parse_file_path(file_path): 169 170 r""" 171 Parse a file path created by create_file_path and return the result as a 172 dictionary. 173 174 This function is the complement to create_file_path. 175 176 Description of argument(s): 177 file_path The file_path. 178 179 Example use: 180 gp.pvar(boot_results_file_path) 181 file_path_data = parse_file_path(boot_results_file_path) 182 gp.pvar(file_path_data) 183 184 Program output. 185 186 boot_results_file_path: 187 /tmp/pgm_name.obmc_boot_test:openbmc_nickname.beye6:master_pid.2039:boot_re 188 sults 189 file_path_data: 190 file_path_data[dir_path]: /tmp/ 191 file_path_data[pgm_name]: obmc_boot_test 192 file_path_data[openbmc_nickname]: beye6 193 file_path_data[master_pid]: 2039 194 file_path_data[boot_results]: 195 """ 196 197 try: 198 result_dict = collections.OrderedDict() 199 except AttributeError: 200 result_dict = DotDict() 201 202 dir_path = os.path.dirname(file_path) + os.sep 203 file_path = os.path.basename(file_path) 204 205 result_dict['dir_path'] = dir_path 206 207 result_dict.update(split_to_dict(file_path)) 208 209 return result_dict 210 211 212def parse_key_value(string, 213 delim=":", 214 strip=" ", 215 to_lower=1, 216 underscores=1): 217 218 r""" 219 Parse a key/value string and return as a key/value tuple. 220 221 This function is useful for parsing a line of program output or data that 222 is in the following form: 223 <key or variable name><delimiter><value> 224 225 An example of a key/value string would be as follows: 226 227 Current Limit State: No Active Power Limit 228 229 In the example shown, the delimiter is ":". The resulting key would be as 230 follows: 231 Current Limit State 232 233 Note: If one were to take the default values of to_lower=1 and 234 underscores=1, the resulting key would be as follows: 235 current_limit_state 236 237 The to_lower and underscores arguments are provided for those who wish to 238 have their key names have the look and feel of python variable names. 239 240 The resulting value for the example above would be as follows: 241 No Active Power Limit 242 243 Another example: 244 name=Mike 245 246 In this case, the delim would be "=", the key is "name" and the value is 247 "Mike". 248 249 Description of argument(s): 250 string The string to be parsed. 251 delim The delimiter which separates the key from 252 the value. 253 strip The characters (if any) to strip from the 254 beginning and end of both the key and the 255 value. 256 to_lower Change the key name to lower case. 257 underscores Change any blanks found in the key name to 258 underscores. 259 """ 260 261 pair = string.split(delim) 262 263 key = pair[0].strip(strip) 264 if len(pair) == 0: 265 value = "" 266 else: 267 value = "".join(pair[1:]).strip(strip) 268 269 if to_lower: 270 key = key.lower() 271 if underscores: 272 key = re.sub(r" ", "_", key) 273 274 return key, value 275 276 277def key_value_list_to_dict(list, 278 **args): 279 280 r""" 281 Convert a list containing key/value strings to a dictionary and return it. 282 283 See docstring of parse_key_value function for details on key/value strings. 284 285 Example usage: 286 287 For the following value of list: 288 289 list: 290 list[0]: Current Limit State: No Active Power Limit 291 list[1]: Exception actions: Hard Power Off & Log Event to SEL 292 list[2]: Power Limit: 0 Watts 293 list[3]: Correction time: 0 milliseconds 294 list[4]: Sampling period: 0 seconds 295 296 And the following call in python: 297 298 power_limit = key_value_outbuf_to_dict(list) 299 300 The resulting power_limit directory would look like this: 301 302 power_limit: 303 [current_limit_state]: No Active Power Limit 304 [exception_actions]: Hard Power Off & Log Event to SEL 305 [power_limit]: 0 Watts 306 [correction_time]: 0 milliseconds 307 [sampling_period]: 0 seconds 308 309 Description of argument(s): 310 list A list of key/value strings. (See 311 docstring of parse_key_value function for 312 details). 313 **args Arguments to be interpreted by 314 parse_key_value. (See docstring of 315 parse_key_value function for details). 316 """ 317 318 try: 319 result_dict = collections.OrderedDict() 320 except AttributeError: 321 result_dict = DotDict() 322 323 for entry in list: 324 key, value = parse_key_value(entry, **args) 325 result_dict[key] = value 326 327 return result_dict 328 329 330def key_value_outbuf_to_dict(out_buf, 331 **args): 332 333 r""" 334 Convert a buffer with a key/value string on each line to a dictionary and 335 return it. 336 337 Each line in the out_buf should end with a \n. 338 339 See docstring of parse_key_value function for details on key/value strings. 340 341 Example usage: 342 343 For the following value of out_buf: 344 345 Current Limit State: No Active Power Limit 346 Exception actions: Hard Power Off & Log Event to SEL 347 Power Limit: 0 Watts 348 Correction time: 0 milliseconds 349 Sampling period: 0 seconds 350 351 And the following call in python: 352 353 power_limit = key_value_outbuf_to_dict(out_buf) 354 355 The resulting power_limit directory would look like this: 356 357 power_limit: 358 [current_limit_state]: No Active Power Limit 359 [exception_actions]: Hard Power Off & Log Event to SEL 360 [power_limit]: 0 Watts 361 [correction_time]: 0 milliseconds 362 [sampling_period]: 0 seconds 363 364 Description of argument(s): 365 out_buf A buffer with a key/value string on each 366 line. (See docstring of parse_key_value 367 function for details). 368 **args Arguments to be interpreted by 369 parse_key_value. (See docstring of 370 parse_key_value function for details). 371 """ 372 373 # Create key_var_list and remove null entries. 374 key_var_list = list(filter(None, out_buf.split("\n"))) 375 return key_value_list_to_dict(key_var_list, **args) 376