Rollup merge of #100206 - RalfJung:miri-terminfo, r=thomcc

test: skip terminfo parsing in Miri

Terminfo parsing takes a significant amount of time in Miri, making libtest startup very slow. To work around that Miri in fact unsets the `TERM` variable. However, this means we don't get colors in `cargo miri test`.

So I propose we add some logic in libtest that skips parsing terminfo files under Miri, and just uses the regular basic coloring commands (taken from the `colored` crate).

As far as I can see, these two commands are all that libtest ever needs from terminfo, so Miri doesn't even lose any functionality through this. If you want I can entirely remove the terminfo parsing code and just use these commands instead.

Cc https://github.com/rust-lang/miri/issues/2292 `@saethlin`
This commit is contained in:
Matthias Krüger 2022-08-07 21:10:25 +02:00 committed by GitHub
commit 07315fe970
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -80,6 +80,17 @@ impl TermInfo {
/// Creates a TermInfo for the named terminal.
pub(crate) fn from_name(name: &str) -> Result<TermInfo, Error> {
if cfg!(miri) {
// Avoid all the work of parsing the terminfo (it's pretty slow under Miri), and just
// assume that the standard color codes work (like e.g. the 'colored' crate).
return Ok(TermInfo {
names: Default::default(),
bools: Default::default(),
numbers: Default::default(),
strings: Default::default(),
});
}
get_dbpath_for_term(name)
.ok_or_else(|| {
Error::IoError(io::Error::new(io::ErrorKind::NotFound, "terminfo file not found"))
@ -119,6 +130,12 @@ pub(crate) struct TerminfoTerminal<T> {
impl<T: Write + Send> Terminal for TerminfoTerminal<T> {
fn fg(&mut self, color: color::Color) -> io::Result<bool> {
let color = self.dim_if_necessary(color);
if cfg!(miri) && color < 8 {
// The Miri logic for this only works for the most basic 8 colors, which we just assume
// the terminal will support. (`num_colors` is always 0 in Miri, so higher colors will
// just fail. But libtest doesn't use any higher colors anyway.)
return write!(self.out, "\x1B[3{color}m").and(Ok(true));
}
if self.num_colors > color {
return self.apply_cap("setaf", &[Param::Number(color as i32)]);
}
@ -126,6 +143,9 @@ impl<T: Write + Send> Terminal for TerminfoTerminal<T> {
}
fn reset(&mut self) -> io::Result<bool> {
if cfg!(miri) {
return write!(self.out, "\x1B[0m").and(Ok(true));
}
// are there any terminals that have color/attrs and not sgr0?
// Try falling back to sgr, then op
let cmd = match ["sgr0", "sgr", "op"].iter().find_map(|cap| self.ti.strings.get(*cap)) {