diff options
Diffstat (limited to 'tools/expo.py')
| -rwxr-xr-x | tools/expo.py | 130 | 
1 files changed, 130 insertions, 0 deletions
| diff --git a/tools/expo.py b/tools/expo.py new file mode 100755 index 00000000000..c6eb87aec73 --- /dev/null +++ b/tools/expo.py @@ -0,0 +1,130 @@ +#!/usr/bin/env python3 +# SPDX-License-Identifier: GPL-2.0+ + +""" +Expo utility - used for testing of expo features + +Copyright 2023 Google LLC +Written by Simon Glass <sjg@chromium.org> +""" + +import argparse +import collections +import io +import re +import subprocess +import sys + +#from u_boot_pylib import cros_subprocess +from u_boot_pylib import tools + +# Parse: +#	SCENE1		= 7, +# or	SCENE2, +RE_ENUM = re.compile(r'(\S*)(\s*= (\d))?,') + +# Parse #define <name>  "string" +RE_DEF = re.compile(r'#define (\S*)\s*"(.*)"') + +def calc_ids(fname): +    """Figure out the value of the enums in a C file + +    Args: +        fname (str): Filename to parse + +    Returns: +        OrderedDict(): +            key (str): enum name +            value (int or str): +                Value of enum, if int +                Value of #define, if string +    """ +    vals = collections.OrderedDict() +    with open(fname, 'r', encoding='utf-8') as inf: +        in_enum = False +        cur_id = 0 +        for line in inf.readlines(): +            line = line.strip() +            if line == 'enum {': +                in_enum = True +                continue +            if in_enum and line == '};': +                in_enum = False + +            if in_enum: +                if not line or line.startswith('/*'): +                    continue +                m_enum = RE_ENUM.match(line) +                if m_enum.group(3): +                    cur_id = int(m_enum.group(3)) +                vals[m_enum.group(1)] = cur_id +                cur_id += 1 +            else: +                m_def = RE_DEF.match(line) +                if m_def: +                    vals[m_def.group(1)] = tools.to_bytes(m_def.group(2)) + +    return vals + + +def run_expo(args): +    """Run the expo program""" +    ids = calc_ids(args.enum_fname) + +    indata = tools.read_file(args.layout) + +    outf = io.BytesIO() + +    for name, val in ids.items(): +        if isinstance(val, int): +            outval = b'%d' % val +        else: +            outval = b'"%s"' % val +        find_str = r'\b%s\b' % name +        indata = re.sub(tools.to_bytes(find_str), outval, indata) + +    outf.write(indata) +    data = outf.getvalue() + +    with open('/tmp/asc', 'wb') as outf: +        outf.write(data) +    proc = subprocess.run('dtc', input=data, capture_output=True, check=True) +    edtb = proc.stdout +    if proc.stderr: +        print(proc.stderr) +        return 1 +    tools.write_file(args.outfile, edtb) +    return 0 + + +def parse_args(argv): +    """Parse the command-line arguments + +    Args: +        argv (list of str): List of string arguments + +    Returns: +        tuple: (options, args) with the command-line options and arugments. +            options provides access to the options (e.g. option.debug) +            args is a list of string arguments +    """ +    parser = argparse.ArgumentParser() +    parser.add_argument('-e', '--enum-fname', type=str, +        help='C file containing enum declaration for expo items') +    parser.add_argument('-l', '--layout', type=str, +        help='Devicetree file source .dts for expo layout') +    parser.add_argument('-o', '--outfile', type=str, +        help='Filename to write expo layout dtb') + +    return parser.parse_args(argv) + +def start_expo(): +    """Start the expo program""" +    args = parse_args(sys.argv[1:]) + +    ret_code = run_expo(args) +    sys.exit(ret_code) + + +if __name__ == "__main__": +    start_expo() | 
