class Cpp_If_Stmt(WORDClsBase): ''' C99 6.10.1 Conditional inclusion if-stmt is # if constant-expression new-line or ifdef identifier new-line or ifndef identifier new-line ''' subclass_names = [] use_names = ['Cpp_Macro_Identifier', 'Cpp_Pp_Tokens'] _regex = re.compile(r"#\s*(ifdef|ifndef|if)\b") _if_pattern = pattern.Pattern('<if>', r'^\s*#\s*if\b', value='#if') _def_pattern = (pattern.Pattern('<ifdef>', r'^\s*#\s*ifdef\b', value='#ifdef'), pattern.Pattern('<ifndef>', r'^\s*#\s*ifndef\b', value='#ifndef')) @staticmethod def match(string): '''Implements the matching for an if preprocessor directive (or its variations ifdef, ifndef). For ifdef and ifndef statements it matches the macro identifier using :py:class:`fparser.two.C99Preprocesser.Cpp_Macro_Identifier` otherwise it uses :py:class:`fparser.two.C99Preprocessor.Cpp_Pp_Tokens` to accept any non-empty string as rhs. :param str string: the string to match with as an if statement. :return: a tuple of size 2 containing the statement's keyword \ and the right hand side, or `None` if there is no match. :rtype: \ (`str`, py:class:`fparser.two.C99Preprocessor.Cpp_Macro_Identifier`)\ or (`str`, py:class:`fparser.two.C99Preprocessor.Cpp_Pp_Tokens`) \ or `NoneType` ''' if not string: return None result = WORDClsBase.match(Cpp_If_Stmt._if_pattern, Cpp_Pp_Tokens, string, colons=False, require_cls=True) return result or WORDClsBase.match(Cpp_If_Stmt._def_pattern, Cpp_Macro_Identifier, string, colons=False, require_cls=True) def tostr(self): ''' :return: this if-stmt as a string. :rtype: str ''' return '{0} {1}'.format(*self.items)
class Cpp_Endif_Stmt(StringBase): ''' C99 6.10.1 Conditional inclusion endif-stmt is # endif new-line ''' subclass_names = [] _pattern = pattern.Pattern('<endif>', r'^\s*#\s*endif\b', value='#endif') @staticmethod def match(string): '''Implements the matching for an endif preprocessor directive. :param str string: the string to match with as an endif statement. :return: a 1-tuple containing the matched string or `None` if \ there is no match. :rtype: (str,) or NoneType ''' if not string: return None return StringBase.match(Cpp_Endif_Stmt._pattern, string) def tostr(self): ''' :return: this endif-stmt as a string. :rtype: str ''' return self.string
class Cpp_Warning_Stmt(WORDClsBase): ''' Not actually part of C99 but supported by most preprocessors and with syntax identical to Cpp_Error_Stmt warning-stmt is # warning [pp-tokens] new-line ''' subclass_names = [] use_names = ['Cpp_Pp_Tokens'] _pattern = pattern.Pattern('<warning>', r'^\s*#\s*warning\b', value='#warning') @staticmethod def match(string): '''Implements the matching for a warning preprocessor directive. The optional right hand side of the directive is not matched any further but simply kept as a string. :param str string: the string to match with as a line statement. :return: an empty tuple or a tuple of size 1 with the right hand \ side as a string, or `None` if there is no match. :rtype: () or (`str`) or `NoneType` ''' if not string: return None return WORDClsBase.match(Cpp_Warning_Stmt._pattern, Cpp_Pp_Tokens, string, colons=False, require_cls=False) def tostr(self): ''' :return: this warning-stmt as a string. :rtype: str ''' if self.items[1]: return '{0} {1}'.format(*self.items) return self.items[0]
class Cpp_Undef_Stmt(WORDClsBase): '''Implements the matching of a preprocessor undef statement for a macro. undef-stmt is # undef identifier new-line Strictly, this is part of 6.10.3 but since it is identified by a different directive keyword (undef instead of define) we treat it separately. ''' subclass_names = [] use_names = ['Cpp_Macro_Identifier'] _pattern = pattern.Pattern('<undef>', r'^\s*(#\s*undef)\b', value='#undef') @staticmethod def match(string): '''Implements the matching for a preprocessor undef statement for a macro. The macro identifier is matched using :py:class:`fparser.two.C99Preprocessor.Cpp_Macro_Identifier`. :param str string: the string to match with as an if statement. :return: a tuple of size 1 containing the macro identifier, or\ `None` if there is no match. :rtype: (py:class:`fparser.two.C99Preprocessor.Cpp_Macro_Identifier`) \ or `NoneType` ''' if not string: return None return WORDClsBase.match(Cpp_Undef_Stmt._pattern, Cpp_Macro_Identifier, string, colons=False, require_cls=True) def tostr(self): ''' :return: this undef-stmt as a string. :rtype: str ''' return '{0} {1}'.format(*self.items)
class Cpp_Macro_Identifier_List(StringBase): '''Implements the matching of an identifier list in a macro definition. identifier-list is (identifier [, identifier-list or ...]) or (...) ''' subclass_names = [] _pattern = pattern.Pattern( '<identifier-list>', r'\((\s*[A-Za-z_]\w*' r'(?:\s*,\s*[A-Za-z_]\w*)*' r'(?:\s*,\s*\.{3})?|\.{3})?\s*\)') @staticmethod def match(string): '''Implements the matching of a macro identifier list as part of a macro definition. It must consist of one or more macro identifier separated by comma, or "..." for a variadic argument list, and must be surrouned by parentheses. For simplicity, the matched list is kept as a single string and not matched as :py:class:`fparser.two.C99Preprocessor.Cpp_Macro_Identifier`. :param str string: the string to match with the pattern rule. :return: a tuple of size 1 containing a string with the \ matched identifier list if there is a match, or None if \ there is not. :rtype: (`str`,) or `NoneType` ''' if not string: return None return StringBase.match(Cpp_Macro_Identifier_List._pattern, string) def tostr(self): ''' :return: this macro-identifier-list as a string. :rtype: str ''' return self.string
class Cpp_Error_Stmt(WORDClsBase): # 6.10.5 Error directive ''' C99 6.10.5 Error directive error-stmt is # error [pp-tokens] new-line ''' subclass_names = [] use_names = ['Cpp_Pp_Tokens'] _pattern = pattern.Pattern('<error>', r'^\s*#\s*error\b', value='#error') @staticmethod def match(string): '''Implements the matching for an error preprocessor directive. The optional right hand side of the directive is not matched any further but simply kept as a string. :param str string: the string to match with as a line statement. :return: an empty tuple or a tuple of size 1 with the right hand \ side as a string, or `None` if there is no match. :rtype: () or (`str`) or `NoneType` ''' if not string: return None return WORDClsBase.match(Cpp_Error_Stmt._pattern, Cpp_Pp_Tokens, string, colons=False, require_cls=False) def tostr(self): ''' :return: this error-stmt as a string. :rtype: str ''' if self.items[1]: return '{0} {1}'.format(*self.items) return self.items[0]
class Cpp_Line_Stmt(WORDClsBase): # 6.10.4 Line control ''' C99 6.10.4 Line control line-stmt is # line digit-sequence [ "s-char-sequence" ] new-line or pp-tokens new-line ''' subclass_names = [] use_names = ['Cpp_Pp_Tokens'] _pattern = pattern.Pattern('<line>', r'^\s*#\s*line\b', value='#line') @staticmethod def match(string): '''Implements the matching for a line preprocessor directive. The right hand side of the directive is not matched any further but simply kept as a string. :param str string: the string to match with as a line statement. :return: a tuple of size 1 with the right hand side as a string, \ or `None` if there is no match. :rtype: (`str`) or `NoneType` ''' if not string: return None return WORDClsBase.match(Cpp_Line_Stmt._pattern, Cpp_Pp_Tokens, string, colons=False, require_cls=True) def tostr(self): ''' :return: this line-stmt as a string. :rtype: str ''' return '{0} {1}'.format(*self.items)
class Cpp_Elif_Stmt(WORDClsBase): ''' C99 6.10.1 Conditional inclusion elif-stmt is # elif constant-expression new-line ''' subclass_names = [] use_names = ['Cpp_Pp_Tokens'] _pattern = pattern.Pattern('<elif-stmt>', r'^\s*#\s*elif\b', value='#elif') @staticmethod def match(string): '''Implements the matching for an elif preprocessor directive. :param str string: the string to match with as an elif statement. :return: a tuple of size 2 containing the statements keyword and \ right hand side, or `None` if there is no match. :rtype: \ (`str`, :py:class:`fparser.two.C99_Preprocessor.Cpp_Pp_Tokens`) \ or `NoneType` ''' if not string: return None return WORDClsBase.match(Cpp_Elif_Stmt._pattern, Cpp_Pp_Tokens, string, colons=False, require_cls=True) def tostr(self): ''' :return: this elif-stmt as a string. :rtype: str ''' return '{0} {1}'.format(*self.items)