17db96d56Sopenharmony_ciimport io 27db96d56Sopenharmony_ciimport logging 37db96d56Sopenharmony_ciimport os 47db96d56Sopenharmony_ciimport os.path 57db96d56Sopenharmony_ciimport re 67db96d56Sopenharmony_ciimport sys 77db96d56Sopenharmony_ci 87db96d56Sopenharmony_cifrom c_common import fsutil 97db96d56Sopenharmony_cifrom c_common.logging import VERBOSITY, Printer 107db96d56Sopenharmony_cifrom c_common.scriptutil import ( 117db96d56Sopenharmony_ci add_verbosity_cli, 127db96d56Sopenharmony_ci add_traceback_cli, 137db96d56Sopenharmony_ci add_sepval_cli, 147db96d56Sopenharmony_ci add_progress_cli, 157db96d56Sopenharmony_ci add_files_cli, 167db96d56Sopenharmony_ci add_commands_cli, 177db96d56Sopenharmony_ci process_args_by_key, 187db96d56Sopenharmony_ci configure_logger, 197db96d56Sopenharmony_ci get_prog, 207db96d56Sopenharmony_ci filter_filenames, 217db96d56Sopenharmony_ci iter_marks, 227db96d56Sopenharmony_ci) 237db96d56Sopenharmony_cifrom c_parser.info import KIND 247db96d56Sopenharmony_cifrom c_parser.match import is_type_decl 257db96d56Sopenharmony_cifrom .match import filter_forward 267db96d56Sopenharmony_cifrom . import ( 277db96d56Sopenharmony_ci analyze as _analyze, 287db96d56Sopenharmony_ci datafiles as _datafiles, 297db96d56Sopenharmony_ci check_all as _check_all, 307db96d56Sopenharmony_ci) 317db96d56Sopenharmony_ci 327db96d56Sopenharmony_ci 337db96d56Sopenharmony_ciKINDS = [ 347db96d56Sopenharmony_ci KIND.TYPEDEF, 357db96d56Sopenharmony_ci KIND.STRUCT, 367db96d56Sopenharmony_ci KIND.UNION, 377db96d56Sopenharmony_ci KIND.ENUM, 387db96d56Sopenharmony_ci KIND.FUNCTION, 397db96d56Sopenharmony_ci KIND.VARIABLE, 407db96d56Sopenharmony_ci KIND.STATEMENT, 417db96d56Sopenharmony_ci] 427db96d56Sopenharmony_ci 437db96d56Sopenharmony_cilogger = logging.getLogger(__name__) 447db96d56Sopenharmony_ci 457db96d56Sopenharmony_ci 467db96d56Sopenharmony_ci####################################### 477db96d56Sopenharmony_ci# table helpers 487db96d56Sopenharmony_ci 497db96d56Sopenharmony_ciTABLE_SECTIONS = { 507db96d56Sopenharmony_ci 'types': ( 517db96d56Sopenharmony_ci ['kind', 'name', 'data', 'file'], 527db96d56Sopenharmony_ci KIND.is_type_decl, 537db96d56Sopenharmony_ci (lambda v: (v.kind.value, v.filename or '', v.name)), 547db96d56Sopenharmony_ci ), 557db96d56Sopenharmony_ci 'typedefs': 'types', 567db96d56Sopenharmony_ci 'structs': 'types', 577db96d56Sopenharmony_ci 'unions': 'types', 587db96d56Sopenharmony_ci 'enums': 'types', 597db96d56Sopenharmony_ci 'functions': ( 607db96d56Sopenharmony_ci ['name', 'data', 'file'], 617db96d56Sopenharmony_ci (lambda kind: kind is KIND.FUNCTION), 627db96d56Sopenharmony_ci (lambda v: (v.filename or '', v.name)), 637db96d56Sopenharmony_ci ), 647db96d56Sopenharmony_ci 'variables': ( 657db96d56Sopenharmony_ci ['name', 'parent', 'data', 'file'], 667db96d56Sopenharmony_ci (lambda kind: kind is KIND.VARIABLE), 677db96d56Sopenharmony_ci (lambda v: (v.filename or '', str(v.parent) if v.parent else '', v.name)), 687db96d56Sopenharmony_ci ), 697db96d56Sopenharmony_ci 'statements': ( 707db96d56Sopenharmony_ci ['file', 'parent', 'data'], 717db96d56Sopenharmony_ci (lambda kind: kind is KIND.STATEMENT), 727db96d56Sopenharmony_ci (lambda v: (v.filename or '', str(v.parent) if v.parent else '', v.name)), 737db96d56Sopenharmony_ci ), 747db96d56Sopenharmony_ci KIND.TYPEDEF: 'typedefs', 757db96d56Sopenharmony_ci KIND.STRUCT: 'structs', 767db96d56Sopenharmony_ci KIND.UNION: 'unions', 777db96d56Sopenharmony_ci KIND.ENUM: 'enums', 787db96d56Sopenharmony_ci KIND.FUNCTION: 'functions', 797db96d56Sopenharmony_ci KIND.VARIABLE: 'variables', 807db96d56Sopenharmony_ci KIND.STATEMENT: 'statements', 817db96d56Sopenharmony_ci} 827db96d56Sopenharmony_ci 837db96d56Sopenharmony_ci 847db96d56Sopenharmony_cidef _render_table(items, columns, relroot=None): 857db96d56Sopenharmony_ci # XXX improve this 867db96d56Sopenharmony_ci header = '\t'.join(columns) 877db96d56Sopenharmony_ci div = '--------------------' 887db96d56Sopenharmony_ci yield header 897db96d56Sopenharmony_ci yield div 907db96d56Sopenharmony_ci total = 0 917db96d56Sopenharmony_ci for item in items: 927db96d56Sopenharmony_ci rowdata = item.render_rowdata(columns) 937db96d56Sopenharmony_ci row = [rowdata[c] for c in columns] 947db96d56Sopenharmony_ci if relroot and 'file' in columns: 957db96d56Sopenharmony_ci index = columns.index('file') 967db96d56Sopenharmony_ci row[index] = os.path.relpath(row[index], relroot) 977db96d56Sopenharmony_ci yield '\t'.join(row) 987db96d56Sopenharmony_ci total += 1 997db96d56Sopenharmony_ci yield div 1007db96d56Sopenharmony_ci yield f'total: {total}' 1017db96d56Sopenharmony_ci 1027db96d56Sopenharmony_ci 1037db96d56Sopenharmony_cidef build_section(name, groupitems, *, relroot=None): 1047db96d56Sopenharmony_ci info = TABLE_SECTIONS[name] 1057db96d56Sopenharmony_ci while type(info) is not tuple: 1067db96d56Sopenharmony_ci if name in KINDS: 1077db96d56Sopenharmony_ci name = info 1087db96d56Sopenharmony_ci info = TABLE_SECTIONS[info] 1097db96d56Sopenharmony_ci 1107db96d56Sopenharmony_ci columns, match_kind, sortkey = info 1117db96d56Sopenharmony_ci items = (v for v in groupitems if match_kind(v.kind)) 1127db96d56Sopenharmony_ci items = sorted(items, key=sortkey) 1137db96d56Sopenharmony_ci def render(): 1147db96d56Sopenharmony_ci yield '' 1157db96d56Sopenharmony_ci yield f'{name}:' 1167db96d56Sopenharmony_ci yield '' 1177db96d56Sopenharmony_ci for line in _render_table(items, columns, relroot): 1187db96d56Sopenharmony_ci yield line 1197db96d56Sopenharmony_ci return items, render 1207db96d56Sopenharmony_ci 1217db96d56Sopenharmony_ci 1227db96d56Sopenharmony_ci####################################### 1237db96d56Sopenharmony_ci# the checks 1247db96d56Sopenharmony_ci 1257db96d56Sopenharmony_ciCHECKS = { 1267db96d56Sopenharmony_ci #'globals': _check_globals, 1277db96d56Sopenharmony_ci} 1287db96d56Sopenharmony_ci 1297db96d56Sopenharmony_ci 1307db96d56Sopenharmony_cidef add_checks_cli(parser, checks=None, *, add_flags=None): 1317db96d56Sopenharmony_ci default = False 1327db96d56Sopenharmony_ci if not checks: 1337db96d56Sopenharmony_ci checks = list(CHECKS) 1347db96d56Sopenharmony_ci default = True 1357db96d56Sopenharmony_ci elif isinstance(checks, str): 1367db96d56Sopenharmony_ci checks = [checks] 1377db96d56Sopenharmony_ci if (add_flags is None and len(checks) > 1) or default: 1387db96d56Sopenharmony_ci add_flags = True 1397db96d56Sopenharmony_ci 1407db96d56Sopenharmony_ci process_checks = add_sepval_cli(parser, '--check', 'checks', checks) 1417db96d56Sopenharmony_ci if add_flags: 1427db96d56Sopenharmony_ci for check in checks: 1437db96d56Sopenharmony_ci parser.add_argument(f'--{check}', dest='checks', 1447db96d56Sopenharmony_ci action='append_const', const=check) 1457db96d56Sopenharmony_ci return [ 1467db96d56Sopenharmony_ci process_checks, 1477db96d56Sopenharmony_ci ] 1487db96d56Sopenharmony_ci 1497db96d56Sopenharmony_ci 1507db96d56Sopenharmony_cidef _get_check_handlers(fmt, printer, verbosity=VERBOSITY): 1517db96d56Sopenharmony_ci div = None 1527db96d56Sopenharmony_ci def handle_after(): 1537db96d56Sopenharmony_ci pass 1547db96d56Sopenharmony_ci if not fmt: 1557db96d56Sopenharmony_ci div = '' 1567db96d56Sopenharmony_ci def handle_failure(failure, data): 1577db96d56Sopenharmony_ci data = repr(data) 1587db96d56Sopenharmony_ci if verbosity >= 3: 1597db96d56Sopenharmony_ci logger.info(f'failure: {failure}') 1607db96d56Sopenharmony_ci logger.info(f'data: {data}') 1617db96d56Sopenharmony_ci else: 1627db96d56Sopenharmony_ci logger.warn(f'failure: {failure} (data: {data})') 1637db96d56Sopenharmony_ci elif fmt == 'raw': 1647db96d56Sopenharmony_ci def handle_failure(failure, data): 1657db96d56Sopenharmony_ci print(f'{failure!r} {data!r}') 1667db96d56Sopenharmony_ci elif fmt == 'brief': 1677db96d56Sopenharmony_ci def handle_failure(failure, data): 1687db96d56Sopenharmony_ci parent = data.parent or '' 1697db96d56Sopenharmony_ci funcname = parent if isinstance(parent, str) else parent.name 1707db96d56Sopenharmony_ci name = f'({funcname}).{data.name}' if funcname else data.name 1717db96d56Sopenharmony_ci failure = failure.split('\t')[0] 1727db96d56Sopenharmony_ci print(f'{data.filename}:{name} - {failure}') 1737db96d56Sopenharmony_ci elif fmt == 'summary': 1747db96d56Sopenharmony_ci def handle_failure(failure, data): 1757db96d56Sopenharmony_ci print(_fmt_one_summary(data, failure)) 1767db96d56Sopenharmony_ci elif fmt == 'full': 1777db96d56Sopenharmony_ci div = '' 1787db96d56Sopenharmony_ci def handle_failure(failure, data): 1797db96d56Sopenharmony_ci name = data.shortkey if data.kind is KIND.VARIABLE else data.name 1807db96d56Sopenharmony_ci parent = data.parent or '' 1817db96d56Sopenharmony_ci funcname = parent if isinstance(parent, str) else parent.name 1827db96d56Sopenharmony_ci known = 'yes' if data.is_known else '*** NO ***' 1837db96d56Sopenharmony_ci print(f'{data.kind.value} {name!r} failed ({failure})') 1847db96d56Sopenharmony_ci print(f' file: {data.filename}') 1857db96d56Sopenharmony_ci print(f' func: {funcname or "-"}') 1867db96d56Sopenharmony_ci print(f' name: {data.name}') 1877db96d56Sopenharmony_ci print(f' data: ...') 1887db96d56Sopenharmony_ci print(f' type unknown: {known}') 1897db96d56Sopenharmony_ci else: 1907db96d56Sopenharmony_ci if fmt in FORMATS: 1917db96d56Sopenharmony_ci raise NotImplementedError(fmt) 1927db96d56Sopenharmony_ci raise ValueError(f'unsupported fmt {fmt!r}') 1937db96d56Sopenharmony_ci return handle_failure, handle_after, div 1947db96d56Sopenharmony_ci 1957db96d56Sopenharmony_ci 1967db96d56Sopenharmony_ci####################################### 1977db96d56Sopenharmony_ci# the formats 1987db96d56Sopenharmony_ci 1997db96d56Sopenharmony_cidef fmt_raw(analysis): 2007db96d56Sopenharmony_ci for item in analysis: 2017db96d56Sopenharmony_ci yield from item.render('raw') 2027db96d56Sopenharmony_ci 2037db96d56Sopenharmony_ci 2047db96d56Sopenharmony_cidef fmt_brief(analysis): 2057db96d56Sopenharmony_ci # XXX Support sorting. 2067db96d56Sopenharmony_ci items = sorted(analysis) 2077db96d56Sopenharmony_ci for kind in KINDS: 2087db96d56Sopenharmony_ci if kind is KIND.STATEMENT: 2097db96d56Sopenharmony_ci continue 2107db96d56Sopenharmony_ci for item in items: 2117db96d56Sopenharmony_ci if item.kind is not kind: 2127db96d56Sopenharmony_ci continue 2137db96d56Sopenharmony_ci yield from item.render('brief') 2147db96d56Sopenharmony_ci yield f' total: {len(items)}' 2157db96d56Sopenharmony_ci 2167db96d56Sopenharmony_ci 2177db96d56Sopenharmony_cidef fmt_summary(analysis): 2187db96d56Sopenharmony_ci # XXX Support sorting and grouping. 2197db96d56Sopenharmony_ci items = list(analysis) 2207db96d56Sopenharmony_ci total = len(items) 2217db96d56Sopenharmony_ci 2227db96d56Sopenharmony_ci def section(name): 2237db96d56Sopenharmony_ci _, render = build_section(name, items) 2247db96d56Sopenharmony_ci yield from render() 2257db96d56Sopenharmony_ci 2267db96d56Sopenharmony_ci yield from section('types') 2277db96d56Sopenharmony_ci yield from section('functions') 2287db96d56Sopenharmony_ci yield from section('variables') 2297db96d56Sopenharmony_ci yield from section('statements') 2307db96d56Sopenharmony_ci 2317db96d56Sopenharmony_ci yield '' 2327db96d56Sopenharmony_ci# yield f'grand total: {len(supported) + len(unsupported)}' 2337db96d56Sopenharmony_ci yield f'grand total: {total}' 2347db96d56Sopenharmony_ci 2357db96d56Sopenharmony_ci 2367db96d56Sopenharmony_cidef _fmt_one_summary(item, extra=None): 2377db96d56Sopenharmony_ci parent = item.parent or '' 2387db96d56Sopenharmony_ci funcname = parent if isinstance(parent, str) else parent.name 2397db96d56Sopenharmony_ci if extra: 2407db96d56Sopenharmony_ci return f'{item.filename:35}\t{funcname or "-":35}\t{item.name:40}\t{extra}' 2417db96d56Sopenharmony_ci else: 2427db96d56Sopenharmony_ci return f'{item.filename:35}\t{funcname or "-":35}\t{item.name}' 2437db96d56Sopenharmony_ci 2447db96d56Sopenharmony_ci 2457db96d56Sopenharmony_cidef fmt_full(analysis): 2467db96d56Sopenharmony_ci # XXX Support sorting. 2477db96d56Sopenharmony_ci items = sorted(analysis, key=lambda v: v.key) 2487db96d56Sopenharmony_ci yield '' 2497db96d56Sopenharmony_ci for item in items: 2507db96d56Sopenharmony_ci yield from item.render('full') 2517db96d56Sopenharmony_ci yield '' 2527db96d56Sopenharmony_ci yield f'total: {len(items)}' 2537db96d56Sopenharmony_ci 2547db96d56Sopenharmony_ci 2557db96d56Sopenharmony_ciFORMATS = { 2567db96d56Sopenharmony_ci 'raw': fmt_raw, 2577db96d56Sopenharmony_ci 'brief': fmt_brief, 2587db96d56Sopenharmony_ci 'summary': fmt_summary, 2597db96d56Sopenharmony_ci 'full': fmt_full, 2607db96d56Sopenharmony_ci} 2617db96d56Sopenharmony_ci 2627db96d56Sopenharmony_ci 2637db96d56Sopenharmony_cidef add_output_cli(parser, *, default='summary'): 2647db96d56Sopenharmony_ci parser.add_argument('--format', dest='fmt', default=default, choices=tuple(FORMATS)) 2657db96d56Sopenharmony_ci 2667db96d56Sopenharmony_ci def process_args(args, *, argv=None): 2677db96d56Sopenharmony_ci pass 2687db96d56Sopenharmony_ci return process_args 2697db96d56Sopenharmony_ci 2707db96d56Sopenharmony_ci 2717db96d56Sopenharmony_ci####################################### 2727db96d56Sopenharmony_ci# the commands 2737db96d56Sopenharmony_ci 2747db96d56Sopenharmony_cidef _cli_check(parser, checks=None, **kwargs): 2757db96d56Sopenharmony_ci if isinstance(checks, str): 2767db96d56Sopenharmony_ci checks = [checks] 2777db96d56Sopenharmony_ci if checks is False: 2787db96d56Sopenharmony_ci process_checks = None 2797db96d56Sopenharmony_ci elif checks is None: 2807db96d56Sopenharmony_ci process_checks = add_checks_cli(parser) 2817db96d56Sopenharmony_ci elif len(checks) == 1 and type(checks) is not dict and re.match(r'^<.*>$', checks[0]): 2827db96d56Sopenharmony_ci check = checks[0][1:-1] 2837db96d56Sopenharmony_ci def process_checks(args, *, argv=None): 2847db96d56Sopenharmony_ci args.checks = [check] 2857db96d56Sopenharmony_ci else: 2867db96d56Sopenharmony_ci process_checks = add_checks_cli(parser, checks=checks) 2877db96d56Sopenharmony_ci process_progress = add_progress_cli(parser) 2887db96d56Sopenharmony_ci process_output = add_output_cli(parser, default=None) 2897db96d56Sopenharmony_ci process_files = add_files_cli(parser, **kwargs) 2907db96d56Sopenharmony_ci return [ 2917db96d56Sopenharmony_ci process_checks, 2927db96d56Sopenharmony_ci process_progress, 2937db96d56Sopenharmony_ci process_output, 2947db96d56Sopenharmony_ci process_files, 2957db96d56Sopenharmony_ci ] 2967db96d56Sopenharmony_ci 2977db96d56Sopenharmony_ci 2987db96d56Sopenharmony_cidef cmd_check(filenames, *, 2997db96d56Sopenharmony_ci checks=None, 3007db96d56Sopenharmony_ci ignored=None, 3017db96d56Sopenharmony_ci fmt=None, 3027db96d56Sopenharmony_ci failfast=False, 3037db96d56Sopenharmony_ci iter_filenames=None, 3047db96d56Sopenharmony_ci relroot=fsutil.USE_CWD, 3057db96d56Sopenharmony_ci track_progress=None, 3067db96d56Sopenharmony_ci verbosity=VERBOSITY, 3077db96d56Sopenharmony_ci _analyze=_analyze, 3087db96d56Sopenharmony_ci _CHECKS=CHECKS, 3097db96d56Sopenharmony_ci **kwargs 3107db96d56Sopenharmony_ci ): 3117db96d56Sopenharmony_ci if not checks: 3127db96d56Sopenharmony_ci checks = _CHECKS 3137db96d56Sopenharmony_ci elif isinstance(checks, str): 3147db96d56Sopenharmony_ci checks = [checks] 3157db96d56Sopenharmony_ci checks = [_CHECKS[c] if isinstance(c, str) else c 3167db96d56Sopenharmony_ci for c in checks] 3177db96d56Sopenharmony_ci printer = Printer(verbosity) 3187db96d56Sopenharmony_ci (handle_failure, handle_after, div 3197db96d56Sopenharmony_ci ) = _get_check_handlers(fmt, printer, verbosity) 3207db96d56Sopenharmony_ci 3217db96d56Sopenharmony_ci filenames, relroot = fsutil.fix_filenames(filenames, relroot=relroot) 3227db96d56Sopenharmony_ci filenames = filter_filenames(filenames, iter_filenames, relroot) 3237db96d56Sopenharmony_ci if track_progress: 3247db96d56Sopenharmony_ci filenames = track_progress(filenames) 3257db96d56Sopenharmony_ci 3267db96d56Sopenharmony_ci logger.info('analyzing files...') 3277db96d56Sopenharmony_ci analyzed = _analyze(filenames, **kwargs) 3287db96d56Sopenharmony_ci analyzed.fix_filenames(relroot, normalize=False) 3297db96d56Sopenharmony_ci decls = filter_forward(analyzed, markpublic=True) 3307db96d56Sopenharmony_ci 3317db96d56Sopenharmony_ci logger.info('checking analysis results...') 3327db96d56Sopenharmony_ci failed = [] 3337db96d56Sopenharmony_ci for data, failure in _check_all(decls, checks, failfast=failfast): 3347db96d56Sopenharmony_ci if data is None: 3357db96d56Sopenharmony_ci printer.info('stopping after one failure') 3367db96d56Sopenharmony_ci break 3377db96d56Sopenharmony_ci if div is not None and len(failed) > 0: 3387db96d56Sopenharmony_ci printer.info(div) 3397db96d56Sopenharmony_ci failed.append(data) 3407db96d56Sopenharmony_ci handle_failure(failure, data) 3417db96d56Sopenharmony_ci handle_after() 3427db96d56Sopenharmony_ci 3437db96d56Sopenharmony_ci printer.info('-------------------------') 3447db96d56Sopenharmony_ci logger.info(f'total failures: {len(failed)}') 3457db96d56Sopenharmony_ci logger.info('done checking') 3467db96d56Sopenharmony_ci 3477db96d56Sopenharmony_ci if fmt == 'summary': 3487db96d56Sopenharmony_ci print('Categorized by storage:') 3497db96d56Sopenharmony_ci print() 3507db96d56Sopenharmony_ci from .match import group_by_storage 3517db96d56Sopenharmony_ci grouped = group_by_storage(failed, ignore_non_match=False) 3527db96d56Sopenharmony_ci for group, decls in grouped.items(): 3537db96d56Sopenharmony_ci print() 3547db96d56Sopenharmony_ci print(group) 3557db96d56Sopenharmony_ci for decl in decls: 3567db96d56Sopenharmony_ci print(' ', _fmt_one_summary(decl)) 3577db96d56Sopenharmony_ci print(f'subtotal: {len(decls)}') 3587db96d56Sopenharmony_ci 3597db96d56Sopenharmony_ci if len(failed) > 0: 3607db96d56Sopenharmony_ci sys.exit(len(failed)) 3617db96d56Sopenharmony_ci 3627db96d56Sopenharmony_ci 3637db96d56Sopenharmony_cidef _cli_analyze(parser, **kwargs): 3647db96d56Sopenharmony_ci process_progress = add_progress_cli(parser) 3657db96d56Sopenharmony_ci process_output = add_output_cli(parser) 3667db96d56Sopenharmony_ci process_files = add_files_cli(parser, **kwargs) 3677db96d56Sopenharmony_ci return [ 3687db96d56Sopenharmony_ci process_progress, 3697db96d56Sopenharmony_ci process_output, 3707db96d56Sopenharmony_ci process_files, 3717db96d56Sopenharmony_ci ] 3727db96d56Sopenharmony_ci 3737db96d56Sopenharmony_ci 3747db96d56Sopenharmony_ci# XXX Support filtering by kind. 3757db96d56Sopenharmony_cidef cmd_analyze(filenames, *, 3767db96d56Sopenharmony_ci fmt=None, 3777db96d56Sopenharmony_ci iter_filenames=None, 3787db96d56Sopenharmony_ci relroot=fsutil.USE_CWD, 3797db96d56Sopenharmony_ci track_progress=None, 3807db96d56Sopenharmony_ci verbosity=None, 3817db96d56Sopenharmony_ci _analyze=_analyze, 3827db96d56Sopenharmony_ci formats=FORMATS, 3837db96d56Sopenharmony_ci **kwargs 3847db96d56Sopenharmony_ci ): 3857db96d56Sopenharmony_ci verbosity = verbosity if verbosity is not None else 3 3867db96d56Sopenharmony_ci 3877db96d56Sopenharmony_ci try: 3887db96d56Sopenharmony_ci do_fmt = formats[fmt] 3897db96d56Sopenharmony_ci except KeyError: 3907db96d56Sopenharmony_ci raise ValueError(f'unsupported fmt {fmt!r}') 3917db96d56Sopenharmony_ci 3927db96d56Sopenharmony_ci filenames, relroot = fsutil.fix_filenames(filenames, relroot=relroot) 3937db96d56Sopenharmony_ci filenames = filter_filenames(filenames, iter_filenames, relroot) 3947db96d56Sopenharmony_ci if track_progress: 3957db96d56Sopenharmony_ci filenames = track_progress(filenames) 3967db96d56Sopenharmony_ci 3977db96d56Sopenharmony_ci logger.info('analyzing files...') 3987db96d56Sopenharmony_ci analyzed = _analyze(filenames, **kwargs) 3997db96d56Sopenharmony_ci analyzed.fix_filenames(relroot, normalize=False) 4007db96d56Sopenharmony_ci decls = filter_forward(analyzed, markpublic=True) 4017db96d56Sopenharmony_ci 4027db96d56Sopenharmony_ci for line in do_fmt(decls): 4037db96d56Sopenharmony_ci print(line) 4047db96d56Sopenharmony_ci 4057db96d56Sopenharmony_ci 4067db96d56Sopenharmony_cidef _cli_data(parser, filenames=None, known=None): 4077db96d56Sopenharmony_ci ArgumentParser = type(parser) 4087db96d56Sopenharmony_ci common = ArgumentParser(add_help=False) 4097db96d56Sopenharmony_ci # These flags will get processed by the top-level parse_args(). 4107db96d56Sopenharmony_ci add_verbosity_cli(common) 4117db96d56Sopenharmony_ci add_traceback_cli(common) 4127db96d56Sopenharmony_ci 4137db96d56Sopenharmony_ci subs = parser.add_subparsers(dest='datacmd') 4147db96d56Sopenharmony_ci 4157db96d56Sopenharmony_ci sub = subs.add_parser('show', parents=[common]) 4167db96d56Sopenharmony_ci if known is None: 4177db96d56Sopenharmony_ci sub.add_argument('--known', required=True) 4187db96d56Sopenharmony_ci if filenames is None: 4197db96d56Sopenharmony_ci sub.add_argument('filenames', metavar='FILE', nargs='+') 4207db96d56Sopenharmony_ci 4217db96d56Sopenharmony_ci sub = subs.add_parser('dump', parents=[common]) 4227db96d56Sopenharmony_ci if known is None: 4237db96d56Sopenharmony_ci sub.add_argument('--known') 4247db96d56Sopenharmony_ci sub.add_argument('--show', action='store_true') 4257db96d56Sopenharmony_ci process_progress = add_progress_cli(sub) 4267db96d56Sopenharmony_ci 4277db96d56Sopenharmony_ci sub = subs.add_parser('check', parents=[common]) 4287db96d56Sopenharmony_ci if known is None: 4297db96d56Sopenharmony_ci sub.add_argument('--known', required=True) 4307db96d56Sopenharmony_ci 4317db96d56Sopenharmony_ci def process_args(args, *, argv): 4327db96d56Sopenharmony_ci if args.datacmd == 'dump': 4337db96d56Sopenharmony_ci process_progress(args, argv) 4347db96d56Sopenharmony_ci return process_args 4357db96d56Sopenharmony_ci 4367db96d56Sopenharmony_ci 4377db96d56Sopenharmony_cidef cmd_data(datacmd, filenames, known=None, *, 4387db96d56Sopenharmony_ci _analyze=_analyze, 4397db96d56Sopenharmony_ci formats=FORMATS, 4407db96d56Sopenharmony_ci extracolumns=None, 4417db96d56Sopenharmony_ci relroot=fsutil.USE_CWD, 4427db96d56Sopenharmony_ci track_progress=None, 4437db96d56Sopenharmony_ci **kwargs 4447db96d56Sopenharmony_ci ): 4457db96d56Sopenharmony_ci kwargs.pop('verbosity', None) 4467db96d56Sopenharmony_ci usestdout = kwargs.pop('show', None) 4477db96d56Sopenharmony_ci if datacmd == 'show': 4487db96d56Sopenharmony_ci do_fmt = formats['summary'] 4497db96d56Sopenharmony_ci if isinstance(known, str): 4507db96d56Sopenharmony_ci known, _ = _datafiles.get_known(known, extracolumns, relroot) 4517db96d56Sopenharmony_ci for line in do_fmt(known): 4527db96d56Sopenharmony_ci print(line) 4537db96d56Sopenharmony_ci elif datacmd == 'dump': 4547db96d56Sopenharmony_ci filenames, relroot = fsutil.fix_filenames(filenames, relroot=relroot) 4557db96d56Sopenharmony_ci if track_progress: 4567db96d56Sopenharmony_ci filenames = track_progress(filenames) 4577db96d56Sopenharmony_ci analyzed = _analyze(filenames, **kwargs) 4587db96d56Sopenharmony_ci analyzed.fix_filenames(relroot, normalize=False) 4597db96d56Sopenharmony_ci if known is None or usestdout: 4607db96d56Sopenharmony_ci outfile = io.StringIO() 4617db96d56Sopenharmony_ci _datafiles.write_known(analyzed, outfile, extracolumns, 4627db96d56Sopenharmony_ci relroot=relroot) 4637db96d56Sopenharmony_ci print(outfile.getvalue()) 4647db96d56Sopenharmony_ci else: 4657db96d56Sopenharmony_ci _datafiles.write_known(analyzed, known, extracolumns, 4667db96d56Sopenharmony_ci relroot=relroot) 4677db96d56Sopenharmony_ci elif datacmd == 'check': 4687db96d56Sopenharmony_ci raise NotImplementedError(datacmd) 4697db96d56Sopenharmony_ci else: 4707db96d56Sopenharmony_ci raise ValueError(f'unsupported data command {datacmd!r}') 4717db96d56Sopenharmony_ci 4727db96d56Sopenharmony_ci 4737db96d56Sopenharmony_ciCOMMANDS = { 4747db96d56Sopenharmony_ci 'check': ( 4757db96d56Sopenharmony_ci 'analyze and fail if the given C source/header files have any problems', 4767db96d56Sopenharmony_ci [_cli_check], 4777db96d56Sopenharmony_ci cmd_check, 4787db96d56Sopenharmony_ci ), 4797db96d56Sopenharmony_ci 'analyze': ( 4807db96d56Sopenharmony_ci 'report on the state of the given C source/header files', 4817db96d56Sopenharmony_ci [_cli_analyze], 4827db96d56Sopenharmony_ci cmd_analyze, 4837db96d56Sopenharmony_ci ), 4847db96d56Sopenharmony_ci 'data': ( 4857db96d56Sopenharmony_ci 'check/manage local data (e.g. known types, ignored vars, caches)', 4867db96d56Sopenharmony_ci [_cli_data], 4877db96d56Sopenharmony_ci cmd_data, 4887db96d56Sopenharmony_ci ), 4897db96d56Sopenharmony_ci} 4907db96d56Sopenharmony_ci 4917db96d56Sopenharmony_ci 4927db96d56Sopenharmony_ci####################################### 4937db96d56Sopenharmony_ci# the script 4947db96d56Sopenharmony_ci 4957db96d56Sopenharmony_cidef parse_args(argv=sys.argv[1:], prog=sys.argv[0], *, subset=None): 4967db96d56Sopenharmony_ci import argparse 4977db96d56Sopenharmony_ci parser = argparse.ArgumentParser( 4987db96d56Sopenharmony_ci prog=prog or get_prog(), 4997db96d56Sopenharmony_ci ) 5007db96d56Sopenharmony_ci 5017db96d56Sopenharmony_ci processors = add_commands_cli( 5027db96d56Sopenharmony_ci parser, 5037db96d56Sopenharmony_ci commands={k: v[1] for k, v in COMMANDS.items()}, 5047db96d56Sopenharmony_ci commonspecs=[ 5057db96d56Sopenharmony_ci add_verbosity_cli, 5067db96d56Sopenharmony_ci add_traceback_cli, 5077db96d56Sopenharmony_ci ], 5087db96d56Sopenharmony_ci subset=subset, 5097db96d56Sopenharmony_ci ) 5107db96d56Sopenharmony_ci 5117db96d56Sopenharmony_ci args = parser.parse_args(argv) 5127db96d56Sopenharmony_ci ns = vars(args) 5137db96d56Sopenharmony_ci 5147db96d56Sopenharmony_ci cmd = ns.pop('cmd') 5157db96d56Sopenharmony_ci 5167db96d56Sopenharmony_ci verbosity, traceback_cm = process_args_by_key( 5177db96d56Sopenharmony_ci args, 5187db96d56Sopenharmony_ci argv, 5197db96d56Sopenharmony_ci processors[cmd], 5207db96d56Sopenharmony_ci ['verbosity', 'traceback_cm'], 5217db96d56Sopenharmony_ci ) 5227db96d56Sopenharmony_ci # "verbosity" is sent to the commands, so we put it back. 5237db96d56Sopenharmony_ci args.verbosity = verbosity 5247db96d56Sopenharmony_ci 5257db96d56Sopenharmony_ci return cmd, ns, verbosity, traceback_cm 5267db96d56Sopenharmony_ci 5277db96d56Sopenharmony_ci 5287db96d56Sopenharmony_cidef main(cmd, cmd_kwargs): 5297db96d56Sopenharmony_ci try: 5307db96d56Sopenharmony_ci run_cmd = COMMANDS[cmd][0] 5317db96d56Sopenharmony_ci except KeyError: 5327db96d56Sopenharmony_ci raise ValueError(f'unsupported cmd {cmd!r}') 5337db96d56Sopenharmony_ci run_cmd(**cmd_kwargs) 5347db96d56Sopenharmony_ci 5357db96d56Sopenharmony_ci 5367db96d56Sopenharmony_ciif __name__ == '__main__': 5377db96d56Sopenharmony_ci cmd, cmd_kwargs, verbosity, traceback_cm = parse_args() 5387db96d56Sopenharmony_ci configure_logger(verbosity) 5397db96d56Sopenharmony_ci with traceback_cm: 5407db96d56Sopenharmony_ci main(cmd, cmd_kwargs) 541