Path: blob/main/Tools/c-analyzer/c_parser/preprocessor/__main__.py
12 views
import logging1import sys23from c_common.scriptutil import (4add_verbosity_cli,5add_traceback_cli,6add_kind_filtering_cli,7add_files_cli,8add_failure_filtering_cli,9add_commands_cli,10process_args_by_key,11configure_logger,12get_prog,13main_for_filenames,14)15from . import (16errors as _errors,17get_preprocessor as _get_preprocessor,18)192021FAIL = {22'err': _errors.ErrorDirectiveError,23'deps': _errors.MissingDependenciesError,24'os': _errors.OSMismatchError,25}26FAIL_DEFAULT = tuple(v for v in FAIL if v != 'os')272829logger = logging.getLogger(__name__)303132##################################33# CLI helpers3435def add_common_cli(parser, *, get_preprocessor=_get_preprocessor):36parser.add_argument('--macros', action='append')37parser.add_argument('--incldirs', action='append')38parser.add_argument('--same', action='append')39process_fail_arg = add_failure_filtering_cli(parser, FAIL)4041def process_args(args, *, argv):42ns = vars(args)4344process_fail_arg(args, argv=argv)45ignore_exc = ns.pop('ignore_exc')46# We later pass ignore_exc to _get_preprocessor().4748args.get_file_preprocessor = get_preprocessor(49file_macros=ns.pop('macros'),50file_incldirs=ns.pop('incldirs'),51file_same=ns.pop('same'),52ignore_exc=ignore_exc,53log_err=print,54)55return process_args565758def _iter_preprocessed(filename, *,59get_preprocessor,60match_kind=None,61pure=False,62):63preprocess = get_preprocessor(filename)64for line in preprocess(tool=not pure) or ():65if match_kind is not None and not match_kind(line.kind):66continue67yield line686970#######################################71# the commands7273def _cli_preprocess(parser, excluded=None, **prepr_kwargs):74parser.add_argument('--pure', action='store_true')75parser.add_argument('--no-pure', dest='pure', action='store_const', const=False)76process_kinds = add_kind_filtering_cli(parser)77process_common = add_common_cli(parser, **prepr_kwargs)78parser.add_argument('--raw', action='store_true')79process_files = add_files_cli(parser, excluded=excluded)8081return [82process_kinds,83process_common,84process_files,85]868788def cmd_preprocess(filenames, *,89raw=False,90iter_filenames=None,91**kwargs92):93if 'get_file_preprocessor' not in kwargs:94kwargs['get_file_preprocessor'] = _get_preprocessor()95if raw:96def show_file(filename, lines):97for line in lines:98print(line)99#print(line.raw)100else:101def show_file(filename, lines):102for line in lines:103linefile = ''104if line.filename != filename:105linefile = f' ({line.filename})'106text = line.data107if line.kind == 'comment':108text = '/* ' + line.data.splitlines()[0]109text += ' */' if '\n' in line.data else r'\n... */'110print(f' {line.lno:>4} {line.kind:10} | {text}')111112filenames = main_for_filenames(filenames, iter_filenames)113for filename in filenames:114lines = _iter_preprocessed(filename, **kwargs)115show_file(filename, lines)116117118def _cli_data(parser):119...120121return None122123124def cmd_data(filenames,125**kwargs126):127# XXX128raise NotImplementedError129130131COMMANDS = {132'preprocess': (133'preprocess the given C source & header files',134[_cli_preprocess],135cmd_preprocess,136),137'data': (138'check/manage local data (e.g. excludes, macros)',139[_cli_data],140cmd_data,141),142}143144145#######################################146# the script147148def parse_args(argv=sys.argv[1:], prog=sys.argv[0], *,149subset='preprocess',150excluded=None,151**prepr_kwargs152):153import argparse154parser = argparse.ArgumentParser(155prog=prog or get_prog(),156)157158processors = add_commands_cli(159parser,160commands={k: v[1] for k, v in COMMANDS.items()},161commonspecs=[162add_verbosity_cli,163add_traceback_cli,164],165subset=subset,166)167168args = parser.parse_args(argv)169ns = vars(args)170171cmd = ns.pop('cmd')172173verbosity, traceback_cm = process_args_by_key(174args,175argv,176processors[cmd],177['verbosity', 'traceback_cm'],178)179180return cmd, ns, verbosity, traceback_cm181182183def main(cmd, cmd_kwargs):184try:185run_cmd = COMMANDS[cmd][0]186except KeyError:187raise ValueError(f'unsupported cmd {cmd!r}')188run_cmd(**cmd_kwargs)189190191if __name__ == '__main__':192cmd, cmd_kwargs, verbosity, traceback_cm = parse_args()193configure_logger(verbosity)194with traceback_cm:195main(cmd, cmd_kwargs)196197198