def test_scan_file_object(self): source_scanner = SourceScanner() report = Report('/root') io_object = io.StringIO('xxx') source_scanner.scan_file_object('test.c', io_object, report) self.assertEqual(len(report.issues), 0) report = Report('/root') io_object = io.StringIO('__asm__("")') source_scanner.scan_file_object('test.c', io_object, report) self.assertEqual(len(report.issues), 0) report = Report('/root') io_object = io.StringIO('__asm__("mov r0, r1")') source_scanner.scan_file_object('test.c', io_object, report) self.assertEqual(len(report.issues), 1) report = Report('/root') io_object = io.StringIO('_otherarch_intrinsic_xyz(123)') source_scanner.scan_file_object('test.c', io_object, report) self.assertEqual(len(report.issues), 1) report = Report('/root') io_object = io.StringIO('#pragma simd foo') source_scanner.scan_file_object('test.c', io_object, report) self.assertEqual(len(report.issues), 1) self.assertEqual(report.issues[0].item_type, ReportItem.NEUTRAL)
def test_scan_file_object(self): asm_source_scanner = AsmSourceScanner() report = Report('/root') io_object = io.StringIO('__asm__("")') asm_source_scanner.scan_file_object('test.s', io_object, report) self.assertEqual(len(report.issues), 0) report = Report('/root') io_object = io.StringIO('__asm__("mov r0, r1")') asm_source_scanner.scan_file_object('test.s', io_object, report) self.assertEqual(len(report.issues), 1)
def test_comments_are_ignored(self): source_scanner = SourceScanner() report = Report('/root') io_object = io.StringIO('// __asm__("mov r0, r1")') source_scanner.scan_file_object('test.c', io_object, report) self.assertEqual(len(report.issues), 0) report = Report('/root') io_object = io.StringIO('/*\n__asm__("mov r0, r1")\n*/') source_scanner.scan_file_object('test.c', io_object, report) self.assertEqual(len(report.issues), 0)
def test_scan_file_object(self): config_guess_scanner = ConfigGuessScanner() report = Report('/root') io_object = io.StringIO('xxx') config_guess_scanner.scan_file_object('config.guess', io_object, report) self.assertEqual(len(report.issues), 1) report = Report('/root') io_object = io.StringIO('aarch64:Linux') config_guess_scanner.scan_file_object('config.guess', io_object, report) self.assertEqual(len(report.remarks), 1)
def test_old_crt(self): makefile_scanner = MakefileScanner() report = Report('/root') io_object = io.StringIO('LIBS=libcmt.lib') makefile_scanner.scan_file_object('Makefile', io_object, report) self.assertEqual(len(report.issues), 1) report = Report('/root') io_object = io.StringIO( '!IF $(OLD_CRT)\nLIBS=libcmt.lib\n!ELSE\nLIBS=libucrt.lib\n!ENDIF') makefile_scanner.scan_file_object('Makefile', io_object, report) self.assertEqual(len(report.issues), 0)
def test_other_arch_cpu_line(self): makefile_scanner = MakefileScanner() report = Report('/root') io_object = io.StringIO('!IF "$(CPU)" == "otherarch"') makefile_scanner.scan_file_object('Makefile', io_object, report) self.assertEqual(len(report.issues), 1) report = Report('/root') io_object = io.StringIO( '!IF "$(VSCMD_ARG_TGT_ARCH)" == "arm"\nTARGET_ARCH=aarch64\n!ELIF "$(CPU)" == "otherarch"\nTARGET_ARCH=otherarch\n!ENDIF' ) makefile_scanner.scan_file_object('Makefile', io_object, report) self.assertEqual(len(report.issues), 0)
def test_define_other_arch(self): makefile_scanner = MakefileScanner() report = Report('/root') io_object = io.StringIO('CFLAGS=/D__otherarch__') makefile_scanner.scan_file_object('Makefile', io_object, report) self.assertEqual(len(report.issues), 1) report = Report('/root') io_object = io.StringIO( '!IF "$(VSCMD_ARG_TGT_ARCH)" == "arm"\nCFLAGS=/D__arm__\n!ELIF "$(CPU)" == "otherarch"\nCFLAGS=/D__otherarch__\n!ENDIF' ) makefile_scanner.scan_file_object('Makefile', io_object, report) self.assertEqual(len(report.issues), 0)
def test_continuation(self): makefile_scanner = MakefileScanner() report = Report('/root') # Should be treated as a single line and only one issue reported. io_object = io.StringIO('LIBS=-lotherarch\\\n-lotherarch') makefile_scanner.scan_file_object('Makefile', io_object, report) self.assertEqual(len(report.issues), 1)
def test_target_command(self): makefile_scanner = MakefileScanner() report = Report('/root') io_object = io.StringIO( 'target.exe: target.c\n\tcl target.c /Fe:target.exe\n\nfoobar.h: target.exe\n\t./target.exe >foobar.h' ) makefile_scanner.scan_file_object('Makefile', io_object, report) self.assertEqual(len(report.issues), 1) report = Report('/root') io_object = io.StringIO( '$(TARGET): target.c\n\tcl target.c /Fe:target.exe\n\nfoobar.h: $(TARGET)\n\t$(TARGET) >foobar.h' ) makefile_scanner.scan_file_object('Makefile', io_object, report) self.assertEqual(len(report.issues), 1)
def test_macro_name(self): source_scanner = SourceScanner() report = Report('/root') io_object = io.StringIO('#define MACRO __asm__("mov r0, r1")') source_scanner.scan_file_object('test.c', io_object, report) self.assertEqual(len(report.issues), 1) self.assertEqual(report.issues[0].function, 'MACRO')
def test_function_name(self): source_scanner = SourceScanner() report = Report('/root') io_object = io.StringIO('void func(void) {\n__asm__("mov r0, r1");\n}') source_scanner.scan_file_object('test.c', io_object, report) self.assertEqual(len(report.issues), 1) self.assertEqual(report.issues[0].function, 'func')
def test_no_equivalent_inline_asm_single_file(self): source_scanner = SourceScanner() report = Report('/root') source_scanner.initialize_report(report) io_object = io.StringIO('__asm__("mov r0, r1"') source_scanner.scan_file_object('test.c', io_object, report) source_scanner.finalize_report(report) self.assertEqual(len(report.issues), 2)
def test_target_command_with_assignment(self): makefile_scanner = MakefileScanner() report = Report('/root') io_object = io.StringIO( 'TARGET=target.exe\n\n$(TARGET): target.c\n\tcl target.c /Fe:target.exe\n\nfoobar.h: $(TARGET)\n\t$(TARGET) >foobar.h' ) makefile_scanner.scan_file_object('Makefile', io_object, report) self.assertEqual(len(report.issues), 1) issue = report.issues[0] self.assertEqual(issue.target, 'target.exe')
def test_no_equivalent_intrinsic_function_inline(self): source_scanner = SourceScanner() report = Report('/root') source_scanner.initialize_report(report) io_object = io.StringIO( 'void func() {\n#if defined(__otherarch__)\n_otherarch_intrinsic_xyz(123));\n#elif defined(__aarch64__)\nfoo\n#endif\n}' ) source_scanner.scan_file_object('test.c', io_object, report) source_scanner.finalize_report(report) self.assertEqual(len(report.issues), 1)
def test_equivalent_inline_asm_function_outline(self): source_scanner = SourceScanner() report = Report('/root') source_scanner.initialize_report(report) io_object = io.StringIO( '#if defined(__otherarch__)\nvoid func() {\n__asm__("mov r0, r1");\n}\n#elif defined(__aarch64__)\nvoid func() {\n__asm__("mov r0, r1");\n}\n#endif' ) source_scanner.scan_file_object('test.c', io_object, report) source_scanner.finalize_report(report) self.assertEqual(len(report.issues), 0)
def test_no_equivalent_intrinsic_file(self): source_scanner = SourceScanner() port_filter = PortFilter() report = Report('/root') port_filter.initialize_report(report) source_scanner.initialize_report(report) io_object = io.StringIO('_otherarch_intrinsic_xyz(123)') report.add_source_file('otherarch.c') source_scanner.scan_file_object('otherarch.c', io_object, report) io_object = io.StringIO('foo') report.add_source_file('aarch64.c') source_scanner.scan_file_object('aarch64.c', io_object, report) source_scanner.finalize_report(report) port_filter.finalize_report(report) self.assertEqual(len(report.issues), 1)
def test_equivalent_inline_asm_file(self): source_scanner = SourceScanner() port_filter = PortFilter() report = Report('/root') port_filter.initialize_report(report) source_scanner.initialize_report(report) io_object = io.StringIO('__asm__("mov r0, r1")') report.add_source_file('otherarch.c') source_scanner.scan_file_object('otherarch.c', io_object, report) io_object = io.StringIO('__asm__("mov r0, r1")') report.add_source_file('aarch64.c') source_scanner.scan_file_object('aarch64.c', io_object, report) source_scanner.finalize_report(report) port_filter.finalize_report(report) self.assertEqual(len(report.issues), 0) found_ported_remark = False for remark in report.remarks: if isinstance(remark, PortedInlineAsmRemark): found_ported_remark = True break self.assertTrue(found_ported_remark)
def test_finalize(self): report = Report('/root') issue_type_config = IssueTypeConfig(None) issue_type_filter = IssueTypeFilter(issue_type_config) issue_type_filter.initialize_report(report) report.add_source_file('test.c') report.add_issue(InlineAsmIssue('test.c', 123)) issue_type_filter.finalize_report(report) self.assertEqual(len(report.issues), 1) report = Report('/root') issue_type_config = IssueTypeConfig('-InlineAsm') issue_type_filter = IssueTypeFilter(issue_type_config) issue_type_filter.initialize_report(report) report.add_source_file('test.c') report.add_issue(InlineAsmIssue('test.c', 123)) issue_type_filter.finalize_report(report) self.assertEqual(len(report.issues), 0) report = Report('/root') issue_type_config = IssueTypeConfig('InlineAsm') issue_type_filter = IssueTypeFilter(issue_type_config) issue_type_filter.initialize_report(report) report.add_source_file('test.c') report.add_issue(InlineAsmIssue('test.c', 123)) issue_type_filter.finalize_report(report) self.assertEqual(len(report.issues), 1) report = Report('/root') issue_type_config = IssueTypeConfig('PreprocessorError') issue_type_filter = IssueTypeFilter(issue_type_config) issue_type_filter.initialize_report(report) report.add_source_file('test.c') report.add_issue(InlineAsmIssue('test.c', 123)) issue_type_filter.finalize_report(report) self.assertEqual(len(report.issues), 0)
def test_scan_file_object(self): makefile_scanner = MakefileScanner() report = Report('/root') io_object = io.StringIO('xxx') makefile_scanner.scan_file_object('Makefile', io_object, report) self.assertEqual(len(report.issues), 0)
def test_finalize(self): report = Report('/root', target_os='linux') target_os_filter = TargetOsFilter() target_os_filter.initialize_report(report) report.add_source_file('test.c') report.add_issue(ConfigGuessIssue('test.c')) report.add_source_file('test.c') report.add_issue(InlineAsmIssue('test-aarch64.c', 123)) target_os_filter.finalize_report(report) self.assertEqual(len(report.issues), 2) report = Report('/root', target_os='windows') target_os_filter = TargetOsFilter() target_os_filter.initialize_report(report) report.add_source_file('test.c') report.add_issue(ConfigGuessIssue('test.c')) report.add_source_file('test.c') report.add_issue(InlineAsmIssue('test-aarch64.c', 123)) target_os_filter.finalize_report(report) self.assertEqual(len(report.issues), 1) report = Report('/root', target_os='all') target_os_filter = TargetOsFilter() target_os_filter.initialize_report(report) report.add_source_file('test.c') report.add_issue(ConfigGuessIssue('test.c')) report.add_source_file('test.c') report.add_issue(InlineAsmIssue('test-aarch64.c', 123)) target_os_filter.finalize_report(report) self.assertEqual(len(report.issues), 2) report = Report('/root', target_os='linux') target_os_filter = TargetOsFilter() target_os_filter.initialize_report(report) report.add_source_file('test.c') report.add_issue(OldCrtIssue('test.c', 123, 'libcmt.lib')) report.add_source_file('test.c') report.add_issue(InlineAsmIssue('test-aarch64.c', 123)) target_os_filter.finalize_report(report) self.assertEqual(len(report.issues), 1) report = Report('/root', target_os='windows') target_os_filter = TargetOsFilter() target_os_filter.initialize_report(report) report.add_source_file('test.c') report.add_issue(OldCrtIssue('test.c', 123, 'libcmt.lib')) report.add_source_file('test.c') report.add_issue(InlineAsmIssue('test-aarch64.c', 123)) target_os_filter.finalize_report(report) self.assertEqual(len(report.issues), 2) report = Report('/root', target_os='all') target_os_filter = TargetOsFilter() target_os_filter.initialize_report(report) report.add_source_file('test.c') report.add_issue(OldCrtIssue('test.c', 123, 'libcmt.lib')) report.add_source_file('test.c') report.add_issue(InlineAsmIssue('test-aarch64.c', 123)) target_os_filter.finalize_report(report) self.assertEqual(len(report.issues), 2)
def test_arch_specific_libs(self): makefile_scanner = MakefileScanner() report = Report('/root') io_object = io.StringIO('-lotherarch') makefile_scanner.scan_file_object('Makefile', io_object, report) self.assertEqual(len(report.issues), 1)
def main(): default_os = os.name if default_os == 'nt': default_os = 'windows' else: default_os = 'linux' epilog = _('Use:') + '\n' + \ textwrap.fill(_('--issue-types=+CrossCompile to enable reporting of cross-compile specific issues.'), initial_indent=' ', subsequent_indent=' ') + '\n' + \ textwrap.fill(_('--issue-types=+CompilerSpecific to enable reporting of use of compiler-specific macros.'), initial_indent=' ', subsequent_indent=' ') + '\n' + \ textwrap.fill(_('--issue-types=+NoEquivalent to enable reporting of aarch64 ported code that does not use intrinsics inline assembly versus other architectures.'), initial_indent=' ', subsequent_indent=' ') + '\n\n' + \ _('Available issue types:') + '\n' + \ textwrap.fill(', '.join(sorted(ISSUE_TYPES.keys())), initial_indent=' ', subsequent_indent=' ') parser = argparse.ArgumentParser( prog=advisor.__project__, description=advisor.__summary__, epilog=epilog, formatter_class=argparse.RawDescriptionHelpFormatter) parser.add_argument('root', metavar='DIRECTORY', help=_('root directory of source tree (default: .)'), default='.') parser.add_argument('--issue-types', help=_('modify the types of issue that are reported (default: %s)') % IssueTypeFilter.DEFAULT_FILTER) parser.add_argument('--no-progress', action='store_false', help=("don't show progress bar"), dest='progress') parser.add_argument('--output', help=_('output file name'), default=None) parser.add_argument('--quiet', action='store_true', help=_('suppress file errors'), default=False) parser.add_argument('--json', action='store_true', help=_('output verbose results as json'), default=False) parser.add_argument('--target-os', help=_('target operating system: all,linux,windows (default: %s)') % default_os, default=default_os) parser.add_argument('--version', action='version', version='%(prog)s ' + advisor.__version__) args = parser.parse_args() if not os.path.exists(args.root): print(_('%s: directory not found.') % args.root, file=sys.stderr) sys.exit(1) elif not os.path.isdir(args.root): print(_('%s: not a directory.') % args.root, file=sys.stderr) sys.exit(1) if not args.output: report = Report(args.root, report_errors=not args.quiet, target_os=args.target_os) else: report = HtmlReport(args.root, report_errors=not args.quiet, target_os=args.target_os) scanners = Scanners(args.issue_types) scanners.initialize_report(report) scanner = AutoScanner(scanners) if args.progress: class FileNameLabel(Widget): def __init__(self): self.fname = None def set_file_name(self, fname): self.fname = fname def update(self, pbar): return self.fname if self.fname else '' def progress_callback(filename): fname_label.set_file_name(filename) progress.update() fname_label = FileNameLabel() progress = ProgressBar(maxval=UnknownLength, widgets=[AnimatedMarker(), ' ', Timer(), ' ', fname_label], poll=0.1) progress.start() scanner.scan_tree(args.root, report, progress_callback=progress_callback if args.progress else None) if args.progress: fname_label.set_file_name(None) progress.finish() scanners.finalize_report(report) if args.output: with open(args.output, 'w') as f: if args.json: report.write_json(f, args.issue_types) else: report.write(f) else: if args.json: report.write_json(sys.stdout, args.issue_types) else: report.write(sys.stdout) print('\nUse --output FILENAME.html to generate an HTML report.')
def test_finalize(self): report = Report('/root') issue_type_filter = IssueTypeFilter('') issue_type_filter.initialize_report(report) report.add_source_file('test.c') report.add_issue(InlineAsmIssue('test.c', 123)) issue_type_filter.finalize_report(report) self.assertEqual(len(report.issues), 1) report = Report('/root') issue_type_filter = IssueTypeFilter('-InlineAsm') issue_type_filter.initialize_report(report) report.add_source_file('test.c') report.add_issue(InlineAsmIssue('test.c', 123)) issue_type_filter.finalize_report(report) self.assertEqual(len(report.issues), 0) report = Report('/root') issue_type_filter = IssueTypeFilter('InlineAsm') issue_type_filter.initialize_report(report) report.add_source_file('test.c') report.add_issue(InlineAsmIssue('test.c', 123)) issue_type_filter.finalize_report(report) self.assertEqual(len(report.issues), 1)
def test_finalize(self): report = Report('/root') port_filter = PortFilter() port_filter.initialize_report(report) report.add_source_file('test.c') report.add_issue(InlineAsmIssue('test.c', 123)) report.add_source_file('test-otherarch.c') report.add_issue(InlineAsmIssue('test-otherarch.c', 123)) report.add_source_file('test-aarch64.c') report.add_issue(InlineAsmIssue('test-aarch64.c', 123)) port_filter.finalize_report(report) self.assertEqual(len(report.issues), 1)