Skip to content

Commit

Permalink
1. Fix translate
Browse files Browse the repository at this point in the history
2. General transformation
3. Fix Cargo.toml
  • Loading branch information
denisandroid committed Nov 10, 2018
1 parent 53af08a commit c0a9522
Show file tree
Hide file tree
Showing 5 changed files with 230 additions and 199 deletions.
10 changes: 5 additions & 5 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
[package]
name = "clucstr"
version = "0.1.4"
version = "0.1.6"
authors = ["Денис Котляров <#Ulin Project 18, denis2005991@gmail.com>"]
repository = "https://github.com/clucompany/cluCStr.git"

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

description = "Creation of CStr with zero cost. Plugin for rust compiler."
keywords = ["cstr", "clucstr", "clucompany"]
description = "Creation of strings C with zero cost. A plug-in for the rust compiler."
keywords = ["cstr", "clucstr", "create_cstr", "clucompany"]
categories = ["development-tools::ffi"]

[features]

[lib]
name = "clucstr"
crate-type = ["dylib", "rlib"]
plugin = true

[dependencies]
8 changes: 7 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +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)

Secure creation of CStr with zero cost. Plugin for rust compiler.
Creation of strings C with zero cost. A plug-in for the rust compiler.

# 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.


# Use
Expand Down
15 changes: 15 additions & 0 deletions examples/use.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@

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

use std::ffi::CStr;

fn main() {
let c_str = cstr!(12u8);

my_function(c_str);
}

fn my_function<A: AsRef<CStr>>(a: A) {
println!("{:?}", a.as_ref());
}
209 changes: 16 additions & 193 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,15 @@
//

/*!
Secure creation of CStr with zero cost. Plugin for rust compiler.
Creation of strings C with zero cost. A plug-in for the rust compiler.
# 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.
# Use
```
Expand Down Expand Up @@ -142,201 +150,16 @@ test tests::cstr_macros ... bench: 90 ns/iter (+/- 14)
test tests::cstr_plugin ... bench: 0 ns/iter (+/- 0)
*/
#![feature(plugin_registrar, rustc_private)]
#![feature(i128_type)]

extern crate syntax;
extern crate rustc;
extern crate rustc_plugin;

use syntax::tokenstream::TokenTree;
use syntax::ext::base::{ExtCtxt, MacResult, DummyResult, MacEager};
use syntax::ext::build::AstBuilder;
use syntax::ext::quote::rt::Span;
use rustc_plugin::Registry;
use syntax::ast::ExprKind;
use syntax::ast::LitKind;
use syntax::ast::Mutability;
use syntax::ast::LitIntType;
use syntax::ast::TyKind;
use syntax::ast::UintTy;
use syntax::ast::UnOp;
use syntax::ast::BlockCheckMode;
use syntax::ast::UnsafeSource;
use syntax::ast::Block;
use syntax::ptr::P;
use syntax::ast;

///Secure creation of CStr with zero cost
//Required for docks!!!!!
#[macro_export]
macro_rules! cstr {
($s:expr) => {};
}
//Required for docks!!!!!


#[doc(hidden)]
#[plugin_registrar]
pub fn plugin_registrar(reg: &mut Registry) {
reg.register_macro("cstr", cstr);
}

#[doc(hidden)]
pub fn cstr(cx: &mut ExtCtxt, sp: Span, args: &[TokenTree]) -> Box<MacResult + 'static> {
let mut parser = cx.new_parser_from_tts(args);

let expr = match parser.parse_expr() {
Ok(a) => a,
Err(_e) => {
cx.span_err(sp, "cstr currently only supports one argument");
return DummyResult::any(sp);
}
};

let c_array = {
let mut add_null = true;

let mut array = match expr.node {
ExprKind::Lit(ref l) => {
//println!("{:?}", l.node);
match l.node {
LitKind::Str(s, _) => {
let s = s.to_string();
let array = s.as_bytes();
let array_len = array.len();

let mut vec_result = Vec::with_capacity(array_len);

for (num, a) in array.iter().enumerate() {
if *a == 0 {
match num+1 == array_len {
true => add_null = false,
_ => {
cx.span_err(sp, "the string has a null byte");
return DummyResult::any(sp);
},
}
}
vec_result.push(
cx.expr_lit(sp,
LitKind::Int(*a as u128, LitIntType::Unsigned(UintTy::U8)),
)
);
}
vec_result
},
LitKind::ByteStr(ref array) => {
let array_len = array.len();
let mut vec_result = Vec::with_capacity(array.len());

for (num, a) in array.iter().enumerate() {
if *a == 0 {
match num+1 == array_len {
true => add_null = false,
_ => {
cx.span_err(sp, "the string has a null byte");
return DummyResult::any(sp);
},
}
}
vec_result.push(
cx.expr_lit(sp,
LitKind::Int(*a as u128, LitIntType::Unsigned(UintTy::U8)),
)
);
}
vec_result
},
LitKind::Byte(ref a) => {
if *a == 0 {
add_null = false;
}
vec!(
cx.expr_lit(sp,
LitKind::Int(*a as u128, LitIntType::Unsigned(UintTy::U8)),
)
)
}
_ => {
cx.span_err(sp, "argument should be a single identifier");
return DummyResult::any(sp);
}

}
},
_ => {
cx.span_err(sp, "argument should be a single identifier");
return DummyResult::any(sp);
}
};

if add_null {
array.reserve(1);
array.push(
cx.expr_lit(sp,
LitKind::Int(0, LitIntType::Unsigned(UintTy::U8)),
)
);
}

cx.expr(
sp,
ExprKind::AddrOf(Mutability::Immutable,
cx.expr(sp, ExprKind::Array(array)) //[u8]
) // &[u8]
)
};

let c_array = cx.expr_cast(
sp,
c_array, //[u8]
cx.ty_ptr(sp, // -> *const [u8]
cx.ty(sp, TyKind::Slice(
cx.ty_ident(sp, cx.ident_of("u8"))
)), // P<TY>

Mutability::Immutable // const
)
);// &[u8] as *const [u8]

let c_cstr = cx.expr_cast(
sp,
c_array, //[i8]
cx.ty_ptr(sp, // -> *const [i8]
cx.ty_ident(sp, cx.ident_of("CStr")),

Mutability::Immutable // const
)
); // as *const CSTR

let c_cstr = cx.expr_unary(sp, UnOp::Deref, c_cstr);
//*([u8] as *const [u8] as *const CStr)

let c_cstr = cx.expr(sp, ExprKind::AddrOf(Mutability::Immutable, c_cstr));
//&*([u8] as *const [u8] as *const CStr)

let block = {
let vec_stmts = vec!(
cx.stmt_expr(c_cstr)
);
let mut block = P(Block {
stmts: vec_stmts,
id: ast::DUMMY_NODE_ID,
rules: BlockCheckMode::Unsafe(UnsafeSource::CompilerGenerated),
span: sp,
recovered: false,

});
cx.expr_block(block)
};// unsafe { &*([u8] as *const [u8] as *const CStr) }


MacEager::expr(
block
)
}
#![feature(plugin_registrar)]
#![feature(rustc_private)]


extern crate syntax;
extern crate rustc;
extern crate rustc_plugin;


mod nightly;
pub use self::nightly::*;
Loading

0 comments on commit c0a9522

Please sign in to comment.