|
17 | 17 | //
|
18 | 18 |
|
19 | 19 | /*!
|
20 |
| -Secure creation of CStr with zero cost. Plugin for rust compiler. |
| 20 | +Creation of strings C with zero cost. A plug-in for the rust compiler. |
| 21 | +
|
| 22 | +# Features |
| 23 | +1. The transparent creation of the C strings with zero cost. |
| 24 | +2. Check of the C lines at the level of the compiler. |
| 25 | +3. Convenient macro for creation of lines. |
| 26 | +4. Plug-in for the compiler. |
| 27 | +
|
| 28 | +
|
21 | 29 |
|
22 | 30 | # Use
|
23 | 31 | ```
|
@@ -142,201 +150,16 @@ test tests::cstr_macros ... bench: 90 ns/iter (+/- 14)
|
142 | 150 |
|
143 | 151 | test tests::cstr_plugin ... bench: 0 ns/iter (+/- 0)
|
144 | 152 | */
|
145 |
| -#![feature(plugin_registrar, rustc_private)] |
146 |
| -#![feature(i128_type)] |
147 | 153 |
|
148 |
| -extern crate syntax; |
149 |
| -extern crate rustc; |
150 |
| -extern crate rustc_plugin; |
151 | 154 |
|
152 |
| -use syntax::tokenstream::TokenTree; |
153 |
| -use syntax::ext::base::{ExtCtxt, MacResult, DummyResult, MacEager}; |
154 |
| -use syntax::ext::build::AstBuilder; |
155 |
| -use syntax::ext::quote::rt::Span; |
156 |
| -use rustc_plugin::Registry; |
157 |
| -use syntax::ast::ExprKind; |
158 |
| -use syntax::ast::LitKind; |
159 |
| -use syntax::ast::Mutability; |
160 |
| -use syntax::ast::LitIntType; |
161 |
| -use syntax::ast::TyKind; |
162 |
| -use syntax::ast::UintTy; |
163 |
| -use syntax::ast::UnOp; |
164 |
| -use syntax::ast::BlockCheckMode; |
165 |
| -use syntax::ast::UnsafeSource; |
166 |
| -use syntax::ast::Block; |
167 |
| -use syntax::ptr::P; |
168 |
| -use syntax::ast; |
169 |
| - |
170 |
| -///Secure creation of CStr with zero cost |
171 |
| -//Required for docks!!!!! |
172 |
| -#[macro_export] |
173 |
| -macro_rules! cstr { |
174 |
| - ($s:expr) => {}; |
175 |
| -} |
176 |
| -//Required for docks!!!!! |
177 |
| - |
178 |
| - |
179 |
| -#[doc(hidden)] |
180 |
| -#[plugin_registrar] |
181 |
| -pub fn plugin_registrar(reg: &mut Registry) { |
182 |
| - reg.register_macro("cstr", cstr); |
183 |
| -} |
184 |
| - |
185 |
| -#[doc(hidden)] |
186 |
| -pub fn cstr(cx: &mut ExtCtxt, sp: Span, args: &[TokenTree]) -> Box<MacResult + 'static> { |
187 |
| - let mut parser = cx.new_parser_from_tts(args); |
188 |
| - |
189 |
| - let expr = match parser.parse_expr() { |
190 |
| - Ok(a) => a, |
191 |
| - Err(_e) => { |
192 |
| - cx.span_err(sp, "cstr currently only supports one argument"); |
193 |
| - return DummyResult::any(sp); |
194 |
| - } |
195 |
| - }; |
196 |
| - |
197 |
| - let c_array = { |
198 |
| - let mut add_null = true; |
199 |
| - |
200 |
| - let mut array = match expr.node { |
201 |
| - ExprKind::Lit(ref l) => { |
202 |
| - //println!("{:?}", l.node); |
203 |
| - match l.node { |
204 |
| - LitKind::Str(s, _) => { |
205 |
| - let s = s.to_string(); |
206 |
| - let array = s.as_bytes(); |
207 |
| - let array_len = array.len(); |
208 |
| - |
209 |
| - let mut vec_result = Vec::with_capacity(array_len); |
210 |
| - |
211 |
| - for (num, a) in array.iter().enumerate() { |
212 |
| - if *a == 0 { |
213 |
| - match num+1 == array_len { |
214 |
| - true => add_null = false, |
215 |
| - _ => { |
216 |
| - cx.span_err(sp, "the string has a null byte"); |
217 |
| - return DummyResult::any(sp); |
218 |
| - }, |
219 |
| - } |
220 |
| - } |
221 |
| - vec_result.push( |
222 |
| - cx.expr_lit(sp, |
223 |
| - LitKind::Int(*a as u128, LitIntType::Unsigned(UintTy::U8)), |
224 |
| - ) |
225 |
| - ); |
226 |
| - } |
227 |
| - vec_result |
228 |
| - }, |
229 |
| - LitKind::ByteStr(ref array) => { |
230 |
| - let array_len = array.len(); |
231 |
| - let mut vec_result = Vec::with_capacity(array.len()); |
232 |
| - |
233 |
| - for (num, a) in array.iter().enumerate() { |
234 |
| - if *a == 0 { |
235 |
| - match num+1 == array_len { |
236 |
| - true => add_null = false, |
237 |
| - _ => { |
238 |
| - cx.span_err(sp, "the string has a null byte"); |
239 |
| - return DummyResult::any(sp); |
240 |
| - }, |
241 |
| - } |
242 |
| - } |
243 |
| - vec_result.push( |
244 |
| - cx.expr_lit(sp, |
245 |
| - LitKind::Int(*a as u128, LitIntType::Unsigned(UintTy::U8)), |
246 |
| - ) |
247 |
| - ); |
248 |
| - } |
249 |
| - vec_result |
250 |
| - }, |
251 |
| - LitKind::Byte(ref a) => { |
252 |
| - if *a == 0 { |
253 |
| - add_null = false; |
254 |
| - } |
255 |
| - vec!( |
256 |
| - cx.expr_lit(sp, |
257 |
| - LitKind::Int(*a as u128, LitIntType::Unsigned(UintTy::U8)), |
258 |
| - ) |
259 |
| - ) |
260 |
| - } |
261 |
| - _ => { |
262 |
| - cx.span_err(sp, "argument should be a single identifier"); |
263 |
| - return DummyResult::any(sp); |
264 |
| - } |
265 |
| - |
266 |
| - } |
267 |
| - }, |
268 |
| - _ => { |
269 |
| - cx.span_err(sp, "argument should be a single identifier"); |
270 |
| - return DummyResult::any(sp); |
271 |
| - } |
272 |
| - }; |
273 |
| - |
274 |
| - if add_null { |
275 |
| - array.reserve(1); |
276 |
| - array.push( |
277 |
| - cx.expr_lit(sp, |
278 |
| - LitKind::Int(0, LitIntType::Unsigned(UintTy::U8)), |
279 |
| - ) |
280 |
| - ); |
281 |
| - } |
282 |
| - |
283 |
| - cx.expr( |
284 |
| - sp, |
285 |
| - ExprKind::AddrOf(Mutability::Immutable, |
286 |
| - cx.expr(sp, ExprKind::Array(array)) //[u8] |
287 |
| - ) // &[u8] |
288 |
| - ) |
289 |
| - }; |
290 |
| - |
291 |
| - let c_array = cx.expr_cast( |
292 |
| - sp, |
293 |
| - c_array, //[u8] |
294 |
| - cx.ty_ptr(sp, // -> *const [u8] |
295 |
| - cx.ty(sp, TyKind::Slice( |
296 |
| - cx.ty_ident(sp, cx.ident_of("u8")) |
297 |
| - )), // P<TY> |
298 |
| - |
299 |
| - Mutability::Immutable // const |
300 |
| - ) |
301 |
| - );// &[u8] as *const [u8] |
302 |
| - |
303 |
| - let c_cstr = cx.expr_cast( |
304 |
| - sp, |
305 |
| - c_array, //[i8] |
306 |
| - cx.ty_ptr(sp, // -> *const [i8] |
307 |
| - cx.ty_ident(sp, cx.ident_of("CStr")), |
308 |
| - |
309 |
| - Mutability::Immutable // const |
310 |
| - ) |
311 |
| - ); // as *const CSTR |
312 |
| - |
313 |
| - let c_cstr = cx.expr_unary(sp, UnOp::Deref, c_cstr); |
314 |
| - //*([u8] as *const [u8] as *const CStr) |
315 |
| - |
316 |
| - let c_cstr = cx.expr(sp, ExprKind::AddrOf(Mutability::Immutable, c_cstr)); |
317 |
| - //&*([u8] as *const [u8] as *const CStr) |
318 |
| - |
319 |
| - let block = { |
320 |
| - let vec_stmts = vec!( |
321 |
| - cx.stmt_expr(c_cstr) |
322 |
| - ); |
323 |
| - let mut block = P(Block { |
324 |
| - stmts: vec_stmts, |
325 |
| - id: ast::DUMMY_NODE_ID, |
326 |
| - rules: BlockCheckMode::Unsafe(UnsafeSource::CompilerGenerated), |
327 |
| - span: sp, |
328 |
| - recovered: false, |
329 |
| - |
330 |
| - }); |
331 |
| - cx.expr_block(block) |
332 |
| - };// unsafe { &*([u8] as *const [u8] as *const CStr) } |
333 |
| - |
334 |
| - |
335 |
| - MacEager::expr( |
336 |
| - block |
337 |
| - ) |
338 |
| -} |
| 155 | +#![feature(plugin_registrar)] |
| 156 | +#![feature(rustc_private)] |
339 | 157 |
|
340 | 158 |
|
| 159 | +extern crate syntax; |
| 160 | +extern crate rustc; |
| 161 | +extern crate rustc_plugin; |
341 | 162 |
|
342 | 163 |
|
| 164 | +mod nightly; |
| 165 | +pub use self::nightly::*; |
0 commit comments