Skip to content

Fix getopts parsing of -L/usr/local/lib #2799

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 15 additions & 15 deletions doc/tutorial.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ import uint::range;
import io::println;

fn main() {
// Open a channel for receiving game results
// Open a channel to receive game results
do listen |result_from_game| {

let times = 10;
Expand All @@ -73,24 +73,24 @@ fn main() {
let winner = result_from_game.recv();
println(#fmt("%s wins round #%u", winner, round));
}
}

fn play_game(player1: str, player2: str) -> str {
fn play_game(player1: str, player2: str) -> str {

// Our rock/paper/scissors types
enum gesture {
rock, paper, scissors
}
// Our rock/paper/scissors types
enum gesture {
rock, paper, scissors
}

let rng = seeded_rng(seed());
// A small inline function for picking an RPS gesture
let pick = || [rock, paper, scissors][rng.gen_uint() % 3];
let rng = seeded_rng(seed());
// A small inline function for picking an RPS gesture
let pick = || [rock, paper, scissors][rng.gen_uint() % 3];

// Pick two gestures and decide the result
alt (pick(), pick()) {
(rock, scissors) | (paper, rock) | (scissors, paper) { copy player1 }
(scissors, rock) | (rock, paper) | (paper, scissors) { copy player2 }
_ { "tie" }
}
// Pick two gestures and decide the result
alt (pick(), pick()) {
(rock, scissors) | (paper, rock) | (scissors, paper) { copy player1 }
(scissors, rock) | (rock, paper) | (paper, scissors) { copy player2 }
_ { "tie" }
}
}
}
Expand Down
40 changes: 39 additions & 1 deletion src/libstd/getopts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -220,10 +220,36 @@ fn getopts(args: ~[str], opts: ~[opt]) -> result unsafe {
}
} else {
let mut j = 1u;
let mut last_valid_opt_id = option::none;
names = ~[];
while j < curlen {
let range = str::char_range_at(cur, j);
vec::push(names, short(range.ch));
let opt = short(range.ch);

/* In a series of potential options (eg. -aheJ), if we see
one which takes an argument, we assume all subsequent
characters make up the argument. This allows options
such as -L/usr/local/lib/foo to be interpreted correctly
*/
alt find_opt(opts, opt) {
some(id) {
last_valid_opt_id = option::some(id);
}
none {
let arg_follows = option::is_some(last_valid_opt_id) &&
alt opts[option::get(last_valid_opt_id)].hasarg {
yes | maybe { true }
no { false }
};
if arg_follows && j + 1 < curlen {
i_arg = option::some(str::slice(cur, j, curlen));
break;
} else {
last_valid_opt_id = option::none;
}
}
}
vec::push(names, opt);
j = range.next;
}
}
Expand Down Expand Up @@ -857,6 +883,18 @@ mod tests {
assert opts_str(match, ~["e", "encrypt"]) == "foo";
assert opts_str(match, ~["encrypt", "e"]) == "foo";
}

#[test]
fn test_nospace() {
let args = ~["-Lfoo"];
let opts = ~[optmulti("L")];
let match = alt getopts(args, opts) {
result::ok(m) { m }
result::err(f) { fail; }
};
assert opts_present(match, ~["L"]);
assert opts_str(match, ~["L"]) == "foo";
}
}

// Local Variables:
Expand Down