pub static color_bright_cyan: u8 = 14u8;
pub static color_bright_white: u8 = 15u8;
+#[cfg(not(target_os = "win32"))]
pub struct Terminal {
color_supported: bool,
priv out: @io::Writer,
priv ti: ~TermInfo
}
+#[cfg(target_os = "win32")]
+pub struct Terminal {
+ color_supported: bool,
+ priv out: @io::Writer,
+}
+
+#[cfg(not(target_os = "win32"))]
pub impl Terminal {
pub fn new(out: @io::Writer) -> Result<Terminal, ~str> {
let term = os::getenv("TERM");
}
fn fg(&self, color: u8) {
if self.color_supported {
- self.out.write(expand(*self.ti.strings.find_equiv(&("setaf")).unwrap(),
- [Number(color as int)], [], []));
+ let s = expand(*self.ti.strings.find_equiv(&("setaf")).unwrap(),
+ [Number(color as int)], [], []);
+ if s.is_ok() {
+ self.out.write(s.get());
+ } else {
+ warn!(s.get_err());
+ }
}
}
fn bg(&self, color: u8) {
if self.color_supported {
- self.out.write(expand(*self.ti.strings.find_equiv(&("setab")).unwrap(),
- [Number(color as int)], [], []));
+ let s = expand(*self.ti.strings.find_equiv(&("setab")).unwrap(),
+ [Number(color as int)], [], []);
+ if s.is_ok() {
+ self.out.write(s.get());
+ } else {
+ warn!(s.get_err());
+ }
}
}
fn reset(&self) {
if self.color_supported {
- self.out.write(expand(*self.ti.strings.find_equiv(&("op")).unwrap(), [], [], []));
+ let s = expand(*self.ti.strings.find_equiv(&("op")).unwrap(), [], [], []);
+ if s.is_ok() {
+ self.out.write(s.get());
+ } else {
+ warn!(s.get_err());
+ }
}
}
}
+
+#[cfg(target_os = "win32")]
+pub impl Terminal {
+ pub fn new(out: @io::Writer) -> Result<Terminal, ~str> {
+ return Ok(Terminal {out: out, color_supported: false});
+ }
+
+ fn fg(&self, color: u8) {
+ }
+
+ fn bg(&self, color: u8) {
+ }
+
+ fn reset(&self) {
+ }
+}
IfBody
}
+/// Types of parameters a capability can use
pub enum Param {
String(~str),
Char(char),
Number(int)
}
-pub fn expand(cap: &[u8], params: &mut [Param], sta: &mut [Param], dyn: &mut [Param]) -> ~[u8] {
+/**
+ Expand a parameterized capability
+
+ # Arguments
+ * `cap` - string to expand
+ * `params` - vector of params for %p1 etc
+ * `sta` - vector of params corresponding to static variables
+ * `dyn` - vector of params corresponding to stativ variables
+
+ To be compatible with ncurses, `sta` and `dyn` should be the same between calls to `expand` for
+ multiple capabilities for the same terminal.
+ */
+pub fn expand(cap: &[u8], params: &mut [Param], sta: &mut [Param], dyn: &mut [Param])
+ -> Result<~[u8], ~str> {
assert!(cap.len() != 0, "expanding an empty capability makes no sense");
assert!(params.len() <= 9, "only 9 parameters are supported by capability strings");
'%' => { output.push(cap[i]); state = Nothing },
'c' => match stack.pop() {
Char(c) => output.push(c as u8),
- _ => fail!("a non-char was used with %c")
+ _ => return Err(~"a non-char was used with %c")
},
's' => match stack.pop() {
String(s) => output.push_all(s.to_bytes()),
- _ => fail!("a non-str was used with %s")
+ _ => return Err(~"a non-str was used with %s")
},
'd' => match stack.pop() {
Number(x) => output.push_all(x.to_str().to_bytes()),
- _ => fail!("a non-number was used with %d")
+ _ => return Err(~"a non-number was used with %d")
},
'p' => state = PushParam,
'P' => state = SetVar,
'{' => state = IntConstant,
'l' => match stack.pop() {
String(s) => stack.push(Number(s.len() as int)),
- _ => fail!("a non-str was used with %l")
+ _ => return Err(~"a non-str was used with %l")
},
'+' => match (stack.pop(), stack.pop()) {
(Number(x), Number(y)) => stack.push(Number(x + y)),
- (_, _) => fail!("non-numbers on stack with +")
+ (_, _) => return Err(~"non-numbers on stack with +")
},
'-' => match (stack.pop(), stack.pop()) {
(Number(x), Number(y)) => stack.push(Number(x - y)),
- (_, _) => fail!("non-numbers on stack with -")
+ (_, _) => return Err(~"non-numbers on stack with -")
},
'*' => match (stack.pop(), stack.pop()) {
(Number(x), Number(y)) => stack.push(Number(x * y)),
- (_, _) => fail!("non-numbers on stack with *")
+ (_, _) => return Err(~"non-numbers on stack with *")
},
'/' => match (stack.pop(), stack.pop()) {
(Number(x), Number(y)) => stack.push(Number(x / y)),
- (_, _) => fail!("non-numbers on stack with /")
+ (_, _) => return Err(~"non-numbers on stack with /")
},
'm' => match (stack.pop(), stack.pop()) {
(Number(x), Number(y)) => stack.push(Number(x % y)),
- (_, _) => fail!("non-numbers on stack with %")
+ (_, _) => return Err(~"non-numbers on stack with %")
},
'&' => match (stack.pop(), stack.pop()) {
(Number(x), Number(y)) => stack.push(Number(x & y)),
- (_, _) => fail!("non-numbers on stack with &")
+ (_, _) => return Err(~"non-numbers on stack with &")
},
'|' => match (stack.pop(), stack.pop()) {
(Number(x), Number(y)) => stack.push(Number(x | y)),
- (_, _) => fail!("non-numbers on stack with |")
+ (_, _) => return Err(~"non-numbers on stack with |")
},
- 'A' => fail!("logical operations unimplemented"),
- 'O' => fail!("logical operations unimplemented"),
- '!' => fail!("logical operations unimplemented"),
+ 'A' => return Err(~"logical operations unimplemented"),
+ 'O' => return Err(~"logical operations unimplemented"),
+ '!' => return Err(~"logical operations unimplemented"),
'~' => match stack.pop() {
Number(x) => stack.push(Number(!x)),
- _ => fail!("non-number on stack with %~")
+ _ => return Err(~"non-number on stack with %~")
},
'i' => match (copy params[0], copy params[1]) {
(Number(x), Number(y)) => {
params[0] = Number(x + 1);
params[1] = Number(y + 1);
},
- (_, _) => fail!("first two params not numbers with %i")
+ (_, _) => return Err(~"first two params not numbers with %i")
},
- '?' => state = fail!("if expressions unimplemented"),
- _ => fail!("unrecognized format option %c", cur)
+ '?' => state = return Err(fmt!("if expressions unimplemented (%?)", cap)),
+ _ => return Err(fmt!("unrecognized format option %c", cur))
}
},
PushParam => {
let idx = (cur as u8) - ('a' as u8);
dyn[idx] = stack.pop();
} else {
- fail!("bad variable name in %P");
+ return Err(~"bad variable name in %P");
}
},
GetVar => {
let idx = (cur as u8) - ('a' as u8);
stack.push(copy dyn[idx]);
} else {
- fail!("bad variable name in %g");
+ return Err(~"bad variable name in %g");
}
},
CharConstant => {
intstate.push(cur as u8);
old_state = Nothing;
}
- _ => fail!("unimplemented state")
+ _ => return Err(~"unimplemented state")
}
if state == old_state {
state = Nothing;
}
i += 1;
}
- output
+ Ok(output)
}
#[cfg(test)]