1#!/usr/bin/env python 2 3r""" 4This script will parse the input error log yaml file and generate 5a header file which will then be used by the error logging client and 6server to collect and validate the error information generated by the 7openbmc software components. 8 9This code uses a mako template to provide the basic template of the header 10file we're going to generate. We then call it with information from the 11yaml to generate the header file. 12 13""" 14 15from mako.template import Template 16from optparse import OptionParser 17import yaml 18import sys 19import os 20 21 22def get_cpp_type(i_type): 23 typeMap = { 24 'int16': 'int16_t', 25 'int32': 'int32_t', 26 'int64': 'int64_t', 27 'uint16': 'uint16_t', 28 'uint32': 'uint32_t', 29 'uint64': 'uint64_t', 30 'double': 'double', 31 # const char* aids usage of constexpr 32 'string': 'const char*'} 33 34 return typeMap[i_type] 35 36 37def gen_elog_hpp(i_rootdir, i_elog_yaml, i_elog_meta_yaml, 38 i_input_mako, i_output_hpp): 39 r""" 40 Read the input yaml file, grab the relevant data and call the mako 41 template to generate the header file. 42 43 Description of arguments: 44 i_rootdir base directory to search for yaml files 45 i_elog_yaml yaml file describing the error logs 46 i_elog_meta_yaml yaml file describing the meta data for elogs 47 i_input_mako input mako template file to use 48 i_output_hpp header file to output the generated code to 49 """ 50 51 # Input parameters to mako template 52 errors = dict() # Main error codes 53 error_msg = dict() # Error msg that corresponds to error code 54 error_lvl = dict() # Error code log level (debug, info, error, ...) 55 meta = list() # The meta data names associated (ERRNO, FILE_NAME, ...) 56 meta_data = dict() # The meta data info (type, format) 57 58 # see elog.yaml for reference 59 ifile = yaml.safe_load(open("/".join((i_rootdir, i_elog_yaml)))) 60 mfile = yaml.safe_load(open(i_elog_meta_yaml)) 61 err_count = 0 62 for i in ifile: 63 match = None 64 # Find the corresponding meta data for this entry 65 for m in mfile: 66 if m['name'] == i['name']: 67 match = m 68 break 69 if (match is None): 70 print "Error - Did not find meta data for " + i['name'] 71 exit(1) 72 # Grab the main error and it's info 73 errors[err_count] = i['name'] 74 error_msg[i['name']] = i['description'] 75 error_lvl[i['name']] = match['level'] 76 tmp_meta = [] 77 # grab all the meta data fields and info 78 for j in match['meta']: 79 str_short = j['str'].split('=')[0] 80 tmp_meta.append(str_short) 81 meta_data[str_short] = {} 82 meta_data[str_short]['str'] = j['str'] 83 meta_data[str_short]['str_short'] = str_short 84 meta_data[str_short]['type'] = get_cpp_type(j['type']) 85 meta.append(tmp_meta) 86 err_count += 1 87 88 # Debug 89 # for i in errors: 90 # print "ERROR: " + errors[i] 91 # print " MSG: " + error_msg[errors[i]] 92 # print " LVL: " + error_lvl[errors[i]] 93 # print " META: " 94 # print meta[i] 95 96 # Load the mako template and call it with the required data 97 mytemplate = Template(filename=i_input_mako) 98 f = open(i_output_hpp, 'w') 99 f.write(mytemplate.render(errors=errors, error_msg=error_msg, 100 error_lvl=error_lvl, meta=meta, 101 meta_data=meta_data, elog_yaml=i_elog_yaml)) 102 f.close() 103 104 105def main(i_args): 106 parser = OptionParser() 107 108 parser.add_option("-e", "--elog", dest="elog_yaml", 109 default="xyz/openbmc_project/Example/Elog.errors.yaml", 110 help="input error yaml file to parse") 111 112 parser.add_option("-m", "--mako", dest="elog_mako", 113 default="elog-gen-template.mako.hpp", 114 help="input mako template file to use") 115 116 parser.add_option("-o", "--output", dest="output_hpp", 117 default="elog-gen.hpp", 118 help="output hpp to generate, elog-gen.hpp is default") 119 120 parser.add_option("-r", "--rootdir", dest="rootdir", 121 default="example", 122 help="Base directory of yaml files to process") 123 124 parser.add_option("-t", "--templatedir", dest="templatedir", 125 default="phosphor-logging/templates/", 126 help="Base directory of files to process") 127 128 (options, args) = parser.parse_args(i_args) 129 130 # Verify the input yaml file 131 yaml_path = "/".join((options.rootdir, options.elog_yaml)) 132 if (not (os.path.isfile(yaml_path))): 133 print "Can not find input yaml file " + yaml_path 134 exit(1) 135 136 # the meta data will be defined in a similar file name where we replace 137 # <Interface>.errors.yaml with <Interface>.metadata.yaml 138 meta_file = options.elog_yaml.replace("errors", "metadata") 139 meta_file = "/".join((options.rootdir, meta_file)) 140 if (not (os.path.isfile(meta_file))): 141 print "Can not find meta yaml file " + meta_file 142 exit(1) 143 144 # Verify the input mako file 145 template_path = "/".join((options.templatedir, options.elog_mako)) 146 if (not (os.path.isfile(template_path))): 147 print "Can not find input template file " + template_path 148 exit(1) 149 150 gen_elog_hpp(options.rootdir, 151 options.elog_yaml, 152 meta_file, 153 template_path, 154 options.output_hpp) 155 156# Only run if it's a script 157if __name__ == '__main__': 158 main(sys.argv[1:]) 159