diff --git a/.github/workflows/nightly_release.yml b/.github/workflows/nightly_release.yml index 7261aeab..0aa08093 100644 --- a/.github/workflows/nightly_release.yml +++ b/.github/workflows/nightly_release.yml @@ -31,7 +31,7 @@ # uses: actions-rs/cargo@v1 # with: # command: test -# args: --release --verbose +# args: --release --verbose --workspace # # - name: Get previous nightly Release info # uses: octokit/request-action@v2.x @@ -73,7 +73,7 @@ # with: # use-cross: true # command: build -# args: --release --verbose --target=x86_64-pc-windows-gnu +# args: --release --verbose --package customasm-cli --target=x86_64-pc-windows-gnu # # - name: Create remote nightly tag # env: @@ -114,4 +114,4 @@ # upload_url: ${{ steps.create_release.outputs.upload_url }} # asset_path: ./pkg/pkg.zip # asset_name: customasm_${{ env.RELEASE_TAG }}_win64.zip -# asset_content_type: application/zip \ No newline at end of file +# asset_content_type: application/zip diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index df1b173a..afbfc87b 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -25,14 +25,14 @@ jobs: uses: actions-rs/cargo@v1 with: command: test - args: --release --verbose + args: --release --verbose --workspace - name: Build uses: actions-rs/cargo@v1 with: use-cross: true command: build - args: --release --verbose --target=x86_64-pc-windows-gnu + args: --release --verbose --package customasm-cli --target=x86_64-pc-windows-gnu - name: Create Release id: create_release @@ -65,4 +65,4 @@ jobs: upload_url: ${{ steps.create_release.outputs.upload_url }} asset_path: ./pkg/pkg.zip asset_name: customasm_win64.zip - asset_content_type: application/zip \ No newline at end of file + asset_content_type: application/zip diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 33eb71a7..23767716 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -2,17 +2,7 @@ name: Test Build on: push: - branches: - - master - - dev - - 'dev-*' - - 'feature-*' pull_request: - branches: - - master - - dev - - 'dev-*' - - 'feature-*' jobs: build: @@ -22,6 +12,6 @@ jobs: steps: - uses: actions/checkout@v2 - name: Build - run: cargo build --verbose + run: cargo build --verbose --workspace - name: Run tests - run: cargo test --verbose \ No newline at end of file + run: cargo test --verbose --workspace diff --git a/Cargo.toml b/Cargo.toml index d72abdc5..8eaec4a4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,7 +9,7 @@ repository = "https://github.com/hlorenzi/customasm" readme = "README.md" license = "Apache-2.0" keywords = ["asm", "assembler", "assembly", "custom"] -categories = ["command-line-utilities", "hardware-support"] +categories = ["hardware-support"] exclude = ["web/*"] build = "src/build.rs" @@ -18,12 +18,7 @@ crate-type = ["lib", "cdylib"] name = "customasm" path = "src/lib.rs" -[[bin]] -name = "customasm" -path = "src/main.rs" - [dependencies] -getopts = "0.2.17" num-bigint = { version = "0.1", default_features = false } num-traits = { version = "0.1", default_features = false } num-integer = { version = "0.1", default_features = false } @@ -31,5 +26,7 @@ num-integer = { version = "0.1", default_features = false } [dev-dependencies] sha2 = "0.9.1" -[build-dependencies] -vergen = "3.1.0" \ No newline at end of file +[workspace] +members = [ + "customasm-cli", +] diff --git a/build_ghpages.ps1 b/build_ghpages.ps1 index 6692fde1..0eb2aaae 100644 --- a/build_ghpages.ps1 +++ b/build_ghpages.ps1 @@ -7,7 +7,7 @@ Remove-Item -Path .gitignore Copy-Item -Path .gitignore.ghpages -Destination .gitignore # Build wasm binary -cargo build --lib --target wasm32-unknown-unknown --release +cargo build --lib --target wasm32-unknown-unknown --release --workspace # Reduce binary size wasm-gc "./target/wasm32-unknown-unknown/release/customasm.wasm" -o "./target/wasm32-unknown-unknown/release/customasm.gc.wasm" @@ -21,4 +21,4 @@ git commit -m "build GitHub Pages" git push -f origin ghpages # Return to main branch -git checkout main \ No newline at end of file +git checkout main diff --git a/build_wasm.ps1 b/build_wasm.ps1 index f17f80cb..6d75fc0b 100644 --- a/build_wasm.ps1 +++ b/build_wasm.ps1 @@ -1,5 +1,5 @@ # Build wasm binary -cargo build --lib --target wasm32-unknown-unknown --release +cargo build --lib --target wasm32-unknown-unknown --release --workspace # Reduce binary size wasm-gc "./target/wasm32-unknown-unknown/release/customasm.wasm" -o "./target/wasm32-unknown-unknown/release/customasm.gc.wasm" diff --git a/customasm-cli/Cargo.toml b/customasm-cli/Cargo.toml new file mode 100644 index 00000000..58f714c9 --- /dev/null +++ b/customasm-cli/Cargo.toml @@ -0,0 +1,22 @@ +[package] +name = "customasm-cli" +version = "0.11.10" +edition = "2018" +authors = ["hlorenzi "] +description = "An assembler for custom, user-defined instruction sets!" +homepage = "https://github.com/hlorenzi/customasm" +repository = "https://github.com/hlorenzi/customasm" +license = "Apache-2.0" +keywords = ["asm", "assembler", "assembly", "custom"] +categories = ["command-line-utilities", "hardware-support"] + +[dependencies] +customasm = { path = "../" } +getopts = "0.2.17" + +[build-dependencies] +vergen = "3.1.0" + +[[bin]] +name = "customasm" +path = "src/main.rs" diff --git a/customasm-cli/build.rs b/customasm-cli/build.rs new file mode 100644 index 00000000..c4a2dc85 --- /dev/null +++ b/customasm-cli/build.rs @@ -0,0 +1,16 @@ +extern crate vergen; + + +use vergen::{generate_cargo_keys, ConstantsFlags}; + + +fn main() +{ + let mut flags = ConstantsFlags::empty(); + flags.toggle(ConstantsFlags::REBUILD_ON_HEAD_CHANGE); + flags.toggle(ConstantsFlags::SEMVER_LIGHTWEIGHT); + flags.toggle(ConstantsFlags::COMMIT_DATE); + flags.toggle(ConstantsFlags::TARGET_TRIPLE); + + generate_cargo_keys(flags).expect("Unable to generate the cargo keys!"); +} diff --git a/customasm-cli/src/driver.rs b/customasm-cli/src/driver.rs new file mode 100644 index 00000000..e96224c9 --- /dev/null +++ b/customasm-cli/src/driver.rs @@ -0,0 +1,442 @@ +use customasm::*; +use getopts; +use std::env; + +enum OutputFormat +{ + Binary, + AnnotatedHex, + AnnotatedBin, + BinStr, + HexStr, + BinDump, + HexDump, + Mif, + IntelHex, + DecComma, + HexComma, + DecC, + HexC, + LogiSim8, + LogiSim16, +} + + +enum SymbolFormat +{ + Default, + MesenMlb, +} + + +pub fn drive(args: &Vec, fileserver: &mut dyn util::FileServer) -> Result<(), ()> +{ + let opts = make_opts(); + + let report = diagn::RcReport::new(); + + let result = drive_inner(report.clone(), &opts, args, fileserver); + + if report.has_messages() + { + println!(""); + } + + util::enable_windows_ansi_support(); + report.print_all(&mut std::io::stderr(), fileserver); + + if let Err(show_usage) = result + { + if show_usage + { + print_version_short(); + print_usage(&opts); + } + } + + result.map_err(|_| ()) +} + + +fn drive_inner( + report: diagn::RcReport, + opts: &getopts::Options, + args: &Vec, + fileserver: &mut dyn util::FileServer, +) -> Result<(), bool> +{ + let matches = parse_opts(report.clone(), opts, args).map_err(|_| true)?; + + if matches.opt_present("h") + { + print_version_full(); + print_usage(&opts); + return Ok(()); + } + + if matches.opt_present("v") + { + print_version_full(); + return Ok(()); + } + + let quiet = matches.opt_present("q"); + let out_stdout = matches.opt_present("p"); + + let out_format = match matches.opt_str("f").as_ref().map(|s| s.as_ref()) + { + Some("annotated") => OutputFormat::AnnotatedHex, + Some("annotatedhex") => OutputFormat::AnnotatedHex, + Some("annotatedbin") => OutputFormat::AnnotatedBin, + + Some("binstr") => OutputFormat::BinStr, + Some("bindump") => OutputFormat::BinDump, + Some("hexstr") => OutputFormat::HexStr, + Some("hexdump") => OutputFormat::HexDump, + Some("binary") => OutputFormat::Binary, + Some("mif") => OutputFormat::Mif, + Some("intelhex") => OutputFormat::IntelHex, + Some("deccomma") => OutputFormat::DecComma, + Some("hexcomma") => OutputFormat::HexComma, + Some("decc") => OutputFormat::DecC, + Some("hexc") => OutputFormat::HexC, + Some("c") => OutputFormat::HexC, + Some("logisim8") => OutputFormat::LogiSim8, + Some("logisim16") => OutputFormat::LogiSim16, + + None => + { + if out_stdout + { + OutputFormat::AnnotatedHex + } + else + { + OutputFormat::Binary + } + } + + Some(_) => + { + report.error("invalid output format"); + return Err(true); + } + }; + + let symbol_format = match matches + .opt_str("symbol-format") + .as_ref() + .map(|s| s.as_ref()) + { + None | Some("default") => SymbolFormat::Default, + Some("mesen-mlb") => SymbolFormat::MesenMlb, + Some(_) => + { + report.error("invalid symbol format"); + return Err(true); + } + }; + + if matches.free.len() < 1 + { + report.error("no input files"); + return Err(true); + } + + let main_asm_file = matches.free[0].clone(); + + let output_symbol_requested = matches.opt_present("s"); + let output_requested = matches.opt_present("o"); + + let output_symbol_file = matches.opt_str("s"); + let output_file = match matches.opt_str("o") + { + Some(f) => Some(f), + None => + { + if output_symbol_requested || output_symbol_file.is_some() + { + None + } + else + { + match get_default_output_filename(report.clone(), &main_asm_file) + { + Ok(f) => Some(f), + Err(_) => None, + } + } + } + }; + + let max_iterations = match matches.opt_str("t") + { + None => 10, + Some(t) => match t.parse::() + { + Ok(t) => t, + Err(_) => + { + report.error("invalid number of iterations"); + return Err(true); + } + }, + }; + + if !quiet + { + print_version_short(); + } + + let mut assembler = asm::Assembler::new(); + for filename in matches.free + { + if !quiet + { + println!("assembling `{}`...", filename); + } + + assembler.register_file(filename); + } + + let output = assembler + .assemble(report.clone(), fileserver, max_iterations) + .map_err(|_| false)?; + + let binary = output.binary; + + let output_symbol_data = if output_symbol_file.is_none() + { + None + } + else + { + Some(match symbol_format + { + SymbolFormat::Default => output.state.symbols.format_default(), + SymbolFormat::MesenMlb => output.state.symbols.format_mesen_mlb(&output.state), + }) + }; + + let output_data: Vec = match out_format + { + OutputFormat::Binary => binary.format_binary(), + + OutputFormat::BinStr => binary.format_binstr().bytes().collect(), + OutputFormat::HexStr => binary.format_hexstr().bytes().collect(), + OutputFormat::BinDump => binary.format_bindump().bytes().collect(), + OutputFormat::HexDump => binary.format_hexdump().bytes().collect(), + OutputFormat::Mif => binary.format_mif().bytes().collect(), + OutputFormat::IntelHex => binary.format_intelhex().bytes().collect(), + OutputFormat::DecComma => binary.format_comma(10).bytes().collect(), + OutputFormat::HexComma => binary.format_comma(16).bytes().collect(), + OutputFormat::DecC => binary.format_c_array(10).bytes().collect(), + OutputFormat::HexC => binary.format_c_array(16).bytes().collect(), + OutputFormat::LogiSim8 => binary.format_logisim(8).bytes().collect(), + OutputFormat::LogiSim16 => binary.format_logisim(16).bytes().collect(), + + OutputFormat::AnnotatedHex => binary.format_annotated_hex(fileserver).bytes().collect(), + OutputFormat::AnnotatedBin => binary.format_annotated_bin(fileserver).bytes().collect(), + }; + + if out_stdout + { + if !quiet + { + println!( + "success after {} iteration{}", + output.iterations, + if output.iterations == 1 { "" } else { "s" } + ); + println!(""); + } + + if output_requested || output_file.is_some() + { + println!("{}", String::from_utf8_lossy(&output_data)); + } + + if output_symbol_requested || output_symbol_file.is_some() + { + if let Some(output_symbol_data) = output_symbol_data + { + println!("{}", &output_symbol_data); + } + } + } + else + { + let mut any_files_written = false; + + if let Some(ref output_file) = output_file + { + println!("writing `{}`...", &output_file); + fileserver + .write_bytes(report.clone(), &output_file, &output_data, None) + .map_err(|_| false)?; + any_files_written = true; + } + + if let Some(output_symbol_data) = output_symbol_data + { + if let Some(ref output_symbol_file) = output_symbol_file + { + println!("writing `{}`...", &output_symbol_file); + fileserver + .write_bytes( + report.clone(), + &output_symbol_file, + &output_symbol_data.bytes().collect::>(), + None, + ) + .map_err(|_| false)?; + any_files_written = true; + } + } + + if !any_files_written + { + println!("no files written"); + } + + if !quiet + { + println!( + "success after {} iteration{}", + output.iterations, + if output.iterations == 1 { "" } else { "s" } + ); + } + } + + Ok(()) +} + + +fn make_opts() -> getopts::Options +{ + let mut opts = getopts::Options::new(); + opts.optopt("f", "format", "The format of the output file. Possible formats: binary, annotated, annotatedbin, binstr, hexstr, bindump, hexdump, mif, intelhex, deccomma, hexcomma, decc, hexc, logisim8, logisim16", "FORMAT"); + opts.opt( + "o", + "output", + "The name of the output file.", + "FILE", + getopts::HasArg::Maybe, + getopts::Occur::Optional, + ); + opts.optopt( + "", + "symbol-format", + "The format of the symbol file. Possible formats: default, mesen-mlb", + "SYMBOL-FORMAT", + ); + opts.opt( + "s", + "symbol", + "The name of the output symbol file.", + "FILE", + getopts::HasArg::Maybe, + getopts::Occur::Optional, + ); + opts.opt( + "t", + "iter", + "The max number of passes the assembler will attempt (default: 10).", + "NUM", + getopts::HasArg::Maybe, + getopts::Occur::Optional, + ); + opts.optflag( + "p", + "print", + "Print output to stdout instead of writing to a file.", + ); + opts.optflag("q", "quiet", "Suppress progress reports."); + opts.optflag("v", "version", "Display version information."); + opts.optflag("h", "help", "Display this information."); + + opts +} + + +fn parse_opts( + report: diagn::RcReport, + opts: &getopts::Options, + args: &Vec, +) -> Result +{ + match opts.parse(&args[1..]) + { + Ok(m) => Ok(m), + Err(f) => Err(report.error(format!("{}", f))), + } +} + + +fn print_usage(opts: &getopts::Options) +{ + println!(""); + println!( + "{}", + opts.usage(&format!( + "Usage: {} [options] ... ", + env!("CARGO_PKG_NAME") + )) + ); +} + + +fn print_version_short() +{ + let mut version = env!("VERGEN_SEMVER_LIGHTWEIGHT").to_string(); + if version == "UNKNOWN" + { + version = format!("v{}", env!("CARGO_PKG_VERSION")); + } + + + let mut date = format!("{}, ", env!("VERGEN_COMMIT_DATE")); + if date == "UNKNOWN, " + { + date = "".to_string(); + } + + + println!( + "{} {} ({}{})", + env!("CARGO_PKG_NAME"), + version, + date, + env!("VERGEN_TARGET_TRIPLE") + ); +} + + +fn print_version_full() +{ + print_version_short(); + println!("https://github.com/hlorenzi/customasm"); +} + + +fn get_default_output_filename(report: diagn::RcReport, input_filename: &str) + -> Result +{ + use std::path::PathBuf; + + let mut output_filename = PathBuf::from(input_filename); + output_filename.set_extension("bin"); + + let output_filename = output_filename + .to_string_lossy() + .into_owned() + .replace("\\", "/"); + + if output_filename == input_filename + { + return Err(report.error("cannot derive safe output filename")); + } + + Ok(output_filename) +} diff --git a/customasm-cli/src/main.rs b/customasm-cli/src/main.rs new file mode 100644 index 00000000..6e885ce8 --- /dev/null +++ b/customasm-cli/src/main.rs @@ -0,0 +1,15 @@ +use customasm::util::FileServerReal; + +mod driver; + +fn main() +{ + let args: Vec = std::env::args().collect(); + + let mut fileserver = FileServerReal::new(); + + if let Err(()) = driver::drive(&args, &mut fileserver) + { + std::process::exit(1); + } +} diff --git a/src/build.rs b/src/build.rs index b3988abd..c676e106 100644 --- a/src/build.rs +++ b/src/build.rs @@ -1,24 +1,4 @@ -extern crate vergen; - - -use vergen::{ConstantsFlags, generate_cargo_keys}; - - fn main() -{ - let mut flags = ConstantsFlags::empty(); - flags.toggle(ConstantsFlags::REBUILD_ON_HEAD_CHANGE); - flags.toggle(ConstantsFlags::SEMVER_LIGHTWEIGHT); - flags.toggle(ConstantsFlags::COMMIT_DATE); - flags.toggle(ConstantsFlags::TARGET_TRIPLE); - - generate_cargo_keys(flags).expect("Unable to generate the cargo keys!"); - - generate_tests(); -} - - -fn generate_tests() { let out_dir = std::env::var("OUT_DIR").unwrap(); let destination = std::path::Path::new(&out_dir).join("test.rs"); diff --git a/src/driver.rs b/src/driver.rs deleted file mode 100644 index 0aa3ef63..00000000 --- a/src/driver.rs +++ /dev/null @@ -1,365 +0,0 @@ -use crate::*; -use getopts; - - -enum OutputFormat -{ - Binary, - AnnotatedHex, - AnnotatedBin, - BinStr, - HexStr, - BinDump, - HexDump, - Mif, - IntelHex, - DecComma, - HexComma, - DecC, - HexC, - LogiSim8, - LogiSim16, -} - - -enum SymbolFormat -{ - Default, - MesenMlb, -} - - -pub fn drive(args: &Vec, fileserver: &mut dyn util::FileServer) -> Result<(), ()> -{ - let opts = make_opts(); - - let report = diagn::RcReport::new(); - - let result = drive_inner(report.clone(), &opts, args, fileserver); - - if report.has_messages() - { println!(""); } - - util::enable_windows_ansi_support(); - report.print_all(&mut std::io::stderr(), fileserver); - - if let Err(show_usage) = result - { - if show_usage - { - print_version_short(); - print_usage(&opts); - } - } - - result.map_err(|_| ()) -} - - -fn drive_inner( - report: diagn::RcReport, - opts: &getopts::Options, - args: &Vec, - fileserver: &mut dyn util::FileServer) - -> Result<(), bool> -{ - let matches = parse_opts(report.clone(), opts, args).map_err(|_| true)?; - - if matches.opt_present("h") - { - print_version_full(); - print_usage(&opts); - return Ok(()); - } - - if matches.opt_present("v") - { - print_version_full(); - return Ok(()); - } - - let quiet = matches.opt_present("q"); - let out_stdout = matches.opt_present("p"); - - let out_format = match matches.opt_str("f").as_ref().map(|s| s.as_ref()) - { - Some("annotated") => OutputFormat::AnnotatedHex, - Some("annotatedhex") => OutputFormat::AnnotatedHex, - Some("annotatedbin") => OutputFormat::AnnotatedBin, - - Some("binstr") => OutputFormat::BinStr, - Some("bindump") => OutputFormat::BinDump, - Some("hexstr") => OutputFormat::HexStr, - Some("hexdump") => OutputFormat::HexDump, - Some("binary") => OutputFormat::Binary, - Some("mif") => OutputFormat::Mif, - Some("intelhex") => OutputFormat::IntelHex, - Some("deccomma") => OutputFormat::DecComma, - Some("hexcomma") => OutputFormat::HexComma, - Some("decc") => OutputFormat::DecC, - Some("hexc") => OutputFormat::HexC, - Some("c") => OutputFormat::HexC, - Some("logisim8") => OutputFormat::LogiSim8, - Some("logisim16") => OutputFormat::LogiSim16, - - None => if out_stdout - { OutputFormat::AnnotatedHex } - else - { OutputFormat::Binary }, - - Some(_) => - { - report.error("invalid output format"); - return Err(true); - } - }; - - let symbol_format = match matches.opt_str("symbol-format").as_ref().map(|s| s.as_ref()) - { - None | - Some("default") => SymbolFormat::Default, - Some("mesen-mlb") => SymbolFormat::MesenMlb, - Some(_) => - { - report.error("invalid symbol format"); - return Err(true); - } - }; - - if matches.free.len() < 1 - { - report.error("no input files"); - return Err(true); - } - - let main_asm_file = matches.free[0].clone(); - - let output_symbol_requested = matches.opt_present("s"); - let output_requested = matches.opt_present("o"); - - let output_symbol_file = matches.opt_str("s"); - let output_file = match matches.opt_str("o") - { - Some(f) => Some(f), - None => - { - if output_symbol_requested || output_symbol_file.is_some() - { None } - else - { - match get_default_output_filename(report.clone(), &main_asm_file) - { - Ok(f) => Some(f), - Err(_) => None, - } - } - } - }; - - let max_iterations = match matches.opt_str("t") - { - None => 10, - Some(t) => - { - match t.parse::() - { - Ok(t) => t, - Err(_) => - { - report.error("invalid number of iterations"); - return Err(true); - } - } - } - }; - - if !quiet - { print_version_short(); } - - let mut assembler = asm::Assembler::new(); - for filename in matches.free - { - if !quiet - { - println!("assembling `{}`...", filename); - } - - assembler.register_file(filename); - } - - let output = assembler.assemble( - report.clone(), - fileserver, - max_iterations) - .map_err(|_| false)?; - - let binary = output.binary; - - let output_symbol_data = if output_symbol_file.is_none() - { - None - } - else - { - Some(match symbol_format - { - SymbolFormat::Default => output.state.symbols.format_default(), - SymbolFormat::MesenMlb => output.state.symbols.format_mesen_mlb(&output.state), - }) - }; - - let output_data: Vec = match out_format - { - OutputFormat::Binary => binary.format_binary(), - - OutputFormat::BinStr => binary.format_binstr () .bytes().collect(), - OutputFormat::HexStr => binary.format_hexstr () .bytes().collect(), - OutputFormat::BinDump => binary.format_bindump () .bytes().collect(), - OutputFormat::HexDump => binary.format_hexdump () .bytes().collect(), - OutputFormat::Mif => binary.format_mif () .bytes().collect(), - OutputFormat::IntelHex => binary.format_intelhex() .bytes().collect(), - OutputFormat::DecComma => binary.format_comma (10).bytes().collect(), - OutputFormat::HexComma => binary.format_comma (16).bytes().collect(), - OutputFormat::DecC => binary.format_c_array (10).bytes().collect(), - OutputFormat::HexC => binary.format_c_array (16).bytes().collect(), - OutputFormat::LogiSim8 => binary.format_logisim (8) .bytes().collect(), - OutputFormat::LogiSim16 => binary.format_logisim (16).bytes().collect(), - - OutputFormat::AnnotatedHex => binary.format_annotated_hex(fileserver).bytes().collect(), - OutputFormat::AnnotatedBin => binary.format_annotated_bin(fileserver).bytes().collect(), - }; - - if out_stdout - { - if !quiet - { - println!("success after {} iteration{}", - output.iterations, - if output.iterations == 1 { "" } else { "s" }); - println!(""); - } - - if output_requested || output_file.is_some() - { println!("{}", String::from_utf8_lossy(&output_data)); } - - if output_symbol_requested || output_symbol_file.is_some() - { - if let Some(output_symbol_data) = output_symbol_data - { println!("{}", &output_symbol_data); } - } - } - else - { - let mut any_files_written = false; - - if let Some(ref output_file) = output_file - { - println!("writing `{}`...", &output_file); - fileserver.write_bytes(report.clone(), &output_file, &output_data, None).map_err(|_| false)?; - any_files_written = true; - } - - if let Some(output_symbol_data) = output_symbol_data - { - if let Some(ref output_symbol_file) = output_symbol_file - { - println!("writing `{}`...", &output_symbol_file); - fileserver.write_bytes(report.clone(), &output_symbol_file, &output_symbol_data.bytes().collect::>(), None).map_err(|_| false)?; - any_files_written = true; - } - } - - if !any_files_written - { println!("no files written"); } - - if !quiet - { - println!("success after {} iteration{}", - output.iterations, - if output.iterations == 1 { "" } else { "s" }); - } - } - - Ok(()) -} - - -fn make_opts() -> getopts::Options -{ - let mut opts = getopts::Options::new(); - opts.optopt("f", "format", "The format of the output file. Possible formats: binary, annotated, annotatedbin, binstr, hexstr, bindump, hexdump, mif, intelhex, deccomma, hexcomma, decc, hexc, logisim8, logisim16", "FORMAT"); - opts.opt("o", "output", "The name of the output file.", "FILE", getopts::HasArg::Maybe, getopts::Occur::Optional); - opts.optopt("", "symbol-format", "The format of the symbol file. Possible formats: default, mesen-mlb", "SYMBOL-FORMAT"); - opts.opt("s", "symbol", "The name of the output symbol file.", "FILE", getopts::HasArg::Maybe, getopts::Occur::Optional); - opts.opt("t", "iter", "The max number of passes the assembler will attempt (default: 10).", "NUM", getopts::HasArg::Maybe, getopts::Occur::Optional); - opts.optflag("p", "print", "Print output to stdout instead of writing to a file."); - opts.optflag("q", "quiet", "Suppress progress reports."); - opts.optflag("v", "version", "Display version information."); - opts.optflag("h", "help", "Display this information."); - - opts -} - - -fn parse_opts(report: diagn::RcReport, opts: &getopts::Options, args: &Vec) -> Result -{ - match opts.parse(&args[1..]) - { - Ok(m) => Ok(m), - Err(f) => Err(report.error(format!("{}", f))) - } -} - - -fn print_usage(opts: &getopts::Options) -{ - println!(""); - println!("{}", opts.usage(&format!("Usage: {} [options] ... ", env!("CARGO_PKG_NAME")))); -} - - -fn print_version_short() -{ - let mut version = env!("VERGEN_SEMVER_LIGHTWEIGHT").to_string(); - if version == "UNKNOWN" - { - version = format!("v{}", env!("CARGO_PKG_VERSION")); - } - - - let mut date = format!("{}, ", env!("VERGEN_COMMIT_DATE")); - if date == "UNKNOWN, " - { - date = "".to_string(); - } - - - println!("{} {} ({}{})", - env!("CARGO_PKG_NAME"), - version, - date, - env!("VERGEN_TARGET_TRIPLE")); -} - - -fn print_version_full() -{ - print_version_short(); - println!("https://github.com/hlorenzi/customasm"); -} - - -fn get_default_output_filename(report: diagn::RcReport, input_filename: &str) -> Result -{ - use std::path::PathBuf; - - let mut output_filename = PathBuf::from(input_filename); - output_filename.set_extension("bin"); - - let output_filename = output_filename.to_string_lossy().into_owned().replace("\\", "/"); - - if output_filename == input_filename - { return Err(report.error("cannot derive safe output filename")); } - - Ok(output_filename) -} diff --git a/src/lib.rs b/src/lib.rs index 756c94a8..5fdfd936 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,18 +1,10 @@ #![allow(dead_code)] - -extern crate num_bigint; -extern crate num_traits; -extern crate num_integer; -extern crate getopts; - - pub mod diagn; pub mod syntax; pub mod expr; pub mod asm; pub mod util; -pub mod driver; pub mod webasm; diff --git a/src/main.rs b/src/main.rs deleted file mode 100644 index edf450f6..00000000 --- a/src/main.rs +++ /dev/null @@ -1,12 +0,0 @@ -extern crate customasm; - - -fn main() -{ - let args: Vec = std::env::args().collect(); - - let mut fileserver = customasm::util::FileServerReal::new(); - - if let Err(()) = customasm::driver::drive(&args, &mut fileserver) - { std::process::exit(1); } -} \ No newline at end of file