diff --git a/Cargo.lock b/Cargo.lock index ac3d46b..05826db 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,5 +1,34 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. +[[package]] +name = "argh" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91792f088f87cdc7a2cfb1d617fa5ea18d7f1dc22ef0e1b5f82f3157cdc522be" +dependencies = [ + "argh_derive", + "argh_shared", +] + +[[package]] +name = "argh_derive" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4eb0c0c120ad477412dc95a4ce31e38f2113e46bd13511253f79196ca68b067" +dependencies = [ + "argh_shared", + "heck", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "argh_shared" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "781f336cc9826dbaddb9754cb5db61e64cab4f69668bd19dcc4a0394a86f4cb1" + [[package]] name = "arrayvec" version = "0.5.2" @@ -18,6 +47,15 @@ version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" +[[package]] +name = "heck" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20564e78d53d2bb135c343b3f47714a56af2061f1c928fdb541dc7b9fdd94205" +dependencies = [ + "unicode-segmentation", +] + [[package]] name = "lexical-core" version = "0.7.4" @@ -39,8 +77,9 @@ checksum = "4d58d1b70b004888f764dfbf6a26a3b0342a1632d33968e4a179d8011c760614" [[package]] name = "make_opcodes" -version = "0.1.0" +version = "0.1.1" dependencies = [ + "argh", "sanny_builder_core", ] @@ -61,6 +100,24 @@ dependencies = [ "version_check", ] +[[package]] +name = "proc-macro2" +version = "1.0.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e0704ee1a7e00d7bb417d0770ea303c1bccbabf0ef1667dae92b5967f5f8a71" +dependencies = [ + "unicode-xid", +] + +[[package]] +name = "quote" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa563d17ecb180e500da1cfd2b028310ac758de548efdd203e18f283af693f37" +dependencies = [ + "proc-macro2", +] + [[package]] name = "ryu" version = "1.0.5" @@ -82,6 +139,29 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" +[[package]] +name = "syn" +version = "1.0.52" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c1e438504729046a5cfae47f97c30d6d083c7d91d94603efdae3477fc070d4c" +dependencies = [ + "proc-macro2", + "quote", + "unicode-xid", +] + +[[package]] +name = "unicode-segmentation" +version = "1.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb0d2e7be6ae3a5fa87eed5fb451aff96f2573d2694942e40543ae0bbe19c796" + +[[package]] +name = "unicode-xid" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564" + [[package]] name = "version_check" version = "0.9.2" diff --git a/Cargo.toml b/Cargo.toml index 8252c70..abe419f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,10 +1,11 @@ [package] name = "make_opcodes" -version = "0.1.0" +version = "0.1.1" authors = ["Seemann "] edition = "2018" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -sanny_builder_core = { git = "https://github.com/sannybuilder/core", branch = "master", package = "sanny_builder_core" } \ No newline at end of file +sanny_builder_core = { git = "https://github.com/sannybuilder/core", branch = "master", package = "sanny_builder_core" } +argh = "0.1.4" \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index ea36231..5475471 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,84 +1,108 @@ +extern crate argh; extern crate sanny_builder_core as sb; +use argh::FromArgs; use sb::dictionary::dictionary_num_by_str::DictNumByStr; use sb::dictionary::ffi::*; use sb::namespaces::namespaces::Namespaces; use std::ffi::CString; +#[derive(FromArgs)] +/// +struct Options { + /// input text file to read + #[argh(positional)] + input: String, + + /// path to output file + #[argh(option)] + output: Option, + + /// path to classes.db + #[argh(option)] + classes: Option, + + /// path to keywords.txt + #[argh(option)] + keywords: Option, +} fn main() { - if let Some(input_file) = std::env::args().nth(1) { - match std::fs::read(input_file) { - Ok(buf) => { - let file_content = String::from_utf8_lossy(&buf); - let mut uniq_opcodes = vec![]; - let mut output = vec![]; - let mut keywords = DictNumByStr::new( - Duplicates::Replace, - CaseFormat::NoFormat, - String::from(";"), - String::from("=,"), - true, - true, - ); - let mut classes = Namespaces::new(); + let options: Options = argh::from_env(); - // todo: read from command line - let has_keywords = keywords.load_file("keywords.txt").is_some(); - let has_classes = classes.load_classes("classes.db").is_some(); + match std::fs::read(options.input) { + Ok(buf) => { + let file_content = String::from_utf8_lossy(&buf); + let mut uniq_opcodes: Vec = vec![]; + let mut output = vec![]; + let mut keywords = DictNumByStr::new( + Duplicates::Replace, + CaseFormat::LowerCase, + String::from(";"), + String::from("=,"), + true, + true, + ); + let mut classes = Namespaces::new(); - for line in file_content.lines() { - let line = line.trim(); + let has_keywords = keywords + .load_file(options.keywords.unwrap_or(String::new()).as_str()) + .is_some(); + let has_classes = classes + .load_classes(options.classes.unwrap_or(String::new()).as_str()) + .is_some(); - // opcode - if let Some(':') = line.chars().nth(4) { - if let Some(opcode) = line.get(0..4) { - if !uniq_opcodes.contains(&opcode) { - uniq_opcodes.push(opcode); - output.push(line); - continue; - } + for line in file_content.lines() { + let line = line.trim(); + + // opcode + if let Some(':') = line.chars().nth(4) { + if let Some(opcode) = line.get(0..4) { + let opcode = String::from(opcode); + if !uniq_opcodes.contains(&opcode) { + uniq_opcodes.push(opcode); + output.push(line); + continue; } } + } - if !has_classes && !has_keywords { - continue; - } + if !has_classes && !has_keywords { + continue; + } - if let Some(first_word) = line - .split(|c: char| { - c.is_ascii_whitespace() || c == '(' || c == ')' || c == ',' - }) - .next() - { - // keyword - if has_keywords { - if let Some(key) = CString::new(first_word).ok() { - if keywords.map.contains_key(&key) { - if !uniq_opcodes.contains(&first_word) { - uniq_opcodes.push(first_word); - output.push(line); - continue; - } + if let Some(first_word) = line + .split(|c: char| c.is_ascii_whitespace() || c == '(' || c == ')' || c == ',') + .map(|s| s.to_ascii_lowercase()) + .next() + { + // keyword + if has_keywords { + if let Some(key) = CString::new(first_word.clone()).ok() { + if keywords.map.contains_key(&key) { + if !uniq_opcodes.contains(&first_word) { + uniq_opcodes.push(first_word); + output.push(line); + continue; } } } + } - // classes - if has_classes { - if first_word.contains('.') { - let mut class = first_word.split(|c| c == '.'); + // classes + if has_classes { + if first_word.contains('.') { + let mut class = first_word.split(|c| c == '.'); - if let Some(class_name) = class.next() { - if let Some(member_name) = class.next() { - // bug: see https://github.com/sannybuilder/dev/issues/92 - if classes - .get_opcode_index_by_name(class_name, member_name) - .is_some() - { - if !uniq_opcodes.contains(&first_word) { - uniq_opcodes.push(first_word); - output.push(line); - continue; - } + if let Some(class_name) = class.next() { + if let Some(member_name) = class.next() { + // bug: see https://github.com/sannybuilder/dev/issues/92 + if classes + .get_opcode_index_by_name(class_name, member_name) + .is_some() + { + if !uniq_opcodes.contains(&first_word) { + uniq_opcodes.push(first_word); + output.push(line); + continue; } } } @@ -86,19 +110,21 @@ fn main() { } } } + } - output.sort(); + output.sort(); + if let Some(output_file) = options.output { + std::fs::write(output_file, output.join("\n")).unwrap(); + } else { for line in output { println!("{}", line); } } - Err(e) => { - println!("{}", e); - std::process::exit(2); - } } - } else { - println!("Usage: make_opcodes.exe "); + Err(e) => { + println!("{}", e); + std::process::exit(2); + } } }