diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 7c9046f067c..dd0ae1a7373 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -154,7 +154,6 @@ repos: language: python entry: python misc/scripts/header_guards.py files: \.(h|hpp|hh|hxx)$ - exclude: ^.*/(dummy|thread|platform_config|platform_gl)\.h$ - id: file-format name: file-format diff --git a/core/extension/make_interface_dumper.py b/core/extension/make_interface_dumper.py index af35688200c..6227c2efede 100644 --- a/core/extension/make_interface_dumper.py +++ b/core/extension/make_interface_dumper.py @@ -14,8 +14,7 @@ def run(target, source, env): g.write( """/* THIS FILE IS GENERATED DO NOT EDIT */ -#ifndef GDEXTENSION_INTERFACE_DUMP_H -#define GDEXTENSION_INTERFACE_DUMP_H +#pragma once #ifdef TOOLS_ENABLED @@ -49,7 +48,5 @@ class GDExtensionInterfaceDump { }; #endif // TOOLS_ENABLED - -#endif // GDEXTENSION_INTERFACE_DUMP_H """ ) diff --git a/core/extension/make_wrappers.py b/core/extension/make_wrappers.py index 665b6f0f91d..96936d8cf3b 100644 --- a/core/extension/make_wrappers.py +++ b/core/extension/make_wrappers.py @@ -119,10 +119,7 @@ def generate_ex_version(argcount, const=False, returns=False): def run(target, source, env): 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/* Extension Wrapper " + str(i) + " Arguments */\n" @@ -138,7 +135,5 @@ def run(target, source, env): txt += generate_mod_version(i, True, False) txt += generate_mod_version(i, True, True) - txt += "\n#endif\n" - with open(str(target[0]), "w", encoding="utf-8", newline="\n") as f: f.write(txt) diff --git a/core/object/make_virtuals.py b/core/object/make_virtuals.py index 13775ecdde0..37ccbe1cfc1 100644 --- a/core/object/make_virtuals.py +++ b/core/object/make_virtuals.py @@ -207,8 +207,7 @@ def run(target, source, env): max_versions = 12 txt = """/* THIS FILE IS GENERATED DO NOT EDIT */ -#ifndef GDVIRTUAL_GEN_H -#define GDVIRTUAL_GEN_H +#pragma once #include "core/object/script_instance.h" @@ -257,7 +256,5 @@ def run(target, source, env): txt += generate_version(i, True, False, False, True) txt += generate_version(i, True, True, False, True) - txt += "#endif // GDVIRTUAL_GEN_H\n" - with open(str(target[0]), "w", encoding="utf-8", newline="\n") as f: f.write(txt) diff --git a/gles3_builders.py b/gles3_builders.py index a9d735ae5b6..d7e9edee568 100644 --- a/gles3_builders.py +++ b/gles3_builders.py @@ -209,13 +209,11 @@ def build_gles3_header( defvariant = "" fd.write("/* WARNING, THIS FILE WAS GENERATED, DO NOT EDIT */\n") + fd.write("#pragma once\n") out_file_base = out_file out_file_base = out_file_base[out_file_base.rfind("/") + 1 :] out_file_base = out_file_base[out_file_base.rfind("\\") + 1 :] - out_file_ifdef = out_file_base.replace(".", "_").upper() - fd.write("#ifndef " + out_file_ifdef + class_suffix + "_GLES3\n") - fd.write("#define " + out_file_ifdef + class_suffix + "_GLES3\n") out_file_class = ( out_file_base.replace(".glsl.gen.h", "").title().replace("_", "").replace(".", "") + "Shader" + class_suffix @@ -580,8 +578,7 @@ def build_gles3_header( fd.write("\t}\n\n") - fd.write("};\n\n") - fd.write("#endif\n") + fd.write("};\n") def build_gles3_headers(target, source, env): diff --git a/glsl_builders.py b/glsl_builders.py index 98a274dd273..cac7f8636c6 100644 --- a/glsl_builders.py +++ b/glsl_builders.py @@ -106,7 +106,6 @@ def build_rd_header( out_file_base = out_file out_file_base = out_file_base[out_file_base.rfind("/") + 1 :] out_file_base = out_file_base[out_file_base.rfind("\\") + 1 :] - out_file_ifdef = out_file_base.replace(".", "_").upper() out_file_class = out_file_base.replace(".glsl.gen.h", "").title().replace("_", "").replace(".", "") + "ShaderRD" if header_data.compute_lines: @@ -125,8 +124,7 @@ def build_rd_header( # Intended curly brackets are doubled so f-string doesn't eat them up. shader_template = f"""/* WARNING, THIS FILE WAS GENERATED, DO NOT EDIT */ -#ifndef {out_file_ifdef}_RD -#define {out_file_ifdef}_RD +#pragma once #include "servers/rendering/renderer_rd/shader_rd.h" @@ -139,8 +137,6 @@ public: {body_content} }} }}; - -#endif """ with open(out_file, "w", encoding="utf-8", newline="\n") as fd: @@ -189,16 +185,13 @@ def build_raw_header( out_file_base = out_file.replace(".glsl.gen.h", "_shader_glsl") out_file_base = out_file_base[out_file_base.rfind("/") + 1 :] out_file_base = out_file_base[out_file_base.rfind("\\") + 1 :] - out_file_ifdef = out_file_base.replace(".", "_").upper() shader_template = f"""/* WARNING, THIS FILE WAS GENERATED, DO NOT EDIT */ -#ifndef {out_file_ifdef}_RAW_H -#define {out_file_ifdef}_RAW_H +#pragma once static const char {out_file_base}[] = {{ {to_raw_cstring(header_data.code)} }}; -#endif """ with open(out_file, "w", encoding="utf-8", newline="\n") as f: diff --git a/methods.py b/methods.py index f9d95a554a3..d2f4e38be23 100644 --- a/methods.py +++ b/methods.py @@ -1447,8 +1447,6 @@ def generate_copyright_header(filename: str) -> str: def generated_wrapper( path, # FIXME: type with `Union[str, Node, List[Node]]` when pytest conflicts are resolved guard: Optional[bool] = None, - prefix: str = "", - suffix: str = "", ) -> Generator[TextIOBase, None, None]: """ Wrapper class to automatically handle copyright headers and header guards @@ -1458,12 +1456,8 @@ def generated_wrapper( - `path`: The path of the file to be created. Can be passed a raw string, an isolated SCons target, or a full SCons target list. If a target list contains multiple entries, produces a warning & only creates the first entry. - - `guard`: Optional bool to determine if a header guard should be added. If - unassigned, header guards are determined by the file extension. - - `prefix`: Custom prefix to prepend to a header guard. Produces a warning if - provided a value when `guard` evaluates to `False`. - - `suffix`: Custom suffix to append to a header guard. Produces a warning if - provided a value when `guard` evaluates to `False`. + - `guard`: Optional bool to determine if `#pragma once` should be added. If + unassigned, the value is determined by file extension. """ # Handle unfiltered SCons target[s] passed as path. @@ -1480,35 +1474,19 @@ def generated_wrapper( path = str(path).replace("\\", "/") if guard is None: - guard = path.endswith((".h", ".hh", ".hpp", ".inc")) - if not guard and (prefix or suffix): - print_warning(f'Trying to assign header guard prefix/suffix while `guard` is disabled: "{path}".') - - header_guard = "" - if guard: - if prefix: - prefix += "_" - if suffix: - suffix = f"_{suffix}" - split = path.split("/")[-1].split(".") - header_guard = (f"{prefix}{split[0]}{suffix}.{'.'.join(split[1:])}".upper() - .replace(".", "_").replace("-", "_").replace(" ", "_").replace("__", "_")) # fmt: skip + guard = path.endswith((".h", ".hh", ".hpp", ".hxx", ".inc")) with open(path, "wt", encoding="utf-8", newline="\n") as file: file.write(generate_copyright_header(path)) file.write("\n/* THIS FILE IS GENERATED. EDITS WILL BE LOST. */\n\n") if guard: - file.write(f"#ifndef {header_guard}\n") - file.write(f"#define {header_guard}\n\n") + file.write("#pragma once\n\n") with StringIO(newline="\n") as str_io: yield str_io file.write(str_io.getvalue().strip() or "/* NO CONTENT */") - if guard: - file.write(f"\n\n#endif // {header_guard}") - file.write("\n") diff --git a/misc/scripts/char_range_fetch.py b/misc/scripts/char_range_fetch.py index fda8da37f08..d4b8ffed522 100755 --- a/misc/scripts/char_range_fetch.py +++ b/misc/scripts/char_range_fetch.py @@ -106,8 +106,7 @@ def generate_char_range_inc() -> None: source += f""" // This file was generated using the `misc/scripts/char_range_fetch.py` script. -#ifndef CHAR_RANGE_INC -#define CHAR_RANGE_INC +#pragma once #include "core/typedefs.h" @@ -125,8 +124,6 @@ struct CharRange {{ source += make_array("lowercase_letter", lowercase_letter) source += make_array("unicode_letter", unicode_letter) - source += "#endif // CHAR_RANGE_INC\n" - char_range_path: str = os.path.join(os.path.dirname(__file__), "../../core/string/char_range.inc") with open(char_range_path, "w", newline="\n") as f: f.write(source) diff --git a/misc/scripts/header_guards.py b/misc/scripts/header_guards.py index 4d4150a097b..63a6b75ff01 100755 --- a/misc/scripts/header_guards.py +++ b/misc/scripts/header_guards.py @@ -2,7 +2,6 @@ # -*- 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.") @@ -13,7 +12,7 @@ invalid = [] for file in sys.argv[1:]: header_start = -1 - HEADER_CHECK_OFFSET = -1 + header_end = -1 with open(file.strip(), "rt", encoding="utf-8", newline="\n") as f: lines = f.readlines() @@ -28,17 +27,21 @@ for file in sys.argv[1:]: if sline.startswith("/**********"): # Godot header starts this way. header_start = idx else: - HEADER_CHECK_OFFSET = 0 # There is no Godot header. + header_end = 0 # There is no Godot header. break else: - if not sline.startswith("*") and not sline.startswith("/*"): # Not in the Godot header anymore. - HEADER_CHECK_OFFSET = idx + 1 # The include should be two lines below the Godot header. + 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 - if HEADER_CHECK_OFFSET < 0: + 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 @@ -46,124 +49,35 @@ for file in sys.argv[1:]: invalid.append(file) continue - split = file.split("/") # Already in posix-format. - - prefix = "" - if split[0] == "modules" and split[-1] == "register_types.h": - prefix = f"{split[1]}_" # Name of module. - elif split[0] == "platform" and (file.endswith("api/api.h") or "/export/" in file): - prefix = f"{split[1]}_" # Name of platform. - elif file.startswith("modules/mono/utils") and "mono" not in split[-1]: - prefix = "MONO_" - elif file == "servers/rendering/storage/utilities.h": - prefix = "RENDERER_" - - suffix = "" - if "dummy" in file and "dummy" not in split[-1]: - suffix = "_DUMMY" - elif "gles3" in file and "gles3" not in split[-1]: - suffix = "_GLES3" - elif "renderer_rd" in file and "rd" not in split[-1]: - suffix = "_RD" - elif split[-1] == "ustring.h": - suffix = "_GODOT" - - name = (f"{prefix}{Path(file).stem}{suffix}{Path(file).suffix}".upper() - .replace(".", "_").replace("-", "_").replace(" ", "_")) # fmt: skip - - 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 - ): - 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 line.startswith("// #import"): # Some dummy obj-c files only have commented out import lines. - objc = True - break - 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: diff --git a/misc/scripts/ucaps_fetch.py b/misc/scripts/ucaps_fetch.py index 2aeaeed7621..8cdecc8727a 100755 --- a/misc/scripts/ucaps_fetch.py +++ b/misc/scripts/ucaps_fetch.py @@ -55,8 +55,7 @@ def generate_ucaps_fetch() -> None: source: str = generate_copyright_header("ucaps.h") source += f""" -#ifndef UCAPS_H -#define UCAPS_H +#pragma once // This file was generated using the `misc/scripts/ucaps_fetch.py` script. @@ -105,8 +104,6 @@ static int _find_lower(int ch) { \treturn ch; } - -#endif // UCAPS_H """ ucaps_path: str = os.path.join(os.path.dirname(__file__), "../../core/string/ucaps.h") diff --git a/platform/SCsub b/platform/SCsub index 248b4b88dd9..3e384347b05 100644 --- a/platform/SCsub +++ b/platform/SCsub @@ -18,7 +18,7 @@ def export_icon_builder(target, source, env): platform = src_path.parent.parent.stem with open(str(source[0]), "r") as file: svg = file.read() - with methods.generated_wrapper(target, prefix=platform) as file: + with methods.generated_wrapper(target) as file: file.write( f"""\ static const char *_{platform}_{src_name}_svg = {methods.to_raw_cstring(svg)}; diff --git a/tests/create_test.py b/tests/create_test.py index 9181cb3ac84..672d851e858 100755 --- a/tests/create_test.py +++ b/tests/create_test.py @@ -78,8 +78,7 @@ def main(): /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /**************************************************************************/ -#ifndef TEST_{name_upper_snake_case}_H -#define TEST_{name_upper_snake_case}_H +#pragma once #include "tests/test_macros.h" @@ -90,14 +89,11 @@ TEST_CASE("[{name_pascal_case}] Example test case") {{ }} }} // namespace Test{name_pascal_case} - -#endif // TEST_{name_upper_snake_case}_H """.format( name_snake_case=name_snake_case, # Capitalize the first letter but keep capitalization for the rest of the string. # This is done in case the user passes a camelCase string instead of PascalCase. name_pascal_case=args.name[0].upper() + args.name[1:], - name_upper_snake_case=name_snake_case.upper(), # The padding length depends on the test name length. padding=" " * (61 - len(name_snake_case)), ) diff --git a/tests/python_build/fixtures/gles3/vertex_fragment_expected_full.glsl b/tests/python_build/fixtures/gles3/vertex_fragment_expected_full.glsl index db5f54e3d8b..c0e8d5c43da 100644 --- a/tests/python_build/fixtures/gles3/vertex_fragment_expected_full.glsl +++ b/tests/python_build/fixtures/gles3/vertex_fragment_expected_full.glsl @@ -1,6 +1,5 @@ /* WARNING, THIS FILE WAS GENERATED, DO NOT EDIT */ -#ifndef VERTEX_FRAGMENT_GLSL_GEN_HGLES3_GLES3 -#define VERTEX_FRAGMENT_GLSL_GEN_HGLES3_GLES3 +#pragma once #include "drivers/gles3/shader_gles3.h" @@ -70,5 +69,3 @@ void main() { } }; - -#endif diff --git a/tests/python_build/fixtures/glsl/compute_expected_full.glsl b/tests/python_build/fixtures/glsl/compute_expected_full.glsl index 386d14f1aa2..310a4241e15 100644 --- a/tests/python_build/fixtures/glsl/compute_expected_full.glsl +++ b/tests/python_build/fixtures/glsl/compute_expected_full.glsl @@ -1,6 +1,5 @@ /* WARNING, THIS FILE WAS GENERATED, DO NOT EDIT */ -#ifndef COMPUTE_SHADER_GLSL_RAW_H -#define COMPUTE_SHADER_GLSL_RAW_H +#pragma once static const char compute_shader_glsl[] = { R"(#[compute] @@ -17,4 +16,3 @@ void main() { } )" }; -#endif diff --git a/tests/python_build/fixtures/glsl/vertex_fragment_expected_full.glsl b/tests/python_build/fixtures/glsl/vertex_fragment_expected_full.glsl index b7329b6a796..2ccc7daf4fe 100644 --- a/tests/python_build/fixtures/glsl/vertex_fragment_expected_full.glsl +++ b/tests/python_build/fixtures/glsl/vertex_fragment_expected_full.glsl @@ -1,6 +1,5 @@ /* WARNING, THIS FILE WAS GENERATED, DO NOT EDIT */ -#ifndef VERTEX_FRAGMENT_SHADER_GLSL_RAW_H -#define VERTEX_FRAGMENT_SHADER_GLSL_RAW_H +#pragma once static const char vertex_fragment_shader_glsl[] = { R"(#[versions] @@ -37,4 +36,3 @@ void main() { } )" }; -#endif diff --git a/tests/python_build/fixtures/rd_glsl/compute_expected_full.glsl b/tests/python_build/fixtures/rd_glsl/compute_expected_full.glsl index 1184510020e..7d4cdb43864 100644 --- a/tests/python_build/fixtures/rd_glsl/compute_expected_full.glsl +++ b/tests/python_build/fixtures/rd_glsl/compute_expected_full.glsl @@ -1,6 +1,5 @@ /* WARNING, THIS FILE WAS GENERATED, DO NOT EDIT */ -#ifndef COMPUTE_GLSL_GEN_H_RD -#define COMPUTE_GLSL_GEN_H_RD +#pragma once #include "servers/rendering/renderer_rd/shader_rd.h" @@ -28,5 +27,3 @@ void main() { setup(nullptr, nullptr, _compute_code, "ComputeShaderRD"); } }; - -#endif diff --git a/tests/python_build/fixtures/rd_glsl/vertex_fragment_expected_full.glsl b/tests/python_build/fixtures/rd_glsl/vertex_fragment_expected_full.glsl index 2f809f1bfe8..7e86dd73106 100644 --- a/tests/python_build/fixtures/rd_glsl/vertex_fragment_expected_full.glsl +++ b/tests/python_build/fixtures/rd_glsl/vertex_fragment_expected_full.glsl @@ -1,6 +1,5 @@ /* WARNING, THIS FILE WAS GENERATED, DO NOT EDIT */ -#ifndef VERTEX_FRAGMENT_GLSL_GEN_H_RD -#define VERTEX_FRAGMENT_GLSL_GEN_H_RD +#pragma once #include "servers/rendering/renderer_rd/shader_rd.h" @@ -42,5 +41,3 @@ void main() { setup(_vertex_code, _fragment_code, nullptr, "VertexFragmentShaderRD"); } }; - -#endif