Skip to content

Commit 6c997b7

Browse files
committed
extra::term: better error handling and win32 shim
1 parent ca570f6 commit 6c997b7

File tree

7 files changed

+98
-41
lines changed

7 files changed

+98
-41
lines changed

src/libextra/term.rs

Lines changed: 44 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -43,12 +43,20 @@ pub static color_bright_magenta: u8 = 13u8;
4343
pub static color_bright_cyan: u8 = 14u8;
4444
pub static color_bright_white: u8 = 15u8;
4545

46+
#[cfg(not(target_os = "win32"))]
4647
pub struct Terminal {
4748
color_supported: bool,
4849
priv out: @io::Writer,
4950
priv ti: ~TermInfo
5051
}
5152

53+
#[cfg(target_os = "win32")]
54+
pub struct Terminal {
55+
color_supported: bool,
56+
priv out: @io::Writer,
57+
}
58+
59+
#[cfg(not(target_os = "win32"))]
5260
pub impl Terminal {
5361
pub fn new(out: @io::Writer) -> Result<Terminal, ~str> {
5462
let term = os::getenv("TERM");
@@ -74,19 +82,50 @@ pub impl Terminal {
7482
}
7583
fn fg(&self, color: u8) {
7684
if self.color_supported {
77-
self.out.write(expand(*self.ti.strings.find_equiv(&("setaf")).unwrap(),
78-
[Number(color as int)], [], []));
85+
let s = expand(*self.ti.strings.find_equiv(&("setaf")).unwrap(),
86+
[Number(color as int)], [], []);
87+
if s.is_ok() {
88+
self.out.write(s.get());
89+
} else {
90+
warn!(s.get_err());
91+
}
7992
}
8093
}
8194
fn bg(&self, color: u8) {
8295
if self.color_supported {
83-
self.out.write(expand(*self.ti.strings.find_equiv(&("setab")).unwrap(),
84-
[Number(color as int)], [], []));
96+
let s = expand(*self.ti.strings.find_equiv(&("setab")).unwrap(),
97+
[Number(color as int)], [], []);
98+
if s.is_ok() {
99+
self.out.write(s.get());
100+
} else {
101+
warn!(s.get_err());
102+
}
85103
}
86104
}
87105
fn reset(&self) {
88106
if self.color_supported {
89-
self.out.write(expand(*self.ti.strings.find_equiv(&("op")).unwrap(), [], [], []));
107+
let s = expand(*self.ti.strings.find_equiv(&("op")).unwrap(), [], [], []);
108+
if s.is_ok() {
109+
self.out.write(s.get());
110+
} else {
111+
warn!(s.get_err());
112+
}
90113
}
91114
}
92115
}
116+
117+
#[cfg(target_os = "win32")]
118+
pub impl Terminal {
119+
pub fn new(out: @io::Writer) -> Result<Terminal, ~str> {
120+
return Ok(Terminal {out: out, color_supported: cs});
121+
}
122+
123+
fn fg(&self, color: u8) {
124+
}
125+
126+
fn bg(&self, color: u8) {
127+
}
128+
129+
fn reset(&self) {
130+
}
131+
}

src/libextra/terminfo/parm.rs

Lines changed: 37 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,27 @@ enum States {
2727
IfBody
2828
}
2929

30+
/// Types of parameters a capability can use
3031
pub enum Param {
3132
String(~str),
3233
Char(char),
3334
Number(int)
3435
}
3536

36-
pub fn expand(cap: &[u8], params: &mut [Param], sta: &mut [Param], dyn: &mut [Param]) -> ~[u8] {
37+
/**
38+
Expand a parameterized capability
39+
40+
# Arguments
41+
* `cap` - string to expand
42+
* `params` - vector of params for %p1 etc
43+
* `sta` - vector of params corresponding to static variables
44+
* `dyn` - vector of params corresponding to stativ variables
45+
46+
To be compatible with ncurses, `sta` and `dyn` should be the same between calls to `expand` for
47+
multiple capabilities for the same terminal.
48+
*/
49+
pub fn expand(cap: &[u8], params: &mut [Param], sta: &mut [Param], dyn: &mut [Param])
50+
-> Result<~[u8], ~str> {
3751
assert!(cap.len() != 0, "expanding an empty capability makes no sense");
3852
assert!(params.len() <= 9, "only 9 parameters are supported by capability strings");
3953

@@ -68,15 +82,15 @@ pub fn expand(cap: &[u8], params: &mut [Param], sta: &mut [Param], dyn: &mut [Pa
6882
'%' => { output.push(cap[i]); state = Nothing },
6983
'c' => match stack.pop() {
7084
Char(c) => output.push(c as u8),
71-
_ => fail!("a non-char was used with %c")
85+
_ => return Err(~"a non-char was used with %c")
7286
},
7387
's' => match stack.pop() {
7488
String(s) => output.push_all(s.to_bytes()),
75-
_ => fail!("a non-str was used with %s")
89+
_ => return Err(~"a non-str was used with %s")
7690
},
7791
'd' => match stack.pop() {
7892
Number(x) => output.push_all(x.to_str().to_bytes()),
79-
_ => fail!("a non-number was used with %d")
93+
_ => return Err(~"a non-number was used with %d")
8094
},
8195
'p' => state = PushParam,
8296
'P' => state = SetVar,
@@ -85,52 +99,52 @@ pub fn expand(cap: &[u8], params: &mut [Param], sta: &mut [Param], dyn: &mut [Pa
8599
'{' => state = IntConstant,
86100
'l' => match stack.pop() {
87101
String(s) => stack.push(Number(s.len() as int)),
88-
_ => fail!("a non-str was used with %l")
102+
_ => return Err(~"a non-str was used with %l")
89103
},
90104
'+' => match (stack.pop(), stack.pop()) {
91105
(Number(x), Number(y)) => stack.push(Number(x + y)),
92-
(_, _) => fail!("non-numbers on stack with +")
106+
(_, _) => return Err(~"non-numbers on stack with +")
93107
},
94108
'-' => match (stack.pop(), stack.pop()) {
95109
(Number(x), Number(y)) => stack.push(Number(x - y)),
96-
(_, _) => fail!("non-numbers on stack with -")
110+
(_, _) => return Err(~"non-numbers on stack with -")
97111
},
98112
'*' => match (stack.pop(), stack.pop()) {
99113
(Number(x), Number(y)) => stack.push(Number(x * y)),
100-
(_, _) => fail!("non-numbers on stack with *")
114+
(_, _) => return Err(~"non-numbers on stack with *")
101115
},
102116
'/' => match (stack.pop(), stack.pop()) {
103117
(Number(x), Number(y)) => stack.push(Number(x / y)),
104-
(_, _) => fail!("non-numbers on stack with /")
118+
(_, _) => return Err(~"non-numbers on stack with /")
105119
},
106120
'm' => match (stack.pop(), stack.pop()) {
107121
(Number(x), Number(y)) => stack.push(Number(x % y)),
108-
(_, _) => fail!("non-numbers on stack with %")
122+
(_, _) => return Err(~"non-numbers on stack with %")
109123
},
110124
'&' => match (stack.pop(), stack.pop()) {
111125
(Number(x), Number(y)) => stack.push(Number(x & y)),
112-
(_, _) => fail!("non-numbers on stack with &")
126+
(_, _) => return Err(~"non-numbers on stack with &")
113127
},
114128
'|' => match (stack.pop(), stack.pop()) {
115129
(Number(x), Number(y)) => stack.push(Number(x | y)),
116-
(_, _) => fail!("non-numbers on stack with |")
130+
(_, _) => return Err(~"non-numbers on stack with |")
117131
},
118-
'A' => fail!("logical operations unimplemented"),
119-
'O' => fail!("logical operations unimplemented"),
120-
'!' => fail!("logical operations unimplemented"),
132+
'A' => return Err(~"logical operations unimplemented"),
133+
'O' => return Err(~"logical operations unimplemented"),
134+
'!' => return Err(~"logical operations unimplemented"),
121135
'~' => match stack.pop() {
122136
Number(x) => stack.push(Number(!x)),
123-
_ => fail!("non-number on stack with %~")
137+
_ => return Err(~"non-number on stack with %~")
124138
},
125139
'i' => match (copy params[0], copy params[1]) {
126140
(Number(x), Number(y)) => {
127141
params[0] = Number(x + 1);
128142
params[1] = Number(y + 1);
129143
},
130-
(_, _) => fail!("first two params not numbers with %i")
144+
(_, _) => return Err(~"first two params not numbers with %i")
131145
},
132-
'?' => state = fail!("if expressions unimplemented"),
133-
_ => fail!("unrecognized format option %c", cur)
146+
'?' => state = return Err(fmt!("if expressions unimplemented (%?)", cap)),
147+
_ => return Err(fmt!("unrecognized format option %c", cur))
134148
}
135149
},
136150
PushParam => {
@@ -145,7 +159,7 @@ pub fn expand(cap: &[u8], params: &mut [Param], sta: &mut [Param], dyn: &mut [Pa
145159
let idx = (cur as u8) - ('a' as u8);
146160
dyn[idx] = stack.pop();
147161
} else {
148-
fail!("bad variable name in %P");
162+
return Err(~"bad variable name in %P");
149163
}
150164
},
151165
GetVar => {
@@ -156,7 +170,7 @@ pub fn expand(cap: &[u8], params: &mut [Param], sta: &mut [Param], dyn: &mut [Pa
156170
let idx = (cur as u8) - ('a' as u8);
157171
stack.push(copy dyn[idx]);
158172
} else {
159-
fail!("bad variable name in %g");
173+
return Err(~"bad variable name in %g");
160174
}
161175
},
162176
CharConstant => {
@@ -174,14 +188,14 @@ pub fn expand(cap: &[u8], params: &mut [Param], sta: &mut [Param], dyn: &mut [Pa
174188
intstate.push(cur as u8);
175189
old_state = Nothing;
176190
}
177-
_ => fail!("unimplemented state")
191+
_ => return Err(~"unimplemented state")
178192
}
179193
if state == old_state {
180194
state = Nothing;
181195
}
182196
i += 1;
183197
}
184-
output
198+
Ok(output)
185199
}
186200

187201
#[cfg(test)]

src/libextra/terminfo/parser/compiled.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
11
/// ncurses-compatible compiled terminfo format parsing (term(5))
2-
///
3-
/// does *not* handle obsolete termcap capabilities!
42
53
use core::prelude::*;
64

@@ -150,6 +148,7 @@ pub static stringnames: &'static[&'static str] = &'static[ "cbt", "_", "cr", "cs
150148
"OTG3", "OTG1", "OTG4", "OTGR", "OTGL", "OTGU", "OTGD", "OTGH", "OTGV", "OTGC", "meml", "memu",
151149
"box1"];
152150

151+
/// Parse a compiled terminfo entry, using long capability names if `longnames` is true
153152
pub fn parse(file: @Reader, longnames: bool) -> Result<~TermInfo, ~str> {
154153
let bnames, snames, nnames;
155154

src/libextra/terminfo/searcher.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
/// Does not support hashed database, only filesystem!
1313
1414
use core::prelude::*;
15-
use core::{os, str, vec};
15+
use core::{os, str};
1616
use core::os::getenv;
1717
use core::io::{file_reader, Reader};
1818
use path = core::path::PosixPath;

src/libextra/terminfo/terminfo.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,15 @@
1010

1111
use core::hashmap::HashMap;
1212

13+
/// A parsed terminfo entry.
1314
pub struct TermInfo {
15+
/// Names for the terminal
1416
names: ~[~str],
17+
/// Map of capability name to boolean value
1518
bools: HashMap<~str, bool>,
19+
/// Map of capability name to numeric value
1620
numbers: HashMap<~str, u16>,
21+
/// Map of capability name to raw (unexpanded) string
1722
strings: HashMap<~str, ~[u8]>
1823
}
1924

src/librustpkg/util.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -280,7 +280,7 @@ pub fn need_dir(s: &Path) {
280280
fn pretty_message<'a>(msg: &'a str, prefix: &'a str, color: u8, out: @io::Writer) {
281281
let term = term::Terminal::new(out);
282282
match term {
283-
Ok(ref t) if t.color_supported => {
283+
Ok(ref t) => {
284284
t.fg(color);
285285
out.write_str(prefix);
286286
t.reset();

src/libsyntax/diagnostic.rs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -191,26 +191,26 @@ fn diagnosticcolor(lvl: level) -> u8 {
191191
}
192192

193193
fn print_diagnostic(topic: &str, lvl: level, msg: &str) {
194-
let term = term::Terminal::new(io::stderr());
194+
let t = term::Terminal::new(io::stderr());
195195

196196
let stderr = io::stderr();
197197

198198
if !topic.is_empty() {
199199
stderr.write_str(fmt!("%s ", topic));
200200
}
201201

202-
match term {
203-
Ok(t) => {
202+
match t {
203+
Ok(term) => {
204204
if stderr.get_type() == io::Screen {
205-
t.fg(diagnosticcolor(lvl));
205+
term.fg(diagnosticcolor(lvl));
206206
stderr.write_str(fmt!("%s: ", diagnosticstr(lvl)));
207-
t.reset();
207+
term.reset();
208208
stderr.write_str(fmt!("%s\n", msg));
209+
} else {
210+
stderr.write_str(fmt!("%s: %s\n", diagnosticstr(lvl), msg));
209211
}
210-
}
211-
Err(_) => {
212-
stderr.write_str(fmt!("%s: %s\n", diagnosticstr(lvl), msg));
213-
}
212+
},
213+
_ => stderr.write_str(fmt!("%s: %s\n", diagnosticstr(lvl), msg))
214214
}
215215
}
216216

0 commit comments

Comments
 (0)