mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2026-10-25 22:50:22 -05:00
12 files changed
+4222
-556
No files matched your search
@@ -0,0 +1 @@
|
||||
exclude_patterns = ['_build']
|
||||
@@ -0,0 +1,52 @@
|
||||
test-domain-c
|
||||
=============
|
||||
|
||||
directives
|
||||
----------
|
||||
|
||||
.. c:function:: int hello(const char *name)
|
||||
|
||||
:rtype: int
|
||||
|
||||
.. c:function:: MyStruct hello2(char *name)
|
||||
|
||||
:rtype: MyStruct
|
||||
|
||||
.. c:member:: float Sphinx.version
|
||||
.. c:var:: int version
|
||||
|
||||
.. c:macro:: IS_SPHINX
|
||||
.. c:macro:: SPHINX(arg1, arg2)
|
||||
|
||||
.. c:struct:: MyStruct
|
||||
.. c:union:: MyUnion
|
||||
.. c:enum:: MyEnum
|
||||
|
||||
.. c:enumerator:: MyEnumerator
|
||||
|
||||
:c:enumerator:`MyEnumerator`
|
||||
|
||||
:c:enumerator:`MyEnumerator`
|
||||
|
||||
:c:enumerator:`MyEnumerator`
|
||||
|
||||
.. c:type:: Sphinx
|
||||
.. c:type:: int SphinxVersionNum
|
||||
|
||||
|
||||
.. c:struct:: A
|
||||
|
||||
.. c:union:: @data
|
||||
|
||||
.. c:member:: int a
|
||||
|
||||
- :c:member:`A.@data.a`
|
||||
- :c:member:`A.a`
|
||||
|
||||
- :c:expr:`unsigned int`
|
||||
- :c:texpr:`unsigned int`
|
||||
|
||||
.. c:var:: A a
|
||||
|
||||
- :c:expr:`a->b`
|
||||
- :c:texpr:`a->b`
|
||||
@@ -107,15 +107,15 @@ Referring to :func:`nothing <>`.
|
||||
C items
|
||||
=======
|
||||
|
||||
.. c:function:: Sphinx_DoSomething()
|
||||
.. c:function:: void Sphinx_DoSomething()
|
||||
|
||||
.. c:member:: SphinxStruct.member
|
||||
.. c:member:: int SphinxStruct.member
|
||||
|
||||
.. c:macro:: SPHINX_USE_PYTHON
|
||||
|
||||
.. c:type:: SphinxType
|
||||
|
||||
.. c:var:: sphinx_global
|
||||
.. c:var:: int sphinx_global
|
||||
|
||||
|
||||
Javascript items
|
||||
|
||||
@@ -28,7 +28,7 @@ def test_build(app):
|
||||
assert path_html in htmltext
|
||||
|
||||
malloc_html = (
|
||||
'<b>Test_Malloc</b>: <i>changed:</i> Changed in version 0.6:'
|
||||
'<b>void *Test_Malloc(size_t n)</b>: <i>changed:</i> Changed in version 0.6:'
|
||||
' Can now be replaced with a different allocator.</a>')
|
||||
assert malloc_html in htmltext
|
||||
|
||||
|
||||
@@ -289,11 +289,11 @@ def test_html4_output(app, status, warning):
|
||||
(".//a[@class='reference internal'][@href='#errmod-error']/strong", 'Error'),
|
||||
# C references
|
||||
(".//span[@class='pre']", 'CFunction()'),
|
||||
(".//a[@href='#c-sphinx-dosomething']", ''),
|
||||
(".//a[@href='#c-sphinxstruct-member']", ''),
|
||||
(".//a[@href='#c-sphinx-use-python']", ''),
|
||||
(".//a[@href='#c-sphinxtype']", ''),
|
||||
(".//a[@href='#c-sphinx-global']", ''),
|
||||
(".//a[@href='#c.Sphinx_DoSomething']", ''),
|
||||
(".//a[@href='#c.SphinxStruct.member']", ''),
|
||||
(".//a[@href='#c.SPHINX_USE_PYTHON']", ''),
|
||||
(".//a[@href='#c.SphinxType']", ''),
|
||||
(".//a[@href='#c.sphinx_global']", ''),
|
||||
# test global TOC created by toctree()
|
||||
(".//ul[@class='current']/li[@class='toctree-l1 current']/a[@href='#']",
|
||||
'Testing object descriptions'),
|
||||
|
||||
+462
-30
@@ -8,73 +8,505 @@
|
||||
:license: BSD, see LICENSE for details.
|
||||
"""
|
||||
|
||||
from docutils import nodes
|
||||
import re
|
||||
|
||||
import pytest
|
||||
|
||||
from docutils import nodes
|
||||
import sphinx.domains.c as cDomain
|
||||
from sphinx import addnodes
|
||||
from sphinx.addnodes import (
|
||||
desc, desc_addname, desc_annotation, desc_content, desc_name, desc_optional,
|
||||
desc_parameter, desc_parameterlist, desc_returns, desc_signature, desc_type,
|
||||
pending_xref
|
||||
)
|
||||
from sphinx.domains.c import DefinitionParser, DefinitionError
|
||||
from sphinx.domains.c import _max_id, _id_prefix, Symbol
|
||||
from sphinx.testing import restructuredtext
|
||||
from sphinx.testing.util import assert_node
|
||||
from sphinx.util import docutils
|
||||
|
||||
|
||||
def parse(name, string):
|
||||
parser = DefinitionParser(string, None)
|
||||
parser.allowFallbackExpressionParsing = False
|
||||
ast = parser.parse_declaration(name, name)
|
||||
parser.assert_end()
|
||||
return ast
|
||||
|
||||
|
||||
def check(name, input, idDict, output=None):
|
||||
# first a simple check of the AST
|
||||
if output is None:
|
||||
output = input
|
||||
ast = parse(name, input)
|
||||
res = str(ast)
|
||||
if res != output:
|
||||
print("")
|
||||
print("Input: ", input)
|
||||
print("Result: ", res)
|
||||
print("Expected: ", output)
|
||||
raise DefinitionError("")
|
||||
rootSymbol = Symbol(None, None, None, None)
|
||||
symbol = rootSymbol.add_declaration(ast, docname="TestDoc")
|
||||
parentNode = addnodes.desc()
|
||||
signode = addnodes.desc_signature(input, '')
|
||||
parentNode += signode
|
||||
ast.describe_signature(signode, 'lastIsName', symbol, options={})
|
||||
|
||||
idExpected = [None]
|
||||
for i in range(1, _max_id + 1):
|
||||
if i in idDict:
|
||||
idExpected.append(idDict[i])
|
||||
else:
|
||||
idExpected.append(idExpected[i - 1])
|
||||
idActual = [None]
|
||||
for i in range(1, _max_id + 1):
|
||||
#try:
|
||||
id = ast.get_id(version=i)
|
||||
assert id is not None
|
||||
idActual.append(id[len(_id_prefix[i]):])
|
||||
#except NoOldIdError:
|
||||
# idActual.append(None)
|
||||
|
||||
res = [True]
|
||||
for i in range(1, _max_id + 1):
|
||||
res.append(idExpected[i] == idActual[i])
|
||||
|
||||
if not all(res):
|
||||
print("input: %s" % input.rjust(20))
|
||||
for i in range(1, _max_id + 1):
|
||||
if res[i]:
|
||||
continue
|
||||
print("Error in id version %d." % i)
|
||||
print("result: %s" % idActual[i])
|
||||
print("expected: %s" % idExpected[i])
|
||||
#print(rootSymbol.dump(0))
|
||||
raise DefinitionError("")
|
||||
|
||||
|
||||
def test_expressions():
|
||||
def exprCheck(expr, output=None):
|
||||
parser = DefinitionParser(expr, None)
|
||||
parser.allowFallbackExpressionParsing = False
|
||||
ast = parser.parse_expression()
|
||||
parser.assert_end()
|
||||
# first a simple check of the AST
|
||||
if output is None:
|
||||
output = expr
|
||||
res = str(ast)
|
||||
if res != output:
|
||||
print("")
|
||||
print("Input: ", input)
|
||||
print("Result: ", res)
|
||||
print("Expected: ", output)
|
||||
raise DefinitionError("")
|
||||
# type expressions
|
||||
exprCheck('int*')
|
||||
exprCheck('int *const*')
|
||||
exprCheck('int *volatile*')
|
||||
exprCheck('int *restrict*')
|
||||
exprCheck('int *(*)(double)')
|
||||
exprCheck('const int*')
|
||||
exprCheck('__int64')
|
||||
exprCheck('unsigned __int64')
|
||||
|
||||
# actual expressions
|
||||
|
||||
# primary
|
||||
exprCheck('true')
|
||||
exprCheck('false')
|
||||
ints = ['5', '0', '075', '0x0123456789ABCDEF', '0XF', '0b1', '0B1']
|
||||
unsignedSuffix = ['', 'u', 'U']
|
||||
longSuffix = ['', 'l', 'L', 'll', 'LL']
|
||||
for i in ints:
|
||||
for u in unsignedSuffix:
|
||||
for l in longSuffix:
|
||||
expr = i + u + l
|
||||
exprCheck(expr)
|
||||
expr = i + l + u
|
||||
exprCheck(expr)
|
||||
for suffix in ['', 'f', 'F', 'l', 'L']:
|
||||
for e in [
|
||||
'5e42', '5e+42', '5e-42',
|
||||
'5.', '5.e42', '5.e+42', '5.e-42',
|
||||
'.5', '.5e42', '.5e+42', '.5e-42',
|
||||
'5.0', '5.0e42', '5.0e+42', '5.0e-42']:
|
||||
expr = e + suffix
|
||||
exprCheck(expr)
|
||||
for e in [
|
||||
'ApF', 'Ap+F', 'Ap-F',
|
||||
'A.', 'A.pF', 'A.p+F', 'A.p-F',
|
||||
'.A', '.ApF', '.Ap+F', '.Ap-F',
|
||||
'A.B', 'A.BpF', 'A.Bp+F', 'A.Bp-F']:
|
||||
expr = "0x" + e + suffix
|
||||
exprCheck(expr)
|
||||
exprCheck('"abc\\"cba"') # string
|
||||
# character literals
|
||||
for p in ['', 'u8', 'u', 'U', 'L']:
|
||||
exprCheck(p + "'a'")
|
||||
exprCheck(p + "'\\n'")
|
||||
exprCheck(p + "'\\012'")
|
||||
exprCheck(p + "'\\0'")
|
||||
exprCheck(p + "'\\x0a'")
|
||||
exprCheck(p + "'\\x0A'")
|
||||
exprCheck(p + "'\\u0a42'")
|
||||
exprCheck(p + "'\\u0A42'")
|
||||
exprCheck(p + "'\\U0001f34c'")
|
||||
exprCheck(p + "'\\U0001F34C'")
|
||||
|
||||
exprCheck('(5)')
|
||||
exprCheck('C')
|
||||
# postfix
|
||||
exprCheck('A(2)')
|
||||
exprCheck('A[2]')
|
||||
exprCheck('a.b.c')
|
||||
exprCheck('a->b->c')
|
||||
exprCheck('i++')
|
||||
exprCheck('i--')
|
||||
# unary
|
||||
exprCheck('++5')
|
||||
exprCheck('--5')
|
||||
exprCheck('*5')
|
||||
exprCheck('&5')
|
||||
exprCheck('+5')
|
||||
exprCheck('-5')
|
||||
exprCheck('!5')
|
||||
exprCheck('~5')
|
||||
exprCheck('sizeof(T)')
|
||||
exprCheck('sizeof -42')
|
||||
exprCheck('alignof(T)')
|
||||
# cast
|
||||
exprCheck('(int)2')
|
||||
# binary op
|
||||
exprCheck('5 || 42')
|
||||
exprCheck('5 && 42')
|
||||
exprCheck('5 | 42')
|
||||
exprCheck('5 ^ 42')
|
||||
exprCheck('5 & 42')
|
||||
# ['==', '!=']
|
||||
exprCheck('5 == 42')
|
||||
exprCheck('5 != 42')
|
||||
# ['<=', '>=', '<', '>']
|
||||
exprCheck('5 <= 42')
|
||||
exprCheck('5 >= 42')
|
||||
exprCheck('5 < 42')
|
||||
exprCheck('5 > 42')
|
||||
# ['<<', '>>']
|
||||
exprCheck('5 << 42')
|
||||
exprCheck('5 >> 42')
|
||||
# ['+', '-']
|
||||
exprCheck('5 + 42')
|
||||
exprCheck('5 - 42')
|
||||
# ['*', '/', '%']
|
||||
exprCheck('5 * 42')
|
||||
exprCheck('5 / 42')
|
||||
exprCheck('5 % 42')
|
||||
# ['.*', '->*']
|
||||
# conditional
|
||||
# TODO
|
||||
# assignment
|
||||
exprCheck('a = 5')
|
||||
exprCheck('a *= 5')
|
||||
exprCheck('a /= 5')
|
||||
exprCheck('a %= 5')
|
||||
exprCheck('a += 5')
|
||||
exprCheck('a -= 5')
|
||||
exprCheck('a >>= 5')
|
||||
exprCheck('a <<= 5')
|
||||
exprCheck('a &= 5')
|
||||
exprCheck('a ^= 5')
|
||||
exprCheck('a |= 5')
|
||||
|
||||
|
||||
def test_type_definitions():
|
||||
check('type', "T", {1: "T"})
|
||||
|
||||
check('type', "bool *b", {1: 'b'})
|
||||
check('type', "bool *const b", {1: 'b'})
|
||||
check('type', "bool *const *b", {1: 'b'})
|
||||
check('type', "bool *volatile *b", {1: 'b'})
|
||||
check('type', "bool *restrict *b", {1: 'b'})
|
||||
check('type', "bool *volatile const b", {1: 'b'})
|
||||
check('type', "bool *volatile const b", {1: 'b'})
|
||||
check('type', "bool *volatile const *b", {1: 'b'})
|
||||
check('type', "bool b[]", {1: 'b'})
|
||||
check('type', "long long int foo", {1: 'foo'})
|
||||
# test decl specs on right
|
||||
check('type', "bool const b", {1: 'b'})
|
||||
|
||||
# from breathe#267 (named function parameters for function pointers
|
||||
check('type', 'void (*gpio_callback_t)(struct device *port, uint32_t pin)',
|
||||
{1: 'gpio_callback_t'})
|
||||
|
||||
|
||||
def test_macro_definitions():
|
||||
check('macro', 'M', {1: 'M'})
|
||||
check('macro', 'M()', {1: 'M'})
|
||||
check('macro', 'M(arg)', {1: 'M'})
|
||||
check('macro', 'M(arg1, arg2)', {1: 'M'})
|
||||
check('macro', 'M(arg1, arg2, arg3)', {1: 'M'})
|
||||
check('macro', 'M(...)', {1: 'M'})
|
||||
check('macro', 'M(arg, ...)', {1: 'M'})
|
||||
check('macro', 'M(arg1, arg2, ...)', {1: 'M'})
|
||||
check('macro', 'M(arg1, arg2, arg3, ...)', {1: 'M'})
|
||||
|
||||
|
||||
def test_member_definitions():
|
||||
check('member', 'void a', {1: 'a'})
|
||||
check('member', '_Bool a', {1: 'a'})
|
||||
check('member', 'bool a', {1: 'a'})
|
||||
check('member', 'char a', {1: 'a'})
|
||||
check('member', 'int a', {1: 'a'})
|
||||
check('member', 'float a', {1: 'a'})
|
||||
check('member', 'double a', {1: 'a'})
|
||||
|
||||
check('member', 'unsigned long a', {1: 'a'})
|
||||
check('member', '__int64 a', {1: 'a'})
|
||||
check('member', 'unsigned __int64 a', {1: 'a'})
|
||||
|
||||
check('member', 'int .a', {1: 'a'})
|
||||
|
||||
check('member', 'int *a', {1: 'a'})
|
||||
check('member', 'int **a', {1: 'a'})
|
||||
check('member', 'const int a', {1: 'a'})
|
||||
check('member', 'volatile int a', {1: 'a'})
|
||||
check('member', 'restrict int a', {1: 'a'})
|
||||
check('member', 'volatile const int a', {1: 'a'})
|
||||
check('member', 'restrict const int a', {1: 'a'})
|
||||
check('member', 'restrict volatile int a', {1: 'a'})
|
||||
check('member', 'restrict volatile const int a', {1: 'a'})
|
||||
|
||||
check('member', 'T t', {1: 't'})
|
||||
|
||||
check('member', 'int a[]', {1: 'a'})
|
||||
|
||||
check('member', 'int (*p)[]', {1: 'p'})
|
||||
|
||||
check('member', 'int a[42]', {1: 'a'})
|
||||
check('member', 'int a = 42', {1: 'a'})
|
||||
check('member', 'T a = {}', {1: 'a'})
|
||||
check('member', 'T a = {1}', {1: 'a'})
|
||||
check('member', 'T a = {1, 2}', {1: 'a'})
|
||||
check('member', 'T a = {1, 2, 3}', {1: 'a'})
|
||||
|
||||
# test from issue #1539
|
||||
check('member', 'CK_UTF8CHAR model[16]', {1: 'model'})
|
||||
|
||||
check('member', 'auto int a', {1: 'a'})
|
||||
check('member', 'register int a', {1: 'a'})
|
||||
check('member', 'extern int a', {1: 'a'})
|
||||
check('member', 'static int a', {1: 'a'})
|
||||
|
||||
check('member', 'thread_local int a', {1: 'a'})
|
||||
check('member', '_Thread_local int a', {1: 'a'})
|
||||
check('member', 'extern thread_local int a', {1: 'a'})
|
||||
check('member', 'thread_local extern int a', {1: 'a'},
|
||||
'extern thread_local int a')
|
||||
check('member', 'static thread_local int a', {1: 'a'})
|
||||
check('member', 'thread_local static int a', {1: 'a'},
|
||||
'static thread_local int a')
|
||||
|
||||
check('member', 'int b : 3', {1: 'b'})
|
||||
|
||||
|
||||
def test_function_definitions():
|
||||
check('function', 'void f()', {1: 'f'})
|
||||
check('function', 'void f(int)', {1: 'f'})
|
||||
check('function', 'void f(int i)', {1: 'f'})
|
||||
check('function', 'void f(int i, int j)', {1: 'f'})
|
||||
check('function', 'void f(...)', {1: 'f'})
|
||||
check('function', 'void f(int i, ...)', {1: 'f'})
|
||||
check('function', 'void f(struct T)', {1: 'f'})
|
||||
check('function', 'void f(struct T t)', {1: 'f'})
|
||||
check('function', 'void f(union T)', {1: 'f'})
|
||||
check('function', 'void f(union T t)', {1: 'f'})
|
||||
check('function', 'void f(enum T)', {1: 'f'})
|
||||
check('function', 'void f(enum T t)', {1: 'f'})
|
||||
|
||||
# test from issue #1539
|
||||
check('function', 'void f(A x[])', {1: 'f'})
|
||||
|
||||
# test from issue #2377
|
||||
check('function', 'void (*signal(int sig, void (*func)(int)))(int)', {1: 'signal'})
|
||||
|
||||
check('function', 'extern void f()', {1: 'f'})
|
||||
check('function', 'static void f()', {1: 'f'})
|
||||
check('function', 'inline void f()', {1: 'f'})
|
||||
|
||||
# tests derived from issue #1753 (skip to keep sanity)
|
||||
check('function', "void f(float *q(double))", {1: 'f'})
|
||||
check('function', "void f(float *(*q)(double))", {1: 'f'})
|
||||
check('function', "void f(float (*q)(double))", {1: 'f'})
|
||||
check('function', "int (*f(double d))(float)", {1: 'f'})
|
||||
check('function', "int (*f(bool b))[5]", {1: 'f'})
|
||||
check('function', "void f(int *const p)", {1: 'f'})
|
||||
check('function', "void f(int *volatile const p)", {1: 'f'})
|
||||
|
||||
# from breathe#223
|
||||
check('function', 'void f(struct E e)', {1: 'f'})
|
||||
check('function', 'void f(enum E e)', {1: 'f'})
|
||||
check('function', 'void f(union E e)', {1: 'f'})
|
||||
|
||||
|
||||
def test_union_definitions():
|
||||
check('struct', 'A', {1: 'A'})
|
||||
|
||||
|
||||
def test_union_definitions():
|
||||
check('union', 'A', {1: 'A'})
|
||||
|
||||
|
||||
def test_enum_definitions():
|
||||
check('enum', 'A', {1: 'A'})
|
||||
|
||||
check('enumerator', 'A', {1: 'A'})
|
||||
check('enumerator', 'A = 42', {1: 'A'})
|
||||
|
||||
|
||||
def test_anon_definitions():
|
||||
return # TODO
|
||||
check('class', '@a', {3: "Ut1_a"})
|
||||
check('union', '@a', {3: "Ut1_a"})
|
||||
check('enum', '@a', {3: "Ut1_a"})
|
||||
check('class', '@1', {3: "Ut1_1"})
|
||||
check('class', '@a::A', {3: "NUt1_a1AE"})
|
||||
|
||||
|
||||
def test_initializers():
|
||||
idsMember = {1: 'v'}
|
||||
idsFunction = {1: 'f'}
|
||||
# no init
|
||||
check('member', 'T v', idsMember)
|
||||
check('function', 'void f(T v)', idsFunction)
|
||||
# with '=', assignment-expression
|
||||
check('member', 'T v = 42', idsMember)
|
||||
check('function', 'void f(T v = 42)', idsFunction)
|
||||
# with '=', braced-init
|
||||
check('member', 'T v = {}', idsMember)
|
||||
check('function', 'void f(T v = {})', idsFunction)
|
||||
check('member', 'T v = {42, 42, 42}', idsMember)
|
||||
check('function', 'void f(T v = {42, 42, 42})', idsFunction)
|
||||
check('member', 'T v = {42, 42, 42,}', idsMember)
|
||||
check('function', 'void f(T v = {42, 42, 42,})', idsFunction)
|
||||
# TODO: designator-list
|
||||
|
||||
|
||||
def test_attributes():
|
||||
return # TODO
|
||||
# style: C++
|
||||
check('member', '[[]] int f', {1: 'f__i', 2: '1f'})
|
||||
check('member', '[ [ ] ] int f', {1: 'f__i', 2: '1f'},
|
||||
# this will fail when the proper grammar is implemented
|
||||
output='[[ ]] int f')
|
||||
check('member', '[[a]] int f', {1: 'f__i', 2: '1f'})
|
||||
# style: GNU
|
||||
check('member', '__attribute__(()) int f', {1: 'f__i', 2: '1f'})
|
||||
check('member', '__attribute__((a)) int f', {1: 'f__i', 2: '1f'})
|
||||
check('member', '__attribute__((a, b)) int f', {1: 'f__i', 2: '1f'})
|
||||
# style: user-defined id
|
||||
check('member', 'id_attr int f', {1: 'f__i', 2: '1f'})
|
||||
# style: user-defined paren
|
||||
check('member', 'paren_attr() int f', {1: 'f__i', 2: '1f'})
|
||||
check('member', 'paren_attr(a) int f', {1: 'f__i', 2: '1f'})
|
||||
check('member', 'paren_attr("") int f', {1: 'f__i', 2: '1f'})
|
||||
check('member', 'paren_attr(()[{}][]{}) int f', {1: 'f__i', 2: '1f'})
|
||||
with pytest.raises(DefinitionError):
|
||||
parse('member', 'paren_attr(() int f')
|
||||
with pytest.raises(DefinitionError):
|
||||
parse('member', 'paren_attr([) int f')
|
||||
with pytest.raises(DefinitionError):
|
||||
parse('member', 'paren_attr({) int f')
|
||||
with pytest.raises(DefinitionError):
|
||||
parse('member', 'paren_attr([)]) int f')
|
||||
with pytest.raises(DefinitionError):
|
||||
parse('member', 'paren_attr((])) int f')
|
||||
with pytest.raises(DefinitionError):
|
||||
parse('member', 'paren_attr({]}) int f')
|
||||
|
||||
# position: decl specs
|
||||
check('function', 'static inline __attribute__(()) void f()',
|
||||
{1: 'f', 2: '1fv'},
|
||||
output='__attribute__(()) static inline void f()')
|
||||
check('function', '[[attr1]] [[attr2]] void f()',
|
||||
{1: 'f', 2: '1fv'},
|
||||
output='[[attr1]] [[attr2]] void f()')
|
||||
# position: declarator
|
||||
check('member', 'int *[[attr]] i', {1: 'i__iP', 2: '1i'})
|
||||
check('member', 'int *const [[attr]] volatile i', {1: 'i__iPVC', 2: '1i'},
|
||||
output='int *[[attr]] volatile const i')
|
||||
check('member', 'int &[[attr]] i', {1: 'i__iR', 2: '1i'})
|
||||
check('member', 'int *[[attr]] *i', {1: 'i__iPP', 2: '1i'})
|
||||
|
||||
|
||||
def test_xref_parsing():
|
||||
return # TODO
|
||||
def check(target):
|
||||
class Config:
|
||||
cpp_id_attributes = ["id_attr"]
|
||||
cpp_paren_attributes = ["paren_attr"]
|
||||
parser = DefinitionParser(target, None, Config())
|
||||
ast, isShorthand = parser.parse_xref_object()
|
||||
parser.assert_end()
|
||||
check('f')
|
||||
check('f()')
|
||||
check('void f()')
|
||||
check('T f()')
|
||||
|
||||
|
||||
# def test_print():
|
||||
# # used for getting all the ids out for checking
|
||||
# for a in ids:
|
||||
# print(a)
|
||||
# raise DefinitionError("")
|
||||
|
||||
|
||||
def filter_warnings(warning, file):
|
||||
lines = warning.getvalue().split("\n");
|
||||
res = [l for l in lines if "domain-c" in l and "{}.rst".format(file) in l and
|
||||
"WARNING: document isn't included in any toctree" not in l]
|
||||
print("Filtered warnings for file '{}':".format(file))
|
||||
for w in res:
|
||||
print(w)
|
||||
return res
|
||||
|
||||
|
||||
@pytest.mark.sphinx(testroot='domain-c', confoverrides={'nitpicky': True})
|
||||
def test_build_domain_c(app, status, warning):
|
||||
app.builder.build_all()
|
||||
ws = filter_warnings(warning, "index")
|
||||
assert len(ws) == 0
|
||||
|
||||
|
||||
def test_cfunction(app):
|
||||
text = (".. c:function:: PyObject* "
|
||||
"PyType_GenericAlloc(PyTypeObject *type, Py_ssize_t nitems)")
|
||||
doctree = restructuredtext.parse(app, text)
|
||||
assert_node(doctree,
|
||||
(addnodes.index,
|
||||
[desc, ([desc_signature, ([desc_type, ([pending_xref, "PyObject"],
|
||||
"* ")],
|
||||
[desc_name, "PyType_GenericAlloc"],
|
||||
[desc_parameterlist, (desc_parameter,
|
||||
desc_parameter)])],
|
||||
desc_content)]))
|
||||
assert_node(doctree[1], addnodes.desc, desctype="function",
|
||||
domain="c", objtype="function", noindex=False)
|
||||
assert_node(doctree[1][0][2][0],
|
||||
[desc_parameter, ([pending_xref, "PyTypeObject"],
|
||||
[nodes.emphasis, "\xa0*type"])])
|
||||
assert_node(doctree[1][0][2][1],
|
||||
[desc_parameter, ([pending_xref, "Py_ssize_t"],
|
||||
[nodes.emphasis, "\xa0nitems"])])
|
||||
|
||||
domain = app.env.get_domain('c')
|
||||
entry = domain.objects.get('PyType_GenericAlloc')
|
||||
assert entry == ('index', 'c-pytype-genericalloc', 'function')
|
||||
assert entry == ('index', 'c.PyType_GenericAlloc', 'function')
|
||||
|
||||
|
||||
def test_cmember(app):
|
||||
text = ".. c:member:: PyObject* PyTypeObject.tp_bases"
|
||||
doctree = restructuredtext.parse(app, text)
|
||||
assert_node(doctree,
|
||||
(addnodes.index,
|
||||
[desc, ([desc_signature, ([desc_type, ([pending_xref, "PyObject"],
|
||||
"* ")],
|
||||
[desc_name, "PyTypeObject.tp_bases"])],
|
||||
desc_content)]))
|
||||
assert_node(doctree[1], addnodes.desc, desctype="member",
|
||||
domain="c", objtype="member", noindex=False)
|
||||
|
||||
domain = app.env.get_domain('c')
|
||||
entry = domain.objects.get('PyTypeObject.tp_bases')
|
||||
assert entry == ('index', 'c-pytypeobject-tp-bases', 'member')
|
||||
assert entry == ('index', 'c.PyTypeObject.tp_bases', 'member')
|
||||
|
||||
|
||||
def test_cvar(app):
|
||||
text = ".. c:var:: PyObject* PyClass_Type"
|
||||
doctree = restructuredtext.parse(app, text)
|
||||
assert_node(doctree,
|
||||
(addnodes.index,
|
||||
[desc, ([desc_signature, ([desc_type, ([pending_xref, "PyObject"],
|
||||
"* ")],
|
||||
[desc_name, "PyClass_Type"])],
|
||||
desc_content)]))
|
||||
assert_node(doctree[1], addnodes.desc, desctype="var",
|
||||
domain="c", objtype="var", noindex=False)
|
||||
|
||||
domain = app.env.get_domain('c')
|
||||
entry = domain.objects.get('PyClass_Type')
|
||||
assert entry == ('index', 'c-pyclass-type', 'var')
|
||||
assert entry == ('index', 'c.PyClass_Type', 'var')
|
||||
Reference in new issue
Block a user