diff options
author | Jakub Kicinski <kuba@kernel.org> | 2023-08-24 14:24:31 -0700 |
---|---|---|
committer | Jakub Kicinski <kuba@kernel.org> | 2023-08-25 18:56:48 -0700 |
commit | a02430c06f56931675f19a914b11a960607b2505 (patch) | |
tree | 1c1d9f35fbe0312b0161120354e5644a8f1b055e /tools/net | |
parent | f5e17b471fa88e1e6b430c5df383a04c8caf3707 (diff) |
tools: ynl-gen: fix uAPI generation after tempfile changes
We use a tempfile for code generation, to avoid wiping the target
file out if the code generator crashes. File contents are copied
from tempfile to actual destination at the end of main().
uAPI generation is relatively simple so when generating the uAPI
header we return from main() early, and never reach the "copy code
over" stage. Since commit under Fixes uAPI headers are not updated
by ynl-gen.
Move the copy/commit of the code into CodeWriter, to make it
easier to call at any point in time. Hook it into the destructor
to make sure we don't miss calling it.
Fixes: f65f305ae008 ("tools: ynl-gen: use temporary file for rendering")
Link: https://lore.kernel.org/r/20230824212431.1683612-1-kuba@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Diffstat (limited to 'tools/net')
-rwxr-xr-x | tools/net/ynl/ynl-gen-c.py | 30 |
1 files changed, 20 insertions, 10 deletions
diff --git a/tools/net/ynl/ynl-gen-c.py b/tools/net/ynl/ynl-gen-c.py index 9209bdcca9c6..897af958cee8 100755 --- a/tools/net/ynl/ynl-gen-c.py +++ b/tools/net/ynl/ynl-gen-c.py @@ -1045,14 +1045,30 @@ class RenderInfo: class CodeWriter: - def __init__(self, nlib, out_file): + def __init__(self, nlib, out_file=None): self.nlib = nlib self._nl = False self._block_end = False self._silent_block = False self._ind = 0 - self._out = out_file + if out_file is None: + self._out = os.sys.stdout + else: + self._out = tempfile.TemporaryFile('w+') + self._out_file = out_file + + def __del__(self): + self.close_out_file() + + def close_out_file(self): + if self._out == os.sys.stdout: + return + with open(self._out_file, 'w+') as out_file: + self._out.seek(0) + shutil.copyfileobj(self._out, out_file) + self._out.close() + self._out = os.sys.stdout @classmethod def _is_cond(cls, line): @@ -2313,11 +2329,9 @@ def main(): parser.add_argument('--source', dest='header', action='store_false') parser.add_argument('--user-header', nargs='+', default=[]) parser.add_argument('--exclude-op', action='append', default=[]) - parser.add_argument('-o', dest='out_file', type=str) + parser.add_argument('-o', dest='out_file', type=str, default=None) args = parser.parse_args() - tmp_file = tempfile.TemporaryFile('w+') if args.out_file else os.sys.stdout - if args.header is None: parser.error("--header or --source is required") @@ -2341,7 +2355,7 @@ def main(): print(f'Message enum-model {parsed.msg_id_model} not supported for {args.mode} generation') os.sys.exit(1) - cw = CodeWriter(BaseNlLib(), tmp_file) + cw = CodeWriter(BaseNlLib(), args.out_file) _, spec_kernel = find_kernel_root(args.spec) if args.mode == 'uapi' or args.header: @@ -2590,10 +2604,6 @@ def main(): if args.header: cw.p(f'#endif /* {hdr_prot} */') - if args.out_file: - out_file = open(args.out_file, 'w+') - tmp_file.seek(0) - shutil.copyfileobj(tmp_file, out_file) if __name__ == "__main__": main() |