Skip to content

Commit 2b94c82

Browse files
committed
cargo run --example something will ICE
Signed-off-by: Peter Atashian <[email protected]>
1 parent 10cc9f2 commit 2b94c82

File tree

3 files changed

+72
-29
lines changed

3 files changed

+72
-29
lines changed

examples/something.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// Copyright 2013-2015 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
extern crate term;
12+
13+
use term::Terminal;
14+
15+
fn main() {
16+
let mut out = term::stdout().unwrap();
17+
out.fg(5);
18+
out.bg(4);
19+
writeln!(&mut out, "Hello World!");
20+
}

src/lib.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
1+
// Copyright 2013-2015 The Rust Project Developers. See the COPYRIGHT
22
// file at the top-level directory of this distribution and at
33
// http://rust-lang.org/COPYRIGHT.
44
//
@@ -79,7 +79,7 @@ pub fn stdout() -> Option<Box<StdoutTerminal>> {
7979
pub fn stdout() -> Option<Box<StdoutTerminal>> {
8080
TerminfoTerminal::new(io::stdout()).map(|t| {
8181
Box::new(t) as Box<StdoutTerminal>
82-
}).or_else(|| WinConsole::new(io::stdout()).map(|t| {
82+
}).or_else(|| WinConsole::new(io::stdout()).ok().map(|t| {
8383
Box::new(t) as Box<StdoutTerminal>
8484
}))
8585
}
@@ -99,7 +99,7 @@ pub fn stderr() -> Option<Box<StderrTerminal>> {
9999
pub fn stderr() -> Option<Box<StderrTerminal>> {
100100
TerminfoTerminal::new(io::stderr()).map(|t| {
101101
Box::new(t) as Box<StderrTerminal>
102-
}).or_else(|| WinConsole::new(io::stderr()).map(|t| {
102+
}).or_else(|| WinConsole::new(io::stderr()).ok().map(|t| {
103103
Box::new(t) as Box<StderrTerminal>
104104
}))
105105
}

src/win.rs

Lines changed: 49 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
1+
// Copyright 2013-2015 The Rust Project Developers. See the COPYRIGHT
22
// file at the top-level directory of this distribution and at
33
// http://rust-lang.org/COPYRIGHT.
44
//
@@ -17,10 +17,11 @@ extern crate winapi;
1717

1818
use std::io::prelude::*;
1919
use std::io;
20+
use std::ptr;
2021

2122
use Attr;
2223
use color;
23-
use {Terminal,UnwrappableTerminal};
24+
use {Terminal, UnwrappableTerminal};
2425

2526
/// A Terminal implementation which uses the Win32 Console API.
2627
pub struct WinConsole<T> {
@@ -69,45 +70,54 @@ fn bits_to_color(bits: u16) -> color::Color {
6970
color | (bits & 0x8) // copy the hi-intensity bit
7071
}
7172

73+
// Just get a handle to the current console buffer whatever it is
74+
fn conout() -> io::Result<winapi::HANDLE> {
75+
let handle = unsafe {
76+
kernel32::CreateFileA("CONOUT$\0".as_ptr() as winapi::LPCSTR, winapi::GENERIC_WRITE,
77+
winapi::FILE_SHARE_WRITE, ptr::null_mut(), winapi::OPEN_EXISTING, 0, ptr::null_mut())
78+
};
79+
if handle == winapi::INVALID_HANDLE_VALUE {
80+
Err(io::Error::last_os_error())
81+
} else {
82+
Ok(handle)
83+
}
84+
}
85+
86+
// This test will only pass if it is running in an actual console, probably
87+
#[test]
88+
fn test_conout() {
89+
assert!(conout().is_ok())
90+
}
91+
7292
impl<T: Write+Send> WinConsole<T> {
73-
fn apply(&mut self) {
93+
fn apply(&mut self) -> io::Result<()> {
94+
let out = try!(conout());
7495
let _unused = self.buf.flush();
7596
let mut accum: winapi::WORD = 0;
7697
accum |= color_to_bits(self.foreground);
7798
accum |= color_to_bits(self.background) << 4;
78-
7999
unsafe {
80-
// Magic -11 means stdout, from
81-
// http://msdn.microsoft.com/en-us/library/windows/desktop/ms683231%28v=vs.85%29.aspx
82-
//
83-
// You may be wondering, "but what about stderr?", and the answer
84-
// to that is that setting terminal attributes on the stdout
85-
// handle also sets them for stderr, since they go to the same
86-
// terminal! Admittedly, this is fragile, since stderr could be
87-
// redirected to a different console. This is good enough for
88-
// rustc though. See #13400.
89-
let out = kernel32::GetStdHandle(-11i32 as winapi::DWORD);
90100
kernel32::SetConsoleTextAttribute(out, accum);
91101
}
102+
Ok(())
92103
}
93104

94105
/// Returns `None` whenever the terminal cannot be created for some
95106
/// reason.
96-
pub fn new(out: T) -> Option<WinConsole<T>> {
107+
pub fn new(out: T) -> io::Result<WinConsole<T>> {
97108
let fg;
98109
let bg;
110+
let handle = try!(conout());
99111
unsafe {
100112
let mut buffer_info = ::std::mem::uninitialized();
101-
let out = kernel32::GetStdHandle(-11i32 as winapi::DWORD);
102-
if kernel32::GetConsoleScreenBufferInfo(out, &mut buffer_info) != 0 {
113+
if kernel32::GetConsoleScreenBufferInfo(handle, &mut buffer_info) != 0 {
103114
fg = bits_to_color(buffer_info.wAttributes);
104115
bg = bits_to_color(buffer_info.wAttributes >> 4);
105116
} else {
106-
fg = color::WHITE;
107-
bg = color::BLACK;
117+
return Err(io::Error::last_os_error());
108118
}
109119
}
110-
Some(WinConsole {
120+
Ok(WinConsole {
111121
buf: out,
112122
def_foreground: fg,
113123
def_background: bg,
@@ -130,14 +140,14 @@ impl<T: Write> Write for WinConsole<T> {
130140
impl<T: Write+Send> Terminal<T> for WinConsole<T> {
131141
fn fg(&mut self, color: color::Color) -> io::Result<bool> {
132142
self.foreground = color;
133-
self.apply();
143+
try!(self.apply());
134144

135145
Ok(true)
136146
}
137147

138148
fn bg(&mut self, color: color::Color) -> io::Result<bool> {
139149
self.background = color;
140-
self.apply();
150+
try!(self.apply());
141151

142152
Ok(true)
143153
}
@@ -146,12 +156,12 @@ impl<T: Write+Send> Terminal<T> for WinConsole<T> {
146156
match attr {
147157
Attr::ForegroundColor(f) => {
148158
self.foreground = f;
149-
self.apply();
159+
try!(self.apply());
150160
Ok(true)
151161
},
152162
Attr::BackgroundColor(b) => {
153163
self.background = b;
154-
self.apply();
164+
try!(self.apply());
155165
Ok(true)
156166
},
157167
_ => Ok(false)
@@ -170,11 +180,24 @@ impl<T: Write+Send> Terminal<T> for WinConsole<T> {
170180
fn reset(&mut self) -> io::Result<bool> {
171181
self.foreground = self.def_foreground;
172182
self.background = self.def_background;
173-
self.apply();
183+
try!(self.apply());
174184

175185
Ok(true)
176186
}
177-
187+
188+
fn cursor_up(&mut self) -> io::Result<bool> {
189+
unimplemented!()
190+
//if GetConsoleScreenBufferInfo(
191+
}
192+
193+
fn delete_line(&mut self) -> io::Result<bool> {
194+
unimplemented!()
195+
}
196+
197+
fn carriage_return(&mut self) -> io::Result<bool> {
198+
unimplemented!()
199+
}
200+
178201
fn get_ref<'a>(&'a self) -> &'a T { &self.buf }
179202

180203
fn get_mut<'a>(&'a mut self) -> &'a mut T { &mut self.buf }

0 commit comments

Comments
 (0)