summaryrefslogtreecommitdiff
path: root/src/main.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/main.rs')
-rw-r--r--src/main.rs92
1 files changed, 81 insertions, 11 deletions
diff --git a/src/main.rs b/src/main.rs
index de2ebb2..c68f26a 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,5 +1,8 @@
mod args;
+mod zip;
+use std::fs::File;
+use std::io;
use std::process::ExitCode;
fn guess_parser(args: &mut dyn Iterator<Item = String>) -> Box<dyn args::Parser> {
@@ -13,7 +16,14 @@ fn guess_parser(args: &mut dyn Iterator<Item = String>) -> Box<dyn args::Parser>
Box::new(args::LongOnlyParser::new())
}
-fn parse_args() -> Result<bool, String> {
+struct Program {
+ classname: String,
+ args: Vec<String>,
+ classpath: String,
+ verbose: bool,
+}
+
+fn parse_args() -> Result<Option<Program>, String> {
let mut options = args::Options::new();
let help_idx = options.push(
args::OptionBuilder::default()
@@ -38,6 +48,22 @@ fn parse_args() -> Result<bool, String> {
.build()
.unwrap(),
);
+ let cp_idx = options.push(
+ args::OptionBuilder::default()
+ .long("cp")
+ .description("class search path of directories and zip/jar files")
+ .value(args::ValueRequirement::Required("CLASSPATH"))
+ .build()
+ .unwrap(),
+ );
+ let classpath_idx = options.push(
+ args::OptionBuilder::default()
+ .long("classpath")
+ .description("class search path of directories and zip/jar files")
+ .value(args::ValueRequirement::Required("CLASSPATH"))
+ .build()
+ .unwrap(),
+ );
let parser = guess_parser(&mut std::env::args());
let maybe_args = parser.run(&mut options, &mut std::env::args());
@@ -46,33 +72,77 @@ fn parse_args() -> Result<bool, String> {
let help = &options[help_idx];
if help.is_set() {
parser.print_help(&options);
- return Ok(true);
+ return Ok(None);
}
let args = maybe_args?;
let version = &options[version_idx];
if version.is_set() {
println!("Version is 0.0.1");
- return Ok(true);
+ return Ok(None);
}
let verbose = &options[verbose_idx];
- println!("verbose: {}", verbose.is_set());
- println!("args: {:?}", args.args);
- Ok(false)
+ let cp = &options[cp_idx];
+ let classpath = &options[classpath_idx];
+ let actual_classpath: &str;
+ if cp.is_set() {
+ if classpath.is_set() {
+ return Err("Both -cp and -classpath set, pick one.".to_string());
+ }
+ actual_classpath = cp.value().as_ref().unwrap();
+ } else if classpath.is_set() {
+ actual_classpath = classpath.value().as_ref().unwrap();
+ } else {
+ actual_classpath = "";
+ }
+
+ let mut run_args = args.args.iter();
+ if let Some(classname) = run_args.next() {
+ Ok(Some(Program {
+ classname: classname.clone(),
+ args: run_args.map(|s| s.clone()).collect(),
+ classpath: actual_classpath.to_string(),
+ verbose: verbose.is_set(),
+ }))
+ } else {
+ Err("Missing class name".to_string())
+ }
+}
+
+fn run(program: Program) -> io::Result<ExitCode> {
+ let mut paths = program.classpath.split(':');
+ let mut file = File::open(paths.next().unwrap())?;
+ let layout = zip::Layout::new(&mut file)?;
+ for (name, idx) in layout.names() {
+ let entry = &layout.entries()[*idx];
+ println!(
+ "{name}: {} {}",
+ entry.compressed_size(),
+ entry.uncompressed_size()
+ );
+ }
+ return Ok(ExitCode::SUCCESS);
}
fn main() -> ExitCode {
match parse_args() {
- Ok(exit) => {
- if exit {
+ Ok(maybe_program) => match maybe_program {
+ Some(program) => match run(program) {
+ Ok(exit_code) => {
+ return exit_code;
+ }
+ Err(err) => {
+ eprintln!("{}", err);
+ return ExitCode::FAILURE;
+ }
+ },
+ None => {
return ExitCode::SUCCESS;
}
- }
+ },
Err(msg) => {
eprintln!("{}", msg);
return ExitCode::FAILURE;
}
}
-
- ExitCode::SUCCESS
}