#[macro_use]
extern crate clap;
extern crate c2rust_transpile;
use clap::{App, Values};
use regex::Regex;
use std::collections::HashSet;
use std::path::{Path, PathBuf};
use std::str::FromStr;
use c2rust_transpile::{Diagnostic, ReplaceMode, TranspilerConfig};
fn main() {
let yaml = load_yaml!("../transpile.yaml");
let matches = App::from_yaml(yaml).get_matches();
let cc_json_path = Path::new(matches.value_of("COMPILE_COMMANDS").unwrap());
let cc_json_path = cc_json_path
.canonicalize()
.unwrap_or_else(|_| {
panic!("Could not find compile_commands.json file at path: {}", cc_json_path.display())
});
let extra_args: Vec<&str> = match matches.values_of("extra-clang-args") {
Some(args) => args.collect(),
None => Vec::new(),
};
let enabled_warnings: HashSet<Diagnostic> = matches
.values_of("warn")
.unwrap_or_else(|| Values::default())
.map(|s| Diagnostic::from_str(s).unwrap())
.collect();
let mut tcfg = TranspilerConfig {
dump_untyped_context: matches.is_present("dump-untyped-clang-ast"),
dump_typed_context: matches.is_present("dump-typed-clang-ast"),
pretty_typed_context: matches.is_present("pretty-typed-clang-ast"),
dump_function_cfgs: matches.is_present("dump-function-cfgs"),
json_function_cfgs: matches.is_present("json-function-cfgs"),
dump_cfg_liveness: matches.is_present("dump-cfgs-liveness"),
dump_structures: matches.is_present("dump-structures"),
incremental_relooper: !matches.is_present("no-incremental-relooper"),
fail_on_error: matches.is_present("fail-on-error"),
fail_on_multiple: matches.is_present("fail-on-multiple"),
filter: {
if matches.is_present("filter") {
let filter = matches.value_of("filter").unwrap();
Some(Regex::new(filter).unwrap())
} else {
None
}
},
debug_relooper_labels: matches.is_present("debug-labels"),
cross_checks: matches.is_present("cross-checks"),
cross_check_backend: matches
.value_of("cross-check-backend")
.map(String::from)
.unwrap(),
cross_check_configs: matches
.values_of("cross-check-config")
.map(|vals| vals.map(String::from).collect::<Vec<_>>())
.unwrap_or_default(),
prefix_function_names: matches.value_of("prefix-function-names").map(String::from),
translate_asm: matches.is_present("translate-asm"),
translate_valist: true,
use_c_loop_info: !matches.is_present("ignore-c-loop-info"),
use_c_multiple_info: !matches.is_present("ignore-c-multiple-info"),
simplify_structures: !matches.is_present("no-simplify-structures"),
overwrite_existing: matches.is_present("overwrite-existing"),
reduce_type_annotations: matches.is_present("reduce-type-annotations"),
reorganize_definitions: matches.is_present("reorganize-definitions"),
emit_modules: matches.is_present("emit-modules"),
emit_build_files: matches.is_present("emit-build-files"),
output_dir: matches.value_of("output-dir").map(PathBuf::from),
main: {
if matches.is_present("main") {
Some(String::from(matches.value_of("main").unwrap()))
} else {
None
}
},
panic_on_translator_failure: {
match matches.value_of("invalid-code") {
Some("panic") => true,
Some("compile_error") => false,
_ => panic!("Invalid option"),
}
},
replace_unsupported_decls: ReplaceMode::Extern,
emit_no_std: matches.is_present("emit-no-std"),
verbose: matches.is_present("verbose"),
enabled_warnings,
};
if tcfg.main != None {
tcfg.emit_build_files = true
};
if tcfg.emit_build_files {
tcfg.emit_modules = true
};
c2rust_transpile::transpile(tcfg, &cc_json_path, &extra_args);
}