Skip to content
This repository was archived by the owner on Mar 7, 2021. It is now read-only.

Commit fd0da95

Browse files
committed
Made the cstr!() macro usable in const contexts
1 parent 82a559c commit fd0da95

File tree

5 files changed

+59
-7
lines changed

5 files changed

+59
-7
lines changed

src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#![no_std]
2-
#![feature(allocator_api, alloc_error_handler, const_fn)]
2+
#![feature(allocator_api, alloc_error_handler, const_fn, const_raw_ptr_deref)]
33

44
extern crate alloc;
55

src/types.rs

+12-6
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,11 @@ impl Mode {
1818
pub struct CStr(str);
1919

2020
impl CStr {
21-
pub fn new(data: &str) -> &CStr {
22-
if data.bytes().position(|b| b == b'\x00') != Some(data.len() - 1) {
23-
panic!("CStr must contain a single NUL byte at the end");
24-
}
25-
unsafe { &*(data as *const str as *const CStr) }
21+
/// Creates a new CStr from a str without performing any additional checks. `data` _must_ end
22+
/// with a NUL byte, and should only have only a single NUL byte, or the string will be
23+
/// truncated.
24+
pub const unsafe fn new_unchecked(data: &str) -> &CStr {
25+
&*(data as *const str as *const CStr)
2626
}
2727
}
2828

@@ -34,9 +34,15 @@ impl Deref for CStr {
3434
}
3535
}
3636

37+
/// Creates a new `CStr` from a string literal. The string literal should not contain any NUL
38+
/// bytes. Example usage:
39+
/// ```
40+
/// const MY_CSTR: &CStr = cstr!("My awesome CStr!");
41+
/// ```
3742
#[macro_export]
3843
macro_rules! cstr {
3944
($str:expr) => {{
40-
$crate::CStr::new(concat!($str, "\x00"))
45+
let s = concat!($str, "\x00");
46+
unsafe { $crate::CStr::new_unchecked(s) }
4147
}};
4248
}

tests/utils/Cargo.toml

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
[package]
2+
name = "utils-tests"
3+
version = "0.1.0"
4+
authors = ["Alex Gaynor <[email protected]>", "Geoffrey Thomas <[email protected]>"]
5+
edition = "2018"
6+
7+
[lib]
8+
crate-type = ["staticlib"]
9+
test = false
10+
11+
[features]
12+
default = ["linux-kernel-module"]
13+
14+
[dependencies]
15+
linux-kernel-module = { path = "../..", optional = true }
16+
17+
[dev-dependencies]
18+
kernel-module-testlib = { path = "../../testlib" }

tests/utils/src/lib.rs

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
#![no_std]
2+
#![feature(const_str_as_bytes)]
3+
4+
use linux_kernel_module;
5+
6+
struct UtilsTestModule;
7+
8+
#[allow(dead_code)]
9+
const TEST_CSTR: &linux_kernel_module::CStr = linux_kernel_module::cstr!("abc");
10+
11+
impl linux_kernel_module::KernelModule for UtilsTestModule {
12+
fn init() -> linux_kernel_module::KernelResult<Self> {
13+
Ok(UtilsTestModule)
14+
}
15+
}
16+
17+
linux_kernel_module::kernel_module!(
18+
UtilsTestModule,
19+
author: "Fish in a Barrel Contributors",
20+
description: "A module for testing various utilities",
21+
license: "GPL"
22+
);

tests/utils/tests/tests.rs

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
use kernel_module_testlib::with_kernel_module;
2+
3+
#[test]
4+
fn test_module_loads() {
5+
with_kernel_module(|| {});
6+
}

0 commit comments

Comments
 (0)