109 lines
3 KiB
Rust
109 lines
3 KiB
Rust
use clap::Subcommand;
|
|
use clap_num::maybe_hex;
|
|
use std::path::PathBuf;
|
|
|
|
#[derive(clap::Parser)]
|
|
struct Cli {
|
|
/// the file to operate on
|
|
#[arg(short, long)]
|
|
file: PathBuf,
|
|
|
|
/// section location
|
|
#[arg(short, long, default_value_t = 1, value_parser = maybe_hex::<u32>)]
|
|
location: u32,
|
|
|
|
#[command(subcommand)]
|
|
command: Command,
|
|
}
|
|
|
|
#[derive(Subcommand)]
|
|
enum Command {
|
|
/// list linear table
|
|
Linear,
|
|
|
|
/// list hash table
|
|
Hash,
|
|
|
|
/// resolve a key via hash table
|
|
HashLookup { key: String },
|
|
|
|
/// list 2D "hilbert curve" table
|
|
X2dhc,
|
|
}
|
|
|
|
fn typ_to_txt(typ: u32) -> String {
|
|
use yglnk_core::IntEnum;
|
|
match yglnk_core::Type::from_int(typ) {
|
|
Ok(x) => format!("{:?}", x),
|
|
Err(_) => format!("{:08x}", typ),
|
|
}
|
|
}
|
|
|
|
fn name_to_txt(name: &[u8]) -> String {
|
|
if let Ok(name) = core::str::from_utf8(name) {
|
|
format!("{:?}", name)
|
|
} else {
|
|
"0x".chars()
|
|
.chain(
|
|
name.iter()
|
|
.flat_map(|i| format!("{:02x}", i).chars().collect::<Vec<_>>()),
|
|
)
|
|
.collect()
|
|
}
|
|
}
|
|
|
|
fn main() {
|
|
let cli = <Cli as clap::Parser>::parse();
|
|
|
|
let fh = std::fs::File::open(&cli.file).expect("unable to open specified file");
|
|
let data = unsafe {
|
|
memmap2::MmapOptions::new()
|
|
.map(&fh)
|
|
.expect("unable to mmap specified file")
|
|
};
|
|
let data = &data[..];
|
|
|
|
match &cli.command {
|
|
Command::Linear => {
|
|
let ltr = yglnk_core::LinearTableRef::parse(data, cli.location)
|
|
.expect("unable to parse table header");
|
|
println!("location\tmeta\t\tname\t\ttyp\t\trest");
|
|
for i in ltr {
|
|
println!(
|
|
"{:08x}\t{:08x}\t{}\t{}\t{}",
|
|
i.location,
|
|
i.meta,
|
|
name_to_txt(i.name),
|
|
typ_to_txt(i.typ),
|
|
name_to_txt(i.rest),
|
|
);
|
|
}
|
|
}
|
|
Command::Hash => {
|
|
let ht = yglnk_core::hash_table::Ref::parse(data, cli.location)
|
|
.expect("unable to parse table header");
|
|
println!("hash\t\tname\t\ttyp\trest");
|
|
for (hash, name, value) in ht.iter() {
|
|
println!(
|
|
"{:016x}\t{}\t{}\t{}",
|
|
hash,
|
|
name_to_txt(name),
|
|
typ_to_txt(value.typ),
|
|
name_to_txt(value.rest),
|
|
);
|
|
}
|
|
}
|
|
Command::HashLookup { key } => {
|
|
let ht = yglnk_core::hash_table::Ref::parse(data, cli.location)
|
|
.expect("unable to parse table header");
|
|
match ht.lookup(key.as_bytes()) {
|
|
None => println!("(none)"),
|
|
Some(value) => {
|
|
println!("typ={} {}", typ_to_txt(value.typ), name_to_txt(value.rest),)
|
|
}
|
|
}
|
|
}
|
|
Command::X2dhc => unimplemented!(),
|
|
}
|
|
}
|