Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
- Fixup: Specify exports via [Module-Definition (.Def)
file](https://learn.microsoft.com/en-us/cpp/build/reference/module-definition-dot-def-files).
- Fixup: Now builds using either `i686-pc-windows-gnu` or `i686-pc-windows-msvc`.
- Fixup: `output!` macro uses Unicode/`OutputDebugStringW` by default.

- Project: Update Rust version to 1.88.0 and edition to 2024. This moves off
nightly, since everything we need is now stabilised, and should help with
Expand Down
6 changes: 3 additions & 3 deletions crates/export-check/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
let (expected_exports, expected_forwards) = parse_def_file()?;

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

let contents = std::fs::read(path)?;
let data = contents.as_slice();
Expand Down Expand Up @@ -115,11 +115,11 @@ fn validate_exports(
exports.sort();
forwards.sort();

for name in exports.iter().copied() {
for name in exports {
println!("{name}");
}

for forward in forwards.iter().copied() {
for forward in forwards {
println!("{forward}");
}

Expand Down
1 change: 1 addition & 0 deletions crates/zipfixup/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ fn main() {
println!("cargo::warning={path}");
println!("cargo::rerun-if-changed={path}");

#[allow(clippy::wildcard_in_or_patterns)]
match env.as_str() {
"gnu" => {
println!("cargo::rustc-link-arg-cdylib={path}");
Expand Down
55 changes: 34 additions & 21 deletions crates/zipfixup/src/dbg.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,18 @@
use ::winapi::um::debugapi::{OutputDebugStringA, OutputDebugStringW};

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

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

pub(crate) fn encode_ascii(msg: &str) {
fn encode_ascii(s: &str) -> Vec<i8> {
s.chars()
.map(|c| {
let b = if c.is_ascii() { c as u8 } else { b'?' };
b as i8
})
.collect()
}

/// Output an ASCII debug string.
///
/// Non-ASCII characters are replaced by `?`. This version may be slightly
/// faster than the Unicode version, as it avoids extra translation (due to
/// Microsoft Unicode ineptness).
#[allow(dead_code, reason = "Use Unicode version by default")]
pub(crate) fn output_debug_string_a(msg: &str) {
let now = time::OffsetDateTime::now_utc();
let s = format!(
"[ZF {:04}-{:02}-{:02}T{:02}:{:02}:{:02}.{:03}Z] {msg}\0",
Expand All @@ -41,27 +60,21 @@ pub(crate) fn encode_ascii(msg: &str) {
now.millisecond(),
);

let v: Vec<i8> = s
.chars()
.map(|c| {
let b = if c.is_ascii() { c as u8 } else { b'?' };
b as i8
})
.collect();
let v: Vec<i8> = encode_ascii(&s);
let p: *const i8 = v.as_ptr();
unsafe { OutputDebugStringA(p) };
// paranoia: ensure `s` is valid until after `OutputDebugStringA`
drop(s);
}

macro_rules! output {
($fmt:literal $(, $args:expr)* $(,)?) => {{
(a $fmt:literal $(, $args:expr)* $(,)?) => {{
let msg: String = format!($fmt $(, $args)*);
$crate::dbg::encode_ascii(&msg);
$crate::dbg::output_debug_string_a(&msg);
}};
(u $fmt:literal $(, $args:expr)* $(,)?) => {{
($fmt:literal $(, $args:expr)* $(,)?) => {{
let msg: String = format!($fmt $(, $args)*);
$crate::dbg::encode_unicode(&msg);
$crate::dbg::output_debug_string_w(&msg);
}};
}
pub(crate) use output;