]> git.lizzy.rs Git - rust.git/commitdiff
extra::term: better error handling and win32 compat
authorCorey Richardson <corey@octayn.net>
Thu, 30 May 2013 23:14:40 +0000 (19:14 -0400)
committerCorey Richardson <corey@octayn.net>
Sat, 1 Jun 2013 00:02:49 +0000 (20:02 -0400)
src/libextra/term.rs
src/libextra/terminfo/parm.rs
src/libextra/terminfo/parser/compiled.rs
src/libextra/terminfo/searcher.rs
src/libextra/terminfo/terminfo.rs
src/librustpkg/util.rs
src/libsyntax/diagnostic.rs

index 691a6b4dc6242cded46512a45f5d1853854c1b5d..26a9e568e6134b0f4407a5c516825b325abe4317 100644 (file)
 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");
@@ -74,19 +82,50 @@ pub fn new(out: @io::Writer) -> Result<Terminal, ~str> {
     }
     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) {
+    }
+}
index c4cc16d058eda1d30755799190e8899d8920dc5c..aee4b44944996bbd9cf20a80977c9cd194a96864 100644 (file)
@@ -27,13 +27,27 @@ enum States {
     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");
 
@@ -68,15 +82,15 @@ pub fn expand(cap: &[u8], params: &mut [Param], sta: &mut [Param], dyn: &mut [Pa
                     '%' => { 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,
@@ -85,52 +99,52 @@ pub fn expand(cap: &[u8], params: &mut [Param], sta: &mut [Param], dyn: &mut [Pa
                     '{' => 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 => {
@@ -145,7 +159,7 @@ pub fn expand(cap: &[u8], params: &mut [Param], sta: &mut [Param], dyn: &mut [Pa
                     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 => {
@@ -156,7 +170,7 @@ pub fn expand(cap: &[u8], params: &mut [Param], sta: &mut [Param], dyn: &mut [Pa
                     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 => {
@@ -174,14 +188,14 @@ pub fn expand(cap: &[u8], params: &mut [Param], sta: &mut [Param], dyn: &mut [Pa
                 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)]
index 2d5979c2634558410a1527f2dcffc6c0ab3fbda6..e63ec1ab5f9911c2ed7be69328febf92d8cff661 100644 (file)
@@ -1,6 +1,4 @@
 /// ncurses-compatible compiled terminfo format parsing (term(5))
-///
-/// does *not* handle obsolete termcap capabilities!
 
 use core::prelude::*;
 
     "OTG3", "OTG1", "OTG4", "OTGR", "OTGL", "OTGU", "OTGD", "OTGH", "OTGV", "OTGC", "meml", "memu",
     "box1"];
 
+/// Parse a compiled terminfo entry, using long capability names if `longnames` is true
 pub fn parse(file: @Reader, longnames: bool) -> Result<~TermInfo, ~str> {
     let bnames, snames, nnames;
 
index f440ce7c9eb437742241989200e1624ca1bd63e0..c2ff8a46ed4530cc1d6521bbf199d1b74dc60b2a 100644 (file)
 /// Does not support hashed database, only filesystem!
 
 use core::prelude::*;
-use core::{os, str, vec};
+use core::{os, str};
 use core::os::getenv;
 use core::io::{file_reader, Reader};
-use path = core::path::PosixPath;
+use path = core::path::Path;
 
 /// Return path to database entry for `term`
 pub fn get_dbpath_for_term(term: &str) -> Option<~path> {
index 1c7f107e4fb6ccf8427f18cd5b6b3a49636ae1e5..141a5b6bf7f9b72b663b00ce6b5ac63c1f3af3fb 100644 (file)
 
 use core::hashmap::HashMap;
 
+/// A parsed terminfo entry.
 pub struct TermInfo {
+    /// Names for the terminal
     names: ~[~str],
+    /// Map of capability name to boolean value
     bools: HashMap<~str, bool>,
+    /// Map of capability name to numeric value
     numbers: HashMap<~str, u16>,
+    /// Map of capability name to raw (unexpanded) string
     strings: HashMap<~str, ~[u8]>
 }
 
index 213ac4f22e26db49f80ece1b1d28df4459c34d37..8071546136f067b3e48f5d9f874aebb1609fc251 100644 (file)
@@ -280,7 +280,7 @@ pub fn need_dir(s: &Path) {
 fn pretty_message<'a>(msg: &'a str, prefix: &'a str, color: u8, out: @io::Writer) {
     let term = term::Terminal::new(out);
     match term {
-        Ok(ref t) if t.color_supported => {
+        Ok(ref t) => {
             t.fg(color);
             out.write_str(prefix);
             t.reset();
index 094082f41e79d44a6b4bb5c252a140104d4aaaf1..fa4a74b895454408841b3e618b7f1bf0b1f86639 100644 (file)
@@ -191,7 +191,7 @@ fn diagnosticcolor(lvl: level) -> u8 {
 }
 
 fn print_diagnostic(topic: &str, lvl: level, msg: &str) {
-    let term = term::Terminal::new(io::stderr());
+    let t = term::Terminal::new(io::stderr());
 
     let stderr = io::stderr();
 
@@ -199,18 +199,18 @@ fn print_diagnostic(topic: &str, lvl: level, msg: &str) {
         stderr.write_str(fmt!("%s ", topic));
     }
 
-    match term {
-        Ok(t) => {
+    match t {
+        Ok(term) => {
             if stderr.get_type() == io::Screen {
-                t.fg(diagnosticcolor(lvl));
+                term.fg(diagnosticcolor(lvl));
                 stderr.write_str(fmt!("%s: ", diagnosticstr(lvl)));
-                t.reset();
+                term.reset();
                 stderr.write_str(fmt!("%s\n", msg));
+            } else {
+                stderr.write_str(fmt!("%s: %s\n", diagnosticstr(lvl), msg));
             }
-        }
-        Err(_) => {
-            stderr.write_str(fmt!("%s: %s\n", diagnosticstr(lvl), msg));
-        }
+        },
+        _ => stderr.write_str(fmt!("%s: %s\n", diagnosticstr(lvl), msg))
     }
 }