import os.path import re, sys from . import common as _common from . import gcc as _gcc _normpath = _gcc._normpath TOOL = 'clang' META_FILES = { '', '', } def preprocess(filename, incldirs=None, includes=None, macros=None, samefiles=None, cwd=None, ): if not cwd or not os.path.isabs(cwd): cwd = os.path.abspath(cwd or '.') filename = _normpath(filename, cwd) postargs = _gcc.POST_ARGS basename = os.path.basename(filename) dirname = os.path.basename(os.path.dirname(filename)) if (basename not in _gcc.FILES_WITHOUT_INTERNAL_CAPI and dirname not in _gcc.DIRS_WITHOUT_INTERNAL_CAPI): postargs += ('-DPy_BUILD_CORE=1',) text = _common.preprocess( TOOL, filename, incldirs=incldirs, includes=includes, macros=macros, #preargs=PRE_ARGS, postargs=postargs, executable=['clang'], compiler='unix', cwd=cwd, ) return _iter_lines(text, filename, samefiles, cwd) EXIT_MARKERS = {'# 2 "" 2', '# 3 "" 2', '# 4 "" 2'} def _iter_lines(text, reqfile, samefiles, cwd, raw=False): lines = iter(text.splitlines()) # The first line is special. # The subsequent lines are consistent. firstlines = [ f'# 1 "{reqfile}"', '# 1 "" 1', '# 1 "" 3', '# 370 "" 3', '# 1 "" 1', '# 1 "" 2', ] for expected in firstlines: line = next(lines) if line != expected: raise NotImplementedError((line, expected)) # Do all the CLI-provided includes. filter_reqfile = (lambda f: _gcc._filter_reqfile(f, reqfile, samefiles)) make_info = (lambda lno: _common.FileInfo(reqfile, lno)) last = None for line in lines: assert last != reqfile, (last,) # NOTE:condition is clang specific if not line: continue lno, included, flags = _gcc._parse_marker_line(line, reqfile) if not included: raise NotImplementedError((line,)) if included == reqfile: # This will be the last one. assert 2 in flags, (line, flags) else: # NOTE:first condition is specific to clang if _normpath(included, cwd) == reqfile: assert 1 in flags or 2 in flags, (line, flags, included, reqfile) else: assert 1 in flags, (line, flags, included, reqfile) yield from _gcc._iter_top_include_lines( lines, _normpath(included, cwd), cwd, filter_reqfile, make_info, raw, EXIT_MARKERS ) last = included # The last one is always the requested file. # NOTE:_normpath is clang specific assert _normpath(included, cwd) == reqfile, (line,)