Skip to content

Commit f1107cc

Browse files
olsonjefferybrson
authored andcommitted
---
yaml --- r: 48637 b: refs/heads/snap-stage3 c: 53db6c7 h: refs/heads/master i: 48635: 9c41528 v: v3
1 parent 859147d commit f1107cc

File tree

5 files changed

+197
-41
lines changed

5 files changed

+197
-41
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
refs/heads/master: 3bbcac322669cff3abde5be937cc4ec3860f3985
33
refs/heads/snap-stage1: e33de59e47c5076a89eadeb38f4934f58a3618a6
4-
refs/heads/snap-stage3: 4bc26ce575b4bc6f7254a2cfe9fee0a08de90b49
4+
refs/heads/snap-stage3: 53db6c7e2a11764a806e87c7268d31288fa9171d
55
refs/heads/try: 2a8fb58d79e685d5ca07b039badcf2ae3ef077ea
66
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105
77
refs/heads/ndm: f3868061cd7988080c30d6d5bf352a5a5fe2460b

branches/snap-stage3/src/libcore/libc.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -534,6 +534,7 @@ pub mod types {
534534

535535
pub type LPCWSTR = *WCHAR;
536536
pub type LPCSTR = *CHAR;
537+
pub type LPTCH = *CHAR;
537538

538539
pub type LPWSTR = *mut WCHAR;
539540
pub type LPSTR = *mut CHAR;
@@ -1594,7 +1595,7 @@ pub mod funcs {
15941595

15951596
pub mod kernel32 {
15961597
use libc::types::os::arch::extra::{BOOL, DWORD, HMODULE};
1597-
use libc::types::os::arch::extra::{LPCWSTR, LPWSTR};
1598+
use libc::types::os::arch::extra::{LPCWSTR, LPWSTR, LPTCH};
15981599
use libc::types::os::arch::extra::{LPSECURITY_ATTRIBUTES};
15991600

16001601
#[abi = "stdcall"]
@@ -1605,6 +1606,8 @@ pub mod funcs {
16051606
-> DWORD;
16061607
unsafe fn SetEnvironmentVariableW(n: LPCWSTR, v: LPCWSTR)
16071608
-> BOOL;
1609+
unsafe fn GetEnvironmentStringsA() -> LPTCH;
1610+
unsafe fn FreeEnvironmentStringsA(env_ptr: LPTCH) -> BOOL;
16081611

16091612
unsafe fn GetModuleFileNameW(hModule: HMODULE,
16101613
lpFilename: LPWSTR,

branches/snap-stage3/src/libcore/os.rs

Lines changed: 56 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -171,20 +171,68 @@ fn with_env_lock<T>(f: &fn() -> T) -> T {
171171
}
172172

173173
pub fn env() -> ~[(~str,~str)] {
174-
extern {
175-
unsafe fn rust_env_pairs() -> ~[~str];
176-
}
177-
178174
unsafe {
179-
do with_env_lock {
175+
#[cfg(windows)]
176+
unsafe fn get_env_pairs() -> ~[~str] {
177+
use libc::types::os::arch::extra::LPTCH;
178+
use libc::funcs::extra::kernel32::{
179+
GetEnvironmentStringsA,
180+
FreeEnvironmentStringsA
181+
};
182+
let ch = GetEnvironmentStringsA();
183+
if (ch as uint == 0) {
184+
fail!(fmt!("os::env() failure getting env string from OS: %s",
185+
os::last_os_error()));
186+
}
187+
let mut curr_ptr: uint = ch as uint;
188+
let mut result = ~[];
189+
while(*(curr_ptr as *libc::c_char) != 0 as libc::c_char) {
190+
let env_pair = str::raw::from_c_str(
191+
curr_ptr as *libc::c_char);
192+
result.push(env_pair);
193+
curr_ptr +=
194+
libc::strlen(curr_ptr as *libc::c_char) as uint
195+
+ 1;
196+
}
197+
FreeEnvironmentStringsA(ch);
198+
result
199+
}
200+
#[cfg(unix)]
201+
unsafe fn get_env_pairs() -> ~[~str] {
202+
extern mod rustrt {
203+
unsafe fn rust_env_pairs() -> **libc::c_char;
204+
}
205+
let environ = rustrt::rust_env_pairs();
206+
if (environ as uint == 0) {
207+
fail!(fmt!("os::env() failure getting env string from OS: %s",
208+
os::last_os_error()));
209+
}
210+
let mut result = ~[];
211+
ptr::array_each(environ, |e| {
212+
let env_pair = str::raw::from_c_str(e);
213+
log(debug, fmt!("get_env_pairs: %s",
214+
env_pair));
215+
result.push(env_pair);
216+
});
217+
result
218+
}
219+
220+
fn env_convert(input: ~[~str]) -> ~[(~str, ~str)] {
180221
let mut pairs = ~[];
181-
for vec::each(rust_env_pairs()) |p| {
182-
let vs = str::splitn_char(*p, '=', 1u);
183-
fail_unless!(vec::len(vs) == 2u);
222+
for input.each |p| {
223+
let vs = str::splitn_char(*p, '=', 1);
224+
log(debug,
225+
fmt!("splitting: len: %u",
226+
vs.len()));
227+
assert vs.len() == 2;
184228
pairs.push((copy vs[0], copy vs[1]));
185229
}
186230
pairs
187231
}
232+
do with_env_lock {
233+
let unparsed_environ = get_env_pairs();
234+
env_convert(unparsed_environ)
235+
}
188236
}
189237
}
190238

branches/snap-stage3/src/libcore/ptr.rs

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ use sys;
1818

1919
#[cfg(test)] use vec;
2020
#[cfg(test)] use str;
21+
#[cfg(test)] use uint;
22+
#[cfg(test)] use debug;
2123
#[cfg(notest)] use cmp::{Eq, Ord};
2224

2325
pub mod libc_ {
@@ -181,6 +183,46 @@ pub pure fn ref_eq<T>(thing: &a/T, other: &b/T) -> bool {
181183
to_uint(thing) == to_uint(other)
182184
}
183185

186+
/**
187+
Given a **T (pointer to an array of pointers),
188+
iterate through each *T, up to the provided `len`,
189+
passing to the provided callback function
190+
191+
SAFETY NOTE: Pointer-arithmetic. Dragons be here.
192+
*/
193+
pub unsafe fn array_each_with_len<T>(arr: **T, len: uint, cb: fn(*T)) {
194+
log(debug, "array_each_with_len: before iterate");
195+
if (arr as uint == 0) {
196+
fail!(~"ptr::array_each_with_len failure: arr input is null pointer");
197+
}
198+
//let start_ptr = *arr;
199+
uint::iterate(0, len, |e| {
200+
let n = offset(arr, e);
201+
cb(*n);
202+
true
203+
});
204+
log(debug, "array_each_with_len: after iterate");
205+
}
206+
207+
/**
208+
Given a null-pointer-terminated **T (pointer to
209+
an array of pointers), iterate through each *T,
210+
passing to the provided callback function
211+
212+
SAFETY NOTE: This will only work with a null-terminated
213+
pointer array. Barely less-dodgey Pointer Arithmetic.
214+
Dragons be here.
215+
*/
216+
pub unsafe fn array_each<T>(arr: **T, cb: fn(*T)) {
217+
if (arr as uint == 0) {
218+
fail!(~"ptr::array_each_with_len failure: arr input is null pointer");
219+
}
220+
let len = buf_len(arr);
221+
log(debug, fmt!("array_each inferred len: %u",
222+
len));
223+
array_each_with_len(arr, len, cb);
224+
}
225+
184226
pub trait Ptr<T> {
185227
pure fn is_null(&self) -> bool;
186228
pure fn is_not_null(&self) -> bool;
@@ -389,3 +431,93 @@ pub fn test_is_null() {
389431
fail_unless!(!mq.is_null());
390432
fail_unless!(mq.is_not_null());
391433
}
434+
435+
#[cfg(test)]
436+
pub mod ptr_tests {
437+
use debug;
438+
use ptr;
439+
use str;
440+
use libc;
441+
use vec;
442+
#[test]
443+
pub fn test_ptr_array_each_with_len() {
444+
unsafe {
445+
let one = ~"oneOne";
446+
let two = ~"twoTwo";
447+
let three = ~"threeThree";
448+
let arr: ~[*i8] = ~[
449+
::cast::transmute(&one[0]),
450+
::cast::transmute(&two[0]),
451+
::cast::transmute(&three[0]),
452+
];
453+
let expected_arr = [
454+
one, two, three
455+
];
456+
let arr_ptr = &arr[0];
457+
let mut ctr = 0;
458+
let mut iteration_count = 0;
459+
ptr::array_each_with_len(arr_ptr, vec::len(arr),
460+
|e| {
461+
let actual = str::raw::from_c_str(e);
462+
let expected = copy expected_arr[ctr];
463+
log(debug,
464+
fmt!("test_ptr_array_each e: %s, a: %s",
465+
expected, actual));
466+
assert actual == expected;
467+
ctr += 1;
468+
iteration_count += 1;
469+
});
470+
assert iteration_count == 3u;
471+
}
472+
}
473+
#[test]
474+
pub fn test_ptr_array_each() {
475+
unsafe {
476+
let one = ~"oneOne";
477+
let two = ~"twoTwo";
478+
let three = ~"threeThree";
479+
let arr: ~[*i8] = ~[
480+
::cast::transmute(&one[0]),
481+
::cast::transmute(&two[0]),
482+
::cast::transmute(&three[0]),
483+
// fake a null terminator
484+
0 as *i8
485+
];
486+
let expected_arr = [
487+
one, two, three
488+
];
489+
let arr_ptr = &arr[0];
490+
let mut ctr = 0;
491+
let mut iteration_count = 0;
492+
ptr::array_each(arr_ptr, |e| {
493+
let actual = str::raw::from_c_str(e);
494+
let expected = copy expected_arr[ctr];
495+
log(debug,
496+
fmt!("test_ptr_array_each e: %s, a: %s",
497+
expected, actual));
498+
assert actual == expected;
499+
ctr += 1;
500+
iteration_count += 1;
501+
});
502+
assert iteration_count == 3;
503+
}
504+
}
505+
#[test]
506+
#[should_fail]
507+
pub fn test_ptr_array_each_with_len_null_ptr() {
508+
unsafe {
509+
ptr::array_each_with_len(0 as **libc::c_char, 1, |e| {
510+
str::raw::from_c_str(e);
511+
});
512+
}
513+
}
514+
#[test]
515+
#[should_fail]
516+
pub fn test_ptr_array_each_null_ptr() {
517+
unsafe {
518+
ptr::array_each(0 as **libc::c_char, |e| {
519+
str::raw::from_c_str(e);
520+
});
521+
}
522+
}
523+
}

branches/snap-stage3/src/rt/rust_builtin.cpp

Lines changed: 4 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -53,44 +53,17 @@ timegm(struct tm *tm)
5353
#endif
5454

5555
#if defined(__WIN32__)
56-
extern "C" CDECL rust_vec_box *
56+
extern "C" CDECL char**
5757
rust_env_pairs() {
58-
rust_task *task = rust_get_current_task();
59-
size_t envc = 0;
60-
LPTCH ch = GetEnvironmentStringsA();
61-
LPTCH c;
62-
for (c = ch; *c; c += strlen(c) + 1) {
63-
++envc;
64-
}
65-
c = ch;
66-
rust_vec_box *v = (rust_vec_box *)
67-
task->kernel->malloc(vec_size<rust_vec_box*>(envc),
68-
"str vec interior");
69-
v->body.fill = v->body.alloc = sizeof(rust_vec*) * envc;
70-
for (size_t i = 0; i < envc; ++i) {
71-
size_t n = strlen(c);
72-
rust_str *str = make_str(task->kernel, c, n, "str");
73-
((rust_str**)&v->body.data)[i] = str;
74-
c += n + 1;
75-
}
76-
if (ch) {
77-
FreeEnvironmentStrings(ch);
78-
}
79-
return v;
58+
return 0;
8059
}
8160
#else
82-
extern "C" CDECL rust_vec_box *
61+
extern "C" CDECL char**
8362
rust_env_pairs() {
84-
rust_task *task = rust_get_current_task();
8563
#ifdef __APPLE__
8664
char **environ = *_NSGetEnviron();
8765
#endif
88-
char **e = environ;
89-
size_t envc = 0;
90-
while (*e) {
91-
++envc; ++e;
92-
}
93-
return make_str_vec(task->kernel, envc, environ);
66+
return environ;
9467
}
9568
#endif
9669

0 commit comments

Comments
 (0)