]> git.lizzy.rs Git - rust.git/commitdiff
auto merge of #8532 : kballard/rust/cstr-cleanup, r=erickt
authorbors <bors@rust-lang.org>
Fri, 16 Aug 2013 13:02:14 +0000 (06:02 -0700)
committerbors <bors@rust-lang.org>
Fri, 16 Aug 2013 13:02:14 +0000 (06:02 -0700)
Implement interior null checking in `.to_c_str()`, among other changes.

34 files changed:
src/libextra/rl.rs
src/librustc/back/link.rs
src/librustc/back/passes.rs
src/librustc/lib/llvm.rs
src/librustc/metadata/loader.rs
src/librustc/middle/trans/asm.rs
src/librustc/middle/trans/base.rs
src/librustc/middle/trans/builder.rs
src/librustc/middle/trans/common.rs
src/librustc/middle/trans/consts.rs
src/librustc/middle/trans/context.rs
src/librustc/middle/trans/controlflow.rs
src/librustc/middle/trans/debuginfo.rs
src/librustc/middle/trans/expr.rs
src/librustc/middle/trans/glue.rs
src/librustc/middle/trans/meth.rs
src/librustc/middle/trans/tvec.rs
src/librustc/middle/trans/type_.rs
src/librustpkg/util.rs
src/libstd/c_str.rs
src/libstd/io.rs
src/libstd/os.rs
src/libstd/path.rs
src/libstd/ptr.rs
src/libstd/rt/borrowck.rs
src/libstd/rt/logging.rs
src/libstd/rt/uv/uvio.rs
src/libstd/rt/uv/uvll.rs
src/libstd/run.rs
src/libstd/sys.rs
src/libstd/unstable/dynamic_lib.rs
src/libstd/unstable/lang.rs
src/test/run-pass/c-stack-returning-int64.rs
src/test/run-pass/foreign-fn-linkname.rs

index 9106d4cd684d916f5c6d58bcbb83dd87962cce90..ead1f276ca701a13c9b3c0fbf08e21bd4685de9c 100644 (file)
@@ -32,7 +32,7 @@ pub mod rustrt {
 
 /// Add a line to history
 pub unsafe fn add_history(line: &str) -> bool {
-    do line.to_c_str().with_ref |buf| {
+    do line.with_c_str |buf| {
         rustrt::linenoiseHistoryAdd(buf) == 1 as c_int
     }
 }
@@ -44,21 +44,21 @@ pub unsafe fn set_history_max_len(len: int) -> bool {
 
 /// Save line history to a file
 pub unsafe fn save_history(file: &str) -> bool {
-    do file.to_c_str().with_ref |buf| {
+    do file.with_c_str |buf| {
         rustrt::linenoiseHistorySave(buf) == 1 as c_int
     }
 }
 
 /// Load line history from a file
 pub unsafe fn load_history(file: &str) -> bool {
-    do file.to_c_str().with_ref |buf| {
+    do file.with_c_str |buf| {
         rustrt::linenoiseHistoryLoad(buf) == 1 as c_int
     }
 }
 
 /// Print out a prompt and then wait for input and return it
 pub unsafe fn read(prompt: &str) -> Option<~str> {
-    do prompt.to_c_str().with_ref |buf| {
+    do prompt.with_c_str |buf| {
         let line = rustrt::linenoise(buf);
 
         if line.is_null() { None }
@@ -80,7 +80,7 @@ pub unsafe fn complete(cb: CompletionCb) {
 
             unsafe {
                 do cb(str::raw::from_c_str(line)) |suggestion| {
-                    do suggestion.to_c_str().with_ref |buf| {
+                    do suggestion.with_c_str |buf| {
                         rustrt::linenoiseAddCompletion(completions, buf);
                     }
                 }
index ed6eab5de193a93f6e700f7c01e6e4d4cddf1099..91b6ee2411091982c3acb9766abd30d1c3a66ee0 100644 (file)
@@ -78,10 +78,10 @@ pub fn WriteOutputFile(sess: Session,
         OptLevel: c_int,
         EnableSegmentedStacks: bool) {
     unsafe {
-        do Triple.to_c_str().with_ref |Triple| {
-            do Cpu.to_c_str().with_ref |Cpu| {
-                do Feature.to_c_str().with_ref |Feature| {
-                    do Output.to_c_str().with_ref |Output| {
+        do Triple.with_c_str |Triple| {
+            do Cpu.with_c_str |Cpu| {
+                do Feature.with_c_str |Feature| {
+                    do Output.with_c_str |Output| {
                         let result = llvm::LLVMRustWriteOutputFile(
                                 PM,
                                 M,
@@ -152,7 +152,7 @@ pub fn exec(sess: Session,
 
                 debug!("linking: %s", path);
 
-                do path.to_c_str().with_ref |buf_t| {
+                do path.with_c_str |buf_t| {
                     if !llvm::LLVMRustLoadCrate(manager, buf_t) {
                         llvm_err(sess, ~"Could not link");
                     }
@@ -171,7 +171,7 @@ pub fn exec(sess: Session,
             // Next, we need to get a handle on the _rust_main function by
             // looking up it's corresponding ValueRef and then requesting that
             // the execution engine compiles the function.
-            let fun = do "_rust_main".to_c_str().with_ref |entry| {
+            let fun = do "_rust_main".with_c_str |entry| {
                 llvm::LLVMGetNamedFunction(m, entry)
             };
             if fun.is_null() {
@@ -270,14 +270,14 @@ pub fn run_passes(sess: Session,
                   output_type_bitcode => {
                     if opts.optimize != session::No {
                         let filename = output.with_filetype("no-opt.bc");
-                        do filename.to_c_str().with_ref |buf| {
+                        do filename.with_c_str |buf| {
                             llvm::LLVMWriteBitcodeToFile(llmod, buf);
                         }
                     }
                   }
                   _ => {
                     let filename = output.with_filetype("bc");
-                    do filename.to_c_str().with_ref |buf| {
+                    do filename.with_c_str |buf| {
                         llvm::LLVMWriteBitcodeToFile(llmod, buf);
                     }
                   }
@@ -340,7 +340,7 @@ pub fn run_passes(sess: Session,
                     // Always output the bitcode file with --save-temps
 
                     let filename = output.with_filetype("opt.bc");
-                    do filename.to_c_str().with_ref |buf| {
+                    do filename.with_c_str |buf| {
                         llvm::LLVMWriteBitcodeToFile(llmod, buf)
                     };
                     // Save the assembly file if -S is used
@@ -401,13 +401,13 @@ pub fn run_passes(sess: Session,
 
             if output_type == output_type_llvm_assembly {
                 // Given options "-S --emit-llvm": output LLVM assembly
-                do output.to_c_str().with_ref |buf_o| {
+                do output.with_c_str |buf_o| {
                     llvm::LLVMRustAddPrintModulePass(pm.llpm, llmod, buf_o);
                 }
             } else {
                 // If only a bitcode file is asked for by using the
                 // '--emit-llvm' flag, then output it here
-                do output.to_c_str().with_ref |buf| {
+                do output.with_c_str |buf| {
                     llvm::LLVMWriteBitcodeToFile(llmod, buf);
                 }
             }
index 854d11fd3503599e030e2d33d8f8a9dbd36ceb21..29bc577dff960c844c87756c581062e487719d02 100644 (file)
@@ -173,7 +173,7 @@ pub fn populate_pass_manager(sess: Session, pm: &mut PassManager, pass_list:&[~s
 }
 
 pub fn create_pass(name:&str) -> Option<PassRef> {
-    do name.to_c_str().with_ref |s| {
+    do name.with_c_str |s| {
         unsafe {
             let p = llvm::LLVMCreatePass(s);
             if p.is_null() {
index 156aafacfec628d5b375ab75d7ae30a7268f5f0d..307b691a56e67de588840ade9a7d577ddd346ae7 100644 (file)
@@ -2271,7 +2271,7 @@ pub struct TargetData {
 }
 
 pub fn mk_target_data(string_rep: &str) -> TargetData {
-    let lltd = do string_rep.to_c_str().with_ref |buf| {
+    let lltd = do string_rep.with_c_str |buf| {
         unsafe { llvm::LLVMCreateTargetData(buf) }
     };
 
index 554cdf4b2b4feb13a9055357ec18cd10316e375f..d0060931a6607eca54c753346ff492fbf8146d20 100644 (file)
@@ -199,7 +199,7 @@ pub fn metadata_matches(extern_metas: &[@ast::MetaItem],
 fn get_metadata_section(os: os,
                         filename: &Path) -> Option<@~[u8]> {
     unsafe {
-        let mb = do filename.to_c_str().with_ref |buf| {
+        let mb = do filename.with_c_str |buf| {
             llvm::LLVMRustCreateMemoryBufferWithContentsOfFile(buf)
         };
         if mb as int == 0 { return option::None::<@~[u8]>; }
index b6057199a280fbccddba02aefe60d7b20f42c5f7..3400da75b9e5e880d237ea3192ce50b7b6659e8c 100644 (file)
@@ -120,8 +120,8 @@ pub fn trans_inline_asm(bcx: @mut Block, ia: &ast::inline_asm) -> @mut Block {
         ast::asm_intel => lib::llvm::AD_Intel
     };
 
-    let r = do ia.asm.to_c_str().with_ref |a| {
-        do constraints.to_c_str().with_ref |c| {
+    let r = do ia.asm.with_c_str |a| {
+        do constraints.with_c_str |c| {
             InlineAsmCall(bcx, a, c, inputs, output, ia.volatile, ia.alignstack, dialect)
         }
     };
index ec6bb0c998e0680a1f9b8378dee9393d0e7b37f0..84b3ab2040722d15f59f1a65754ca8282c7fdd63 100644 (file)
@@ -181,7 +181,7 @@ fn drop(&self) {
 }
 
 pub fn decl_fn(llmod: ModuleRef, name: &str, cc: lib::llvm::CallConv, ty: Type) -> ValueRef {
-    let llfn: ValueRef = do name.to_c_str().with_ref |buf| {
+    let llfn: ValueRef = do name.with_c_str |buf| {
         unsafe {
             llvm::LLVMGetOrInsertFunction(llmod, buf, ty.to_ref())
         }
@@ -221,7 +221,7 @@ pub fn get_extern_const(externs: &mut ExternMap, llmod: ModuleRef,
         None => ()
     }
     unsafe {
-        let c = do name.to_c_str().with_ref |buf| {
+        let c = do name.with_c_str |buf| {
             llvm::LLVMAddGlobal(llmod, ty.to_ref(), buf)
         };
         externs.insert(name, c);
@@ -523,7 +523,7 @@ pub fn get_res_dtor(ccx: @mut CrateContext,
 // Structural comparison: a rather involved form of glue.
 pub fn maybe_name_value(cx: &CrateContext, v: ValueRef, s: &str) {
     if cx.sess.opts.save_temps {
-        do s.to_c_str().with_ref |buf| {
+        do s.with_c_str |buf| {
             unsafe {
                 llvm::LLVMSetValueName(v, buf)
             }
@@ -1136,7 +1136,7 @@ pub fn new_block(cx: @mut FunctionContext,
                  opt_node_info: Option<NodeInfo>)
               -> @mut Block {
     unsafe {
-        let llbb = do name.to_c_str().with_ref |buf| {
+        let llbb = do name.with_c_str |buf| {
             llvm::LLVMAppendBasicBlockInContext(cx.ccx.llcx, cx.llfn, buf)
         };
         let bcx = @mut Block::new(llbb,
@@ -1553,7 +1553,7 @@ pub struct BasicBlocks {
 pub fn mk_staticallocas_basic_block(llfn: ValueRef) -> BasicBlockRef {
     unsafe {
         let cx = task_llcx();
-        do "static_allocas".to_c_str().with_ref | buf| {
+        do "static_allocas".with_c_str | buf| {
             llvm::LLVMAppendBasicBlockInContext(cx, llfn, buf)
         }
     }
@@ -1562,7 +1562,7 @@ pub fn mk_staticallocas_basic_block(llfn: ValueRef) -> BasicBlockRef {
 pub fn mk_return_basic_block(llfn: ValueRef) -> BasicBlockRef {
     unsafe {
         let cx = task_llcx();
-        do "return".to_c_str().with_ref |buf| {
+        do "return".with_c_str |buf| {
             llvm::LLVMAppendBasicBlockInContext(cx, llfn, buf)
         }
     }
@@ -2328,7 +2328,7 @@ fn create_entry_fn(ccx: @mut CrateContext,
             };
             decl_cdecl_fn(ccx.llmod, main_name, llfty)
         };
-        let llbb = do "top".to_c_str().with_ref |buf| {
+        let llbb = do "top".with_c_str |buf| {
             unsafe {
                 llvm::LLVMAppendBasicBlockInContext(ccx.llcx, llfn, buf)
             }
@@ -2338,7 +2338,7 @@ fn create_entry_fn(ccx: @mut CrateContext,
             llvm::LLVMPositionBuilderAtEnd(bld, llbb);
 
             let crate_map = ccx.crate_map;
-            let opaque_crate_map = do "crate_map".to_c_str().with_ref |buf| {
+            let opaque_crate_map = do "crate_map".with_c_str |buf| {
                 llvm::LLVMBuildPointerCast(bld, crate_map, Type::i8p().to_ref(), buf)
             };
 
@@ -2356,7 +2356,7 @@ fn create_entry_fn(ccx: @mut CrateContext,
                 };
 
                 let args = {
-                    let opaque_rust_main = do "rust_main".to_c_str().with_ref |buf| {
+                    let opaque_rust_main = do "rust_main".with_c_str |buf| {
                         llvm::LLVMBuildPointerCast(bld, rust_main, Type::i8p().to_ref(), buf)
                     };
 
@@ -2438,7 +2438,7 @@ pub fn get_item_val(ccx: @mut CrateContext, id: ast::NodeId) -> ValueRef {
 
                             unsafe {
                                 let llty = llvm::LLVMTypeOf(v);
-                                let g = do sym.to_c_str().with_ref |buf| {
+                                let g = do sym.with_c_str |buf| {
                                     llvm::LLVMAddGlobal(ccx.llmod, llty, buf)
                                 };
 
@@ -2471,7 +2471,7 @@ pub fn get_item_val(ccx: @mut CrateContext, id: ast::NodeId) -> ValueRef {
 
                     match (attr::first_attr_value_str_by_name(i.attrs, "link_section")) {
                         Some(sect) => unsafe {
-                            do sect.to_c_str().with_ref |buf| {
+                            do sect.with_c_str |buf| {
                                 llvm::LLVMSetSection(v, buf);
                             }
                         },
@@ -2512,7 +2512,7 @@ pub fn get_item_val(ccx: @mut CrateContext, id: ast::NodeId) -> ValueRef {
                         }
                         ast::foreign_item_static(*) => {
                             let ident = token::ident_to_str(&ni.ident);
-                            let g = do ident.to_c_str().with_ref |buf| {
+                            let g = do ident.with_c_str |buf| {
                                 unsafe {
                                     let ty = type_of(ccx, ty);
                                     llvm::LLVMAddGlobal(ccx.llmod, ty.to_ref(), buf)
@@ -2619,7 +2619,7 @@ pub fn trans_constant(ccx: &mut CrateContext, it: @ast::item) {
             let s = mangle_exported_name(ccx, p, ty::mk_int()).to_managed();
             let disr_val = vi[i].disr_val;
             note_unique_llvm_symbol(ccx, s);
-            let discrim_gvar = do s.to_c_str().with_ref |buf| {
+            let discrim_gvar = do s.with_c_str |buf| {
                 unsafe {
                     llvm::LLVMAddGlobal(ccx.llmod, ccx.int_type.to_ref(), buf)
                 }
@@ -2814,7 +2814,7 @@ pub fn decl_gc_metadata(ccx: &mut CrateContext, llmod_id: &str) {
     }
 
     let gc_metadata_name = ~"_gc_module_metadata_" + llmod_id;
-    let gc_metadata = do gc_metadata_name.to_c_str().with_ref |buf| {
+    let gc_metadata = do gc_metadata_name.with_c_str |buf| {
         unsafe {
             llvm::LLVMAddGlobal(ccx.llmod, Type::i32().to_ref(), buf)
         }
@@ -2829,7 +2829,7 @@ pub fn decl_gc_metadata(ccx: &mut CrateContext, llmod_id: &str) {
 pub fn create_module_map(ccx: &mut CrateContext) -> ValueRef {
     let elttype = Type::struct_([ccx.int_type, ccx.int_type], false);
     let maptype = Type::array(&elttype, (ccx.module_data.len() + 1) as u64);
-    let map = do "_rust_mod_map".to_c_str().with_ref |buf| {
+    let map = do "_rust_mod_map".with_c_str |buf| {
         unsafe {
             llvm::LLVMAddGlobal(ccx.llmod, maptype.to_ref(), buf)
         }
@@ -2877,7 +2877,7 @@ pub fn decl_crate_map(sess: session::Session, mapmeta: LinkMeta,
     let sym_name = ~"_rust_crate_map_" + mapname;
     let arrtype = Type::array(&int_type, n_subcrates as u64);
     let maptype = Type::struct_([Type::i32(), Type::i8p(), int_type, arrtype], false);
-    let map = do sym_name.to_c_str().with_ref |buf| {
+    let map = do sym_name.with_c_str |buf| {
         unsafe {
             llvm::LLVMAddGlobal(llmod, maptype.to_ref(), buf)
         }
@@ -2896,7 +2896,7 @@ pub fn fill_crate_map(ccx: @mut CrateContext, map: ValueRef) {
                       cdata.name,
                       cstore::get_crate_vers(cstore, i),
                       cstore::get_crate_hash(cstore, i));
-        let cr = do nm.to_c_str().with_ref |buf| {
+        let cr = do nm.with_c_str |buf| {
             unsafe {
                 llvm::LLVMAddGlobal(ccx.llmod, ccx.int_type.to_ref(), buf)
             }
@@ -2959,21 +2959,21 @@ pub fn write_metadata(cx: &mut CrateContext, crate: &ast::Crate) {
     let encode_parms = crate_ctxt_to_encode_parms(cx, encode_inlined_item);
     let llmeta = C_bytes(encoder::encode_metadata(encode_parms, crate));
     let llconst = C_struct([llmeta]);
-    let mut llglobal = do "rust_metadata".to_c_str().with_ref |buf| {
+    let mut llglobal = do "rust_metadata".with_c_str |buf| {
         unsafe {
             llvm::LLVMAddGlobal(cx.llmod, val_ty(llconst).to_ref(), buf)
         }
     };
     unsafe {
         llvm::LLVMSetInitializer(llglobal, llconst);
-        do cx.sess.targ_cfg.target_strs.meta_sect_name.to_c_str().with_ref |buf| {
+        do cx.sess.targ_cfg.target_strs.meta_sect_name.with_c_str |buf| {
             llvm::LLVMSetSection(llglobal, buf)
         };
         lib::llvm::SetLinkage(llglobal, lib::llvm::InternalLinkage);
 
         let t_ptr_i8 = Type::i8p();
         llglobal = llvm::LLVMConstBitCast(llglobal, t_ptr_i8.to_ref());
-        let llvm_used = do "llvm.used".to_c_str().with_ref |buf| {
+        let llvm_used = do "llvm.used".with_c_str |buf| {
             llvm::LLVMAddGlobal(cx.llmod, Type::array(&t_ptr_i8, 1).to_ref(), buf)
         };
         lib::llvm::SetLinkage(llvm_used, lib::llvm::AppendingLinkage);
@@ -2987,7 +2987,7 @@ fn mk_global(ccx: &CrateContext,
              internal: bool)
           -> ValueRef {
     unsafe {
-        let llglobal = do name.to_c_str().with_ref |buf| {
+        let llglobal = do name.with_c_str |buf| {
             llvm::LLVMAddGlobal(ccx.llmod, val_ty(llval).to_ref(), buf)
         };
         llvm::LLVMSetInitializer(llglobal, llval);
index 5c216b2e14346684620185f0213be2666003b9b0..cba7a2253952ff55989de9d882914dbfbd7d4510 100644 (file)
@@ -423,7 +423,7 @@ pub fn alloca(&self, ty: Type, name: &str) -> ValueRef {
             if name.is_empty() {
                 llvm::LLVMBuildAlloca(self.llbuilder, ty.to_ref(), noname())
             } else {
-                do name.to_c_str().with_ref |c| {
+                do name.with_c_str |c| {
                     llvm::LLVMBuildAlloca(self.llbuilder, ty.to_ref(), c)
                 }
             }
@@ -739,7 +739,7 @@ pub fn add_comment(&self, text: &str) {
             let sanitized = text.replace("$", "");
             let comment_text = fmt!("# %s", sanitized.replace("\n", "\n\t# "));
             self.count_insn("inlineasm");
-            let asm = do comment_text.to_c_str().with_ref |c| {
+            let asm = do comment_text.with_c_str |c| {
                 unsafe {
                     llvm::LLVMConstInlineAsm(Type::func([], &Type::void()).to_ref(),
                                              c, noname(), False, False)
@@ -895,7 +895,7 @@ pub fn trap(&self) {
             let BB: BasicBlockRef = llvm::LLVMGetInsertBlock(self.llbuilder);
             let FN: ValueRef = llvm::LLVMGetBasicBlockParent(BB);
             let M: ModuleRef = llvm::LLVMGetGlobalParent(FN);
-            let T: ValueRef = do "llvm.trap".to_c_str().with_ref |buf| {
+            let T: ValueRef = do "llvm.trap".with_c_str |buf| {
                 llvm::LLVMGetNamedFunction(M, buf)
             };
             assert!((T as int != 0));
index fde33220d8426cd076adbe384283a759eb222281..4ca4a9a12fc4c96ba7355e2e90cb647139169c65 100644 (file)
@@ -36,7 +36,7 @@
 use std::cast::transmute;
 use std::cast;
 use std::hashmap::{HashMap};
-use std::libc::{c_uint, c_longlong, c_ulonglong};
+use std::libc::{c_uint, c_longlong, c_ulonglong, c_char};
 use std::vec;
 use syntax::ast::ident;
 use syntax::ast_map::{path, path_elt};
@@ -709,7 +709,7 @@ pub fn C_integral(t: Type, u: u64, sign_extend: bool) -> ValueRef {
 
 pub fn C_floating(s: &str, t: Type) -> ValueRef {
     unsafe {
-        do s.to_c_str().with_ref |buf| {
+        do s.with_c_str |buf| {
             llvm::LLVMConstRealOfString(t.to_ref(), buf)
         }
     }
@@ -757,12 +757,12 @@ pub fn C_cstr(cx: &mut CrateContext, s: @str) -> ValueRef {
             None => ()
         }
 
-        let sc = do s.to_c_str().with_ref |buf| {
-            llvm::LLVMConstStringInContext(cx.llcx, buf, s.len() as c_uint, False)
+        let sc = do s.as_imm_buf |buf, buflen| {
+            llvm::LLVMConstStringInContext(cx.llcx, buf as *c_char, buflen as c_uint, False)
         };
 
         let gsym = token::gensym("str");
-        let g = do fmt!("str%u", gsym).to_c_str().with_ref |buf| {
+        let g = do fmt!("str%u", gsym).with_c_str |buf| {
             llvm::LLVMAddGlobal(cx.llmod, val_ty(sc).to_ref(), buf)
         };
         llvm::LLVMSetInitializer(g, sc);
index b362ba396f16d97f3c858c1b7b6015ac983955f8..87d26fa5ba07c6f7b4be346e0a25166583f08159 100644 (file)
@@ -103,7 +103,7 @@ pub fn const_vec(cx: @mut CrateContext, e: &ast::expr, es: &[@ast::expr])
 
 fn const_addr_of(cx: &mut CrateContext, cv: ValueRef) -> ValueRef {
     unsafe {
-        let gv = do "const".to_c_str().with_ref |name| {
+        let gv = do "const".with_c_str |name| {
             llvm::LLVMAddGlobal(cx.llmod, val_ty(cv).to_ref(), name)
         };
         llvm::LLVMSetInitializer(gv, cv);
@@ -529,7 +529,7 @@ fn const_expr_unadjusted(cx: @mut CrateContext, e: &ast::expr) -> ValueRef {
               ast::expr_vec(ref es, ast::m_imm) => {
                 let (cv, sz, llunitty) = const_vec(cx, e, *es);
                 let llty = val_ty(cv);
-                let gv = do "const".to_c_str().with_ref |name| {
+                let gv = do "const".with_c_str |name| {
                     llvm::LLVMAddGlobal(cx.llmod, llty.to_ref(), name)
                 };
                 llvm::LLVMSetInitializer(gv, cv);
index c0c1475e80834afce5aa171010f095c4b15f5c83..5d0849ef12c9ab2ba2bcca0e845b013959ed84fc 100644 (file)
@@ -128,15 +128,15 @@ pub fn new(sess: session::Session,
         unsafe {
             let llcx = llvm::LLVMContextCreate();
             set_task_llcx(llcx);
-            let llmod = do name.to_c_str().with_ref |buf| {
+            let llmod = do name.with_c_str |buf| {
                 llvm::LLVMModuleCreateWithNameInContext(buf, llcx)
             };
             let data_layout: &str = sess.targ_cfg.target_strs.data_layout;
             let targ_triple: &str = sess.targ_cfg.target_strs.target_triple;
-            do data_layout.to_c_str().with_ref |buf| {
+            do data_layout.with_c_str |buf| {
                 llvm::LLVMSetDataLayout(llmod, buf)
             };
-            do targ_triple.to_c_str().with_ref |buf| {
+            do targ_triple.with_c_str |buf| {
                 llvm::LLVMSetTarget(llmod, buf)
             };
             let targ_cfg = sess.targ_cfg;
index ed061e66f4194dd0eab1df915f87b7fd188b8312..04d401f82970ceb567c12dd1f24f4554b26374e4 100644 (file)
@@ -237,7 +237,7 @@ pub fn trans_log(log_ex: &ast::expr,
             ccx, modpath, "loglevel");
         let global;
         unsafe {
-            global = do s.to_c_str().with_ref |buf| {
+            global = do s.with_c_str |buf| {
                 llvm::LLVMAddGlobal(ccx.llmod, Type::i32().to_ref(), buf)
             };
             llvm::LLVMSetGlobalConstant(global, False);
index 66ff2495c296de6dfcd05328a9732c5df722d73c..d23c009ac1599c87bc2ea57057f0a864510c2adb 100644 (file)
@@ -207,7 +207,7 @@ pub fn create_argument_metadata(bcx: @mut Block,
             argument_index as c_uint
         };
 
-        let arg_metadata = do name.to_c_str().with_ref |name| {
+        let arg_metadata = do name.with_c_str |name| {
             unsafe {
                 llvm::LLVMDIBuilderCreateLocalVariable(
                     DIB(cx),
@@ -351,8 +351,8 @@ pub fn create_function_metadata(fcx: &mut FunctionContext) -> DISubprogram {
     };
 
     let fn_metadata =
-        do cx.sess.str_of(ident).to_c_str().with_ref |name| {
-        do cx.sess.str_of(ident).to_c_str().with_ref |linkage| {
+        do cx.sess.str_of(ident).with_c_str |name| {
+        do cx.sess.str_of(ident).with_c_str |linkage| {
             unsafe {
                 llvm::LLVMDIBuilderCreateFunction(
                     DIB(cx),
@@ -420,11 +420,11 @@ fn compile_unit_metadata(cx: @mut CrateContext) {
     let work_dir = cx.sess.working_dir.to_str();
     let producer = fmt!("rustc version %s", env!("CFG_VERSION"));
 
-    do crate_name.to_c_str().with_ref |crate_name| {
-    do work_dir.to_c_str().with_ref |work_dir| {
-    do producer.to_c_str().with_ref |producer| {
-    do "".to_c_str().with_ref |flags| {
-    do "".to_c_str().with_ref |split_name| {
+    do crate_name.with_c_str |crate_name| {
+    do work_dir.with_c_str |work_dir| {
+    do producer.with_c_str |producer| {
+    do "".with_c_str |flags| {
+    do "".with_c_str |split_name| {
         unsafe {
             llvm::LLVMDIBuilderCreateCompileUnit(dcx.builder,
                 DW_LANG_RUST as c_uint, crate_name, work_dir, producer,
@@ -449,7 +449,7 @@ fn declare_local(bcx: @mut Block,
     let type_metadata = type_metadata(cx, variable_type, span);
     let scope = scope_metadata(bcx.fcx, node_id, span);
 
-    let var_metadata = do name.to_c_str().with_ref |name| {
+    let var_metadata = do name.with_c_str |name| {
         unsafe {
             llvm::LLVMDIBuilderCreateLocalVariable(
                 DIB(cx),
@@ -501,8 +501,8 @@ fn file_metadata(cx: &mut CrateContext, full_path: &str) -> DIFile {
         };
 
     let file_metadata =
-        do file_name.to_c_str().with_ref |file_name| {
-        do work_dir.to_c_str().with_ref |work_dir| {
+        do file_name.with_c_str |file_name| {
+        do work_dir.with_c_str |work_dir| {
             unsafe {
                 llvm::LLVMDIBuilderCreateFile(DIB(cx), file_name, work_dir)
             }
@@ -566,7 +566,7 @@ fn basic_type_metadata(cx: &mut CrateContext, t: ty::t) -> DIType {
 
     let llvm_type = type_of::type_of(cx, t);
     let (size, align) = size_and_align_of(cx, llvm_type);
-    let ty_metadata = do name.to_c_str().with_ref |name| {
+    let ty_metadata = do name.with_c_str |name| {
         unsafe {
             llvm::LLVMDIBuilderCreateBasicType(
                 DIB(cx),
@@ -587,7 +587,7 @@ fn pointer_type_metadata(cx: &mut CrateContext,
     let pointer_llvm_type = type_of::type_of(cx, pointer_type);
     let (pointer_size, pointer_align) = size_and_align_of(cx, pointer_llvm_type);
     let name = ty_to_str(cx.tcx, pointer_type);
-    let ptr_metadata = do name.to_c_str().with_ref |name| {
+    let ptr_metadata = do name.with_c_str |name| {
         unsafe {
             llvm::LLVMDIBuilderCreatePointerType(
                 DIB(cx),
@@ -681,7 +681,7 @@ fn enum_metadata(cx: &mut CrateContext,
             let name: &str = cx.sess.str_of(v.name);
             let discriminant_value = v.disr_val as c_ulonglong;
 
-            do name.to_c_str().with_ref |name| {
+            do name.with_c_str |name| {
                 unsafe {
                     llvm::LLVMDIBuilderCreateEnumerator(
                         DIB(cx),
@@ -695,7 +695,7 @@ fn enum_metadata(cx: &mut CrateContext,
     let loc = span_start(cx, span);
     let file_metadata = file_metadata(cx, loc.file.name);
 
-    let discriminant_type_metadata = do enum_name.to_c_str().with_ref |enum_name| {
+    let discriminant_type_metadata = do enum_name.with_c_str |enum_name| {
         unsafe {
             llvm::LLVMDIBuilderCreateEnumerationType(
                 DIB(cx),
@@ -732,7 +732,7 @@ fn enum_metadata(cx: &mut CrateContext,
                         Some(discriminant_type_metadata),
                         span);
 
-                    do "".to_c_str().with_ref |name| {
+                    do "".with_c_str |name| {
                         unsafe {
                             llvm::LLVMDIBuilderCreateMemberType(
                                 DIB(cx),
@@ -752,7 +752,7 @@ fn enum_metadata(cx: &mut CrateContext,
             let enum_llvm_type = type_of::type_of(cx, enum_type);
             let (enum_type_size, enum_type_align) = size_and_align_of(cx, enum_llvm_type);
 
-            return do enum_name.to_c_str().with_ref |enum_name| {
+            return do enum_name.with_c_str |enum_name| {
                 unsafe {
                     llvm::LLVMDIBuilderCreateUnionType(
                     DIB(cx),
@@ -836,7 +836,7 @@ fn composite_type_metadata(cx: &mut CrateContext,
             let member_offset = machine::llelement_offset(cx, composite_llvm_type, i);
             let member_name: &str = member_names[i];
 
-            do member_name.to_c_str().with_ref |member_name| {
+            do member_name.with_c_str |member_name| {
                 unsafe {
                     llvm::LLVMDIBuilderCreateMemberType(
                         DIB(cx),
@@ -854,7 +854,7 @@ fn composite_type_metadata(cx: &mut CrateContext,
         })
         .collect();
 
-    return do composite_type_name.to_c_str().with_ref |name| {
+    return do composite_type_name.with_c_str |name| {
         unsafe {
             llvm::LLVMDIBuilderCreateStructType(
                 DIB(cx),
@@ -1080,7 +1080,7 @@ fn unimplemented_type_metadata(cx: &mut CrateContext, t: ty::t) -> DIType {
     debug!("unimplemented_type_metadata: %?", ty::get(t));
 
     let name = ty_to_str(cx.tcx, t);
-    let metadata = do fmt!("NYI<%s>", name).to_c_str().with_ref |name| {
+    let metadata = do fmt!("NYI<%s>", name).with_c_str |name| {
         unsafe {
             llvm::LLVMDIBuilderCreateBasicType(
                 DIB(cx),
index 2a63ce976b6db273e9e1c7a1494b2f71189aaf42..04fd477a317380d2eee4a560eeb9c482e0f24bca 100644 (file)
@@ -1030,7 +1030,7 @@ fn get_val(bcx: @mut Block, did: ast::def_id, const_ty: ty::t)
                             let symbol = csearch::get_symbol(
                                 bcx.ccx().sess.cstore,
                                 did);
-                            let llval = do symbol.to_c_str().with_ref |buf| {
+                            let llval = do symbol.with_c_str |buf| {
                                 llvm::LLVMAddGlobal(bcx.ccx().llmod,
                                                     llty.to_ref(),
                                                     buf)
index 4f894deb1a1c19eed3d692569ea876997395a246..9acc3018046b3bf324559ed27675ea2ac27668fe 100644 (file)
@@ -673,7 +673,7 @@ pub fn declare_tydesc(ccx: &mut CrateContext, t: ty::t) -> @mut tydesc_info {
     let name = mangle_internal_name_by_type_and_seq(ccx, t, "tydesc").to_managed();
     note_unique_llvm_symbol(ccx, name);
     debug!("+++ declare_tydesc %s %s", ppaux::ty_to_str(ccx.tcx, t), name);
-    let gvar = do name.to_c_str().with_ref |buf| {
+    let gvar = do name.with_c_str |buf| {
         unsafe {
             llvm::LLVMAddGlobal(ccx.llmod, ccx.tydesc_type.to_ref(), buf)
         }
index f5b2ff755966e6cf3f29ff2f7b2cb2fe26202d19..9ffbafb706cd4ab8ce68d65c277a622af86e1a8e 100644 (file)
@@ -537,7 +537,7 @@ pub fn make_vtable(ccx: &mut CrateContext,
 
         let tbl = C_struct(components);
         let vtable = ccx.sess.str_of(gensym_name("vtable"));
-        let vt_gvar = do vtable.to_c_str().with_ref |buf| {
+        let vt_gvar = do vtable.with_c_str |buf| {
             llvm::LLVMAddGlobal(ccx.llmod, val_ty(tbl).to_ref(), buf)
         };
         llvm::LLVMSetInitializer(vt_gvar, tbl);
index 5b0e2fa18f240af3716c6604a6ae391512b18d5e..47d5b7ff3a53f9ae5b72793068a0b84f919b3fd8 100644 (file)
@@ -265,7 +265,7 @@ pub fn trans_lit_str(bcx: @mut Block,
         Ignore => bcx,
         SaveIn(lldest) => {
             unsafe {
-                let bytes = str_lit.len(); // count null-terminator too
+                let bytes = str_lit.len();
                 let llbytes = C_uint(bcx.ccx(), bytes);
                 let llcstr = C_cstr(bcx.ccx(), str_lit);
                 let llcstr = llvm::LLVMConstPointerCast(llcstr, Type::i8p().to_ref());
index 8d94a0d10d6fae3c71e2b5754b157886cd3fb334..f8f6f7b87ec6a9419208f6cf08bd98bde9b55226 100644 (file)
@@ -171,7 +171,7 @@ pub fn struct_(els: &[Type], packed: bool) -> Type {
 
     pub fn named_struct(name: &str) -> Type {
         let ctx = base::task_llcx();
-        ty!(name.to_c_str().with_ref(|s| llvm::LLVMStructCreateNamed(ctx, s)))
+        ty!(name.with_c_str(|s| llvm::LLVMStructCreateNamed(ctx, s)))
     }
 
     pub fn empty_struct() -> Type {
index de80aafb44135ae43358dc2dca952bf67385f540..82f098b668dc45d1dbd424e6f56816c3496c4427 100644 (file)
@@ -398,8 +398,8 @@ pub fn link_exe(src: &Path, dest: &Path) -> bool {
     use std::libc;
 
     unsafe {
-        do src.to_c_str().with_ref |src_buf| {
-            do dest.to_c_str().with_ref |dest_buf| {
+        do src.with_c_str |src_buf| {
+            do dest.with_c_str |dest_buf| {
                 libc::link(src_buf, dest_buf) == 0 as libc::c_int &&
                     libc::chmod(dest_buf, 755) == 0 as libc::c_int
             }
index 7e31354366084b061dffef714b178b0263badc03..6fc14439abb24e1a59030c770c5213522677fd23 100644 (file)
@@ -9,14 +9,28 @@
 // except according to those terms.
 
 use cast;
-use iterator::Iterator;
+use iterator::{Iterator,range};
 use libc;
 use ops::Drop;
 use option::{Option, Some, None};
 use ptr::RawPtr;
 use ptr;
 use str::StrSlice;
-use vec::ImmutableVector;
+use vec::{ImmutableVector,CopyableVector};
+use container::Container;
+
+/// Resolution options for the `null_byte` condition
+pub enum NullByteResolution {
+    /// Truncate at the null byte
+    Truncate,
+    /// Use a replacement byte
+    ReplaceWith(libc::c_char)
+}
+
+condition! {
+    // this should be &[u8] but there's a lifetime issue
+    null_byte: (~[u8]) -> super::NullByteResolution;
+}
 
 /// The representation of a C String.
 ///
@@ -34,6 +48,7 @@ pub unsafe fn new(buf: *libc::c_char, owns_buffer: bool) -> CString {
     }
 
     /// Unwraps the wrapped `*libc::c_char` from the `CString` wrapper.
+    /// Any ownership of the buffer by the `CString` wrapper is forgotten.
     pub unsafe fn unwrap(self) -> *libc::c_char {
         let mut c_str = self;
         c_str.owns_buffer_ = false;
@@ -89,7 +104,7 @@ pub fn as_bytes<'a>(&'a self) -> &'a [u8] {
     }
 
     /// Return a CString iterator.
-    fn iter<'a>(&'a self) -> CStringIterator<'a> {
+    pub fn iter<'a>(&'a self) -> CStringIterator<'a> {
         CStringIterator {
             ptr: self.buf,
             lifetime: unsafe { cast::transmute(self.buf) },
@@ -109,8 +124,38 @@ fn drop(&self) {
 
 /// A generic trait for converting a value to a CString.
 pub trait ToCStr {
-    /// Create a C String.
+    /// Copy the receiver into a CString.
+    ///
+    /// # Failure
+    ///
+    /// Raises the `null_byte` condition if the receiver has an interior null.
     fn to_c_str(&self) -> CString;
+
+    /// Unsafe variant of `to_c_str()` that doesn't check for nulls.
+    unsafe fn to_c_str_unchecked(&self) -> CString;
+
+    /// Work with a temporary CString constructed from the receiver.
+    /// The provided `*libc::c_char` will be freed immediately upon return.
+    ///
+    /// # Example
+    ///
+    /// ~~~ {.rust}
+    /// let s = "PATH".with_c_str(|path| libc::getenv(path))
+    /// ~~~
+    ///
+    /// # Failure
+    ///
+    /// Raises the `null_byte` condition if the receiver has an interior null.
+    #[inline]
+    fn with_c_str<T>(&self, f: &fn(*libc::c_char) -> T) -> T {
+        self.to_c_str().with_ref(f)
+    }
+
+    /// Unsafe variant of `with_c_str()` that doesn't check for nulls.
+    #[inline]
+    unsafe fn with_c_str_unchecked<T>(&self, f: &fn(*libc::c_char) -> T) -> T {
+        self.to_c_str_unchecked().with_ref(f)
+    }
 }
 
 impl<'self> ToCStr for &'self str {
@@ -118,22 +163,43 @@ impl<'self> ToCStr for &'self str {
     fn to_c_str(&self) -> CString {
         self.as_bytes().to_c_str()
     }
+
+    #[inline]
+    unsafe fn to_c_str_unchecked(&self) -> CString {
+        self.as_bytes().to_c_str_unchecked()
+    }
 }
 
 impl<'self> ToCStr for &'self [u8] {
     fn to_c_str(&self) -> CString {
-        do self.as_imm_buf |self_buf, self_len| {
-            unsafe {
-                let buf = libc::malloc(self_len as libc::size_t + 1) as *mut u8;
-                if buf.is_null() {
-                    fail!("failed to allocate memory!");
+        let mut cs = unsafe { self.to_c_str_unchecked() };
+        do cs.with_mut_ref |buf| {
+            for i in range(0, self.len()) {
+                unsafe {
+                    let p = buf.offset_inbounds(i as int);
+                    if *p == 0 {
+                        match null_byte::cond.raise(self.to_owned()) {
+                            Truncate => break,
+                            ReplaceWith(c) => *p = c
+                        }
+                    }
                 }
+            }
+        }
+        cs
+    }
 
-                ptr::copy_memory(buf, self_buf, self_len);
-                *ptr::mut_offset(buf, self_len as int) = 0;
-
-                CString::new(buf as *libc::c_char, true)
+    unsafe fn to_c_str_unchecked(&self) -> CString {
+        do self.as_imm_buf |self_buf, self_len| {
+            let buf = libc::malloc(self_len as libc::size_t + 1) as *mut u8;
+            if buf.is_null() {
+                fail!("failed to allocate memory!");
             }
+
+            ptr::copy_memory(buf, self_buf, self_len);
+            *ptr::mut_offset(buf, self_len as int) = 0;
+
+            CString::new(buf as *libc::c_char, true)
         }
     }
 }
@@ -230,4 +296,49 @@ fn test_iterator() {
         assert_eq!(iter.next(), Some('o' as libc::c_char));
         assert_eq!(iter.next(), None);
     }
+
+    #[test]
+    #[ignore(cfg(windows))]
+    fn test_to_c_str_fail() {
+        use c_str::null_byte::cond;
+
+        let mut error_happened = false;
+        do cond.trap(|err| {
+            assert_eq!(err, bytes!("he", 0, "llo").to_owned())
+            error_happened = true;
+            Truncate
+        }).inside {
+            "he\x00llo".to_c_str()
+        };
+        assert!(error_happened);
+
+        do cond.trap(|_| {
+            ReplaceWith('?' as libc::c_char)
+        }).inside(|| "he\x00llo".to_c_str()).with_ref |buf| {
+            unsafe {
+                assert_eq!(*buf.offset(0), 'h' as libc::c_char);
+                assert_eq!(*buf.offset(1), 'e' as libc::c_char);
+                assert_eq!(*buf.offset(2), '?' as libc::c_char);
+                assert_eq!(*buf.offset(3), 'l' as libc::c_char);
+                assert_eq!(*buf.offset(4), 'l' as libc::c_char);
+                assert_eq!(*buf.offset(5), 'o' as libc::c_char);
+                assert_eq!(*buf.offset(6), 0);
+            }
+        }
+    }
+
+    #[test]
+    fn test_to_c_str_unchecked() {
+        unsafe {
+            do "he\x00llo".to_c_str_unchecked().with_ref |buf| {
+                assert_eq!(*buf.offset(0), 'h' as libc::c_char);
+                assert_eq!(*buf.offset(1), 'e' as libc::c_char);
+                assert_eq!(*buf.offset(2), 0);
+                assert_eq!(*buf.offset(3), 'l' as libc::c_char);
+                assert_eq!(*buf.offset(4), 'l' as libc::c_char);
+                assert_eq!(*buf.offset(5), 'o' as libc::c_char);
+                assert_eq!(*buf.offset(6), 0);
+            }
+        }
+    }
 }
index 2c18bd272e81785cdc1379d708322cb0f0786918..c9e0c4f862d3a6e2f860c2f1878b51a33b6bb725 100644 (file)
@@ -1041,8 +1041,8 @@ pub fn stdin() -> @Reader {
 }
 
 pub fn file_reader(path: &Path) -> Result<@Reader, ~str> {
-    let f = do path.to_c_str().with_ref |pathbuf| {
-        do "rb".to_c_str().with_ref |modebuf| {
+    let f = do path.with_c_str |pathbuf| {
+        do "rb".with_c_str |modebuf| {
             unsafe { libc::fopen(pathbuf, modebuf as *libc::c_char) }
         }
     };
@@ -1291,7 +1291,7 @@ fn wb() -> c_int { O_WRONLY as c_int }
         }
     }
     let fd = unsafe {
-        do path.to_c_str().with_ref |pathbuf| {
+        do path.with_c_str |pathbuf| {
             libc::open(pathbuf, fflags, (S_IRUSR | S_IWUSR) as c_int)
         }
     };
@@ -1574,8 +1574,8 @@ pub fn file_writer(path: &Path, flags: &[FileFlag]) -> Result<@Writer, ~str> {
 // FIXME: fileflags // #2004
 pub fn buffered_file_writer(path: &Path) -> Result<@Writer, ~str> {
     unsafe {
-        let f = do path.to_c_str().with_ref |pathbuf| {
-            do "w".to_c_str().with_ref |modebuf| {
+        let f = do path.with_c_str |pathbuf| {
+            do "w".with_c_str |modebuf| {
                 libc::fopen(pathbuf, modebuf)
             }
         };
index c916be79c53e5a3fa13c5e0d072c3139e3a149ad..b357489d62ff82174fab87f883b9b21509f94e06 100644 (file)
@@ -239,7 +239,7 @@ fn env_convert(input: ~[~str]) -> ~[(~str, ~str)] {
 pub fn getenv(n: &str) -> Option<~str> {
     unsafe {
         do with_env_lock {
-            let s = do n.to_c_str().with_ref |buf| {
+            let s = do n.with_c_str |buf| {
                 libc::getenv(buf)
             };
             if s.is_null() {
@@ -274,8 +274,8 @@ pub fn getenv(n: &str) -> Option<~str> {
 pub fn setenv(n: &str, v: &str) {
     unsafe {
         do with_env_lock {
-            do n.to_c_str().with_ref |nbuf| {
-                do v.to_c_str().with_ref |vbuf| {
+            do n.with_c_str |nbuf| {
+                do v.with_c_str |vbuf| {
                     libc::funcs::posix01::unistd::setenv(nbuf, vbuf, 1);
                 }
             }
@@ -306,7 +306,7 @@ pub fn unsetenv(n: &str) {
     fn _unsetenv(n: &str) {
         unsafe {
             do with_env_lock {
-                do n.to_c_str().with_ref |nbuf| {
+                do n.with_c_str |nbuf| {
                     libc::funcs::posix01::unistd::unsetenv(nbuf);
                 }
             }
@@ -328,7 +328,7 @@ fn _unsetenv(n: &str) {
 }
 
 pub fn fdopen(fd: c_int) -> *FILE {
-    do "r".to_c_str().with_ref |modebuf| {
+    do "r".with_c_str |modebuf| {
         unsafe {
             libc::fdopen(fd, modebuf)
         }
@@ -464,7 +464,7 @@ fn load_self() -> Option<~str> {
             let mut path = [0 as c_char, .. TMPBUF_SZ];
 
             do path.as_mut_buf |buf, len| {
-                let len = do "/proc/self/exe".to_c_str().with_ref |proc_self_buf| {
+                let len = do "/proc/self/exe".with_c_str |proc_self_buf| {
                     readlink(proc_self_buf, buf, len as size_t) as uint
                 };
 
@@ -593,7 +593,7 @@ pub fn walk_dir(p: &Path, f: &fn(&Path) -> bool) -> bool {
 /// Indicates whether a path represents a directory
 pub fn path_is_dir(p: &Path) -> bool {
     unsafe {
-        do p.to_c_str().with_ref |buf| {
+        do p.with_c_str |buf| {
             rustrt::rust_path_is_dir(buf) != 0 as c_int
         }
     }
@@ -602,7 +602,7 @@ pub fn path_is_dir(p: &Path) -> bool {
 /// Indicates whether a path exists
 pub fn path_exists(p: &Path) -> bool {
     unsafe {
-        do p.to_c_str().with_ref |buf| {
+        do p.with_c_str |buf| {
             rustrt::rust_path_exists(buf) != 0 as c_int
         }
     }
@@ -645,7 +645,7 @@ fn mkdir(p: &Path, _mode: c_int) -> bool {
 
     #[cfg(unix)]
     fn mkdir(p: &Path, mode: c_int) -> bool {
-        do p.to_c_str().with_ref |buf| {
+        do p.with_c_str |buf| {
             unsafe {
                 libc::mkdir(buf, mode as libc::mode_t) == (0 as c_int)
             }
@@ -697,7 +697,7 @@ unsafe fn get_list(p: &Path) -> ~[~str] {
             let mut strings = ~[];
             debug!("os::list_dir -- BEFORE OPENDIR");
 
-            let dir_ptr = do p.to_c_str().with_ref |buf| {
+            let dir_ptr = do p.with_c_str |buf| {
                 opendir(buf)
             };
 
@@ -819,7 +819,7 @@ fn rmdir(p: &Path) -> bool {
 
     #[cfg(unix)]
     fn rmdir(p: &Path) -> bool {
-        do p.to_c_str().with_ref |buf| {
+        do p.with_c_str |buf| {
             unsafe {
                 libc::rmdir(buf) == (0 as c_int)
             }
@@ -844,7 +844,7 @@ fn chdir(p: &Path) -> bool {
 
     #[cfg(unix)]
     fn chdir(p: &Path) -> bool {
-        do p.to_c_str().with_ref |buf| {
+        do p.with_c_str |buf| {
             unsafe {
                 libc::chdir(buf) == (0 as c_int)
             }
@@ -872,8 +872,8 @@ fn do_copy_file(from: &Path, to: &Path) -> bool {
     #[cfg(unix)]
     fn do_copy_file(from: &Path, to: &Path) -> bool {
         unsafe {
-            let istream = do from.to_c_str().with_ref |fromp| {
-                do "rb".to_c_str().with_ref |modebuf| {
+            let istream = do from.with_c_str |fromp| {
+                do "rb".with_c_str |modebuf| {
                     libc::fopen(fromp, modebuf)
                 }
             };
@@ -884,8 +884,8 @@ fn do_copy_file(from: &Path, to: &Path) -> bool {
             let from_mode = from.get_mode().expect("copy_file: couldn't get permissions \
                                                     for source file");
 
-            let ostream = do to.to_c_str().with_ref |top| {
-                do "w+b".to_c_str().with_ref |modebuf| {
+            let ostream = do to.with_c_str |top| {
+                do "w+b".with_c_str |modebuf| {
                     libc::fopen(top, modebuf)
                 }
             };
@@ -917,7 +917,7 @@ fn do_copy_file(from: &Path, to: &Path) -> bool {
             fclose(ostream);
 
             // Give the new file the old file's permissions
-            if do to.to_c_str().with_ref |to_buf| {
+            if do to.with_c_str |to_buf| {
                 libc::chmod(to_buf, from_mode as libc::mode_t)
             } != 0 {
                 return false; // should be a condition...
@@ -944,7 +944,7 @@ fn unlink(p: &Path) -> bool {
     #[cfg(unix)]
     fn unlink(p: &Path) -> bool {
         unsafe {
-            do p.to_c_str().with_ref |buf| {
+            do p.with_c_str |buf| {
                 libc::unlink(buf) == (0 as c_int)
             }
         }
@@ -1282,7 +1282,7 @@ fn default_glob_t () -> libc::glob_t {
     }
 
     let mut g = default_glob_t();
-    do pattern.to_c_str().with_ref |c_pattern| {
+    do pattern.with_c_str |c_pattern| {
         unsafe { libc::glob(c_pattern, 0, ptr::null(), &mut g) }
     };
     do(|| {
@@ -1929,14 +1929,14 @@ fn copy_file_ok() {
             let out = tempdir.push("out.txt");
 
             /* Write the temp input file */
-            let ostream = do input.to_c_str().with_ref |fromp| {
-                do "w+b".to_c_str().with_ref |modebuf| {
+            let ostream = do input.with_c_str |fromp| {
+                do "w+b".with_c_str |modebuf| {
                     libc::fopen(fromp, modebuf)
                 }
             };
             assert!((ostream as uint != 0u));
             let s = ~"hello";
-            do "hello".to_c_str().with_ref |buf| {
+            do "hello".with_c_str |buf| {
                 let write_len = libc::fwrite(buf as *c_void,
                                              1u as size_t,
                                              (s.len() + 1u) as size_t,
@@ -2013,11 +2013,11 @@ fn lseek_(fd: c_int, size: uint) {
         remove_file(&path);
 
         let fd = unsafe {
-            let fd = do path.to_c_str().with_ref |path| {
+            let fd = do path.with_c_str |path| {
                 open(path, O_CREAT | O_RDWR | O_TRUNC, S_IRUSR | S_IWUSR)
             };
             lseek_(fd, size);
-            do "x".to_c_str().with_ref |x| {
+            do "x".with_c_str |x| {
                 assert!(write(fd, x as *c_void, 1) == 1);
             }
             fd
index 177f0efb6dad380677fef7b9d442ddbb5bf11411..de7658b5710b32cded88809f57693383a8896b5e 100644 (file)
@@ -381,7 +381,7 @@ pub fn default_stat() -> libc::stat {
 #[cfg(target_os = "win32")]
 impl WindowsPath {
     pub fn stat(&self) -> Option<libc::stat> {
-        do self.to_c_str().with_ref |buf| {
+        do self.with_c_str |buf| {
             let mut st = stat::arch::default_stat();
             match unsafe { libc::stat(buf, &mut st) } {
                 0 => Some(st),
@@ -415,7 +415,7 @@ pub fn get_mode(&self) -> Option<uint> {
 #[cfg(not(target_os = "win32"))]
 impl PosixPath {
     pub fn stat(&self) -> Option<libc::stat> {
-        do self.to_c_str().with_ref |buf| {
+        do self.with_c_str |buf| {
             let mut st = stat::arch::default_stat();
             match unsafe { libc::stat(buf as *libc::c_char, &mut st) } {
                 0 => Some(st),
@@ -493,7 +493,7 @@ pub fn get_ctime(&self) -> Option<(i64, int)> {
 #[cfg(unix)]
 impl PosixPath {
     pub fn lstat(&self) -> Option<libc::stat> {
-        do self.to_c_str().with_ref |buf| {
+        do self.with_c_str |buf| {
             let mut st = stat::arch::default_stat();
             match unsafe { libc::lstat(buf, &mut st) } {
                 0 => Some(st),
@@ -569,6 +569,10 @@ impl ToCStr for PosixPath {
     fn to_c_str(&self) -> c_str::CString {
         self.to_str().to_c_str()
     }
+
+    unsafe fn to_c_str_unchecked(&self) -> c_str::CString {
+        self.to_str().to_c_str_unchecked()
+    }
 }
 
 // FIXME (#3227): when default methods in traits are working, de-duplicate
@@ -781,6 +785,10 @@ impl c_str::ToCStr for WindowsPath {
     fn to_c_str(&self) -> c_str::CString {
         self.to_str().to_c_str()
     }
+
+    unsafe fn to_c_str_unchecked(&self) -> c_str::CString {
+        self.to_str().to_c_str_unchecked()
+    }
 }
 
 impl GenericPath for WindowsPath {
index 50c25a2f722f841d322a5e8557ceb7597f46c17e..de8f8c69e8432e25cd4137f9eae6007c3e59b561 100644 (file)
@@ -482,7 +482,7 @@ struct Pair {
     fn test_position() {
         use libc::c_char;
 
-        do "hello".to_c_str().with_ref |p| {
+        do "hello".with_c_str |p| {
             unsafe {
                 assert!(2u == position(p, |c| *c == 'l' as c_char));
                 assert!(4u == position(p, |c| *c == 'o' as c_char));
@@ -493,9 +493,9 @@ fn test_position() {
 
     #[test]
     fn test_buf_len() {
-        do "hello".to_c_str().with_ref |p0| {
-            do "there".to_c_str().with_ref |p1| {
-                do "thing".to_c_str().with_ref |p2| {
+        do "hello".with_c_str |p0| {
+            do "there".with_c_str |p1| {
+                do "thing".with_c_str |p2| {
                     let v = ~[p0, p1, p2, null()];
                     do v.as_imm_buf |vp, len| {
                         assert_eq!(unsafe { buf_len(vp) }, 3u);
index f620a7347a4cd31bf403146bfa4c62c2ceff9a5e..ba4cbc668038fcec80364da26d167f7ae5e762cd 100644 (file)
@@ -52,7 +52,7 @@ unsafe fn fail_borrowed(box: *mut raw::Box<()>, file: *c_char, line: size_t) {
     match try_take_task_borrow_list() {
         None => { // not recording borrows
             let msg = "borrowed";
-            do msg.to_c_str().with_ref |msg_p| {
+            do msg.with_c_str |msg_p| {
                 sys::begin_unwind_(msg_p, file, line);
             }
         }
@@ -68,7 +68,7 @@ unsafe fn fail_borrowed(box: *mut raw::Box<()>, file: *c_char, line: size_t) {
                     sep = " and at ";
                 }
             }
-            do msg.to_c_str().with_ref |msg_p| {
+            do msg.with_c_str |msg_p| {
                 sys::begin_unwind_(msg_p, file, line)
             }
         }
@@ -208,7 +208,7 @@ pub unsafe fn unrecord_borrow(a: *u8, old_ref_count: uint,
             let br = borrow_list.pop();
             if br.box != a || br.file != file || br.line != line {
                 let err = fmt!("wrong borrow found, br=%?", br);
-                do err.to_c_str().with_ref |msg_p| {
+                do err.with_c_str |msg_p| {
                     sys::begin_unwind_(msg_p, file, line)
                 }
             }
index 117795f6c90e0ab49860e92cd73c6277fceea12a..4ee65a2b4495fa275d6baca8c4393229f4292155 100644 (file)
@@ -66,7 +66,7 @@ pub fn init(crate_map: *u8) {
     let log_spec = os::getenv("RUST_LOG");
     match log_spec {
         Some(spec) => {
-            do spec.to_c_str().with_ref |buf| {
+            do spec.with_c_str |buf| {
                 unsafe { rust_update_log_settings(crate_map, buf) }
             }
         }
index 038ebad3540aecd29657474dffaacaaf8a2ab365..a26b8a3ad594de52f5bc128b24eaa580f664fe02 100644 (file)
@@ -654,7 +654,7 @@ fn sendto(&mut self, buf: &[u8], dst: SocketAddr) -> Result<(), IoError> {
 
     fn join_multicast(&mut self, multi: IpAddr) -> Result<(), IoError> {
         let r = unsafe {
-            do multi.to_str().to_c_str().with_ref |m_addr| {
+            do multi.to_str().with_c_str |m_addr| {
                 uvll::udp_set_membership(self.native_handle(), m_addr,
                                          ptr::null(), uvll::UV_JOIN_GROUP)
             }
@@ -668,7 +668,7 @@ fn join_multicast(&mut self, multi: IpAddr) -> Result<(), IoError> {
 
     fn leave_multicast(&mut self, multi: IpAddr) -> Result<(), IoError> {
         let r = unsafe {
-            do multi.to_str().to_c_str().with_ref |m_addr| {
+            do multi.to_str().with_c_str |m_addr| {
                 uvll::udp_set_membership(self.native_handle(), m_addr,
                                          ptr::null(), uvll::UV_LEAVE_GROUP)
             }
index e240395a495d36f02f60cc0daadd06c58353c773..11d64f4697cb8e3ad28950b591b39b4684642a76 100644 (file)
@@ -373,12 +373,12 @@ pub unsafe fn is_ip6_addr(addr: *sockaddr) -> bool {
 }
 
 pub unsafe fn malloc_ip4_addr(ip: &str, port: int) -> *sockaddr_in {
-    do ip.to_c_str().with_ref |ip_buf| {
+    do ip.with_c_str |ip_buf| {
         rust_uv_ip4_addrp(ip_buf as *u8, port as libc::c_int)
     }
 }
 pub unsafe fn malloc_ip6_addr(ip: &str, port: int) -> *sockaddr_in6 {
-    do ip.to_c_str().with_ref |ip_buf| {
+    do ip.with_c_str |ip_buf| {
         rust_uv_ip6_addrp(ip_buf as *u8, port as libc::c_int)
     }
 }
index 4d751101d730d4c44316d188d5497f1f08eccaff..bd284b39983045f8a64324c2c8a84064a908ac75 100644 (file)
@@ -506,7 +506,7 @@ fn spawn_process_os(prog: &str, args: &[~str],
 
         do with_envp(env) |envp| {
             do with_dirp(dir) |dirp| {
-                do cmd.to_c_str().with_ref |cmdp| {
+                do cmd.with_c_str |cmdp| {
                     let created = CreateProcessA(ptr::null(), cast::transmute(cmdp),
                                                  ptr::mut_null(), ptr::mut_null(), TRUE,
                                                  0, envp, dirp, &mut si, &mut pi);
@@ -775,7 +775,7 @@ fn with_envp<T>(env: Option<~[(~str, ~str)]>, cb: &fn(*mut c_void) -> T) -> T {
 
 fn with_dirp<T>(d: Option<&Path>, cb: &fn(*libc::c_char) -> T) -> T {
     match d {
-      Some(dir) => dir.to_c_str().with_ref(|buf| cb(buf)),
+      Some(dir) => dir.with_c_str(|buf| cb(buf)),
       None => cb(ptr::null())
     }
 }
index 03e6412fcb8c739fb8bcc562123a66bfdb1549de..bfb9bee78028c3d59755739f3021f64194d0c427 100644 (file)
@@ -105,8 +105,8 @@ pub trait FailWithCause {
 
 impl FailWithCause for ~str {
     fn fail_with(cause: ~str, file: &'static str, line: uint) -> ! {
-        do cause.to_c_str().with_ref |msg_buf| {
-            do file.to_c_str().with_ref |file_buf| {
+        do cause.with_c_str |msg_buf| {
+            do file.with_c_str |file_buf| {
                 begin_unwind_(msg_buf, file_buf, line as libc::size_t)
             }
         }
@@ -115,8 +115,8 @@ fn fail_with(cause: ~str, file: &'static str, line: uint) -> ! {
 
 impl FailWithCause for &'static str {
     fn fail_with(cause: &'static str, file: &'static str, line: uint) -> ! {
-        do cause.to_c_str().with_ref |msg_buf| {
-            do file.to_c_str().with_ref |file_buf| {
+        do cause.with_c_str |msg_buf| {
+            do file.with_c_str |file_buf| {
                 begin_unwind_(msg_buf, file_buf, line as libc::size_t)
             }
         }
index 49e3e0777df84e58356fe734fe07d3e37c36f34f..005cedd0ffdfdccca83d869c3b519e091beb4f6e 100644 (file)
@@ -66,7 +66,7 @@ pub unsafe fn symbol<T>(&self, symbol: &str) -> Result<T, ~str> {
         // T but that feature is still unimplemented
 
         let maybe_symbol_value = do dl::check_for_errors_in {
-            do symbol.to_c_str().with_ref |raw_string| {
+            do symbol.with_c_str |raw_string| {
                 dl::symbol(self.handle, raw_string)
             }
         };
@@ -145,7 +145,7 @@ mod dl {
     use result::*;
 
     pub unsafe fn open_external(filename: &path::Path) -> *libc::c_void {
-        do filename.to_c_str().with_ref |raw_name| {
+        do filename.with_c_str |raw_name| {
             dlopen(raw_name, Lazy as libc::c_int)
         }
     }
index 956ffb82902de0addac7b55c8b0a33f9e22b2e7f..91b4283ba12dd92236cb847bbaf833331bbd2fa9 100644 (file)
@@ -29,7 +29,7 @@ pub fn fail_bounds_check(file: *c_char, line: size_t,
                          index: size_t, len: size_t) {
     let msg = fmt!("index out of bounds: the len is %d but the index is %d",
                     len as int, index as int);
-    do msg.to_c_str().with_ref |buf| {
+    do msg.with_c_str |buf| {
         fail_(buf, file, line);
     }
 }
index e91c11f5cd0a703eea86f5080aec6051d1c52bf9..22c5e9dad25a4723cab72ca83277e7daf3acf79d 100644 (file)
@@ -20,11 +20,11 @@ mod libc {
 }
 
 fn atol(s: ~str) -> int {
-    s.to_c_str().with_ref(|x| unsafe { libc::atol(x as *u8) })
+    s.with_c_str(|x| unsafe { libc::atol(x as *u8) })
 }
 
 fn atoll(s: ~str) -> i64 {
-    s.to_c_str().with_ref(|x| unsafe { libc::atoll(x as *u8) })
+    s.with_c_str(|x| unsafe { libc::atoll(x as *u8) })
 }
 
 pub fn main() {
index b5a114ef22364e64dc2bea3f7ccf326b914afa50..827f950dab241ec9924c16ebd736d6fdec2de15f 100644 (file)
@@ -26,7 +26,7 @@ mod libc {
 fn strlen(str: ~str) -> uint {
     unsafe {
         // C string is terminated with a zero
-        do str.to_c_str().with_ref |buf| {
+        do str.with_c_str |buf| {
             libc::my_strlen(buf as *u8)
         }
     }