forked from rust-lang/rust-by-example
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add chapter on command-line arguments
- Loading branch information
Showing
10 changed files
with
312 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
use std::os; | ||
|
||
fn main() { | ||
let args = os::args(); | ||
// The first argument is the path that was used to call the program. | ||
println!("My path is {}.", args[0]); | ||
// The rest of the arguments are the passed command line parameters. | ||
// Call the program like this: | ||
// $ ./args arg1 arg2 | ||
println!("I got {} arguments: {}.", args.len() - 1, args.tail()); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
extern crate getopts; | ||
|
||
use std::os; | ||
use std::io::{print, println}; | ||
use std::io::stdio; | ||
|
||
static VERSION: &'static str = "1.0.0"; | ||
|
||
fn main() { | ||
let args = os::args(); | ||
let ref program = args[0]; | ||
|
||
// Set possible flags. | ||
// The first argument to `optflag` is the short flag name. | ||
// The second argument is the long flag name. | ||
// The third argument is the help text. | ||
let opts = [ | ||
getopts::optflag("n", "", "do not output the trailing newline"), | ||
getopts::optflag("h", "help", "display this help and exit"), | ||
getopts::optflag("V", "version", | ||
"output version information and exit"), | ||
]; | ||
|
||
let matches = match getopts::getopts(args.tail(), &opts) { | ||
Ok(m) => m, | ||
Err(f) => { | ||
println!("{}", f); | ||
os::set_exit_status(1); | ||
return; | ||
// The exit code is 0 (success) by default. | ||
// Any exit code other than 0 indicates failure. | ||
} | ||
}; | ||
|
||
if matches.opt_present("help") { | ||
//^ We could as well have used the short name: "h" | ||
println!("echo {} - display a line of text", VERSION); | ||
println!(""); | ||
println!("Usage:"); | ||
println!(" {} [SHORT-OPTION]... [STRING]...", program); | ||
println!(" {} LONG-OPTION", program); | ||
println!(""); | ||
println(getopts::usage("Echo the STRING(s) to standard output.", &opts) | ||
.as_slice()); | ||
return; | ||
} | ||
|
||
if matches.opt_present("version") { | ||
println!("echo version: {}", VERSION); | ||
return; | ||
} | ||
|
||
if !matches.free.is_empty() { | ||
//^ `matches.free` contains all the arguments that are not options. | ||
let string = matches.free.connect(" "); | ||
print(string.as_slice()); | ||
} | ||
|
||
if !matches.opt_present("n") { | ||
println!("") | ||
} else { | ||
stdio::flush(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
To build unix-style command line interfaces, you can use the [getopts](http://doc.rust-lang.org/getopts/index.html) crate. | ||
|
||
Here is a simple implementation of the `echo` unix program: | ||
|
||
{echo.play} | ||
|
||
``` | ||
$ ./echo -h | ||
echo 1.0.0 - display a line of text | ||
Usage: | ||
./echo [SHORT-OPTION]... [STRING]... | ||
./echo LONG-OPTION | ||
Echo the STRING(s) to standard output. | ||
Options: | ||
-n do not output the trailing newline | ||
-h --help display this help and exit | ||
-V --version output version information and exit | ||
$ ./echo --version | ||
echo version: 1.0.0 | ||
$ ./echo Hello, World! | ||
Hello, World! | ||
``` | ||
|
||
This is a simplified version of the `echo` implementation by | ||
[uutils](/~https://github.com/uutils/coreutils). | ||
|
||
|
||
It is also possible to use *options* instead of *flags*, such that values can | ||
be passed to the program: | ||
|
||
{testopt.rs} | ||
|
||
Here are some examples how the program behaves given different combinations of | ||
arguments: | ||
|
||
``` | ||
$ ./testopt | ||
a=false, b=false, c="" | ||
$ ./testopt -a -b | ||
a=true, b=true, c="" | ||
$ ./testopt -ab | ||
a=true, b=true, c="" | ||
$ ./testopt -c | ||
Argument to option 'c' missing. | ||
$ ./testopt -c value | ||
a=false, b=false, c="value" | ||
$ ./testopt -c=value | ||
a=false, b=false, c="=value" | ||
$ ./testopt -cvalue | ||
a=false, b=false, c="value" | ||
$ ./testopt arg | ||
a=false, b=false, c="" | ||
free arguments: [arg] | ||
$ ./testopt -a arg | ||
a=true, b=false, c="" | ||
free arguments: [arg] | ||
$ ./testopt -c value arg | ||
a=false, b=false, c="value" | ||
free arguments: [arg] | ||
$ ./testopt -a -- -b | ||
a=true, b=false, c="" | ||
free arguments: [-b] | ||
$ ./testopt -a - | ||
a=true, b=false, c="" | ||
free arguments: [-] | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
#!/bin/sh | ||
# Generate the example output for input.md. | ||
|
||
function run { | ||
echo '$' $1 | ||
$1 | ||
} | ||
|
||
run './testopt' | ||
run './testopt -a -b' | ||
run './testopt -ab' | ||
run './testopt -c' | ||
run './testopt -c value' | ||
run './testopt -c=value' | ||
run './testopt -cvalue' | ||
run './testopt arg' | ||
run './testopt -a arg' | ||
run './testopt -c value arg' | ||
run './testopt -a -- -b' | ||
run './testopt -a -' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
extern crate getopts; | ||
|
||
use std::os; | ||
|
||
fn main() { | ||
let args = os::args(); | ||
let opts = [ | ||
getopts::optflag("a", "long_a", ""), | ||
getopts::optflag("b", "long_b", ""), | ||
getopts::optopt("c", "long_c", "", "VALUE"), | ||
//^ Use `optflagopt` if the argument should be optional. | ||
// Use `reqopt` if the option is required. | ||
// Use `optmulti`, `optflagmulti` if options can occur multiple times. | ||
]; | ||
|
||
let matches = match getopts::getopts(args.tail(), &opts) { | ||
Ok(m) => m, | ||
Err(f) => { | ||
println!("{}", f); | ||
os::set_exit_status(1); | ||
return; | ||
} | ||
}; | ||
let a = if matches.opt_present("a") {true} else {false}; | ||
let b = if matches.opt_present("b") {true} else {false}; | ||
let c = match matches.opt_str("c") { | ||
Some(s) => s, | ||
None => String::from_str(""), | ||
}; | ||
//^ Use `matches.opt_default` if you need a default (`opflagopt`). | ||
// Use `matches.opt_count` if you need to count how many were matched | ||
// (`*multi`). | ||
|
||
println!("a={}, b={}, c=\"{}\"", a, b, c); | ||
if !matches.free.is_empty() { | ||
println!("free arguments: {}", matches.free); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
The command line arguments can be accessed using `std::os::args`, which returns | ||
a [vector](http://static.rust-lang.org/doc/master/std/vec/index.html) of strings: | ||
|
||
{args.play} | ||
|
||
``` | ||
$ ./args 1 2 3 | ||
My path is ./args. | ||
I got 3 arguments: [1, 2, 3]. | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
Matching can be used to parse simple arguments: | ||
|
||
{match_args.play} | ||
|
||
``` | ||
$ ./match_args Rust | ||
This is not the answer. | ||
$ ./match_args 42 | ||
This is the answer! | ||
$ ./match_args do something | ||
error: second argument not an integer | ||
usage: | ||
match_args <string> | ||
Check whether given string is the answer. | ||
match_args {increase|decrease} <integer> | ||
Increase or decrease given integer by one. | ||
$ ./match_args do 42 | ||
error: invalid command | ||
usage: | ||
match_args <string> | ||
Check whether given string is the answer. | ||
match_args {increase|decrease} <integer> | ||
Increase or decrease given integer by one. | ||
$ ./match_args increase 42 | ||
43 | ||
``` | ||
|
||
<!-- TODO link to the getopts example, after moving this out of the staging area --> | ||
For implementing more complicated, unix-like command line interfaces see the `getopts` example. | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
use std::os; | ||
|
||
fn increase(number: int) { | ||
println!("{}", number + 1); | ||
} | ||
|
||
fn decrease(number: int) { | ||
println!("{}", number - 1); | ||
} | ||
|
||
fn help() { | ||
println!("usage: | ||
match_args <string> | ||
Check whether given string is the answer. | ||
match_args {{increase|decrease}} <integer> | ||
Increase or decrease given integer by one."); | ||
} | ||
|
||
fn main() { | ||
let args = os::args(); | ||
|
||
match args.as_slice() { | ||
// no arguments passed | ||
[ref name] => { | ||
println!("My name is '{}'. Try passing some arguments!", name); | ||
}, | ||
// one argument passed | ||
[_, ref string] => { | ||
if string.as_slice() == "42" { | ||
println!("This is the answer!"); | ||
} else { | ||
println!("This is not the answer."); | ||
} | ||
}, | ||
// one command and one argument passed | ||
[_, ref cmd, ref num] => { | ||
// parse the number | ||
let number: int = match from_str(num.as_slice()) { | ||
Some(n) => { | ||
n | ||
}, | ||
None => { | ||
println!("error: second argument not an integer"); | ||
help(); | ||
return; | ||
}, | ||
}; | ||
// parse the command | ||
match cmd.as_slice() { | ||
"increase" => increase(number), | ||
"decrease" => decrease(number), | ||
_ => { | ||
println!("error: invalid command"); | ||
help(); | ||
}, | ||
} | ||
}, | ||
// all the other cases | ||
_ => { | ||
// show a help message | ||
help(); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters