Skip to content

Commit d947f04

Browse files
authored
Merge pull request #12 from TerranMechworks/output-debug-string-w
Use OutputDebugStringW by default
2 parents 5b253b2 + 0b3a34a commit d947f04

4 files changed

Lines changed: 39 additions & 24 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
- Fixup: Specify exports via [Module-Definition (.Def)
1212
file](https://learn.microsoft.com/en-us/cpp/build/reference/module-definition-dot-def-files).
1313
- Fixup: Now builds using either `i686-pc-windows-gnu` or `i686-pc-windows-msvc`.
14+
- Fixup: `output!` macro uses Unicode/`OutputDebugStringW` by default.
1415

1516
- Project: Update Rust version to 1.88.0 and edition to 2024. This moves off
1617
nightly, since everything we need is now stabilised, and should help with

crates/export-check/src/main.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
88
let (expected_exports, expected_forwards) = parse_def_file()?;
99

1010
for path in std::env::args().skip(1) {
11-
println!("=== {} ===", path);
11+
println!("=== {path} ===");
1212

1313
let contents = std::fs::read(path)?;
1414
let data = contents.as_slice();
@@ -115,11 +115,11 @@ fn validate_exports(
115115
exports.sort();
116116
forwards.sort();
117117

118-
for name in exports.iter().copied() {
118+
for name in exports {
119119
println!("{name}");
120120
}
121121

122-
for forward in forwards.iter().copied() {
122+
for forward in forwards {
123123
println!("{forward}");
124124
}
125125

crates/zipfixup/build.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ fn main() {
1010
println!("cargo::warning={path}");
1111
println!("cargo::rerun-if-changed={path}");
1212

13+
#[allow(clippy::wildcard_in_or_patterns)]
1314
match env.as_str() {
1415
"gnu" => {
1516
println!("cargo::rustc-link-arg-cdylib={path}");

crates/zipfixup/src/dbg.rs

Lines changed: 34 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,18 @@
11
use ::winapi::um::debugapi::{OutputDebugStringA, OutputDebugStringW};
22

3-
#[expect(dead_code, reason = "test me!")]
4-
pub(crate) fn encode_unicode(msg: &str) {
3+
/// Output a Unicode debug string.
4+
///
5+
/// OutputDebugStringW is... weird/standard Microsoft:
6+
/// > `OutputDebugStringW` converts the specified string based on the current
7+
/// > system locale information and passes it to `OutputDebugStringA` to be
8+
/// > displayed. As a result, some Unicode characters may not be displayed
9+
/// > correctly.
10+
///
11+
/// See <https://learn.microsoft.com/en-us/windows/win32/api/debugapi/nf-debugapi-outputdebugstringw>.
12+
///
13+
/// Although you shouldn't log a lot of stuff, if you need to, the ASCII
14+
/// version may be slightly faster.
15+
pub(crate) fn output_debug_string_w(msg: &str) {
516
let now = time::OffsetDateTime::now_utc();
617
let s = format!(
718
"[ZF {:04}-{:02}-{:02}T{:02}:{:02}:{:02}.{:03}Z] {msg}\0",
@@ -16,19 +27,27 @@ pub(crate) fn encode_unicode(msg: &str) {
1627

1728
let v: Vec<u16> = s.encode_utf16().collect();
1829
let p: *const u16 = v.as_ptr();
19-
// OutputDebugStringW is... weird/standard Microsoft:
20-
// > `OutputDebugStringW` converts the specified string based on the current
21-
// > system locale information and passes it to `OutputDebugStringA` to be
22-
// > displayed. As a result, some Unicode characters may not be displayed
23-
// > correctly.
24-
// https://learn.microsoft.com/en-us/windows/win32/api/debugapi/nf-debugapi-outputdebugstringw
25-
// Therefore, we may be better off just using OutputDebugStringA...
2630
unsafe { OutputDebugStringW(p) };
2731
// paranoia: ensure `v` is valid until after `OutputDebugStringW`
2832
drop(v);
2933
}
3034

31-
pub(crate) fn encode_ascii(msg: &str) {
35+
fn encode_ascii(s: &str) -> Vec<i8> {
36+
s.chars()
37+
.map(|c| {
38+
let b = if c.is_ascii() { c as u8 } else { b'?' };
39+
b as i8
40+
})
41+
.collect()
42+
}
43+
44+
/// Output an ASCII debug string.
45+
///
46+
/// Non-ASCII characters are replaced by `?`. This version may be slightly
47+
/// faster than the Unicode version, as it avoids extra translation (due to
48+
/// Microsoft Unicode ineptness).
49+
#[allow(dead_code, reason = "Use Unicode version by default")]
50+
pub(crate) fn output_debug_string_a(msg: &str) {
3251
let now = time::OffsetDateTime::now_utc();
3352
let s = format!(
3453
"[ZF {:04}-{:02}-{:02}T{:02}:{:02}:{:02}.{:03}Z] {msg}\0",
@@ -41,27 +60,21 @@ pub(crate) fn encode_ascii(msg: &str) {
4160
now.millisecond(),
4261
);
4362

44-
let v: Vec<i8> = s
45-
.chars()
46-
.map(|c| {
47-
let b = if c.is_ascii() { c as u8 } else { b'?' };
48-
b as i8
49-
})
50-
.collect();
63+
let v: Vec<i8> = encode_ascii(&s);
5164
let p: *const i8 = v.as_ptr();
5265
unsafe { OutputDebugStringA(p) };
5366
// paranoia: ensure `s` is valid until after `OutputDebugStringA`
5467
drop(s);
5568
}
5669

5770
macro_rules! output {
58-
($fmt:literal $(, $args:expr)* $(,)?) => {{
71+
(a $fmt:literal $(, $args:expr)* $(,)?) => {{
5972
let msg: String = format!($fmt $(, $args)*);
60-
$crate::dbg::encode_ascii(&msg);
73+
$crate::dbg::output_debug_string_a(&msg);
6174
}};
62-
(u $fmt:literal $(, $args:expr)* $(,)?) => {{
75+
($fmt:literal $(, $args:expr)* $(,)?) => {{
6376
let msg: String = format!($fmt $(, $args)*);
64-
$crate::dbg::encode_unicode(&msg);
77+
$crate::dbg::output_debug_string_w(&msg);
6578
}};
6679
}
6780
pub(crate) use output;

0 commit comments

Comments
 (0)