summaryrefslogtreecommitdiff
path: root/Tools/c-analyzer/c_parser/preprocessor/errors.py
diff options
context:
space:
mode:
Diffstat (limited to 'Tools/c-analyzer/c_parser/preprocessor/errors.py')
-rw-r--r--Tools/c-analyzer/c_parser/preprocessor/errors.py110
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)