mirror of
				https://github.com/python/cpython.git
				synced 2025-10-30 21:21:22 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			196 lines
		
	
	
	
		
			4.9 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			196 lines
		
	
	
	
		
			4.9 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| import logging
 | |
| import sys
 | |
| 
 | |
| from c_common.scriptutil import (
 | |
|     add_verbosity_cli,
 | |
|     add_traceback_cli,
 | |
|     add_kind_filtering_cli,
 | |
|     add_files_cli,
 | |
|     add_failure_filtering_cli,
 | |
|     add_commands_cli,
 | |
|     process_args_by_key,
 | |
|     configure_logger,
 | |
|     get_prog,
 | |
|     main_for_filenames,
 | |
| )
 | |
| from . import (
 | |
|     errors as _errors,
 | |
|     get_preprocessor as _get_preprocessor,
 | |
| )
 | |
| 
 | |
| 
 | |
| FAIL = {
 | |
|     'err': _errors.ErrorDirectiveError,
 | |
|     'deps': _errors.MissingDependenciesError,
 | |
|     'os': _errors.OSMismatchError,
 | |
| }
 | |
| FAIL_DEFAULT = tuple(v for v in FAIL if v != 'os')
 | |
| 
 | |
| 
 | |
| logger = logging.getLogger(__name__)
 | |
| 
 | |
| 
 | |
| ##################################
 | |
| # CLI helpers
 | |
| 
 | |
| def add_common_cli(parser, *, get_preprocessor=_get_preprocessor):
 | |
|     parser.add_argument('--macros', action='append')
 | |
|     parser.add_argument('--incldirs', action='append')
 | |
|     parser.add_argument('--same', action='append')
 | |
|     process_fail_arg = add_failure_filtering_cli(parser, FAIL)
 | |
| 
 | |
|     def process_args(args, *, argv):
 | |
|         ns = vars(args)
 | |
| 
 | |
|         process_fail_arg(args, argv=argv)
 | |
|         ignore_exc = ns.pop('ignore_exc')
 | |
|         # We later pass ignore_exc to _get_preprocessor().
 | |
| 
 | |
|         args.get_file_preprocessor = get_preprocessor(
 | |
|             file_macros=ns.pop('macros'),
 | |
|             file_incldirs=ns.pop('incldirs'),
 | |
|             file_same=ns.pop('same'),
 | |
|             ignore_exc=ignore_exc,
 | |
|             log_err=print,
 | |
|         )
 | |
|     return process_args
 | |
| 
 | |
| 
 | |
| def _iter_preprocessed(filename, *,
 | |
|                        get_preprocessor,
 | |
|                        match_kind=None,
 | |
|                        pure=False,
 | |
|                        ):
 | |
|     preprocess = get_preprocessor(filename)
 | |
|     for line in preprocess(tool=not pure) or ():
 | |
|         if match_kind is not None and not match_kind(line.kind):
 | |
|             continue
 | |
|         yield line
 | |
| 
 | |
| 
 | |
| #######################################
 | |
| # the commands
 | |
| 
 | |
| def _cli_preprocess(parser, excluded=None, **prepr_kwargs):
 | |
|     parser.add_argument('--pure', action='store_true')
 | |
|     parser.add_argument('--no-pure', dest='pure', action='store_const', const=False)
 | |
|     process_kinds = add_kind_filtering_cli(parser)
 | |
|     process_common = add_common_cli(parser, **prepr_kwargs)
 | |
|     parser.add_argument('--raw', action='store_true')
 | |
|     process_files = add_files_cli(parser, excluded=excluded)
 | |
| 
 | |
|     return [
 | |
|         process_kinds,
 | |
|         process_common,
 | |
|         process_files,
 | |
|     ]
 | |
| 
 | |
| 
 | |
| def cmd_preprocess(filenames, *,
 | |
|                    raw=False,
 | |
|                    iter_filenames=None,
 | |
|                    **kwargs
 | |
|                    ):
 | |
|     if 'get_file_preprocessor' not in kwargs:
 | |
|         kwargs['get_file_preprocessor'] = _get_preprocessor()
 | |
|     if raw:
 | |
|         def show_file(filename, lines):
 | |
|             for line in lines:
 | |
|                 print(line)
 | |
|                 #print(line.raw)
 | |
|     else:
 | |
|         def show_file(filename, lines):
 | |
|             for line in lines:
 | |
|                 linefile = ''
 | |
|                 if line.filename != filename:
 | |
|                     linefile = f' ({line.filename})'
 | |
|                 text = line.data
 | |
|                 if line.kind == 'comment':
 | |
|                     text = '/* ' + line.data.splitlines()[0]
 | |
|                     text += ' */' if '\n' in line.data else r'\n... */'
 | |
|                 print(f' {line.lno:>4} {line.kind:10} | {text}')
 | |
| 
 | |
|     filenames = main_for_filenames(filenames, iter_filenames)
 | |
|     for filename in filenames:
 | |
|         lines = _iter_preprocessed(filename, **kwargs)
 | |
|         show_file(filename, lines)
 | |
| 
 | |
| 
 | |
| def _cli_data(parser):
 | |
|     ...
 | |
| 
 | |
|     return None
 | |
| 
 | |
| 
 | |
| def cmd_data(filenames,
 | |
|              **kwargs
 | |
|              ):
 | |
|     # XXX
 | |
|     raise NotImplementedError
 | |
| 
 | |
| 
 | |
| COMMANDS = {
 | |
|     'preprocess': (
 | |
|         'preprocess the given C source & header files',
 | |
|         [_cli_preprocess],
 | |
|         cmd_preprocess,
 | |
|     ),
 | |
|     'data': (
 | |
|         'check/manage local data (e.g. excludes, macros)',
 | |
|         [_cli_data],
 | |
|         cmd_data,
 | |
|     ),
 | |
| }
 | |
| 
 | |
| 
 | |
| #######################################
 | |
| # the script
 | |
| 
 | |
| def parse_args(argv=sys.argv[1:], prog=sys.argv[0], *,
 | |
|                subset='preprocess',
 | |
|                excluded=None,
 | |
|                **prepr_kwargs
 | |
|                ):
 | |
|     import argparse
 | |
|     parser = argparse.ArgumentParser(
 | |
|         prog=prog or get_prog(),
 | |
|     )
 | |
| 
 | |
|     processors = add_commands_cli(
 | |
|         parser,
 | |
|         commands={k: v[1] for k, v in COMMANDS.items()},
 | |
|         commonspecs=[
 | |
|             add_verbosity_cli,
 | |
|             add_traceback_cli,
 | |
|         ],
 | |
|         subset=subset,
 | |
|     )
 | |
| 
 | |
|     args = parser.parse_args(argv)
 | |
|     ns = vars(args)
 | |
| 
 | |
|     cmd = ns.pop('cmd')
 | |
| 
 | |
|     verbosity, traceback_cm = process_args_by_key(
 | |
|         args,
 | |
|         argv,
 | |
|         processors[cmd],
 | |
|         ['verbosity', 'traceback_cm'],
 | |
|     )
 | |
| 
 | |
|     return cmd, ns, verbosity, traceback_cm
 | |
| 
 | |
| 
 | |
| def main(cmd, cmd_kwargs):
 | |
|     try:
 | |
|         run_cmd = COMMANDS[cmd][0]
 | |
|     except KeyError:
 | |
|         raise ValueError(f'unsupported cmd {cmd!r}')
 | |
|     run_cmd(**cmd_kwargs)
 | |
| 
 | |
| 
 | |
| if __name__ == '__main__':
 | |
|     cmd, cmd_kwargs, verbosity, traceback_cm = parse_args()
 | |
|     configure_logger(verbosity)
 | |
|     with traceback_cm:
 | |
|         main(cmd, cmd_kwargs)
 | 
