From 084c78b035c11c078231e5215650f95b53d04348 Mon Sep 17 00:00:00 2001 From: Thaddeus Crews Date: Sat, 1 Feb 2025 10:11:55 -0600 Subject: [PATCH] Style: Integrate `#pragma once` in builders/checks --- .pre-commit-config.yaml | 7 ++- core/extension/make_interface_dumper.py | 5 +- core/extension/make_wrappers.py | 7 +-- core/object/make_virtuals.py | 5 +- gles3_builders.py | 7 +-- glsl_builders.py | 11 +--- methods.py | 30 ++------- misc/scripts/header_guards.py | 62 +++++-------------- misc/scripts/ucaps_fetch.py | 5 +- platform/SCsub | 2 +- tests/create_test.py | 6 +- .../gles3/vertex_fragment_expected_full.glsl | 5 +- .../fixtures/glsl/compute_expected_full.glsl | 4 +- .../glsl/vertex_fragment_expected_full.glsl | 4 +- .../rd_glsl/compute_expected_full.glsl | 5 +- .../vertex_fragment_expected_full.glsl | 5 +- 16 files changed, 40 insertions(+), 130 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 5627d7500397..f6d858ce30c1 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -154,7 +154,12 @@ repos: language: python entry: python misc/scripts/header_guards.py files: \.(h|hpp|hh|hxx)$ - exclude: ^.*/(dummy|thread|platform_config|platform_gl)\.h$ + exclude: | + (?x)^( + drivers/(apple|coreaudio|coremidi|metal)/.*| + misc/dist/ios_xcode/.*| + platform/(ios|macos)/(?!platform_(config|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 af35688200ce..6227c2efede4 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 665b6f0f91d5..96936d8cf3b0 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 13775ecdde07..37ccbe1cfc19 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 a9d735ae5b6a..d7e9edee5684 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 98a274dd2738..cac7f8636c61 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 @@ class {out_file_class} : public ShaderRD {{ {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 85fdf1978fb1..babcd6bcdb88 100644 --- a/methods.py +++ b/methods.py @@ -1451,8 +1451,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 @@ -1462,12 +1460,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. @@ -1484,35 +1478,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/header_guards.py b/misc/scripts/header_guards.py index 4d4150a097b7..d4787617f5c0 100755 --- a/misc/scripts/header_guards.py +++ b/misc/scripts/header_guards.py @@ -80,6 +80,12 @@ and lines[HEADER_BEGIN_OFFSET] == HEADER_BEGIN and 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 # Guards might exist but with the wrong names. @@ -88,9 +94,9 @@ 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) @@ -99,70 +105,32 @@ header_check = -1 header_begin = -1 header_end = -1 - pragma_once = -1 - objc = False + skip = 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(("#import", "#pragma once")): + skip = True + break 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 - break - if objc: - 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) + if skip: 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) + 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) 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) if changed: diff --git a/misc/scripts/ucaps_fetch.py b/misc/scripts/ucaps_fetch.py index 2aeaeed76212..8cdecc8727a0 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 @@ def generate_ucaps_fetch() -> None: \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 248b4b88dd91..3e384347b05d 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 9181cb3ac847..672d851e858e 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 @@ def main(): }} }} // 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 db5f54e3d8b7..c0e8d5c43da3 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 386d14f1aa25..310a4241e150 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 b7329b6a796b..2ccc7daf4feb 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 1184510020e3..7d4cdb438646 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 2f809f1bfe81..7e86dd731063 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