44//! Rust.
55
66use super :: * ;
7+ use c2rust_ast_builder:: CaptureBy ;
78use failure:: format_err;
89use proc_macro2:: { TokenStream , TokenTree } ;
910
@@ -53,45 +54,110 @@ impl<'c> Translation<'c> {
5354 if n >= 2 {
5455 // `argv` and `argc`
5556
57+ // let mut args_strings: Vec<Vec<u8>> = (::std::env::args())
58+ // .map(|arg| {
59+ // (::std::ffi::CString::new(arg))
60+ // .expect("Failed to convert argument into CString.")
61+ // .into_bytes_with_nul()
62+ // })
63+ // .collect();
5664 stmts. push ( mk ( ) . local_stmt ( Box :: new ( mk ( ) . local (
57- mk ( ) . mutbl ( ) . ident_pat ( "args" ) ,
65+ mk ( ) . mutbl ( ) . ident_pat ( "args_strings" ) ,
66+ Some ( mk ( ) . path_ty ( vec ! [ mk( ) . path_segment_with_args(
67+ "Vec" ,
68+ mk( ) . angle_bracketed_args( vec![ mk( ) . path_ty( vec![
69+ mk( ) . path_segment_with_args(
70+ "Vec" ,
71+ mk( ) . angle_bracketed_args( vec![ mk( ) . ident_ty( "u8" ) ] ) ,
72+ ) ,
73+ ] ) ] ) ,
74+ ) ] ) ) ,
75+ Some ( mk ( ) . method_call_expr (
76+ mk ( ) . method_call_expr (
77+ mk ( ) . call_expr ( args_fn, vec ! [ ] ) ,
78+ "map" ,
79+ vec ! [ mk( ) . closure_expr(
80+ CaptureBy :: Ref ,
81+ Movability :: Movable ,
82+ vec![ mk( ) . ident_pat( "arg" ) ] ,
83+ ReturnType :: Default ,
84+ mk( ) . method_call_expr(
85+ mk( ) . method_call_expr(
86+ mk( ) . call_expr(
87+ mk( ) . abs_path_expr( vec![
88+ "std" , "ffi" , "CString" , "new" ,
89+ ] ) ,
90+ vec![ mk( ) . path_expr( vec![ "arg" ] ) ] ,
91+ ) ,
92+ "expect" ,
93+ vec![
94+ mk( ) . lit_expr(
95+ "Failed to convert argument into CString." ,
96+ ) ,
97+ ] ,
98+ ) ,
99+ "into_bytes_with_nul" ,
100+ vec![ ] ,
101+ ) ,
102+ ) ] ,
103+ ) ,
104+ "collect" ,
105+ vec ! [ ] ,
106+ ) ) ,
107+ ) ) ) ) ;
108+
109+ // let mut args_ptrs: Vec<*mut ::core::ffi::c_char> = args_strings
110+ // .iter_mut()
111+ // .map(|arg| arg.as_mut_ptr() as *mut ::core::ffi::c_char)
112+ // .chain(::core::iter::once(::core::ptr::null_mut()))
113+ // .collect();
114+ stmts. push ( mk ( ) . local_stmt ( Box :: new ( mk ( ) . local (
115+ mk ( ) . mutbl ( ) . ident_pat ( "args_ptrs" ) ,
58116 Some ( mk ( ) . path_ty ( vec ! [ mk( ) . path_segment_with_args(
59117 "Vec" ,
60118 mk( ) . angle_bracketed_args( vec![
61119 mk( ) . mutbl( ) . ptr_ty( mk( ) . abs_path_ty( vec![ "core" , "ffi" , "c_char" ] ) ) ,
62120 ] ) ,
63121 ) ] ) ) ,
64- Some ( mk ( ) . call_expr ( mk ( ) . path_expr ( vec ! [ "Vec" , "new" ] ) , vec ! [ ] ) ) ,
65- ) ) ) ) ;
66- stmts. push ( mk ( ) . semi_stmt ( mk ( ) . for_expr (
67- mk ( ) . ident_pat ( "arg" ) ,
68- mk ( ) . call_expr ( args_fn, vec ! [ ] ) ,
69- mk ( ) . block ( vec ! [ mk( ) . semi_stmt( mk( ) . method_call_expr(
70- mk( ) . path_expr( vec![ "args" ] ) ,
71- "push" ,
72- vec![ mk( ) . method_call_expr(
122+ Some ( mk ( ) . method_call_expr (
123+ mk ( ) . method_call_expr (
73124 mk ( ) . method_call_expr (
74- mk( ) . call_expr (
75- // TODO(kkysen) change `"std"` to `"alloc"` after `#![feature(alloc_c_string)]` is stabilized in `1.63.0`
76- mk ( ) . abs_path_expr ( vec! [ "std" , "ffi" , "CString" , "new" ] ) ,
77- vec![ mk ( ) . path_expr ( vec! [ "arg" ] ) ] ,
125+ mk ( ) . method_call_expr (
126+ mk ( ) . ident_expr ( "args_strings" ) ,
127+ "iter_mut" ,
128+ vec ! [ ] ,
78129 ) ,
79- "expect" ,
80- vec![ mk( ) . lit_expr( "Failed to convert argument into CString." ) ] ,
130+ "map" ,
131+ vec ! [ mk( ) . closure_expr(
132+ CaptureBy :: Ref ,
133+ Movability :: Movable ,
134+ vec![ mk( ) . ident_pat( "arg" ) ] ,
135+ ReturnType :: Default ,
136+ mk( ) . cast_expr(
137+ mk( ) . method_call_expr(
138+ mk( ) . ident_expr( "arg" ) ,
139+ "as_mut_ptr" ,
140+ vec![ ] ,
141+ ) ,
142+ mk( ) . mutbl( ) . ptr_ty(
143+ mk( ) . abs_path_ty( vec![ "core" , "ffi" , "c_char" ] ) ,
144+ ) ,
145+ ) ,
146+ ) ] ,
81147 ) ,
82- "into_raw " ,
83- vec![ ] ,
84- ) ] ,
85- ) ) ] ) ,
86- None :: < Ident > ,
87- ) ) ) ;
88- stmts . push ( mk ( ) . semi_stmt ( mk ( ) . method_call_expr (
89- mk ( ) . path_expr ( vec ! [ "args" ] ) ,
90- "push" ,
91- vec ! [
92- mk ( ) . call_expr ( mk ( ) . abs_path_expr ( vec![ "core" , "ptr" , "null_mut" ] ) , vec! [ ] ) ,
93- ] ,
94- ) ) ) ;
148+ "chain " ,
149+ vec ! [ mk ( ) . call_expr (
150+ mk ( ) . abs_path_expr ( vec! [ "core" , "iter" , "once" ] ) ,
151+ vec! [ mk ( ) . call_expr (
152+ mk ( ) . abs_path_expr ( vec! [ "core" , "ptr" , "null_mut" ] ) ,
153+ vec! [ ] ,
154+ ) ] ,
155+ ) ] ,
156+ ) ,
157+ "collect" ,
158+ vec ! [ ] ,
159+ ) ) ,
160+ ) ) ) ) ;
95161
96162 let argc_ty: Box < Type > = match self . ast_context . index ( parameters[ 0 ] ) . kind {
97163 CDeclKind :: Variable { ref typ, .. } => self . convert_type ( typ. ctype ) ,
@@ -105,8 +171,7 @@ impl<'c> Translation<'c> {
105171 "Cannot find type of 'argv' argument in main function" ,
106172 ) ) ,
107173 } ?;
108-
109- let args = mk ( ) . ident_expr ( "args" ) ;
174+ let args = mk ( ) . ident_expr ( "args_ptrs" ) ;
110175 let argc = mk ( ) . binary_expr (
111176 BinOp :: Sub ( Default :: default ( ) ) ,
112177 mk ( ) . method_call_expr ( args. clone ( ) , "len" , no_args. clone ( ) ) ,
0 commit comments