コード例 #1
0
def _test_minimal(code_snippet: str) -> bool:
    ast_expo = get_cmd_or_die(c.AST_EXPO)
    ast_impo = get_cmd_or_die(c.AST_IMPO)

    tempdir = tempfile.gettempdir()
    cfile = os.path.join(tempdir, "test.c")
    with open(cfile, 'w') as fh:
        fh.write(code_snippet)

    # avoid warnings about missing compiler flags, not strictly required
    cc_json = os.path.join(tempdir, "compile_commands.json")
    with open(cc_json, 'w') as fh:
        fh.write(minimal_cc_db)

    cborfile = cfile + '.cbor'

    invoke(ast_expo[cfile])

    ld_lib_path = get_rust_toolchain_libpath(c.CUSTOM_RUST_NAME)

    # don't overwrite existing ld lib path if any...
    if 'LD_LIBRARY_PATH' in pb.local.env:
        ld_lib_path += ':' + pb.local.env['LD_LIBRARY_PATH']

    args = []
    args += ['--ddump-untyped-clang-ast']
    args += [cborfile]

    # import ast
    with pb.local.env(RUST_BACKTRACE='1', LD_LIBRARY_PATH=ld_lib_path):
        invoke(ast_impo, args)

    return True  # if we get this far, test passed
コード例 #2
0
    def translate(self, cc_db, extra_args: List[str] = []) -> RustFile:
        extensionless_file, _ = os.path.splitext(self.path)

        # help plumbum find rust
        ld_lib_path = get_rust_toolchain_libpath()
        if 'LD_LIBRARY_PATH' in pb.local.env:
            ld_lib_path += ':' + pb.local.env['LD_LIBRARY_PATH']

        # run the transpiler
        transpiler = get_cmd_or_die(c.TRANSPILER)

        args = [
            cc_db,
            "--prefix-function-names",
            "rust_",
            "--overwrite-existing",
        ]

        if self.disable_incremental_relooper:
            args.append("--no-incremental-relooper")
        if self.disallow_current_block:
            args.append("--fail-on-multiple")
        if self.translate_const_macros:
            args.append("--translate-const-macros")
        if self.reorganize_definitions:
            args.append("--reorganize-definitions")
        if self.emit_build_files:
            args.append("--emit-build-files")

        if self.logLevel == 'DEBUG':
            args.append("--log-level=debug")

        args.append("--")
        args.extend(extra_args)

        # Add -isysroot on MacOS to get SDK directory
        if on_mac():
            try:
                xcrun = pb.local["xcrun"]
                args.append("-isysroot" + xcrun("--show-sdk-path").strip())
            except pb.CommandNotFound:
                pass

        with pb.local.env(RUST_BACKTRACE='1', LD_LIBRARY_PATH=ld_lib_path):
            # log the command in a format that's easy to re-run
            translation_cmd = "LD_LIBRARY_PATH=" + ld_lib_path + " \\\n"
            translation_cmd += str(transpiler[args])
            logging.debug("translation command:\n %s", translation_cmd)
            retcode, stdout, stderr = (transpiler[args]).run(
                retcode=None)

            logging.debug("stdout:\n%s", stdout)
            logging.debug("stderr:\n%s", stderr)

        if retcode != 0:
            raise NonZeroReturn(stderr)

        return RustFile(extensionless_file + ".rs")
コード例 #3
0
def run_tests(testcases: List[str]) -> None:
    ipath = os.path.join(c.RREF_DIR, "target/debug/idiomize")
    # refactor = '{ip} -P ../.. -p plugin_stub -r alongside'.format(ip=ipath)
    # NOTE:PL: I removed the plugin options (-P, -p) to get the tests to run.
    refactor = '{ip} -r alongside'.format(ip=ipath)

    # help plumbum find rust
    ld_lib_path = get_rust_toolchain_libpath(c.CUSTOM_RUST_NAME)
    if 'LD_LIBRARY_PATH' in pb.local.env:
        ld_lib_path += ':' + pb.local.env['LD_LIBRARY_PATH']

    rustflags = "-L {rust_lib_dir}/rustlib/{triplet}/lib"
    rustflags = rustflags.format(rust_lib_dir=ld_lib_path,
                                 triplet=get_host_triplet())

    with pb.local.env(RUST_BACKTRACE='1',
                      RUST_LOG="idiomize=info",
                      LD_LIBRARY_PATH=ld_lib_path,
                      not_LD_LIBRARY_PATH=ld_lib_path,
                      refactor=refactor,
                      rustflags=rustflags):
        for test in testcases:
            script = pb.local.get(test)
            testdir = os.path.dirname(test)
            testname = os.path.basename(testdir)
            try:
                with pb.local.cwd(testdir):
                    logging.debug("testing: %s", testdir)
                    script.run()

                    old_new_rust = os.path.join(testdir, "old.rs.new")
                    assert os.path.isfile(
                        old_new_rust), "missing rewritten rust"
                    mode = "overwrite"  # set to 'replace' to generate backups
                    rustfmt["--force", "--write-mode", mode,
                            old_new_rust].run()

                    new_rust = os.path.join(testdir, "new.rs")
                    diff["-wB", new_rust, old_new_rust].run()

                    print(" {}[ OK ]{} ".format(Colors.OKGREEN,
                                                Colors.NO_COLOR) + testname)
                    logging.debug(" [ OK ] " + testname)
            except pb.ProcessExecutionError as pee:
                print(" {}[FAIL]{} ".format(Colors.FAIL, Colors.NO_COLOR) +
                      testname)
                logging.debug(" [FAIL] " + testname)
                logfile = os.path.join(testdir, "log")
                if os.path.exists(logfile):
                    with open(logfile, "r") as fh:
                        lines = fh.readlines()
                        logging.debug("".join(lines))
コード例 #4
0
ファイル: transpile.py プロジェクト: shlomif/c2rust
    def transpile_single(cmd) -> Tuple[str, int, str, str, str]:

        if import_only:
            cbor_file = os.path.join(cmd['directory'], cmd['file'] + ".cbor")
        else:
            cbor_file = export_ast_from(ast_expo, cc_db_name,
                                        include_dirs, **cmd)
        assert os.path.isfile(cbor_file), "missing: " + cbor_file

        ld_lib_path = get_rust_toolchain_libpath()

        # don't overwrite existing ld lib path if any...
        if 'LD_LIBRARY_PATH' in pb.local.env:
            ld_lib_path += ':' + pb.local.env['LD_LIBRARY_PATH']

        # import ast
        with pb.local.env(RUST_BACKTRACE='1',
                          LD_LIBRARY_PATH=ld_lib_path):
            file_basename = os.path.basename(cmd['file'])
            cbor_basename = os.path.basename(cbor_file)
            logging.info(" importing ast from %s", cbor_basename)
            translation_cmd = "RUST_BACKTRACE=1 \\\n"
            translation_cmd += "LD_LIBRARY_PATH=" + ld_lib_path + " \\\n"
            translation_cmd += str(
                ast_impo[cbor_file, impo_args, extra_impo_args])
            logging.debug("translation command:\n %s", translation_cmd)
            try:
                ast_impo_cmd = ast_impo[cbor_file, impo_args, extra_impo_args]
                # NOTE: this will log ast-importer output but not in color
                retcode, rust_output, importer_warnings = ast_impo_cmd.run()
                if importer_warnings:
                    if verbose:
                        logging.warning(importer_warnings)
                    else:
                        logging.debug(importer_warnings)

                e = "Expected file suffix `.c.cbor`; actual: " + cbor_basename
                assert cbor_file.endswith(".c.cbor"), e
                rust_file = cbor_file[:-7] + ".rs"
                with open(rust_file, "w") as rust_fh:
                    rust_fh.writelines(rust_output)
                    logging.debug("wrote output rust to %s", rust_file)

                rustfmt(rust_file)

                return (file_basename, retcode, rust_output, importer_warnings,
                        os.path.abspath(rust_file))
            except pb.ProcessExecutionError as pee:
                return (file_basename, pee.retcode, pee.stdout, pee.stderr,
                        None)
コード例 #5
0
ファイル: test_translator.py プロジェクト: anp/c2rust
    def translate(self) -> RustFile:
        c_file_path, _ = os.path.splitext(self.path)
        extensionless_file, _ = os.path.splitext(c_file_path)
        rust_src = extensionless_file + ".rs"

        # help plumbum find rust
        ld_lib_path = get_rust_toolchain_libpath()
        if 'LD_LIBRARY_PATH' in pb.local.env:
            ld_lib_path += ':' + pb.local.env['LD_LIBRARY_PATH']

        # run the importer
        ast_importer = get_cmd_or_die(c.AST_IMPO)

        args = [
            self.path,
            "--prefix-function-names",
            "rust_",
        ]

        if self.enable_relooper:
            args.append("--reloop-cfgs")
            #  args.append("--use-c-loop-info")
            #  args.append("--use-c-multiple-info")
        if self.disallow_current_block:
            args.append("--fail-on-multiple")

        with pb.local.env(RUST_BACKTRACE='1', LD_LIBRARY_PATH=ld_lib_path):
            # log the command in a format that's easy to re-run
            translation_cmd = "LD_LIBRARY_PATH=" + ld_lib_path + " \\\n"
            translation_cmd += str(ast_importer[args] > rust_src)
            logging.debug("translation command:\n %s", translation_cmd)
            retcode, stdout, stderr = (ast_importer[args] > rust_src).run(
                retcode=None)

        logging.debug("stdout:\n%s", stdout)

        if retcode != 0:
            raise NonZeroReturn(stderr)

        return RustFile(extensionless_file + ".rs")
コード例 #6
0
ファイル: test_translator.py プロジェクト: zzl133/c2rust
    def run(self) -> List[TestOutcome]:
        outcomes = []

        any_tests = any(test_fn for test_file in self.rs_test_files
                        for test_fn in test_file.test_functions)

        if not any_tests:
            description = "No tests were found..."
            logging.debug("%s:", self.name)
            logging.debug("%s [ SKIPPED ] %s %s", Colors.OKBLUE,
                          Colors.NO_COLOR, description)
            return []

        if not self.c_files:
            description = "No c files were found..."
            logging.debug("%s:", self.name)
            logging.debug("%s [ SKIPPED ] %s %s", Colors.OKBLUE,
                          Colors.NO_COLOR, description)
            return []

        sys.stdout.write("{}:\n".format(self.name))

        # .c -> .a
        description = "libtest.a: creating a static C library..."

        self.print_status(Colors.WARNING, "RUNNING", description)

        try:
            static_library = build_static_library(self.c_files, self.full_path)
        except NonZeroReturn as exception:
            self.print_status(Colors.FAIL, "FAILED", "create libtest.a")
            sys.stdout.write('\n')
            sys.stdout.write(str(exception))

            outcomes.append(TestOutcome.UnexpectedFailure)

            return outcomes

        self.generated_files["c_lib"].append(static_library)
        self.generated_files["c_obj"].extend(static_library.obj_files)

        rust_file_builder = RustFileBuilder()
        rust_file_builder.add_features([
            "libc",
            "extern_types",
            "simd_ffi",
            "stdsimd",
            "const_transmute",
            "nll",
            "linkage",
            "register_tool",
        ])
        rust_file_builder.add_pragma("register_tool", ["c2rust"])

        # Ensure that path to rustc's lib dir is in`LD_LIBRARY_PATH`
        ld_lib_path = get_rust_toolchain_libpath()
        if 'LD_LIBRARY_PATH' in pb.local.env:
            ld_lib_path += ':' + pb.local.env['LD_LIBRARY_PATH']

        # .c -> .rs
        for c_file in self.c_files:
            _, c_file_short = os.path.split(c_file.path)
            description = "{}: translating the C file into Rust...".format(
                c_file_short)

            # Run the step
            self.print_status(Colors.WARNING, "RUNNING", description)

            self._generate_cc_db(c_file.path)

            try:
                logging.debug("translating %s", c_file_short)
                translated_rust_file = c_file.translate(
                    self.generated_files["cc_db"],
                    ld_lib_path,
                    extra_args=["-march=native"])
            except NonZeroReturn as exception:
                self.print_status(Colors.FAIL, "FAILED",
                                  "translate " + c_file_short)
                sys.stdout.write('\n')
                sys.stdout.write(str(exception))

                outcomes.append(TestOutcome.UnexpectedFailure)
                continue

            self.generated_files["rust_src"].append(translated_rust_file)
            if c_file.emit_build_files:
                self.generated_files["rust_src"].append(self.full_path +
                                                        "/src/Cargo.toml")
                self.generated_files["rust_src"].append(self.full_path +
                                                        "/src/build.rs")
                self.generated_files["rust_src"].append(self.full_path +
                                                        "/src/c2rust-lib.rs")
                self.generated_files["rust_src"].append(self.full_path +
                                                        "/src/rust-toolchain")

            _, rust_file_short = os.path.split(translated_rust_file.path)
            extensionless_rust_file, _ = os.path.splitext(rust_file_short)

            rust_file_builder.add_mod(
                RustMod(extensionless_rust_file, RustVisibility.Public))

        match_arms = []
        rustc_extra_args = ["-C", "target-cpu=native"]

        # Build one binary that can call all the tests
        for test_file in self.rs_test_files:
            # rustc_extra_args.append(["-L", "crate={}".format(c.TARGET_DIR)])
            rust_file_builder.add_features(test_file.features)
            rust_file_builder.add_extern_crates(test_file.extern_crates)

            _, file_name = os.path.split(test_file.path)
            extensionless_file_name, _ = os.path.splitext(file_name)

            if not test_file.pass_expected:
                try:
                    test_file.compile(CrateType.Library,
                                      save_output=False,
                                      extra_args=rustc_extra_args)

                    self.print_status(
                        Colors.FAIL, "OK",
                        "Unexpected success {}".format(file_name))
                    sys.stdout.write('\n')

                    outcomes.append(TestOutcome.UnexpectedSuccess)
                except NonZeroReturn as exception:
                    self.print_status(Colors.OKBLUE, "FAILED",
                                      "Expected failure {}".format(file_name))
                    sys.stdout.write('\n')

                    logging.error("stderr:%s\n", str(exception))

                    outcomes.append(TestOutcome.Failure)

                continue

            for test_function in test_file.test_functions:
                rust_file_builder.add_mod(
                    RustMod(extensionless_file_name, RustVisibility.Public))
                left = "Some(\"{}::{}\")".format(extensionless_file_name,
                                                 test_function.name)
                right = "{}::{}()".format(extensionless_file_name,
                                          test_function.name)
                match_arms.append((left, right))

        match_arms.append(
            ("e", "panic!(\"Tried to run unknown test: {:?}\", e)"))

        test_main_body = [
            RustMatch(
                "std::env::args().nth(1).as_ref().map(AsRef::<str>::as_ref)",
                match_arms),
        ]
        test_main = RustFunction("main",
                                 visibility=RustVisibility.Public,
                                 body=test_main_body)

        rust_file_builder.add_function(test_main)

        main_file = rust_file_builder.build(self.full_path + "/src/main.rs")

        self.generated_files["rust_src"].append(main_file)

        # Try and build test binary
        with pb.local.cwd(self.full_path):
            args = ["build"]

            if c.BUILD_TYPE == 'release':
                args.append('--release')

            retcode, stdout, stderr = cargo[args].run(retcode=None)

        if retcode != 0:
            _, main_file_path_short = os.path.split(main_file.path)

            self.print_status(Colors.FAIL, "FAILED",
                              "compile {}".format(main_file_path_short))
            sys.stdout.write('\n')
            sys.stdout.write(stderr)

            outcomes.append(TestOutcome.UnexpectedFailure)

            return outcomes

        for test_file in self.rs_test_files:
            if not test_file.pass_expected:
                continue

            _, file_name = os.path.split(test_file.path)
            extensionless_file_name, _ = os.path.splitext(file_name)

            for test_function in test_file.test_functions:
                args = [
                    "run", "{}::{}".format(extensionless_file_name,
                                           test_function.name)
                ]

                if c.BUILD_TYPE == 'release':
                    args.append('--release')

                with pb.local.cwd(self.full_path):
                    retcode, stdout, stderr = cargo[args].run(retcode=None)

                logging.debug("stdout:%s\n", stdout)

                test_str = file_name + ' - ' + test_function.name

                if retcode == 0:
                    if test_function.pass_expected:
                        self.print_status(Colors.OKGREEN, "OK",
                                          "    test " + test_str)
                        sys.stdout.write('\n')

                        outcomes.append(TestOutcome.Success)
                    else:
                        self.print_status(Colors.FAIL, "FAILED",
                                          "test " + test_str)
                        sys.stdout.write('\n')

                        outcomes.append(TestOutcome.UnexpectedSuccess)

                elif retcode != 0:
                    if test_function.pass_expected:
                        self.print_status(Colors.FAIL, "FAILED",
                                          "test " + test_str)
                        sys.stdout.write('\n')
                        sys.stdout.write(stderr)

                        outcomes.append(TestOutcome.UnexpectedFailure)
                    else:
                        self.print_status(Colors.OKBLUE, "FAILED",
                                          "test " + test_str)
                        sys.stdout.write('\n')

                        outcomes.append(TestOutcome.Failure)

        if not outcomes:
            display_text = "   No rust file(s) matching " + self.files.pattern
            display_text += " within this folder\n"
            self.print_status(Colors.OKBLUE, "N/A", display_text)
        return outcomes