]> Git Repo - u-boot.git/blob - tools/expo.py
Merge tag 'u-boot-at91-2023.10-a' of https://source.denx.de/u-boot/custodians/u-boot...
[u-boot.git] / tools / expo.py
1 #!/usr/bin/env python3
2 # SPDX-License-Identifier: GPL-2.0+
3
4 """
5 Expo utility - used for testing of expo features
6
7 Copyright 2023 Google LLC
8 Written by Simon Glass <[email protected]>
9 """
10
11 import argparse
12 import collections
13 import io
14 import re
15 import subprocess
16 import sys
17
18 #from u_boot_pylib import cros_subprocess
19 from u_boot_pylib import tools
20
21 # Parse:
22 #       SCENE1          = 7,
23 # or    SCENE2,
24 RE_ENUM = re.compile(r'(\S*)(\s*= (\d))?,')
25
26 # Parse #define <name>  "string"
27 RE_DEF = re.compile(r'#define (\S*)\s*"(.*)"')
28
29 def calc_ids(fname):
30     """Figure out the value of the enums in a C file
31
32     Args:
33         fname (str): Filename to parse
34
35     Returns:
36         OrderedDict():
37             key (str): enum name
38             value (int or str):
39                 Value of enum, if int
40                 Value of #define, if string
41     """
42     vals = collections.OrderedDict()
43     with open(fname, 'r', encoding='utf-8') as inf:
44         in_enum = False
45         cur_id = 0
46         for line in inf.readlines():
47             line = line.strip()
48             if line == 'enum {':
49                 in_enum = True
50                 continue
51             if in_enum and line == '};':
52                 in_enum = False
53
54             if in_enum:
55                 if not line or line.startswith('/*'):
56                     continue
57                 m_enum = RE_ENUM.match(line)
58                 if m_enum.group(3):
59                     cur_id = int(m_enum.group(3))
60                 vals[m_enum.group(1)] = cur_id
61                 cur_id += 1
62             else:
63                 m_def = RE_DEF.match(line)
64                 if m_def:
65                     vals[m_def.group(1)] = tools.to_bytes(m_def.group(2))
66
67     return vals
68
69
70 def run_expo(args):
71     """Run the expo program"""
72     fname = args.enum_fname or args.layout
73     ids = calc_ids(fname)
74     if not ids:
75         print(f"Warning: No enum ID values found in file '{fname}'")
76
77     indata = tools.read_file(args.layout)
78
79     outf = io.BytesIO()
80
81     for name, val in ids.items():
82         if isinstance(val, int):
83             outval = b'%d' % val
84         else:
85             outval = b'"%s"' % val
86         find_str = r'\b%s\b' % name
87         indata = re.sub(tools.to_bytes(find_str), outval, indata)
88
89     outf.write(indata)
90     data = outf.getvalue()
91
92     with open('/tmp/asc', 'wb') as outf:
93         outf.write(data)
94     proc = subprocess.run('dtc', input=data, capture_output=True)
95     edtb = proc.stdout
96     if proc.stderr:
97         print(f"Devicetree compiler error:\n{proc.stderr.decode('utf-8')}")
98         return 1
99     tools.write_file(args.outfile, edtb)
100     return 0
101
102
103 def parse_args(argv):
104     """Parse the command-line arguments
105
106     Args:
107         argv (list of str): List of string arguments
108
109     Returns:
110         tuple: (options, args) with the command-line options and arugments.
111             options provides access to the options (e.g. option.debug)
112             args is a list of string arguments
113     """
114     parser = argparse.ArgumentParser()
115     parser.add_argument('-D', '--debug', action='store_true',
116         help='Enable full debug traceback')
117     parser.add_argument('-e', '--enum-fname', type=str,
118         help='.dts or C file containing enum declaration for expo items')
119     parser.add_argument('-l', '--layout', type=str, required=True,
120         help='Devicetree file source .dts for expo layout (and perhaps enums)')
121     parser.add_argument('-o', '--outfile', type=str, required=True,
122         help='Filename to write expo layout dtb')
123
124     return parser.parse_args(argv)
125
126 def start_expo():
127     """Start the expo program"""
128     args = parse_args(sys.argv[1:])
129
130     if not args.debug:
131         sys.tracebacklimit = 0
132
133     ret_code = run_expo(args)
134     sys.exit(ret_code)
135
136
137 if __name__ == "__main__":
138     start_expo()
This page took 0.034344 seconds and 4 git commands to generate.