Skip to content

Commit

Permalink
Merge pull request torvalds#664 from wedsonaf/writer-move
Browse files Browse the repository at this point in the history
rust: move `Writer` to the `str` module and rename it to `Formatter`
  • Loading branch information
wedsonaf authored Feb 8, 2022
2 parents eb2238d + f56f670 commit 807abc2
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 35 deletions.
37 changes: 2 additions & 35 deletions rust/kernel/print.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,50 +6,17 @@
//!
//! Reference: <https://www.kernel.org/doc/html/latest/core-api/printk-basics.html>

use core::cmp;
use core::fmt;

use crate::bindings;
use crate::c_types::{c_char, c_void};
use crate::{bindings, str::Formatter};

// Called from `vsprintf` with format specifier `%pA`.
#[no_mangle]
unsafe fn rust_fmt_argument(buf: *mut c_char, end: *mut c_char, ptr: *const c_void) -> *mut c_char {
use fmt::Write;

// Use `usize` to use `saturating_*` functions.
struct Writer {
buf: usize,
end: usize,
}

impl Write for Writer {
fn write_str(&mut self, s: &str) -> fmt::Result {
// `buf` value after writing `len` bytes. This does not have to be bounded
// by `end`, but we don't want it to wrap around to 0.
let buf_new = self.buf.saturating_add(s.len());

// Amount that we can copy. `saturating_sub` ensures we get 0 if
// `buf` goes past `end`.
let len_to_copy = cmp::min(buf_new, self.end).saturating_sub(self.buf);

// SAFETY: In any case, `buf` is non-null and properly aligned.
// If `len_to_copy` is non-zero, then we know `buf` has not past
// `end` yet and so is valid.
unsafe {
core::ptr::copy_nonoverlapping(
s.as_bytes().as_ptr(),
self.buf as *mut u8,
len_to_copy,
)
};

self.buf = buf_new;
Ok(())
}
}

let mut w = Writer {
let mut w = Formatter {
buf: buf as _,
end: end as _,
};
Expand Down
26 changes: 26 additions & 0 deletions rust/kernel/str.rs
Original file line number Diff line number Diff line change
Expand Up @@ -373,3 +373,29 @@ mod tests {
assert_eq!(unchecked_str, "🐧");
}
}

// Use `usize` to use `saturating_*` functions.
pub(crate) struct Formatter {
pub(crate) buf: usize,
pub(crate) end: usize,
}

impl fmt::Write for Formatter {
fn write_str(&mut self, s: &str) -> fmt::Result {
// `buf` value after writing `len` bytes. This does not have to be bounded by `end`, but we
// don't want it to wrap around to 0.
let buf_new = self.buf.saturating_add(s.len());

// Amount that we can copy. `saturating_sub` ensures we get 0 if `buf` goes past `end`.
let len_to_copy = core::cmp::min(buf_new, self.end).saturating_sub(self.buf);

// SAFETY: In any case, `buf` is non-null and properly aligned. If `len_to_copy` is
// non-zero, then we know `buf` has not past `end` yet and so is valid.
unsafe {
core::ptr::copy_nonoverlapping(s.as_bytes().as_ptr(), self.buf as *mut u8, len_to_copy)
};

self.buf = buf_new;
Ok(())
}
}

0 comments on commit 807abc2

Please sign in to comment.