std: replace str::as_c_str with std::c_str

This commit is contained in:
Erick Tryzelaar 2013-08-03 17:13:14 -07:00
parent 0512475fda
commit 3102b1797e
35 changed files with 509 additions and 268 deletions

View File

@ -11,7 +11,7 @@
// FIXME #3921. This is unsafe because linenoise uses global mutable // FIXME #3921. This is unsafe because linenoise uses global mutable
// state without mutexes. // state without mutexes.
use std::c_str::ToCStr;
use std::libc::{c_char, c_int}; use std::libc::{c_char, c_int};
use std::local_data; use std::local_data;
use std::str; use std::str;
@ -32,7 +32,7 @@ pub mod rustrt {
/// Add a line to history /// Add a line to history
pub unsafe fn add_history(line: &str) -> bool { 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 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 /// Save line history to a file
pub unsafe fn save_history(file: &str) -> bool { 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 rustrt::linenoiseHistorySave(buf) == 1 as c_int
} }
} }
/// Load line history from a file /// Load line history from a file
pub unsafe fn load_history(file: &str) -> bool { 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 rustrt::linenoiseHistoryLoad(buf) == 1 as c_int
} }
} }
/// Print out a prompt and then wait for input and return it /// Print out a prompt and then wait for input and return it
pub unsafe fn read(prompt: &str) -> Option<~str> { 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); let line = rustrt::linenoise(buf);
if line.is_null() { None } if line.is_null() { None }
@ -80,7 +80,7 @@ pub unsafe fn complete(cb: CompletionCb) {
unsafe { unsafe {
do cb(str::raw::from_c_str(line)) |suggestion| { 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); rustrt::linenoiseAddCompletion(completions, buf);
} }
} }

View File

@ -22,6 +22,7 @@ use middle::trans::common::gensym_name;
use middle::ty; use middle::ty;
use util::ppaux; use util::ppaux;
use std::c_str::ToCStr;
use std::char; use std::char;
use std::hash::Streaming; use std::hash::Streaming;
use std::hash; use std::hash;
@ -76,9 +77,9 @@ pub fn WriteOutputFile(sess: Session,
OptLevel: c_int, OptLevel: c_int,
EnableSegmentedStacks: bool) { EnableSegmentedStacks: bool) {
unsafe { unsafe {
do Triple.as_c_str |Triple| { do Triple.to_c_str().with_ref |Triple| {
do Feature.as_c_str |Feature| { do Feature.to_c_str().with_ref |Feature| {
do Output.as_c_str |Output| { do Output.to_c_str().with_ref |Output| {
let result = llvm::LLVMRustWriteOutputFile( let result = llvm::LLVMRustWriteOutputFile(
PM, PM,
M, M,
@ -105,6 +106,7 @@ pub mod jit {
use lib::llvm::{ModuleRef, ContextRef, ExecutionEngineRef}; use lib::llvm::{ModuleRef, ContextRef, ExecutionEngineRef};
use metadata::cstore; use metadata::cstore;
use std::c_str::ToCStr;
use std::cast; use std::cast;
use std::local_data; use std::local_data;
use std::unstable::intrinsics; use std::unstable::intrinsics;
@ -146,7 +148,7 @@ pub mod jit {
debug!("linking: %s", path); 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) { if !llvm::LLVMRustLoadCrate(manager, buf_t) {
llvm_err(sess, ~"Could not link"); llvm_err(sess, ~"Could not link");
} }
@ -165,7 +167,7 @@ pub mod jit {
// Next, we need to get a handle on the _rust_main function by // Next, we need to get a handle on the _rust_main function by
// looking up it's corresponding ValueRef and then requesting that // looking up it's corresponding ValueRef and then requesting that
// the execution engine compiles the function. // 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) llvm::LLVMGetNamedFunction(m, entry)
}; };
if fun.is_null() { if fun.is_null() {
@ -230,6 +232,7 @@ pub mod write {
use back::passes; use back::passes;
use std::c_str::ToCStr;
use std::libc::{c_int, c_uint}; use std::libc::{c_int, c_uint};
use std::path::Path; use std::path::Path;
use std::run; use std::run;
@ -263,14 +266,14 @@ pub mod write {
output_type_bitcode => { output_type_bitcode => {
if opts.optimize != session::No { if opts.optimize != session::No {
let filename = output.with_filetype("no-opt.bc"); 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); llvm::LLVMWriteBitcodeToFile(llmod, buf);
} }
} }
} }
_ => { _ => {
let filename = output.with_filetype("bc"); 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); llvm::LLVMWriteBitcodeToFile(llmod, buf);
} }
} }
@ -333,7 +336,7 @@ pub mod write {
// Always output the bitcode file with --save-temps // Always output the bitcode file with --save-temps
let filename = output.with_filetype("opt.bc"); 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) llvm::LLVMWriteBitcodeToFile(llmod, buf)
}; };
// Save the assembly file if -S is used // Save the assembly file if -S is used
@ -391,13 +394,13 @@ pub mod write {
if output_type == output_type_llvm_assembly { if output_type == output_type_llvm_assembly {
// Given options "-S --emit-llvm": output 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); llvm::LLVMRustAddPrintModulePass(pm.llpm, llmod, buf_o);
} }
} else { } else {
// If only a bitcode file is asked for by using the // If only a bitcode file is asked for by using the
// '--emit-llvm' flag, then output it here // '--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); llvm::LLVMWriteBitcodeToFile(llmod, buf);
} }
} }

View File

@ -8,6 +8,7 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
use std::c_str::ToCStr;
use std::io; use std::io;
use driver::session::{OptLevel, No, Less, Aggressive}; 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> { pub fn create_pass(name:&str) -> Option<PassRef> {
do name.as_c_str |s| { do name.to_c_str().with_ref |s| {
unsafe { unsafe {
let p = llvm::LLVMCreatePass(s); let p = llvm::LLVMCreatePass(s);
if p.is_null() { if p.is_null() {

View File

@ -8,7 +8,7 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
use std::c_str::ToCStr;
use std::hashmap::HashMap; use std::hashmap::HashMap;
use std::libc::{c_uint, c_ushort}; use std::libc::{c_uint, c_ushort};
use std::option; use std::option;
@ -2234,7 +2234,7 @@ pub struct TargetData {
} }
pub fn mk_target_data(string_rep: &str) -> 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) } unsafe { llvm::LLVMCreateTargetData(buf) }
}; };

View File

@ -24,6 +24,7 @@ use syntax::print::pprust;
use syntax::{ast, attr}; use syntax::{ast, attr};
use syntax::attr::AttrMetaMethods; use syntax::attr::AttrMetaMethods;
use std::c_str::ToCStr;
use std::cast; use std::cast;
use std::io; use std::io;
use std::num; use std::num;
@ -186,7 +187,7 @@ pub fn metadata_matches(extern_metas: &[@ast::MetaItem],
fn get_metadata_section(os: os, fn get_metadata_section(os: os,
filename: &Path) -> Option<@~[u8]> { filename: &Path) -> Option<@~[u8]> {
unsafe { unsafe {
let mb = do filename.to_str().as_c_str |buf| { let mb = do filename.to_c_str().with_ref |buf| {
llvm::LLVMRustCreateMemoryBufferWithContentsOfFile(buf) llvm::LLVMRustCreateMemoryBufferWithContentsOfFile(buf)
}; };
if mb as int == 0 { return option::None::<@~[u8]>; } if mb as int == 0 { return option::None::<@~[u8]>; }

View File

@ -12,6 +12,7 @@
# Translation of inline assembly. # Translation of inline assembly.
*/ */
use std::c_str::ToCStr;
use lib; use lib;
use middle::trans::build::*; 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 ast::asm_intel => lib::llvm::AD_Intel
}; };
let r = do ia.asm.as_c_str |a| { let r = do ia.asm.to_c_str().with_ref |a| {
do constraints.as_c_str |c| { do constraints.to_c_str().with_ref |c| {
InlineAsmCall(bcx, a, c, inputs, output, ia.volatile, ia.alignstack, dialect) InlineAsmCall(bcx, a, c, inputs, output, ia.volatile, ia.alignstack, dialect)
} }
}; };

View File

@ -65,6 +65,7 @@ use util::ppaux::{Repr, ty_to_str};
use middle::trans::type_::Type; use middle::trans::type_::Type;
use std::c_str::ToCStr;
use std::hash; use std::hash;
use std::hashmap::HashMap; use std::hashmap::HashMap;
use std::io; use std::io;
@ -179,7 +180,7 @@ impl<'self> Drop for StatRecorder<'self> {
} }
pub fn decl_fn(llmod: ModuleRef, name: &str, cc: lib::llvm::CallConv, ty: Type) -> ValueRef { 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 { unsafe {
llvm::LLVMGetOrInsertFunction(llmod, buf, ty.to_ref()) llvm::LLVMGetOrInsertFunction(llmod, buf, ty.to_ref())
} }
@ -219,7 +220,7 @@ pub fn get_extern_const(externs: &mut ExternMap, llmod: ModuleRef,
None => () None => ()
} }
unsafe { 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) llvm::LLVMAddGlobal(llmod, ty.to_ref(), buf)
}; };
externs.insert(name, c); externs.insert(name, c);
@ -548,7 +549,7 @@ pub fn get_res_dtor(ccx: @mut CrateContext,
// Structural comparison: a rather involved form of glue. // Structural comparison: a rather involved form of glue.
pub fn maybe_name_value(cx: &CrateContext, v: ValueRef, s: &str) { pub fn maybe_name_value(cx: &CrateContext, v: ValueRef, s: &str) {
if cx.sess.opts.save_temps { if cx.sess.opts.save_temps {
do s.as_c_str |buf| { do s.to_c_str().with_ref |buf| {
unsafe { unsafe {
llvm::LLVMSetValueName(v, buf) llvm::LLVMSetValueName(v, buf)
} }
@ -1162,7 +1163,7 @@ pub fn new_block(cx: @mut FunctionContext,
opt_node_info: Option<NodeInfo>) opt_node_info: Option<NodeInfo>)
-> @mut Block { -> @mut Block {
unsafe { 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) llvm::LLVMAppendBasicBlockInContext(cx.ccx.llcx, cx.llfn, buf)
}; };
let bcx = @mut Block::new(llbb, let bcx = @mut Block::new(llbb,
@ -1579,7 +1580,7 @@ pub struct BasicBlocks {
pub fn mk_staticallocas_basic_block(llfn: ValueRef) -> BasicBlockRef { pub fn mk_staticallocas_basic_block(llfn: ValueRef) -> BasicBlockRef {
unsafe { unsafe {
let cx = task_llcx(); 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) 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 { pub fn mk_return_basic_block(llfn: ValueRef) -> BasicBlockRef {
unsafe { unsafe {
let cx = task_llcx(); let cx = task_llcx();
do "return".as_c_str |buf| { do "return".to_c_str().with_ref |buf| {
llvm::LLVMAppendBasicBlockInContext(cx, llfn, buf) llvm::LLVMAppendBasicBlockInContext(cx, llfn, buf)
} }
} }
@ -2346,7 +2347,7 @@ pub fn create_entry_wrapper(ccx: @mut CrateContext,
}; };
decl_cdecl_fn(ccx.llmod, main_name, llfty) 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 { unsafe {
llvm::LLVMAppendBasicBlockInContext(ccx.llcx, llfn, buf) llvm::LLVMAppendBasicBlockInContext(ccx.llcx, llfn, buf)
} }
@ -2356,7 +2357,7 @@ pub fn create_entry_wrapper(ccx: @mut CrateContext,
llvm::LLVMPositionBuilderAtEnd(bld, llbb); llvm::LLVMPositionBuilderAtEnd(bld, llbb);
let crate_map = ccx.crate_map; 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) llvm::LLVMBuildPointerCast(bld, crate_map, Type::i8p().to_ref(), buf)
}; };
@ -2374,7 +2375,7 @@ pub fn create_entry_wrapper(ccx: @mut CrateContext,
}; };
let args = { 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) 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 { unsafe {
let llty = llvm::LLVMTypeOf(v); 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) 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")) { match (attr::first_attr_value_str_by_name(i.attrs, "link_section")) {
Some(sect) => unsafe { Some(sect) => unsafe {
do sect.as_c_str |buf| { do sect.to_c_str().with_ref |buf| {
llvm::LLVMSetSection(v, 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(*) => { ast::foreign_item_static(*) => {
let ident = token::ident_to_str(&ni.ident); 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 { unsafe {
let ty = type_of(ccx, ty); let ty = type_of(ccx, ty);
llvm::LLVMAddGlobal(ccx.llmod, ty.to_ref(), buf) 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 s = mangle_exported_name(ccx, p, ty::mk_int()).to_managed();
let disr_val = vi[i].disr_val; let disr_val = vi[i].disr_val;
note_unique_llvm_symbol(ccx, s); 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 { unsafe {
llvm::LLVMAddGlobal(ccx.llmod, ccx.int_type.to_ref(), buf) 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_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 { unsafe {
llvm::LLVMAddGlobal(ccx.llmod, Type::i32().to_ref(), buf) 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 { pub fn create_module_map(ccx: &mut CrateContext) -> ValueRef {
let elttype = Type::struct_([ccx.int_type, ccx.int_type], false); let elttype = Type::struct_([ccx.int_type, ccx.int_type], false);
let maptype = Type::array(&elttype, (ccx.module_data.len() + 1) as u64); 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 { unsafe {
llvm::LLVMAddGlobal(ccx.llmod, maptype.to_ref(), buf) 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 sym_name = ~"_rust_crate_map_" + mapname;
let arrtype = Type::array(&int_type, n_subcrates as u64); let arrtype = Type::array(&int_type, n_subcrates as u64);
let maptype = Type::struct_([Type::i32(), Type::i8p(), int_type, arrtype], false); 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 { unsafe {
llvm::LLVMAddGlobal(llmod, maptype.to_ref(), buf) llvm::LLVMAddGlobal(llmod, maptype.to_ref(), buf)
} }
@ -2856,7 +2857,7 @@ pub fn fill_crate_map(ccx: @mut CrateContext, map: ValueRef) {
cdata.name, cdata.name,
cstore::get_crate_vers(cstore, i), cstore::get_crate_vers(cstore, i),
cstore::get_crate_hash(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 { unsafe {
llvm::LLVMAddGlobal(ccx.llmod, ccx.int_type.to_ref(), buf) 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 encode_parms = crate_ctxt_to_encode_parms(cx, encode_inlined_item);
let llmeta = C_bytes(encoder::encode_metadata(encode_parms, crate)); let llmeta = C_bytes(encoder::encode_metadata(encode_parms, crate));
let llconst = C_struct([llmeta]); 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 { unsafe {
llvm::LLVMAddGlobal(cx.llmod, val_ty(llconst).to_ref(), buf) llvm::LLVMAddGlobal(cx.llmod, val_ty(llconst).to_ref(), buf)
} }
}; };
unsafe { unsafe {
llvm::LLVMSetInitializer(llglobal, llconst); 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) llvm::LLVMSetSection(llglobal, buf)
}; };
lib::llvm::SetLinkage(llglobal, lib::llvm::InternalLinkage); lib::llvm::SetLinkage(llglobal, lib::llvm::InternalLinkage);
let t_ptr_i8 = Type::i8p(); let t_ptr_i8 = Type::i8p();
llglobal = llvm::LLVMConstBitCast(llglobal, t_ptr_i8.to_ref()); 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) llvm::LLVMAddGlobal(cx.llmod, Type::array(&t_ptr_i8, 1).to_ref(), buf)
}; };
lib::llvm::SetLinkage(llvm_used, lib::llvm::AppendingLinkage); lib::llvm::SetLinkage(llvm_used, lib::llvm::AppendingLinkage);
@ -2947,7 +2948,7 @@ fn mk_global(ccx: &CrateContext,
internal: bool) internal: bool)
-> ValueRef { -> ValueRef {
unsafe { 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::LLVMAddGlobal(ccx.llmod, val_ty(llval).to_ref(), buf)
}; };
llvm::LLVMSetInitializer(llglobal, llval); llvm::LLVMSetInitializer(llglobal, llval);

View File

@ -423,7 +423,7 @@ impl Builder {
if name.is_empty() { if name.is_empty() {
llvm::LLVMBuildAlloca(self.llbuilder, ty.to_ref(), noname()) llvm::LLVMBuildAlloca(self.llbuilder, ty.to_ref(), noname())
} else { } else {
do name.as_c_str |c| { do name.to_c_str().with_ref |c| {
llvm::LLVMBuildAlloca(self.llbuilder, ty.to_ref(), c) llvm::LLVMBuildAlloca(self.llbuilder, ty.to_ref(), c)
} }
} }
@ -739,7 +739,7 @@ impl Builder {
let sanitized = text.replace("$", ""); let sanitized = text.replace("$", "");
let comment_text = fmt!("# %s", sanitized.replace("\n", "\n\t# ")); let comment_text = fmt!("# %s", sanitized.replace("\n", "\n\t# "));
self.count_insn("inlineasm"); 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 { unsafe {
llvm::LLVMConstInlineAsm(Type::func([], &Type::void()).to_ref(), llvm::LLVMConstInlineAsm(Type::func([], &Type::void()).to_ref(),
c, noname(), False, False) c, noname(), False, False)
@ -895,7 +895,7 @@ impl Builder {
let BB: BasicBlockRef = llvm::LLVMGetInsertBlock(self.llbuilder); let BB: BasicBlockRef = llvm::LLVMGetInsertBlock(self.llbuilder);
let FN: ValueRef = llvm::LLVMGetBasicBlockParent(BB); let FN: ValueRef = llvm::LLVMGetBasicBlockParent(BB);
let M: ModuleRef = llvm::LLVMGetGlobalParent(FN); 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) llvm::LLVMGetNamedFunction(M, buf)
}; };
assert!((T as int != 0)); assert!((T as int != 0));

View File

@ -31,6 +31,7 @@ use util::ppaux::{Repr};
use middle::trans::type_::Type; use middle::trans::type_::Type;
use std::c_str::ToCStr;
use std::cast::transmute; use std::cast::transmute;
use std::cast; use std::cast;
use std::hashmap::{HashMap}; 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 { pub fn C_floating(s: &str, t: Type) -> ValueRef {
unsafe { unsafe {
do s.as_c_str |buf| { do s.to_c_str().with_ref |buf| {
llvm::LLVMConstRealOfString(t.to_ref(), buf) llvm::LLVMConstRealOfString(t.to_ref(), buf)
} }
} }
@ -755,12 +756,12 @@ pub fn C_cstr(cx: &mut CrateContext, s: @str) -> ValueRef {
None => () 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) llvm::LLVMConstStringInContext(cx.llcx, buf, s.len() as c_uint, False)
}; };
let gsym = token::gensym("str"); 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::LLVMAddGlobal(cx.llmod, val_ty(sc).to_ref(), buf)
}; };
llvm::LLVMSetInitializer(g, sc); llvm::LLVMSetInitializer(g, sc);

View File

@ -30,6 +30,7 @@ use util::ppaux::{Repr, ty_to_str};
use middle::trans::type_::Type; use middle::trans::type_::Type;
use std::c_str::ToCStr;
use std::libc::c_uint; use std::libc::c_uint;
use syntax::{ast, ast_util, ast_map}; 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 { fn const_addr_of(cx: &mut CrateContext, cv: ValueRef) -> ValueRef {
unsafe { 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::LLVMAddGlobal(cx.llmod, val_ty(cv).to_ref(), name)
}; };
llvm::LLVMSetInitializer(gv, cv); 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) => { ast::expr_vec(ref es, ast::m_imm) => {
let (cv, sz, llunitty) = const_vec(cx, e, *es); let (cv, sz, llunitty) = const_vec(cx, e, *es);
let llty = val_ty(cv); 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::LLVMAddGlobal(cx.llmod, llty.to_ref(), name)
}; };
llvm::LLVMSetInitializer(gv, cv); llvm::LLVMSetInitializer(gv, cv);

View File

@ -26,6 +26,7 @@ use middle::ty;
use middle::trans::type_::Type; use middle::trans::type_::Type;
use std::c_str::ToCStr;
use std::hash; use std::hash;
use std::hashmap::{HashMap, HashSet}; use std::hashmap::{HashMap, HashSet};
use std::local_data; use std::local_data;
@ -124,11 +125,17 @@ impl CrateContext {
unsafe { unsafe {
let llcx = llvm::LLVMContextCreate(); let llcx = llvm::LLVMContextCreate();
set_task_llcx(llcx); 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 data_layout: &str = sess.targ_cfg.target_strs.data_layout;
let targ_triple: &str = sess.targ_cfg.target_strs.target_triple; let targ_triple: &str = sess.targ_cfg.target_strs.target_triple;
data_layout.as_c_str(|buf| llvm::LLVMSetDataLayout(llmod, buf)); do data_layout.to_c_str().with_ref |buf| {
targ_triple.as_c_str(|buf| llvm::LLVMSetTarget(llmod, 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 targ_cfg = sess.targ_cfg;
let td = mk_target_data(sess.targ_cfg.target_strs.data_layout); let td = mk_target_data(sess.targ_cfg.target_strs.data_layout);

View File

@ -8,6 +8,7 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
use std::c_str::ToCStr;
use back::link; use back::link;
use lib; use lib;
@ -240,7 +241,7 @@ pub fn trans_log(log_ex: &ast::expr,
ccx, modpath, "loglevel"); ccx, modpath, "loglevel");
let global; let global;
unsafe { 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::LLVMAddGlobal(ccx.llmod, Type::i32().to_ref(), buf)
}; };
llvm::LLVMSetGlobalConstant(global, False); llvm::LLVMSetGlobalConstant(global, False);

View File

@ -63,6 +63,7 @@ use middle::ty;
use middle::pat_util; use middle::pat_util;
use util::ppaux::ty_to_str; use util::ppaux::ty_to_str;
use std::c_str::ToCStr;
use std::hashmap::HashMap; use std::hashmap::HashMap;
use std::libc::{c_uint, c_ulonglong, c_longlong}; use std::libc::{c_uint, c_ulonglong, c_longlong};
use std::ptr; 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 ty = node_id_type(bcx, node_id);
let type_metadata = type_metadata(cx, ty, span); 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 { unsafe {
llvm::LLVMDIBuilderCreateLocalVariable( llvm::LLVMDIBuilderCreateLocalVariable(
DIB(cx), DIB(cx),
@ -246,7 +247,7 @@ pub fn create_argument_metadata(bcx: @mut Block,
argument_index as c_uint 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 { unsafe {
llvm::LLVMDIBuilderCreateLocalVariable( llvm::LLVMDIBuilderCreateLocalVariable(
DIB(cx), DIB(cx),
@ -382,8 +383,8 @@ pub fn create_function_metadata(fcx: &FunctionContext) -> DISubprogram {
}; };
let fn_metadata = let fn_metadata =
do cx.sess.str_of(ident).as_c_str |name| { do cx.sess.str_of(ident).to_c_str().with_ref |name| {
do cx.sess.str_of(ident).as_c_str |linkage| { do cx.sess.str_of(ident).to_c_str().with_ref |linkage| {
unsafe { unsafe {
llvm::LLVMDIBuilderCreateFunction( llvm::LLVMDIBuilderCreateFunction(
DIB(cx), DIB(cx),
@ -430,11 +431,11 @@ fn compile_unit_metadata(cx: @mut CrateContext) {
let work_dir = cx.sess.working_dir.to_str(); let work_dir = cx.sess.working_dir.to_str();
let producer = fmt!("rustc version %s", env!("CFG_VERSION")); let producer = fmt!("rustc version %s", env!("CFG_VERSION"));
do crate_name.as_c_str |crate_name| { do crate_name.to_c_str().with_ref |crate_name| {
do work_dir.as_c_str |work_dir| { do work_dir.to_c_str().with_ref |work_dir| {
do producer.as_c_str |producer| { do producer.to_c_str().with_ref |producer| {
do "".as_c_str |flags| { do "".to_c_str().with_ref |flags| {
do "".as_c_str |split_name| { do "".to_c_str().with_ref |split_name| {
unsafe { unsafe {
llvm::LLVMDIBuilderCreateCompileUnit(dcx.builder, llvm::LLVMDIBuilderCreateCompileUnit(dcx.builder,
DW_LANG_RUST as c_uint, crate_name, work_dir, producer, 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 = let file_metadata =
do file_name.as_c_str |file_name| { do file_name.to_c_str().with_ref |file_name| {
do work_dir.as_c_str |work_dir| { do work_dir.to_c_str().with_ref |work_dir| {
unsafe { unsafe {
llvm::LLVMDIBuilderCreateFile(DIB(cx), file_name, work_dir) 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 llvm_type = type_of::type_of(cx, t);
let (size, align) = size_and_align_of(cx, llvm_type); 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 { unsafe {
llvm::LLVMDIBuilderCreateBasicType( llvm::LLVMDIBuilderCreateBasicType(
DIB(cx), 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_llvm_type = type_of::type_of(cx, pointer_type);
let (pointer_size, pointer_align) = size_and_align_of(cx, pointer_llvm_type); let (pointer_size, pointer_align) = size_and_align_of(cx, pointer_llvm_type);
let name = ty_to_str(cx.tcx, pointer_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 { unsafe {
llvm::LLVMDIBuilderCreatePointerType( llvm::LLVMDIBuilderCreatePointerType(
DIB(cx), DIB(cx),
@ -665,7 +666,7 @@ fn enum_metadata(cx: &mut CrateContext,
let name: &str = cx.sess.str_of(v.name); let name: &str = cx.sess.str_of(v.name);
let discriminant_value = v.disr_val as c_ulonglong; let discriminant_value = v.disr_val as c_ulonglong;
do name.as_c_str |name| { do name.to_c_str().with_ref |name| {
unsafe { unsafe {
llvm::LLVMDIBuilderCreateEnumerator( llvm::LLVMDIBuilderCreateEnumerator(
DIB(cx), DIB(cx),
@ -679,7 +680,7 @@ fn enum_metadata(cx: &mut CrateContext,
let loc = span_start(cx, span); let loc = span_start(cx, span);
let file_metadata = file_metadata(cx, loc.file.name); 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 { unsafe {
llvm::LLVMDIBuilderCreateEnumerationType( llvm::LLVMDIBuilderCreateEnumerationType(
DIB(cx), DIB(cx),
@ -716,7 +717,7 @@ fn enum_metadata(cx: &mut CrateContext,
Some(discriminant_type_metadata), Some(discriminant_type_metadata),
span); span);
do "".as_c_str |name| { do "".to_c_str().with_ref |name| {
unsafe { unsafe {
llvm::LLVMDIBuilderCreateMemberType( llvm::LLVMDIBuilderCreateMemberType(
DIB(cx), 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_llvm_type = type_of::type_of(cx, enum_type);
let (enum_type_size, enum_type_align) = size_and_align_of(cx, enum_llvm_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 { unsafe {
llvm::LLVMDIBuilderCreateUnionType( llvm::LLVMDIBuilderCreateUnionType(
DIB(cx), 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_offset = machine::llelement_offset(cx, composite_llvm_type, i);
let member_name: &str = member_names[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 { unsafe {
llvm::LLVMDIBuilderCreateMemberType( llvm::LLVMDIBuilderCreateMemberType(
DIB(cx), DIB(cx),
@ -838,7 +839,7 @@ fn composite_type_metadata(cx: &mut CrateContext,
}) })
.collect(); .collect();
return do composite_type_name.as_c_str |name| { return do composite_type_name.to_c_str().with_ref |name| {
unsafe { unsafe {
llvm::LLVMDIBuilderCreateStructType( llvm::LLVMDIBuilderCreateStructType(
DIB(cx), DIB(cx),
@ -1064,7 +1065,7 @@ fn unimplemented_type_metadata(cx: &mut CrateContext, t: ty::t) -> DIType {
debug!("unimplemented_type_metadata: %?", ty::get(t)); debug!("unimplemented_type_metadata: %?", ty::get(t));
let name = ty_to_str(cx.tcx, 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 { unsafe {
llvm::LLVMDIBuilderCreateBasicType( llvm::LLVMDIBuilderCreateBasicType(
DIB(cx), DIB(cx),

View File

@ -964,7 +964,7 @@ fn trans_lvalue_unadjusted(bcx: @mut Block, expr: @ast::expr) -> DatumBlock {
let symbol = csearch::get_symbol( let symbol = csearch::get_symbol(
bcx.ccx().sess.cstore, bcx.ccx().sess.cstore,
did); did);
let llval = do symbol.as_c_str |buf| { let llval = do symbol.to_c_str().with_ref |buf| {
llvm::LLVMAddGlobal(bcx.ccx().llmod, llvm::LLVMAddGlobal(bcx.ccx().llmod,
llty.to_ref(), llty.to_ref(),
buf) buf)

View File

@ -37,6 +37,7 @@ use util::ppaux::ty_to_short_str;
use middle::trans::type_::Type; use middle::trans::type_::Type;
use std::c_str::ToCStr;
use std::libc::c_uint; use std::libc::c_uint;
use syntax::ast; 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(); let name = mangle_internal_name_by_type_and_seq(ccx, t, "tydesc").to_managed();
note_unique_llvm_symbol(ccx, name); note_unique_llvm_symbol(ccx, name);
debug!("+++ declare_tydesc %s %s", ppaux::ty_to_str(ccx.tcx, t), 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 { unsafe {
llvm::LLVMAddGlobal(ccx.llmod, ccx.tydesc_type.to_ref(), buf) llvm::LLVMAddGlobal(ccx.llmod, ccx.tydesc_type.to_ref(), buf)
} }

View File

@ -32,6 +32,7 @@ use util::ppaux::Repr;
use middle::trans::type_::Type; use middle::trans::type_::Type;
use std::c_str::ToCStr;
use std::vec; use std::vec;
use syntax::ast_map::{path, path_mod, path_name}; use syntax::ast_map::{path, path_mod, path_name};
use syntax::ast_util; use syntax::ast_util;
@ -605,7 +606,7 @@ pub fn make_vtable(ccx: &mut CrateContext,
let tbl = C_struct(components); let tbl = C_struct(components);
let vtable = ccx.sess.str_of(gensym_name("vtable")); 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::LLVMAddGlobal(ccx.llmod, val_ty(tbl).to_ref(), buf)
}; };
llvm::LLVMSetInitializer(vt_gvar, tbl); llvm::LLVMSetInitializer(vt_gvar, tbl);

View File

@ -20,6 +20,7 @@ use middle::trans::base;
use syntax::ast; use syntax::ast;
use syntax::abi::{Architecture, X86, X86_64, Arm, Mips}; use syntax::abi::{Architecture, X86, X86_64, Arm, Mips};
use std::c_str::ToCStr;
use std::vec; use std::vec;
use std::cast; use std::cast;
@ -170,7 +171,7 @@ impl Type {
pub fn named_struct(name: &str) -> Type { pub fn named_struct(name: &str) -> Type {
let ctx = base::task_llcx(); 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 { pub fn empty_struct() -> Type {

View File

@ -9,6 +9,7 @@
// except according to those terms. // except according to those terms.
use std::{os, result}; use std::{os, result};
use std::c_str::ToCStr;
use rustc::driver::{driver, session}; use rustc::driver::{driver, session};
use rustc::metadata::filesearch; use rustc::metadata::filesearch;
use extra::getopts::groups::getopts; 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 { pub fn link_exe(src: &Path, dest: &Path) -> bool {
use std::libc; use std::libc;
unsafe { unsafe {
do src.to_str().as_c_str |src_buf| { do src.to_c_str().with_ref |src_buf| {
do dest.to_str().as_c_str |dest_buf| { do dest.to_c_str().with_ref |dest_buf| {
libc::link(src_buf, dest_buf) == 0 as libc::c_int && libc::link(src_buf, dest_buf) == 0 as libc::c_int &&
libc::chmod(dest_buf, 755) == 0 as libc::c_int libc::chmod(dest_buf, 755) == 0 as libc::c_int
} }

291
src/libstd/c_str.rs Normal file
View File

@ -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(|_| ());
}
}

View File

@ -48,6 +48,7 @@ implement `Reader` and `Writer`, where appropriate.
use cast; use cast;
use clone::Clone; use clone::Clone;
use c_str::ToCStr;
use container::Container; use container::Container;
use int; use int;
use iterator::Iterator; use iterator::Iterator;
@ -1040,8 +1041,8 @@ pub fn stdin() -> @Reader {
} }
pub fn file_reader(path: &Path) -> Result<@Reader, ~str> { pub fn file_reader(path: &Path) -> Result<@Reader, ~str> {
let f = do path.to_str().as_c_str |pathbuf| { let f = do path.to_c_str().with_ref |pathbuf| {
do "r".as_c_str |modebuf| { do "r".to_c_str().with_ref |modebuf| {
unsafe { libc::fopen(pathbuf, modebuf as *libc::c_char) } unsafe { libc::fopen(pathbuf, modebuf as *libc::c_char) }
} }
}; };
@ -1290,9 +1291,8 @@ pub fn mk_file_writer(path: &Path, flags: &[FileFlag])
} }
} }
let fd = unsafe { let fd = unsafe {
do path.to_str().as_c_str |pathbuf| { do path.to_c_str().with_ref |pathbuf| {
libc::open(pathbuf, fflags, libc::open(pathbuf, fflags, (S_IRUSR | S_IWUSR) as c_int)
(S_IRUSR | S_IWUSR) as c_int)
} }
}; };
if fd < (0 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 // FIXME: fileflags // #2004
pub fn buffered_file_writer(path: &Path) -> Result<@Writer, ~str> { pub fn buffered_file_writer(path: &Path) -> Result<@Writer, ~str> {
unsafe { unsafe {
let f = do path.to_str().as_c_str |pathbuf| { let f = do path.to_c_str().with_ref |pathbuf| {
do "w".as_c_str |modebuf| { do "w".to_c_str().with_ref |modebuf| {
libc::fopen(pathbuf, modebuf) libc::fopen(pathbuf, modebuf)
} }
}; };

View File

@ -28,6 +28,7 @@
#[allow(missing_doc)]; #[allow(missing_doc)];
use c_str::ToCStr;
use cast; use cast;
use clone::Clone; use clone::Clone;
use container::Container; use container::Container;
@ -241,7 +242,9 @@ pub fn env() -> ~[(~str,~str)] {
pub fn getenv(n: &str) -> Option<~str> { pub fn getenv(n: &str) -> Option<~str> {
unsafe { unsafe {
do with_env_lock { 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) { if ptr::null::<u8>() == cast::transmute(s) {
None None
} else { } else {
@ -274,8 +277,8 @@ pub fn getenv(n: &str) -> Option<~str> {
pub fn setenv(n: &str, v: &str) { pub fn setenv(n: &str, v: &str) {
unsafe { unsafe {
do with_env_lock { do with_env_lock {
do n.to_str().as_c_str |nbuf| { do n.to_c_str().with_ref |nbuf| {
do v.to_str().as_c_str |vbuf| { do v.to_c_str().with_ref |vbuf| {
libc::funcs::posix01::unistd::setenv(nbuf, vbuf, 1); libc::funcs::posix01::unistd::setenv(nbuf, vbuf, 1);
} }
} }
@ -306,7 +309,7 @@ pub fn unsetenv(n: &str) {
fn _unsetenv(n: &str) { fn _unsetenv(n: &str) {
unsafe { unsafe {
do with_env_lock { 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); libc::funcs::posix01::unistd::unsetenv(nbuf);
} }
} }
@ -328,7 +331,7 @@ pub fn unsetenv(n: &str) {
} }
pub fn fdopen(fd: c_int) -> *FILE { pub fn fdopen(fd: c_int) -> *FILE {
do "r".as_c_str |modebuf| { do "r".to_c_str().with_ref |modebuf| {
unsafe { unsafe {
libc::fdopen(fd, modebuf) libc::fdopen(fd, modebuf)
} }
@ -462,9 +465,9 @@ pub fn self_exe_path() -> Option<Path> {
use libc::funcs::posix01::unistd::readlink; use libc::funcs::posix01::unistd::readlink;
let mut path_str = str::with_capacity(TMPBUF_SZ); 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; 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) 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 /// Indicates whether a path represents a directory
pub fn path_is_dir(p: &Path) -> bool { pub fn path_is_dir(p: &Path) -> bool {
unsafe { 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 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 /// Indicates whether a path exists
pub fn path_exists(p: &Path) -> bool { pub fn path_exists(p: &Path) -> bool {
unsafe { 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 rustrt::rust_path_exists(buf) != 0 as c_int
} }
} }
@ -647,7 +650,7 @@ pub fn make_dir(p: &Path, mode: c_int) -> bool {
#[cfg(unix)] #[cfg(unix)]
fn mkdir(p: &Path, mode: c_int) -> bool { 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 { unsafe {
libc::mkdir(buf, mode as libc::mode_t) == (0 as c_int) libc::mkdir(buf, mode as libc::mode_t) == (0 as c_int)
} }
@ -823,7 +826,7 @@ pub fn remove_dir(p: &Path) -> bool {
#[cfg(unix)] #[cfg(unix)]
fn rmdir(p: &Path) -> bool { fn rmdir(p: &Path) -> bool {
do p.to_str().as_c_str |buf| { do p.to_c_str().with_ref |buf| {
unsafe { unsafe {
libc::rmdir(buf) == (0 as c_int) libc::rmdir(buf) == (0 as c_int)
} }
@ -848,7 +851,7 @@ pub fn change_dir(p: &Path) -> bool {
#[cfg(unix)] #[cfg(unix)]
fn chdir(p: &Path) -> bool { fn chdir(p: &Path) -> bool {
do p.to_str().as_c_str |buf| { do p.to_c_str().with_ref |buf| {
unsafe { unsafe {
libc::chdir(buf) == (0 as c_int) libc::chdir(buf) == (0 as c_int)
} }
@ -876,8 +879,8 @@ pub fn copy_file(from: &Path, to: &Path) -> bool {
#[cfg(unix)] #[cfg(unix)]
fn do_copy_file(from: &Path, to: &Path) -> bool { fn do_copy_file(from: &Path, to: &Path) -> bool {
unsafe { unsafe {
let istream = do from.to_str().as_c_str |fromp| { let istream = do from.to_c_str().with_ref |fromp| {
do "rb".as_c_str |modebuf| { do "rb".to_c_str().with_ref |modebuf| {
libc::fopen(fromp, modebuf) libc::fopen(fromp, modebuf)
} }
}; };
@ -888,8 +891,8 @@ pub fn copy_file(from: &Path, to: &Path) -> bool {
let from_mode = from.get_mode().expect("copy_file: couldn't get permissions \ let from_mode = from.get_mode().expect("copy_file: couldn't get permissions \
for source file"); for source file");
let ostream = do to.to_str().as_c_str |top| { let ostream = do to.to_c_str().with_ref |top| {
do "w+b".as_c_str |modebuf| { do "w+b".to_c_str().with_ref |modebuf| {
libc::fopen(top, modebuf) libc::fopen(top, modebuf)
} }
}; };
@ -921,7 +924,7 @@ pub fn copy_file(from: &Path, to: &Path) -> bool {
fclose(ostream); fclose(ostream);
// Give the new file the old file's permissions // 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) libc::chmod(to_buf, from_mode as libc::mode_t)
} != 0 { } != 0 {
return false; // should be a condition... return false; // should be a condition...
@ -948,7 +951,7 @@ pub fn remove_file(p: &Path) -> bool {
#[cfg(unix)] #[cfg(unix)]
fn unlink(p: &Path) -> bool { fn unlink(p: &Path) -> bool {
unsafe { unsafe {
do p.to_str().as_c_str |buf| { do p.to_c_str().with_ref |buf| {
libc::unlink(buf) == (0 as c_int) libc::unlink(buf) == (0 as c_int)
} }
} }
@ -1294,7 +1297,7 @@ pub fn glob(pattern: &str) -> ~[Path] {
} }
let mut g = default_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) } unsafe { libc::glob(c_pattern, 0, ptr::null(), &mut g) }
}; };
do(|| { do(|| {
@ -1699,6 +1702,7 @@ pub mod consts {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use c_str::ToCStr;
use libc::{c_int, c_void, size_t}; use libc::{c_int, c_void, size_t};
use libc; use libc;
use option::Some; use option::Some;
@ -1711,7 +1715,6 @@ mod tests {
use rand; use rand;
use run; use run;
use str::StrSlice; use str::StrSlice;
use vec::CopyableVector;
use libc::consts::os::posix88::{S_IRUSR, S_IWUSR, S_IXUSR}; use libc::consts::os::posix88::{S_IRUSR, S_IWUSR, S_IXUSR};
@ -1941,19 +1944,19 @@ mod tests {
let out = tempdir.push("out.txt"); let out = tempdir.push("out.txt");
/* Write the temp input file */ /* Write the temp input file */
let ostream = do input.to_str().as_c_str |fromp| { let ostream = do input.to_c_str().with_ref |fromp| {
do "w+b".as_c_str |modebuf| { do "w+b".to_c_str().with_ref |modebuf| {
libc::fopen(fromp, modebuf) libc::fopen(fromp, modebuf)
} }
}; };
assert!((ostream as uint != 0u)); assert!((ostream as uint != 0u));
let s = ~"hello"; let s = ~"hello";
let mut buf = s.to_owned().to_c_str(); do "hello".to_c_str().with_ref |buf| {
let len = buf.len(); let write_len = libc::fwrite(buf as *c_void,
do buf.as_mut_buf |b, _len| { 1u as size_t,
assert_eq!(libc::fwrite(b as *c_void, 1u as size_t, (s.len() + 1u) as size_t,
(s.len() + 1u) as size_t, ostream), ostream);
len as size_t) assert_eq!(write_len, (s.len() + 1) as size_t)
} }
assert_eq!(libc::fclose(ostream), (0u as c_int)); assert_eq!(libc::fclose(ostream), (0u as c_int));
let in_mode = input.get_mode(); let in_mode = input.get_mode();
@ -2025,11 +2028,11 @@ mod tests {
remove_file(&path); remove_file(&path);
let fd = unsafe { 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) open(path, O_CREAT | O_RDWR | O_TRUNC, S_IRUSR | S_IWUSR)
}; };
lseek_(fd, size); 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); assert!(write(fd, x as *c_void, 1) == 1);
} }
fd fd

View File

@ -16,9 +16,11 @@ Cross-platform file path handling
#[allow(missing_doc)]; #[allow(missing_doc)];
use c_str::ToCStr;
use c_str;
use clone::Clone; use clone::Clone;
use container::Container;
use cmp::Eq; use cmp::Eq;
use container::Container;
use iterator::{Iterator, IteratorUtil}; use iterator::{Iterator, IteratorUtil};
use libc; use libc;
use option::{None, Option, Some}; use option::{None, Option, Some};
@ -341,7 +343,7 @@ mod stat {
#[cfg(target_os = "win32")] #[cfg(target_os = "win32")]
impl WindowsPath { impl WindowsPath {
pub fn stat(&self) -> Option<libc::stat> { 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(); let mut st = stat::arch::default_stat();
match unsafe { libc::stat(buf, &mut st) } { match unsafe { libc::stat(buf, &mut st) } {
0 => Some(st), 0 => Some(st),
@ -375,7 +377,7 @@ impl WindowsPath {
#[cfg(not(target_os = "win32"))] #[cfg(not(target_os = "win32"))]
impl PosixPath { impl PosixPath {
pub fn stat(&self) -> Option<libc::stat> { 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(); let mut st = stat::arch::default_stat();
match unsafe { libc::stat(buf as *libc::c_char, &mut st) } { match unsafe { libc::stat(buf as *libc::c_char, &mut st) } {
0 => Some(st), 0 => Some(st),
@ -453,7 +455,7 @@ impl PosixPath {
#[cfg(unix)] #[cfg(unix)]
impl PosixPath { impl PosixPath {
pub fn lstat(&self) -> Option<libc::stat> { 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(); let mut st = stat::arch::default_stat();
match unsafe { libc::lstat(buf, &mut st) } { match unsafe { libc::lstat(buf, &mut st) } {
0 => Some(st), 0 => Some(st),
@ -525,6 +527,12 @@ impl ToStr for PosixPath {
} }
} }
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 // FIXME (#3227): when default methods in traits are working, de-duplicate
// PosixPath and WindowsPath, most of their methods are common. // PosixPath and WindowsPath, most of their methods are common.
impl GenericPath for PosixPath { impl GenericPath for PosixPath {
@ -730,6 +738,11 @@ impl ToStr for WindowsPath {
} }
} }
impl c_str::ToCStr for WindowsPath {
fn to_c_str(&self) -> c_str::CString {
self.to_str().to_c_str()
}
}
impl GenericPath for WindowsPath { impl GenericPath for WindowsPath {
fn from_str(s: &str) -> WindowsPath { fn from_str(s: &str) -> WindowsPath {

View File

@ -43,6 +43,7 @@ pub use io::{print, println};
pub use iterator::range; pub use iterator::range;
// Reexported types and traits // Reexported types and traits
pub use c_str::ToCStr;
pub use clone::{Clone, DeepClone}; pub use clone::{Clone, DeepClone};
pub use cmp::{Eq, ApproxEq, Ord, TotalEq, TotalOrd, Ordering, Less, Equal, Greater, Equiv}; pub use cmp::{Eq, ApproxEq, Ord, TotalEq, TotalOrd, Ordering, Less, Equal, Greater, Equiv};
pub use char::Char; pub use char::Char;

View File

@ -486,24 +486,25 @@ pub mod ptr_tests {
#[test] #[test]
fn test_position() { fn test_position() {
use c_str::ToCStr;
use libc::c_char; use libc::c_char;
let s = ~"hello"; do "hello".to_c_str().with_ref |p| {
unsafe { unsafe {
assert!(2u == s.as_c_str(|p| position(p, |c| *c == 'l' as c_char))); assert!(2u == position(p, |c| *c == 'l' as c_char));
assert!(4u == s.as_c_str(|p| position(p, |c| *c == 'o' as c_char))); assert!(4u == position(p, |c| *c == 'o' as c_char));
assert!(5u == s.as_c_str(|p| position(p, |c| *c == 0 as c_char))); assert!(5u == position(p, |c| *c == 0 as c_char));
}
} }
} }
#[test] #[test]
fn test_buf_len() { fn test_buf_len() {
let s0 = ~"hello"; use c_str::ToCStr;
let s1 = ~"there";
let s2 = ~"thing"; do "hello".to_c_str().with_ref |p0| {
do s0.as_c_str |p0| { do "there".to_c_str().with_ref |p1| {
do s1.as_c_str |p1| { do "thing".to_c_str().with_ref |p2| {
do s2.as_c_str |p2| {
let v = ~[p0, p1, p2, null()]; let v = ~[p0, p1, p2, null()];
do v.as_imm_buf |vp, len| { do v.as_imm_buf |vp, len| {
assert_eq!(unsafe { buf_len(vp) }, 3u); assert_eq!(unsafe { buf_len(vp) }, 3u);

View File

@ -8,6 +8,7 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
use c_str::ToCStr;
use cast::transmute; use cast::transmute;
use libc::{c_char, c_void, size_t, STDERR_FILENO}; use libc::{c_char, c_void, size_t, STDERR_FILENO};
use io; 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() { match try_take_task_borrow_list() {
None => { // not recording borrows None => { // not recording borrows
let msg = "borrowed"; 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); 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 "; 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) 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(); let br = borrow_list.pop();
if br.box != a || br.file != file || br.line != line { if br.box != a || br.file != file || br.line != line {
let err = fmt!("wrong borrow found, br=%?", br); 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) sys::begin_unwind_(msg_p, file, line)
} }
} }

View File

@ -45,15 +45,15 @@ impl Logger for StdErrLogger {
/// Configure logging by traversing the crate map and setting the /// Configure logging by traversing the crate map and setting the
/// per-module global logging flags based on the logging spec /// per-module global logging flags based on the logging spec
pub fn init(crate_map: *u8) { pub fn init(crate_map: *u8) {
use c_str::ToCStr;
use os; use os;
use str::StrSlice;
use ptr; use ptr;
use option::{Some, None}; use option::{Some, None};
let log_spec = os::getenv("RUST_LOG"); let log_spec = os::getenv("RUST_LOG");
match log_spec { match log_spec {
Some(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) } unsafe { rust_update_log_settings(crate_map, buf) }
} }
} }

View File

@ -8,26 +8,26 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
use option::*; use c_str::ToCStr;
use result::*;
use ops::Drop;
use cell::Cell;
use cast;
use cast::transmute; use cast::transmute;
use cast;
use cell::Cell;
use clone::Clone; use clone::Clone;
use libc::{c_int, c_uint, c_void}; use libc::{c_int, c_uint, c_void};
use ops::Drop;
use option::*;
use ptr; use ptr;
use result::*;
use rt::io::IoError; use rt::io::IoError;
use rt::io::net::ip::{IpAddr, Ipv4, Ipv6}; use rt::io::net::ip::{IpAddr, Ipv4, Ipv6};
use rt::io::{standard_error, OtherIoError};
use rt::local::Local;
use rt::rtio::*;
use rt::sched::Scheduler;
use rt::tube::Tube;
use rt::uv::*; use rt::uv::*;
use rt::uv::idle::IdleWatcher; use rt::uv::idle::IdleWatcher;
use rt::uv::net::{UvIpv4, UvIpv6}; use rt::uv::net::{UvIpv4, UvIpv6};
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 unstable::sync::Exclusive; use unstable::sync::Exclusive;
#[cfg(test)] use container::Container; #[cfg(test)] use container::Container;
@ -663,7 +663,7 @@ impl RtioUdpSocket for UvUdpSocket {
}; };
let r = unsafe { 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, uvll::udp_set_membership(self.native_handle(), m_addr,
ptr::null(), uvll::UV_JOIN_GROUP) ptr::null(), uvll::UV_JOIN_GROUP)
} }
@ -686,7 +686,7 @@ impl RtioUdpSocket for UvUdpSocket {
}; };
let r = unsafe { 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, uvll::udp_set_membership(self.native_handle(), m_addr,
ptr::null(), uvll::UV_LEAVE_GROUP) ptr::null(), uvll::UV_LEAVE_GROUP)
} }

View File

@ -29,6 +29,7 @@
#[allow(non_camel_case_types)]; // C types #[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::{size_t, c_int, c_uint, c_void, c_char, uintptr_t};
use libc::{malloc, free}; use libc::{malloc, free};
use libc; 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 { 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) 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 { 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) rust_uv_ip6_addrp(ip_buf as *u8, port as libc::c_int)
} }
} }

View File

@ -12,6 +12,7 @@
#[allow(missing_doc)]; #[allow(missing_doc)];
use c_str::ToCStr;
use cast; use cast;
use clone::Clone; use clone::Clone;
use comm::{stream, SharedChan, GenericChan, GenericPort}; 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_envp(env) |envp| {
do with_dirp(dir) |dirp| { 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), let created = CreateProcessA(ptr::null(), cast::transmute(cmdp),
ptr::mut_null(), ptr::mut_null(), TRUE, ptr::mut_null(), ptr::mut_null(), TRUE,
0, envp, dirp, &mut si, &mut pi); 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. // hold all the ~[u8] byte strings.
let mut tmps = vec::with_capacity(args.len() + 1); 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() { 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 // Next, convert each of the byte strings into a pointer. This is
// technically unsafe as the caller could leak these pointers out of our // technically unsafe as the caller could leak these pointers out of our
// scope. // scope.
let mut ptrs = do tmps.map |tmp| { 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. // 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. // Once again, this is unsafe.
let mut ptrs = do tmps.map |tmp| { 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()); 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() { foreach pair in env.iter() {
let kv = fmt!("%s=%s", pair.first(), pair.second()); 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); 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 { fn with_dirp<T>(d: Option<&Path>, cb: &fn(*libc::c_char) -> T) -> T {
match d { 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()) None => cb(ptr::null())
} }
} }

View File

@ -172,6 +172,7 @@ pub mod local_data;
pub mod gc; pub mod gc;
pub mod libc; pub mod libc;
pub mod c_str;
pub mod os; pub mod os;
pub mod path; pub mod path;
pub mod rand; pub mod rand;

View File

@ -1182,7 +1182,6 @@ pub trait StrSlice<'self> {
fn subslice_offset(&self, inner: &str) -> uint; fn subslice_offset(&self, inner: &str) -> uint;
fn as_imm_buf<T>(&self, f: &fn(*u8, uint) -> T) -> T; 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 /// Extension methods for strings
@ -1931,32 +1930,6 @@ impl<'self> StrSlice<'self> for &'self str {
let v: &[u8] = unsafe { cast::transmute(*self) }; let v: &[u8] = unsafe { cast::transmute(*self) };
v.as_imm_buf(f) 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)] #[allow(missing_doc)]
@ -1973,13 +1946,6 @@ pub trait OwnedStr {
fn capacity(&self) -> uint; fn capacity(&self) -> uint;
fn to_bytes_with_null(self) -> ~[u8]; 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. /// Work with the mutable byte buffer and length of a slice.
/// ///
/// The given length is one byte longer than the 'official' indexable /// The given length is one byte longer than the 'official' indexable
@ -2171,13 +2137,6 @@ impl OwnedStr for ~str {
unsafe { cast::transmute(self) } 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] #[inline]
fn as_mut_buf<T>(&mut self, f: &fn(*mut u8, uint) -> T) -> T { fn as_mut_buf<T>(&mut self, f: &fn(*mut u8, uint) -> T) -> T {
let v: &mut ~[u8] = unsafe { cast::transmute(self) }; let v: &mut ~[u8] = unsafe { cast::transmute(self) };
@ -2915,63 +2874,6 @@ mod tests {
} }
} }
#[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] #[test]
fn test_subslice_offset() { fn test_subslice_offset() {
let a = "kernelsprite"; let a = "kernelsprite";

View File

@ -12,13 +12,13 @@
#[allow(missing_doc)]; #[allow(missing_doc)];
use c_str::ToCStr;
use cast; use cast;
use gc; use gc;
use io; use io;
use libc; use libc;
use libc::{c_char, size_t}; use libc::{c_char, size_t};
use repr; use repr;
use str::StrSlice;
use str; use str;
use unstable::intrinsics; use unstable::intrinsics;
@ -115,8 +115,8 @@ pub trait FailWithCause {
impl FailWithCause for ~str { impl FailWithCause for ~str {
fn fail_with(cause: ~str, file: &'static str, line: uint) -> ! { fn fail_with(cause: ~str, file: &'static str, line: uint) -> ! {
do cause.as_c_str |msg_buf| { do cause.to_c_str().with_ref |msg_buf| {
do file.as_c_str |file_buf| { do file.to_c_str().with_ref |file_buf| {
begin_unwind_(msg_buf, file_buf, line as libc::size_t) begin_unwind_(msg_buf, file_buf, line as libc::size_t)
} }
} }
@ -125,8 +125,8 @@ impl FailWithCause for ~str {
impl FailWithCause for &'static str { impl FailWithCause for &'static str {
fn fail_with(cause: &'static str, file: &'static str, line: uint) -> ! { fn fail_with(cause: &'static str, file: &'static str, line: uint) -> ! {
do cause.as_c_str |msg_buf| { do cause.to_c_str().with_ref |msg_buf| {
do file.as_c_str |file_buf| { do file.to_c_str().with_ref |file_buf| {
begin_unwind_(msg_buf, file_buf, line as libc::size_t) begin_unwind_(msg_buf, file_buf, line as libc::size_t)
} }
} }

View File

@ -15,6 +15,7 @@ Dynamic library facilities.
A simple wrapper over the platforms dynamic library facilities A simple wrapper over the platforms dynamic library facilities
*/ */
use c_str::ToCStr;
use cast; use cast;
use path; use path;
use libc; use libc;
@ -65,7 +66,7 @@ impl DynamicLibrary {
// T but that feature is still unimplemented // T but that feature is still unimplemented
let maybe_symbol_value = do dl::check_for_errors_in { 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) dl::symbol(self.handle, raw_string)
} }
}; };
@ -135,6 +136,7 @@ mod test {
#[cfg(target_os = "macos")] #[cfg(target_os = "macos")]
#[cfg(target_os = "freebsd")] #[cfg(target_os = "freebsd")]
mod dl { mod dl {
use c_str::ToCStr;
use libc; use libc;
use path; use path;
use ptr; use ptr;
@ -143,7 +145,7 @@ mod dl {
use result::*; use result::*;
pub unsafe fn open_external(filename: &path::Path) -> *libc::c_void { 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) dlopen(raw_name, Lazy as libc::c_int)
} }
} }

View File

@ -10,6 +10,7 @@
//! Runtime calls emitted by the compiler. //! Runtime calls emitted by the compiler.
use c_str::ToCStr;
use cast::transmute; use cast::transmute;
use libc::{c_char, c_uchar, c_void, size_t, uintptr_t, c_int}; use libc::{c_char, c_uchar, c_void, size_t, uintptr_t, c_int};
use str; use str;
@ -49,7 +50,7 @@ pub fn fail_bounds_check(file: *c_char, line: size_t,
index: size_t, len: size_t) { index: size_t, len: size_t) {
let msg = fmt!("index out of bounds: the len is %d but the index is %d", let msg = fmt!("index out of bounds: the len is %d but the index is %d",
len as int, index as int); len as int, index as int);
do msg.as_c_str |buf| { do msg.to_c_str().with_ref |buf| {
fail_(buf, file, line); fail_(buf, file, line);
} }
} }

View File

@ -26,8 +26,9 @@ mod libc {
fn strlen(str: ~str) -> uint { fn strlen(str: ~str) -> uint {
unsafe { unsafe {
// C string is terminated with a zero // C string is terminated with a zero
let bytes = str.to_bytes_with_null(); do str.to_c_str().with_ref |buf| {
return libc::my_strlen(vec::raw::to_ptr(bytes)); libc::my_strlen(buf as *u8)
}
} }
} }