forked from cs4414/ps2
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgash.rs
104 lines (86 loc) · 2.68 KB
/
gash.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
//
// gash.rs
//
// Starting code for PS2
// Running on Rust 0.9
//
// University of Virginia - cs4414 Spring 2014
// Weilin Xu, David Evans
// Version 0.4
//
extern mod extra;
use std::{io, run, os};
use std::io::buffered::BufferedReader;
use std::io::stdin;
use extra::getopts;
struct Shell {
cmd_prompt: ~str,
}
impl Shell {
fn new(prompt_str: &str) -> Shell {
Shell {
cmd_prompt: prompt_str.to_owned(),
}
}
fn run(&mut self) {
let mut stdin = BufferedReader::new(stdin());
loop {
print(self.cmd_prompt);
io::stdio::flush();
let line = stdin.read_line().unwrap();
let cmd_line = line.trim().to_owned();
let program = cmd_line.splitn(' ', 1).nth(0).expect("no program");
match program {
"" => { continue; }
"exit" => { return; }
_ => { self.run_cmdline(cmd_line); }
}
}
}
fn run_cmdline(&mut self, cmd_line: &str) {
let mut argv: ~[~str] =
cmd_line.split(' ').filter_map(|x| if x != "" { Some(x.to_owned()) } else { None }).to_owned_vec();
if argv.len() > 0 {
let program: ~str = argv.remove(0);
self.run_cmd(program, argv);
}
}
fn run_cmd(&mut self, program: &str, argv: &[~str]) {
if self.cmd_exists(program) {
run::process_status(program, argv);
} else {
println!("{:s}: command not found", program);
}
}
fn cmd_exists(&mut self, cmd_path: &str) -> bool {
let ret = run::process_output("which", [cmd_path.to_owned()]);
return ret.expect("exit code error.").status.success();
}
}
fn get_cmdline_from_args() -> Option<~str> {
/* Begin processing program arguments and initiate the parameters. */
let args = os::args();
let opts = ~[
getopts::optopt("c")
];
let matches = match getopts::getopts(args.tail(), opts) {
Ok(m) => { m }
Err(f) => { fail!(f.to_err_msg()) }
};
if matches.opt_present("c") {
let cmd_str = match matches.opt_str("c") {
Some(cmd_str) => {cmd_str.to_owned()},
None => {~""}
};
return Some(cmd_str);
} else {
return None;
}
}
fn main() {
let opt_cmd_line = get_cmdline_from_args();
match opt_cmd_line {
Some(cmd_line) => Shell::new("").run_cmdline(cmd_line),
None => Shell::new("gash > ").run()
}
}