| #!/usr/bin/env python |
| # -*- coding: utf-8 -*- |
| import re |
| import os |
| import json |
| import shlex |
| import logging |
| import argparse |
| import string |
| import traceback |
| class ParserState(): |
| EXPECT_DEFAULT='init' |
| DEFAULT = '\[default\]' |
| MDTYPE= '\[modem_type\]' |
| READ_LEVEL = '\[read_level\]' |
| CLASS = '\[class\]' |
| STRING= '\[string\]' |
| STRING_CONTENT= 'string content' |
| MESSAGE='\[message\]' |
| |
| parserState = ParserState.DEFAULT |
| default = [] |
| legacyParams = {} |
| classes = [] |
| strings = [] |
| msgs = [] |
| traceFamily = '' |
| |
| def init_logger(log_filename): |
| logging.basicConfig(level=logging.DEBUG, |
| format='%(asctime)s %(name)-12s %(levelname)-8s %(message)s', |
| datefmt='%m-%d %H:%M:%S', |
| filename=log_filename) |
| console = logging.StreamHandler() |
| console.setLevel(logging.INFO) |
| formatter = logging.Formatter('%(name)-12s: %(levelname)-8s %(message)s') |
| console.setFormatter(formatter) |
| logging.getLogger('').addHandler(console) |
| #for line in map(lambda x: x.rstrip(), lines): |
| def parseTmd(tmd_file): |
| global default |
| global legacyParams |
| global classes |
| global strings |
| global msgs |
| global traceFamily |
| key = '' |
| parserState = ParserState.EXPECT_DEFAULT |
| logging.info('Processing {}'.format(tmd_file)) |
| file = open(tmd_file) |
| line = file.readline() |
| while line: |
| line = line.rstrip().lstrip() |
| logging.debug('[IO] State {}: line: {}'.format(parserState, line)) |
| if line == '' or line.startswith('//') or line.startswith('#'): |
| logging.debug('skip line comment or empty line') |
| line = file.readline() |
| continue |
| # state change |
| if re.match(ParserState.DEFAULT, line, re.IGNORECASE): |
| parserState = ParserState.DEFAULT |
| line = file.readline() |
| continue |
| elif re.match(ParserState.MDTYPE, line, re.IGNORECASE): |
| parserState = ParserState.MDTYPE |
| line = file.readline() |
| continue |
| elif re.match(ParserState.CLASS, line, re.IGNORECASE): |
| parserState = ParserState.CLASS |
| line = file.readline() |
| continue |
| elif re.match(ParserState.STRING, line, re.IGNORECASE): |
| parserState = ParserState.STRING |
| line = file.readline() |
| continue |
| elif re.match(ParserState.MESSAGE, line, re.IGNORECASE): |
| parserState = ParserState.MESSAGE |
| line = file.readline() |
| continue |
| # parse |
| if parserState == ParserState.DEFAULT: |
| default.append(line) |
| if line.startswith('L2_Buffer'): |
| traceFamily = 'L2' |
| logging.info('This is L2 TMD') |
| elif line.startswith('TCMFORCE') or line.startswith('TCMON'): |
| legacyParams.update({'codeSection': line}) |
| logging.info('codesection {}'.format(line)) |
| elif line.startswith('L2SRAMFORCE'): |
| legacyParams.update({'codeSection': line}) |
| logging.info('codesection {}'.format(line)) |
| elif line.startswith('MAX_ARG'): |
| legacyParams.update({'l2MaxArg': int(line.split()[1])}) |
| logging.info('MAX_ARG {}'.format(line.split()[1])) |
| elif line.startswith('L2_BUFFER_SETTING'): |
| legacyParams.update({'l2BufferSetting': line.split()[1]}) |
| logging.info('L2_BUF {}'.format(line.split()[1])) |
| if traceFamily is '': |
| traceFamily = 'L1' |
| logging.info('This is L1 TMD') |
| if 'l2MaxArg' not in legacyParams.keys() and traceFamily == 'L2': |
| legacyParams.update({'l2MaxArg': 4}) |
| if 'l2BufferSetting' not in legacyParams.keys() and traceFamily == 'L2': |
| legacyParams.update({'l2BufferSetting': 'L2_BUFFER_EL2'}) |
| logging.debug('Append defaultParams {}'.format(default)) |
| elif parserState == ParserState.MDTYPE: |
| legacyParams.update( { 'modemType': line } ) |
| logging.info('Update legacyParams {}'.format(legacyParams)) |
| elif parserState == ParserState.CLASS: |
| cls = re.split(r' |\t', line) |
| if len(cls) > 1: |
| if cls[0].endswith('_UH'): |
| debugLevel = 'Ultra-High' |
| if cls[0].endswith('_H'): |
| debugLevel = 'High' |
| if cls[0].endswith('_M'): |
| debugLevel = 'Medium' |
| if cls[0].endswith('_L'): |
| debugLevel = 'Low' |
| if cls[0].endswith('_UL'): |
| debugLevel = 'Ultra-Low' |
| else: |
| debugLevel = 'Ultra-Low' |
| _class = { cls[0]: {'tag': ['Baseline'], 'traceType': 'CoreDesign', 'debugLevel': debugLevel, 'filterDefaultValue' : cls[1].upper(), '_comment': 'filterDefaulValue is used in xl1sim, will be phased out later' } } |
| classes.append(_class) |
| logging.info('Append traceClassDef {}'.format(_class)) |
| else: |
| logging.error('Invalid Trace Class') |
| elif parserState == ParserState.STRING: |
| if line.startswith('"') or line.startswith(','): |
| allMatches = re.finditer(r'("(.*?)")(\s*,?)', line) |
| for match in allMatches: |
| strs.append(match.group(2)) |
| logging.debug('Append {} stringTranslationDef {}'.format(key, match.group(1))) |
| elif line.startswith('{'): |
| logging.info('Start Processing StringTranslation {}'.format(key)) |
| dictionary = {} |
| strs = [] |
| match = re.search(r'("(.*?)")(\s*,?)', line[1::]) |
| if match: |
| strs.append(match.group(2)) |
| logging.debug('Append {} stringTranslationDef {}'.format(key, match.group(1))) |
| elif line.startswith('}'): |
| logging.info('End Processing StringTranslation {}'.format(key)) |
| dictionary[key] = strs |
| strings.append(dictionary) |
| else: |
| key = line |
| elif parserState == ParserState.MESSAGE: |
| msg = shlex.split(line) |
| trc = {} |
| if len(msg) >= 4: |
| trc['traceHighlightOption'] = msg[0] |
| trc['traceClass'] = msg[-2] |
| trc['format'] = msg[-1] |
| if len(msg) == 5: |
| rep = re.sub(r'[\(|\)]', r'', msg[1]) |
| sep = string.split(rep, '/') |
| for par in sep: |
| if par == 'ex_force_l1': |
| trc['dhlReserved'] = par |
| elif par == 'ex_force_l2': |
| trc['dhlReserved'] = par |
| elif par == 'force_l1': |
| trc['dhlReserved'] = par |
| elif par == 'force_l2': |
| trc['dhlReserved'] = par |
| elif par == 'cond': |
| trc['traceDataPath'] = par |
| elif par == 'hw_cond': |
| trc['traceDataPath'] = par |
| elif par == 'on_demand': |
| trc['traceDataPath'] = par |
| elif par == 'non_smp': |
| trc['smpProperty'] = par |
| elif par == 'smp': |
| trc['smpProperty'] = par |
| _trc = { msg[2] : trc } |
| msgs.append(_trc) |
| logging.info('Append traceDef {}'.format(msg[2])) |
| logging.debug('Append traceDef {}'.format(_trc)) |
| elif len(msg) == 4: |
| _trc = { msg[1] : trc } |
| msgs.append(_trc) |
| logging.info('Append traceDef {}'.format(msg[1])) |
| logging.debug('Append traceDef {}'.format(_trc)) |
| else: |
| logging.warning('skip line') |
| line = file.readline() |
| def main(): |
| parser = argparse.ArgumentParser(description='TMD-UTMD', |
| formatter_class=argparse.ArgumentDefaultsHelpFormatter) |
| parser.add_argument("-v", action="version", version='1.0.0') |
| parser.add_argument("tmd_file", |
| help="input TMD file") |
| parser.add_argument("utmd_file", |
| help="output UTMD file") |
| parser.add_argument("-l", dest="log_file", |
| help="log file", |
| default='legacy-utmd.log', |
| action="store") |
| args = parser.parse_args() |
| if args.tmd_file is None: |
| parser.print_help() |
| quit() |
| if args.utmd_file is None: |
| parser.print_help() |
| quit() |
| init_logger(args.log_file) |
| tmp_filename = args.tmd_file + '.tmp' |
| os.system('cat {} |gcc -fpreprocessed -dD -E -P - > {}'.format(args.tmd_file, tmp_filename)) |
| parseTmd(tmp_filename) |
| j = json.dumps({'module':default[0], |
| 'legacyParameters': legacyParams, |
| 'stringTranslationDefs': strings, |
| 'traceClassDefs': classes, |
| 'traceDefs': msgs, |
| 'traceFamily': traceFamily |
| }, |
| sort_keys=True, |
| ensure_ascii=False, |
| indent=2 |
| ) |
| utmd_file = open(args.utmd_file, 'w') |
| utmd_file.write(j) |
| os.system('rm -f {}.tmp'.format(args.tmd_file)) |
| if __name__ == '__main__': |
| try: |
| main() |
| except: |
| logging.error('WTF') |
| traceback.print_exc(file=sys.stderr) |
| |