Skip to content

Commit

Permalink
1. It is updated according to changes in the compiler Rust.
Browse files Browse the repository at this point in the history
2. Add edition=2018.
3. Documentation is updated.
4. The code of a plug-in is rewritten and optimized.
5. Examples 'use, panic' are rewritten, the example of benchmarking is added.
6. Updating of the license according to 2019, the English version of a name of the developer is added.
7. 'Travis.yml' fix, 'Cargo.toml' description corrected.
  • Loading branch information
denisandroid committed Mar 3, 2019
1 parent c0a9522 commit 52fffbb
Show file tree
Hide file tree
Showing 10 changed files with 726 additions and 536 deletions.
4 changes: 2 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ rust:
- nightly
matrix:
allow_failures:
- rust: nightly
- rust: nightly
script:
- cargo build --verbose
- cargo test --lib --verbose
- cargo test --verbose
5 changes: 3 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
[package]
name = "clucstr"
version = "0.1.6"
version = "0.1.7"
authors = ["Денис Котляров <#Ulin Project 18, denis2005991@gmail.com>"]
repository = "https://github.com/clucompany/cluCStr.git"
edition = "2018"

license = "Apache-2.0"
readme = "README.md"

description = "Creation of strings C with zero cost. A plug-in for the rust compiler."
description = "Safe creation of 'CStr' with zero cost at a compilation stage with check of zero bytes and a possibility of communication of several values."
keywords = ["cstr", "clucstr", "create_cstr", "clucompany"]
categories = ["development-tools::ffi"]

Expand Down
324 changes: 162 additions & 162 deletions LICENSE

Large diffs are not rendered by default.

190 changes: 101 additions & 89 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,13 @@
[![crates.io](http://meritbadge.herokuapp.com/clucstr)](https://crates.io/crates/clucstr)
[![Documentation](https://docs.rs/clucstr/badge.svg)](https://docs.rs/clucstr)

Creation of strings C with zero cost. A plug-in for the rust compiler.
Safe creation of 'CStr' with zero cost at a compilation stage with check of zero bytes and a possibility of communication of several values.

# Features
1. The transparent creation of the C strings with zero cost.
2. Check of the C lines at the level of the compiler.
3. Convenient macro for creation of lines.
4. Plug-in for the compiler.

1. Creation of safe CStr at a compilation stage.
2. Check of zero bytes at a stage of compilation or checks of "Rls or Rust check".
3. Concatenation of several values, different types: [u8], & 'static str, u8, i8, (0 without specifying the type).
4. All actions happen at a compilation stage, processor time is not required.

# Use
```
Expand All @@ -21,124 +20,137 @@ Creation of strings C with zero cost. A plug-in for the rust compiler.
use std::ffi::CStr;
fn main() {
let c_str = cstr!("cluWorld!!!");
let c_str_barr = cstr!(b"cluWorld!!!");
let c_str_b = cstr!(b'A');
}
```

```
#![feature(plugin)]
#![plugin(clucstr)]
use std::ffi::CStr;
fn main() {
println_str(cstr!("cluWorld!!!"));
//CSTR "cluWorld!!!"
//CArray [99, 108, 117, 87, 111, 114, 108, 100, 33, 33, 33, 0] 12
println_str(cstr!(b"cluWorld!!!"));
//CSTR "cluWorld!!!"
//CArray [99, 108, 117, 87, 111, 114, 108, 100, 33, 33, 33, 0] 12
println_str(cstr!(b'A'));
//CSTR "A"
//CArray [65, 0] 2
let c_str = cstr!("cluWorld");
//"cluWorld" <-- [99, 108, 117, 87, 111, 114, 108, 100, 0], len:9
let c_str2 = cstr!("cluWorld\0");
//"cluWorld" <-- [99, 108, 117, 87, 111, 114, 108, 100, 0], len:9
let c_str3 = cstr!("clu", b"World");
//"cluWorld" <-- [99, 108, 117, 87, 111, 114, 108, 100, 0], len:9
let c_str4 = cstr!(
b'c', b'l', b'u',
b'W', b'o', b'r', b'l', b'd',
0
);
//"cluWorld" <-- [99, 108, 117, 87, 111, 114, 108, 100, 0], len:9
let c_str5 = cstr!(
"clu",
//It is possible to insert such values as: [u8], & 'static str, u8, i8, (0 without specifying the type).
b'W', b'o', b'r', b'l', b"d\0"
//The zero byte is automatically added, it is possible to write it, and it is possible not to write.
//It is forbidden to insert zero byte in the middle or at the beginning of a line.
);
//"cluWorld" <-- [99, 108, 117, 87, 111, 114, 108, 100, 0], len:9
my_function(c_str);
my_function(c_str2);
my_function(c_str3);
my_function(c_str4);
my_function(c_str5);
}
fn println_str(cstr: &CStr) {
println!("CSTR {:?}", cstr);
let cstr_array = cstr.to_bytes_with_nul();
println!("CArray {:?} {}", cstr_array, cstr_array.len());
println!();
fn my_function(a: &'static CStr) {
//'static --> it is possible not to write.
let c_arr = a.to_bytes_with_nul();
println!("{:?} <-- array: {:?}, len: {}", a, c_arr, c_arr.len());
}
```

# Panic
```
#![feature(plugin)]
#![plugin(clucstr)]
#[allow(unused_imports)]
use std::ffi::CStr;
fn main() {
let c_str = cstr!("\0Test_str");
// PANIC! A null byte was found.
//let c_str = cstr!("cluW\0orld");
//PANIC! trailing byte detected
let c_str = cstr!(b"\0Test_array");
// PANIC! A null byte was found.
//let c_str2 = cstr!("cluWorld\0\0");
//PANIC! trailing byte detected
let c_str = cstr!("Test_str\0");
//It is allowed to write since the null byte is at the end.
//let c_str3 = cstr!("\0clu", b"W\0orld");
//PANIC! trailing byte detected
let c_str = cstr!(b"Test_str\0");
//It is allowed to write since the null byte is at the end.
/*let c_str4 = cstr!(
b'c', b'l', b'u', 0u8,
b'W', b'o', b'r', b'l', b'd',
0
);*/
//PANIC! trailing byte detected
}
```

# Benchmarking
cstr_macros - old method of converting strings to cstr. Note that in CStr, there is no protection from null bytes.

cstr_plugin - new method for converting strings to cstr.
```
#![feature(plugin)]
#![plugin(clucstr)]
#![feature(test)]
extern crate test;
use std::ffi::CStr;
#[macro_export]
macro_rules! cstr_macro {
($s:expr) => {
unsafe {
::std::ffi::CStr::from_ptr(
concat!($s, "\0")
as *const str
as *const [::std::os::raw::c_char]
as *const ::std::os::raw::c_char
)
}
};
}
#![feature(plugin)]
#![plugin(clucstr)]
#[cfg(test)]
mod tests {
use super::*;
use test::Bencher;
#[bench]
fn cstr_plugin(b: &mut Bencher) {
b.iter(|| {
for _a in 0..10 {
let _cstr0 = cstr!(b"test");
}
});
}
#[bench]
fn cstr_macros(b: &mut Bencher) {
b.iter(|| {
for _a in 0..10 {
let _cstr0 = cstr_macro!("test");
}
});
}
use super::*;
use tests::test::Bencher;
use std::ffi::CStr;
extern crate test;
macro_rules! unsafe_cstr {
($s:expr) => {
unsafe {
::std::ffi::CStr::from_ptr(
concat!($s, "\0")
as *const str
as *const [::std::os::raw::c_char]
as *const ::std::os::raw::c_char
)
}
};
}
#[bench]
fn cstr_plugin(b: &mut Bencher) {
b.iter(|| {
for _a in 0..10 {
let _cstr0 = cstr!(b"test");
}
});
}
#[bench]
fn cstr_macros(b: &mut Bencher) {
b.iter(|| {
for _a in 0..10 {
let _cstr0 = unsafe_cstr!("test");
}
});
}
}
```
running 2 tests

test tests::cstr_macros ... bench: 90 ns/iter (+/- 14)
test tests::cstr_macros ... bench: 67 ns/iter (+/- 1) !Attention ns > 0, full unsafe, no guarantees

test tests::cstr_plugin ... bench: 0 ns/iter (+/- 0) !Attention ns == 0, plus zero byte checking and plus concatenation

test tests::cstr_plugin ... bench: 0 ns/iter (+/- 0)
# Launch benchmark:

cargo bench --example bench

# License

Copyright 2018 #UlinProject Денис Котляров
Copyright 2019 #UlinProject Denis Kotlyarov (Денис Котляров)

Licensed under the Apache License, Version 2.0
Licensed under the Apache License, Version 2.0
49 changes: 49 additions & 0 deletions examples/bench.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@


//RUN cargo bench --example bench
#![feature(test)]

#![feature(plugin)]
#![plugin(clucstr)]


#[cfg(test)]
mod tests {
use super::*;
use tests::test::Bencher;
use std::ffi::CStr;

extern crate test;



macro_rules! unsafe_cstr {
($s:expr) => {
unsafe {
::std::ffi::CStr::from_ptr(
concat!($s, "\0")
as *const str
as *const [::std::os::raw::c_char]
as *const ::std::os::raw::c_char
)
}
};
}

#[bench]
fn cstr_plugin(b: &mut Bencher) {
b.iter(|| {
for _a in 0..10 {
let _cstr0 = cstr!(b"test");
}
});
}
#[bench]
fn cstr_macros(b: &mut Bencher) {
b.iter(|| {
for _a in 0..10 {
let _cstr0 = unsafe_cstr!("test");
}
});
}
}
28 changes: 28 additions & 0 deletions examples/panic.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@

#![feature(plugin)]
#![plugin(clucstr)]

#[allow(unused_imports)]
use std::ffi::CStr;

//ATTENTION!!!
//
//For display of panic 'RLS or Rust Check' it is required to uncomment functions.

fn main() {
//let c_str = cstr!("cluW\0orld");
//PANIC! trailing byte detected

//let c_str2 = cstr!("cluWorld\0\0");
//PANIC! trailing byte detected

//let c_str3 = cstr!("\0clu", b"W\0orld");
//PANIC! trailing byte detected

/*let c_str4 = cstr!(
b'c', b'l', b'u', 0u8,
b'W', b'o', b'r', b'l', b'd',
0
);*/
//PANIC! trailing byte detected
}
39 changes: 35 additions & 4 deletions examples/use.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,42 @@
use std::ffi::CStr;

fn main() {
let c_str = cstr!(12u8);
let c_str = cstr!("cluWorld");
//"cluWorld" <-- [99, 108, 117, 87, 111, 114, 108, 100, 0], len:9

my_function(c_str);
let c_str2 = cstr!("cluWorld\0");
//"cluWorld" <-- [99, 108, 117, 87, 111, 114, 108, 100, 0], len:9

let c_str3 = cstr!("clu", b"World");
//"cluWorld" <-- [99, 108, 117, 87, 111, 114, 108, 100, 0], len:9

let c_str4 = cstr!(
b'c', b'l', b'u',
b'W', b'o', b'r', b'l', b'd',
0
);
//"cluWorld" <-- [99, 108, 117, 87, 111, 114, 108, 100, 0], len:9

let c_str5 = cstr!(
"clu",
//It is possible to insert such values as: [u8], & 'static str, u8, i8, (0 without specifying the type).

b'W', b'o', b'r', b'l', b"d\0"
//The zero byte is automatically added, it is possible to write it, and it is possible not to write.
//It is forbidden to insert zero byte in the middle or at the beginning of a line.
);
//"cluWorld" <-- [99, 108, 117, 87, 111, 114, 108, 100, 0], len:9

my_function(c_str);
my_function(c_str2);
my_function(c_str3);
my_function(c_str4);
my_function(c_str5);
}

fn my_function<A: AsRef<CStr>>(a: A) {
println!("{:?}", a.as_ref());
fn my_function(a: &'static CStr) {
//'static --> it is possible not to write.

let c_arr = a.to_bytes_with_nul();
println!("{:?} <-- array: {:?}, len: {}", a, c_arr, c_arr.len());
}
Loading

0 comments on commit 52fffbb

Please sign in to comment.