From 226d79ad562b793533af350f5e6189833c524797 Mon Sep 17 00:00:00 2001 From: Alina Lenk Date: Mon, 27 May 2024 14:08:20 +0200 Subject: [PATCH 10/10] generate_enums.py: Add option to generate is-generic function See osdn #48792 Requested by Marko Lindqvist Signed-off-by: Alina Lenk --- gen_headers/generate_enums.py | 45 ++++++++++++++++++++++++++++++++--- 1 file changed, 42 insertions(+), 3 deletions(-) diff --git a/gen_headers/generate_enums.py b/gen_headers/generate_enums.py index 3ace220ec8..88d6b6797d 100755 --- a/gen_headers/generate_enums.py +++ b/gen_headers/generate_enums.py @@ -55,6 +55,10 @@ The following are supported: - generic Generate values with no name and the given identifier followed by their index (starting at 1) +- generic-check + (requires generic) + Generate a function "bool (enum value)" + that evaluates to TRUE iff the value is one of the generic values - bitwise - zero (requires bitwise) @@ -410,9 +414,15 @@ class Specenum: bitvector: "str | None" = None """The SPECENUM_BITVECTOR name, if given""" - values: "list[EnumValue]" + proper_values: "list[EnumValue]" """The values of this enum""" + generic_values: "list[EnumValue]" + """The generic values of this enum (e.g. user flags)""" + + generic_check: "str | None" = None + """The name of the is-generic function, if desired""" + def __init__(self, name: str, lines: typing.Iterable[str]): self.name = name @@ -450,6 +460,14 @@ class Specenum: if not generic_amount: raise ValueError(f"amount for option {option!r} of enum {self.name} must be positive") generic_prefix = mo_g.group(2) + elif option == "generic-check": + if self.generic_check: + raise ValueError(f"duplicate option {option!r} for enum {self.name}") + if not arg: + raise ValueError(f"option {option!r} for enum {self.name} requires an argument") + if not arg.isascii() or not arg.isidentifier(): + raise ValueError(f"malformed argument for option {option!r} of enum {self.name}") + self.generic_check = arg elif option == "bitwise": if self.bitwise: raise ValueError(f"duplicate option {option!r} for enum {self.name}") @@ -504,6 +522,8 @@ class Specenum: raise ValueError(f"option 'count' conflicts with option 'bitwise' for enum {self.name}") if self.bitvector and self.bitwise: raise ValueError(f"option 'bitvector' conflicts with option 'bitwise' for enum {self.name}") + if self.generic_check and not generic_amount: + raise ValueError(f"option 'generic-check' for enum {self.name} requires option 'generic'") # check sanity if self.zero is __class__.DEFAULT_ZERO and not self.prefix: @@ -511,13 +531,20 @@ class Specenum: if self.count is __class__.DEFAULT_COUNT and not self.prefix: raise ValueError(f"option 'count' for enum {self.name} requires an argument or option 'prefix'") - self.values = [ + self.proper_values = [ EnumValue.parse(line) for line in lines - ] + [ + ] + self.generic_values = [ EnumValue(generic_prefix + str(i), None) for i in range(1, generic_amount + 1) ] + @property + def values(self) -> "typing.Iterator[EnumValue]": + """All values of this enum, including generic ones""" + yield from self.proper_values + yield from self.generic_values + def code_parts(self) -> typing.Iterable[str]: """Yield code defining this enum""" yield f"""\ @@ -556,6 +583,18 @@ class Specenum: #include "specenum_gen.h" """ + if self.generic_check is not None: + # validity check means we know generic_values is not empty + assert self.generic_values + yield f"""\ + +static inline bool {self.generic_check}(enum {self.name} value) +{{ + return ((value >= {self.prefix}{self.generic_values[0].identifier}) + && (value <= {self.prefix}{self.generic_values[-1].identifier})); +}} +""" + class EnumsDefinition(typing.Iterable[Specenum]): """Represents an entire enums definition file""" -- 2.34.1