diff options
Diffstat (limited to 'Tools/c-analyzer/c_parser/preprocessor/errors.py')
-rw-r--r-- | Tools/c-analyzer/c_parser/preprocessor/errors.py | 110 |
1 files changed, 110 insertions, 0 deletions
diff --git a/Tools/c-analyzer/c_parser/preprocessor/errors.py b/Tools/c-analyzer/c_parser/preprocessor/errors.py new file mode 100644 index 0000000000..9b66801d63 --- /dev/null +++ b/Tools/c-analyzer/c_parser/preprocessor/errors.py @@ -0,0 +1,110 @@ +import sys + + +OS = sys.platform + + +def _as_tuple(items): + if isinstance(items, str): + return tuple(items.strip().replace(',', ' ').split()) + elif items: + return tuple(items) + else: + return () + + +class PreprocessorError(Exception): + """Something preprocessor-related went wrong.""" + + @classmethod + def _msg(cls, filename, reason, **ignored): + msg = 'failure while preprocessing' + if reason: + msg = f'{msg} ({reason})' + return msg + + def __init__(self, filename, preprocessor=None, reason=None): + if isinstance(reason, str): + reason = reason.strip() + + self.filename = filename + self.preprocessor = preprocessor or None + self.reason = str(reason) if reason else None + + msg = self._msg(**vars(self)) + msg = f'({filename}) {msg}' + if preprocessor: + msg = f'[{preprocessor}] {msg}' + super().__init__(msg) + + +class PreprocessorFailure(PreprocessorError): + """The preprocessor command failed.""" + + @classmethod + def _msg(cls, error, **ignored): + msg = 'preprocessor command failed' + if error: + msg = f'{msg} {error}' + return msg + + def __init__(self, filename, argv, error=None, preprocessor=None): + exitcode = -1 + if isinstance(error, tuple): + if len(error) == 2: + error, exitcode = error + else: + error = str(error) + if isinstance(error, str): + error = error.strip() + + self.argv = _as_tuple(argv) or None + self.error = error if error else None + self.exitcode = exitcode + + reason = str(self.error) + super().__init__(filename, preprocessor, reason) + + +class ErrorDirectiveError(PreprocessorFailure): + """The file hit a #error directive.""" + + @classmethod + def _msg(cls, error, **ignored): + return f'#error directive hit ({error})' + + def __init__(self, filename, argv, error, *args, **kwargs): + super().__init__(filename, argv, error, *args, **kwargs) + + +class MissingDependenciesError(PreprocessorFailure): + """The preprocessor did not have access to all the target's dependencies.""" + + @classmethod + def _msg(cls, missing, **ignored): + msg = 'preprocessing failed due to missing dependencies' + if missing: + msg = f'{msg} ({", ".join(missing)})' + return msg + + def __init__(self, filename, missing=None, *args, **kwargs): + self.missing = _as_tuple(missing) or None + + super().__init__(filename, *args, **kwargs) + + +class OSMismatchError(MissingDependenciesError): + """The target is not compatible with the host OS.""" + + @classmethod + def _msg(cls, expected, **ignored): + return f'OS is {OS} but expected {expected or "???"}' + + def __init__(self, filename, expected=None, *args, **kwargs): + if isinstance(expected, str): + expected = expected.strip() + + self.actual = OS + self.expected = expected if expected else None + + super().__init__(filename, None, *args, **kwargs) |