From 6d44677b2e593b93e80cc2288266c359a14bd092 Mon Sep 17 00:00:00 2001 From: Adam Turner <9087854+aa-turner@users.noreply.github.com> Date: Thu, 16 Jun 2022 20:51:34 +0100 Subject: [PATCH] Revert removing pre-v3 syntax in the C domain --- sphinx/domains/c.py | 60 +++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 58 insertions(+), 2 deletions(-) diff --git a/sphinx/domains/c.py b/sphinx/domains/c.py index 2d2c59eb885..75092dcb786 100644 --- a/sphinx/domains/c.py +++ b/sphinx/domains/c.py @@ -12,6 +12,7 @@ from sphinx.addnodes import pending_xref from sphinx.application import Sphinx from sphinx.builders import Builder +from sphinx.deprecation import RemovedInSphinx70Warning from sphinx.directives import ObjectDescription from sphinx.domains import Domain, ObjType from sphinx.environment import BuildEnvironment @@ -3252,8 +3253,27 @@ def handle_signature(self, sig: str, signode: TextElement) -> ASTDeclaration: parser = DefinitionParser(sig, location=signode, config=self.env.config) try: - ast = self.parse_definition(parser) - parser.assert_end() + try: + ast = self.parse_definition(parser) + parser.assert_end() + except DefinitionError as eOrig: + if not self.env.config['c_allow_pre_v3']: + raise + if self.objtype != 'type': + raise + try: + ast = self.parse_pre_v3_type_definition(parser) + parser.assert_end() + except DefinitionError: + raise eOrig + self.object_type = ast.objectType # type: ignore + if self.env.config['c_warn_on_allowed_pre_v3']: + msg = "{}: Pre-v3 C type directive '.. c:type:: {}' converted to " \ + "'.. c:{}:: {}'." \ + "\nThe original parsing error was:\n{}" + msg = msg.format(RemovedInSphinx70Warning.__name__, + sig, ast.objectType, ast, eOrig) + logger.warning(msg, location=signode) except DefinitionError as e: logger.warning(e, location=signode) # It is easier to assume some phony name than handling the error in @@ -3655,6 +3675,39 @@ def process_link(self, env: BuildEnvironment, refnode: Element, title = title[dot + 1:] return title, target + def run(self) -> Tuple[List[Node], List[system_message]]: + if not self.env.config['c_allow_pre_v3']: + return super().run() + + text = self.text.replace('\n', ' ') + parser = DefinitionParser(text, location=self.get_location(), + config=self.env.config) + try: + parser.parse_xref_object() + # it succeeded, so let it through + return super().run() + except DefinitionError as eOrig: + # try as if it was an c:expr + parser.pos = 0 + try: + ast = parser.parse_expression() + except DefinitionError: + # that didn't go well, just default back + return super().run() + classes = ['xref', 'c', 'c-texpr'] + parentSymbol = self.env.temp_data.get('cpp:parent_symbol', None) + if parentSymbol is None: + parentSymbol = self.env.domaindata['c']['root_symbol'] + signode = nodes.inline(classes=classes) + ast.describe_signature(signode, 'markType', self.env, parentSymbol) + + if self.env.config['c_warn_on_allowed_pre_v3']: + msg = "{}: Pre-v3 C type role ':c:type:`{}`' converted to ':c:expr:`{}`'." + msg += "\nThe original parsing error was:\n{}" + msg = msg.format(RemovedInSphinx70Warning.__name__, text, text, eOrig) + logger.warning(msg, location=self.get_location()) + return [signode], [] + class CExprRole(SphinxRole): def __init__(self, asCode: bool) -> None: @@ -3864,6 +3917,9 @@ def setup(app: Sphinx) -> Dict[str, Any]: app.add_config_value("c_extra_keywords", _macroKeywords, 'env') app.add_post_transform(AliasTransform) + app.add_config_value("c_allow_pre_v3", False, 'env') + app.add_config_value("c_warn_on_allowed_pre_v3", True, 'env') + return { 'version': 'builtin', 'env_version': 2,