@@ -57,6 +57,7 @@ def _tokencollection() -> TokenCollection:
5757 TOK = TokenCollection ()
5858 TOK .add (r"#\[(?P<values>[^\]]+)\](?=\s*)" , "CONFIG_FLAG" )
5959 TOK .add (r"#define\s+(?P<name>[^\s]+)(?P<value>[^\r\n]*)" , "DEFINE" )
60+ TOK .add (r"#undef\s+(?P<name>[^\s]+)\s*" , "UNDEF" )
6061 TOK .add (r"#ifdef\s+(?P<name>[^\s]+)\s*" , "IFDEF" )
6162 TOK .add (r"#ifndef\s+(?P<name>[^\s]+)\s*" , "IFNDEF" )
6263 TOK .add (r"#else\s*" , "ELSE" )
@@ -154,6 +155,16 @@ def _constant(self, tokens: TokenConsumer) -> None:
154155
155156 self .cstruct .consts [match ["name" ]] = value
156157
158+ def _undef (self , tokens : TokenConsumer ) -> None :
159+ const = tokens .consume ()
160+ pattern = self .TOK .patterns [self .TOK .UNDEF ]
161+ match = pattern .match (const .value ).groupdict ()
162+
163+ if match ["name" ] in self .cstruct .consts :
164+ del self .cstruct .consts [match ["name" ]]
165+ else :
166+ raise ParserError (f"line { self ._lineno (const )} : constant { match ['name' ]!r} not defined" )
167+
157168 def _enum (self , tokens : TokenConsumer ) -> None :
158169 # We cheat with enums because the entire enum is in the token
159170 etok = tokens .consume ()
@@ -443,6 +454,8 @@ def parse(self, data: str) -> None:
443454 self ._config_flag (tokens )
444455 elif token == self .TOK .DEFINE :
445456 self ._constant (tokens )
457+ elif token == self .TOK .UNDEF :
458+ self ._undef (tokens )
446459 elif token == self .TOK .TYPEDEF :
447460 self ._typedef (tokens )
448461 elif token == self .TOK .STRUCT :
0 commit comments