Added overriding of data and function paths.

This commit is contained in:
Filipe Rodrigues 2021-04-30 17:27:32 +01:00
parent c4678e54cc
commit 6548ef75a8
2 changed files with 97 additions and 28 deletions

View File

@ -2,7 +2,7 @@
// Imports
use clap::{App as ClapApp, Arg as ClapArg};
use std::path::{Path, PathBuf};
use std::path::PathBuf;
/// Command line data
#[derive(PartialEq, Clone, Debug)]
@ -21,6 +21,18 @@ pub struct CliData {
/// If the data table should be printed
pub print_data_table: bool,
/// Known data path
pub known_data_path: PathBuf,
/// Foreign data path
pub foreign_data_path: PathBuf,
/// Known functions path
pub known_funcs_path: PathBuf,
/// Instruction overrides path
pub inst_arg_overrides_path: PathBuf,
}
impl CliData {
@ -32,6 +44,11 @@ impl CliData {
const PRINT_HEADER_STR: &str = "print-header";
const PRINT_DATA_TABLE_STR: &str = "print-data-table";
const KNOWN_DATA_PATH_STR: &str = "known-data-path";
const FOREIGN_DATA_PATH_STR: &str = "foreign-data-path";
const KNOWN_FUNCS_PATH_STR: &str = "known-funcs-path";
const INST_ARG_OVERRIDES_PATH_STR: &str = "inst-arg-overrides-path";
// Get all matches from cli
let matches = ClapApp::new("Dcb Decompiler")
.version("0.0")
@ -39,40 +56,65 @@ impl CliData {
.about("Decompiles all code from the Digimon Digital Card Battle `.bin` game file")
.arg(
ClapArg::with_name(INPUT_FILE_STR)
.long(INPUT_FILE_STR)
.help("Sets the input game file to use")
.required(true)
.index(1),
.index(1)
.takes_value(true),
)
.arg(
ClapArg::with_name(OUTPUT_DIR_STR)
.long("output")
.long(OUTPUT_DIR_STR)
.short("o")
.help("Sets the input game file to use")
.takes_value(true),
)
.arg(
ClapArg::with_name(PRINT_INST_POS_STR)
.long("print-inst-pos")
.long(PRINT_INST_POS_STR)
.help("If instructions' positions should be printed"),
)
.arg(
ClapArg::with_name(PRINT_HEADER_STR)
.long("print-header")
.long(PRINT_HEADER_STR)
.help("If the header of the executable should be printed"),
)
.arg(
ClapArg::with_name(PRINT_DATA_TABLE_STR)
.long("print-data-table")
.long(PRINT_DATA_TABLE_STR)
.help("If the data table of the executable should be printed"),
)
.arg(
ClapArg::with_name(KNOWN_DATA_PATH_STR)
.long(KNOWN_DATA_PATH_STR)
.help("Sets the path of the known data")
.takes_value(true),
)
.arg(
ClapArg::with_name(FOREIGN_DATA_PATH_STR)
.long(FOREIGN_DATA_PATH_STR)
.help("Sets the path of the foreign data")
.takes_value(true),
)
.arg(
ClapArg::with_name(KNOWN_FUNCS_PATH_STR)
.long(KNOWN_FUNCS_PATH_STR)
.help("Sets the path of the known funcs")
.takes_value(true),
)
.arg(
ClapArg::with_name(INST_ARG_OVERRIDES_PATH_STR)
.long(INST_ARG_OVERRIDES_PATH_STR)
.help("Sets the path of the function arguments overrides")
.takes_value(true),
)
.get_matches();
// Get the input filename
// Note: required
let input_path = matches
.value_of(INPUT_FILE_STR)
.map(Path::new)
.map(Path::to_path_buf)
.map(PathBuf::from)
.expect("Unable to get required argument `input-file`");
// Get the output directory, or just use `src`
@ -86,6 +128,19 @@ impl CliData {
let print_header = matches.is_present(PRINT_HEADER_STR);
let print_data_table = matches.is_present(PRINT_DATA_TABLE_STR);
let known_data_path = matches
.value_of(KNOWN_DATA_PATH_STR)
.unwrap_or(default_paths::KNOWN_DATA);
let foreign_data_path = matches
.value_of(FOREIGN_DATA_PATH_STR)
.unwrap_or(default_paths::FOREIGN_DATA);
let known_funcs_path = matches
.value_of(KNOWN_FUNCS_PATH_STR)
.unwrap_or(default_paths::KNOWN_FUNCS);
let inst_arg_overrides_path = matches
.value_of(INST_ARG_OVERRIDES_PATH_STR)
.unwrap_or(default_paths::INST_ARG_OVERRIDES);
// Return the cli data
Self {
input_path,
@ -93,6 +148,27 @@ impl CliData {
print_inst_pos,
print_header,
print_data_table,
known_data_path: PathBuf::from(known_data_path),
foreign_data_path: PathBuf::from(foreign_data_path),
known_funcs_path: PathBuf::from(known_funcs_path),
inst_arg_overrides_path: PathBuf::from(inst_arg_overrides_path),
}
}
}
/// Default paths
mod default_paths {
/// Known data path
pub const KNOWN_DATA: &str = "resources/game_data.yaml";
/// Foreign data path
pub const FOREIGN_DATA: &str = "resources/foreign_data.yaml";
/// Known functions path
pub const KNOWN_FUNCS: &str = "resources/game_funcs.yaml";
/// Instruction overrides path
pub const INST_ARG_OVERRIDES: &str = "resources/inst_args_override.yaml";
}

View File

@ -19,18 +19,6 @@ use dcb_exe::{
use itertools::{Itertools, Position};
use std::{collections::BTreeMap, fmt, fs, path::PathBuf};
/// Known data path
pub const KNOWN_DATA_PATH: &str = "resources/game_data.yaml";
/// Foreign data path
pub const FOREIGN_DATA_PATH: &str = "resources/foreign_data.yaml";
/// Known functions path
pub const KNOWN_FUNCS_PATH: &str = "resources/game_funcs.yaml";
/// Instruction overrides path
pub const INST_ARG_OVERRIDES_PATH: &str = "resources/inst_args_override.yaml";
fn main() -> Result<(), anyhow::Error> {
// Initialize the logger
simplelog::TermLogger::init(
@ -47,23 +35,28 @@ fn main() -> Result<(), anyhow::Error> {
let mut input_file = fs::File::open(&cli.input_path).context("Unable to open input file")?;
// Load the known and foreign data / func tables
let known_data: Vec<_> = dcb_util::parse_from_file(KNOWN_DATA_PATH, serde_yaml::from_reader)
let known_data_path = cli.known_data_path;
let foreign_data_path = cli.foreign_data_path;
let known_funcs_path = cli.known_funcs_path;
let inst_arg_overrides_path = cli.inst_arg_overrides_path;
let known_data: Vec<_> = dcb_util::parse_from_file(&known_data_path, serde_yaml::from_reader)
.map_err(dcb_util::fmt_err_wrapper_owned)
.map_err(|err| log::warn!("Unable to load game data from {KNOWN_DATA_PATH}:\n{err}"))
.map_err(|err| log::warn!("Unable to load game data from {known_data_path:?}:\n{err}"))
.unwrap_or_default();
let foreign_data: Vec<_> = dcb_util::parse_from_file(FOREIGN_DATA_PATH, serde_yaml::from_reader)
let foreign_data: Vec<_> = dcb_util::parse_from_file(&foreign_data_path, serde_yaml::from_reader)
.map_err(dcb_util::fmt_err_wrapper_owned)
.map_err(|err| log::warn!("Unable to load foreign data from {FOREIGN_DATA_PATH}:\n{err}"))
.map_err(|err| log::warn!("Unable to load foreign data from {foreign_data_path:?}:\n{err}"))
.unwrap_or_default();
let data_table = known_data.into_iter().chain(foreign_data).collect();
let func_table = dcb_util::parse_from_file(KNOWN_FUNCS_PATH, serde_yaml::from_reader)
let func_table = dcb_util::parse_from_file(&known_funcs_path, serde_yaml::from_reader)
.map_err(dcb_util::fmt_err_wrapper_owned)
.map_err(|err| log::warn!("Unable to load functions from {KNOWN_FUNCS_PATH}:\n{err}"))
.map_err(|err| log::warn!("Unable to load functions from {known_funcs_path:?}:\n{err}"))
.unwrap_or_default();
let mut inst_arg_overrides = dcb_util::parse_from_file(INST_ARG_OVERRIDES_PATH, serde_yaml::from_reader)
let mut inst_arg_overrides = dcb_util::parse_from_file(&inst_arg_overrides_path, serde_yaml::from_reader)
.map_err(dcb_util::fmt_err_wrapper_owned)
.map_err(|err| log::warn!("Unable to load instruction overrides from {INST_ARG_OVERRIDES_PATH}:\n{err}"))
.map_err(|err| log::warn!("Unable to load instruction overrides from {inst_arg_overrides_path:?}:\n{err}"))
.unwrap_or_default();
// Read the executable