diff options
Diffstat (limited to 'Tools/c-analyzer/c_parser/source.py')
-rw-r--r-- | Tools/c-analyzer/c_parser/source.py | 64 |
1 files changed, 64 insertions, 0 deletions
diff --git a/Tools/c-analyzer/c_parser/source.py b/Tools/c-analyzer/c_parser/source.py new file mode 100644 index 0000000..30a09ee --- /dev/null +++ b/Tools/c-analyzer/c_parser/source.py @@ -0,0 +1,64 @@ +import contextlib +import os.path + + +def resolve(source, filename): + if _looks_like_filename(source): + return _resolve_filename(source, filename) + + if isinstance(source, str): + source = source.splitlines() + + # At this point "source" is not a str. + if not filename: + filename = None + elif not isinstance(filename, str): + raise TypeError(f'filename should be str (or None), got {filename!r}') + else: + filename, _ = _resolve_filename(filename) + return source, filename + + +@contextlib.contextmanager +def good_file(filename, alt=None): + if not _looks_like_filename(filename): + raise ValueError(f'expected a filename, got {filename}') + filename, _ = _resolve_filename(filename, alt) + try: + yield filename + except Exception: + if not os.path.exists(filename): + raise FileNotFoundError(f'file not found: {filename}') + raise # re-raise + + +def _looks_like_filename(value): + if not isinstance(value, str): + return False + return value.endswith(('.c', '.h')) + + +def _resolve_filename(filename, alt=None): + if os.path.isabs(filename): + ... +# raise NotImplementedError + else: + filename = os.path.join('.', filename) + + if not alt: + alt = filename + elif os.path.abspath(filename) == os.path.abspath(alt): + alt = filename + else: + raise ValueError(f'mismatch: {filename} != {alt}') + return filename, alt + + +@contextlib.contextmanager +def opened(source, filename=None): + source, filename = resolve(source, filename) + if isinstance(source, str): + with open(source) as srcfile: + yield srcfile, filename + else: + yield source, filename |