From 97c2f6b5560f4d8ca91ab72f9e0032b02a948081 Mon Sep 17 00:00:00 2001 From: Jesse Luehrs Date: Sat, 13 Apr 2013 15:06:33 -0500 Subject: split out the terminfo stuff to a pluggable backend --- Makefile | 13 ++- README | 3 + src/info.rs | 249 ---------------------------------------------------- src/info/builtin.rs | 0 src/info/curses.rs | 249 ++++++++++++++++++++++++++++++++++++++++++++++++++++ src/term.rs | 10 ++- 6 files changed, 271 insertions(+), 253 deletions(-) delete mode 100644 src/info.rs create mode 100644 src/info/builtin.rs create mode 100644 src/info/curses.rs diff --git a/Makefile b/Makefile index bf455f4..3d68652 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,14 @@ RUSTC = rustc MAIN_SOURCE = src/term.rs -OTHER_SOURCES = src/hexes.rs src/ios.rs src/info.rs src/util.rs src/trie.rs +OTHER_SOURCES = src/hexes.rs src/ios.rs src/util.rs src/trie.rs +ifdef CURSES +OTHER_SOURCES += src/info/curses.rs +CFG = --cfg curses +else +OTHER_SOURCES += src/info/builtin.rs +CFG = +endif TESTS = bin/termios bin/termios2 bin/termios3 bin/rl bin/password bin/attrs bin/tput all: build tests @@ -9,7 +16,7 @@ all: build tests build: tmp/built check: build - $(RUSTC) -L tmp --test $(MAIN_SOURCE) -o TEST + $(RUSTC) $(CFG) -L tmp --test $(MAIN_SOURCE) -o TEST ./TEST @rm -f TEST @@ -21,7 +28,7 @@ bin/%: test/%.rs tmp/built tmp/built: $(MAIN_SOURCE) $(OTHER_SOURCES) tmp/libtermios_wrapper.a tmp/libio_helper.a @mkdir -p lib - $(RUSTC) --out-dir lib -L tmp $(MAIN_SOURCE) && touch tmp/built + $(RUSTC) $(CFG) --out-dir lib -L tmp $(MAIN_SOURCE) && touch tmp/built clibs: tmp/libtermios_wrapper.a tmp/libio_helper.a diff --git a/README b/README index 98f5a82..aff70d5 100644 --- a/README +++ b/README @@ -1,3 +1,6 @@ This library implements low-level bindings for terminfo and termios, and also provides a more convenient interface (called 'hexes') on top of that. See http://doy.github.com/rust-term/ for documentation. + +If you want to link against the curses terminfo library (instead of the more +limited built-in one), you should set "CURSES=1" in the make invocation. diff --git a/src/info.rs b/src/info.rs deleted file mode 100644 index 72c0f51..0000000 --- a/src/info.rs +++ /dev/null @@ -1,249 +0,0 @@ -use core::libc::{c_char,c_int,c_long}; - -/// The default colors available on a terminal emulator. -#[deriving(Eq)] -pub enum Color { - ColorBlack = 0, - ColorRed, - ColorGreen, - ColorYellow, - ColorBlue, - ColorMagenta, - ColorCyan, - ColorWhite, -} - -/** - * Initialize the terminfo database. - * - * This must be called before any functions from this module are used. The - * current terminal is determined by looking at the `TERM` environment - * variable. - */ -pub fn init () { - unsafe { c::setupterm(ptr::null(), 1, ptr::null()) }; -} - -macro_rules! def_escape( - ($name:ident -> $escape:expr) => ( - pub fn $name () -> ~str { - let attr = $escape; - match escape(attr) { - Some(e) => e, - None => fail!(fmt!("%s is not supported on this terminal", - attr)), - } - } - ); - ($name:ident -> $escape:expr, $ty1:ident) => ( - pub fn $name (p1: $ty1) -> ~str { - let attr = $escape; - match escape1(attr, p1 as int) { - Some(e) => e, - None => fail!(fmt!("%s is not supported on this terminal", - attr)), - } - } - ); - ($name:ident -> $escape:expr, $ty1:ident, $ty2:ident) => ( - pub fn $name (p1: $ty1, p2: $ty2) -> ~str { - let attr = $escape; - match escape2(attr, p1 as int, p2 as int) { - Some(e) => e, - None => fail!(fmt!("%s is not supported on this terminal", - attr)), - } - } - ); -) - -// XXX macros can't take attributes yet (including documentation), so change -// these to /// once that is fixed - -// The terminal escape to clear the screen. -def_escape!(clear_screen -> "clear") -// The terminal escape to set the foreground color to `p1`. -def_escape!(set_a_foreground -> "setaf", Color) -// The terminal escape to set the background color to `p1`. -def_escape!(set_a_background -> "setab", Color) -// The terminal escape to reset the foreground and background colors. -def_escape!(orig_pair -> "op") -// The terminal escape to reset all attributes. -def_escape!(exit_attribute_mode -> "sgr0") -// The terminal escape to move the cursor to the top left of the screen. -def_escape!(cursor_home -> "home") -// The terminal escape to move the cursor to (`p1`, `p2`). -def_escape!(cursor_address -> "cup", uint, uint) -// The terminal escape to enable underline mode. -def_escape!(enter_underline_mode -> "smul") -// The terminal escape to disable underline mode. -def_escape!(exit_underline_mode -> "rmul") -// The terminal escape to enable standout mode. -def_escape!(enter_standout_mode -> "smso") -// The terminal escape to disable standout mode. -def_escape!(exit_standout_mode -> "rmso") -// The terminal escape to enable reverse video mode. -def_escape!(enter_reverse_mode -> "rev") -// The terminal escape to enable bold mode. -def_escape!(enter_bold_mode -> "bold") -// The terminal escape to enable blink mode. -def_escape!(enter_blink_mode -> "blink") -// The terminal escape to make the cursor invisible. -def_escape!(cursor_invisible -> "civis") -// The terminal escape to make the cursor visible. -def_escape!(cursor_normal -> "cnorm") -// The terminal escape to enable the alternate screen. -def_escape!(enter_ca_mode -> "smcup") -// The terminal escape to disable the alternate screen. -def_escape!(exit_ca_mode -> "rmcup") -// The terminal escape to enter keypad mode. -def_escape!(keypad_xmit -> "smkx") -// The terminal escape to leave keypad mode. -def_escape!(keypad_local -> "rmkx") - -// The terminal escape generated by the backspace key. -def_escape!(key_backspace -> "kbs") -// The terminal escape generated by the return key. -def_escape!(carriage_return -> "cr") -// The terminal escape generated by the tab key. -def_escape!(tab -> "ht") -// The terminal escape generated by the up arrow key. -def_escape!(key_up -> "kcuu1") -// The terminal escape generated by the down arrow key. -def_escape!(key_down -> "kcud1") -// The terminal escape generated by the left arrow key. -def_escape!(key_left -> "kcub1") -// The terminal escape generated by the right arrow key. -def_escape!(key_right -> "kcuf1") -// The terminal escape generated by the home key. -def_escape!(key_home -> "khome") -// The terminal escape generated by the end key. -def_escape!(key_end -> "kend") -// The terminal escape generated by the insert key. -def_escape!(key_ic -> "kich1") -// The terminal escape generated by the delete key. -def_escape!(key_dc -> "kdch1") -// The terminal escape generated by the F1 key. -def_escape!(key_f1 -> "kf1") -// The terminal escape generated by the F2 key. -def_escape!(key_f2 -> "kf2") -// The terminal escape generated by the F3 key. -def_escape!(key_f3 -> "kf3") -// The terminal escape generated by the F4 key. -def_escape!(key_f4 -> "kf4") -// The terminal escape generated by the F5 key. -def_escape!(key_f5 -> "kf5") -// The terminal escape generated by the F6 key. -def_escape!(key_f6 -> "kf6") -// The terminal escape generated by the F7 key. -def_escape!(key_f7 -> "kf7") -// The terminal escape generated by the F8 key. -def_escape!(key_f8 -> "kf8") -// The terminal escape generated by the F9 key. -def_escape!(key_f9 -> "kf9") -// The terminal escape generated by the F10 key. -def_escape!(key_f10 -> "kf10") -// The terminal escape generated by the F11 key. -def_escape!(key_f11 -> "kf11") -// The terminal escape generated by the F12 key. -def_escape!(key_f12 -> "kf12") - -/// The terminal escape generated by the F<`n`> key. -pub fn key_f (n: uint) -> ~str { - let attr = fmt!("kf%?", n); - match escape(attr) { - Some(e) => e, - None => fail!(fmt!("%s is not supported on this terminal", attr)), - } -} - -/// The terminal escape corresponding to the `name` terminfo capability. -pub fn escape (name: &str) -> Option<~str> { - do str::as_c_str(name) |c_name| { - unsafe { - let e = tigetstr(c_name); - if e == ptr::null() { - None - } - else { - Some(str::raw::from_c_str(e)) - } - } - } -} - -/** - * The terminal escape corresponding to the `name` terminfo capability. - * - * This capability must take one parameter, which should be passed as `p1`. - */ -pub fn escape1 (name: &str, p1: int) -> Option<~str> { - do str::as_c_str(name) |c_name| { - unsafe { - let e = tigetstr(c_name); - if e == ptr::null() { - None - } - else { - Some(str::raw::from_c_str(tparm1(e, p1))) - } - } - } -} - -/** - * The terminal escape corresponding to the `name` terminfo capability. - * - * This capability must take two parameters, which should be passed as `p1` - * and `p2`. - */ -pub fn escape2 (name: &str, p1: int, p2: int) -> Option<~str> { - do str::as_c_str(name) |c_name| { - unsafe { - let e = tigetstr(c_name); - if e == ptr::null() { - None - } - else { - Some(str::raw::from_c_str(tparm2(e, p1, p2))) - } - } - } -} - -unsafe fn tigetstr (name: *c_char) -> *c_char { - let c_out = c::tigetstr(name); - if c_out as int == -1 { - fail!(fmt!("%s is not a terminal capability", - unsafe { str::raw::from_c_str(name) })); - } - c_out -} - -unsafe fn tparm1 (name: *c_char, p1: int) -> *c_char { - let ret = c::tparm(name, p1 as c_long, 0, 0, 0, 0, 0, 0, 0, 0); - if ret == ptr::null() { - fail!(fmt!("Couldn't assemble parameters with %s %d", - unsafe { str::raw::from_c_str(name) }, p1)); - } - ret -} - -unsafe fn tparm2 (name: *c_char, p1: int, p2: int) -> *c_char { - let ret = c::tparm(name, p1 as c_long, p2 as c_long, 0, 0, 0, 0, 0, 0, 0); - if ret == ptr::null() { - fail!(fmt!("Couldn't assemble parameters with %s %d %d", - unsafe { str::raw::from_c_str(name) }, p1, p2)); - } - ret -} - -#[link_name = "curses"] -extern mod c { - fn setupterm (term: *c_char, fd: c_int, errret: *c_int) -> c_int; - fn tigetstr (s: *c_char) -> *c_char; - fn tparm (s: *c_char, - a1: c_long, a2: c_long, a3: c_long, - a4: c_long, a5: c_long, a6: c_long, - a7: c_long, a8: c_long, a9: c_long) -> *c_char; -} diff --git a/src/info/builtin.rs b/src/info/builtin.rs new file mode 100644 index 0000000..e69de29 diff --git a/src/info/curses.rs b/src/info/curses.rs new file mode 100644 index 0000000..72c0f51 --- /dev/null +++ b/src/info/curses.rs @@ -0,0 +1,249 @@ +use core::libc::{c_char,c_int,c_long}; + +/// The default colors available on a terminal emulator. +#[deriving(Eq)] +pub enum Color { + ColorBlack = 0, + ColorRed, + ColorGreen, + ColorYellow, + ColorBlue, + ColorMagenta, + ColorCyan, + ColorWhite, +} + +/** + * Initialize the terminfo database. + * + * This must be called before any functions from this module are used. The + * current terminal is determined by looking at the `TERM` environment + * variable. + */ +pub fn init () { + unsafe { c::setupterm(ptr::null(), 1, ptr::null()) }; +} + +macro_rules! def_escape( + ($name:ident -> $escape:expr) => ( + pub fn $name () -> ~str { + let attr = $escape; + match escape(attr) { + Some(e) => e, + None => fail!(fmt!("%s is not supported on this terminal", + attr)), + } + } + ); + ($name:ident -> $escape:expr, $ty1:ident) => ( + pub fn $name (p1: $ty1) -> ~str { + let attr = $escape; + match escape1(attr, p1 as int) { + Some(e) => e, + None => fail!(fmt!("%s is not supported on this terminal", + attr)), + } + } + ); + ($name:ident -> $escape:expr, $ty1:ident, $ty2:ident) => ( + pub fn $name (p1: $ty1, p2: $ty2) -> ~str { + let attr = $escape; + match escape2(attr, p1 as int, p2 as int) { + Some(e) => e, + None => fail!(fmt!("%s is not supported on this terminal", + attr)), + } + } + ); +) + +// XXX macros can't take attributes yet (including documentation), so change +// these to /// once that is fixed + +// The terminal escape to clear the screen. +def_escape!(clear_screen -> "clear") +// The terminal escape to set the foreground color to `p1`. +def_escape!(set_a_foreground -> "setaf", Color) +// The terminal escape to set the background color to `p1`. +def_escape!(set_a_background -> "setab", Color) +// The terminal escape to reset the foreground and background colors. +def_escape!(orig_pair -> "op") +// The terminal escape to reset all attributes. +def_escape!(exit_attribute_mode -> "sgr0") +// The terminal escape to move the cursor to the top left of the screen. +def_escape!(cursor_home -> "home") +// The terminal escape to move the cursor to (`p1`, `p2`). +def_escape!(cursor_address -> "cup", uint, uint) +// The terminal escape to enable underline mode. +def_escape!(enter_underline_mode -> "smul") +// The terminal escape to disable underline mode. +def_escape!(exit_underline_mode -> "rmul") +// The terminal escape to enable standout mode. +def_escape!(enter_standout_mode -> "smso") +// The terminal escape to disable standout mode. +def_escape!(exit_standout_mode -> "rmso") +// The terminal escape to enable reverse video mode. +def_escape!(enter_reverse_mode -> "rev") +// The terminal escape to enable bold mode. +def_escape!(enter_bold_mode -> "bold") +// The terminal escape to enable blink mode. +def_escape!(enter_blink_mode -> "blink") +// The terminal escape to make the cursor invisible. +def_escape!(cursor_invisible -> "civis") +// The terminal escape to make the cursor visible. +def_escape!(cursor_normal -> "cnorm") +// The terminal escape to enable the alternate screen. +def_escape!(enter_ca_mode -> "smcup") +// The terminal escape to disable the alternate screen. +def_escape!(exit_ca_mode -> "rmcup") +// The terminal escape to enter keypad mode. +def_escape!(keypad_xmit -> "smkx") +// The terminal escape to leave keypad mode. +def_escape!(keypad_local -> "rmkx") + +// The terminal escape generated by the backspace key. +def_escape!(key_backspace -> "kbs") +// The terminal escape generated by the return key. +def_escape!(carriage_return -> "cr") +// The terminal escape generated by the tab key. +def_escape!(tab -> "ht") +// The terminal escape generated by the up arrow key. +def_escape!(key_up -> "kcuu1") +// The terminal escape generated by the down arrow key. +def_escape!(key_down -> "kcud1") +// The terminal escape generated by the left arrow key. +def_escape!(key_left -> "kcub1") +// The terminal escape generated by the right arrow key. +def_escape!(key_right -> "kcuf1") +// The terminal escape generated by the home key. +def_escape!(key_home -> "khome") +// The terminal escape generated by the end key. +def_escape!(key_end -> "kend") +// The terminal escape generated by the insert key. +def_escape!(key_ic -> "kich1") +// The terminal escape generated by the delete key. +def_escape!(key_dc -> "kdch1") +// The terminal escape generated by the F1 key. +def_escape!(key_f1 -> "kf1") +// The terminal escape generated by the F2 key. +def_escape!(key_f2 -> "kf2") +// The terminal escape generated by the F3 key. +def_escape!(key_f3 -> "kf3") +// The terminal escape generated by the F4 key. +def_escape!(key_f4 -> "kf4") +// The terminal escape generated by the F5 key. +def_escape!(key_f5 -> "kf5") +// The terminal escape generated by the F6 key. +def_escape!(key_f6 -> "kf6") +// The terminal escape generated by the F7 key. +def_escape!(key_f7 -> "kf7") +// The terminal escape generated by the F8 key. +def_escape!(key_f8 -> "kf8") +// The terminal escape generated by the F9 key. +def_escape!(key_f9 -> "kf9") +// The terminal escape generated by the F10 key. +def_escape!(key_f10 -> "kf10") +// The terminal escape generated by the F11 key. +def_escape!(key_f11 -> "kf11") +// The terminal escape generated by the F12 key. +def_escape!(key_f12 -> "kf12") + +/// The terminal escape generated by the F<`n`> key. +pub fn key_f (n: uint) -> ~str { + let attr = fmt!("kf%?", n); + match escape(attr) { + Some(e) => e, + None => fail!(fmt!("%s is not supported on this terminal", attr)), + } +} + +/// The terminal escape corresponding to the `name` terminfo capability. +pub fn escape (name: &str) -> Option<~str> { + do str::as_c_str(name) |c_name| { + unsafe { + let e = tigetstr(c_name); + if e == ptr::null() { + None + } + else { + Some(str::raw::from_c_str(e)) + } + } + } +} + +/** + * The terminal escape corresponding to the `name` terminfo capability. + * + * This capability must take one parameter, which should be passed as `p1`. + */ +pub fn escape1 (name: &str, p1: int) -> Option<~str> { + do str::as_c_str(name) |c_name| { + unsafe { + let e = tigetstr(c_name); + if e == ptr::null() { + None + } + else { + Some(str::raw::from_c_str(tparm1(e, p1))) + } + } + } +} + +/** + * The terminal escape corresponding to the `name` terminfo capability. + * + * This capability must take two parameters, which should be passed as `p1` + * and `p2`. + */ +pub fn escape2 (name: &str, p1: int, p2: int) -> Option<~str> { + do str::as_c_str(name) |c_name| { + unsafe { + let e = tigetstr(c_name); + if e == ptr::null() { + None + } + else { + Some(str::raw::from_c_str(tparm2(e, p1, p2))) + } + } + } +} + +unsafe fn tigetstr (name: *c_char) -> *c_char { + let c_out = c::tigetstr(name); + if c_out as int == -1 { + fail!(fmt!("%s is not a terminal capability", + unsafe { str::raw::from_c_str(name) })); + } + c_out +} + +unsafe fn tparm1 (name: *c_char, p1: int) -> *c_char { + let ret = c::tparm(name, p1 as c_long, 0, 0, 0, 0, 0, 0, 0, 0); + if ret == ptr::null() { + fail!(fmt!("Couldn't assemble parameters with %s %d", + unsafe { str::raw::from_c_str(name) }, p1)); + } + ret +} + +unsafe fn tparm2 (name: *c_char, p1: int, p2: int) -> *c_char { + let ret = c::tparm(name, p1 as c_long, p2 as c_long, 0, 0, 0, 0, 0, 0, 0); + if ret == ptr::null() { + fail!(fmt!("Couldn't assemble parameters with %s %d %d", + unsafe { str::raw::from_c_str(name) }, p1, p2)); + } + ret +} + +#[link_name = "curses"] +extern mod c { + fn setupterm (term: *c_char, fd: c_int, errret: *c_int) -> c_int; + fn tigetstr (s: *c_char) -> *c_char; + fn tparm (s: *c_char, + a1: c_long, a2: c_long, a3: c_long, + a4: c_long, a5: c_long, a6: c_long, + a7: c_long, a8: c_long, a9: c_long) -> *c_char; +} diff --git a/src/term.rs b/src/term.rs index 0daa5ca..3ae11e0 100644 --- a/src/term.rs +++ b/src/term.rs @@ -6,7 +6,15 @@ #[crate_type = "lib"]; pub mod hexes; -pub mod info; pub mod ios; + +#[cfg(curses)] +#[path = "info/curses.rs"] +pub mod info; + +#[cfg(not(curses))] +#[path = "info/builtin.rs"] +pub mod info; + mod trie; mod util; -- cgit v1.2.3-54-g00ecf