xo65 0.1.0

Library for parsing cc65 object files (xo65 format)
Documentation
use tabled::Tabled;

use xo65::{Xo65, Xo65Flags, Xo65Header};

pub fn dump(obj: &Xo65) {
    dump_flags(obj);
    dump_tables(obj);
}

fn dump_flags(obj: &Xo65) {
    let flags = obj.header().flags();

    println!("Flags: {:#06X} ({})", flags.get(), FmtFlagsDesc(flags));
    println!();
}

fn dump_tables(obj: &Xo65) {
    println!("Tables:");
    println!("{}", FmtXo65Tables { hdr: obj.header() });
    println!();
}

#[derive(Debug)]
struct FmtFlagsDesc(Xo65Flags);

impl std::fmt::Display for FmtFlagsDesc {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        if self.0.has_debug_info() {
            write!(f, "DBGINFO")
        } else {
            write!(f, "")
        }
    }
}

#[derive(Debug)]
struct FmtXo65Tables<'a, 'data> {
    hdr: &'a Xo65Header<'data>,
}

impl std::fmt::Display for FmtXo65Tables<'_, '_> {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        use tabled::{
            settings::{object::Columns, Alignment, Style},
            Table,
        };

        let tables = [
            TabledTable::new(
                "MetadataTable",
                self.hdr.metadata_table_offset(),
                self.hdr.metadata_table_len(),
            ),
            TabledTable::new(
                "FileTable",
                self.hdr.file_table_offset(),
                self.hdr.file_table_len(),
            ),
            TabledTable::new(
                "SectionTable",
                self.hdr.section_table_offset(),
                self.hdr.section_table_len(),
            ),
            TabledTable::new(
                "ImportTable",
                self.hdr.import_table_offset(),
                self.hdr.import_table_len(),
            ),
            TabledTable::new(
                "ExportTable",
                self.hdr.export_table_offset(),
                self.hdr.export_table_len(),
            ),
            TabledTable::new(
                "DebugSymbolTable",
                self.hdr.debug_symbol_table_offset(),
                self.hdr.debug_symbol_table_len(),
            ),
            TabledTable::new(
                "LineInfoTable",
                self.hdr.line_info_table_offset(),
                self.hdr.line_info_table_len(),
            ),
            TabledTable::new(
                "StringTable",
                self.hdr.string_table_offset(),
                self.hdr.string_table_len(),
            ),
            TabledTable::new(
                "AssertTable",
                self.hdr.assert_table_offset(),
                self.hdr.assert_table_len(),
            ),
            TabledTable::new(
                "ScopeTable",
                self.hdr.scope_table_offset(),
                self.hdr.scope_table_len(),
            ),
            TabledTable::new(
                "SpanTable",
                self.hdr.span_table_offset(),
                self.hdr.span_table_len(),
            ),
        ];

        Table::new(tables)
            .with(Style::empty())
            .modify(Columns::single(1), Alignment::right()) // offset
            .modify(Columns::single(2), Alignment::right()) // size
            .fmt(f)
    }
}

#[derive(Debug, Tabled)]
struct TabledTable {
    name: &'static str,
    offset: String,
    size: String,
}

impl TabledTable {
    fn new(name: &'static str, offset: usize, size: usize) -> Self {
        let offset = format!("{offset:#8X}");
        let size = format!("{size:#8X}");

        Self { name, offset, size }
    }
}