Skip to content

Commit 52fffbb

Browse files
committed
1. It is updated according to changes in the compiler Rust.
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.
1 parent c0a9522 commit 52fffbb

File tree

10 files changed

+726
-536
lines changed

10 files changed

+726
-536
lines changed

.travis.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ rust:
44
- nightly
55
matrix:
66
allow_failures:
7-
- rust: nightly
7+
- rust: nightly
88
script:
99
- cargo build --verbose
10-
- cargo test --lib --verbose
10+
- cargo test --verbose

Cargo.toml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
[package]
22
name = "clucstr"
3-
version = "0.1.6"
3+
version = "0.1.7"
44
authors = ["Денис Котляров <#Ulin Project 18, denis2005991@gmail.com>"]
55
repository = "https://github.com/clucompany/cluCStr.git"
6+
edition = "2018"
67

78
license = "Apache-2.0"
89
readme = "README.md"
910

10-
description = "Creation of strings C with zero cost. A plug-in for the rust compiler."
11+
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."
1112
keywords = ["cstr", "clucstr", "create_cstr", "clucompany"]
1213
categories = ["development-tools::ffi"]
1314

LICENSE

Lines changed: 162 additions & 162 deletions
Large diffs are not rendered by default.

README.md

Lines changed: 101 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,13 @@
44
[![crates.io](http://meritbadge.herokuapp.com/clucstr)](https://crates.io/crates/clucstr)
55
[![Documentation](https://docs.rs/clucstr/badge.svg)](https://docs.rs/clucstr)
66

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

99
# Features
10-
1. The transparent creation of the C strings with zero cost.
11-
2. Check of the C lines at the level of the compiler.
12-
3. Convenient macro for creation of lines.
13-
4. Plug-in for the compiler.
14-
10+
1. Creation of safe CStr at a compilation stage.
11+
2. Check of zero bytes at a stage of compilation or checks of "Rls or Rust check".
12+
3. Concatenation of several values, different types: [u8], & 'static str, u8, i8, (0 without specifying the type).
13+
4. All actions happen at a compilation stage, processor time is not required.
1514

1615
# Use
1716
```
@@ -21,124 +20,137 @@ Creation of strings C with zero cost. A plug-in for the rust compiler.
2120
use std::ffi::CStr;
2221
2322
fn main() {
24-
let c_str = cstr!("cluWorld!!!");
25-
let c_str_barr = cstr!(b"cluWorld!!!");
26-
let c_str_b = cstr!(b'A');
27-
}
28-
```
29-
30-
```
31-
#![feature(plugin)]
32-
#![plugin(clucstr)]
33-
34-
use std::ffi::CStr;
35-
36-
fn main() {
37-
println_str(cstr!("cluWorld!!!"));
38-
//CSTR "cluWorld!!!"
39-
//CArray [99, 108, 117, 87, 111, 114, 108, 100, 33, 33, 33, 0] 12
40-
41-
println_str(cstr!(b"cluWorld!!!"));
42-
//CSTR "cluWorld!!!"
43-
//CArray [99, 108, 117, 87, 111, 114, 108, 100, 33, 33, 33, 0] 12
44-
45-
println_str(cstr!(b'A'));
46-
//CSTR "A"
47-
//CArray [65, 0] 2
23+
let c_str = cstr!("cluWorld");
24+
//"cluWorld" <-- [99, 108, 117, 87, 111, 114, 108, 100, 0], len:9
25+
26+
let c_str2 = cstr!("cluWorld\0");
27+
//"cluWorld" <-- [99, 108, 117, 87, 111, 114, 108, 100, 0], len:9
28+
29+
let c_str3 = cstr!("clu", b"World");
30+
//"cluWorld" <-- [99, 108, 117, 87, 111, 114, 108, 100, 0], len:9
31+
32+
let c_str4 = cstr!(
33+
b'c', b'l', b'u',
34+
b'W', b'o', b'r', b'l', b'd',
35+
0
36+
);
37+
//"cluWorld" <-- [99, 108, 117, 87, 111, 114, 108, 100, 0], len:9
38+
39+
let c_str5 = cstr!(
40+
"clu",
41+
//It is possible to insert such values as: [u8], & 'static str, u8, i8, (0 without specifying the type).
42+
43+
b'W', b'o', b'r', b'l', b"d\0"
44+
//The zero byte is automatically added, it is possible to write it, and it is possible not to write.
45+
//It is forbidden to insert zero byte in the middle or at the beginning of a line.
46+
);
47+
//"cluWorld" <-- [99, 108, 117, 87, 111, 114, 108, 100, 0], len:9
48+
49+
my_function(c_str);
50+
my_function(c_str2);
51+
my_function(c_str3);
52+
my_function(c_str4);
53+
my_function(c_str5);
4854
}
4955
50-
51-
fn println_str(cstr: &CStr) {
52-
println!("CSTR {:?}", cstr);
53-
54-
let cstr_array = cstr.to_bytes_with_nul();
55-
println!("CArray {:?} {}", cstr_array, cstr_array.len());
56-
println!();
56+
fn my_function(a: &'static CStr) {
57+
//'static --> it is possible not to write.
58+
59+
let c_arr = a.to_bytes_with_nul();
60+
println!("{:?} <-- array: {:?}, len: {}", a, c_arr, c_arr.len());
5761
}
5862
```
5963

6064
# Panic
6165
```
66+
6267
#![feature(plugin)]
6368
#![plugin(clucstr)]
6469
70+
#[allow(unused_imports)]
6571
use std::ffi::CStr;
6672
6773
fn main() {
68-
let c_str = cstr!("\0Test_str");
69-
// PANIC! A null byte was found.
74+
//let c_str = cstr!("cluW\0orld");
75+
//PANIC! trailing byte detected
7076
71-
let c_str = cstr!(b"\0Test_array");
72-
// PANIC! A null byte was found.
77+
//let c_str2 = cstr!("cluWorld\0\0");
78+
//PANIC! trailing byte detected
7379
74-
let c_str = cstr!("Test_str\0");
75-
//It is allowed to write since the null byte is at the end.
80+
//let c_str3 = cstr!("\0clu", b"W\0orld");
81+
//PANIC! trailing byte detected
7682
77-
let c_str = cstr!(b"Test_str\0");
78-
//It is allowed to write since the null byte is at the end.
83+
/*let c_str4 = cstr!(
84+
b'c', b'l', b'u', 0u8,
85+
b'W', b'o', b'r', b'l', b'd',
86+
0
87+
);*/
88+
//PANIC! trailing byte detected
7989
}
8090
```
8191

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

85-
cstr_plugin - new method for converting strings to cstr.
8694
```
87-
#![feature(plugin)]
88-
#![plugin(clucstr)]
8995
#![feature(test)]
9096
91-
extern crate test;
92-
use std::ffi::CStr;
93-
94-
95-
#[macro_export]
96-
macro_rules! cstr_macro {
97-
($s:expr) => {
98-
unsafe {
99-
::std::ffi::CStr::from_ptr(
100-
concat!($s, "\0")
101-
as *const str
102-
as *const [::std::os::raw::c_char]
103-
as *const ::std::os::raw::c_char
104-
)
105-
}
106-
};
107-
}
97+
#![feature(plugin)]
98+
#![plugin(clucstr)]
10899
109100
110101
#[cfg(test)]
111102
mod tests {
112-
use super::*;
113-
use test::Bencher;
114-
115-
#[bench]
116-
fn cstr_plugin(b: &mut Bencher) {
117-
b.iter(|| {
118-
for _a in 0..10 {
119-
let _cstr0 = cstr!(b"test");
120-
}
121-
});
122-
}
123-
#[bench]
124-
fn cstr_macros(b: &mut Bencher) {
125-
b.iter(|| {
126-
for _a in 0..10 {
127-
let _cstr0 = cstr_macro!("test");
128-
}
129-
});
130-
}
103+
use super::*;
104+
use tests::test::Bencher;
105+
use std::ffi::CStr;
106+
107+
extern crate test;
108+
109+
110+
111+
macro_rules! unsafe_cstr {
112+
($s:expr) => {
113+
unsafe {
114+
::std::ffi::CStr::from_ptr(
115+
concat!($s, "\0")
116+
as *const str
117+
as *const [::std::os::raw::c_char]
118+
as *const ::std::os::raw::c_char
119+
)
120+
}
121+
};
122+
}
123+
124+
#[bench]
125+
fn cstr_plugin(b: &mut Bencher) {
126+
b.iter(|| {
127+
for _a in 0..10 {
128+
let _cstr0 = cstr!(b"test");
129+
}
130+
});
131+
}
132+
#[bench]
133+
fn cstr_macros(b: &mut Bencher) {
134+
b.iter(|| {
135+
for _a in 0..10 {
136+
let _cstr0 = unsafe_cstr!("test");
137+
}
138+
});
139+
}
131140
}
132141
```
133142
running 2 tests
134143

135-
test tests::cstr_macros ... bench: 90 ns/iter (+/- 14)
144+
test tests::cstr_macros ... bench: 67 ns/iter (+/- 1) !Attention ns > 0, full unsafe, no guarantees
145+
146+
test tests::cstr_plugin ... bench: 0 ns/iter (+/- 0) !Attention ns == 0, plus zero byte checking and plus concatenation
136147

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

150+
cargo bench --example bench
139151

140152
# License
141153

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

144-
Licensed under the Apache License, Version 2.0
156+
Licensed under the Apache License, Version 2.0

examples/bench.rs

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
2+
3+
//RUN cargo bench --example bench
4+
#![feature(test)]
5+
6+
#![feature(plugin)]
7+
#![plugin(clucstr)]
8+
9+
10+
#[cfg(test)]
11+
mod tests {
12+
use super::*;
13+
use tests::test::Bencher;
14+
use std::ffi::CStr;
15+
16+
extern crate test;
17+
18+
19+
20+
macro_rules! unsafe_cstr {
21+
($s:expr) => {
22+
unsafe {
23+
::std::ffi::CStr::from_ptr(
24+
concat!($s, "\0")
25+
as *const str
26+
as *const [::std::os::raw::c_char]
27+
as *const ::std::os::raw::c_char
28+
)
29+
}
30+
};
31+
}
32+
33+
#[bench]
34+
fn cstr_plugin(b: &mut Bencher) {
35+
b.iter(|| {
36+
for _a in 0..10 {
37+
let _cstr0 = cstr!(b"test");
38+
}
39+
});
40+
}
41+
#[bench]
42+
fn cstr_macros(b: &mut Bencher) {
43+
b.iter(|| {
44+
for _a in 0..10 {
45+
let _cstr0 = unsafe_cstr!("test");
46+
}
47+
});
48+
}
49+
}

examples/panic.rs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
2+
#![feature(plugin)]
3+
#![plugin(clucstr)]
4+
5+
#[allow(unused_imports)]
6+
use std::ffi::CStr;
7+
8+
//ATTENTION!!!
9+
//
10+
//For display of panic 'RLS or Rust Check' it is required to uncomment functions.
11+
12+
fn main() {
13+
//let c_str = cstr!("cluW\0orld");
14+
//PANIC! trailing byte detected
15+
16+
//let c_str2 = cstr!("cluWorld\0\0");
17+
//PANIC! trailing byte detected
18+
19+
//let c_str3 = cstr!("\0clu", b"W\0orld");
20+
//PANIC! trailing byte detected
21+
22+
/*let c_str4 = cstr!(
23+
b'c', b'l', b'u', 0u8,
24+
b'W', b'o', b'r', b'l', b'd',
25+
0
26+
);*/
27+
//PANIC! trailing byte detected
28+
}

examples/use.rs

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,42 @@
55
use std::ffi::CStr;
66

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

10-
my_function(c_str);
11+
let c_str2 = cstr!("cluWorld\0");
12+
//"cluWorld" <-- [99, 108, 117, 87, 111, 114, 108, 100, 0], len:9
13+
14+
let c_str3 = cstr!("clu", b"World");
15+
//"cluWorld" <-- [99, 108, 117, 87, 111, 114, 108, 100, 0], len:9
16+
17+
let c_str4 = cstr!(
18+
b'c', b'l', b'u',
19+
b'W', b'o', b'r', b'l', b'd',
20+
0
21+
);
22+
//"cluWorld" <-- [99, 108, 117, 87, 111, 114, 108, 100, 0], len:9
23+
24+
let c_str5 = cstr!(
25+
"clu",
26+
//It is possible to insert such values as: [u8], & 'static str, u8, i8, (0 without specifying the type).
27+
28+
b'W', b'o', b'r', b'l', b"d\0"
29+
//The zero byte is automatically added, it is possible to write it, and it is possible not to write.
30+
//It is forbidden to insert zero byte in the middle or at the beginning of a line.
31+
);
32+
//"cluWorld" <-- [99, 108, 117, 87, 111, 114, 108, 100, 0], len:9
33+
34+
my_function(c_str);
35+
my_function(c_str2);
36+
my_function(c_str3);
37+
my_function(c_str4);
38+
my_function(c_str5);
1139
}
1240

13-
fn my_function<A: AsRef<CStr>>(a: A) {
14-
println!("{:?}", a.as_ref());
41+
fn my_function(a: &'static CStr) {
42+
//'static --> it is possible not to write.
43+
44+
let c_arr = a.to_bytes_with_nul();
45+
println!("{:?} <-- array: {:?}, len: {}", a, c_arr, c_arr.len());
1546
}

0 commit comments

Comments
 (0)