17db96d56Sopenharmony_ciimport logging 27db96d56Sopenharmony_ciimport sys 37db96d56Sopenharmony_ci 47db96d56Sopenharmony_cifrom c_common.fsutil import expand_filenames, iter_files_by_suffix 57db96d56Sopenharmony_cifrom c_common.scriptutil import ( 67db96d56Sopenharmony_ci VERBOSITY, 77db96d56Sopenharmony_ci add_verbosity_cli, 87db96d56Sopenharmony_ci add_traceback_cli, 97db96d56Sopenharmony_ci add_commands_cli, 107db96d56Sopenharmony_ci add_kind_filtering_cli, 117db96d56Sopenharmony_ci add_files_cli, 127db96d56Sopenharmony_ci add_progress_cli, 137db96d56Sopenharmony_ci main_for_filenames, 147db96d56Sopenharmony_ci process_args_by_key, 157db96d56Sopenharmony_ci configure_logger, 167db96d56Sopenharmony_ci get_prog, 177db96d56Sopenharmony_ci) 187db96d56Sopenharmony_cifrom c_parser.info import KIND 197db96d56Sopenharmony_ciimport c_parser.__main__ as c_parser 207db96d56Sopenharmony_ciimport c_analyzer.__main__ as c_analyzer 217db96d56Sopenharmony_ciimport c_analyzer as _c_analyzer 227db96d56Sopenharmony_cifrom c_analyzer.info import UNKNOWN 237db96d56Sopenharmony_cifrom . import _analyzer, _capi, _files, _parser, REPO_ROOT 247db96d56Sopenharmony_ci 257db96d56Sopenharmony_ci 267db96d56Sopenharmony_cilogger = logging.getLogger(__name__) 277db96d56Sopenharmony_ci 287db96d56Sopenharmony_ci 297db96d56Sopenharmony_cidef _resolve_filenames(filenames): 307db96d56Sopenharmony_ci if filenames: 317db96d56Sopenharmony_ci resolved = (_files.resolve_filename(f) for f in filenames) 327db96d56Sopenharmony_ci else: 337db96d56Sopenharmony_ci resolved = _files.iter_filenames() 347db96d56Sopenharmony_ci return resolved 357db96d56Sopenharmony_ci 367db96d56Sopenharmony_ci 377db96d56Sopenharmony_ci####################################### 387db96d56Sopenharmony_ci# the formats 397db96d56Sopenharmony_ci 407db96d56Sopenharmony_cidef fmt_summary(analysis): 417db96d56Sopenharmony_ci # XXX Support sorting and grouping. 427db96d56Sopenharmony_ci supported = [] 437db96d56Sopenharmony_ci unsupported = [] 447db96d56Sopenharmony_ci for item in analysis: 457db96d56Sopenharmony_ci if item.supported: 467db96d56Sopenharmony_ci supported.append(item) 477db96d56Sopenharmony_ci else: 487db96d56Sopenharmony_ci unsupported.append(item) 497db96d56Sopenharmony_ci total = 0 507db96d56Sopenharmony_ci 517db96d56Sopenharmony_ci def section(name, groupitems): 527db96d56Sopenharmony_ci nonlocal total 537db96d56Sopenharmony_ci items, render = c_analyzer.build_section(name, groupitems, 547db96d56Sopenharmony_ci relroot=REPO_ROOT) 557db96d56Sopenharmony_ci yield from render() 567db96d56Sopenharmony_ci total += len(items) 577db96d56Sopenharmony_ci 587db96d56Sopenharmony_ci yield '' 597db96d56Sopenharmony_ci yield '====================' 607db96d56Sopenharmony_ci yield 'supported' 617db96d56Sopenharmony_ci yield '====================' 627db96d56Sopenharmony_ci 637db96d56Sopenharmony_ci yield from section('types', supported) 647db96d56Sopenharmony_ci yield from section('variables', supported) 657db96d56Sopenharmony_ci 667db96d56Sopenharmony_ci yield '' 677db96d56Sopenharmony_ci yield '====================' 687db96d56Sopenharmony_ci yield 'unsupported' 697db96d56Sopenharmony_ci yield '====================' 707db96d56Sopenharmony_ci 717db96d56Sopenharmony_ci yield from section('types', unsupported) 727db96d56Sopenharmony_ci yield from section('variables', unsupported) 737db96d56Sopenharmony_ci 747db96d56Sopenharmony_ci yield '' 757db96d56Sopenharmony_ci yield f'grand total: {total}' 767db96d56Sopenharmony_ci 777db96d56Sopenharmony_ci 787db96d56Sopenharmony_ci####################################### 797db96d56Sopenharmony_ci# the checks 807db96d56Sopenharmony_ci 817db96d56Sopenharmony_ciCHECKS = dict(c_analyzer.CHECKS, **{ 827db96d56Sopenharmony_ci 'globals': _analyzer.check_globals, 837db96d56Sopenharmony_ci}) 847db96d56Sopenharmony_ci 857db96d56Sopenharmony_ci####################################### 867db96d56Sopenharmony_ci# the commands 877db96d56Sopenharmony_ci 887db96d56Sopenharmony_ciFILES_KWARGS = dict(excluded=_parser.EXCLUDED, nargs='*') 897db96d56Sopenharmony_ci 907db96d56Sopenharmony_ci 917db96d56Sopenharmony_cidef _cli_parse(parser): 927db96d56Sopenharmony_ci process_output = c_parser.add_output_cli(parser) 937db96d56Sopenharmony_ci process_kind = add_kind_filtering_cli(parser) 947db96d56Sopenharmony_ci process_preprocessor = c_parser.add_preprocessor_cli( 957db96d56Sopenharmony_ci parser, 967db96d56Sopenharmony_ci get_preprocessor=_parser.get_preprocessor, 977db96d56Sopenharmony_ci ) 987db96d56Sopenharmony_ci process_files = add_files_cli(parser, **FILES_KWARGS) 997db96d56Sopenharmony_ci return [ 1007db96d56Sopenharmony_ci process_output, 1017db96d56Sopenharmony_ci process_kind, 1027db96d56Sopenharmony_ci process_preprocessor, 1037db96d56Sopenharmony_ci process_files, 1047db96d56Sopenharmony_ci ] 1057db96d56Sopenharmony_ci 1067db96d56Sopenharmony_ci 1077db96d56Sopenharmony_cidef cmd_parse(filenames=None, **kwargs): 1087db96d56Sopenharmony_ci filenames = _resolve_filenames(filenames) 1097db96d56Sopenharmony_ci if 'get_file_preprocessor' not in kwargs: 1107db96d56Sopenharmony_ci kwargs['get_file_preprocessor'] = _parser.get_preprocessor() 1117db96d56Sopenharmony_ci c_parser.cmd_parse( 1127db96d56Sopenharmony_ci filenames, 1137db96d56Sopenharmony_ci relroot=REPO_ROOT, 1147db96d56Sopenharmony_ci file_maxsizes=_parser.MAX_SIZES, 1157db96d56Sopenharmony_ci **kwargs 1167db96d56Sopenharmony_ci ) 1177db96d56Sopenharmony_ci 1187db96d56Sopenharmony_ci 1197db96d56Sopenharmony_cidef _cli_check(parser, **kwargs): 1207db96d56Sopenharmony_ci return c_analyzer._cli_check(parser, CHECKS, **kwargs, **FILES_KWARGS) 1217db96d56Sopenharmony_ci 1227db96d56Sopenharmony_ci 1237db96d56Sopenharmony_cidef cmd_check(filenames=None, **kwargs): 1247db96d56Sopenharmony_ci filenames = _resolve_filenames(filenames) 1257db96d56Sopenharmony_ci kwargs['get_file_preprocessor'] = _parser.get_preprocessor(log_err=print) 1267db96d56Sopenharmony_ci c_analyzer.cmd_check( 1277db96d56Sopenharmony_ci filenames, 1287db96d56Sopenharmony_ci relroot=REPO_ROOT, 1297db96d56Sopenharmony_ci _analyze=_analyzer.analyze, 1307db96d56Sopenharmony_ci _CHECKS=CHECKS, 1317db96d56Sopenharmony_ci file_maxsizes=_parser.MAX_SIZES, 1327db96d56Sopenharmony_ci **kwargs 1337db96d56Sopenharmony_ci ) 1347db96d56Sopenharmony_ci 1357db96d56Sopenharmony_ci 1367db96d56Sopenharmony_cidef cmd_analyze(filenames=None, **kwargs): 1377db96d56Sopenharmony_ci formats = dict(c_analyzer.FORMATS) 1387db96d56Sopenharmony_ci formats['summary'] = fmt_summary 1397db96d56Sopenharmony_ci filenames = _resolve_filenames(filenames) 1407db96d56Sopenharmony_ci kwargs['get_file_preprocessor'] = _parser.get_preprocessor(log_err=print) 1417db96d56Sopenharmony_ci c_analyzer.cmd_analyze( 1427db96d56Sopenharmony_ci filenames, 1437db96d56Sopenharmony_ci relroot=REPO_ROOT, 1447db96d56Sopenharmony_ci _analyze=_analyzer.analyze, 1457db96d56Sopenharmony_ci formats=formats, 1467db96d56Sopenharmony_ci file_maxsizes=_parser.MAX_SIZES, 1477db96d56Sopenharmony_ci **kwargs 1487db96d56Sopenharmony_ci ) 1497db96d56Sopenharmony_ci 1507db96d56Sopenharmony_ci 1517db96d56Sopenharmony_cidef _cli_data(parser): 1527db96d56Sopenharmony_ci filenames = False 1537db96d56Sopenharmony_ci known = True 1547db96d56Sopenharmony_ci return c_analyzer._cli_data(parser, filenames, known) 1557db96d56Sopenharmony_ci 1567db96d56Sopenharmony_ci 1577db96d56Sopenharmony_cidef cmd_data(datacmd, **kwargs): 1587db96d56Sopenharmony_ci formats = dict(c_analyzer.FORMATS) 1597db96d56Sopenharmony_ci formats['summary'] = fmt_summary 1607db96d56Sopenharmony_ci filenames = (file 1617db96d56Sopenharmony_ci for file in _resolve_filenames(None) 1627db96d56Sopenharmony_ci if file not in _parser.EXCLUDED) 1637db96d56Sopenharmony_ci kwargs['get_file_preprocessor'] = _parser.get_preprocessor(log_err=print) 1647db96d56Sopenharmony_ci if datacmd == 'show': 1657db96d56Sopenharmony_ci types = _analyzer.read_known() 1667db96d56Sopenharmony_ci results = [] 1677db96d56Sopenharmony_ci for decl, info in types.items(): 1687db96d56Sopenharmony_ci if info is UNKNOWN: 1697db96d56Sopenharmony_ci if decl.kind in (KIND.STRUCT, KIND.UNION): 1707db96d56Sopenharmony_ci extra = {'unsupported': ['type unknown'] * len(decl.members)} 1717db96d56Sopenharmony_ci else: 1727db96d56Sopenharmony_ci extra = {'unsupported': ['type unknown']} 1737db96d56Sopenharmony_ci info = (info, extra) 1747db96d56Sopenharmony_ci results.append((decl, info)) 1757db96d56Sopenharmony_ci if decl.shortkey == 'struct _object': 1767db96d56Sopenharmony_ci tempinfo = info 1777db96d56Sopenharmony_ci known = _analyzer.Analysis.from_results(results) 1787db96d56Sopenharmony_ci analyze = None 1797db96d56Sopenharmony_ci elif datacmd == 'dump': 1807db96d56Sopenharmony_ci known = _analyzer.KNOWN_FILE 1817db96d56Sopenharmony_ci def analyze(files, **kwargs): 1827db96d56Sopenharmony_ci decls = [] 1837db96d56Sopenharmony_ci for decl in _analyzer.iter_decls(files, **kwargs): 1847db96d56Sopenharmony_ci if not KIND.is_type_decl(decl.kind): 1857db96d56Sopenharmony_ci continue 1867db96d56Sopenharmony_ci if not decl.filename.endswith('.h'): 1877db96d56Sopenharmony_ci if decl.shortkey not in _analyzer.KNOWN_IN_DOT_C: 1887db96d56Sopenharmony_ci continue 1897db96d56Sopenharmony_ci decls.append(decl) 1907db96d56Sopenharmony_ci results = _c_analyzer.analyze_decls( 1917db96d56Sopenharmony_ci decls, 1927db96d56Sopenharmony_ci known={}, 1937db96d56Sopenharmony_ci analyze_resolved=_analyzer.analyze_resolved, 1947db96d56Sopenharmony_ci ) 1957db96d56Sopenharmony_ci return _analyzer.Analysis.from_results(results) 1967db96d56Sopenharmony_ci else: # check 1977db96d56Sopenharmony_ci known = _analyzer.read_known() 1987db96d56Sopenharmony_ci def analyze(files, **kwargs): 1997db96d56Sopenharmony_ci return _analyzer.iter_decls(files, **kwargs) 2007db96d56Sopenharmony_ci extracolumns = None 2017db96d56Sopenharmony_ci c_analyzer.cmd_data( 2027db96d56Sopenharmony_ci datacmd, 2037db96d56Sopenharmony_ci filenames, 2047db96d56Sopenharmony_ci known, 2057db96d56Sopenharmony_ci _analyze=analyze, 2067db96d56Sopenharmony_ci formats=formats, 2077db96d56Sopenharmony_ci extracolumns=extracolumns, 2087db96d56Sopenharmony_ci relroot=REPO_ROOT, 2097db96d56Sopenharmony_ci **kwargs 2107db96d56Sopenharmony_ci ) 2117db96d56Sopenharmony_ci 2127db96d56Sopenharmony_ci 2137db96d56Sopenharmony_cidef _cli_capi(parser): 2147db96d56Sopenharmony_ci parser.add_argument('--levels', action='append', metavar='LEVEL[,...]') 2157db96d56Sopenharmony_ci parser.add_argument(f'--public', dest='levels', 2167db96d56Sopenharmony_ci action='append_const', const='public') 2177db96d56Sopenharmony_ci parser.add_argument(f'--no-public', dest='levels', 2187db96d56Sopenharmony_ci action='append_const', const='no-public') 2197db96d56Sopenharmony_ci for level in _capi.LEVELS: 2207db96d56Sopenharmony_ci parser.add_argument(f'--{level}', dest='levels', 2217db96d56Sopenharmony_ci action='append_const', const=level) 2227db96d56Sopenharmony_ci def process_levels(args, *, argv=None): 2237db96d56Sopenharmony_ci levels = [] 2247db96d56Sopenharmony_ci for raw in args.levels or (): 2257db96d56Sopenharmony_ci for level in raw.replace(',', ' ').strip().split(): 2267db96d56Sopenharmony_ci if level == 'public': 2277db96d56Sopenharmony_ci levels.append('stable') 2287db96d56Sopenharmony_ci levels.append('cpython') 2297db96d56Sopenharmony_ci elif level == 'no-public': 2307db96d56Sopenharmony_ci levels.append('private') 2317db96d56Sopenharmony_ci levels.append('internal') 2327db96d56Sopenharmony_ci elif level in _capi.LEVELS: 2337db96d56Sopenharmony_ci levels.append(level) 2347db96d56Sopenharmony_ci else: 2357db96d56Sopenharmony_ci parser.error(f'expected LEVEL to be one of {sorted(_capi.LEVELS)}, got {level!r}') 2367db96d56Sopenharmony_ci args.levels = set(levels) 2377db96d56Sopenharmony_ci 2387db96d56Sopenharmony_ci parser.add_argument('--kinds', action='append', metavar='KIND[,...]') 2397db96d56Sopenharmony_ci for kind in _capi.KINDS: 2407db96d56Sopenharmony_ci parser.add_argument(f'--{kind}', dest='kinds', 2417db96d56Sopenharmony_ci action='append_const', const=kind) 2427db96d56Sopenharmony_ci def process_kinds(args, *, argv=None): 2437db96d56Sopenharmony_ci kinds = [] 2447db96d56Sopenharmony_ci for raw in args.kinds or (): 2457db96d56Sopenharmony_ci for kind in raw.replace(',', ' ').strip().split(): 2467db96d56Sopenharmony_ci if kind in _capi.KINDS: 2477db96d56Sopenharmony_ci kinds.append(kind) 2487db96d56Sopenharmony_ci else: 2497db96d56Sopenharmony_ci parser.error(f'expected KIND to be one of {sorted(_capi.KINDS)}, got {kind!r}') 2507db96d56Sopenharmony_ci args.kinds = set(kinds) 2517db96d56Sopenharmony_ci 2527db96d56Sopenharmony_ci parser.add_argument('--group-by', dest='groupby', 2537db96d56Sopenharmony_ci choices=['level', 'kind']) 2547db96d56Sopenharmony_ci 2557db96d56Sopenharmony_ci parser.add_argument('--format', default='table') 2567db96d56Sopenharmony_ci parser.add_argument('--summary', dest='format', 2577db96d56Sopenharmony_ci action='store_const', const='summary') 2587db96d56Sopenharmony_ci def process_format(args, *, argv=None): 2597db96d56Sopenharmony_ci orig = args.format 2607db96d56Sopenharmony_ci args.format = _capi.resolve_format(args.format) 2617db96d56Sopenharmony_ci if isinstance(args.format, str): 2627db96d56Sopenharmony_ci if args.format not in _capi._FORMATS: 2637db96d56Sopenharmony_ci parser.error(f'unsupported format {orig!r}') 2647db96d56Sopenharmony_ci 2657db96d56Sopenharmony_ci parser.add_argument('--show-empty', dest='showempty', action='store_true') 2667db96d56Sopenharmony_ci parser.add_argument('--no-show-empty', dest='showempty', action='store_false') 2677db96d56Sopenharmony_ci parser.set_defaults(showempty=None) 2687db96d56Sopenharmony_ci 2697db96d56Sopenharmony_ci # XXX Add --sort-by, --sort and --no-sort. 2707db96d56Sopenharmony_ci 2717db96d56Sopenharmony_ci parser.add_argument('--ignore', dest='ignored', action='append') 2727db96d56Sopenharmony_ci def process_ignored(args, *, argv=None): 2737db96d56Sopenharmony_ci ignored = [] 2747db96d56Sopenharmony_ci for raw in args.ignored or (): 2757db96d56Sopenharmony_ci ignored.extend(raw.replace(',', ' ').strip().split()) 2767db96d56Sopenharmony_ci args.ignored = ignored or None 2777db96d56Sopenharmony_ci 2787db96d56Sopenharmony_ci parser.add_argument('filenames', nargs='*', metavar='FILENAME') 2797db96d56Sopenharmony_ci process_progress = add_progress_cli(parser) 2807db96d56Sopenharmony_ci 2817db96d56Sopenharmony_ci return [ 2827db96d56Sopenharmony_ci process_levels, 2837db96d56Sopenharmony_ci process_kinds, 2847db96d56Sopenharmony_ci process_format, 2857db96d56Sopenharmony_ci process_ignored, 2867db96d56Sopenharmony_ci process_progress, 2877db96d56Sopenharmony_ci ] 2887db96d56Sopenharmony_ci 2897db96d56Sopenharmony_ci 2907db96d56Sopenharmony_cidef cmd_capi(filenames=None, *, 2917db96d56Sopenharmony_ci levels=None, 2927db96d56Sopenharmony_ci kinds=None, 2937db96d56Sopenharmony_ci groupby='kind', 2947db96d56Sopenharmony_ci format='table', 2957db96d56Sopenharmony_ci showempty=None, 2967db96d56Sopenharmony_ci ignored=None, 2977db96d56Sopenharmony_ci track_progress=None, 2987db96d56Sopenharmony_ci verbosity=VERBOSITY, 2997db96d56Sopenharmony_ci **kwargs 3007db96d56Sopenharmony_ci ): 3017db96d56Sopenharmony_ci render = _capi.get_renderer(format) 3027db96d56Sopenharmony_ci 3037db96d56Sopenharmony_ci filenames = _files.iter_header_files(filenames, levels=levels) 3047db96d56Sopenharmony_ci #filenames = (file for file, _ in main_for_filenames(filenames)) 3057db96d56Sopenharmony_ci if track_progress: 3067db96d56Sopenharmony_ci filenames = track_progress(filenames) 3077db96d56Sopenharmony_ci items = _capi.iter_capi(filenames) 3087db96d56Sopenharmony_ci if levels: 3097db96d56Sopenharmony_ci items = (item for item in items if item.level in levels) 3107db96d56Sopenharmony_ci if kinds: 3117db96d56Sopenharmony_ci items = (item for item in items if item.kind in kinds) 3127db96d56Sopenharmony_ci 3137db96d56Sopenharmony_ci filter = _capi.resolve_filter(ignored) 3147db96d56Sopenharmony_ci if filter: 3157db96d56Sopenharmony_ci items = (item for item in items if filter(item, log=lambda msg: logger.log(1, msg))) 3167db96d56Sopenharmony_ci 3177db96d56Sopenharmony_ci lines = render( 3187db96d56Sopenharmony_ci items, 3197db96d56Sopenharmony_ci groupby=groupby, 3207db96d56Sopenharmony_ci showempty=showempty, 3217db96d56Sopenharmony_ci verbose=verbosity > VERBOSITY, 3227db96d56Sopenharmony_ci ) 3237db96d56Sopenharmony_ci print() 3247db96d56Sopenharmony_ci for line in lines: 3257db96d56Sopenharmony_ci print(line) 3267db96d56Sopenharmony_ci 3277db96d56Sopenharmony_ci 3287db96d56Sopenharmony_ci# We do not define any other cmd_*() handlers here, 3297db96d56Sopenharmony_ci# favoring those defined elsewhere. 3307db96d56Sopenharmony_ci 3317db96d56Sopenharmony_ciCOMMANDS = { 3327db96d56Sopenharmony_ci 'check': ( 3337db96d56Sopenharmony_ci 'analyze and fail if the CPython source code has any problems', 3347db96d56Sopenharmony_ci [_cli_check], 3357db96d56Sopenharmony_ci cmd_check, 3367db96d56Sopenharmony_ci ), 3377db96d56Sopenharmony_ci 'analyze': ( 3387db96d56Sopenharmony_ci 'report on the state of the CPython source code', 3397db96d56Sopenharmony_ci [(lambda p: c_analyzer._cli_analyze(p, **FILES_KWARGS))], 3407db96d56Sopenharmony_ci cmd_analyze, 3417db96d56Sopenharmony_ci ), 3427db96d56Sopenharmony_ci 'parse': ( 3437db96d56Sopenharmony_ci 'parse the CPython source files', 3447db96d56Sopenharmony_ci [_cli_parse], 3457db96d56Sopenharmony_ci cmd_parse, 3467db96d56Sopenharmony_ci ), 3477db96d56Sopenharmony_ci 'data': ( 3487db96d56Sopenharmony_ci 'check/manage local data (e.g. known types, ignored vars, caches)', 3497db96d56Sopenharmony_ci [_cli_data], 3507db96d56Sopenharmony_ci cmd_data, 3517db96d56Sopenharmony_ci ), 3527db96d56Sopenharmony_ci 'capi': ( 3537db96d56Sopenharmony_ci 'inspect the C-API', 3547db96d56Sopenharmony_ci [_cli_capi], 3557db96d56Sopenharmony_ci cmd_capi, 3567db96d56Sopenharmony_ci ), 3577db96d56Sopenharmony_ci} 3587db96d56Sopenharmony_ci 3597db96d56Sopenharmony_ci 3607db96d56Sopenharmony_ci####################################### 3617db96d56Sopenharmony_ci# the script 3627db96d56Sopenharmony_ci 3637db96d56Sopenharmony_cidef parse_args(argv=sys.argv[1:], prog=None, *, subset=None): 3647db96d56Sopenharmony_ci import argparse 3657db96d56Sopenharmony_ci parser = argparse.ArgumentParser( 3667db96d56Sopenharmony_ci prog=prog or get_prog(), 3677db96d56Sopenharmony_ci ) 3687db96d56Sopenharmony_ci 3697db96d56Sopenharmony_ci# if subset == 'check' or subset == ['check']: 3707db96d56Sopenharmony_ci# if checks is not None: 3717db96d56Sopenharmony_ci# commands = dict(COMMANDS) 3727db96d56Sopenharmony_ci# commands['check'] = list(commands['check']) 3737db96d56Sopenharmony_ci# cli = commands['check'][1][0] 3747db96d56Sopenharmony_ci# commands['check'][1][0] = (lambda p: cli(p, checks=checks)) 3757db96d56Sopenharmony_ci processors = add_commands_cli( 3767db96d56Sopenharmony_ci parser, 3777db96d56Sopenharmony_ci commands=COMMANDS, 3787db96d56Sopenharmony_ci commonspecs=[ 3797db96d56Sopenharmony_ci add_verbosity_cli, 3807db96d56Sopenharmony_ci add_traceback_cli, 3817db96d56Sopenharmony_ci ], 3827db96d56Sopenharmony_ci subset=subset, 3837db96d56Sopenharmony_ci ) 3847db96d56Sopenharmony_ci 3857db96d56Sopenharmony_ci args = parser.parse_args(argv) 3867db96d56Sopenharmony_ci ns = vars(args) 3877db96d56Sopenharmony_ci 3887db96d56Sopenharmony_ci cmd = ns.pop('cmd') 3897db96d56Sopenharmony_ci 3907db96d56Sopenharmony_ci verbosity, traceback_cm = process_args_by_key( 3917db96d56Sopenharmony_ci args, 3927db96d56Sopenharmony_ci argv, 3937db96d56Sopenharmony_ci processors[cmd], 3947db96d56Sopenharmony_ci ['verbosity', 'traceback_cm'], 3957db96d56Sopenharmony_ci ) 3967db96d56Sopenharmony_ci if cmd != 'parse': 3977db96d56Sopenharmony_ci # "verbosity" is sent to the commands, so we put it back. 3987db96d56Sopenharmony_ci args.verbosity = verbosity 3997db96d56Sopenharmony_ci 4007db96d56Sopenharmony_ci return cmd, ns, verbosity, traceback_cm 4017db96d56Sopenharmony_ci 4027db96d56Sopenharmony_ci 4037db96d56Sopenharmony_cidef main(cmd, cmd_kwargs): 4047db96d56Sopenharmony_ci try: 4057db96d56Sopenharmony_ci run_cmd = COMMANDS[cmd][-1] 4067db96d56Sopenharmony_ci except KeyError: 4077db96d56Sopenharmony_ci raise ValueError(f'unsupported cmd {cmd!r}') 4087db96d56Sopenharmony_ci run_cmd(**cmd_kwargs) 4097db96d56Sopenharmony_ci 4107db96d56Sopenharmony_ci 4117db96d56Sopenharmony_ciif __name__ == '__main__': 4127db96d56Sopenharmony_ci cmd, cmd_kwargs, verbosity, traceback_cm = parse_args() 4137db96d56Sopenharmony_ci configure_logger(verbosity) 4147db96d56Sopenharmony_ci with traceback_cm: 4157db96d56Sopenharmony_ci main(cmd, cmd_kwargs) 416