mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2025-02-25 18:55:22 -06:00
Merge pull request #7376 from jakobandersen/c_cpp_error_messages
C, C++, improve error messages
This commit is contained in:
commit
6deb592a2f
@ -1986,6 +1986,10 @@ class DefinitionParser(BaseParser):
|
||||
|
||||
_prefix_keys = ('struct', 'enum', 'union')
|
||||
|
||||
@property
|
||||
def language(self) -> str:
|
||||
return 'C'
|
||||
|
||||
def _parse_string(self) -> str:
|
||||
if self.current_char != '"':
|
||||
return None
|
||||
@ -2697,7 +2701,7 @@ class DefinitionParser(BaseParser):
|
||||
restrict=restrict, volatile=volatile, const=const,
|
||||
attrs=attrs)
|
||||
if typed and self.current_char == '(': # note: peeking, not skipping
|
||||
# maybe this is the beginning of params,try that first,
|
||||
# maybe this is the beginning of params, try that first,
|
||||
# otherwise assume it's noptr->declarator > ( ptr-declarator )
|
||||
pos = self.pos
|
||||
try:
|
||||
@ -2706,7 +2710,10 @@ class DefinitionParser(BaseParser):
|
||||
typed)
|
||||
return res
|
||||
except DefinitionError as exParamQual:
|
||||
prevErrors.append((exParamQual, "If declId and parameters"))
|
||||
msg = "If declarator-id with parameters"
|
||||
if paramMode == 'function':
|
||||
msg += " (e.g., 'void f(int arg)')"
|
||||
prevErrors.append((exParamQual, msg))
|
||||
self.pos = pos
|
||||
try:
|
||||
assert self.current_char == '('
|
||||
@ -2723,7 +2730,10 @@ class DefinitionParser(BaseParser):
|
||||
return ASTDeclaratorParen(inner=inner, next=next)
|
||||
except DefinitionError as exNoPtrParen:
|
||||
self.pos = pos
|
||||
prevErrors.append((exNoPtrParen, "If parenthesis in noptr-declarator"))
|
||||
msg = "If parenthesis in noptr-declarator"
|
||||
if paramMode == 'function':
|
||||
msg += " (e.g., 'void (*f(int arg))(double)')"
|
||||
prevErrors.append((exNoPtrParen, msg))
|
||||
header = "Error in declarator"
|
||||
raise self._make_multi_error(prevErrors, header)
|
||||
pos = self.pos
|
||||
|
@ -4576,6 +4576,10 @@ class DefinitionParser(BaseParser):
|
||||
super().__init__(definition, location=location)
|
||||
self.config = config
|
||||
|
||||
@property
|
||||
def language(self) -> str:
|
||||
return 'C++'
|
||||
|
||||
def _parse_string(self) -> str:
|
||||
if self.current_char != '"':
|
||||
return None
|
||||
@ -5470,7 +5474,7 @@ class DefinitionParser(BaseParser):
|
||||
self.skip_ws()
|
||||
if not self.skip_string('('):
|
||||
if paramMode == 'function':
|
||||
self.fail('Expecting "(" in parameters_and_qualifiers.')
|
||||
self.fail('Expecting "(" in parameters-and-qualifiers.')
|
||||
else:
|
||||
return None
|
||||
args = []
|
||||
@ -5483,7 +5487,7 @@ class DefinitionParser(BaseParser):
|
||||
self.skip_ws()
|
||||
if not self.skip_string(')'):
|
||||
self.fail('Expected ")" after "..." in '
|
||||
'parameters_and_qualifiers.')
|
||||
'parameters-and-qualifiers.')
|
||||
break
|
||||
# note: it seems that function arguments can always be named,
|
||||
# even in function pointers and similar.
|
||||
@ -5498,7 +5502,7 @@ class DefinitionParser(BaseParser):
|
||||
break
|
||||
else:
|
||||
self.fail(
|
||||
'Expecting "," or ")" in parameters_and_qualifiers, '
|
||||
'Expecting "," or ")" in parameters-and-qualifiers, '
|
||||
'got "%s".' % self.current_char)
|
||||
|
||||
# TODO: why did we have this bail-out?
|
||||
@ -5529,7 +5533,7 @@ class DefinitionParser(BaseParser):
|
||||
exceptionSpec = 'noexcept'
|
||||
self.skip_ws()
|
||||
if self.skip_string('('):
|
||||
self.fail('Parameterised "noexcept" not implemented.')
|
||||
self.fail('Parameterised "noexcept" not yet implemented.')
|
||||
|
||||
self.skip_ws()
|
||||
override = self.skip_word_and_ws('override')
|
||||
@ -5795,14 +5799,15 @@ class DefinitionParser(BaseParser):
|
||||
typed)
|
||||
return res
|
||||
except DefinitionError as exParamQual:
|
||||
prevErrors.append((exParamQual, "If declId, parameters, and qualifiers"))
|
||||
prevErrors.append((exParamQual,
|
||||
"If declarator-id with parameters-and-qualifiers"))
|
||||
self.pos = pos
|
||||
try:
|
||||
assert self.current_char == '('
|
||||
self.skip_string('(')
|
||||
# TODO: hmm, if there is a name, it must be in inner, right?
|
||||
# TODO: hmm, if there must be parameters, they must b
|
||||
# inside, right?
|
||||
# TODO: hmm, if there must be parameters, they must be
|
||||
# inside, right?
|
||||
inner = self._parse_declarator(named, paramMode, typed)
|
||||
if not self.skip_string(')'):
|
||||
self.fail("Expected ')' in \"( ptr-declarator )\"")
|
||||
@ -5821,7 +5826,7 @@ class DefinitionParser(BaseParser):
|
||||
except DefinitionError as e:
|
||||
self.pos = pos
|
||||
prevErrors.append((e, "If declarator-id"))
|
||||
header = "Error in declarator or parameters and qualifiers"
|
||||
header = "Error in declarator or parameters-and-qualifiers"
|
||||
raise self._make_multi_error(prevErrors, header)
|
||||
|
||||
def _parse_initializer(self, outer: str = None, allowFallback: bool = True
|
||||
@ -5994,10 +5999,10 @@ class DefinitionParser(BaseParser):
|
||||
if eExpr is None:
|
||||
raise eType
|
||||
errs = []
|
||||
errs.append((eExpr, "If default is an expression"))
|
||||
errs.append((eType, "If default is a type"))
|
||||
errs.append((eExpr, "If default template argument is an expression"))
|
||||
errs.append((eType, "If default template argument is a type"))
|
||||
msg = "Error in non-type template parameter"
|
||||
msg += " or constrianted template paramter."
|
||||
msg += " or constrained template parameter."
|
||||
raise self._make_multi_error(errs, msg)
|
||||
|
||||
def _parse_type_using(self) -> ASTTypeUsing:
|
||||
|
@ -154,19 +154,23 @@ class BaseParser:
|
||||
result = [header, '\n']
|
||||
for e in errors:
|
||||
if len(e[1]) > 0:
|
||||
ident = ' '
|
||||
indent = ' '
|
||||
result.append(e[1])
|
||||
result.append(':\n')
|
||||
for line in str(e[0]).split('\n'):
|
||||
if len(line) == 0:
|
||||
continue
|
||||
result.append(ident)
|
||||
result.append(indent)
|
||||
result.append(line)
|
||||
result.append('\n')
|
||||
else:
|
||||
result.append(str(e[0]))
|
||||
return DefinitionError(''.join(result))
|
||||
|
||||
@property
|
||||
def language(self) -> str:
|
||||
raise NotImplementedError
|
||||
|
||||
def status(self, msg: str) -> None:
|
||||
# for debugging
|
||||
indicator = '-' * self.pos + '^'
|
||||
@ -176,8 +180,8 @@ class BaseParser:
|
||||
errors = []
|
||||
indicator = '-' * self.pos + '^'
|
||||
exMain = DefinitionError(
|
||||
'Invalid definition: %s [error at %d]\n %s\n %s' %
|
||||
(msg, self.pos, self.definition, indicator))
|
||||
'Invalid %s declaration: %s [error at %d]\n %s\n %s' %
|
||||
(self.language, msg, self.pos, self.definition, indicator))
|
||||
errors.append((exMain, "Main error"))
|
||||
for err in self.otherErrors:
|
||||
errors.append((err, "Potential other error"))
|
||||
|
Loading…
Reference in New Issue
Block a user