diff --git a/Cargo.lock b/Cargo.lock index 6f3f38e37..66ac48b9a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -17,6 +17,15 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" +[[package]] +name = "aho-corasick" +version = "0.7.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc936419f96fa211c1b9166887b38e5e40b19958e5b895be7c1f93adec7071ac" +dependencies = [ + "memchr", +] + [[package]] name = "aho-corasick" version = "1.0.1" @@ -178,6 +187,16 @@ dependencies = [ "generic-array", ] +[[package]] +name = "bstr" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6798148dccfbff0fae41c7574d2fa8f1ef3492fba0face179de5d8d447d67b05" +dependencies = [ + "memchr", + "serde", +] + [[package]] name = "byteorder" version = "1.5.0" @@ -353,6 +372,7 @@ dependencies = [ "fern", "handlebars", "indexmap", + "insta", "itertools", "log", "log-reroute", @@ -726,6 +746,12 @@ dependencies = [ "log", ] +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + [[package]] name = "fs-err" version = "2.9.0" @@ -775,6 +801,19 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" +[[package]] +name = "globset" +version = "0.4.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "029d74589adefde59de1a0c4f4732695c32805624aec7b68d91503d4dba79afc" +dependencies = [ + "aho-corasick 0.7.20", + "bstr", + "fnv", + "log", + "regex", +] + [[package]] name = "half" version = "1.8.2" @@ -861,9 +900,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9a28d25139df397cbca21408bb742cf6837e04cdbebf1b07b760caf971d6a972" dependencies = [ "console", + "globset", "lazy_static", "linked-hash-map", "similar", + "walkdir", "yaml-rust", ] @@ -1242,7 +1283,7 @@ version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "af83e617f331cc6ae2da5443c602dfa5af81e517212d9d611a5b3ba1777b5370" dependencies = [ - "aho-corasick", + "aho-corasick 1.0.1", "memchr", "regex-syntax", ] @@ -1291,6 +1332,15 @@ version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041" +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + [[package]] name = "serde" version = "1.0.163" @@ -1607,6 +1657,16 @@ version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +[[package]] +name = "walkdir" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" +dependencies = [ + "same-file", + "winapi-util", +] + [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" diff --git a/c2rust-transpile/Cargo.toml b/c2rust-transpile/Cargo.toml index 3ead86f69..43fbe77b2 100644 --- a/c2rust-transpile/Cargo.toml +++ b/c2rust-transpile/Cargo.toml @@ -42,3 +42,6 @@ tempfile = "3.5.0" [features] # Force static linking of LLVM llvm-static = ["c2rust-ast-exporter/llvm-static"] + +[dev-dependencies] +insta = { version = "1.15", features = ["glob"] } diff --git a/c2rust-transpile/tests/snapshots.rs b/c2rust-transpile/tests/snapshots.rs new file mode 100644 index 000000000..2ecee39ad --- /dev/null +++ b/c2rust-transpile/tests/snapshots.rs @@ -0,0 +1,52 @@ +use std::fs; + +#[test] +fn transpile() { + let config = || c2rust_transpile::TranspilerConfig { + dump_untyped_context: false, + dump_typed_context: false, + pretty_typed_context: false, + dump_function_cfgs: false, + json_function_cfgs: false, + dump_cfg_liveness: false, + dump_structures: false, + verbose: false, + debug_ast_exporter: false, + incremental_relooper: true, + fail_on_multiple: false, + filter: None, + debug_relooper_labels: false, + prefix_function_names: None, + translate_asm: true, + use_c_loop_info: true, + use_c_multiple_info: true, + simplify_structures: true, + panic_on_translator_failure: false, + emit_modules: false, + fail_on_error: false, + replace_unsupported_decls: c2rust_transpile::ReplaceMode::Extern, + translate_valist: true, + overwrite_existing: true, + reduce_type_annotations: false, + reorganize_definitions: false, + enabled_warnings: Default::default(), + emit_no_std: false, + output_dir: None, + translate_const_macros: false, + translate_fn_macros: false, + disable_refactoring: false, + preserve_unused_functions: false, + log_level: log::LevelFilter::Warn, + emit_build_files: false, + binaries: Vec::new(), + }; + insta::glob!("snapshots/*.c", |c_path: &Path| { + let (_temp_dir, temp_path) = + c2rust_transpile::create_temp_compile_commands(&[c_path.to_owned()]); + c2rust_transpile::transpile(config(), &temp_path, &[]); + let rs_path = c_path.with_extension("rs"); + let rust = fs::read_to_string(&rs_path).unwrap(); + fs::remove_file(&rs_path).unwrap(); + insta::assert_snapshot!(&rust); + }); +} diff --git a/c2rust-transpile/tests/snapshots/factorial.c b/c2rust-transpile/tests/snapshots/factorial.c new file mode 100644 index 000000000..c0e7e73b8 --- /dev/null +++ b/c2rust-transpile/tests/snapshots/factorial.c @@ -0,0 +1,7 @@ +unsigned short factorial(unsigned short n) { + unsigned short result = 1; + for (unsigned short i = 1; i < n; i++) { + result *= i; + } + return result; +} diff --git a/c2rust-transpile/tests/snapshots/gotos.c b/c2rust-transpile/tests/snapshots/gotos.c new file mode 100644 index 000000000..02094f59a --- /dev/null +++ b/c2rust-transpile/tests/snapshots/gotos.c @@ -0,0 +1,24 @@ +int sum(int count) { + goto a; + + b: + --count; + goto d; + + a:; + int x = 0; + goto d; + + c: + return x; + + d: + if(count <= 0) + goto c; + goto e; + + e: + x += count; + goto b; +} + diff --git a/c2rust-transpile/tests/snapshots/insertion.c b/c2rust-transpile/tests/snapshots/insertion.c new file mode 100644 index 000000000..7409484b2 --- /dev/null +++ b/c2rust-transpile/tests/snapshots/insertion.c @@ -0,0 +1,11 @@ +void insertion_sort(int const n, int * const p) { + for (int i = 1; i < n; i++) { + int const tmp = p[i]; + int j = i; + while (j > 0 && p[j-1] > tmp) { + p[j] = p[j-1]; + j--; + } + p[j] = tmp; + } +} diff --git a/c2rust-transpile/tests/snapshots/snapshots__transpile@factorial.c.snap b/c2rust-transpile/tests/snapshots/snapshots__transpile@factorial.c.snap new file mode 100644 index 000000000..e12756fde --- /dev/null +++ b/c2rust-transpile/tests/snapshots/snapshots__transpile@factorial.c.snap @@ -0,0 +1,26 @@ +--- +source: c2rust-transpile/tests/snapshots.rs +expression: "&output" +input_file: c2rust-transpile/tests/snapshots/factorial.c +--- +#![allow( + dead_code, + mutable_transmutes, + non_camel_case_types, + non_snake_case, + non_upper_case_globals, + unused_assignments, + unused_mut +)] +#[no_mangle] +pub unsafe extern "C" fn factorial(mut n: std::ffi::c_ushort) -> std::ffi::c_ushort { + let mut result: std::ffi::c_ushort = 1 as std::ffi::c_int as std::ffi::c_ushort; + let mut i: std::ffi::c_ushort = 1 as std::ffi::c_int as std::ffi::c_ushort; + while (i as std::ffi::c_int) < n as std::ffi::c_int { + result = (result as std::ffi::c_int * i as std::ffi::c_int) + as std::ffi::c_ushort; + i = i.wrapping_add(1); + i; + } + return result; +} diff --git a/c2rust-transpile/tests/snapshots/snapshots__transpile@gotos.c.snap b/c2rust-transpile/tests/snapshots/snapshots__transpile@gotos.c.snap new file mode 100644 index 000000000..89dfb4702 --- /dev/null +++ b/c2rust-transpile/tests/snapshots/snapshots__transpile@gotos.c.snap @@ -0,0 +1,24 @@ +--- +source: c2rust-transpile/tests/snapshots.rs +expression: "&output" +input_file: c2rust-transpile/tests/snapshots/gotos.c +--- +#![allow( + dead_code, + mutable_transmutes, + non_camel_case_types, + non_snake_case, + non_upper_case_globals, + unused_assignments, + unused_mut +)] +#[no_mangle] +pub unsafe extern "C" fn sum(mut count: std::ffi::c_int) -> std::ffi::c_int { + let mut x: std::ffi::c_int = 0 as std::ffi::c_int; + while !(count <= 0 as std::ffi::c_int) { + x += count; + count -= 1; + count; + } + return x; +} diff --git a/c2rust-transpile/tests/snapshots/snapshots__transpile@insertion.c.snap b/c2rust-transpile/tests/snapshots/snapshots__transpile@insertion.c.snap new file mode 100644 index 000000000..e9ecab6fa --- /dev/null +++ b/c2rust-transpile/tests/snapshots/snapshots__transpile@insertion.c.snap @@ -0,0 +1,32 @@ +--- +source: c2rust-transpile/tests/snapshots.rs +expression: "&output" +input_file: c2rust-transpile/tests/snapshots/insertion.c +--- +#![allow( + dead_code, + mutable_transmutes, + non_camel_case_types, + non_snake_case, + non_upper_case_globals, + unused_assignments, + unused_mut +)] +#[no_mangle] +pub unsafe extern "C" fn insertion_sort(n: std::ffi::c_int, p: *mut std::ffi::c_int) { + let mut i: std::ffi::c_int = 1 as std::ffi::c_int; + while i < n { + let tmp: std::ffi::c_int = *p.offset(i as isize); + let mut j: std::ffi::c_int = i; + while j > 0 as std::ffi::c_int + && *p.offset((j - 1 as std::ffi::c_int) as isize) > tmp + { + *p.offset(j as isize) = *p.offset((j - 1 as std::ffi::c_int) as isize); + j -= 1; + j; + } + *p.offset(j as isize) = tmp; + i += 1; + i; + } +}