mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-26 00:34:06 +00:00
Merge pull request #3739 from killerswan/usagemsg
Add a module to getopts for verbose option group declaration (and use it in rustc)
This commit is contained in:
commit
33adb7a824
@ -203,6 +203,13 @@ pub pure fn connect(v: &[~str], sep: &str) -> ~str {
|
||||
move s
|
||||
}
|
||||
|
||||
/// Given a string, make a new string with repeated copies of it
|
||||
pub fn repeat(ss: &str, nn: uint) -> ~str {
|
||||
let mut acc = ~"";
|
||||
for nn.times { acc += ss; }
|
||||
return acc;
|
||||
}
|
||||
|
||||
/*
|
||||
Section: Adding to and removing from a string
|
||||
*/
|
||||
@ -573,6 +580,40 @@ pub pure fn words(s: &str) -> ~[~str] {
|
||||
split_nonempty(s, |c| char::is_whitespace(c))
|
||||
}
|
||||
|
||||
/** Split a string into a vector of substrings,
|
||||
* each of which is less than a limit
|
||||
*/
|
||||
pub fn split_within(ss: &str, lim: uint) -> ~[~str] {
|
||||
let words = str::words(ss);
|
||||
|
||||
// empty?
|
||||
if words == ~[] { return ~[]; }
|
||||
|
||||
let mut rows : ~[~str] = ~[];
|
||||
let mut row : ~str = ~"";
|
||||
|
||||
for words.each |wptr| {
|
||||
let word = *wptr;
|
||||
|
||||
// if adding this word to the row would go over the limit,
|
||||
// then start a new row
|
||||
if str::len(row) + str::len(word) + 1 > lim {
|
||||
rows += [row]; // save previous row
|
||||
row = word; // start a new one
|
||||
} else {
|
||||
if str::len(row) > 0 { row += ~" " } // separate words
|
||||
row += word; // append to this row
|
||||
}
|
||||
}
|
||||
|
||||
// save the last row
|
||||
if row != ~"" { rows += [row]; }
|
||||
|
||||
return rows;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// Convert a string to lowercase. ASCII only
|
||||
pub pure fn to_lower(s: &str) -> ~str {
|
||||
map(s,
|
||||
@ -2479,6 +2520,18 @@ mod tests {
|
||||
assert ~[] == words(~"");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_split_within() {
|
||||
assert split_within(~"", 0) == ~[];
|
||||
assert split_within(~"", 15) == ~[];
|
||||
assert split_within(~"hello", 15) == ~[~"hello"];
|
||||
|
||||
let data = ~"\nMary had a little lamb\nLittle lamb\n";
|
||||
assert split_within(data, 15) == ~[~"Mary had a little",
|
||||
~"lamb Little",
|
||||
~"lamb"];
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_find_str() {
|
||||
// byte positions
|
||||
@ -2554,6 +2607,15 @@ mod tests {
|
||||
t(~[~"hi"], ~" ", ~"hi");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_repeat() {
|
||||
assert repeat(~"x", 4) == ~"xxxx";
|
||||
assert repeat(~"hi", 4) == ~"hihihihi";
|
||||
assert repeat(~"ไท华", 3) == ~"ไท华ไท华ไท华";
|
||||
assert repeat(~"", 4) == ~"";
|
||||
assert repeat(~"hi", 0) == ~"";
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_to_upper() {
|
||||
// libc::toupper, and hence str::to_upper
|
||||
|
@ -82,7 +82,7 @@ pub type Opt = {name: Name, hasarg: HasArg, occur: Occur};
|
||||
|
||||
fn mkname(nm: &str) -> Name {
|
||||
let unm = str::from_slice(nm);
|
||||
return if str::len(nm) == 1u {
|
||||
return if nm.len() == 1u {
|
||||
Short(str::char_at(unm, 0u))
|
||||
} else { Long(unm) };
|
||||
}
|
||||
@ -114,6 +114,22 @@ impl Occur : Eq {
|
||||
pure fn ne(other: &Occur) -> bool { !self.eq(other) }
|
||||
}
|
||||
|
||||
impl HasArg : Eq {
|
||||
pure fn eq(other: &HasArg) -> bool {
|
||||
(self as uint) == ((*other) as uint)
|
||||
}
|
||||
pure fn ne(other: &HasArg) -> bool { !self.eq(other) }
|
||||
}
|
||||
|
||||
impl Opt : Eq {
|
||||
pure fn eq(other: &Opt) -> bool {
|
||||
self.name == (*other).name &&
|
||||
self.hasarg == (*other).hasarg &&
|
||||
self.occur == (*other).occur
|
||||
}
|
||||
pure fn ne(other: &Opt) -> bool { !self.eq(other) }
|
||||
}
|
||||
|
||||
/// Create an option that is required and takes an argument
|
||||
pub fn reqopt(name: &str) -> Opt {
|
||||
return {name: mkname(name), hasarg: Yes, occur: Req};
|
||||
@ -150,8 +166,29 @@ enum Optval { Val(~str), Given, }
|
||||
*/
|
||||
pub type Matches = {opts: ~[Opt], vals: ~[~[Optval]], free: ~[~str]};
|
||||
|
||||
impl Optval : Eq {
|
||||
pure fn eq(other: &Optval) -> bool {
|
||||
match self {
|
||||
Val(ref s) => match *other { Val (ref os) => s == os,
|
||||
Given => false },
|
||||
Given => match *other { Val(_) => false,
|
||||
Given => true }
|
||||
}
|
||||
}
|
||||
pure fn ne(other: &Optval) -> bool { !self.eq(other) }
|
||||
}
|
||||
|
||||
impl Matches : Eq {
|
||||
pure fn eq(other: &Matches) -> bool {
|
||||
self.opts == (*other).opts &&
|
||||
self.vals == (*other).vals &&
|
||||
self.free == (*other).free
|
||||
}
|
||||
pure fn ne(other: &Matches) -> bool { !self.eq(other) }
|
||||
}
|
||||
|
||||
fn is_arg(arg: &str) -> bool {
|
||||
return str::len(arg) > 1u && arg[0] == '-' as u8;
|
||||
return arg.len() > 1u && arg[0] == '-' as u8;
|
||||
}
|
||||
|
||||
fn name_str(nm: &Name) -> ~str {
|
||||
@ -177,6 +214,35 @@ pub enum Fail_ {
|
||||
UnexpectedArgument(~str),
|
||||
}
|
||||
|
||||
impl Fail_ : Eq {
|
||||
// this whole thing should be easy to infer...
|
||||
pure fn eq(other: &Fail_) -> bool {
|
||||
match self {
|
||||
ArgumentMissing(ref s) => {
|
||||
match *other { ArgumentMissing(ref so) => s == so,
|
||||
_ => false }
|
||||
}
|
||||
UnrecognizedOption(ref s) => {
|
||||
match *other { UnrecognizedOption(ref so) => s == so,
|
||||
_ => false }
|
||||
}
|
||||
OptionMissing(ref s) => {
|
||||
match *other { OptionMissing(ref so) => s == so,
|
||||
_ => false }
|
||||
}
|
||||
OptionDuplicated(ref s) => {
|
||||
match *other { OptionDuplicated(ref so) => s == so,
|
||||
_ => false }
|
||||
}
|
||||
UnexpectedArgument(ref s) => {
|
||||
match *other { UnexpectedArgument(ref so) => s == so,
|
||||
_ => false }
|
||||
}
|
||||
}
|
||||
}
|
||||
pure fn ne(other: &Fail_) -> bool { !self.eq(other) }
|
||||
}
|
||||
|
||||
/// Convert a `fail_` enum into an error string
|
||||
pub fn fail_str(f: Fail_) -> ~str {
|
||||
return match f {
|
||||
@ -220,7 +286,7 @@ pub fn getopts(args: &[~str], opts: &[Opt]) -> Result unsafe {
|
||||
let mut i = 0u;
|
||||
while i < l {
|
||||
let cur = args[i];
|
||||
let curlen = str::len(cur);
|
||||
let curlen = cur.len();
|
||||
if !is_arg(cur) {
|
||||
free.push(cur);
|
||||
} else if cur == ~"--" {
|
||||
@ -444,6 +510,194 @@ impl FailType : Eq {
|
||||
pure fn ne(other: &FailType) -> bool { !self.eq(other) }
|
||||
}
|
||||
|
||||
/** A module which provides a way to specify descriptions and
|
||||
* groups of short and long option names, together.
|
||||
*/
|
||||
pub mod groups {
|
||||
|
||||
/** one group of options, e.g., both -h and --help, along with
|
||||
* their shared description and properties
|
||||
*/
|
||||
pub type OptGroup = {
|
||||
short_name: ~str,
|
||||
long_name: ~str,
|
||||
hint: ~str,
|
||||
desc: ~str,
|
||||
hasarg: HasArg,
|
||||
occur: Occur
|
||||
};
|
||||
|
||||
impl OptGroup : Eq {
|
||||
pure fn eq(other: &OptGroup) -> bool {
|
||||
self.short_name == (*other).short_name &&
|
||||
self.long_name == (*other).long_name &&
|
||||
self.hint == (*other).hint &&
|
||||
self.desc == (*other).desc &&
|
||||
self.hasarg == (*other).hasarg &&
|
||||
self.occur == (*other).occur
|
||||
}
|
||||
pure fn ne(other: &OptGroup) -> bool { !self.eq(other) }
|
||||
}
|
||||
|
||||
/// Create a long option that is required and takes an argument
|
||||
pub fn reqopt(short_name: &str, long_name: &str,
|
||||
desc: &str, hint: &str) -> OptGroup {
|
||||
let len = short_name.len();
|
||||
assert len == 1 || len == 0;
|
||||
return {short_name: str::from_slice(short_name),
|
||||
long_name: str::from_slice(long_name),
|
||||
hint: str::from_slice(hint),
|
||||
desc: str::from_slice(desc),
|
||||
hasarg: Yes,
|
||||
occur: Req};
|
||||
}
|
||||
|
||||
/// Create a long option that is optional and takes an argument
|
||||
pub fn optopt(short_name: &str, long_name: &str,
|
||||
desc: &str, hint: &str) -> OptGroup {
|
||||
let len = short_name.len();
|
||||
assert len == 1 || len == 0;
|
||||
return {short_name: str::from_slice(short_name),
|
||||
long_name: str::from_slice(long_name),
|
||||
hint: str::from_slice(hint),
|
||||
desc: str::from_slice(desc),
|
||||
hasarg: Yes,
|
||||
occur: Optional};
|
||||
}
|
||||
|
||||
/// Create a long option that is optional and does not take an argument
|
||||
pub fn optflag(short_name: &str, long_name: &str,
|
||||
desc: &str) -> OptGroup {
|
||||
let len = short_name.len();
|
||||
assert len == 1 || len == 0;
|
||||
return {short_name: str::from_slice(short_name),
|
||||
long_name: str::from_slice(long_name),
|
||||
hint: ~"",
|
||||
desc: str::from_slice(desc),
|
||||
hasarg: No,
|
||||
occur: Optional};
|
||||
}
|
||||
|
||||
/// Create a long option that is optional and takes an optional argument
|
||||
pub fn optflagopt(short_name: &str, long_name: &str,
|
||||
desc: &str, hint: &str) -> OptGroup {
|
||||
let len = short_name.len();
|
||||
assert len == 1 || len == 0;
|
||||
return {short_name: str::from_slice(short_name),
|
||||
long_name: str::from_slice(long_name),
|
||||
hint: str::from_slice(hint),
|
||||
desc: str::from_slice(desc),
|
||||
hasarg: Maybe,
|
||||
occur: Optional};
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a long option that is optional, takes an argument, and may occur
|
||||
* multiple times
|
||||
*/
|
||||
pub fn optmulti(short_name: &str, long_name: &str,
|
||||
desc: &str, hint: &str) -> OptGroup {
|
||||
let len = short_name.len();
|
||||
assert len == 1 || len == 0;
|
||||
return {short_name: str::from_slice(short_name),
|
||||
long_name: str::from_slice(long_name),
|
||||
hint: str::from_slice(hint),
|
||||
desc: str::from_slice(desc),
|
||||
hasarg: Yes,
|
||||
occur: Multi};
|
||||
}
|
||||
|
||||
// translate OptGroup into Opt
|
||||
// (both short and long names correspond to different Opts)
|
||||
pub fn long_to_short(lopt: &OptGroup) -> ~[Opt] {
|
||||
match ((*lopt).short_name.len(),
|
||||
(*lopt).long_name.len()) {
|
||||
|
||||
(0,0) => fail ~"this long-format option was given no name",
|
||||
|
||||
(0,_) => ~[{name: Long(((*lopt).long_name)),
|
||||
hasarg: (*lopt).hasarg,
|
||||
occur: (*lopt).occur}],
|
||||
|
||||
(1,0) => ~[{name: Short(str::char_at((*lopt).short_name, 0)),
|
||||
hasarg: (*lopt).hasarg,
|
||||
occur: (*lopt).occur}],
|
||||
|
||||
(1,_) => ~[{name: Short(str::char_at((*lopt).short_name, 0)),
|
||||
hasarg: (*lopt).hasarg,
|
||||
occur: (*lopt).occur},
|
||||
{name: Long(((*lopt).long_name)),
|
||||
hasarg: (*lopt).hasarg,
|
||||
occur: (*lopt).occur}],
|
||||
|
||||
(_,_) => fail ~"something is wrong with the long-form opt"
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse command line args with the provided long format options
|
||||
*/
|
||||
pub fn getopts(args: &[~str], opts: &[OptGroup]) -> Result {
|
||||
::getopts::getopts(args, vec::flat_map(opts, long_to_short))
|
||||
}
|
||||
|
||||
/**
|
||||
* Derive a usage message from a set of long options
|
||||
*/
|
||||
pub fn usage(brief: &str, opts: &[OptGroup]) -> ~str {
|
||||
|
||||
let desc_sep = ~"\n" + str::repeat(~" ", 24);
|
||||
|
||||
let rows = vec::map(opts, |optref| {
|
||||
let short_name = (*optref).short_name;
|
||||
let long_name = (*optref).long_name;
|
||||
let hint = (*optref).hint;
|
||||
let desc = (*optref).desc;
|
||||
let hasarg = (*optref).hasarg;
|
||||
|
||||
let mut row = str::repeat(~" ", 4);
|
||||
|
||||
// short option
|
||||
row += match short_name.len() {
|
||||
0 => ~"",
|
||||
1 => ~"-" + short_name + " ",
|
||||
_ => fail ~"the short name should only be 1 char long",
|
||||
};
|
||||
|
||||
// long option
|
||||
row += match long_name.len() {
|
||||
0 => ~"",
|
||||
_ => ~"--" + long_name + " ",
|
||||
};
|
||||
|
||||
// arg
|
||||
row += match hasarg {
|
||||
No => ~"",
|
||||
Yes => hint,
|
||||
Maybe => ~"[" + hint + ~"]",
|
||||
};
|
||||
|
||||
// here we just need to indent the start of the description
|
||||
let rowlen = row.len();
|
||||
row += if rowlen < 24 {
|
||||
str::repeat(~" ", 24 - rowlen)
|
||||
} else {
|
||||
desc_sep
|
||||
};
|
||||
|
||||
// wrapped description
|
||||
row += str::connect(str::split_within(desc, 54), desc_sep);
|
||||
|
||||
row
|
||||
});
|
||||
|
||||
return str::from_slice(brief) +
|
||||
~"\n\nOptions:\n" +
|
||||
str::connect(rows, ~"\n") +
|
||||
~"\n\n";
|
||||
}
|
||||
} // end groups module
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
#[legacy_exports];
|
||||
@ -943,6 +1197,158 @@ mod tests {
|
||||
assert opts_present(matches, ~[~"L"]);
|
||||
assert opts_str(matches, ~[~"L"]) == ~"foo";
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_groups_reqopt() {
|
||||
let opt = groups::reqopt(~"b", ~"banana", ~"some bananas", ~"VAL");
|
||||
assert opt == { short_name: ~"b",
|
||||
long_name: ~"banana",
|
||||
hint: ~"VAL",
|
||||
desc: ~"some bananas",
|
||||
hasarg: Yes,
|
||||
occur: Req }
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_groups_optopt() {
|
||||
let opt = groups::optopt(~"a", ~"apple", ~"some apples", ~"VAL");
|
||||
assert opt == { short_name: ~"a",
|
||||
long_name: ~"apple",
|
||||
hint: ~"VAL",
|
||||
desc: ~"some apples",
|
||||
hasarg: Yes,
|
||||
occur: Optional }
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_groups_optflag() {
|
||||
let opt = groups::optflag(~"k", ~"kiwi", ~"some kiwis");
|
||||
assert opt == { short_name: ~"k",
|
||||
long_name: ~"kiwi",
|
||||
hint: ~"",
|
||||
desc: ~"some kiwis",
|
||||
hasarg: No,
|
||||
occur: Optional }
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_groups_optflagopt() {
|
||||
let opt = groups::optflagopt(~"p", ~"pineapple",
|
||||
~"some pineapples", ~"VAL");
|
||||
assert opt == { short_name: ~"p",
|
||||
long_name: ~"pineapple",
|
||||
hint: ~"VAL",
|
||||
desc: ~"some pineapples",
|
||||
hasarg: Maybe,
|
||||
occur: Optional }
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_groups_optmulti() {
|
||||
let opt = groups::optmulti(~"l", ~"lime",
|
||||
~"some limes", ~"VAL");
|
||||
assert opt == { short_name: ~"l",
|
||||
long_name: ~"lime",
|
||||
hint: ~"VAL",
|
||||
desc: ~"some limes",
|
||||
hasarg: Yes,
|
||||
occur: Multi }
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_groups_long_to_short() {
|
||||
let short = ~[reqopt(~"b"), reqopt(~"banana")];
|
||||
let verbose = groups::reqopt(~"b", ~"banana",
|
||||
~"some bananas", ~"VAL");
|
||||
|
||||
assert groups::long_to_short(&verbose) == short;
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_groups_getopts() {
|
||||
let short = ~[
|
||||
reqopt(~"b"), reqopt(~"banana"),
|
||||
optopt(~"a"), optopt(~"apple"),
|
||||
optflag(~"k"), optflagopt(~"kiwi"),
|
||||
optflagopt(~"p"),
|
||||
optmulti(~"l")
|
||||
];
|
||||
|
||||
let verbose = ~[
|
||||
groups::reqopt(~"b", ~"banana", ~"Desc", ~"VAL"),
|
||||
groups::optopt(~"a", ~"apple", ~"Desc", ~"VAL"),
|
||||
groups::optflag(~"k", ~"kiwi", ~"Desc"),
|
||||
groups::optflagopt(~"p", ~"", ~"Desc", ~"VAL"),
|
||||
groups::optmulti(~"l", ~"", ~"Desc", ~"VAL"),
|
||||
];
|
||||
|
||||
let sample_args = ~[~"-k", ~"15", ~"--apple", ~"1", ~"k",
|
||||
~"-p", ~"16", ~"l", ~"35"];
|
||||
|
||||
// NOTE: we should sort before comparing
|
||||
assert getopts(sample_args, short)
|
||||
== groups::getopts(sample_args, verbose);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_groups_usage() {
|
||||
let optgroups = ~[
|
||||
groups::reqopt(~"b", ~"banana", ~"Desc", ~"VAL"),
|
||||
groups::optopt(~"a", ~"012345678901234567890123456789",
|
||||
~"Desc", ~"VAL"),
|
||||
groups::optflag(~"k", ~"kiwi", ~"Desc"),
|
||||
groups::optflagopt(~"p", ~"", ~"Desc", ~"VAL"),
|
||||
groups::optmulti(~"l", ~"", ~"Desc", ~"VAL"),
|
||||
];
|
||||
|
||||
let expected =
|
||||
~"Usage: fruits
|
||||
|
||||
Options:
|
||||
-b --banana VAL Desc
|
||||
-a --012345678901234567890123456789 VAL
|
||||
Desc
|
||||
-k --kiwi Desc
|
||||
-p [VAL] Desc
|
||||
-l VAL Desc
|
||||
|
||||
";
|
||||
|
||||
let generated_usage = groups::usage(~"Usage: fruits", optgroups);
|
||||
|
||||
debug!("expected: <<%s>>", expected);
|
||||
debug!("generated: <<%s>>", generated_usage);
|
||||
assert generated_usage == expected;
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_groups_usage_description_wrapping() {
|
||||
// indentation should be 24 spaces
|
||||
// lines wrap after 78: or rather descriptions wrap after 54
|
||||
|
||||
let optgroups = ~[
|
||||
groups::optflag(~"k", ~"kiwi",
|
||||
~"This is a long description which won't be wrapped..+.."), // 54
|
||||
groups::optflag(~"a", ~"apple",
|
||||
~"This is a long description which _will_ be wrapped..+.."), // 55
|
||||
];
|
||||
|
||||
let expected =
|
||||
~"Usage: fruits
|
||||
|
||||
Options:
|
||||
-k --kiwi This is a long description which won't be wrapped..+..
|
||||
-a --apple This is a long description which _will_ be
|
||||
wrapped..+..
|
||||
|
||||
";
|
||||
|
||||
let usage = groups::usage(~"Usage: fruits", optgroups);
|
||||
|
||||
debug!("expected: <<%s>>", expected);
|
||||
debug!("generated: <<%s>>", usage);
|
||||
assert usage == expected
|
||||
}
|
||||
}
|
||||
|
||||
// Local Variables:
|
||||
|
@ -10,8 +10,10 @@ use util::ppaux;
|
||||
use back::link;
|
||||
use result::{Ok, Err};
|
||||
use std::getopts;
|
||||
use std::getopts::{opt_present};
|
||||
use std::getopts::groups;
|
||||
use std::getopts::groups::{optopt, optmulti, optflag, optflagopt, getopts};
|
||||
use io::WriterUtil;
|
||||
use getopts::{optopt, optmulti, optflag, optflagopt, opt_present};
|
||||
use back::{x86, x86_64};
|
||||
use std::map::HashMap;
|
||||
use lib::llvm::llvm;
|
||||
@ -623,27 +625,69 @@ fn parse_pretty(sess: Session, &&name: ~str) -> pp_mode {
|
||||
}
|
||||
}
|
||||
|
||||
fn opts() -> ~[getopts::Opt] {
|
||||
return ~[optflag(~"h"), optflag(~"help"),
|
||||
optflag(~"v"), optflag(~"version"),
|
||||
optflag(~"emit-llvm"), optflagopt(~"pretty"),
|
||||
optflag(~"ls"), optflag(~"parse-only"), optflag(~"no-trans"),
|
||||
optflag(~"O"), optopt(~"opt-level"), optmulti(~"L"), optflag(~"S"),
|
||||
optopt(~"o"), optopt(~"out-dir"), optflag(~"xg"),
|
||||
optflag(~"c"), optflag(~"g"), optflag(~"save-temps"),
|
||||
optopt(~"sysroot"), optopt(~"target"),
|
||||
optflag(~"jit"),
|
||||
|
||||
optmulti(~"W"), optmulti(~"warn"),
|
||||
optmulti(~"A"), optmulti(~"allow"),
|
||||
optmulti(~"D"), optmulti(~"deny"),
|
||||
optmulti(~"F"), optmulti(~"forbid"),
|
||||
|
||||
optmulti(~"Z"),
|
||||
|
||||
optmulti(~"cfg"), optflag(~"test"),
|
||||
optflag(~"lib"), optflag(~"bin"),
|
||||
optflag(~"static"), optflag(~"gc")];
|
||||
// rustc command line options
|
||||
fn optgroups() -> ~[getopts::groups::OptGroup] {
|
||||
~[
|
||||
optflag(~"", ~"bin", ~"Compile an executable crate (default)"),
|
||||
optflag(~"c", ~"", ~"Compile and assemble, but do not link"),
|
||||
optmulti(~"", ~"cfg", ~"Configure the compilation
|
||||
environment", ~"SPEC"),
|
||||
optflag(~"", ~"emit-llvm",
|
||||
~"Produce an LLVM bitcode file"),
|
||||
optflag(~"g", ~"", ~"Produce debug info (experimental)"),
|
||||
optflag(~"", ~"gc", ~"Garbage collect shared data (experimental)"),
|
||||
optflag(~"h", ~"help",~"Display this message"),
|
||||
optmulti(~"L", ~"", ~"Add a directory to the library search path",
|
||||
~"PATH"),
|
||||
optflag(~"", ~"lib", ~"Compile a library crate"),
|
||||
optflag(~"", ~"ls", ~"List the symbols defined by a library crate"),
|
||||
optflag(~"", ~"jit", ~"Execute using JIT (experimental)"),
|
||||
optflag(~"", ~"no-trans",
|
||||
~"Run all passes except translation; no output"),
|
||||
optflag(~"O", ~"", ~"Equivalent to --opt-level=2"),
|
||||
optopt(~"o", ~"", ~"Write output to <filename>", ~"FILENAME"),
|
||||
optopt(~"", ~"opt-level",
|
||||
~"Optimize with possible levels 0-3", ~"LEVEL"),
|
||||
optopt( ~"", ~"out-dir",
|
||||
~"Write output to compiler-chosen filename
|
||||
in <dir>", ~"DIR"),
|
||||
optflag(~"", ~"parse-only",
|
||||
~"Parse only; do not compile, assemble, or link"),
|
||||
optflagopt(~"", ~"pretty",
|
||||
~"Pretty-print the input instead of compiling;
|
||||
valid types are: normal (un-annotated source),
|
||||
expanded (crates expanded),
|
||||
typed (crates expanded, with type annotations),
|
||||
or identified (fully parenthesized,
|
||||
AST nodes and blocks with IDs)", ~"TYPE"),
|
||||
optflag(~"S", ~"", ~"Compile only; do not assemble or link"),
|
||||
optflag(~"", ~"xg", ~"Extra debugging info (experimental)"),
|
||||
optflag(~"", ~"save-temps",
|
||||
~"Write intermediate files (.bc, .opt.bc, .o)
|
||||
in addition to normal output"),
|
||||
optflag(~"", ~"static",
|
||||
~"Use or produce static libraries or binaries
|
||||
(experimental)"),
|
||||
optopt(~"", ~"sysroot",
|
||||
~"Override the system root", ~"PATH"),
|
||||
optflag(~"", ~"test", ~"Build a test harness"),
|
||||
optopt(~"", ~"target",
|
||||
~"Target triple cpu-manufacturer-kernel[-os]
|
||||
to compile for (see
|
||||
http://sources.redhat.com/autobook/autobook/autobook_17.html
|
||||
for detail)", ~"TRIPLE"),
|
||||
optmulti(~"W", ~"warn",
|
||||
~"Set lint warnings", ~"OPT"),
|
||||
optmulti(~"A", ~"allow",
|
||||
~"Set lint allowed", ~"OPT"),
|
||||
optmulti(~"D", ~"deny",
|
||||
~"Set lint denied", ~"OPT"),
|
||||
optmulti(~"F", ~"forbid",
|
||||
~"Set lint forbidden", ~"OPT"),
|
||||
optmulti(~"Z", ~"", ~"Set internal debugging options", "FLAG"),
|
||||
optflag( ~"v", ~"version",
|
||||
~"Print version info and exit"),
|
||||
]
|
||||
}
|
||||
|
||||
type output_filenames = @{out_filename:Path, obj_filename:Path};
|
||||
@ -741,7 +785,7 @@ mod test {
|
||||
#[test]
|
||||
fn test_switch_implies_cfg_test() {
|
||||
let matches =
|
||||
match getopts::getopts(~[~"--test"], opts()) {
|
||||
match getopts(~[~"--test"], optgroups()) {
|
||||
Ok(m) => m,
|
||||
Err(f) => fail ~"test_switch_implies_cfg_test: " +
|
||||
getopts::fail_str(f)
|
||||
@ -758,7 +802,7 @@ mod test {
|
||||
#[test]
|
||||
fn test_switch_implies_cfg_test_unless_cfg_test() {
|
||||
let matches =
|
||||
match getopts::getopts(~[~"--test", ~"--cfg=test"], opts()) {
|
||||
match getopts(~[~"--test", ~"--cfg=test"], optgroups()) {
|
||||
Ok(m) => m,
|
||||
Err(f) => {
|
||||
fail ~"test_switch_implies_cfg_test_unless_cfg_test: " +
|
||||
|
@ -16,6 +16,7 @@ use io::ReaderUtil;
|
||||
use std::getopts;
|
||||
use std::map::HashMap;
|
||||
use getopts::{opt_present};
|
||||
use getopts::groups;
|
||||
use rustc::driver::driver::*;
|
||||
use syntax::codemap;
|
||||
use syntax::diagnostic;
|
||||
@ -31,46 +32,11 @@ fn version(argv0: &str) {
|
||||
}
|
||||
|
||||
fn usage(argv0: &str) {
|
||||
io::println(fmt!("Usage: %s [options] <input>\n", argv0) +
|
||||
~"
|
||||
Options:
|
||||
|
||||
--bin Compile an executable crate (default)
|
||||
-c Compile and assemble, but do not link
|
||||
--cfg <cfgspec> Configure the compilation environment
|
||||
--emit-llvm Produce an LLVM bitcode file
|
||||
-g Produce debug info (experimental)
|
||||
--gc Garbage collect shared data (experimental/temporary)
|
||||
-h --help Display this message
|
||||
-L <path> Add a directory to the library search path
|
||||
--lib Compile a library crate
|
||||
--ls List the symbols defined by a compiled library crate
|
||||
--jit Execute using JIT (experimental)
|
||||
--no-trans Run all passes except translation; no output
|
||||
-O Equivalent to --opt-level=2
|
||||
-o <filename> Write output to <filename>
|
||||
--opt-level <lvl> Optimize with possible levels 0-3
|
||||
--out-dir <dir> Write output to compiler-chosen filename in <dir>
|
||||
--parse-only Parse only; do not compile, assemble, or link
|
||||
--pretty [type] Pretty-print the input instead of compiling;
|
||||
valid types are: normal (un-annotated source),
|
||||
expanded (crates expanded), typed (crates expanded,
|
||||
with type annotations), or identified (fully
|
||||
parenthesized, AST nodes and blocks with IDs)
|
||||
-S Compile only; do not assemble or link
|
||||
--save-temps Write intermediate files (.bc, .opt.bc, .o)
|
||||
in addition to normal output
|
||||
--static Use or produce static libraries or binaries
|
||||
(experimental)
|
||||
--sysroot <path> Override the system root
|
||||
--test Build a test harness
|
||||
--target <triple> Target cpu-manufacturer-kernel[-os] to compile for
|
||||
(default: host triple)
|
||||
(see http://sources.redhat.com/autobook/autobook/
|
||||
autobook_17.html for detail)
|
||||
let message = fmt!("Usage: %s [OPTIONS] INPUT", argv0);
|
||||
io::println(groups::usage(message, optgroups()) +
|
||||
~"Additional help:
|
||||
-W help Print 'lint' options and default settings
|
||||
-Z help Print internal options for debugging rustc
|
||||
-v --version Print version info and exit
|
||||
");
|
||||
}
|
||||
|
||||
@ -127,7 +93,7 @@ fn run_compiler(args: &~[~str], demitter: diagnostic::emitter) {
|
||||
if args.is_empty() { usage(binary); return; }
|
||||
|
||||
let matches =
|
||||
match getopts::getopts(args, opts()) {
|
||||
match getopts::groups::getopts(args, optgroups()) {
|
||||
Ok(m) => m,
|
||||
Err(f) => {
|
||||
early_error(demitter, getopts::fail_str(f))
|
||||
|
Loading…
Reference in New Issue
Block a user