Files
email-tracker/external/duckdb/scripts/verify_enum_integrity.py
2025-10-24 19:21:19 -05:00

63 lines
2.2 KiB
Python

from cxxheaderparser.parser import CxxParser, ParserOptions
from cxxheaderparser.visitor import CxxVisitor
from cxxheaderparser.preprocessor import make_pcpp_preprocessor
from cxxheaderparser.parserstate import NamespaceBlockState
from cxxheaderparser.types import EnumDecl
import textwrap
import os
class Visitor:
def on_enum(self, state: NamespaceBlockState, cursor: EnumDecl) -> None:
enum_name = cursor.typename.segments[0].format()
if '<' in enum_name:
raise Exception(
"Enum '{}' is an anonymous enum, please name it\n".format(cursor.doxygen[3:] if cursor.doxygen else '')
)
enum_constants = dict()
for enum_const in cursor.values:
name = enum_const.name.format()
if enum_const.value is None:
raise Exception(f"Enum constant '{name}' in '{enum_name}' does not have an explicit value assignment.")
value = enum_const.value.format()
if value in enum_constants:
other_constant = enum_constants[value]
error = f"""
Enum '{enum_name}' contains a duplicate value:
Value {value} is defined for both '{other_constant}' and '{name}'
"""
error = textwrap.dedent(error)
raise Exception(error)
enum_constants[value] = name
print(f"Successfully verified the integrity of enum {enum_name} ({len(enum_constants)} entries)")
def __getattr__(self, name):
return lambda *args, **kwargs: True
def parse_enum(file_path):
# Create index
parser = CxxParser(
file_path,
None,
visitor=Visitor(),
options=ParserOptions(preprocessor=make_pcpp_preprocessor()),
)
parser.parse()
if __name__ == "__main__":
import argparse
parser = argparse.ArgumentParser(description="Parse a C header file and check enum integrity.")
parser.add_argument("file_path", type=str, help="Path to the C header file")
args = parser.parse_args()
file_path = args.file_path
if not os.path.exists(file_path):
raise Exception(f"Error: file '{file_path}' does not exist")
enum_dict = parse_enum(file_path)