Browse Source

Style: Integrate `#pragma once` in builders/checks

Thaddeus Crews 5 months ago
parent
commit
107cb1da5e
2 changed files with 59 additions and 146 deletions
  1. 13 61
      binding_generator.py
  2. 46 85
      misc/scripts/header_guards.py

+ 13 - 61
binding_generator.py

@@ -51,11 +51,7 @@ virtual $RETVAL _##m_name($FUNCARGS) $CONST override; \\
 def generate_wrappers(target):
 def generate_wrappers(target):
     max_versions = 12
     max_versions = 12
 
 
-    txt = """
-#ifndef GDEXTENSION_WRAPPERS_GEN_H
-#define GDEXTENSION_WRAPPERS_GEN_H
-
-"""
+    txt = "#pragma once"
 
 
     for i in range(max_versions + 1):
     for i in range(max_versions + 1):
         txt += "\n/* Module Wrapper " + str(i) + " Arguments */\n"
         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, False)
         txt += generate_mod_version(i, True, True)
         txt += generate_mod_version(i, True, True)
 
 
-    txt += "\n#endif\n"
-
     with open(target, "w", encoding="utf-8") as f:
     with open(target, "w", encoding="utf-8") as f:
         f.write(txt)
         f.write(txt)
 
 
@@ -187,8 +181,7 @@ def generate_virtuals(target):
     max_versions = 12
     max_versions = 12
 
 
     txt = """/* THIS FILE IS GENERATED DO NOT EDIT */
     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, False, True)
         txt += generate_virtual_version(i, True, True, 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:
     with open(target, "w", encoding="utf-8") as f:
         f.write(txt)
         f.write(txt)
 
 
@@ -359,11 +350,8 @@ def generate_builtin_bindings(api, output_dir, build_config):
         variant_size_source = []
         variant_size_source = []
         add_header("variant_size.hpp", 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'#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))
         variant_size_file.write("\n".join(variant_size_source))
 
 
@@ -443,8 +431,7 @@ def generate_builtin_bindings(api, output_dir, build_config):
         builtin_header = []
         builtin_header = []
         add_header("builtin_types.hpp", 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("")
         builtin_header.append("")
 
 
@@ -459,8 +446,6 @@ def generate_builtin_bindings(api, output_dir, build_config):
 
 
         builtin_header.append("")
         builtin_header.append("")
 
 
-        builtin_header.append("#endif // ! GODOT_CPP_BUILTIN_TYPES_HPP")
-
         builtin_header_file.write("\n".join(builtin_header))
         builtin_header_file.write("\n".join(builtin_header))
 
 
     # Create a header with bindings for builtin types.
     # Create a header with bindings for builtin types.
@@ -469,8 +454,7 @@ def generate_builtin_bindings(api, output_dir, build_config):
         builtin_binds = []
         builtin_binds = []
         add_header("builtin_binds.hpp", 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("")
         builtin_binds.append("#include <godot_cpp/variant/builtin_types.hpp>")
         builtin_binds.append("#include <godot_cpp/variant/builtin_types.hpp>")
         builtin_binds.append("")
         builtin_binds.append("")
@@ -482,7 +466,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(f"VARIANT_ENUM_CAST({builtin_api['name']}::{enum_api['name']});")
 
 
         builtin_binds.append("")
         builtin_binds.append("")
-        builtin_binds.append("#endif // ! GODOT_CPP_BUILTIN_BINDS_HPP")
 
 
         builtin_binds_file.write("\n".join(builtin_binds))
         builtin_binds_file.write("\n".join(builtin_binds))
 
 
@@ -498,9 +481,7 @@ def generate_builtin_class_vararg_method_implements_header(builtin_classes):
 
 
     add_header("builtin_vararg_methods.hpp", result)
     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("")
     result.append("")
     for builtin_api in builtin_classes:
     for builtin_api in builtin_classes:
         if "methods" not in builtin_api:
         if "methods" not in builtin_api:
@@ -515,8 +496,6 @@ def generate_builtin_class_vararg_method_implements_header(builtin_classes):
             )
             )
             result.append("")
             result.append("")
 
 
-    result.append(f"#endif // ! {header_guard}")
-
     return "\n".join(result)
     return "\n".join(result)
 
 
 
 
@@ -526,12 +505,9 @@ def generate_builtin_class_header(builtin_api, size, used_classes, fully_used_cl
     class_name = builtin_api["name"]
     class_name = builtin_api["name"]
     snake_class_name = camel_to_snake(class_name).upper()
     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)
     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("")
     result.append("#include <godot_cpp/core/defs.hpp>")
     result.append("#include <godot_cpp/core/defs.hpp>")
@@ -960,8 +936,6 @@ def generate_builtin_class_header(builtin_api, size, used_classes, fully_used_cl
     result.append("")
     result.append("")
     result.append("} // namespace godot")
     result.append("} // namespace godot")
 
 
-    result.append("")
-    result.append(f"#endif // ! {header_guard}")
     result.append("")
     result.append("")
 
 
     return "\n".join(result)
     return "\n".join(result)
@@ -1493,9 +1467,7 @@ def generate_engine_classes_bindings(api, output_dir, use_template_get_node):
         result = []
         result = []
         add_header(f"{snake_struct_name}.hpp", 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 = []
         used_classes = []
         expanded_format = native_struct["format"].replace("(", " ").replace(")", ";").replace(",", ";")
         expanded_format = native_struct["format"].replace("(", " ").replace(")", ";").replace(",", ";")
@@ -1535,7 +1507,6 @@ def generate_engine_classes_bindings(api, output_dir, use_template_get_node):
         result.append("")
         result.append("")
         result.append("} // namespace godot")
         result.append("} // namespace godot")
         result.append("")
         result.append("")
-        result.append(f"#endif // ! {header_guard}")
 
 
         with header_filename.open("w+", encoding="utf-8") as header_file:
         with header_filename.open("w+", encoding="utf-8") as header_file:
             header_file.write("\n".join(result))
             header_file.write("\n".join(result))
@@ -1551,11 +1522,7 @@ def generate_engine_class_header(class_api, used_classes, fully_used_classes, us
 
 
     add_header(f"{snake_class_name.lower()}.hpp", result)
     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("")
     result.append("")
 
 
     if len(fully_used_classes) > 0:
     if len(fully_used_classes) > 0:
@@ -1844,7 +1811,6 @@ def generate_engine_class_header(class_api, used_classes, fully_used_classes, us
         result.append("\t")
         result.append("\t")
         result.append("")
         result.append("")
 
 
-    result.append(f"#endif // ! {header_guard}")
     result.append("")
     result.append("")
 
 
     return "\n".join(result)
     return "\n".join(result)
@@ -2046,9 +2012,7 @@ def generate_global_constants(api, output_dir):
 
 
     header_filename = include_gen_folder / "global_constants.hpp"
     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("")
     header.append("#include <cstdint>")
     header.append("#include <cstdint>")
     header.append("")
     header.append("")
@@ -2078,7 +2042,6 @@ def generate_global_constants(api, output_dir):
     header.append("} // namespace godot")
     header.append("} // namespace godot")
 
 
     header.append("")
     header.append("")
-    header.append(f"#endif // ! {header_guard}")
 
 
     with header_filename.open("w+", encoding="utf-8") as header_file:
     with header_filename.open("w+", encoding="utf-8") as header_file:
         header_file.write("\n".join(header))
         header_file.write("\n".join(header))
@@ -2094,9 +2057,7 @@ def generate_version_header(api, output_dir):
 
 
     header_file_path = include_gen_folder / header_filename
     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("")
 
 
     header.append(f"#define GODOT_VERSION_MAJOR {api['header']['version_major']}")
     header.append(f"#define GODOT_VERSION_MAJOR {api['header']['version_major']}")
@@ -2105,8 +2066,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_STATUS \"{api['header']['version_status']}\"")
     header.append(f"#define GODOT_VERSION_BUILD \"{api['header']['version_build']}\"")
     header.append(f"#define GODOT_VERSION_BUILD \"{api['header']['version_build']}\"")
 
 
-    header.append("")
-    header.append(f"#endif // {header_guard}")
     header.append("")
     header.append("")
 
 
     with header_file_path.open("w+", encoding="utf-8") as header_file:
     with header_file_path.open("w+", encoding="utf-8") as header_file:
@@ -2127,9 +2086,7 @@ def generate_global_constant_binds(api, output_dir):
 
 
     header_filename = include_gen_folder / "global_constants_binds.hpp"
     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("")
     header.append("#include <godot_cpp/classes/global_constants.hpp>")
     header.append("#include <godot_cpp/classes/global_constants.hpp>")
     header.append("")
     header.append("")
@@ -2148,8 +2105,6 @@ def generate_global_constant_binds(api, output_dir):
 
 
     header.append("")
     header.append("")
 
 
-    header.append(f"#endif // ! {header_guard}")
-
     with header_filename.open("w+", encoding="utf-8") as header_file:
     with header_filename.open("w+", encoding="utf-8") as header_file:
         header_file.write("\n".join(header))
         header_file.write("\n".join(header))
 
 
@@ -2168,9 +2123,7 @@ def generate_utility_functions(api, output_dir):
 
 
     header_filename = include_gen_folder / "utility_functions.hpp"
     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("")
     header.append("#include <godot_cpp/variant/builtin_types.hpp>")
     header.append("#include <godot_cpp/variant/builtin_types.hpp>")
     header.append("#include <godot_cpp/variant/variant.hpp>")
     header.append("#include <godot_cpp/variant/variant.hpp>")
@@ -2209,7 +2162,6 @@ def generate_utility_functions(api, output_dir):
     header.append("")
     header.append("")
     header.append("} // namespace godot")
     header.append("} // namespace godot")
     header.append("")
     header.append("")
-    header.append(f"#endif // ! {header_guard}")
 
 
     with header_filename.open("w+", encoding="utf-8") as header_file:
     with header_filename.open("w+", encoding="utf-8") as header_file:
         header_file.write("\n".join(header))
         header_file.write("\n".join(header))

+ 46 - 85
misc/scripts/header_guards.py

@@ -2,121 +2,82 @@
 # -*- coding: utf-8 -*-
 # -*- coding: utf-8 -*-
 
 
 import sys
 import sys
-from pathlib import Path
 
 
 if len(sys.argv) < 2:
 if len(sys.argv) < 2:
     print("Invalid usage of header_guards.py, it should be called with a path to one or multiple files.")
     print("Invalid usage of header_guards.py, it should be called with a path to one or multiple files.")
     sys.exit(1)
     sys.exit(1)
 
 
-HEADER_CHECK_OFFSET = 30
-HEADER_BEGIN_OFFSET = 31
-HEADER_END_OFFSET = -1
-
 changed = []
 changed = []
 invalid = []
 invalid = []
 
 
 for file in sys.argv[1:]:
 for file in sys.argv[1:]:
-    with open(file, "rt", encoding="utf-8", newline="\n") as f:
-        lines = f.readlines()
+    header_start = -1
+    header_end = -1
 
 
-    if len(lines) <= HEADER_BEGIN_OFFSET:
-        continue  # Most likely a dummy file.
+    with open(file.strip(), "rt", encoding="utf-8", newline="\n") as f:
+        lines = f.readlines()
 
 
-    if lines[HEADER_CHECK_OFFSET].startswith("#import"):
-        continue  # Early catch obj-c file.
+    for idx, line in enumerate(lines):
+        sline = line.strip()
+
+        if header_start < 0:
+            if sline == "":  # Skip empty lines at the top.
+                continue
+
+            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
+
+    if (HEADER_CHECK_OFFSET := header_end) < 0 or HEADER_CHECK_OFFSET >= len(lines):
+        invalid.append(file)
+        continue
 
 
-    name = f"GODOT_{Path(file).name}".upper().replace(".", "_").replace("-", "_").replace(" ", "_")
+    if lines[HEADER_CHECK_OFFSET].startswith("#pragma once"):
+        continue
 
 
-    HEADER_CHECK = f"#ifndef {name}\n"
-    HEADER_BEGIN = f"#define {name}\n"
-    HEADER_END = f"#endif // {name}\n"
+    # Might be using legacy header guards.
+    HEADER_BEGIN_OFFSET = HEADER_CHECK_OFFSET + 1
+    HEADER_END_OFFSET = len(lines) - 1
 
 
-    if (
-        lines[HEADER_CHECK_OFFSET] == HEADER_CHECK
-        and lines[HEADER_BEGIN_OFFSET] == HEADER_BEGIN
-        and lines[HEADER_END_OFFSET] == HEADER_END
-    ):
+    if HEADER_BEGIN_OFFSET >= HEADER_END_OFFSET:
+        invalid.append(file)
         continue
         continue
 
 
-    # Guards might exist but with the wrong names.
     if (
     if (
         lines[HEADER_CHECK_OFFSET].startswith("#ifndef")
         lines[HEADER_CHECK_OFFSET].startswith("#ifndef")
         and lines[HEADER_BEGIN_OFFSET].startswith("#define")
         and lines[HEADER_BEGIN_OFFSET].startswith("#define")
         and lines[HEADER_END_OFFSET].startswith("#endif")
         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:
         with open(file, "wt", encoding="utf-8", newline="\n") as f:
             f.writelines(lines)
             f.writelines(lines)
         changed.append(file)
         changed.append(file)
         continue
         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
+    # Verify `#pragma once` doesn't exist at invalid location.
+    misplaced = False
+    for line in lines:
+        if line.startswith("#pragma once"):
+            misplaced = True
             break
             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)
-        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)
+    if misplaced:
+        invalid.append(file)
         continue
         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:
 if changed:
     for file in changed:
     for file in changed: