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

Commit

Permalink
Made the cstr!() macro usable in const contexts
Browse files Browse the repository at this point in the history
  • Loading branch information
alex committed Sep 22, 2019
1 parent 82a559c commit fd0da95
Show file tree
Hide file tree
Showing 5 changed files with 59 additions and 7 deletions.
2 changes: 1 addition & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#![no_std]
#![feature(allocator_api, alloc_error_handler, const_fn)]
#![feature(allocator_api, alloc_error_handler, const_fn, const_raw_ptr_deref)]

extern crate alloc;

Expand Down
18 changes: 12 additions & 6 deletions src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,11 @@ impl Mode {
pub struct CStr(str);

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

Expand All @@ -34,9 +34,15 @@ impl Deref for CStr {
}
}

/// Creates a new `CStr` from a string literal. The string literal should not contain any NUL
/// bytes. Example usage:
/// ```
/// const MY_CSTR: &CStr = cstr!("My awesome CStr!");
/// ```
#[macro_export]
macro_rules! cstr {
($str:expr) => {{
$crate::CStr::new(concat!($str, "\x00"))
let s = concat!($str, "\x00");
unsafe { $crate::CStr::new_unchecked(s) }
}};
}
18 changes: 18 additions & 0 deletions tests/utils/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
[package]
name = "utils-tests"
version = "0.1.0"
authors = ["Alex Gaynor <[email protected]>", "Geoffrey Thomas <[email protected]>"]
edition = "2018"

[lib]
crate-type = ["staticlib"]
test = false

[features]
default = ["linux-kernel-module"]

[dependencies]
linux-kernel-module = { path = "../..", optional = true }

[dev-dependencies]
kernel-module-testlib = { path = "../../testlib" }
22 changes: 22 additions & 0 deletions tests/utils/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#![no_std]
#![feature(const_str_as_bytes)]

use linux_kernel_module;

struct UtilsTestModule;

#[allow(dead_code)]
const TEST_CSTR: &linux_kernel_module::CStr = linux_kernel_module::cstr!("abc");

impl linux_kernel_module::KernelModule for UtilsTestModule {
fn init() -> linux_kernel_module::KernelResult<Self> {
Ok(UtilsTestModule)
}
}

linux_kernel_module::kernel_module!(
UtilsTestModule,
author: "Fish in a Barrel Contributors",
description: "A module for testing various utilities",
license: "GPL"
);
6 changes: 6 additions & 0 deletions tests/utils/tests/tests.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
use kernel_module_testlib::with_kernel_module;

#[test]
fn test_module_loads() {
with_kernel_module(|| {});
}

0 comments on commit fd0da95

Please sign in to comment.