Skip to content

Commit 6f08115

Browse files
committed
Split CString::new into CString::new and CString::new_owned
1 parent ff50f24 commit 6f08115

File tree

12 files changed

+85
-46
lines changed

12 files changed

+85
-46
lines changed

src/libnative/io/addrinfo.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ fn get_error(s: c_int) -> IoError {
106106
use std::c_str::CString;
107107

108108
let err_str = unsafe {
109-
CString::new(gai_strerror(s), false).as_str().unwrap().to_string()
109+
CString::new(gai_strerror(s)).as_str().unwrap().to_string()
110110
};
111111
IoError {
112112
code: s as uint,

src/libnative/io/file_unix.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -351,7 +351,7 @@ pub fn readdir(p: &CString) -> IoResult<Vec<CString>> {
351351
use libc::{opendir, readdir_r, closedir};
352352

353353
fn prune(root: &CString, dirs: Vec<Path>) -> Vec<CString> {
354-
let root = unsafe { CString::new(root.as_ptr(), false) };
354+
let root = unsafe { CString::new(root.as_ptr()) };
355355
let root = Path::new(root);
356356

357357
dirs.into_iter().filter(|path| {
@@ -376,7 +376,7 @@ pub fn readdir(p: &CString) -> IoResult<Vec<CString>> {
376376
while unsafe { readdir_r(dir_ptr, ptr, &mut entry_ptr) == 0 } {
377377
if entry_ptr.is_null() { break }
378378
let cstr = unsafe {
379-
CString::new(rust_list_dir_val(entry_ptr), false)
379+
CString::new(rust_list_dir_val(entry_ptr))
380380
};
381381
paths.push(Path::new(cstr));
382382
}

src/libnative/io/file_windows.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -347,7 +347,7 @@ pub fn mkdir(p: &CString, _mode: uint) -> IoResult<()> {
347347

348348
pub fn readdir(p: &CString) -> IoResult<Vec<CString>> {
349349
fn prune(root: &CString, dirs: Vec<Path>) -> Vec<CString> {
350-
let root = unsafe { CString::new(root.as_ptr(), false) };
350+
let root = unsafe { CString::new(root.as_ptr()) };
351351
let root = Path::new(root);
352352

353353
dirs.into_iter().filter(|path| {
@@ -356,7 +356,7 @@ pub fn readdir(p: &CString) -> IoResult<Vec<CString>> {
356356
}
357357

358358
let star = Path::new(unsafe {
359-
CString::new(p.as_ptr(), false)
359+
CString::new(p.as_ptr())
360360
}).join("*");
361361
let path = try!(to_utf16(&star.to_c_str()));
362362

src/librustc/back/write.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,10 +46,10 @@ pub enum OutputType {
4646
pub fn llvm_err(handler: &diagnostic::Handler, msg: String) -> ! {
4747
unsafe {
4848
let cstr = llvm::LLVMRustGetLastError();
49-
if cstr == ptr::null() {
49+
if cstr as *const i8 == ptr::null() {
5050
handler.fatal(msg.as_slice());
5151
} else {
52-
let err = CString::new(cstr, true);
52+
let err = CString::new_owned(cstr);
5353
let err = String::from_utf8_lossy(err.as_bytes());
5454
handler.fatal(format!("{}: {}",
5555
msg.as_slice(),
@@ -373,7 +373,7 @@ unsafe extern "C" fn diagnostic_handler(info: DiagnosticInfoRef, user: *mut c_vo
373373

374374
match llvm::diagnostic::Diagnostic::unpack(info) {
375375
llvm::diagnostic::Optimization(opt) => {
376-
let pass_name = CString::new(opt.pass_name, false);
376+
let pass_name = CString::new(opt.pass_name);
377377
let pass_name = pass_name.as_str().expect("got a non-UTF8 pass name from LLVM");
378378
let enabled = match cgcx.remark {
379379
AllPasses => true,

src/librustc/middle/trans/base.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2988,7 +2988,7 @@ fn internalize_symbols(cx: &SharedCrateContext, reachable: &HashSet<String>) {
29882988
continue
29892989
}
29902990

2991-
let name = CString::new(llvm::LLVMGetValueName(val), false);
2991+
let name = CString::new(llvm::LLVMGetValueName(val));
29922992
declared.insert(name);
29932993
}
29942994
}
@@ -3004,7 +3004,7 @@ fn internalize_symbols(cx: &SharedCrateContext, reachable: &HashSet<String>) {
30043004
continue
30053005
}
30063006

3007-
let name = CString::new(llvm::LLVMGetValueName(val), false);
3007+
let name = CString::new(llvm::LLVMGetValueName(val));
30083008
if !declared.contains(&name) &&
30093009
!reachable.contains_equiv(name.as_str().unwrap()) {
30103010
llvm::SetLinkage(val, llvm::InternalLinkage);

src/librustc_llvm/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1625,7 +1625,7 @@ extern {
16251625

16261626
/** Returns a string describing the last error caused by an LLVMRust*
16271627
call. */
1628-
pub fn LLVMRustGetLastError() -> *const c_char;
1628+
pub fn LLVMRustGetLastError() -> *mut c_char;
16291629

16301630
/// Print the pass timings since static dtors aren't picking them up.
16311631
pub fn LLVMRustPrintPassTimings();

src/librustrt/c_str.rs

Lines changed: 63 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -85,13 +85,17 @@ use core::slice;
8585
use core::str;
8686
use libc;
8787

88+
enum CStringInner {
89+
Owned(*mut libc::c_char),
90+
NotOwned(*const libc::c_char),
91+
}
92+
8893
/// The representation of a C String.
8994
///
9095
/// This structure wraps a `*libc::c_char`, and will automatically free the
9196
/// memory it is pointing to when it goes out of scope.
9297
pub struct CString {
93-
buf: *const libc::c_char,
94-
owns_buffer_: bool,
98+
inner: CStringInner,
9599
}
96100

97101
impl Clone for CString {
@@ -102,19 +106,19 @@ impl Clone for CString {
102106
let len = self.len() + 1;
103107
let buf = unsafe { libc::malloc(len as libc::size_t) } as *mut libc::c_char;
104108
if buf.is_null() { ::alloc::oom() }
105-
unsafe { ptr::copy_nonoverlapping_memory(buf, self.buf, len); }
106-
CString { buf: buf as *const libc::c_char, owns_buffer_: true }
109+
unsafe { ptr::copy_nonoverlapping_memory(buf, self.as_ptr(), len); }
110+
CString { inner: Owned(buf) }
107111
}
108112
}
109113

110114
impl PartialEq for CString {
111115
fn eq(&self, other: &CString) -> bool {
112116
// Check if the two strings share the same buffer
113-
if self.buf as uint == other.buf as uint {
117+
if self.as_ptr() as uint == other.as_ptr() as uint {
114118
true
115119
} else {
116120
unsafe {
117-
libc::strcmp(self.buf, other.buf) == 0
121+
libc::strcmp(self.as_ptr(), other.as_ptr()) == 0
118122
}
119123
}
120124
}
@@ -144,9 +148,20 @@ impl CString {
144148
///# Failure
145149
///
146150
/// Fails if `buf` is null
147-
pub unsafe fn new(buf: *const libc::c_char, owns_buffer: bool) -> CString {
151+
pub unsafe fn new(buf: *const libc::c_char) -> CString {
152+
assert!(!buf.is_null());
153+
CString { inner: NotOwned(buf) }
154+
}
155+
156+
/// Like CString::new except that `buf` will be freed when the value goes
157+
/// out of scope.
158+
///
159+
///# Failure
160+
///
161+
/// Fails if `buf` is null
162+
pub unsafe fn new_owned(buf: *mut libc::c_char) -> CString {
148163
assert!(!buf.is_null());
149-
CString { buf: buf, owns_buffer_: owns_buffer }
164+
CString { inner: Owned(buf) }
150165
}
151166

152167
/// Return a pointer to the NUL-terminated string data.
@@ -179,8 +194,12 @@ impl CString {
179194
/// }
180195
/// }
181196
/// ```
197+
#[inline]
182198
pub fn as_ptr(&self) -> *const libc::c_char {
183-
self.buf
199+
match self.inner {
200+
Owned(buf) => buf as *const libc::c_char,
201+
NotOwned(buf) => buf,
202+
}
184203
}
185204

186205
/// Return a mutable pointer to the NUL-terminated string data.
@@ -200,21 +219,28 @@ impl CString {
200219
/// // wrong (the CString will be freed, invalidating `p`)
201220
/// let p = foo.to_c_str().as_mut_ptr();
202221
/// ```
222+
#[inline]
203223
pub fn as_mut_ptr(&mut self) -> *mut libc::c_char {
204-
self.buf as *mut _
224+
match self.inner {
225+
Owned(buf) => buf,
226+
NotOwned(buf) => buf as *mut libc::c_char,
227+
}
205228
}
206229

207230
/// Returns whether or not the `CString` owns the buffer.
208231
pub fn owns_buffer(&self) -> bool {
209-
self.owns_buffer_
232+
match self.inner {
233+
Owned(_) => true,
234+
NotOwned(_) => false,
235+
}
210236
}
211237

212238
/// Converts the CString into a `&[u8]` without copying.
213239
/// Includes the terminating NUL byte.
214240
#[inline]
215241
pub fn as_bytes<'a>(&'a self) -> &'a [u8] {
216242
unsafe {
217-
mem::transmute(Slice { data: self.buf, len: self.len() + 1 })
243+
mem::transmute(Slice { data: self.as_ptr(), len: self.len() + 1 })
218244
}
219245
}
220246

@@ -223,7 +249,7 @@ impl CString {
223249
#[inline]
224250
pub fn as_bytes_no_nul<'a>(&'a self) -> &'a [u8] {
225251
unsafe {
226-
mem::transmute(Slice { data: self.buf, len: self.len() })
252+
mem::transmute(Slice { data: self.as_ptr(), len: self.len() })
227253
}
228254
}
229255

@@ -238,7 +264,7 @@ impl CString {
238264
/// Return a CString iterator.
239265
pub fn iter<'a>(&'a self) -> CChars<'a> {
240266
CChars {
241-
ptr: self.buf,
267+
ptr: self.as_ptr(),
242268
marker: marker::ContravariantLifetime,
243269
}
244270
}
@@ -255,8 +281,9 @@ impl CString {
255281
/// Prefer `.as_ptr()` when just retrieving a pointer to the
256282
/// string data, as that does not relinquish ownership.
257283
pub unsafe fn unwrap(mut self) -> *const libc::c_char {
258-
self.owns_buffer_ = false;
259-
self.buf
284+
let ret = self.as_ptr();
285+
self.inner = NotOwned(ret);
286+
ret
260287
}
261288

262289
/// Return the number of bytes in the CString (not including the NUL
@@ -273,14 +300,26 @@ impl CString {
273300

274301
impl Drop for CString {
275302
fn drop(&mut self) {
276-
if self.owns_buffer_ {
277-
unsafe {
278-
libc::free(self.buf as *mut libc::c_void)
279-
}
303+
match self.inner {
304+
Owned(buf) => unsafe {
305+
libc::free(buf as *mut libc::c_void)
306+
},
307+
_ => {},
280308
}
281309
}
282310
}
283311

312+
<<<<<<< HEAD
313+
=======
314+
impl Collection for CString {
315+
/// Return the number of bytes in the CString (not including the NUL terminator).
316+
#[inline]
317+
fn len(&self) -> uint {
318+
unsafe { libc::strlen(self.as_ptr()) as uint }
319+
}
320+
}
321+
322+
>>>>>>> Split CString::new into CString::new and CString::new_owned
284323
impl fmt::Show for CString {
285324
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
286325
String::from_utf8_lossy(self.as_bytes_no_nul()).fmt(f)
@@ -393,7 +432,7 @@ impl ToCStr for [u8] {
393432
ptr::copy_memory(buf, self.as_ptr(), self_len);
394433
*buf.offset(self_len as int) = 0;
395434

396-
CString::new(buf as *const libc::c_char, true)
435+
CString::new_owned(buf as *mut i8)
397436
}
398437

399438
fn with_c_str<T>(&self, f: |*const libc::c_char| -> T) -> T {
@@ -500,7 +539,7 @@ pub unsafe fn from_c_multistring(buf: *const libc::c_char,
500539
};
501540
while ((limited_count && ctr < limit) || !limited_count)
502541
&& *(curr_ptr as *const libc::c_char) != 0 as libc::c_char {
503-
let cstr = CString::new(curr_ptr as *const libc::c_char, false);
542+
let cstr = CString::new(curr_ptr as *const libc::c_char);
504543
f(&cstr);
505544
curr_ptr += cstr.len() + 1;
506545
ctr += 1;
@@ -665,7 +704,7 @@ mod tests {
665704
#[test]
666705
#[should_fail]
667706
fn test_new_fail() {
668-
let _c_str = unsafe { CString::new(ptr::null(), false) };
707+
let _c_str = unsafe { CString::new(ptr::null()) };
669708
}
670709

671710
#[test]
@@ -681,7 +720,7 @@ mod tests {
681720
let s = "test".to_string();
682721
let c = s.to_c_str();
683722
// give the closure a non-owned CString
684-
let mut c_ = unsafe { CString::new(c.as_ptr(), false) };
723+
let mut c_ = unsafe { CString::new(c.as_ptr()) };
685724
f(&c_);
686725
// muck with the buffer for later printing
687726
unsafe { *c_.as_mut_ptr() = 'X' as libc::c_char }

src/libstd/dynamic_lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -242,7 +242,7 @@ pub mod dl {
242242
let ret = if ptr::null() == last_error {
243243
Ok(result)
244244
} else {
245-
Err(String::from_str(CString::new(last_error, false).as_str()
245+
Err(String::from_str(CString::new(last_error).as_str()
246246
.unwrap()))
247247
};
248248

src/libstd/os.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ pub fn getcwd() -> Path {
100100
if libc::getcwd(buf.as_mut_ptr(), buf.len() as libc::size_t).is_null() {
101101
panic!()
102102
}
103-
Path::new(CString::new(buf.as_ptr(), false))
103+
Path::new(CString::new(buf.as_ptr()))
104104
}
105105
}
106106

@@ -288,7 +288,7 @@ pub fn env_as_bytes() -> Vec<(Vec<u8>,Vec<u8>)> {
288288
let mut result = Vec::new();
289289
while *environ != 0 as *const _ {
290290
let env_pair =
291-
CString::new(*environ, false).as_bytes_no_nul().to_vec();
291+
CString::new(*environ).as_bytes_no_nul().to_vec();
292292
result.push(env_pair);
293293
environ = environ.offset(1);
294294
}
@@ -355,7 +355,7 @@ pub fn getenv_as_bytes(n: &str) -> Option<Vec<u8>> {
355355
if s.is_null() {
356356
None
357357
} else {
358-
Some(CString::new(s as *const i8, false).as_bytes_no_nul().to_vec())
358+
Some(CString::new(s as *const i8).as_bytes_no_nul().to_vec())
359359
}
360360
})
361361
}
@@ -1103,7 +1103,7 @@ unsafe fn load_argc_and_argv(argc: int,
11031103
use c_str::CString;
11041104

11051105
Vec::from_fn(argc as uint, |i| {
1106-
CString::new(*argv.offset(i as int), false).as_bytes_no_nul().to_vec()
1106+
CString::new(*argv.offset(i as int)).as_bytes_no_nul().to_vec()
11071107
})
11081108
}
11091109

@@ -1170,7 +1170,7 @@ fn real_args_as_bytes() -> Vec<Vec<u8>> {
11701170
let tmp = objc_msgSend(args, objectAtSel, i);
11711171
let utf_c_str: *const libc::c_char =
11721172
mem::transmute(objc_msgSend(tmp, utf8Sel));
1173-
let s = CString::new(utf_c_str, false);
1173+
let s = CString::new(utf_c_str);
11741174
res.push(s.as_bytes_no_nul().to_vec())
11751175
}
11761176
}

src/libstd/rt/backtrace.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -382,7 +382,7 @@ mod imp {
382382
output(w, idx,addr, None)
383383
} else {
384384
output(w, idx, addr, Some(unsafe {
385-
CString::new(info.dli_sname, false)
385+
CString::new(info.dli_sname)
386386
}))
387387
}
388388
}
@@ -516,7 +516,7 @@ mod imp {
516516
if ret == 0 || data.is_null() {
517517
output(w, idx, addr, None)
518518
} else {
519-
output(w, idx, addr, Some(unsafe { CString::new(data, false) }))
519+
output(w, idx, addr, Some(unsafe { CString::new(data) }))
520520
}
521521
}
522522

@@ -990,7 +990,7 @@ mod imp {
990990

991991
if ret == libc::TRUE {
992992
try!(write!(w, " - "));
993-
let cstr = unsafe { CString::new(info.Name.as_ptr(), false) };
993+
let cstr = unsafe { CString::new(info.Name.as_ptr()) };
994994
let bytes = cstr.as_bytes();
995995
match cstr.as_str() {
996996
Some(s) => try!(super::demangle(w, s)),

src/test/run-pass/unix-process-spawn-errno.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ use rustrt::c_str;
2424
macro_rules! c_string {
2525
($s:expr) => { {
2626
let ptr = concat!($s, "\0").as_ptr() as *const i8;
27-
unsafe { &c_str::CString::new(ptr, false) }
27+
unsafe { &c_str::CString::new(ptr) }
2828
} }
2929
}
3030

0 commit comments

Comments
 (0)