diff --git a/binding_generator.py b/binding_generator.py index 1efc5b4e..9697687f 100644 --- a/binding_generator.py +++ b/binding_generator.py @@ -51,11 +51,7 @@ virtual $RETVAL _##m_name($FUNCARGS) $CONST override; \\ def generate_wrappers(target): max_versions = 12 - txt = """ -#ifndef GDEXTENSION_WRAPPERS_GEN_H -#define GDEXTENSION_WRAPPERS_GEN_H - -""" + txt = "#pragma once" for i in range(max_versions + 1): txt += "\n/* Module Wrapper " + str(i) + " Arguments */\n" @@ -64,8 +60,6 @@ def generate_wrappers(target): txt += generate_mod_version(i, True, False) txt += generate_mod_version(i, True, True) - txt += "\n#endif\n" - with open(target, "w", encoding="utf-8") as f: f.write(txt) @@ -187,8 +181,7 @@ def generate_virtuals(target): max_versions = 12 txt = """/* THIS FILE IS GENERATED DO NOT EDIT */ -#ifndef GDEXTENSION_GDVIRTUAL_GEN_H -#define GDEXTENSION_GDVIRTUAL_GEN_H +#pragma once """ @@ -203,8 +196,6 @@ def generate_virtuals(target): txt += generate_virtual_version(i, True, False, True) txt += generate_virtual_version(i, True, True, True) - txt += "#endif // GDEXTENSION_GDVIRTUAL_GEN_H\n" - with open(target, "w", encoding="utf-8") as f: f.write(txt) @@ -364,11 +355,8 @@ def generate_builtin_bindings(api, output_dir, build_config): variant_size_source = [] add_header("variant_size.hpp", variant_size_source) - header_guard = "GODOT_CPP_VARIANT_SIZE_HPP" - variant_size_source.append(f"#ifndef {header_guard}") - variant_size_source.append(f"#define {header_guard}") + variant_size_source.append("#pragma once") variant_size_source.append(f'#define GODOT_CPP_VARIANT_SIZE {builtin_sizes["Variant"]}') - variant_size_source.append(f"#endif // ! {header_guard}") variant_size_file.write("\n".join(variant_size_source)) @@ -448,8 +436,7 @@ def generate_builtin_bindings(api, output_dir, build_config): builtin_header = [] add_header("builtin_types.hpp", builtin_header) - builtin_header.append("#ifndef GODOT_CPP_BUILTIN_TYPES_HPP") - builtin_header.append("#define GODOT_CPP_BUILTIN_TYPES_HPP") + builtin_header.append("#pragma once") builtin_header.append("") @@ -464,8 +451,6 @@ def generate_builtin_bindings(api, output_dir, build_config): builtin_header.append("") - builtin_header.append("#endif // ! GODOT_CPP_BUILTIN_TYPES_HPP") - builtin_header_file.write("\n".join(builtin_header)) # Create a header with bindings for builtin types. @@ -474,8 +459,7 @@ def generate_builtin_bindings(api, output_dir, build_config): builtin_binds = [] add_header("builtin_binds.hpp", builtin_binds) - builtin_binds.append("#ifndef GODOT_CPP_BUILTIN_BINDS_HPP") - builtin_binds.append("#define GODOT_CPP_BUILTIN_BINDS_HPP") + builtin_binds.append("#pragma once") builtin_binds.append("") builtin_binds.append("#include ") builtin_binds.append("") @@ -487,7 +471,6 @@ def generate_builtin_bindings(api, output_dir, build_config): builtin_binds.append(f"VARIANT_ENUM_CAST({builtin_api['name']}::{enum_api['name']});") builtin_binds.append("") - builtin_binds.append("#endif // ! GODOT_CPP_BUILTIN_BINDS_HPP") builtin_binds_file.write("\n".join(builtin_binds)) @@ -503,9 +486,7 @@ def generate_builtin_class_vararg_method_implements_header(builtin_classes): add_header("builtin_vararg_methods.hpp", result) - header_guard = "GODOT_CPP_BUILTIN_VARARG_METHODS_HPP" - result.append(f"#ifndef {header_guard}") - result.append(f"#define {header_guard}") + result.append("#pragma once") result.append("") for builtin_api in builtin_classes: if "methods" not in builtin_api: @@ -520,8 +501,6 @@ def generate_builtin_class_vararg_method_implements_header(builtin_classes): ) result.append("") - result.append(f"#endif // ! {header_guard}") - return "\n".join(result) @@ -531,12 +510,9 @@ def generate_builtin_class_header(builtin_api, size, used_classes, fully_used_cl class_name = builtin_api["name"] snake_class_name = camel_to_snake(class_name).upper() - header_guard = f"GODOT_CPP_{snake_class_name}_HPP" - add_header(f"{snake_class_name.lower()}.hpp", result) - result.append(f"#ifndef {header_guard}") - result.append(f"#define {header_guard}") + result.append("#pragma once") result.append("") result.append("#include ") @@ -965,8 +941,6 @@ def generate_builtin_class_header(builtin_api, size, used_classes, fully_used_cl result.append("") result.append("} // namespace godot") - result.append("") - result.append(f"#endif // ! {header_guard}") result.append("") return "\n".join(result) @@ -1498,9 +1472,7 @@ def generate_engine_classes_bindings(api, output_dir, use_template_get_node): result = [] add_header(f"{snake_struct_name}.hpp", result) - header_guard = f"GODOT_CPP_{snake_struct_name.upper()}_HPP" - result.append(f"#ifndef {header_guard}") - result.append(f"#define {header_guard}") + result.append("#pragma once") used_classes = [] expanded_format = native_struct["format"].replace("(", " ").replace(")", ";").replace(",", ";") @@ -1540,7 +1512,6 @@ def generate_engine_classes_bindings(api, output_dir, use_template_get_node): result.append("") result.append("} // namespace godot") result.append("") - result.append(f"#endif // ! {header_guard}") with header_filename.open("w+", encoding="utf-8") as header_file: header_file.write("\n".join(result)) @@ -1556,11 +1527,7 @@ def generate_engine_class_header(class_api, used_classes, fully_used_classes, us add_header(f"{snake_class_name.lower()}.hpp", result) - header_guard = f"GODOT_CPP_{snake_class_name}_HPP" - - result.append(f"#ifndef {header_guard}") - result.append(f"#define {header_guard}") - + result.append("#pragma once") result.append("") if len(fully_used_classes) > 0: @@ -1849,7 +1816,6 @@ def generate_engine_class_header(class_api, used_classes, fully_used_classes, us result.append("\t") result.append("") - result.append(f"#endif // ! {header_guard}") result.append("") return "\n".join(result) @@ -2051,9 +2017,7 @@ def generate_global_constants(api, output_dir): header_filename = include_gen_folder / "global_constants.hpp" - header_guard = "GODOT_CPP_GLOBAL_CONSTANTS_HPP" - header.append(f"#ifndef {header_guard}") - header.append(f"#define {header_guard}") + header.append("#pragma once") header.append("") header.append("#include ") header.append("") @@ -2083,7 +2047,6 @@ def generate_global_constants(api, output_dir): header.append("} // namespace godot") header.append("") - header.append(f"#endif // ! {header_guard}") with header_filename.open("w+", encoding="utf-8") as header_file: header_file.write("\n".join(header)) @@ -2099,9 +2062,7 @@ def generate_version_header(api, output_dir): header_file_path = include_gen_folder / header_filename - header_guard = "GODOT_CPP_VERSION_HPP" - header.append(f"#ifndef {header_guard}") - header.append(f"#define {header_guard}") + header.append("#pragma once") header.append("") header.append(f"#define GODOT_VERSION_MAJOR {api['header']['version_major']}") @@ -2110,8 +2071,6 @@ def generate_version_header(api, output_dir): header.append(f"#define GODOT_VERSION_STATUS \"{api['header']['version_status']}\"") header.append(f"#define GODOT_VERSION_BUILD \"{api['header']['version_build']}\"") - header.append("") - header.append(f"#endif // {header_guard}") header.append("") with header_file_path.open("w+", encoding="utf-8") as header_file: @@ -2132,9 +2091,7 @@ def generate_global_constant_binds(api, output_dir): header_filename = include_gen_folder / "global_constants_binds.hpp" - header_guard = "GODOT_CPP_GLOBAL_CONSTANTS_BINDS_HPP" - header.append(f"#ifndef {header_guard}") - header.append(f"#define {header_guard}") + header.append("#pragma once") header.append("") header.append("#include ") header.append("") @@ -2153,8 +2110,6 @@ def generate_global_constant_binds(api, output_dir): header.append("") - header.append(f"#endif // ! {header_guard}") - with header_filename.open("w+", encoding="utf-8") as header_file: header_file.write("\n".join(header)) @@ -2173,9 +2128,7 @@ def generate_utility_functions(api, output_dir): header_filename = include_gen_folder / "utility_functions.hpp" - header_guard = "GODOT_CPP_UTILITY_FUNCTIONS_HPP" - header.append(f"#ifndef {header_guard}") - header.append(f"#define {header_guard}") + header.append("#pragma once") header.append("") header.append("#include ") header.append("#include ") @@ -2214,7 +2167,6 @@ def generate_utility_functions(api, output_dir): header.append("") header.append("} // namespace godot") header.append("") - header.append(f"#endif // ! {header_guard}") with header_filename.open("w+", encoding="utf-8") as header_file: header_file.write("\n".join(header)) diff --git a/misc/scripts/header_guards.py b/misc/scripts/header_guards.py index c99c4220..63a6b75f 100644 --- a/misc/scripts/header_guards.py +++ b/misc/scripts/header_guards.py @@ -2,121 +2,82 @@ # -*- coding: utf-8 -*- import sys -from pathlib import Path if len(sys.argv) < 2: print("Invalid usage of header_guards.py, it should be called with a path to one or multiple files.") sys.exit(1) -HEADER_CHECK_OFFSET = 30 -HEADER_BEGIN_OFFSET = 31 -HEADER_END_OFFSET = -1 - changed = [] invalid = [] for file in sys.argv[1:]: - with open(file, "rt", encoding="utf-8", newline="\n") as f: + header_start = -1 + header_end = -1 + + with open(file.strip(), "rt", encoding="utf-8", newline="\n") as f: lines = f.readlines() - if len(lines) <= HEADER_BEGIN_OFFSET: - continue # Most likely a dummy file. + for idx, line in enumerate(lines): + sline = line.strip() - if lines[HEADER_CHECK_OFFSET].startswith("#import"): - continue # Early catch obj-c file. + if header_start < 0: + if sline == "": # Skip empty lines at the top. + continue - name = f"GODOT_{Path(file).name}".upper().replace(".", "_").replace("-", "_").replace(" ", "_") + if sline.startswith("/**********"): # Godot header starts this way. + header_start = idx + else: + header_end = 0 # There is no Godot header. + break + else: + if not sline.startswith(("*", "/*")): # Not in the Godot header anymore. + header_end = idx + 1 # The guard should be two lines below the Godot header. + break - HEADER_CHECK = f"#ifndef {name}\n" - HEADER_BEGIN = f"#define {name}\n" - HEADER_END = f"#endif // {name}\n" - - if ( - lines[HEADER_CHECK_OFFSET] == HEADER_CHECK - and lines[HEADER_BEGIN_OFFSET] == HEADER_BEGIN - and lines[HEADER_END_OFFSET] == HEADER_END - ): + if (HEADER_CHECK_OFFSET := header_end) < 0 or HEADER_CHECK_OFFSET >= len(lines): + invalid.append(file) + continue + + if lines[HEADER_CHECK_OFFSET].startswith("#pragma once"): + continue + + # Might be using legacy header guards. + HEADER_BEGIN_OFFSET = HEADER_CHECK_OFFSET + 1 + HEADER_END_OFFSET = len(lines) - 1 + + if HEADER_BEGIN_OFFSET >= HEADER_END_OFFSET: + invalid.append(file) continue - # Guards might exist but with the wrong names. if ( lines[HEADER_CHECK_OFFSET].startswith("#ifndef") and lines[HEADER_BEGIN_OFFSET].startswith("#define") and lines[HEADER_END_OFFSET].startswith("#endif") ): - lines[HEADER_CHECK_OFFSET] = HEADER_CHECK - lines[HEADER_BEGIN_OFFSET] = HEADER_BEGIN - lines[HEADER_END_OFFSET] = HEADER_END + lines[HEADER_CHECK_OFFSET] = "#pragma once" + lines[HEADER_BEGIN_OFFSET] = "\n" + lines.pop() with open(file, "wt", encoding="utf-8", newline="\n") as f: f.writelines(lines) changed.append(file) continue - header_check = -1 - header_begin = -1 - header_end = -1 - pragma_once = -1 - objc = False - - for idx, line in enumerate(lines): - if not line.startswith("#"): - continue - elif line.startswith("#ifndef") and header_check == -1: - header_check = idx - elif line.startswith("#define") and header_begin == -1: - header_begin = idx - elif line.startswith("#endif") and header_end == -1: - header_end = idx - elif line.startswith("#pragma once"): - pragma_once = idx - break - elif line.startswith("#import"): - objc = True + # Verify `#pragma once` doesn't exist at invalid location. + misplaced = False + for line in lines: + if line.startswith("#pragma once"): + misplaced = True break - if objc: + if misplaced: + invalid.append(file) continue - if pragma_once != -1: - lines.pop(pragma_once) - lines.insert(HEADER_CHECK_OFFSET, HEADER_CHECK) - lines.insert(HEADER_BEGIN_OFFSET, HEADER_BEGIN) - lines.append("\n") - lines.append(HEADER_END) - with open(file, "wt", encoding="utf-8", newline="\n") as f: - f.writelines(lines) - changed.append(file) - continue - - if header_check == -1 and header_begin == -1 and header_end == -1: - # Guards simply didn't exist - lines.insert(HEADER_CHECK_OFFSET, HEADER_CHECK) - lines.insert(HEADER_BEGIN_OFFSET, HEADER_BEGIN) - lines.append("\n") - lines.append(HEADER_END) - with open(file, "wt", encoding="utf-8", newline="\n") as f: - f.writelines(lines) - changed.append(file) - continue - - if header_check != -1 and header_begin != -1 and header_end != -1: - # All prepends "found", see if we can salvage this. - if header_check == header_begin - 1 and header_begin < header_end: - lines.pop(header_check) - lines.pop(header_begin - 1) - lines.pop(header_end - 2) - if lines[header_end - 3] == "\n": - lines.pop(header_end - 3) - lines.insert(HEADER_CHECK_OFFSET, HEADER_CHECK) - lines.insert(HEADER_BEGIN_OFFSET, HEADER_BEGIN) - lines.append("\n") - lines.append(HEADER_END) - with open(file, "wt", encoding="utf-8", newline="\n") as f: - f.writelines(lines) - changed.append(file) - continue - - invalid.append(file) + # Assume that we're simply missing a guard entirely. + lines.insert(HEADER_CHECK_OFFSET, "#pragma once\n\n") + with open(file, "wt", encoding="utf-8", newline="\n") as f: + f.writelines(lines) + changed.append(file) if changed: for file in changed: