diff --git a/src/main.rs b/src/main.rs index a30eb95..5446f27 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,3 +1,68 @@ +// Try to keep this string updated with the argument parsing, otherwise it will +// get confusing for users. +static USAGE: &'static str = "usage: pine [options] input + +options: + --help print all options"; + fn main() { - println!("Hello, world!"); + // Throw away the first argument, which usually is the executable name. + let args = std::env::args().skip(1).collect::>(); + + // If there is no arguments, we short circuit to avoid having to perform the + // expensive command-line argument generation and parsing step. We can allow + // ourselves to do this since, unlike i.e. rustc, we don't print full usage + // information on invocation of only the binary, but instead we behave more + // like clang or go. + if args.len() == 0 { + eprintln!("pine: \x1b[1;31merror\x1b[0m: no input files"); + std::process::exit(1); + } + + let mut path: Option<&str> = None; + // Handle command-line arguments. + let mut i = 0; + loop { + if i == args.len() { + break; + } + + let arg = args[i].as_str(); + + if arg.starts_with("--") { + match &arg[2..] { + "help" => { + println!("{}\n", USAGE); + return; + }, + _ => { + eprintln!("pine: \x1b[1;31merror\x1b[0m: unknown argument '{}'", arg); + std::process::exit(1); + }, + }; + } else if arg.starts_with("-") { + // We don't handle arguments that start with a single dash, this might be + // added later. For now we just exit with an error. + eprintln!("pine: \x1b[1;31merror\x1b[0m: unknown argument '{}'", arg); + std::process::exit(1); + } else { + if path.is_some() { + eprintln!("pine: \x1b[1;31merror\x1b[0m: multiple file names provided (first two are `{}` and `{}`)", path.unwrap(), arg); + std::process::exit(1); + } + + // Use this argument as an input file. + path = Some(arg); + } + + i += 1; + } + + if path.is_none() { + eprintln!("pine: \x1b[1;31merror\x1b[0m: no input files"); + std::process::exit(1); + } + + let path = path.unwrap(); + eprintln!("compiling `{}`", path); }