mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2025-02-25 18:55:22 -06:00
Merge pull request #7905 from jakobandersen/c_compat
C, add compatibility flag for parsing some pre-v3 input
This commit is contained in:
commit
03e1070888
9
CHANGES
9
CHANGES
@ -10,6 +10,9 @@ Incompatible changes
|
|||||||
Deprecated
|
Deprecated
|
||||||
----------
|
----------
|
||||||
|
|
||||||
|
* C, parsing of pre-v3 style type directives and roles, along with the options
|
||||||
|
:confval:`c_allow_pre_v3` and :confval:`c_warn_on_allowed_pre_v3`.
|
||||||
|
|
||||||
Features added
|
Features added
|
||||||
--------------
|
--------------
|
||||||
|
|
||||||
@ -24,6 +27,12 @@ Features added
|
|||||||
* #7052: add ``:noindexentry:`` to the Python, C, C++, and Javascript domains.
|
* #7052: add ``:noindexentry:`` to the Python, C, C++, and Javascript domains.
|
||||||
Update the documentation to better reflect the relationship between this option
|
Update the documentation to better reflect the relationship between this option
|
||||||
and the ``:noindex:`` option.
|
and the ``:noindex:`` option.
|
||||||
|
* #7899: C, add possibility of parsing of some pre-v3 style type directives and
|
||||||
|
roles and try to convert them to equivalent v3 directives/roles.
|
||||||
|
Set the new option :confval:`c_allow_pre_v3` to ``True`` to enable this.
|
||||||
|
The warnings printed from this functionality can be suppressed by setting
|
||||||
|
:confval:`c_warn_on_allowed_pre_v3`` to ``True``.
|
||||||
|
The functionality is immediately deprecated.
|
||||||
|
|
||||||
Bugs fixed
|
Bugs fixed
|
||||||
----------
|
----------
|
||||||
|
@ -2545,6 +2545,23 @@ Options for the C domain
|
|||||||
|
|
||||||
.. versionadded:: 3.0
|
.. versionadded:: 3.0
|
||||||
|
|
||||||
|
.. confval:: c_allow_pre_v3
|
||||||
|
|
||||||
|
A boolean (default ``False``) controlling whether to parse and try to
|
||||||
|
convert pre-v3 style type directives and type roles.
|
||||||
|
|
||||||
|
.. versionadded:: 3.2
|
||||||
|
.. deprecated:: 3.2
|
||||||
|
Use the directives and roles added in v3.
|
||||||
|
|
||||||
|
.. confval:: c_warn_on_allowed_pre_v3
|
||||||
|
|
||||||
|
A boolean (default ``True``) controlling whether to warn when a pre-v3
|
||||||
|
style type directive/role is parsed and converted.
|
||||||
|
|
||||||
|
.. versionadded:: 3.2
|
||||||
|
.. deprecated:: 3.2
|
||||||
|
Use the directives and roles added in v3.
|
||||||
|
|
||||||
.. _cpp-config:
|
.. _cpp-config:
|
||||||
|
|
||||||
|
@ -22,6 +22,7 @@ from sphinx import addnodes
|
|||||||
from sphinx.addnodes import pending_xref
|
from sphinx.addnodes import pending_xref
|
||||||
from sphinx.application import Sphinx
|
from sphinx.application import Sphinx
|
||||||
from sphinx.builders import Builder
|
from sphinx.builders import Builder
|
||||||
|
from sphinx.deprecation import RemovedInSphinx50Warning
|
||||||
from sphinx.directives import ObjectDescription
|
from sphinx.directives import ObjectDescription
|
||||||
from sphinx.domains import Domain, ObjType
|
from sphinx.domains import Domain, ObjType
|
||||||
from sphinx.environment import BuildEnvironment
|
from sphinx.environment import BuildEnvironment
|
||||||
@ -2937,6 +2938,23 @@ class DefinitionParser(BaseParser):
|
|||||||
init = ASTInitializer(initVal)
|
init = ASTInitializer(initVal)
|
||||||
return ASTEnumerator(name, init)
|
return ASTEnumerator(name, init)
|
||||||
|
|
||||||
|
def parse_pre_v3_type_definition(self) -> ASTDeclaration:
|
||||||
|
self.skip_ws()
|
||||||
|
declaration = None # type: Any
|
||||||
|
if self.skip_word('struct'):
|
||||||
|
typ = 'struct'
|
||||||
|
declaration = self._parse_struct()
|
||||||
|
elif self.skip_word('union'):
|
||||||
|
typ = 'union'
|
||||||
|
declaration = self._parse_union()
|
||||||
|
elif self.skip_word('enum'):
|
||||||
|
typ = 'enum'
|
||||||
|
declaration = self._parse_enum()
|
||||||
|
else:
|
||||||
|
self.fail("Could not parse pre-v3 type directive."
|
||||||
|
" Must start with 'struct', 'union', or 'enum'.")
|
||||||
|
return ASTDeclaration(typ, typ, declaration, False)
|
||||||
|
|
||||||
def parse_declaration(self, objectType: str, directiveType: str) -> ASTDeclaration:
|
def parse_declaration(self, objectType: str, directiveType: str) -> ASTDeclaration:
|
||||||
if objectType not in ('function', 'member',
|
if objectType not in ('function', 'member',
|
||||||
'macro', 'struct', 'union', 'enum', 'enumerator', 'type'):
|
'macro', 'struct', 'union', 'enum', 'enumerator', 'type'):
|
||||||
@ -3114,6 +3132,9 @@ class CObject(ObjectDescription):
|
|||||||
def parse_definition(self, parser: DefinitionParser) -> ASTDeclaration:
|
def parse_definition(self, parser: DefinitionParser) -> ASTDeclaration:
|
||||||
return parser.parse_declaration(self.object_type, self.objtype)
|
return parser.parse_declaration(self.object_type, self.objtype)
|
||||||
|
|
||||||
|
def parse_pre_v3_type_definition(self, parser: DefinitionParser) -> ASTDeclaration:
|
||||||
|
return parser.parse_pre_v3_type_definition()
|
||||||
|
|
||||||
def describe_signature(self, signode: TextElement, ast: Any, options: Dict) -> None:
|
def describe_signature(self, signode: TextElement, ast: Any, options: Dict) -> None:
|
||||||
ast.describe_signature(signode, 'lastIsName', self.env, options)
|
ast.describe_signature(signode, 'lastIsName', self.env, options)
|
||||||
|
|
||||||
@ -3135,8 +3156,27 @@ class CObject(ObjectDescription):
|
|||||||
|
|
||||||
parser = DefinitionParser(sig, location=signode, config=self.env.config)
|
parser = DefinitionParser(sig, location=signode, config=self.env.config)
|
||||||
try:
|
try:
|
||||||
ast = self.parse_definition(parser)
|
try:
|
||||||
parser.assert_end()
|
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(RemovedInSphinx50Warning.__name__,
|
||||||
|
sig, ast.objectType, ast, eOrig)
|
||||||
|
logger.warning(msg, location=signode)
|
||||||
except DefinitionError as e:
|
except DefinitionError as e:
|
||||||
logger.warning(e, location=signode)
|
logger.warning(e, location=signode)
|
||||||
# It is easier to assume some phony name than handling the error in
|
# It is easier to assume some phony name than handling the error in
|
||||||
@ -3445,6 +3485,39 @@ class CXRefRole(XRefRole):
|
|||||||
title = title[dot + 1:]
|
title = title[dot + 1:]
|
||||||
return title, target
|
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_source_info(),
|
||||||
|
config=self.env.config)
|
||||||
|
try:
|
||||||
|
parser.parse_xref_object()
|
||||||
|
# it suceeded, 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(RemovedInSphinx50Warning.__name__, text, text, eOrig)
|
||||||
|
logger.warning(msg, location=self.get_source_info())
|
||||||
|
return [signode], []
|
||||||
|
|
||||||
|
|
||||||
class CExprRole(SphinxRole):
|
class CExprRole(SphinxRole):
|
||||||
def __init__(self, asCode: bool) -> None:
|
def __init__(self, asCode: bool) -> None:
|
||||||
@ -3646,6 +3719,9 @@ def setup(app: Sphinx) -> Dict[str, Any]:
|
|||||||
app.add_config_value("c_paren_attributes", [], 'env')
|
app.add_config_value("c_paren_attributes", [], 'env')
|
||||||
app.add_post_transform(AliasTransform)
|
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 {
|
return {
|
||||||
'version': 'builtin',
|
'version': 'builtin',
|
||||||
'env_version': 2,
|
'env_version': 2,
|
||||||
|
Loading…
Reference in New Issue
Block a user