mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-22 06:44:35 +00:00
Auto merge of #87247 - crlf0710:merge-libterm-into-libtest, r=nagisa
Merge libterm into libtest I think it's quite clear at this point that rust won't stablize the current libterm APIs to the outside world. And its only user is libtest. The compiler doesn't use this api at all. So I'm merging the crate into libtest as a module. This also allows me to remove 15% of the libterm code, since these APIs are dead-code now.
This commit is contained in:
commit
39d8d3ab6a
@ -5095,14 +5095,6 @@ dependencies = [
|
||||
"serde_json",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "term"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"core",
|
||||
"std",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "term"
|
||||
version = "0.6.1"
|
||||
@ -5155,7 +5147,6 @@ dependencies = [
|
||||
"panic_unwind",
|
||||
"proc_macro",
|
||||
"std",
|
||||
"term 0.0.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1,9 +0,0 @@
|
||||
[package]
|
||||
authors = ["The Rust Project Developers"]
|
||||
name = "term"
|
||||
version = "0.0.0"
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
core = { path = "../core" }
|
||||
std = { path = "../std" }
|
@ -1,194 +0,0 @@
|
||||
//! Terminal formatting library.
|
||||
//!
|
||||
//! This crate provides the `Terminal` trait, which abstracts over an [ANSI
|
||||
//! Terminal][ansi] to provide color printing, among other things. There are two
|
||||
//! implementations, the `TerminfoTerminal`, which uses control characters from
|
||||
//! a [terminfo][ti] database, and `WinConsole`, which uses the [Win32 Console
|
||||
//! API][win].
|
||||
//!
|
||||
//! # Examples
|
||||
//!
|
||||
//! ```no_run
|
||||
//! # #![feature(rustc_private)]
|
||||
//! extern crate term;
|
||||
//! use std::io::prelude::*;
|
||||
//!
|
||||
//! fn main() {
|
||||
//! let mut t = term::stdout().unwrap();
|
||||
//!
|
||||
//! t.fg(term::color::GREEN).unwrap();
|
||||
//! write!(t, "hello, ").unwrap();
|
||||
//!
|
||||
//! t.fg(term::color::RED).unwrap();
|
||||
//! writeln!(t, "world!").unwrap();
|
||||
//!
|
||||
//! assert!(t.reset().unwrap());
|
||||
//! }
|
||||
//! ```
|
||||
//!
|
||||
//! [ansi]: https://en.wikipedia.org/wiki/ANSI_escape_code
|
||||
//! [win]: https://docs.microsoft.com/en-us/windows/console/character-mode-applications
|
||||
//! [ti]: https://en.wikipedia.org/wiki/Terminfo
|
||||
|
||||
#![doc(html_playground_url = "https://play.rust-lang.org/", test(attr(deny(warnings))))]
|
||||
#![deny(missing_docs)]
|
||||
#![cfg_attr(windows, feature(libc))]
|
||||
|
||||
use std::io::prelude::*;
|
||||
use std::io::{self, Stderr, Stdout};
|
||||
|
||||
pub use terminfo::TerminfoTerminal;
|
||||
#[cfg(windows)]
|
||||
pub use win::WinConsole;
|
||||
|
||||
pub mod terminfo;
|
||||
|
||||
#[cfg(windows)]
|
||||
mod win;
|
||||
|
||||
/// Alias for stdout terminals.
|
||||
pub type StdoutTerminal = dyn Terminal<Output = Stdout> + Send;
|
||||
/// Alias for stderr terminals.
|
||||
pub type StderrTerminal = dyn Terminal<Output = Stderr> + Send;
|
||||
|
||||
#[cfg(not(windows))]
|
||||
/// Returns a Terminal wrapping stdout, or None if a terminal couldn't be
|
||||
/// opened.
|
||||
pub fn stdout() -> Option<Box<StdoutTerminal>> {
|
||||
TerminfoTerminal::new(io::stdout()).map(|t| Box::new(t) as Box<StdoutTerminal>)
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
/// Returns a Terminal wrapping stdout, or None if a terminal couldn't be
|
||||
/// opened.
|
||||
pub fn stdout() -> Option<Box<StdoutTerminal>> {
|
||||
TerminfoTerminal::new(io::stdout())
|
||||
.map(|t| Box::new(t) as Box<StdoutTerminal>)
|
||||
.or_else(|| WinConsole::new(io::stdout()).ok().map(|t| Box::new(t) as Box<StdoutTerminal>))
|
||||
}
|
||||
|
||||
#[cfg(not(windows))]
|
||||
/// Returns a Terminal wrapping stderr, or None if a terminal couldn't be
|
||||
/// opened.
|
||||
pub fn stderr() -> Option<Box<StderrTerminal>> {
|
||||
TerminfoTerminal::new(io::stderr()).map(|t| Box::new(t) as Box<StderrTerminal>)
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
/// Returns a Terminal wrapping stderr, or None if a terminal couldn't be
|
||||
/// opened.
|
||||
pub fn stderr() -> Option<Box<StderrTerminal>> {
|
||||
TerminfoTerminal::new(io::stderr())
|
||||
.map(|t| Box::new(t) as Box<StderrTerminal>)
|
||||
.or_else(|| WinConsole::new(io::stderr()).ok().map(|t| Box::new(t) as Box<StderrTerminal>))
|
||||
}
|
||||
|
||||
/// Terminal color definitions
|
||||
#[allow(missing_docs)]
|
||||
pub mod color {
|
||||
/// Number for a terminal color
|
||||
pub type Color = u32;
|
||||
|
||||
pub const BLACK: Color = 0;
|
||||
pub const RED: Color = 1;
|
||||
pub const GREEN: Color = 2;
|
||||
pub const YELLOW: Color = 3;
|
||||
pub const BLUE: Color = 4;
|
||||
pub const MAGENTA: Color = 5;
|
||||
pub const CYAN: Color = 6;
|
||||
pub const WHITE: Color = 7;
|
||||
|
||||
pub const BRIGHT_BLACK: Color = 8;
|
||||
pub const BRIGHT_RED: Color = 9;
|
||||
pub const BRIGHT_GREEN: Color = 10;
|
||||
pub const BRIGHT_YELLOW: Color = 11;
|
||||
pub const BRIGHT_BLUE: Color = 12;
|
||||
pub const BRIGHT_MAGENTA: Color = 13;
|
||||
pub const BRIGHT_CYAN: Color = 14;
|
||||
pub const BRIGHT_WHITE: Color = 15;
|
||||
}
|
||||
|
||||
/// Terminal attributes for use with term.attr().
|
||||
///
|
||||
/// Most attributes can only be turned on and must be turned off with term.reset().
|
||||
/// The ones that can be turned off explicitly take a boolean value.
|
||||
/// Color is also represented as an attribute for convenience.
|
||||
#[derive(Debug, PartialEq, Eq, Copy, Clone)]
|
||||
pub enum Attr {
|
||||
/// Bold (or possibly bright) mode
|
||||
Bold,
|
||||
/// Dim mode, also called faint or half-bright. Often not supported
|
||||
Dim,
|
||||
/// Italics mode. Often not supported
|
||||
Italic(bool),
|
||||
/// Underline mode
|
||||
Underline(bool),
|
||||
/// Blink mode
|
||||
Blink,
|
||||
/// Standout mode. Often implemented as Reverse, sometimes coupled with Bold
|
||||
Standout(bool),
|
||||
/// Reverse mode, inverts the foreground and background colors
|
||||
Reverse,
|
||||
/// Secure mode, also called invis mode. Hides the printed text
|
||||
Secure,
|
||||
/// Convenience attribute to set the foreground color
|
||||
ForegroundColor(color::Color),
|
||||
/// Convenience attribute to set the background color
|
||||
BackgroundColor(color::Color),
|
||||
}
|
||||
|
||||
/// A terminal with similar capabilities to an ANSI Terminal
|
||||
/// (foreground/background colors etc).
|
||||
pub trait Terminal: Write {
|
||||
/// The terminal's output writer type.
|
||||
type Output: Write;
|
||||
|
||||
/// Sets the foreground color to the given color.
|
||||
///
|
||||
/// If the color is a bright color, but the terminal only supports 8 colors,
|
||||
/// the corresponding normal color will be used instead.
|
||||
///
|
||||
/// Returns `Ok(true)` if the color was set, `Ok(false)` otherwise, and `Err(e)`
|
||||
/// if there was an I/O error.
|
||||
fn fg(&mut self, color: color::Color) -> io::Result<bool>;
|
||||
|
||||
/// Sets the background color to the given color.
|
||||
///
|
||||
/// If the color is a bright color, but the terminal only supports 8 colors,
|
||||
/// the corresponding normal color will be used instead.
|
||||
///
|
||||
/// Returns `Ok(true)` if the color was set, `Ok(false)` otherwise, and `Err(e)`
|
||||
/// if there was an I/O error.
|
||||
fn bg(&mut self, color: color::Color) -> io::Result<bool>;
|
||||
|
||||
/// Sets the given terminal attribute, if supported. Returns `Ok(true)`
|
||||
/// if the attribute was supported, `Ok(false)` otherwise, and `Err(e)` if
|
||||
/// there was an I/O error.
|
||||
fn attr(&mut self, attr: Attr) -> io::Result<bool>;
|
||||
|
||||
/// Returns `true` if the given terminal attribute is supported.
|
||||
fn supports_attr(&self, attr: Attr) -> bool;
|
||||
|
||||
/// Resets all terminal attributes and colors to their defaults.
|
||||
///
|
||||
/// Returns `Ok(true)` if the terminal was reset, `Ok(false)` otherwise, and `Err(e)` if there
|
||||
/// was an I/O error.
|
||||
///
|
||||
/// *Note: This does not flush.*
|
||||
///
|
||||
/// That means the reset command may get buffered so, if you aren't planning on doing anything
|
||||
/// else that might flush stdout's buffer (e.g., writing a line of text), you should flush after
|
||||
/// calling reset.
|
||||
fn reset(&mut self) -> io::Result<bool>;
|
||||
|
||||
/// Gets an immutable reference to the stream inside
|
||||
fn get_ref(&self) -> &Self::Output;
|
||||
|
||||
/// Gets a mutable reference to the stream inside
|
||||
fn get_mut(&mut self) -> &mut Self::Output;
|
||||
|
||||
/// Returns the contained stream, destroying the `Terminal`
|
||||
fn into_inner(self) -> Self::Output
|
||||
where
|
||||
Self: Sized;
|
||||
}
|
@ -10,7 +10,6 @@ crate-type = ["dylib", "rlib"]
|
||||
[dependencies]
|
||||
cfg-if = { version = "0.1.8", features = ['rustc-dep-of-std'] }
|
||||
getopts = { version = "0.2.21", features = ['rustc-dep-of-std'] }
|
||||
term = { path = "../term" }
|
||||
std = { path = "../std" }
|
||||
core = { path = "../core" }
|
||||
libc = { version = "0.2", default-features = false }
|
||||
|
@ -13,7 +13,7 @@ use super::{
|
||||
formatters::{JsonFormatter, JunitFormatter, OutputFormatter, PrettyFormatter, TerseFormatter},
|
||||
helpers::{concurrency::get_concurrency, metrics::MetricMap},
|
||||
options::{Options, OutputFormat},
|
||||
run_tests,
|
||||
run_tests, term,
|
||||
test_result::TestResult,
|
||||
time::{TestExecTime, TestSuiteExecTime},
|
||||
types::{NamePadding, TestDesc, TestDescAndFn},
|
||||
|
@ -4,6 +4,7 @@ use super::OutputFormatter;
|
||||
use crate::{
|
||||
bench::fmt_bench_samples,
|
||||
console::{ConsoleTestState, OutputLocation},
|
||||
term,
|
||||
test_result::TestResult,
|
||||
time,
|
||||
types::TestDesc,
|
||||
|
@ -4,6 +4,7 @@ use super::OutputFormatter;
|
||||
use crate::{
|
||||
bench::fmt_bench_samples,
|
||||
console::{ConsoleTestState, OutputLocation},
|
||||
term,
|
||||
test_result::TestResult,
|
||||
time,
|
||||
types::NamePadding,
|
||||
|
@ -20,7 +20,7 @@
|
||||
#![crate_name = "test"]
|
||||
#![unstable(feature = "test", issue = "50297")]
|
||||
#![doc(test(attr(deny(warnings))))]
|
||||
#![cfg_attr(unix, feature(libc))]
|
||||
#![feature(libc)]
|
||||
#![feature(rustc_private)]
|
||||
#![feature(nll)]
|
||||
#![feature(available_concurrency)]
|
||||
@ -80,6 +80,7 @@ mod formatters;
|
||||
mod helpers;
|
||||
mod options;
|
||||
pub mod stats;
|
||||
mod term;
|
||||
mod test_result;
|
||||
mod time;
|
||||
mod types;
|
||||
|
85
library/test/src/term.rs
Normal file
85
library/test/src/term.rs
Normal file
@ -0,0 +1,85 @@
|
||||
//! Terminal formatting module.
|
||||
//!
|
||||
//! This module provides the `Terminal` trait, which abstracts over an [ANSI
|
||||
//! Terminal][ansi] to provide color printing, among other things. There are two
|
||||
//! implementations, the `TerminfoTerminal`, which uses control characters from
|
||||
//! a [terminfo][ti] database, and `WinConsole`, which uses the [Win32 Console
|
||||
//! API][win].
|
||||
//!
|
||||
//! [ansi]: https://en.wikipedia.org/wiki/ANSI_escape_code
|
||||
//! [win]: https://docs.microsoft.com/en-us/windows/console/character-mode-applications
|
||||
//! [ti]: https://en.wikipedia.org/wiki/Terminfo
|
||||
|
||||
#![deny(missing_docs)]
|
||||
|
||||
use std::io::{self, prelude::*};
|
||||
|
||||
pub(crate) use terminfo::TerminfoTerminal;
|
||||
#[cfg(windows)]
|
||||
pub(crate) use win::WinConsole;
|
||||
|
||||
pub(crate) mod terminfo;
|
||||
|
||||
#[cfg(windows)]
|
||||
mod win;
|
||||
|
||||
/// Alias for stdout terminals.
|
||||
pub(crate) type StdoutTerminal = dyn Terminal + Send;
|
||||
|
||||
#[cfg(not(windows))]
|
||||
/// Returns a Terminal wrapping stdout, or None if a terminal couldn't be
|
||||
/// opened.
|
||||
pub(crate) fn stdout() -> Option<Box<StdoutTerminal>> {
|
||||
TerminfoTerminal::new(io::stdout()).map(|t| Box::new(t) as Box<StdoutTerminal>)
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
/// Returns a Terminal wrapping stdout, or None if a terminal couldn't be
|
||||
/// opened.
|
||||
pub(crate) fn stdout() -> Option<Box<StdoutTerminal>> {
|
||||
TerminfoTerminal::new(io::stdout())
|
||||
.map(|t| Box::new(t) as Box<StdoutTerminal>)
|
||||
.or_else(|| WinConsole::new(io::stdout()).ok().map(|t| Box::new(t) as Box<StdoutTerminal>))
|
||||
}
|
||||
|
||||
/// Terminal color definitions
|
||||
#[allow(missing_docs)]
|
||||
#[cfg_attr(not(windows), allow(dead_code))]
|
||||
pub(crate) mod color {
|
||||
/// Number for a terminal color
|
||||
pub(crate) type Color = u32;
|
||||
|
||||
pub(crate) const BLACK: Color = 0;
|
||||
pub(crate) const RED: Color = 1;
|
||||
pub(crate) const GREEN: Color = 2;
|
||||
pub(crate) const YELLOW: Color = 3;
|
||||
pub(crate) const BLUE: Color = 4;
|
||||
pub(crate) const MAGENTA: Color = 5;
|
||||
pub(crate) const CYAN: Color = 6;
|
||||
pub(crate) const WHITE: Color = 7;
|
||||
}
|
||||
|
||||
/// A terminal with similar capabilities to an ANSI Terminal
|
||||
/// (foreground/background colors etc).
|
||||
pub trait Terminal: Write {
|
||||
/// Sets the foreground color to the given color.
|
||||
///
|
||||
/// If the color is a bright color, but the terminal only supports 8 colors,
|
||||
/// the corresponding normal color will be used instead.
|
||||
///
|
||||
/// Returns `Ok(true)` if the color was set, `Ok(false)` otherwise, and `Err(e)`
|
||||
/// if there was an I/O error.
|
||||
fn fg(&mut self, color: color::Color) -> io::Result<bool>;
|
||||
|
||||
/// Resets all terminal attributes and colors to their defaults.
|
||||
///
|
||||
/// Returns `Ok(true)` if the terminal was reset, `Ok(false)` otherwise, and `Err(e)` if there
|
||||
/// was an I/O error.
|
||||
///
|
||||
/// *Note: This does not flush.*
|
||||
///
|
||||
/// That means the reset command may get buffered so, if you aren't planning on doing anything
|
||||
/// else that might flush stdout's buffer (e.g., writing a line of text), you should flush after
|
||||
/// calling reset.
|
||||
fn reset(&mut self) -> io::Result<bool>;
|
||||
}
|
@ -8,9 +8,8 @@ use std::fs::File;
|
||||
use std::io::{self, prelude::*, BufReader};
|
||||
use std::path::Path;
|
||||
|
||||
use crate::color;
|
||||
use crate::Attr;
|
||||
use crate::Terminal;
|
||||
use super::color;
|
||||
use super::Terminal;
|
||||
|
||||
use parm::{expand, Param, Variables};
|
||||
use parser::compiled::{msys_terminfo, parse};
|
||||
@ -18,20 +17,20 @@ use searcher::get_dbpath_for_term;
|
||||
|
||||
/// A parsed terminfo database entry.
|
||||
#[derive(Debug)]
|
||||
pub struct TermInfo {
|
||||
pub(crate) struct TermInfo {
|
||||
/// Names for the terminal
|
||||
pub names: Vec<String>,
|
||||
pub(crate) names: Vec<String>,
|
||||
/// Map of capability name to boolean value
|
||||
pub bools: HashMap<String, bool>,
|
||||
pub(crate) bools: HashMap<String, bool>,
|
||||
/// Map of capability name to numeric value
|
||||
pub numbers: HashMap<String, u32>,
|
||||
pub(crate) numbers: HashMap<String, u32>,
|
||||
/// Map of capability name to raw (unexpanded) string
|
||||
pub strings: HashMap<String, Vec<u8>>,
|
||||
pub(crate) strings: HashMap<String, Vec<u8>>,
|
||||
}
|
||||
|
||||
/// A terminfo creation error.
|
||||
#[derive(Debug)]
|
||||
pub enum Error {
|
||||
pub(crate) enum Error {
|
||||
/// TermUnset Indicates that the environment doesn't include enough information to find
|
||||
/// the terminfo entry.
|
||||
TermUnset,
|
||||
@ -64,7 +63,7 @@ impl fmt::Display for Error {
|
||||
|
||||
impl TermInfo {
|
||||
/// Creates a TermInfo based on current environment.
|
||||
pub fn from_env() -> Result<TermInfo, Error> {
|
||||
pub(crate) fn from_env() -> Result<TermInfo, Error> {
|
||||
let term = match env::var("TERM") {
|
||||
Ok(name) => TermInfo::from_name(&name),
|
||||
Err(..) => return Err(Error::TermUnset),
|
||||
@ -79,7 +78,7 @@ impl TermInfo {
|
||||
}
|
||||
|
||||
/// Creates a TermInfo for the named terminal.
|
||||
pub fn from_name(name: &str) -> Result<TermInfo, Error> {
|
||||
pub(crate) fn from_name(name: &str) -> Result<TermInfo, Error> {
|
||||
get_dbpath_for_term(name)
|
||||
.ok_or_else(|| {
|
||||
Error::IoError(io::Error::new(io::ErrorKind::NotFound, "terminfo file not found"))
|
||||
@ -88,7 +87,7 @@ impl TermInfo {
|
||||
}
|
||||
|
||||
/// Parse the given TermInfo.
|
||||
pub fn from_path<P: AsRef<Path>>(path: P) -> Result<TermInfo, Error> {
|
||||
pub(crate) fn from_path<P: AsRef<Path>>(path: P) -> Result<TermInfo, Error> {
|
||||
Self::_from_path(path.as_ref())
|
||||
}
|
||||
// Keep the metadata small
|
||||
@ -99,43 +98,24 @@ impl TermInfo {
|
||||
}
|
||||
}
|
||||
|
||||
pub mod searcher;
|
||||
pub(crate) mod searcher;
|
||||
|
||||
/// TermInfo format parsing.
|
||||
pub mod parser {
|
||||
pub(crate) mod parser {
|
||||
//! ncurses-compatible compiled terminfo format parsing (term(5))
|
||||
pub mod compiled;
|
||||
}
|
||||
pub mod parm;
|
||||
|
||||
fn cap_for_attr(attr: Attr) -> &'static str {
|
||||
match attr {
|
||||
Attr::Bold => "bold",
|
||||
Attr::Dim => "dim",
|
||||
Attr::Italic(true) => "sitm",
|
||||
Attr::Italic(false) => "ritm",
|
||||
Attr::Underline(true) => "smul",
|
||||
Attr::Underline(false) => "rmul",
|
||||
Attr::Blink => "blink",
|
||||
Attr::Standout(true) => "smso",
|
||||
Attr::Standout(false) => "rmso",
|
||||
Attr::Reverse => "rev",
|
||||
Attr::Secure => "invis",
|
||||
Attr::ForegroundColor(_) => "setaf",
|
||||
Attr::BackgroundColor(_) => "setab",
|
||||
}
|
||||
pub(crate) mod compiled;
|
||||
}
|
||||
pub(crate) mod parm;
|
||||
|
||||
/// A Terminal that knows how many colors it supports, with a reference to its
|
||||
/// parsed Terminfo database record.
|
||||
pub struct TerminfoTerminal<T> {
|
||||
pub(crate) struct TerminfoTerminal<T> {
|
||||
num_colors: u32,
|
||||
out: T,
|
||||
ti: TermInfo,
|
||||
}
|
||||
|
||||
impl<T: Write + Send> Terminal for TerminfoTerminal<T> {
|
||||
type Output = T;
|
||||
fn fg(&mut self, color: color::Color) -> io::Result<bool> {
|
||||
let color = self.dim_if_necessary(color);
|
||||
if self.num_colors > color {
|
||||
@ -144,32 +124,6 @@ impl<T: Write + Send> Terminal for TerminfoTerminal<T> {
|
||||
Ok(false)
|
||||
}
|
||||
|
||||
fn bg(&mut self, color: color::Color) -> io::Result<bool> {
|
||||
let color = self.dim_if_necessary(color);
|
||||
if self.num_colors > color {
|
||||
return self.apply_cap("setab", &[Param::Number(color as i32)]);
|
||||
}
|
||||
Ok(false)
|
||||
}
|
||||
|
||||
fn attr(&mut self, attr: Attr) -> io::Result<bool> {
|
||||
match attr {
|
||||
Attr::ForegroundColor(c) => self.fg(c),
|
||||
Attr::BackgroundColor(c) => self.bg(c),
|
||||
_ => self.apply_cap(cap_for_attr(attr), &[]),
|
||||
}
|
||||
}
|
||||
|
||||
fn supports_attr(&self, attr: Attr) -> bool {
|
||||
match attr {
|
||||
Attr::ForegroundColor(_) | Attr::BackgroundColor(_) => self.num_colors > 0,
|
||||
_ => {
|
||||
let cap = cap_for_attr(attr);
|
||||
self.ti.strings.get(cap).is_some()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn reset(&mut self) -> io::Result<bool> {
|
||||
// are there any terminals that have color/attrs and not sgr0?
|
||||
// Try falling back to sgr, then op
|
||||
@ -182,26 +136,11 @@ impl<T: Write + Send> Terminal for TerminfoTerminal<T> {
|
||||
};
|
||||
self.out.write_all(&cmd).and(Ok(true))
|
||||
}
|
||||
|
||||
fn get_ref(&self) -> &T {
|
||||
&self.out
|
||||
}
|
||||
|
||||
fn get_mut(&mut self) -> &mut T {
|
||||
&mut self.out
|
||||
}
|
||||
|
||||
fn into_inner(self) -> T
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
self.out
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Write + Send> TerminfoTerminal<T> {
|
||||
/// Creates a new TerminfoTerminal with the given TermInfo and Write.
|
||||
pub fn new_with_terminfo(out: T, terminfo: TermInfo) -> TerminfoTerminal<T> {
|
||||
pub(crate) fn new_with_terminfo(out: T, terminfo: TermInfo) -> TerminfoTerminal<T> {
|
||||
let nc = if terminfo.strings.contains_key("setaf") && terminfo.strings.contains_key("setab")
|
||||
{
|
||||
terminfo.numbers.get("colors").map_or(0, |&n| n)
|
||||
@ -215,7 +154,7 @@ impl<T: Write + Send> TerminfoTerminal<T> {
|
||||
/// Creates a new TerminfoTerminal for the current environment with the given Write.
|
||||
///
|
||||
/// Returns `None` when the terminfo cannot be found or parsed.
|
||||
pub fn new(out: T) -> Option<TerminfoTerminal<T>> {
|
||||
pub(crate) fn new(out: T) -> Option<TerminfoTerminal<T>> {
|
||||
TermInfo::from_env().map(move |ti| TerminfoTerminal::new_with_terminfo(out, ti)).ok()
|
||||
}
|
||||
|
@ -35,13 +35,12 @@ enum FormatState {
|
||||
/// Types of parameters a capability can use
|
||||
#[allow(missing_docs)]
|
||||
#[derive(Clone)]
|
||||
pub enum Param {
|
||||
Words(String),
|
||||
pub(crate) enum Param {
|
||||
Number(i32),
|
||||
}
|
||||
|
||||
/// Container for static and dynamic variable arrays
|
||||
pub struct Variables {
|
||||
pub(crate) struct Variables {
|
||||
/// Static variables A-Z
|
||||
sta_va: [Param; 26],
|
||||
/// Dynamic variables a-z
|
||||
@ -50,7 +49,7 @@ pub struct Variables {
|
||||
|
||||
impl Variables {
|
||||
/// Returns a new zero-initialized Variables
|
||||
pub fn new() -> Variables {
|
||||
pub(crate) fn new() -> Variables {
|
||||
Variables {
|
||||
sta_va: [
|
||||
Number(0),
|
||||
@ -121,7 +120,11 @@ impl Variables {
|
||||
///
|
||||
/// To be compatible with ncurses, `vars` should be the same between calls to `expand` for
|
||||
/// multiple capabilities for the same terminal.
|
||||
pub fn expand(cap: &[u8], params: &[Param], vars: &mut Variables) -> Result<Vec<u8>, String> {
|
||||
pub(crate) fn expand(
|
||||
cap: &[u8],
|
||||
params: &[Param],
|
||||
vars: &mut Variables,
|
||||
) -> Result<Vec<u8>, String> {
|
||||
let mut state = Nothing;
|
||||
|
||||
// expanded cap will only rarely be larger than the cap itself
|
||||
@ -168,7 +171,6 @@ pub fn expand(cap: &[u8], params: &[Param], vars: &mut Variables) -> Result<Vec<
|
||||
Some(Number(0)) => output.push(128u8),
|
||||
// Don't check bounds. ncurses just casts and truncates.
|
||||
Some(Number(c)) => output.push(c as u8),
|
||||
Some(_) => return Err("a non-char was used with %c".to_string()),
|
||||
None => return Err("stack is empty".to_string()),
|
||||
}
|
||||
}
|
||||
@ -178,7 +180,6 @@ pub fn expand(cap: &[u8], params: &[Param], vars: &mut Variables) -> Result<Vec<
|
||||
'\'' => state = CharConstant,
|
||||
'{' => state = IntConstant(0),
|
||||
'l' => match stack.pop() {
|
||||
Some(Words(s)) => stack.push(Number(s.len() as i32)),
|
||||
Some(_) => return Err("a non-str was used with %l".to_string()),
|
||||
None => return Err("stack is empty".to_string()),
|
||||
},
|
||||
@ -195,9 +196,6 @@ pub fn expand(cap: &[u8], params: &[Param], vars: &mut Variables) -> Result<Vec<
|
||||
'm' => x % y,
|
||||
_ => unreachable!("All cases handled"),
|
||||
})),
|
||||
(Some(_), Some(_)) => {
|
||||
return Err(format!("non-numbers on stack with {}", cur));
|
||||
}
|
||||
_ => return Err("stack is empty".to_string()),
|
||||
}
|
||||
}
|
||||
@ -216,9 +214,6 @@ pub fn expand(cap: &[u8], params: &[Param], vars: &mut Variables) -> Result<Vec<
|
||||
0
|
||||
},
|
||||
)),
|
||||
(Some(_), Some(_)) => {
|
||||
return Err(format!("non-numbers on stack with {}", cur));
|
||||
}
|
||||
_ => return Err("stack is empty".to_string()),
|
||||
},
|
||||
'!' | '~' => match stack.pop() {
|
||||
@ -228,7 +223,6 @@ pub fn expand(cap: &[u8], params: &[Param], vars: &mut Variables) -> Result<Vec<
|
||||
'~' => !x,
|
||||
_ => unreachable!(),
|
||||
})),
|
||||
Some(_) => return Err(format!("non-numbers on stack with {}", cur)),
|
||||
None => return Err("stack is empty".to_string()),
|
||||
},
|
||||
'i' => match (&mparams[0], &mparams[1]) {
|
||||
@ -236,7 +230,6 @@ pub fn expand(cap: &[u8], params: &[Param], vars: &mut Variables) -> Result<Vec<
|
||||
mparams[0] = Number(x + 1);
|
||||
mparams[1] = Number(y + 1);
|
||||
}
|
||||
_ => return Err("first two params not numbers with %i".to_string()),
|
||||
},
|
||||
|
||||
// printf-style support for %doxXs
|
||||
@ -271,7 +264,6 @@ pub fn expand(cap: &[u8], params: &[Param], vars: &mut Variables) -> Result<Vec<
|
||||
't' => match stack.pop() {
|
||||
Some(Number(0)) => state = SeekIfElse(0),
|
||||
Some(Number(_)) => (),
|
||||
Some(_) => return Err("non-number on stack with conditional".to_string()),
|
||||
None => return Err("stack is empty".to_string()),
|
||||
},
|
||||
'e' => state = SeekIfEnd(0),
|
||||
@ -480,15 +472,6 @@ impl FormatOp {
|
||||
_ => panic!("bad FormatOp char"),
|
||||
}
|
||||
}
|
||||
fn to_char(self) -> char {
|
||||
match self {
|
||||
FormatOp::Digit => 'd',
|
||||
FormatOp::Octal => 'o',
|
||||
FormatOp::LowerHex => 'x',
|
||||
FormatOp::UpperHex => 'X',
|
||||
FormatOp::String => 's',
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn format(val: Param, op: FormatOp, flags: Flags) -> Result<Vec<u8>, String> {
|
||||
@ -533,16 +516,6 @@ fn format(val: Param, op: FormatOp, flags: Flags) -> Result<Vec<u8>, String> {
|
||||
}
|
||||
.into_bytes()
|
||||
}
|
||||
Words(s) => match op {
|
||||
FormatOp::String => {
|
||||
let mut s = s.into_bytes();
|
||||
if flags.precision > 0 && flags.precision < s.len() {
|
||||
s.truncate(flags.precision);
|
||||
}
|
||||
s
|
||||
}
|
||||
_ => return Err(format!("non-string on stack with %{}", op.to_char())),
|
||||
},
|
||||
};
|
||||
if flags.width > s.len() {
|
||||
let n = flags.width - s.len();
|
@ -51,7 +51,10 @@ fn test_param_stack_failure_conditions() {
|
||||
for &cap in caps.iter() {
|
||||
let res = get_res("", cap, &[], vars);
|
||||
assert!(res.is_err(), "Op {} succeeded incorrectly with 0 stack entries", cap);
|
||||
let p = if cap == "%s" || cap == "%l" { Words("foo".to_string()) } else { Number(97) };
|
||||
if cap == "%s" || cap == "%l" {
|
||||
continue;
|
||||
}
|
||||
let p = Number(97);
|
||||
let res = get_res("%p1", cap, &[p], vars);
|
||||
assert!(res.is_ok(), "Op {} failed with 1 stack entry: {}", cap, res.unwrap_err());
|
||||
}
|
||||
@ -109,23 +112,6 @@ fn test_conditionals() {
|
||||
fn test_format() {
|
||||
let mut varstruct = Variables::new();
|
||||
let vars = &mut varstruct;
|
||||
assert_eq!(
|
||||
expand(
|
||||
b"%p1%s%p2%2s%p3%2s%p4%.2s",
|
||||
&[
|
||||
Words("foo".to_string()),
|
||||
Words("foo".to_string()),
|
||||
Words("f".to_string()),
|
||||
Words("foo".to_string())
|
||||
],
|
||||
vars
|
||||
),
|
||||
Ok("foofoo ffo".bytes().collect::<Vec<_>>())
|
||||
);
|
||||
assert_eq!(
|
||||
expand(b"%p1%:-4.2s", &[Words("foo".to_string())], vars),
|
||||
Ok("fo ".bytes().collect::<Vec<_>>())
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
expand(b"%p1%d%p1%.3d%p1%5d%p1%:+d", &[Number(1)], vars),
|
@ -13,7 +13,7 @@ mod tests;
|
||||
// These are the orders ncurses uses in its compiled format (as of 5.9). Not sure if portable.
|
||||
|
||||
#[rustfmt::skip]
|
||||
pub static boolfnames: &[&str] = &["auto_left_margin", "auto_right_margin",
|
||||
pub(crate) static boolfnames: &[&str] = &["auto_left_margin", "auto_right_margin",
|
||||
"no_esc_ctlc", "ceol_standout_glitch", "eat_newline_glitch", "erase_overstrike", "generic_type",
|
||||
"hard_copy", "has_meta_key", "has_status_line", "insert_null_glitch", "memory_above",
|
||||
"memory_below", "move_insert_mode", "move_standout_mode", "over_strike", "status_line_esc_ok",
|
||||
@ -26,13 +26,13 @@ pub static boolfnames: &[&str] = &["auto_left_margin", "auto_right_margin",
|
||||
"return_does_clr_eol"];
|
||||
|
||||
#[rustfmt::skip]
|
||||
pub static boolnames: &[&str] = &["bw", "am", "xsb", "xhp", "xenl", "eo",
|
||||
pub(crate) static boolnames: &[&str] = &["bw", "am", "xsb", "xhp", "xenl", "eo",
|
||||
"gn", "hc", "km", "hs", "in", "db", "da", "mir", "msgr", "os", "eslok", "xt", "hz", "ul", "xon",
|
||||
"nxon", "mc5i", "chts", "nrrmc", "npc", "ndscr", "ccc", "bce", "hls", "xhpa", "crxm", "daisy",
|
||||
"xvpa", "sam", "cpix", "lpix", "OTbs", "OTns", "OTnc", "OTMT", "OTNL", "OTpt", "OTxr"];
|
||||
|
||||
#[rustfmt::skip]
|
||||
pub static numfnames: &[&str] = &[ "columns", "init_tabs", "lines",
|
||||
pub(crate) static numfnames: &[&str] = &[ "columns", "init_tabs", "lines",
|
||||
"lines_of_memory", "magic_cookie_glitch", "padding_baud_rate", "virtual_terminal",
|
||||
"width_status_line", "num_labels", "label_height", "label_width", "max_attributes",
|
||||
"maximum_windows", "max_colors", "max_pairs", "no_color_video", "buffer_capacity",
|
||||
@ -43,13 +43,13 @@ pub static numfnames: &[&str] = &[ "columns", "init_tabs", "lines",
|
||||
"new_line_delay", "backspace_delay", "horizontal_tab_delay", "number_of_function_keys"];
|
||||
|
||||
#[rustfmt::skip]
|
||||
pub static numnames: &[&str] = &[ "cols", "it", "lines", "lm", "xmc", "pb",
|
||||
pub(crate) static numnames: &[&str] = &[ "cols", "it", "lines", "lm", "xmc", "pb",
|
||||
"vt", "wsl", "nlab", "lh", "lw", "ma", "wnum", "colors", "pairs", "ncv", "bufsz", "spinv",
|
||||
"spinh", "maddr", "mjump", "mcs", "mls", "npins", "orc", "orl", "orhi", "orvi", "cps", "widcs",
|
||||
"btns", "bitwin", "bitype", "UTug", "OTdC", "OTdN", "OTdB", "OTdT", "OTkn"];
|
||||
|
||||
#[rustfmt::skip]
|
||||
pub static stringfnames: &[&str] = &[ "back_tab", "bell", "carriage_return",
|
||||
pub(crate) static stringfnames: &[&str] = &[ "back_tab", "bell", "carriage_return",
|
||||
"change_scroll_region", "clear_all_tabs", "clear_screen", "clr_eol", "clr_eos",
|
||||
"column_address", "command_character", "cursor_address", "cursor_down", "cursor_home",
|
||||
"cursor_invisible", "cursor_left", "cursor_mem_address", "cursor_normal", "cursor_right",
|
||||
@ -123,7 +123,7 @@ pub static stringfnames: &[&str] = &[ "back_tab", "bell", "carriage_return",
|
||||
"acs_plus", "memory_lock", "memory_unlock", "box_chars_1"];
|
||||
|
||||
#[rustfmt::skip]
|
||||
pub static stringnames: &[&str] = &[ "cbt", "_", "cr", "csr", "tbc", "clear",
|
||||
pub(crate) static stringnames: &[&str] = &[ "cbt", "_", "cr", "csr", "tbc", "clear",
|
||||
"_", "_", "hpa", "cmdch", "cup", "cud1", "home", "civis", "cub1", "mrcup", "cnorm", "cuf1",
|
||||
"ll", "cuu1", "cvvis", "dch1", "dl1", "dsl", "hd", "smacs", "blink", "bold", "smcup", "smdc",
|
||||
"dim", "smir", "invis", "prot", "rev", "smso", "smul", "ech", "rmacs", "sgr0", "rmcup", "rmdc",
|
||||
@ -178,7 +178,7 @@ fn read_byte(r: &mut dyn io::Read) -> io::Result<u8> {
|
||||
|
||||
/// Parse a compiled terminfo entry, using long capability names if `longnames`
|
||||
/// is true
|
||||
pub fn parse(file: &mut dyn io::Read, longnames: bool) -> Result<TermInfo, String> {
|
||||
pub(crate) fn parse(file: &mut dyn io::Read, longnames: bool) -> Result<TermInfo, String> {
|
||||
macro_rules! t( ($e:expr) => (
|
||||
match $e {
|
||||
Ok(e) => e,
|
||||
@ -317,7 +317,7 @@ pub fn parse(file: &mut dyn io::Read, longnames: bool) -> Result<TermInfo, Strin
|
||||
}
|
||||
|
||||
/// Creates a dummy TermInfo struct for msys terminals
|
||||
pub fn msys_terminfo() -> TermInfo {
|
||||
pub(crate) fn msys_terminfo() -> TermInfo {
|
||||
let mut strings = HashMap::new();
|
||||
strings.insert("sgr0".to_string(), b"\x1B[0m".to_vec());
|
||||
strings.insert("bold".to_string(), b"\x1B[1m".to_vec());
|
@ -11,7 +11,7 @@ mod tests;
|
||||
|
||||
/// Return path to database entry for `term`
|
||||
#[allow(deprecated)]
|
||||
pub fn get_dbpath_for_term(term: &str) -> Option<PathBuf> {
|
||||
pub(crate) fn get_dbpath_for_term(term: &str) -> Option<PathBuf> {
|
||||
let mut dirs_to_search = Vec::new();
|
||||
let first_char = term.chars().next()?;
|
||||
|
@ -5,12 +5,11 @@
|
||||
use std::io;
|
||||
use std::io::prelude::*;
|
||||
|
||||
use crate::color;
|
||||
use crate::Attr;
|
||||
use crate::Terminal;
|
||||
use super::color;
|
||||
use super::Terminal;
|
||||
|
||||
/// A Terminal implementation that uses the Win32 Console API.
|
||||
pub struct WinConsole<T> {
|
||||
pub(crate) struct WinConsole<T> {
|
||||
buf: T,
|
||||
def_foreground: color::Color,
|
||||
def_background: color::Color,
|
||||
@ -115,7 +114,7 @@ impl<T: Write + Send + 'static> WinConsole<T> {
|
||||
}
|
||||
|
||||
/// Returns `None` whenever the terminal cannot be created for some reason.
|
||||
pub fn new(out: T) -> io::Result<WinConsole<T>> {
|
||||
pub(crate) fn new(out: T) -> io::Result<WinConsole<T>> {
|
||||
use std::mem::MaybeUninit;
|
||||
|
||||
let fg;
|
||||
@ -154,8 +153,6 @@ impl<T: Write> Write for WinConsole<T> {
|
||||
}
|
||||
|
||||
impl<T: Write + Send + 'static> Terminal for WinConsole<T> {
|
||||
type Output = T;
|
||||
|
||||
fn fg(&mut self, color: color::Color) -> io::Result<bool> {
|
||||
self.foreground = color;
|
||||
self.apply();
|
||||
@ -163,38 +160,6 @@ impl<T: Write + Send + 'static> Terminal for WinConsole<T> {
|
||||
Ok(true)
|
||||
}
|
||||
|
||||
fn bg(&mut self, color: color::Color) -> io::Result<bool> {
|
||||
self.background = color;
|
||||
self.apply();
|
||||
|
||||
Ok(true)
|
||||
}
|
||||
|
||||
fn attr(&mut self, attr: Attr) -> io::Result<bool> {
|
||||
match attr {
|
||||
Attr::ForegroundColor(f) => {
|
||||
self.foreground = f;
|
||||
self.apply();
|
||||
Ok(true)
|
||||
}
|
||||
Attr::BackgroundColor(b) => {
|
||||
self.background = b;
|
||||
self.apply();
|
||||
Ok(true)
|
||||
}
|
||||
_ => Ok(false),
|
||||
}
|
||||
}
|
||||
|
||||
fn supports_attr(&self, attr: Attr) -> bool {
|
||||
// it claims support for underscore and reverse video, but I can't get
|
||||
// it to do anything -cmr
|
||||
match attr {
|
||||
Attr::ForegroundColor(_) | Attr::BackgroundColor(_) => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
fn reset(&mut self) -> io::Result<bool> {
|
||||
self.foreground = self.def_foreground;
|
||||
self.background = self.def_background;
|
||||
@ -202,19 +167,4 @@ impl<T: Write + Send + 'static> Terminal for WinConsole<T> {
|
||||
|
||||
Ok(true)
|
||||
}
|
||||
|
||||
fn get_ref(&self) -> &T {
|
||||
&self.buf
|
||||
}
|
||||
|
||||
fn get_mut(&mut self) -> &mut T {
|
||||
&mut self.buf
|
||||
}
|
||||
|
||||
fn into_inner(self) -> T
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
self.buf
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user