]> git.lizzy.rs Git - rust.git/commitdiff
std: replace str::as_c_str with std::c_str
authorErick Tryzelaar <erick.tryzelaar@gmail.com>
Sun, 4 Aug 2013 00:13:14 +0000 (17:13 -0700)
committerErick Tryzelaar <erick.tryzelaar@gmail.com>
Sun, 4 Aug 2013 21:13:17 +0000 (14:13 -0700)
35 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/type_.rs
src/librustpkg/util.rs
src/libstd/c_str.rs [new file with mode: 0644]
src/libstd/io.rs
src/libstd/os.rs
src/libstd/path.rs
src/libstd/prelude.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/std.rs
src/libstd/str.rs
src/libstd/sys.rs
src/libstd/unstable/dynamic_lib.rs
src/libstd/unstable/lang.rs
src/test/run-pass/foreign-fn-linkname.rs

index 8aff8d388877f367e8e042cd4b23518b8b97c83b..9106d4cd684d916f5c6d58bcbb83dd87962cce90 100644 (file)
@@ -11,7 +11,7 @@
 // FIXME #3921. This is unsafe because linenoise uses global mutable
 // state without mutexes.
 
-
+use std::c_str::ToCStr;
 use std::libc::{c_char, c_int};
 use std::local_data;
 use std::str;
@@ -32,7 +32,7 @@ pub mod rustrt {
 
 /// Add a line to history
 pub unsafe fn add_history(line: &str) -> bool {
-    do line.as_c_str |buf| {
+    do line.to_c_str().with_ref |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.as_c_str |buf| {
+    do file.to_c_str().with_ref |buf| {
         rustrt::linenoiseHistorySave(buf) == 1 as c_int
     }
 }
 
 /// Load line history from a file
 pub unsafe fn load_history(file: &str) -> bool {
-    do file.as_c_str |buf| {
+    do file.to_c_str().with_ref |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.as_c_str |buf| {
+    do prompt.to_c_str().with_ref |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.as_c_str |buf| {
+                    do suggestion.to_c_str().with_ref |buf| {
                         rustrt::linenoiseAddCompletion(completions, buf);
                     }
                 }
index 02cb7f168ce7b34862b40c014ac6ddb2f1c69e38..3d02d50b49125b0315ef1f9bddf1efe28a6063c2 100644 (file)
@@ -22,6 +22,7 @@
 use middle::ty;
 use util::ppaux;
 
+use std::c_str::ToCStr;
 use std::char;
 use std::hash::Streaming;
 use std::hash;
@@ -76,9 +77,9 @@ pub fn WriteOutputFile(sess: Session,
         OptLevel: c_int,
         EnableSegmentedStacks: bool) {
     unsafe {
-        do Triple.as_c_str |Triple| {
-            do Feature.as_c_str |Feature| {
-                do Output.as_c_str |Output| {
+        do Triple.to_c_str().with_ref |Triple| {
+            do Feature.to_c_str().with_ref |Feature| {
+                do Output.to_c_str().with_ref |Output| {
                     let result = llvm::LLVMRustWriteOutputFile(
                             PM,
                             M,
@@ -105,6 +106,7 @@ pub mod jit {
     use lib::llvm::{ModuleRef, ContextRef, ExecutionEngineRef};
     use metadata::cstore;
 
+    use std::c_str::ToCStr;
     use std::cast;
     use std::local_data;
     use std::unstable::intrinsics;
@@ -146,7 +148,7 @@ pub fn exec(sess: Session,
 
                 debug!("linking: %s", path);
 
-                do path.as_c_str |buf_t| {
+                do path.to_c_str().with_ref |buf_t| {
                     if !llvm::LLVMRustLoadCrate(manager, buf_t) {
                         llvm_err(sess, ~"Could not link");
                     }
@@ -165,7 +167,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".as_c_str |entry| {
+            let fun = do "_rust_main".to_c_str().with_ref |entry| {
                 llvm::LLVMGetNamedFunction(m, entry)
             };
             if fun.is_null() {
@@ -230,6 +232,7 @@ pub mod write {
 
     use back::passes;
 
+    use std::c_str::ToCStr;
     use std::libc::{c_int, c_uint};
     use std::path::Path;
     use std::run;
@@ -263,14 +266,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_str().as_c_str |buf| {
+                        do filename.to_c_str().with_ref |buf| {
                             llvm::LLVMWriteBitcodeToFile(llmod, buf);
                         }
                     }
                   }
                   _ => {
                     let filename = output.with_filetype("bc");
-                    do filename.to_str().as_c_str |buf| {
+                    do filename.to_c_str().with_ref |buf| {
                         llvm::LLVMWriteBitcodeToFile(llmod, buf);
                     }
                   }
@@ -333,7 +336,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_str().as_c_str |buf| {
+                    do filename.to_c_str().with_ref |buf| {
                         llvm::LLVMWriteBitcodeToFile(llmod, buf)
                     };
                     // Save the assembly file if -S is used
@@ -391,13 +394,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_str().as_c_str |buf_o| {
+                do output.to_c_str().with_ref |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_str().as_c_str |buf| {
+                do output.to_c_str().with_ref |buf| {
                     llvm::LLVMWriteBitcodeToFile(llmod, buf);
                 }
             }
index 831719135b13d9f365ba30966e7061c46ccf6723..eb70a811fe00b4ac31961d551909d13fd30cabcb 100644 (file)
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use std::c_str::ToCStr;
 use std::io;
 
 use driver::session::{OptLevel, No, Less, Aggressive};
@@ -173,7 +174,7 @@ pub fn populate_pass_manager(sess: Session, pm: &mut PassManager, pass_list:&[~s
 }
 
 pub fn create_pass(name:&str) -> Option<PassRef> {
-    do name.as_c_str |s| {
+    do name.to_c_str().with_ref |s| {
         unsafe {
             let p = llvm::LLVMCreatePass(s);
             if p.is_null() {
index 6c631a104aa9f0fa3c4acb74b575b0b9893dff29..98f32af2f30aa1a41bacd1904c137e2016804437 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-
+use std::c_str::ToCStr;
 use std::hashmap::HashMap;
 use std::libc::{c_uint, c_ushort};
 use std::option;
@@ -2234,7 +2234,7 @@ pub struct TargetData {
 }
 
 pub fn mk_target_data(string_rep: &str) -> TargetData {
-    let lltd = do string_rep.as_c_str |buf| {
+    let lltd = do string_rep.to_c_str().with_ref |buf| {
         unsafe { llvm::LLVMCreateTargetData(buf) }
     };
 
index 89a53df731695f46b221395b507a23a79303abd7..8b41277a3dab70f613c58df24c0dbcdf892f4e29 100644 (file)
@@ -24,6 +24,7 @@
 use syntax::{ast, attr};
 use syntax::attr::AttrMetaMethods;
 
+use std::c_str::ToCStr;
 use std::cast;
 use std::io;
 use std::num;
@@ -186,7 +187,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_str().as_c_str |buf| {
+        let mb = do filename.to_c_str().with_ref |buf| {
             llvm::LLVMRustCreateMemoryBufferWithContentsOfFile(buf)
         };
         if mb as int == 0 { return option::None::<@~[u8]>; }
index 2c7e3ae0043c0f42c0986b80a0a179137caf7334..9973599e339545f69778b0204533754f0ed4825b 100644 (file)
@@ -12,6 +12,7 @@
 # Translation of inline assembly.
 */
 
+use std::c_str::ToCStr;
 
 use lib;
 use middle::trans::build::*;
@@ -122,8 +123,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.as_c_str |a| {
-        do constraints.as_c_str |c| {
+    let r = do ia.asm.to_c_str().with_ref |a| {
+        do constraints.to_c_str().with_ref |c| {
             InlineAsmCall(bcx, a, c, inputs, output, ia.volatile, ia.alignstack, dialect)
         }
     };
index e0a7cd8cc0b57871fbe707ca1b5203162bde68bf..5b048558fd117ca89264c04c65e4fac9ff302c6e 100644 (file)
@@ -65,6 +65,7 @@
 
 use middle::trans::type_::Type;
 
+use std::c_str::ToCStr;
 use std::hash;
 use std::hashmap::HashMap;
 use std::io;
@@ -179,7 +180,7 @@ pub fn drop(&self) {
 }
 
 pub fn decl_fn(llmod: ModuleRef, name: &str, cc: lib::llvm::CallConv, ty: Type) -> ValueRef {
-    let llfn: ValueRef = do name.as_c_str |buf| {
+    let llfn: ValueRef = do name.to_c_str().with_ref |buf| {
         unsafe {
             llvm::LLVMGetOrInsertFunction(llmod, buf, ty.to_ref())
         }
@@ -219,7 +220,7 @@ pub fn get_extern_const(externs: &mut ExternMap, llmod: ModuleRef,
         None => ()
     }
     unsafe {
-        let c = do name.as_c_str |buf| {
+        let c = do name.to_c_str().with_ref |buf| {
             llvm::LLVMAddGlobal(llmod, ty.to_ref(), buf)
         };
         externs.insert(name, c);
@@ -548,7 +549,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.as_c_str |buf| {
+        do s.to_c_str().with_ref |buf| {
             unsafe {
                 llvm::LLVMSetValueName(v, buf)
             }
@@ -1162,7 +1163,7 @@ pub fn new_block(cx: @mut FunctionContext,
                  opt_node_info: Option<NodeInfo>)
               -> @mut Block {
     unsafe {
-        let llbb = do name.as_c_str |buf| {
+        let llbb = do name.to_c_str().with_ref |buf| {
             llvm::LLVMAppendBasicBlockInContext(cx.ccx.llcx, cx.llfn, buf)
         };
         let bcx = @mut Block::new(llbb,
@@ -1579,7 +1580,7 @@ pub struct BasicBlocks {
 pub fn mk_staticallocas_basic_block(llfn: ValueRef) -> BasicBlockRef {
     unsafe {
         let cx = task_llcx();
-        do "static_allocas".as_c_str | buf| {
+        do "static_allocas".to_c_str().with_ref | buf| {
             llvm::LLVMAppendBasicBlockInContext(cx, llfn, buf)
         }
     }
@@ -1588,7 +1589,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".as_c_str |buf| {
+        do "return".to_c_str().with_ref |buf| {
             llvm::LLVMAppendBasicBlockInContext(cx, llfn, buf)
         }
     }
@@ -2346,7 +2347,7 @@ fn create_entry_fn(ccx: @mut CrateContext,
             };
             decl_cdecl_fn(ccx.llmod, main_name, llfty)
         };
-        let llbb = do "top".as_c_str |buf| {
+        let llbb = do "top".to_c_str().with_ref |buf| {
             unsafe {
                 llvm::LLVMAppendBasicBlockInContext(ccx.llcx, llfn, buf)
             }
@@ -2356,7 +2357,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".as_c_str |buf| {
+            let opaque_crate_map = do "crate_map".to_c_str().with_ref |buf| {
                 llvm::LLVMBuildPointerCast(bld, crate_map, Type::i8p().to_ref(), buf)
             };
 
@@ -2374,7 +2375,7 @@ fn create_entry_fn(ccx: @mut CrateContext,
                 };
 
                 let args = {
-                    let opaque_rust_main = do "rust_main".as_c_str |buf| {
+                    let opaque_rust_main = do "rust_main".to_c_str().with_ref |buf| {
                         llvm::LLVMBuildPointerCast(bld, rust_main, Type::i8p().to_ref(), buf)
                     };
 
@@ -2462,7 +2463,7 @@ pub fn get_item_val(ccx: @mut CrateContext, id: ast::NodeId) -> ValueRef {
 
                             unsafe {
                                 let llty = llvm::LLVMTypeOf(v);
-                                let g = do sym.as_c_str |buf| {
+                                let g = do sym.to_c_str().with_ref |buf| {
                                     llvm::LLVMAddGlobal(ccx.llmod, llty, buf)
                                 };
 
@@ -2486,7 +2487,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.as_c_str |buf| {
+                            do sect.to_c_str().with_ref |buf| {
                                 llvm::LLVMSetSection(v, buf);
                             }
                         },
@@ -2527,7 +2528,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.as_c_str |buf| {
+                            let g = do ident.to_c_str().with_ref |buf| {
                                 unsafe {
                                     let ty = type_of(ccx, ty);
                                     llvm::LLVMAddGlobal(ccx.llmod, ty.to_ref(), buf)
@@ -2633,7 +2634,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.as_c_str |buf| {
+            let discrim_gvar = do s.to_c_str().with_ref |buf| {
                 unsafe {
                     llvm::LLVMAddGlobal(ccx.llmod, ccx.int_type.to_ref(), buf)
                 }
@@ -2774,7 +2775,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.as_c_str |buf| {
+    let gc_metadata = do gc_metadata_name.to_c_str().with_ref |buf| {
         unsafe {
             llvm::LLVMAddGlobal(ccx.llmod, Type::i32().to_ref(), buf)
         }
@@ -2789,7 +2790,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".as_c_str |buf| {
+    let map = do "_rust_mod_map".to_c_str().with_ref |buf| {
         unsafe {
             llvm::LLVMAddGlobal(ccx.llmod, maptype.to_ref(), buf)
         }
@@ -2837,7 +2838,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.as_c_str |buf| {
+    let map = do sym_name.to_c_str().with_ref |buf| {
         unsafe {
             llvm::LLVMAddGlobal(llmod, maptype.to_ref(), buf)
         }
@@ -2856,7 +2857,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.as_c_str |buf| {
+        let cr = do nm.to_c_str().with_ref |buf| {
             unsafe {
                 llvm::LLVMAddGlobal(ccx.llmod, ccx.int_type.to_ref(), buf)
             }
@@ -2919,21 +2920,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".as_c_str |buf| {
+    let mut llglobal = do "rust_metadata".to_c_str().with_ref |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.as_c_str |buf| {
+        do cx.sess.targ_cfg.target_strs.meta_sect_name.to_c_str().with_ref |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".as_c_str |buf| {
+        let llvm_used = do "llvm.used".to_c_str().with_ref |buf| {
             llvm::LLVMAddGlobal(cx.llmod, Type::array(&t_ptr_i8, 1).to_ref(), buf)
         };
         lib::llvm::SetLinkage(llvm_used, lib::llvm::AppendingLinkage);
@@ -2947,7 +2948,7 @@ fn mk_global(ccx: &CrateContext,
              internal: bool)
           -> ValueRef {
     unsafe {
-        let llglobal = do name.as_c_str |buf| {
+        let llglobal = do name.to_c_str().with_ref |buf| {
             llvm::LLVMAddGlobal(ccx.llmod, val_ty(llval).to_ref(), buf)
         };
         llvm::LLVMSetInitializer(llglobal, llval);
index 9d44dacfd68542faea349d41682dbb98e540b4a5..bfdee1b8f34df4ff92e44dcb80cf04fcba2171d2 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.as_c_str |c| {
+                do name.to_c_str().with_ref |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.as_c_str |c| {
+            let asm = do comment_text.to_c_str().with_ref |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".as_c_str |buf| {
+            let T: ValueRef = do "llvm.trap".to_c_str().with_ref |buf| {
                 llvm::LLVMGetNamedFunction(M, buf)
             };
             assert!((T as int != 0));
index df59133d9706e71c298337ddd4c89e2f902c134a..4f5fae8db1a4cf4783d82969f7273749a575b577 100644 (file)
@@ -31,6 +31,7 @@
 
 use middle::trans::type_::Type;
 
+use std::c_str::ToCStr;
 use std::cast::transmute;
 use std::cast;
 use std::hashmap::{HashMap};
@@ -707,7 +708,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.as_c_str |buf| {
+        do s.to_c_str().with_ref |buf| {
             llvm::LLVMConstRealOfString(t.to_ref(), buf)
         }
     }
@@ -755,12 +756,12 @@ pub fn C_cstr(cx: &mut CrateContext, s: @str) -> ValueRef {
             None => ()
         }
 
-        let sc = do s.as_c_str |buf| {
+        let sc = do s.to_c_str().with_ref |buf| {
             llvm::LLVMConstStringInContext(cx.llcx, buf, s.len() as c_uint, False)
         };
 
         let gsym = token::gensym("str");
-        let g = do fmt!("str%u", gsym).as_c_str |buf| {
+        let g = do fmt!("str%u", gsym).to_c_str().with_ref |buf| {
             llvm::LLVMAddGlobal(cx.llmod, val_ty(sc).to_ref(), buf)
         };
         llvm::LLVMSetInitializer(g, sc);
index 40d0d77c16ecb11cfe39ddcc75bc86a059ba1823..0cb423d4921eb77a0ab654d279d5b6d2e892bc9d 100644 (file)
@@ -30,6 +30,7 @@
 
 use middle::trans::type_::Type;
 
+use std::c_str::ToCStr;
 use std::libc::c_uint;
 use syntax::{ast, ast_util, ast_map};
 
@@ -101,7 +102,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".as_c_str |name| {
+        let gv = do "const".to_c_str().with_ref |name| {
             llvm::LLVMAddGlobal(cx.llmod, val_ty(cv).to_ref(), name)
         };
         llvm::LLVMSetInitializer(gv, cv);
@@ -527,7 +528,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".as_c_str |name| {
+                let gv = do "const".to_c_str().with_ref |name| {
                     llvm::LLVMAddGlobal(cx.llmod, llty.to_ref(), name)
                 };
                 llvm::LLVMSetInitializer(gv, cv);
index 802163583d6a1dacb8ee552cbf392403f5d7ca27..54c957d115a4da811d9e4d7120ff2cf8d414e345 100644 (file)
@@ -26,6 +26,7 @@
 
 use middle::trans::type_::Type;
 
+use std::c_str::ToCStr;
 use std::hash;
 use std::hashmap::{HashMap, HashSet};
 use std::local_data;
@@ -124,11 +125,17 @@ pub fn new(sess: session::Session,
         unsafe {
             let llcx = llvm::LLVMContextCreate();
             set_task_llcx(llcx);
-            let llmod = name.as_c_str(|buf| llvm::LLVMModuleCreateWithNameInContext(buf, llcx));
+            let llmod = do name.to_c_str().with_ref |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;
-            data_layout.as_c_str(|buf| llvm::LLVMSetDataLayout(llmod, buf));
-            targ_triple.as_c_str(|buf| llvm::LLVMSetTarget(llmod, buf));
+            do data_layout.to_c_str().with_ref |buf| {
+                llvm::LLVMSetDataLayout(llmod, buf)
+            };
+            do targ_triple.to_c_str().with_ref |buf| {
+                llvm::LLVMSetTarget(llmod, buf)
+            };
             let targ_cfg = sess.targ_cfg;
 
             let td = mk_target_data(sess.targ_cfg.target_strs.data_layout);
index 7d9eb95505bb7d4887b936bbac26bbfd3e51900c..ec96371132e96b19e23b3d01a6e61f2b278f82bc 100644 (file)
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use std::c_str::ToCStr;
 
 use back::link;
 use lib;
@@ -240,7 +241,7 @@ pub fn trans_log(log_ex: &ast::expr,
             ccx, modpath, "loglevel");
         let global;
         unsafe {
-            global = do s.as_c_str |buf| {
+            global = do s.to_c_str().with_ref |buf| {
                 llvm::LLVMAddGlobal(ccx.llmod, Type::i32().to_ref(), buf)
             };
             llvm::LLVMSetGlobalConstant(global, False);
index e31a27a4c6ca0a035e2dcf9e2e158833e6bf13f8..c427c34e1d85dbed268a5f0179b2924429109ea7 100644 (file)
@@ -63,6 +63,7 @@
 use middle::pat_util;
 use util::ppaux::ty_to_str;
 
+use std::c_str::ToCStr;
 use std::hashmap::HashMap;
 use std::libc::{c_uint, c_ulonglong, c_longlong};
 use std::ptr;
@@ -159,7 +160,7 @@ pub fn create_local_var_metadata(bcx: @mut Block, local: &ast::Local) {
         let ty = node_id_type(bcx, node_id);
         let type_metadata = type_metadata(cx, ty, span);
 
-        let var_metadata = do name.as_c_str |name| {
+        let var_metadata = do name.to_c_str().with_ref |name| {
             unsafe {
                 llvm::LLVMDIBuilderCreateLocalVariable(
                     DIB(cx),
@@ -246,7 +247,7 @@ pub fn create_argument_metadata(bcx: @mut Block,
             argument_index as c_uint
         };
 
-        let arg_metadata = do name.as_c_str |name| {
+        let arg_metadata = do name.to_c_str().with_ref |name| {
             unsafe {
                 llvm::LLVMDIBuilderCreateLocalVariable(
                     DIB(cx),
@@ -382,8 +383,8 @@ pub fn create_function_metadata(fcx: &FunctionContext) -> DISubprogram {
     };
 
     let fn_metadata =
-        do cx.sess.str_of(ident).as_c_str |name| {
-        do cx.sess.str_of(ident).as_c_str |linkage| {
+        do cx.sess.str_of(ident).to_c_str().with_ref |name| {
+        do cx.sess.str_of(ident).to_c_str().with_ref |linkage| {
             unsafe {
                 llvm::LLVMDIBuilderCreateFunction(
                     DIB(cx),
@@ -430,11 +431,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.as_c_str |crate_name| {
-    do work_dir.as_c_str |work_dir| {
-    do producer.as_c_str |producer| {
-    do "".as_c_str |flags| {
-    do "".as_c_str |split_name| {
+    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| {
         unsafe {
             llvm::LLVMDIBuilderCreateCompileUnit(dcx.builder,
                 DW_LANG_RUST as c_uint, crate_name, work_dir, producer,
@@ -461,8 +462,8 @@ fn file_metadata(cx: &mut CrateContext, full_path: &str) -> DIFile {
         };
 
     let file_metadata =
-        do file_name.as_c_str |file_name| {
-        do work_dir.as_c_str |work_dir| {
+        do file_name.to_c_str().with_ref |file_name| {
+        do work_dir.to_c_str().with_ref |work_dir| {
             unsafe {
                 llvm::LLVMDIBuilderCreateFile(DIB(cx), file_name, work_dir)
             }
@@ -550,7 +551,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.as_c_str |name| {
+    let ty_metadata = do name.to_c_str().with_ref |name| {
         unsafe {
             llvm::LLVMDIBuilderCreateBasicType(
                 DIB(cx),
@@ -571,7 +572,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.as_c_str |name| {
+    let ptr_metadata = do name.to_c_str().with_ref |name| {
         unsafe {
             llvm::LLVMDIBuilderCreatePointerType(
                 DIB(cx),
@@ -665,7 +666,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.as_c_str |name| {
+            do name.to_c_str().with_ref |name| {
                 unsafe {
                     llvm::LLVMDIBuilderCreateEnumerator(
                         DIB(cx),
@@ -679,7 +680,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.as_c_str |enum_name| {
+    let discriminant_type_metadata = do enum_name.to_c_str().with_ref |enum_name| {
         unsafe {
             llvm::LLVMDIBuilderCreateEnumerationType(
                 DIB(cx),
@@ -716,7 +717,7 @@ fn enum_metadata(cx: &mut CrateContext,
                         Some(discriminant_type_metadata),
                         span);
 
-                    do "".as_c_str |name| {
+                    do "".to_c_str().with_ref |name| {
                         unsafe {
                             llvm::LLVMDIBuilderCreateMemberType(
                                 DIB(cx),
@@ -736,7 +737,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.as_c_str |enum_name| {
+            return do enum_name.to_c_str().with_ref |enum_name| {
                 unsafe {
                     llvm::LLVMDIBuilderCreateUnionType(
                     DIB(cx),
@@ -820,7 +821,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.as_c_str |member_name| {
+            do member_name.to_c_str().with_ref |member_name| {
                 unsafe {
                     llvm::LLVMDIBuilderCreateMemberType(
                         DIB(cx),
@@ -838,7 +839,7 @@ fn composite_type_metadata(cx: &mut CrateContext,
         })
         .collect();
 
-    return do composite_type_name.as_c_str |name| {
+    return do composite_type_name.to_c_str().with_ref |name| {
         unsafe {
             llvm::LLVMDIBuilderCreateStructType(
                 DIB(cx),
@@ -1064,7 +1065,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).as_c_str |name| {
+    let metadata = do fmt!("NYI<%s>", name).to_c_str().with_ref |name| {
         unsafe {
             llvm::LLVMDIBuilderCreateBasicType(
                 DIB(cx),
index c5b3d328f30422106437b08068b766bf032c906b..10586dbe55b1acc349d7862d54c1788d824880a1 100644 (file)
@@ -964,7 +964,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.as_c_str |buf| {
+                            let llval = do symbol.to_c_str().with_ref |buf| {
                                 llvm::LLVMAddGlobal(bcx.ccx().llmod,
                                                     llty.to_ref(),
                                                     buf)
index bbf07e369750f94ee17e9a7515429778bd9b2216..c0a5795e87de1870970deb9053a0f65edfc9326d 100644 (file)
@@ -37,6 +37,7 @@
 
 use middle::trans::type_::Type;
 
+use std::c_str::ToCStr;
 use std::libc::c_uint;
 use syntax::ast;
 
@@ -659,7 +660,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.as_c_str |buf| {
+    let gvar = do name.to_c_str().with_ref |buf| {
         unsafe {
             llvm::LLVMAddGlobal(ccx.llmod, ccx.tydesc_type.to_ref(), buf)
         }
index debaf0f04a7df67b9f2baa8c844fe74babff8c38..b3939a3105065b03e979aa69ceff657800f0819e 100644 (file)
@@ -32,6 +32,7 @@
 
 use middle::trans::type_::Type;
 
+use std::c_str::ToCStr;
 use std::vec;
 use syntax::ast_map::{path, path_mod, path_name};
 use syntax::ast_util;
@@ -605,7 +606,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.as_c_str |buf| {
+        let vt_gvar = do vtable.to_c_str().with_ref |buf| {
             llvm::LLVMAddGlobal(ccx.llmod, val_ty(tbl).to_ref(), buf)
         };
         llvm::LLVMSetInitializer(vt_gvar, tbl);
index 9bb7f9571f39f1775b5e3c9a32ba324a866edd83..110febfcc9f579b7080786fb98335b77c7f6a678 100644 (file)
@@ -20,6 +20,7 @@
 use syntax::ast;
 use syntax::abi::{Architecture, X86, X86_64, Arm, Mips};
 
+use std::c_str::ToCStr;
 use std::vec;
 use std::cast;
 
@@ -170,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.as_c_str(|s| llvm::LLVMStructCreateNamed(ctx, s)))
+        ty!(name.to_c_str().with_ref(|s| llvm::LLVMStructCreateNamed(ctx, s)))
     }
 
     pub fn empty_struct() -> Type {
index 2010e1d4b793f5f0dc69610a6730825e96c34a78..7ef2b90297d732f116e875309418ef0d9bb779fe 100644 (file)
@@ -9,6 +9,7 @@
 // except according to those terms.
 
 use std::{os, result};
+use std::c_str::ToCStr;
 use rustc::driver::{driver, session};
 use rustc::metadata::filesearch;
 use extra::getopts::groups::getopts;
@@ -374,8 +375,8 @@ pub fn link_exe(_src: &Path, _dest: &Path) -> bool {
 pub fn link_exe(src: &Path, dest: &Path) -> bool {
     use std::libc;
     unsafe {
-        do src.to_str().as_c_str |src_buf| {
-            do dest.to_str().as_c_str |dest_buf| {
+        do src.to_c_str().with_ref |src_buf| {
+            do dest.to_c_str().with_ref |dest_buf| {
                 libc::link(src_buf, dest_buf) == 0 as libc::c_int &&
                     libc::chmod(dest_buf, 755) == 0 as libc::c_int
             }
diff --git a/src/libstd/c_str.rs b/src/libstd/c_str.rs
new file mode 100644 (file)
index 0000000..29aa68b
--- /dev/null
@@ -0,0 +1,291 @@
+// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use cast;
+use iterator::Iterator;
+use libc;
+use ops::Drop;
+use option::{Option, Some, None};
+use ptr::RawPtr;
+use ptr;
+use str::StrSlice;
+use vec::ImmutableVector;
+
+/**
+ * The representation of a C String.
+ *
+ * This structure wraps a `*libc::c_char`, and will automatically free the
+ * memory it is pointing to when it goes out of scope.
+ */
+pub struct CString {
+    priv buf: *libc::c_char,
+}
+
+impl<'self> CString {
+    /**
+     * Create a C String from a str.
+     */
+    pub fn from_str(s: &str) -> CString {
+        s.to_c_str()
+    }
+
+    /**
+     * Take the wrapped `*libc::c_char` from the `CString` wrapper.
+     *
+     * # Failure
+     *
+     * If the wrapper is empty.
+     */
+    pub unsafe fn take(&mut self) -> *libc::c_char {
+        if self.buf.is_null() {
+            fail!("CString has no wrapped `*libc::c_char`");
+        }
+        let buf = self.buf;
+        self.buf = ptr::null();
+        buf
+    }
+
+    /**
+     * Puts a `*libc::c_char` into the `CString` wrapper.
+     *
+     * # Failure
+     *
+     * If the `*libc::c_char` is null.
+     * If the wrapper is not empty.
+     */
+    pub fn put_back(&mut self, buf: *libc::c_char) {
+        if buf.is_null() {
+            fail!("attempt to put a null pointer into a CString");
+        }
+        if self.buf.is_not_null() {
+            fail!("CString already wraps a `*libc::c_char`");
+        }
+        self.buf = buf;
+    }
+
+    /**
+     * Calls a closure with a reference to the underlying `*libc::c_char`.
+     */
+    pub fn with_ref<T>(&self, f: &fn(*libc::c_char) -> T) -> T {
+        if self.buf.is_null() {
+            fail!("CString already wraps a `*libc::c_char`");
+        }
+        f(self.buf)
+    }
+
+    /**
+     * Calls a closure with a mutable reference to the underlying `*libc::c_char`.
+     */
+    pub fn with_mut_ref<T>(&mut self, f: &fn(*mut libc::c_char) -> T) -> T {
+        if self.buf.is_not_null() {
+            fail!("CString already wraps a `*libc::c_char`");
+        }
+        f(unsafe { cast::transmute(self.buf) })
+    }
+
+    /**
+     * Returns true if the CString does not wrap a `*libc::c_char`.
+     */
+    pub fn is_empty(&self) -> bool {
+        self.buf.is_null()
+    }
+
+    /**
+     * Returns true if the CString wraps a `*libc::c_char`.
+     */
+    pub fn is_not_empty(&self) -> bool {
+        self.buf.is_not_null()
+    }
+
+    /**
+     * Converts the CString into a `&[u8]` without copying.
+     */
+    pub fn as_bytes(&self) -> &'self [u8] {
+        unsafe {
+            let len = libc::strlen(self.buf) as uint;
+            cast::transmute((self.buf, len + 1))
+        }
+    }
+
+    /**
+     * Return a CString iterator.
+     */
+    fn iter(&self) -> CStringIterator<'self> {
+        CStringIterator {
+            ptr: self.buf,
+            lifetime: unsafe { cast::transmute(self.buf) },
+        }
+    }
+}
+
+impl Drop for CString {
+    fn drop(&self) {
+        if self.buf.is_not_null() {
+            unsafe {
+                libc::free(self.buf as *libc::c_void)
+            };
+        }
+    }
+}
+
+/**
+ * A generic trait for converting a value to a CString.
+ */
+pub trait ToCStr {
+    /**
+     * Create a C String.
+     */
+    fn to_c_str(&self) -> CString;
+}
+
+impl<'self> ToCStr for &'self str {
+    /**
+     * Create a C String from a `&str`.
+     */
+    fn to_c_str(&self) -> CString {
+        self.as_bytes().to_c_str()
+    }
+}
+
+impl<'self> ToCStr for &'self [u8] {
+    /**
+     * Create a C String from a `&[u8]`.
+     */
+    fn to_c_str(&self) -> CString {
+        do self.as_imm_buf |self_buf, self_len| {
+            unsafe {
+                let buf = libc::malloc(self_len as u64 + 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 { buf: buf as *libc::c_char }
+            }
+        }
+    }
+}
+
+/**
+ * External iterator for a CString's bytes.
+ *
+ * Use with the `std::iterator` module.
+ */
+pub struct CStringIterator<'self> {
+    priv ptr: *libc::c_char,
+    priv lifetime: &'self libc::c_char, // FIXME: #5922
+}
+
+impl<'self> Iterator<libc::c_char> for CStringIterator<'self> {
+    /**
+     * Advance the iterator.
+     */
+    fn next(&mut self) -> Option<libc::c_char> {
+        if self.ptr.is_null() {
+            None
+        } else {
+            let ch = unsafe { *self.ptr };
+            self.ptr = ptr::offset(self.ptr, 1);
+            Some(ch)
+        }
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+    use libc;
+    use ptr;
+
+    #[test]
+    fn test_to_c_str() {
+        do "".to_c_str().with_ref |buf| {
+            unsafe {
+                assert_eq!(*ptr::offset(buf, 0), 0);
+            }
+        }
+
+        do "hello".to_c_str().with_ref |buf| {
+            unsafe {
+                assert_eq!(*ptr::offset(buf, 0), 'h' as libc::c_char);
+                assert_eq!(*ptr::offset(buf, 1), 'e' as libc::c_char);
+                assert_eq!(*ptr::offset(buf, 2), 'l' as libc::c_char);
+                assert_eq!(*ptr::offset(buf, 3), 'l' as libc::c_char);
+                assert_eq!(*ptr::offset(buf, 4), 'o' as libc::c_char);
+                assert_eq!(*ptr::offset(buf, 5), 0);
+            }
+        }
+    }
+
+    #[test]
+    fn test_take() {
+        let mut c_str = "hello".to_c_str();
+        unsafe { libc::free(c_str.take() as *libc::c_void) }
+        assert!(c_str.is_empty());
+    }
+
+    #[test]
+    fn test_take_and_put_back() {
+        let mut c_str = "hello".to_c_str();
+        assert!(c_str.is_not_empty());
+
+        let buf = unsafe { c_str.take() };
+
+        assert!(c_str.is_empty());
+
+        c_str.put_back(buf);
+
+        assert!(c_str.is_not_empty());
+    }
+
+    #[test]
+    #[should_fail]
+    #[ignore(cfg(windows))]
+    fn test_take_empty_fail() {
+        let mut c_str = "hello".to_c_str();
+        unsafe {
+            libc::free(c_str.take() as *libc::c_void);
+            c_str.take();
+        }
+    }
+
+    #[test]
+    #[should_fail]
+    #[ignore(cfg(windows))]
+    fn test_put_back_null_fail() {
+        let mut c_str = "hello".to_c_str();
+        c_str.put_back(ptr::null());
+    }
+
+    #[test]
+    #[should_fail]
+    #[ignore(cfg(windows))]
+    fn test_put_back_full_fail() {
+        let mut c_str = "hello".to_c_str();
+        c_str.put_back(0xdeadbeef as *libc::c_char);
+    }
+
+    fn test_with() {
+        let c_str = "hello".to_c_str();
+        let len = unsafe { c_str.with_ref(|buf| libc::strlen(buf)) };
+        assert!(c_str.is_not_empty());
+        assert_eq!(len, 5);
+    }
+
+    #[test]
+    #[should_fail]
+    #[ignore(cfg(windows))]
+    fn test_with_empty_fail() {
+        let mut c_str = "hello".to_c_str();
+        unsafe { libc::free(c_str.take() as *libc::c_void) }
+        c_str.with_ref(|_| ());
+    }
+}
index 606c958b4085e6f4e9e7ffad1d82a7e1780f0c3e..78c6e8d5342ded001a00363f435c306ab3436274 100644 (file)
@@ -48,6 +48,7 @@
 
 use cast;
 use clone::Clone;
+use c_str::ToCStr;
 use container::Container;
 use int;
 use iterator::Iterator;
@@ -1040,8 +1041,8 @@ pub fn stdin() -> @Reader {
 }
 
 pub fn file_reader(path: &Path) -> Result<@Reader, ~str> {
-    let f = do path.to_str().as_c_str |pathbuf| {
-        do "r".as_c_str |modebuf| {
+    let f = do path.to_c_str().with_ref |pathbuf| {
+        do "r".to_c_str().with_ref |modebuf| {
             unsafe { libc::fopen(pathbuf, modebuf as *libc::c_char) }
         }
     };
@@ -1290,9 +1291,8 @@ fn wb() -> c_int { O_WRONLY as c_int }
         }
     }
     let fd = unsafe {
-        do path.to_str().as_c_str |pathbuf| {
-            libc::open(pathbuf, fflags,
-                       (S_IRUSR | S_IWUSR) as c_int)
+        do path.to_c_str().with_ref |pathbuf| {
+            libc::open(pathbuf, fflags, (S_IRUSR | S_IWUSR) as c_int)
         }
     };
     if fd < (0 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_str().as_c_str |pathbuf| {
-            do "w".as_c_str |modebuf| {
+        let f = do path.to_c_str().with_ref |pathbuf| {
+            do "w".to_c_str().with_ref |modebuf| {
                 libc::fopen(pathbuf, modebuf)
             }
         };
index f17a59db38f5a4030f189bf0f0adb28d4c7ffce2..fb4f14d33c60bc8d145d5307058bcac3c4f9514d 100644 (file)
@@ -28,6 +28,7 @@
 
 #[allow(missing_doc)];
 
+use c_str::ToCStr;
 use cast;
 use clone::Clone;
 use container::Container;
@@ -241,7 +242,9 @@ fn env_convert(input: ~[~str]) -> ~[(~str, ~str)] {
 pub fn getenv(n: &str) -> Option<~str> {
     unsafe {
         do with_env_lock {
-            let s = n.as_c_str(|s| libc::getenv(s as *libc::c_char));
+            let s = do n.to_c_str().with_ref |buf| {
+                libc::getenv(buf)
+            };
             if ptr::null::<u8>() == cast::transmute(s) {
                 None
             } else {
@@ -274,8 +277,8 @@ pub fn getenv(n: &str) -> Option<~str> {
 pub fn setenv(n: &str, v: &str) {
     unsafe {
         do with_env_lock {
-            do n.to_str().as_c_str |nbuf| {
-                do v.to_str().as_c_str |vbuf| {
+            do n.to_c_str().with_ref |nbuf| {
+                do v.to_c_str().with_ref |vbuf| {
                     libc::funcs::posix01::unistd::setenv(nbuf, vbuf, 1);
                 }
             }
@@ -306,7 +309,7 @@ pub fn unsetenv(n: &str) {
     fn _unsetenv(n: &str) {
         unsafe {
             do with_env_lock {
-                do n.to_str().as_c_str |nbuf| {
+                do n.to_c_str().with_ref |nbuf| {
                     libc::funcs::posix01::unistd::unsetenv(nbuf);
                 }
             }
@@ -328,7 +331,7 @@ fn _unsetenv(n: &str) {
 }
 
 pub fn fdopen(fd: c_int) -> *FILE {
-    do "r".as_c_str |modebuf| {
+    do "r".to_c_str().with_ref |modebuf| {
         unsafe {
             libc::fdopen(fd, modebuf)
         }
@@ -462,9 +465,9 @@ fn load_self() -> Option<~str> {
             use libc::funcs::posix01::unistd::readlink;
 
             let mut path_str = str::with_capacity(TMPBUF_SZ);
-            let len = do path_str.as_c_str |buf| {
+            let len = do path_str.to_c_str().with_ref |buf| {
                 let buf = buf as *mut c_char;
-                do "/proc/self/exe".as_c_str |proc_self_buf| {
+                do "/proc/self/exe".to_c_str().with_ref |proc_self_buf| {
                     readlink(proc_self_buf, buf, TMPBUF_SZ as size_t)
                 }
             };
@@ -595,7 +598,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_str().as_c_str |buf| {
+        do p.to_c_str().with_ref |buf| {
             rustrt::rust_path_is_dir(buf) != 0 as c_int
         }
     }
@@ -604,7 +607,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_str().as_c_str |buf| {
+        do p.to_c_str().with_ref |buf| {
             rustrt::rust_path_exists(buf) != 0 as c_int
         }
     }
@@ -647,7 +650,7 @@ fn mkdir(p: &Path, _mode: c_int) -> bool {
 
     #[cfg(unix)]
     fn mkdir(p: &Path, mode: c_int) -> bool {
-        do p.to_str().as_c_str |buf| {
+        do p.to_c_str().with_ref |buf| {
             unsafe {
                 libc::mkdir(buf, mode as libc::mode_t) == (0 as c_int)
             }
@@ -823,7 +826,7 @@ fn rmdir(p: &Path) -> bool {
 
     #[cfg(unix)]
     fn rmdir(p: &Path) -> bool {
-        do p.to_str().as_c_str |buf| {
+        do p.to_c_str().with_ref |buf| {
             unsafe {
                 libc::rmdir(buf) == (0 as c_int)
             }
@@ -848,7 +851,7 @@ fn chdir(p: &Path) -> bool {
 
     #[cfg(unix)]
     fn chdir(p: &Path) -> bool {
-        do p.to_str().as_c_str |buf| {
+        do p.to_c_str().with_ref |buf| {
             unsafe {
                 libc::chdir(buf) == (0 as c_int)
             }
@@ -876,8 +879,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_str().as_c_str |fromp| {
-                do "rb".as_c_str |modebuf| {
+            let istream = do from.to_c_str().with_ref |fromp| {
+                do "rb".to_c_str().with_ref |modebuf| {
                     libc::fopen(fromp, modebuf)
                 }
             };
@@ -888,8 +891,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_str().as_c_str |top| {
-                do "w+b".as_c_str |modebuf| {
+            let ostream = do to.to_c_str().with_ref |top| {
+                do "w+b".to_c_str().with_ref |modebuf| {
                     libc::fopen(top, modebuf)
                 }
             };
@@ -921,7 +924,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_str().as_c_str |to_buf| {
+            if do to.to_c_str().with_ref |to_buf| {
                 libc::chmod(to_buf, from_mode as libc::mode_t)
             } != 0 {
                 return false; // should be a condition...
@@ -948,7 +951,7 @@ fn unlink(p: &Path) -> bool {
     #[cfg(unix)]
     fn unlink(p: &Path) -> bool {
         unsafe {
-            do p.to_str().as_c_str |buf| {
+            do p.to_c_str().with_ref |buf| {
                 libc::unlink(buf) == (0 as c_int)
             }
         }
@@ -1294,7 +1297,7 @@ fn default_glob_t () -> libc::glob_t {
     }
 
     let mut g = default_glob_t();
-    do pattern.as_c_str |c_pattern| {
+    do pattern.to_c_str().with_ref |c_pattern| {
         unsafe { libc::glob(c_pattern, 0, ptr::null(), &mut g) }
     };
     do(|| {
@@ -1699,6 +1702,7 @@ pub mod mips {
 
 #[cfg(test)]
 mod tests {
+    use c_str::ToCStr;
     use libc::{c_int, c_void, size_t};
     use libc;
     use option::Some;
@@ -1711,7 +1715,6 @@ mod tests {
     use rand;
     use run;
     use str::StrSlice;
-    use vec::CopyableVector;
     use libc::consts::os::posix88::{S_IRUSR, S_IWUSR, S_IXUSR};
 
 
@@ -1941,19 +1944,19 @@ fn copy_file_ok() {
             let out = tempdir.push("out.txt");
 
             /* Write the temp input file */
-            let ostream = do input.to_str().as_c_str |fromp| {
-                do "w+b".as_c_str |modebuf| {
+            let ostream = do input.to_c_str().with_ref |fromp| {
+                do "w+b".to_c_str().with_ref |modebuf| {
                     libc::fopen(fromp, modebuf)
                 }
             };
             assert!((ostream as uint != 0u));
             let s = ~"hello";
-            let mut buf = s.to_owned().to_c_str();
-            let len = buf.len();
-            do buf.as_mut_buf |b, _len| {
-                assert_eq!(libc::fwrite(b as *c_void, 1u as size_t,
-                                        (s.len() + 1u) as size_t, ostream),
-                           len as size_t)
+            do "hello".to_c_str().with_ref |buf| {
+                let write_len = libc::fwrite(buf as *c_void,
+                                             1u as size_t,
+                                             (s.len() + 1u) as size_t,
+                                             ostream);
+                assert_eq!(write_len, (s.len() + 1) as size_t)
             }
             assert_eq!(libc::fclose(ostream), (0u as c_int));
             let in_mode = input.get_mode();
@@ -2025,11 +2028,11 @@ fn lseek_(fd: c_int, size: uint) {
         remove_file(&path);
 
         let fd = unsafe {
-            let fd = do path.to_str().as_c_str |path| {
+            let fd = do path.to_c_str().with_ref |path| {
                 open(path, O_CREAT | O_RDWR | O_TRUNC, S_IRUSR | S_IWUSR)
             };
             lseek_(fd, size);
-            do "x".as_c_str |x| {
+            do "x".to_c_str().with_ref |x| {
                 assert!(write(fd, x as *c_void, 1) == 1);
             }
             fd
index 989a5cbd35b3b79729567f2471bcfeafb4cd449e..fe8776c21d5a38caab50bada20f5696313198467 100644 (file)
 
 #[allow(missing_doc)];
 
+use c_str::ToCStr;
+use c_str;
 use clone::Clone;
-use container::Container;
 use cmp::Eq;
+use container::Container;
 use iterator::{Iterator, IteratorUtil};
 use libc;
 use option::{None, Option, Some};
@@ -341,7 +343,7 @@ pub fn default_stat() -> libc::stat {
 #[cfg(target_os = "win32")]
 impl WindowsPath {
     pub fn stat(&self) -> Option<libc::stat> {
-        do self.to_str().as_c_str |buf| {
+        do self.to_c_str().with_ref |buf| {
             let mut st = stat::arch::default_stat();
             match unsafe { libc::stat(buf, &mut st) } {
                 0 => Some(st),
@@ -375,7 +377,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_str().as_c_str |buf| {
+        do self.to_c_str().with_ref |buf| {
             let mut st = stat::arch::default_stat();
             match unsafe { libc::stat(buf as *libc::c_char, &mut st) } {
                 0 => Some(st),
@@ -453,7 +455,7 @@ pub fn get_ctime(&self) -> Option<(i64, int)> {
 #[cfg(unix)]
 impl PosixPath {
     pub fn lstat(&self) -> Option<libc::stat> {
-        do self.to_str().as_c_str |buf| {
+        do self.to_c_str().with_ref |buf| {
             let mut st = stat::arch::default_stat();
             match unsafe { libc::lstat(buf, &mut st) } {
                 0 => Some(st),
@@ -525,6 +527,12 @@ fn to_str(&self) -> ~str {
     }
 }
 
+impl ToCStr for PosixPath {
+    fn to_c_str(&self) -> c_str::CString {
+        self.to_str().to_c_str()
+    }
+}
+
 // FIXME (#3227): when default methods in traits are working, de-duplicate
 // PosixPath and WindowsPath, most of their methods are common.
 impl GenericPath for PosixPath {
@@ -730,6 +738,11 @@ fn to_str(&self) -> ~str {
     }
 }
 
+impl c_str::ToCStr for WindowsPath {
+    fn to_c_str(&self) -> c_str::CString {
+        self.to_str().to_c_str()
+    }
+}
 
 impl GenericPath for WindowsPath {
     fn from_str(s: &str) -> WindowsPath {
index 7e21504c1d294825b06f612f6893b03053448b02..5b8833f3f361bdbff53f3a03a1fddad5a5b89044 100644 (file)
@@ -43,6 +43,7 @@
 pub use iterator::range;
 
 // Reexported types and traits
+pub use c_str::ToCStr;
 pub use clone::{Clone, DeepClone};
 pub use cmp::{Eq, ApproxEq, Ord, TotalEq, TotalOrd, Ordering, Less, Equal, Greater, Equiv};
 pub use char::Char;
index 3af4769fcdb43d2436f6aea63cbc624d1b38d767..77222490f171d028abd3d5f0fadf70c2f9e28cb9 100644 (file)
@@ -486,24 +486,25 @@ struct Pair {
 
     #[test]
     fn test_position() {
+        use c_str::ToCStr;
         use libc::c_char;
 
-        let s = ~"hello";
-        unsafe {
-            assert!(2u == s.as_c_str(|p| position(p, |c| *c == 'l' as c_char)));
-            assert!(4u == s.as_c_str(|p| position(p, |c| *c == 'o' as c_char)));
-            assert!(5u == s.as_c_str(|p| position(p, |c| *c == 0 as c_char)));
+        do "hello".to_c_str().with_ref |p| {
+            unsafe {
+                assert!(2u == position(p, |c| *c == 'l' as c_char));
+                assert!(4u == position(p, |c| *c == 'o' as c_char));
+                assert!(5u == position(p, |c| *c == 0 as c_char));
+            }
         }
     }
 
     #[test]
     fn test_buf_len() {
-        let s0 = ~"hello";
-        let s1 = ~"there";
-        let s2 = ~"thing";
-        do s0.as_c_str |p0| {
-            do s1.as_c_str |p1| {
-                do s2.as_c_str |p2| {
+        use c_str::ToCStr;
+
+        do "hello".to_c_str().with_ref |p0| {
+            do "there".to_c_str().with_ref |p1| {
+                do "thing".to_c_str().with_ref |p2| {
                     let v = ~[p0, p1, p2, null()];
                     do v.as_imm_buf |vp, len| {
                         assert_eq!(unsafe { buf_len(vp) }, 3u);
index 4a6a9585b93741d3b2366a179591600bb3cbea38..3a51fd032c0e8d6669af793e026da312758a83ce 100644 (file)
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use c_str::ToCStr;
 use cast::transmute;
 use libc::{c_char, c_void, size_t, STDERR_FILENO};
 use io;
@@ -76,7 +77,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.as_c_str |msg_p| {
+            do msg.to_c_str().with_ref |msg_p| {
                 sys::begin_unwind_(msg_p, file, line);
             }
         }
@@ -92,7 +93,7 @@ unsafe fn fail_borrowed(box: *mut raw::Box<()>, file: *c_char, line: size_t) {
                     sep = " and at ";
                 }
             }
-            do msg.as_c_str |msg_p| {
+            do msg.to_c_str().with_ref |msg_p| {
                 sys::begin_unwind_(msg_p, file, line)
             }
         }
@@ -231,7 +232,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.as_c_str |msg_p| {
+                do err.to_c_str().with_ref |msg_p| {
                     sys::begin_unwind_(msg_p, file, line)
                 }
             }
index 11d11daebc254be912a0b2a25048db789b12874a..76619704bee43d3350d506675e86f27712550316 100644 (file)
@@ -45,15 +45,15 @@ fn log(&mut self, msg: Either<~str, &'static str>) {
 /// Configure logging by traversing the crate map and setting the
 /// per-module global logging flags based on the logging spec
 pub fn init(crate_map: *u8) {
+    use c_str::ToCStr;
     use os;
-    use str::StrSlice;
     use ptr;
     use option::{Some, None};
 
     let log_spec = os::getenv("RUST_LOG");
     match log_spec {
         Some(spec) => {
-            do spec.as_c_str |buf| {
+            do spec.to_c_str().with_ref |buf| {
                 unsafe { rust_update_log_settings(crate_map, buf) }
             }
         }
index e15e3adb8c9f3db551709af7c47b5d125be6e160..071a90f4a8346531aace430293fb8969cf9bf15a 100644 (file)
@@ -8,26 +8,26 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use option::*;
-use result::*;
-use ops::Drop;
-use cell::Cell;
-use cast;
+use c_str::ToCStr;
 use cast::transmute;
+use cast;
+use cell::Cell;
 use clone::Clone;
 use libc::{c_int, c_uint, c_void};
+use ops::Drop;
+use option::*;
 use ptr;
+use result::*;
 use rt::io::IoError;
 use rt::io::net::ip::{IpAddr, Ipv4, Ipv6};
-use rt::uv::*;
-use rt::uv::idle::IdleWatcher;
-use rt::uv::net::{UvIpv4, UvIpv6};
+use rt::io::{standard_error, OtherIoError};
+use rt::local::Local;
 use rt::rtio::*;
 use rt::sched::Scheduler;
-use rt::io::{standard_error, OtherIoError};
 use rt::tube::Tube;
-use rt::local::Local;
-use str::StrSlice;
+use rt::uv::*;
+use rt::uv::idle::IdleWatcher;
+use rt::uv::net::{UvIpv4, UvIpv6};
 use unstable::sync::Exclusive;
 
 #[cfg(test)] use container::Container;
@@ -663,7 +663,7 @@ fn join_multicast(&mut self, multi: IpAddr) -> Result<(), IoError> {
         };
 
         let r = unsafe {
-            do ip_str.as_c_str |m_addr| {
+            do ip_str.to_c_str().with_ref |m_addr| {
                 uvll::udp_set_membership(self.native_handle(), m_addr,
                                          ptr::null(), uvll::UV_JOIN_GROUP)
             }
@@ -686,7 +686,7 @@ fn leave_multicast(&mut self, multi: IpAddr) -> Result<(), IoError> {
         };
 
         let r = unsafe {
-            do ip_str.as_c_str |m_addr| {
+            do ip_str.to_c_str().with_ref |m_addr| {
                 uvll::udp_set_membership(self.native_handle(), m_addr,
                                          ptr::null(), uvll::UV_LEAVE_GROUP)
             }
index 07264839c3555dda0107bdc085540cf2168d98b8..bd2d28f8642c44736552dfc9d400b066436df33e 100644 (file)
@@ -29,6 +29,7 @@
 
 #[allow(non_camel_case_types)]; // C types
 
+use c_str::ToCStr;
 use libc::{size_t, c_int, c_uint, c_void, c_char, uintptr_t};
 use libc::{malloc, free};
 use libc;
@@ -372,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.as_c_str |ip_buf| {
+    do ip.to_c_str().with_ref |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.as_c_str |ip_buf| {
+    do ip.to_c_str().with_ref |ip_buf| {
         rust_uv_ip6_addrp(ip_buf as *u8, port as libc::c_int)
     }
 }
index 9114c4879b2452b2761c6d13ab827a3abebfeae1..6e447d3ded473d839636694665ed91989d0f9fd8 100644 (file)
@@ -12,6 +12,7 @@
 
 #[allow(missing_doc)];
 
+use c_str::ToCStr;
 use cast;
 use clone::Clone;
 use comm::{stream, SharedChan, GenericChan, GenericPort};
@@ -506,7 +507,7 @@ fn spawn_process_os(prog: &str, args: &[~str],
 
         do with_envp(env) |envp| {
             do with_dirp(dir) |dirp| {
-                do cmd.as_c_str |cmdp| {
+                do cmd.to_c_str().with_ref |cmdp| {
                     let created = CreateProcessA(ptr::null(), cast::transmute(cmdp),
                                                  ptr::mut_null(), ptr::mut_null(), TRUE,
                                                  0, envp, dirp, &mut si, &mut pi);
@@ -697,17 +698,17 @@ fn with_argv<T>(prog: &str, args: &[~str], cb: &fn(**libc::c_char) -> T) -> T {
     // hold all the ~[u8] byte strings.
     let mut tmps = vec::with_capacity(args.len() + 1);
 
-    tmps.push(prog.to_owned().to_c_str());
+    tmps.push(prog.to_c_str());
 
     foreach arg in args.iter() {
-        tmps.push(arg.to_owned().to_c_str());
+        tmps.push(arg.to_c_str());
     }
 
     // Next, convert each of the byte strings into a pointer. This is
     // technically unsafe as the caller could leak these pointers out of our
     // scope.
     let mut ptrs = do tmps.map |tmp| {
-        tmp.as_imm_buf(|buf, _| buf as *libc::c_char)
+        tmp.with_ref(|buf| buf)
     };
 
     // Finally, make sure we add a null pointer.
@@ -734,7 +735,7 @@ fn with_envp<T>(env: Option<&[(~str, ~str)]>, cb: &fn(*c_void) -> T) -> T {
 
             // Once again, this is unsafe.
             let mut ptrs = do tmps.map |tmp| {
-                tmp.as_imm_buf(|buf, _| buf as *libc::c_char)
+                tmp.with_ref(|buf| buf)
             };
             ptrs.push(ptr::null());
 
@@ -757,7 +758,7 @@ fn with_envp<T>(env: Option<&[(~str, ~str)]>, cb: &fn(*mut c_void) -> T) -> T {
 
             foreach pair in env.iter() {
                 let kv = fmt!("%s=%s", pair.first(), pair.second());
-                blk.push_all(kv.to_c_str());
+                blk.push_all(kv.to_c_str().as_bytes());
             }
 
             blk.push(0);
@@ -772,7 +773,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_str().as_c_str(cb),
+      Some(dir) => dir.to_c_str().with_ref(|buf| cb(buf)),
       None => cb(ptr::null())
     }
 }
index 76d65192e01a98eb43b414e3ca57ad8fb50af7f8..d51f0de1d275b2bd84eaa273a7a6a123e9ec25b8 100644 (file)
@@ -172,6 +172,7 @@ pub mod linkhack {
 
 pub mod gc;
 pub mod libc;
+pub mod c_str;
 pub mod os;
 pub mod path;
 pub mod rand;
index f75bbcf20ebcb321e4fad2835c94fbd405db362c..851a9326392d13f9c43d79426772210dc36b1a5c 100644 (file)
@@ -1182,7 +1182,6 @@ fn split_options_iter<Sep: CharEq>(&self, sep: Sep, count: uint, allow_trailing_
     fn subslice_offset(&self, inner: &str) -> uint;
 
     fn as_imm_buf<T>(&self, f: &fn(*u8, uint) -> T) -> T;
-    fn as_c_str<T>(&self, f: &fn(*libc::c_char) -> T) -> T;
 }
 
 /// Extension methods for strings
@@ -1931,32 +1930,6 @@ fn as_imm_buf<T>(&self, f: &fn(*u8, uint) -> T) -> T {
         let v: &[u8] = unsafe { cast::transmute(*self) };
         v.as_imm_buf(f)
     }
-
-    /// Work with the byte buffer of a string as a null-terminated C string.
-    ///
-    /// Allows for unsafe manipulation of strings, which is useful for foreign
-    /// interop. This is similar to `str::as_buf`, but guarantees null-termination.
-    /// If the given slice is not already null-terminated, this function will
-    /// allocate a temporary, copy the slice, null terminate it, and pass
-    /// that instead.
-    ///
-    /// # Example
-    ///
-    /// ~~~ {.rust}
-    /// let s = "PATH".as_c_str(|path| libc::getenv(path));
-    /// ~~~
-    #[inline]
-    fn as_c_str<T>(&self, f: &fn(*libc::c_char) -> T) -> T {
-        do self.as_imm_buf |buf, len| {
-            // NB: len includes the trailing null.
-            assert!(len > 0);
-            if unsafe { *(ptr::offset(buf, (len - 1) as int)) != 0 } {
-                self.to_owned().as_c_str(|s| f(s))
-            } else {
-                f(buf as *libc::c_char)
-            }
-        }
-    }
 }
 
 #[allow(missing_doc)]
@@ -1973,13 +1946,6 @@ pub trait OwnedStr {
     fn capacity(&self) -> uint;
     fn to_bytes_with_null(self) -> ~[u8];
 
-    /// Allocates a null terminate byte array.
-    ///
-    /// # Failure
-    ///
-    /// Fails if there are any null characters inside the byte array.
-    fn to_c_str(self) -> ~[u8];
-
     /// Work with the mutable byte buffer and length of a slice.
     ///
     /// The given length is one byte longer than the 'official' indexable
@@ -2171,13 +2137,6 @@ fn to_bytes_with_null(self) -> ~[u8] {
         unsafe { cast::transmute(self) }
     }
 
-    #[inline]
-    fn to_c_str(self) -> ~[u8] {
-        let bytes = self.to_bytes_with_null();
-        assert!(bytes.slice(0, bytes.len() - 1).iter().all(|byte| *byte != 0));
-        bytes
-    }
-
     #[inline]
     fn as_mut_buf<T>(&mut self, f: &fn(*mut u8, uint) -> T) -> T {
         let v: &mut ~[u8] = unsafe { cast::transmute(self) };
@@ -2915,63 +2874,6 @@ fn test_as_imm_buf() {
         }
     }
 
-    #[test]
-    fn test_as_c_str() {
-        let a = ~"";
-        do a.as_c_str |buf| {
-            unsafe {
-                assert_eq!(*ptr::offset(buf, 0), 0);
-            }
-        }
-
-        let a = ~"hello";
-        do a.as_c_str |buf| {
-            unsafe {
-                assert_eq!(*ptr::offset(buf, 0), 'h' as libc::c_char);
-                assert_eq!(*ptr::offset(buf, 1), 'e' as libc::c_char);
-                assert_eq!(*ptr::offset(buf, 2), 'l' as libc::c_char);
-                assert_eq!(*ptr::offset(buf, 3), 'l' as libc::c_char);
-                assert_eq!(*ptr::offset(buf, 4), 'o' as libc::c_char);
-                assert_eq!(*ptr::offset(buf, 5), 0);
-            }
-        }
-    }
-
-    #[test]
-    fn test_to_c_str() {
-        let s = ~"ศไทย中华Việt Nam";
-        let v = ~[
-            224, 184, 168, 224, 185, 132, 224, 184, 151, 224, 184, 162, 228,
-            184, 173, 229, 141, 142, 86, 105, 225, 187, 135, 116, 32, 78, 97,
-            109, 0
-        ];
-        assert_eq!((~"").to_c_str(), ~[0]);
-        assert_eq!((~"abc").to_c_str(), ~['a' as u8, 'b' as u8, 'c' as u8, 0]);
-        assert_eq!(s.to_c_str(), v);
-    }
-
-    #[test]
-    fn test_as_c_str() {
-        let a = ~"";
-        do a.as_c_str |buf| {
-            unsafe {
-                assert_eq!(*ptr::offset(buf, 0), 0);
-            }
-        }
-
-        let a = ~"hello";
-        do a.as_c_str |buf| {
-            unsafe {
-                assert_eq!(*ptr::offset(buf, 0), 'h' as libc::c_char);
-                assert_eq!(*ptr::offset(buf, 1), 'e' as libc::c_char);
-                assert_eq!(*ptr::offset(buf, 2), 'l' as libc::c_char);
-                assert_eq!(*ptr::offset(buf, 3), 'l' as libc::c_char);
-                assert_eq!(*ptr::offset(buf, 4), 'o' as libc::c_char);
-                assert_eq!(*ptr::offset(buf, 5), 0);
-            }
-        }
-    }
-
     #[test]
     fn test_subslice_offset() {
         let a = "kernelsprite";
index 51609709cdbcad3530e011856f96470982eca260..b40f87617a91411fa263d77bca0996e9cb0dc0b0 100644 (file)
 
 #[allow(missing_doc)];
 
+use c_str::ToCStr;
 use cast;
 use gc;
 use io;
 use libc;
 use libc::{c_char, size_t};
 use repr;
-use str::StrSlice;
 use str;
 use unstable::intrinsics;
 
@@ -115,8 +115,8 @@ pub trait FailWithCause {
 
 impl FailWithCause for ~str {
     fn fail_with(cause: ~str, file: &'static str, line: uint) -> ! {
-        do cause.as_c_str |msg_buf| {
-            do file.as_c_str |file_buf| {
+        do cause.to_c_str().with_ref |msg_buf| {
+            do file.to_c_str().with_ref |file_buf| {
                 begin_unwind_(msg_buf, file_buf, line as libc::size_t)
             }
         }
@@ -125,8 +125,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.as_c_str |msg_buf| {
-            do file.as_c_str |file_buf| {
+        do cause.to_c_str().with_ref |msg_buf| {
+            do file.to_c_str().with_ref |file_buf| {
                 begin_unwind_(msg_buf, file_buf, line as libc::size_t)
             }
         }
index 8d5654255f14a7264f50a9b3294dec4b49ffcc3c..49e3e0777df84e58356fe734fe07d3e37c36f34f 100644 (file)
@@ -15,6 +15,7 @@
 A simple wrapper over the platforms dynamic library facilities
 
 */
+use c_str::ToCStr;
 use cast;
 use path;
 use libc;
@@ -65,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.as_c_str |raw_string| {
+            do symbol.to_c_str().with_ref |raw_string| {
                 dl::symbol(self.handle, raw_string)
             }
         };
@@ -135,6 +136,7 @@ fn test_errors_do_not_crash() {
 #[cfg(target_os = "macos")]
 #[cfg(target_os = "freebsd")]
 mod dl {
+    use c_str::ToCStr;
     use libc;
     use path;
     use ptr;
@@ -143,7 +145,7 @@ mod dl {
     use result::*;
 
     pub unsafe fn open_external(filename: &path::Path) -> *libc::c_void {
-        do filename.to_str().as_c_str |raw_name| {
+        do filename.to_c_str().with_ref |raw_name| {
             dlopen(raw_name, Lazy as libc::c_int)
         }
     }
index e0c4950b38eaa8a0cb1d4cc742838b3493486bc2..1ea815f721cc1cb0d170c0c3cacbf11f9ef6ac38 100644 (file)
@@ -10,6 +10,7 @@
 
 //! Runtime calls emitted by the compiler.
 
+use c_str::ToCStr;
 use cast::transmute;
 use libc::{c_char, c_uchar, c_void, size_t, uintptr_t, c_int};
 use str;
@@ -49,7 +50,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.as_c_str |buf| {
+    do msg.to_c_str().with_ref |buf| {
         fail_(buf, file, line);
     }
 }
index 38f36dd258b7acde112eb972d96eaebab173f3fc..b5a114ef22364e64dc2bea3f7ccf326b914afa50 100644 (file)
@@ -26,8 +26,9 @@ mod libc {
 fn strlen(str: ~str) -> uint {
     unsafe {
         // C string is terminated with a zero
-        let bytes = str.to_bytes_with_null();
-        return libc::my_strlen(vec::raw::to_ptr(bytes));
+        do str.to_c_str().with_ref |buf| {
+            libc::my_strlen(buf as *u8)
+        }
     }
 }