Skip to content

Commit 5a9d4aa

Browse files
committed
test suite: Output UTF-8 from cmd.exe on Windows
1 parent a97b3ff commit 5a9d4aa

File tree

3 files changed

+76
-1
lines changed

3 files changed

+76
-1
lines changed

src/liblibc/lib.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -1827,6 +1827,7 @@ pub mod types {
18271827
pub type HINSTANCE = HANDLE;
18281828
pub type HMODULE = HINSTANCE;
18291829

1830+
pub type UINT = c_uint;
18301831
pub type LONG = c_long;
18311832
pub type PLONG = *mut c_long;
18321833

@@ -6170,7 +6171,7 @@ pub mod funcs {
61706171

61716172
pub mod kernel32 {
61726173
use types::os::arch::c95::{c_uint};
6173-
use types::os::arch::extra::{BOOL, DWORD, SIZE_T, HMODULE,
6174+
use types::os::arch::extra::{BOOL, UINT, DWORD, SIZE_T, HMODULE,
61746175
LPCWSTR, LPWSTR,
61756176
LPWCH, LPDWORD, LPVOID,
61766177
LPCVOID, LPOVERLAPPED,
@@ -6355,6 +6356,8 @@ pub mod funcs {
63556356
lpNumberOfBytesTransferred: LPDWORD,
63566357
bWait: BOOL) -> BOOL;
63576358
pub fn DisconnectNamedPipe(hNamedPipe: HANDLE) -> BOOL;
6359+
pub fn GetConsoleOutputCP() -> UINT;
6360+
pub fn SetConsoleOutputCP(wCodePageID: UINT) -> BOOL;
63586361
}
63596362
}
63606363

src/libtest/lib.rs

+33
Original file line numberDiff line numberDiff line change
@@ -638,6 +638,35 @@ pub fn fmt_bench_samples(bs: &BenchSamples) -> String {
638638
}
639639
}
640640

641+
struct ConsoleOutputCPGuard {
642+
#[allow(dead_code)]
643+
old_cp: libc::UINT
644+
}
645+
646+
impl ConsoleOutputCPGuard {
647+
#[cfg(windows)]
648+
fn new(new_cp: libc::UINT) -> Self {
649+
unsafe {
650+
let res = ConsoleOutputCPGuard { old_cp: libc::GetConsoleOutputCP() };
651+
libc::SetConsoleOutputCP(new_cp);
652+
res
653+
}
654+
}
655+
#[cfg(not(windows))]
656+
fn new(_new_cp: libc::UINT) -> Self {
657+
ConsoleOutputCPGuard { old_cp: 0 }
658+
}
659+
}
660+
661+
#[cfg(windows)]
662+
impl Drop for ConsoleOutputCPGuard {
663+
fn drop(&mut self) {
664+
unsafe {
665+
libc::SetConsoleOutputCP(self.old_cp);
666+
}
667+
}
668+
}
669+
641670
// A simple console test runner
642671
pub fn run_tests_console(opts: &TestOpts, tests: Vec<TestDescAndFn> ) -> io::Result<bool> {
643672

@@ -695,6 +724,10 @@ pub fn run_tests_console(opts: &TestOpts, tests: Vec<TestDescAndFn> ) -> io::Res
695724
},
696725
None => {}
697726
}
727+
// Tests on Windows use cmd.exe commands like `set` or `cd`, their output should
728+
// be encoded in UTF-8 (issue #25268). Encoding of cmd.exe's output is controlled
729+
// by console output code page, so set it to UTF-8 temporarily.
730+
let _guard = ConsoleOutputCPGuard::new(65001);
698731
try!(run_tests(opts, tests, |x| callback(&x, &mut st)));
699732
return st.write_run_finish();
700733
}

src/test/run-pass/issue-25268.rs

+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
// Copyright 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+
use std::process::Command;
12+
use std::env;
13+
14+
#[cfg(all(unix, not(target_os="android")))]
15+
pub fn env_cmd() -> Command {
16+
Command::new("env")
17+
}
18+
#[cfg(target_os="android")]
19+
pub fn env_cmd() -> Command {
20+
let mut cmd = Command::new("/system/bin/sh");
21+
cmd.arg("-c").arg("set");
22+
cmd
23+
}
24+
25+
#[cfg(windows)]
26+
pub fn env_cmd() -> Command {
27+
let mut cmd = Command::new("cmd");
28+
cmd.arg("/c").arg("set");
29+
cmd
30+
}
31+
32+
33+
fn main() {
34+
let result = env_cmd().env("RUST_ISSUE_25268", "æ").output().unwrap();
35+
let output = String::from_utf8(result.stdout).unwrap();
36+
37+
assert!(output.contains("RUST_ISSUE_25268=æ"),
38+
"didn't find RUST_ISSUE_25268=æ inside of:\n\n{}", output);
39+
}

0 commit comments

Comments
 (0)