yu.dong | c33b307 | 2024-08-21 23:14:49 -0700 | [diff] [blame] | 1 | #!/usr/bin/env python |
| 2 | # -*- coding: utf-8 -*- |
| 3 | import re |
| 4 | import os |
| 5 | import json |
| 6 | import shlex |
| 7 | import logging |
| 8 | import argparse |
| 9 | import string |
| 10 | import traceback |
| 11 | class ParserState(): |
| 12 | EXPECT_DEFAULT='init' |
| 13 | DEFAULT = '\[default\]' |
| 14 | MDTYPE= '\[modem_type\]' |
| 15 | READ_LEVEL = '\[read_level\]' |
| 16 | CLASS = '\[class\]' |
| 17 | STRING= '\[string\]' |
| 18 | STRING_CONTENT= 'string content' |
| 19 | MESSAGE='\[message\]' |
| 20 | |
| 21 | parserState = ParserState.DEFAULT |
| 22 | default = [] |
| 23 | legacyParams = {} |
| 24 | classes = [] |
| 25 | strings = [] |
| 26 | msgs = [] |
| 27 | traceFamily = '' |
| 28 | |
| 29 | def init_logger(log_filename): |
| 30 | logging.basicConfig(level=logging.DEBUG, |
| 31 | format='%(asctime)s %(name)-12s %(levelname)-8s %(message)s', |
| 32 | datefmt='%m-%d %H:%M:%S', |
| 33 | filename=log_filename) |
| 34 | console = logging.StreamHandler() |
| 35 | console.setLevel(logging.INFO) |
| 36 | formatter = logging.Formatter('%(name)-12s: %(levelname)-8s %(message)s') |
| 37 | console.setFormatter(formatter) |
| 38 | logging.getLogger('').addHandler(console) |
| 39 | #for line in map(lambda x: x.rstrip(), lines): |
| 40 | def parseTmd(tmd_file): |
| 41 | global default |
| 42 | global legacyParams |
| 43 | global classes |
| 44 | global strings |
| 45 | global msgs |
| 46 | global traceFamily |
| 47 | key = '' |
| 48 | parserState = ParserState.EXPECT_DEFAULT |
| 49 | logging.info('Processing {}'.format(tmd_file)) |
| 50 | file = open(tmd_file) |
| 51 | line = file.readline() |
| 52 | while line: |
| 53 | line = line.rstrip().lstrip() |
| 54 | logging.debug('[IO] State {}: line: {}'.format(parserState, line)) |
| 55 | if line == '' or line.startswith('//') or line.startswith('#'): |
| 56 | logging.debug('skip line comment or empty line') |
| 57 | line = file.readline() |
| 58 | continue |
| 59 | # state change |
| 60 | if re.match(ParserState.DEFAULT, line, re.IGNORECASE): |
| 61 | parserState = ParserState.DEFAULT |
| 62 | line = file.readline() |
| 63 | continue |
| 64 | elif re.match(ParserState.MDTYPE, line, re.IGNORECASE): |
| 65 | parserState = ParserState.MDTYPE |
| 66 | line = file.readline() |
| 67 | continue |
| 68 | elif re.match(ParserState.CLASS, line, re.IGNORECASE): |
| 69 | parserState = ParserState.CLASS |
| 70 | line = file.readline() |
| 71 | continue |
| 72 | elif re.match(ParserState.STRING, line, re.IGNORECASE): |
| 73 | parserState = ParserState.STRING |
| 74 | line = file.readline() |
| 75 | continue |
| 76 | elif re.match(ParserState.MESSAGE, line, re.IGNORECASE): |
| 77 | parserState = ParserState.MESSAGE |
| 78 | line = file.readline() |
| 79 | continue |
| 80 | # parse |
| 81 | if parserState == ParserState.DEFAULT: |
| 82 | default.append(line) |
| 83 | if line.startswith('L2_Buffer'): |
| 84 | traceFamily = 'L2' |
| 85 | logging.info('This is L2 TMD') |
| 86 | elif line.startswith('TCMFORCE') or line.startswith('TCMON'): |
| 87 | legacyParams.update({'codeSection': line}) |
| 88 | logging.info('codesection {}'.format(line)) |
| 89 | elif line.startswith('L2SRAMFORCE'): |
| 90 | legacyParams.update({'codeSection': line}) |
| 91 | logging.info('codesection {}'.format(line)) |
| 92 | elif line.startswith('MAX_ARG'): |
| 93 | legacyParams.update({'l2MaxArg': int(line.split()[1])}) |
| 94 | logging.info('MAX_ARG {}'.format(line.split()[1])) |
| 95 | elif line.startswith('L2_BUFFER_SETTING'): |
| 96 | legacyParams.update({'l2BufferSetting': line.split()[1]}) |
| 97 | logging.info('L2_BUF {}'.format(line.split()[1])) |
| 98 | if traceFamily is '': |
| 99 | traceFamily = 'L1' |
| 100 | logging.info('This is L1 TMD') |
| 101 | if 'l2MaxArg' not in legacyParams.keys() and traceFamily == 'L2': |
| 102 | legacyParams.update({'l2MaxArg': 4}) |
| 103 | if 'l2BufferSetting' not in legacyParams.keys() and traceFamily == 'L2': |
| 104 | legacyParams.update({'l2BufferSetting': 'L2_BUFFER_EL2'}) |
| 105 | logging.debug('Append defaultParams {}'.format(default)) |
| 106 | elif parserState == ParserState.MDTYPE: |
| 107 | legacyParams.update( { 'modemType': line } ) |
| 108 | logging.info('Update legacyParams {}'.format(legacyParams)) |
| 109 | elif parserState == ParserState.CLASS: |
| 110 | cls = re.split(r' |\t', line) |
| 111 | if len(cls) > 1: |
| 112 | if cls[0].endswith('_UH'): |
| 113 | debugLevel = 'Ultra-High' |
| 114 | if cls[0].endswith('_H'): |
| 115 | debugLevel = 'High' |
| 116 | if cls[0].endswith('_M'): |
| 117 | debugLevel = 'Medium' |
| 118 | if cls[0].endswith('_L'): |
| 119 | debugLevel = 'Low' |
| 120 | if cls[0].endswith('_UL'): |
| 121 | debugLevel = 'Ultra-Low' |
| 122 | else: |
| 123 | debugLevel = 'Ultra-Low' |
| 124 | _class = { cls[0]: {'tag': ['Baseline'], 'traceType': 'CoreDesign', 'debugLevel': debugLevel, 'filterDefaultValue' : cls[1].upper(), '_comment': 'filterDefaulValue is used in xl1sim, will be phased out later' } } |
| 125 | classes.append(_class) |
| 126 | logging.info('Append traceClassDef {}'.format(_class)) |
| 127 | else: |
| 128 | logging.error('Invalid Trace Class') |
| 129 | elif parserState == ParserState.STRING: |
| 130 | if line.startswith('"') or line.startswith(','): |
| 131 | allMatches = re.finditer(r'("(.*?)")(\s*,?)', line) |
| 132 | for match in allMatches: |
| 133 | strs.append(match.group(2)) |
| 134 | logging.debug('Append {} stringTranslationDef {}'.format(key, match.group(1))) |
| 135 | elif line.startswith('{'): |
| 136 | logging.info('Start Processing StringTranslation {}'.format(key)) |
| 137 | dictionary = {} |
| 138 | strs = [] |
| 139 | match = re.search(r'("(.*?)")(\s*,?)', line[1::]) |
| 140 | if match: |
| 141 | strs.append(match.group(2)) |
| 142 | logging.debug('Append {} stringTranslationDef {}'.format(key, match.group(1))) |
| 143 | elif line.startswith('}'): |
| 144 | logging.info('End Processing StringTranslation {}'.format(key)) |
| 145 | dictionary[key] = strs |
| 146 | strings.append(dictionary) |
| 147 | else: |
| 148 | key = line |
| 149 | elif parserState == ParserState.MESSAGE: |
| 150 | msg = shlex.split(line) |
| 151 | trc = {} |
| 152 | if len(msg) >= 4: |
| 153 | trc['traceHighlightOption'] = msg[0] |
| 154 | trc['traceClass'] = msg[-2] |
| 155 | trc['format'] = msg[-1] |
| 156 | if len(msg) == 5: |
| 157 | rep = re.sub(r'[\(|\)]', r'', msg[1]) |
| 158 | sep = string.split(rep, '/') |
| 159 | for par in sep: |
| 160 | if par == 'ex_force_l1': |
| 161 | trc['dhlReserved'] = par |
| 162 | elif par == 'ex_force_l2': |
| 163 | trc['dhlReserved'] = par |
| 164 | elif par == 'force_l1': |
| 165 | trc['dhlReserved'] = par |
| 166 | elif par == 'force_l2': |
| 167 | trc['dhlReserved'] = par |
| 168 | elif par == 'cond': |
| 169 | trc['traceDataPath'] = par |
| 170 | elif par == 'hw_cond': |
| 171 | trc['traceDataPath'] = par |
| 172 | elif par == 'on_demand': |
| 173 | trc['traceDataPath'] = par |
| 174 | elif par == 'non_smp': |
| 175 | trc['smpProperty'] = par |
| 176 | elif par == 'smp': |
| 177 | trc['smpProperty'] = par |
| 178 | _trc = { msg[2] : trc } |
| 179 | msgs.append(_trc) |
| 180 | logging.info('Append traceDef {}'.format(msg[2])) |
| 181 | logging.debug('Append traceDef {}'.format(_trc)) |
| 182 | elif len(msg) == 4: |
| 183 | _trc = { msg[1] : trc } |
| 184 | msgs.append(_trc) |
| 185 | logging.info('Append traceDef {}'.format(msg[1])) |
| 186 | logging.debug('Append traceDef {}'.format(_trc)) |
| 187 | else: |
| 188 | logging.warning('skip line') |
| 189 | line = file.readline() |
| 190 | def main(): |
| 191 | parser = argparse.ArgumentParser(description='TMD-UTMD', |
| 192 | formatter_class=argparse.ArgumentDefaultsHelpFormatter) |
| 193 | parser.add_argument("-v", action="version", version='1.0.0') |
| 194 | parser.add_argument("tmd_file", |
| 195 | help="input TMD file") |
| 196 | parser.add_argument("utmd_file", |
| 197 | help="output UTMD file") |
| 198 | parser.add_argument("-l", dest="log_file", |
| 199 | help="log file", |
| 200 | default='legacy-utmd.log', |
| 201 | action="store") |
| 202 | args = parser.parse_args() |
| 203 | if args.tmd_file is None: |
| 204 | parser.print_help() |
| 205 | quit() |
| 206 | if args.utmd_file is None: |
| 207 | parser.print_help() |
| 208 | quit() |
| 209 | init_logger(args.log_file) |
| 210 | tmp_filename = args.tmd_file + '.tmp' |
| 211 | os.system('cat {} |gcc -fpreprocessed -dD -E -P - > {}'.format(args.tmd_file, tmp_filename)) |
| 212 | parseTmd(tmp_filename) |
| 213 | j = json.dumps({'module':default[0], |
| 214 | 'legacyParameters': legacyParams, |
| 215 | 'stringTranslationDefs': strings, |
| 216 | 'traceClassDefs': classes, |
| 217 | 'traceDefs': msgs, |
| 218 | 'traceFamily': traceFamily |
| 219 | }, |
| 220 | sort_keys=True, |
| 221 | ensure_ascii=False, |
| 222 | indent=2 |
| 223 | ) |
| 224 | utmd_file = open(args.utmd_file, 'w') |
| 225 | utmd_file.write(j) |
| 226 | os.system('rm -f {}.tmp'.format(args.tmd_file)) |
| 227 | if __name__ == '__main__': |
| 228 | try: |
| 229 | main() |
| 230 | except: |
| 231 | logging.error('WTF') |
| 232 | traceback.print_exc(file=sys.stderr) |
| 233 | |