#! /usr/bin/env python3 # # Copyright 2016 - 2025 gary@drinkingtea.net # # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. # import argparse import os import json import pathlib import sys def write_txt_file(path: str, txt: str): with open(path, "w") as f: f.write(txt) print(f'Wrote {path}') def file_to_hex(path: str, line_prefix: str) -> tuple[str, int]: with open(path, 'rb') as f: out = line_prefix data = f.read() i = 1 for b in data: out += f"{b:#0{4}x}," if i % 10 == 0: out += '\n\t' else: out += ' ' i += 1 return out[:-1], len(data) def file_to_cpp(path: str, cpp_name: str) -> tuple[str, str]: cpp = '' hpp = '' data, data_len = file_to_hex(path, "\t") cpp += f'\nstatic constexpr ox::Array {cpp_name}Data {{\n{data}\n}};\n' cpp += f'\nox::SpanView {cpp_name}() noexcept {{ return {cpp_name}Data; }}\n' hpp += f'\n[[nodiscard]]\nox::SpanView {cpp_name}() noexcept;\n' return cpp, hpp def proc_rsrc_file(rsrc_path: str):# Open and read the JSON file with open(rsrc_path, 'r') as file: data = json.load(file) base_path = pathlib.Path(rsrc_path).parent.absolute() if 'all_files' in data: all_files = data['all_files'] else: all_files = None if 'namespace' in data: namespace = data['namespace'] else: namespace = '' if len(namespace) > 0: push_ns = f'namespace {namespace} {{\n' pop_ns = '\n}\n' else: push_ns = '' pop_ns = '' cpp = '// Generated\n\n#include \n' cpp += '#include \n\n' hpp = '// Generated\n\n#include \n\n' cpp += push_ns hpp += push_ns all_files_func_decl = '' all_files_func = '' if all_files is not None: all_files_func_decl += f'\n[[nodiscard]]\nox::Vector> {all_files}() noexcept;\n' all_files_func += f'\nox::Vector> {all_files}() noexcept {{\n\treturn {{\n' for f in data['files']: if 'path' not in f: print('src file path missing', file=sys.stderr) sys.exit(1) path = f['path'] if 'cpp_name' not in f: print('var name missing', file=sys.stderr) sys.exit(1) cpp_name = f['cpp_name'] c, h = file_to_cpp(os.path.join(base_path, path), cpp_name) cpp += c if len(h) > 0: hpp += h if all_files is not None: all_files_func += f'\t\t{cpp_name}(),\n' cpp += all_files_func + '\t};\n}\n' hpp += all_files_func_decl cpp += pop_ns hpp += pop_ns write_txt_file(os.path.join(base_path, data['cpp']), cpp) if 'hpp' in data: write_txt_file(os.path.join(base_path, data['hpp']), hpp) def main() -> int: parser = argparse.ArgumentParser() parser.add_argument('--rsrc', help='path to file', required=True) args = parser.parse_args() proc_rsrc_file(args.rsrc) return 0 if __name__ == '__main__': try: err = main() sys.exit(err) except KeyboardInterrupt: sys.exit(1)