about summary refs log tree commit diff
path: root/src/libstd
diff options
context:
space:
mode:
authorJeff Olson <olson.jeffery@gmail.com>2013-09-16 13:20:58 -0700
committerJeff Olson <olson.jeffery@gmail.com>2013-09-16 23:19:23 -0700
commit63182885d857fdf5641449a397ad7e3f4ebff8a7 (patch)
treeb0c7c1fe3b4d2bcde31a1834a7fce37eb72cf160 /src/libstd
parent71c7798d66953e9f53192d54985a6a46736f5ca5 (diff)
downloadrust-63182885d857fdf5641449a397ad7e3f4ebff8a7.tar.gz
rust-63182885d857fdf5641449a397ad7e3f4ebff8a7.zip
std: more work on from_c_multistring.. let it take an optional len param
Diffstat (limited to 'src/libstd')
-rw-r--r--src/libstd/os.rs2
-rw-r--r--src/libstd/str.rs22
2 files changed, 18 insertions, 6 deletions
diff --git a/src/libstd/os.rs b/src/libstd/os.rs
index af657274c67..d0a658a46a9 100644
--- a/src/libstd/os.rs
+++ b/src/libstd/os.rs
@@ -196,7 +196,7 @@ pub fn env() -> ~[(~str,~str)] {
             if (ch as uint == 0) {
                 fail!("os::env() failure getting env string from OS: %s", os::last_os_error());
             }
-            result = unsafe { str::raw::from_c_multistring(ch as *libc::c_char) };
+            result = unsafe { str::raw::from_c_multistring(ch as *libc::c_char, None) };
             FreeEnvironmentStringsA(ch);
             result
         }
diff --git a/src/libstd/str.rs b/src/libstd/str.rs
index 84df2d2005d..7cbc88ed204 100644
--- a/src/libstd/str.rs
+++ b/src/libstd/str.rs
@@ -22,6 +22,7 @@ use char;
 use char::Char;
 use clone::{Clone, DeepClone};
 use container::{Container, Mutable};
+use num::Times;
 use iter::{Iterator, FromIterator, Extendable, range};
 use iter::{Filter, AdditiveIterator, Map};
 use iter::{Invert, DoubleEndedIterator, ExactSize};
@@ -938,6 +939,7 @@ static TAG_CONT_U8: u8 = 128u8;
 
 /// Unsafe operations
 pub mod raw {
+    use option::{Option, Some};
     use cast;
     use libc;
     use ptr;
@@ -1092,20 +1094,29 @@ pub mod raw {
     }
 
     /// Parses a C "multistring", eg windows env values or
-    /// the req->ptr result in a uv_fs_readdir() call
+    /// the req->ptr result in a uv_fs_readdir() call.
+    /// Optionally, a `count` can be passed in, limiting the
+    /// parsing to only being done `count`-times.
     #[inline]
-    pub unsafe fn from_c_multistring(c: *libc::c_char) -> ~[~str] {
+    pub unsafe fn from_c_multistring(buf: *libc::c_char, count: Option<uint>) -> ~[~str] {
         #[fixed_stack_segment]; #[inline(never)];
 
-        let mut curr_ptr: uint = c as uint;
+        let mut curr_ptr: uint = buf as uint;
         let mut result = ~[];
-        while(*(curr_ptr as *libc::c_char) != 0 as libc::c_char) {
+        let mut ctr = 0;
+        let (limited_count, limit) = match count {
+            Some(limit) => (true, limit),
+            None => (false, 0)
+        };
+        while(*(curr_ptr as *libc::c_char) != 0 as libc::c_char
+             && ((limited_count && ctr < limit) || !limited_count)) {
             let env_pair = from_c_str(
                 curr_ptr as *libc::c_char);
             result.push(env_pair);
             curr_ptr +=
                 libc::strlen(curr_ptr as *libc::c_char) as uint
                 + 1;
+            ctr += 1;
         }
         result
     }
@@ -1127,10 +1138,11 @@ pub mod raw {
 
     #[test]
     fn test_str_multistring_parsing() {
+        use option::None;
         unsafe {
             let input = bytes!("zero", "\x00", "one", "\x00", "\x00");
             let ptr = vec::raw::to_ptr(input);
-            let mut result = from_c_multistring(ptr as *libc::c_char);
+            let mut result = from_c_multistring(ptr as *libc::c_char, None);
             assert!(result.len() == 2);
             let mut ctr = 0;
             for x in result.iter() {