Skip to content

Commit c09643c

Browse files
committed
C, fix parsing of fundamental types
When multiple simple type specifiers are part of the type, then they may appear in any order.
1 parent 67d6734 commit c09643c

File tree

4 files changed

+37
-26
lines changed

4 files changed

+37
-26
lines changed

CHANGES

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ Features added
1616
Bugs fixed
1717
----------
1818

19-
* #9917: C++, parse fundamental types no matter the order of simple type
19+
* #9917: C and C++, parse fundamental types no matter the order of simple type
2020
specifiers.
2121

2222
Testing

sphinx/domains/c.py

Lines changed: 27 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -95,28 +95,18 @@
9595
_simple_type_specifiers_re = re.compile(r"""(?x)
9696
\b(
9797
void|_Bool|bool
98-
# Integer
99-
# -------
100-
|((signed|unsigned)\s+)?(char|(
101-
((long\s+long|long|short)\s+)?int
102-
))
98+
|signed|unsigned
99+
|short|long
100+
|char
101+
|int
103102
|__uint128|__int128
104-
# extensions
105-
|((signed|unsigned)\s+)?__int(8|16|32|64|128)
106-
# Floating-point
107-
# --------------
108-
|(float|double|long\s+double)(\s+(_Complex|complex|_Imaginary|imaginary))?
109-
|(_Complex|complex|_Imaginary|imaginary)\s+(float|double|long\s+double)
103+
|__int(8|16|32|64|128) # extension
104+
|float|double
110105
|_Decimal(32|64|128)
111-
# extensions
112-
|__float80|_Float64x|__float128|_Float128|__ibm128
113-
|__fp16
114-
# Fixed-point, extension
115-
|(_Sat\s+)?((signed|unsigned)\s+)?((short|long|long\s+long)\s+)?(_Fract|fract|_Accum|accum)
116-
# Integer types that could be prefixes of the previous ones
117-
# ---------------------------------------------------------
118-
|((signed|unsigned)\s+)?(long\s+long|long|short)
119-
|signed|unsigned
106+
|_Complex|complex|_Imaginary|imaginary
107+
|__float80|_Float64x|__float128|_Float128|__ibm128 # extension
108+
|__fp16 # extension
109+
|_Sat|_Fract|fract|_Accum|accum # extension
120110
)\b
121111
""")
122112

@@ -636,8 +626,9 @@ class ASTTrailingTypeSpec(ASTBase):
636626

637627

638628
class ASTTrailingTypeSpecFundamental(ASTTrailingTypeSpec):
639-
def __init__(self, name: str) -> None:
640-
self.names = name.split()
629+
def __init__(self, names: List[str]) -> None:
630+
assert len(names) != 0
631+
self.names = names
641632

642633
def _stringify(self, transform: StringifyTransform) -> str:
643634
return ' '.join(self.names)
@@ -2580,12 +2571,24 @@ def _parse_nested_name(self) -> ASTNestedName:
25802571
break
25812572
return ASTNestedName(names, rooted)
25822573

2574+
def _parse_simple_type_specifiers(self) -> ASTTrailingTypeSpecFundamental:
2575+
names: List[str] = []
2576+
2577+
self.skip_ws()
2578+
while self.match(_simple_type_specifiers_re):
2579+
names.append(self.matched_text)
2580+
self.skip_ws()
2581+
if len(names) == 0:
2582+
return None
2583+
return ASTTrailingTypeSpecFundamental(names)
2584+
25832585
def _parse_trailing_type_spec(self) -> ASTTrailingTypeSpec:
25842586
# fundamental types, https://en.cppreference.com/w/c/language/type
25852587
# and extensions
25862588
self.skip_ws()
2587-
if self.match(_simple_type_specifiers_re):
2588-
return ASTTrailingTypeSpecFundamental(self.matched_text)
2589+
res = self._parse_simple_type_specifiers()
2590+
if res is not None:
2591+
return res
25892592

25902593
# prefixed
25912594
prefix = None

tests/test_domain_c.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
:license: BSD, see LICENSE for details.
99
"""
1010

11+
import itertools
1112
import zlib
1213
from xml.etree import ElementTree
1314

@@ -329,6 +330,13 @@ def signed(t):
329330
input = "{key}%s foo" % t
330331
output = ' '.join(input.split())
331332
check('type', input, {1: 'foo'}, key='typedef', output=output)
333+
if ' ' in t:
334+
# try permutations of all components
335+
tcs = t.split()
336+
for p in itertools.permutations(tcs):
337+
input = "{key}%s foo" % ' '.join(p)
338+
output = ' '.join(input.split())
339+
check("type", input, {1: 'foo'}, key='typedef', output=output)
332340

333341

334342
def test_domain_c_ast_type_definitions():

tests/test_domain_cpp.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ def makeIdV2():
144144
output = "void f(%s arg)" % t
145145
check("function", input, {1: id1, 2: id2}, output=output)
146146
if ' ' in t:
147-
# try permutations of all commponents
147+
# try permutations of all components
148148
tcs = t.split()
149149
for p in itertools.permutations(tcs):
150150
input = "void f(%s arg)" % ' '.join(p)

0 commit comments

Comments
 (0)