1 import contextlib
2 import os.path
3
4
5 def resolve(source, filename):
6 if _looks_like_filename(source):
7 return _resolve_filename(source, filename)
8
9 if isinstance(source, str):
10 source = source.splitlines()
11
12 # At this point "source" is not a str.
13 if not filename:
14 filename = None
15 elif not isinstance(filename, str):
16 raise TypeError(f'filename should be str (or None), got {filename!r}')
17 else:
18 filename, _ = _resolve_filename(filename)
19 return source, filename
20
21
22 @contextlib.contextmanager
23 def good_file(filename, alt=None):
24 if not _looks_like_filename(filename):
25 raise ValueError(f'expected a filename, got {filename}')
26 filename, _ = _resolve_filename(filename, alt)
27 try:
28 yield filename
29 except Exception:
30 if not os.path.exists(filename):
31 raise FileNotFoundError(f'file not found: {filename}')
32 raise # re-raise
33
34
35 def _looks_like_filename(value):
36 if not isinstance(value, str):
37 return False
38 return value.endswith(('.c', '.h'))
39
40
41 def _resolve_filename(filename, alt=None):
42 if os.path.isabs(filename):
43 ...
44 # raise NotImplementedError
45 else:
46 filename = os.path.join('.', filename)
47
48 if not alt:
49 alt = filename
50 elif os.path.abspath(filename) == os.path.abspath(alt):
51 alt = filename
52 else:
53 raise ValueError(f'mismatch: {filename} != {alt}')
54 return filename, alt
55
56
57 @contextlib.contextmanager
58 def opened(source, filename=None):
59 source, filename = resolve(source, filename)
60 if isinstance(source, str):
61 with open(source) as srcfile:
62 yield srcfile, filename
63 else:
64 yield source, filename