about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustc/middle/trans/base.rs60
-rw-r--r--src/libstd/rt/crate_map.rs352
-rw-r--r--src/libstd/rt/logging.rs155
3 files changed, 343 insertions, 224 deletions
diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs
index 2c0497283c1..16ac802ee15 100644
--- a/src/librustc/middle/trans/base.rs
+++ b/src/librustc/middle/trans/base.rs
@@ -54,7 +54,7 @@ use middle::trans::glue;
 use middle::trans::inline;
 use middle::trans::llrepr::LlvmRepr;
 use middle::trans::machine;
-use middle::trans::machine::{llalign_of_min, llsize_of};
+use middle::trans::machine::{llalign_of_min, llsize_of, llsize_of_alloc};
 use middle::trans::meth;
 use middle::trans::monomorphize;
 use middle::trans::tvec;
@@ -2911,9 +2911,10 @@ pub fn decl_gc_metadata(ccx: &mut CrateContext, llmod_id: &str) {
     }
 }
 
-pub fn create_module_map(ccx: &mut CrateContext) -> ValueRef {
-    let elttype = Type::struct_([ccx.int_type, ccx.int_type], false);
-    let maptype = Type::array(&elttype, (ccx.module_data.len() + 1) as u64);
+pub fn create_module_map(ccx: &mut CrateContext) -> (ValueRef, uint, uint) {
+    let str_slice_type = Type::struct_([Type::i8p(), ccx.int_type], false);
+    let elttype = Type::struct_([str_slice_type, ccx.int_type], false);
+    let maptype = Type::array(&elttype, ccx.module_data.len() as u64);
     let map = do "_rust_mod_map".with_c_str |buf| {
         unsafe {
             llvm::LLVMAddGlobal(ccx.llmod, maptype.to_ref(), buf)
@@ -2931,19 +2932,18 @@ pub fn create_module_map(ccx: &mut CrateContext) -> ValueRef {
     }
 
     for key in keys.iter() {
-        let val = *ccx.module_data.find_equiv(key).unwrap();
-        let s_const = C_cstr(ccx, *key);
-        let s_ptr = p2i(ccx, s_const);
-        let v_ptr = p2i(ccx, val);
-        let elt = C_struct([s_ptr, v_ptr]);
-        elts.push(elt);
-    }
-    let term = C_struct([C_int(ccx, 0), C_int(ccx, 0)]);
-    elts.push(term);
+            let val = *ccx.module_data.find_equiv(key).unwrap();
+            let v_ptr = p2i(ccx, val);
+            let elt = C_struct([
+                C_estr_slice(ccx, *key),
+                v_ptr
+            ]);
+            elts.push(elt);
+    }
     unsafe {
         llvm::LLVMSetInitializer(map, C_array(elttype, elts));
     }
-    return map;
+    return (map, keys.len(), llsize_of_alloc(ccx, elttype));
 }
 
 
@@ -2959,9 +2959,10 @@ pub fn decl_crate_map(sess: session::Session, mapmeta: LinkMeta,
     } else {
         ~"toplevel"
     };
+
     let sym_name = ~"_rust_crate_map_" + mapname;
-    let arrtype = Type::array(&int_type, n_subcrates as u64);
-    let maptype = Type::struct_([Type::i32(), int_type, arrtype], false);
+    let slicetype = Type::struct_([int_type, int_type], false);
+    let maptype = Type::struct_([Type::i32(), slicetype, slicetype], false);
     let map = do sym_name.with_c_str |buf| {
         unsafe {
             llvm::LLVMAddGlobal(llmod, maptype.to_ref(), buf)
@@ -2996,14 +2997,29 @@ pub fn fill_crate_map(ccx: &mut CrateContext, map: ValueRef) {
         subcrates.push(p2i(ccx, cr));
         i += 1;
     }
-    subcrates.push(C_int(ccx, 0));
-
     unsafe {
-        let mod_map = create_module_map(ccx);
+        let maptype = Type::array(&ccx.int_type, subcrates.len() as u64);
+        let vec_elements = do "_crate_map_child_vectors".with_c_str |buf| {
+            llvm::LLVMAddGlobal(ccx.llmod, maptype.to_ref(), buf)
+        };
+        lib::llvm::SetLinkage(vec_elements, lib::llvm::InternalLinkage);
+
+        llvm::LLVMSetInitializer(vec_elements, C_array(ccx.int_type, subcrates));
+        let (mod_map, mod_count, mod_struct_size) = create_module_map(ccx);
+
         llvm::LLVMSetInitializer(map, C_struct(
-            [C_i32(1),
-             p2i(ccx, mod_map),
-             C_array(ccx.int_type, subcrates)]));
+            [C_i32(2),
+             C_struct([
+                p2i(ccx, mod_map),
+                // byte size of the module map array, an entry consists of two integers
+                C_int(ccx, ((mod_count * mod_struct_size) as int))
+             ]),
+             C_struct([
+                p2i(ccx, vec_elements),
+                // byte size of the subcrates array, an entry consists of an integer
+                C_int(ccx, (subcrates.len() * llsize_of_alloc(ccx, ccx.int_type)) as int)
+             ])
+        ]));
     }
 }
 
diff --git a/src/libstd/rt/crate_map.rs b/src/libstd/rt/crate_map.rs
index 2844cc81892..061c2e53c7c 100644
--- a/src/libstd/rt/crate_map.rs
+++ b/src/libstd/rt/crate_map.rs
@@ -8,13 +8,17 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use container::MutableSet;
+use hashmap::HashSet;
+use option::{Some, None, Option};
+use vec::ImmutableVector;
 
+/// Imports for old crate map versions
+use cast::transmute;
 use libc::c_char;
 use ptr;
-use ptr::RawPtr;
+use str::raw::from_c_str;
 use vec;
-use hashmap::HashSet;
-use container::MutableSet;
 
 // Need to tell the linker on OS X to not barf on undefined symbols
 // and instead look them up at runtime, which we need to resolve
@@ -27,35 +31,52 @@ extern {}
 extern {
     #[weak_linkage]
     #[link_name = "_rust_crate_map_toplevel"]
-    static CRATE_MAP: CrateMap;
+    static CRATE_MAP: CrateMap<'static>;
 }
 
-pub struct ModEntry {
+/// structs for old crate map versions
+pub struct ModEntryV0 {
     name: *c_char,
     log_level: *mut u32
 }
-struct CrateMapV0 {
-    entries: *ModEntry,
-    children: [*CrateMap, ..1]
+pub struct CrateMapV0 {
+    entries: *ModEntryV0,
+    children: [*CrateMapV0, ..1]
 }
 
-struct CrateMap {
+pub struct CrateMapV1 {
     version: i32,
-    entries: *ModEntry,
+    entries: *ModEntryV0,
     /// a dynamically sized struct, where all pointers to children are listed adjacent
     /// to the struct, terminated with NULL
-    children: [*CrateMap, ..1]
+    children: [*CrateMapV1, ..1]
+}
+
+pub struct ModEntry<'self> {
+    name: &'self str,
+    log_level: *mut u32
+}
+
+pub struct CrateMap<'self> {
+    version: i32,
+    entries: &'self [ModEntry<'self>],
+    children: &'self [&'self CrateMap<'self>]
 }
 
 #[cfg(not(windows))]
-pub fn get_crate_map() -> *CrateMap {
-    &'static CRATE_MAP as *CrateMap
+pub fn get_crate_map() -> Option<&'static CrateMap<'static>> {
+    let ptr: (*CrateMap) = &'static CRATE_MAP;
+    if ptr.is_null() {
+        return None;
+    } else {
+        return Some(&'static CRATE_MAP);
+    }
 }
 
 #[cfg(windows)]
 #[fixed_stack_segment]
 #[inline(never)]
-pub fn get_crate_map() -> *CrateMap {
+pub fn get_crate_map() -> Option<&'static CrateMap<'static>> {
     use c_str::ToCStr;
     use unstable::dynamic_lib::dl;
 
@@ -67,157 +88,254 @@ pub fn get_crate_map() -> *CrateMap {
         dl::close(module);
         sym
     };
-
-    sym as *CrateMap
+    let ptr: (*CrateMap) = sym as *CrateMap;
+    if ptr.is_null() {
+        return None;
+    } else {
+        unsafe {
+            return Some(transmute(sym));
+        }
+    }
 }
 
-unsafe fn version(crate_map: *CrateMap) -> i32 {
-    match (*crate_map).version {
+fn version(crate_map: &CrateMap) -> i32 {
+    match crate_map.version {
+        2 => return 2,
         1 => return 1,
         _ => return 0
     }
 }
 
-unsafe fn entries(crate_map: *CrateMap) -> *ModEntry {
-    match version(crate_map) {
-        0 => {
-            let v0 = crate_map as (*CrateMapV0);
-            return (*v0).entries;
-        }
-        1 => return (*crate_map).entries,
-        _ => fail2!("Unknown crate map version!")
-    }
-}
-
-unsafe fn iterator(crate_map: *CrateMap) -> **CrateMap {
-    match version(crate_map) {
-        0 => {
-            let v0 = crate_map as (*CrateMapV0);
-            return vec::raw::to_ptr((*v0).children);
-        }
-        1 => return vec::raw::to_ptr((*crate_map).children),
-        _ => fail2!("Unknown crate map version!")
+fn iter_module_map(mod_entries: &[ModEntry], f: &fn(&ModEntry)) {
+    for entry in mod_entries.iter() {
+        f(entry);
     }
 }
 
-unsafe fn iter_module_map(mod_entries: *ModEntry, f: &fn(*mut ModEntry)) {
-    let mut curr = mod_entries;
-
+unsafe fn iter_module_map_v0(entries: *ModEntryV0, f: &fn(&ModEntry)) {
+    let mut curr = entries;
     while !(*curr).name.is_null() {
-        f(curr as *mut ModEntry);
+        let mod_entry = ModEntry { name: from_c_str((*curr).name), log_level: (*curr).log_level };
+        f(&mod_entry);
         curr = curr.offset(1);
     }
 }
 
-unsafe fn do_iter_crate_map(crate_map: *CrateMap, f: &fn(*mut ModEntry),
-                            visited: &mut HashSet<*CrateMap>) {
-    if visited.insert(crate_map) {
-        iter_module_map(entries(crate_map), |x| f(x));
-        let child_crates = iterator(crate_map);
-        do ptr::array_each(child_crates) |child| {
-            do_iter_crate_map(child, |x| f(x), visited);
+fn do_iter_crate_map<'a>(crate_map: &'a CrateMap<'a>, f: &fn(&ModEntry),
+                            visited: &mut HashSet<*CrateMap<'a>>) {
+    if visited.insert(crate_map as *CrateMap) {
+        match version(crate_map) {
+            2 => {
+                let (entries, children) = (crate_map.entries, crate_map.children);
+                iter_module_map(entries, |x| f(x));
+                for child in children.iter() {
+                    do_iter_crate_map(*child, |x| f(x), visited);
+                }
+            },
+            // code for old crate map versions
+            1 => unsafe {
+                let v1: *CrateMapV1 = transmute(crate_map);
+                iter_module_map_v0((*v1).entries, |x| f(x));
+                let children = vec::raw::to_ptr((*v1).children);
+                do ptr::array_each(children) |child| {
+                    do_iter_crate_map(transmute(child), |x| f(x), visited);
+                }
+            },
+            0 => unsafe {
+                let v0: *CrateMapV0 = transmute(crate_map);
+                iter_module_map_v0((*v0).entries, |x| f(x));
+                let children = vec::raw::to_ptr((*v0).children);
+                do ptr::array_each(children) |child| {
+                    do_iter_crate_map(transmute(child), |x| f(x), visited);
+                }
+            },
+            _ => fail2!("invalid crate map version")
         }
     }
 }
 
 /// Iterates recursively over `crate_map` and all child crate maps
-pub unsafe fn iter_crate_map(crate_map: *CrateMap, f: &fn(*mut ModEntry)) {
+pub fn iter_crate_map<'a>(crate_map: &'a CrateMap<'a>, f: &fn(&ModEntry)) {
     // XXX: use random numbers as keys from the OS-level RNG when there is a nice
     //        way to do this
-    let mut v: HashSet<*CrateMap> = HashSet::with_capacity_and_keys(0, 0, 32);
+    let mut v: HashSet<*CrateMap<'a>> = HashSet::with_capacity_and_keys(0, 0, 32);
     do_iter_crate_map(crate_map, f, &mut v);
 }
 
-#[test]
-fn iter_crate_map_duplicates() {
-    use c_str::ToCStr;
-    use cast::transmute;
-
-    struct CrateMapT3 {
-        version: i32,
-        entries: *ModEntry,
-        children: [*CrateMap, ..3]
-    }
+#[cfg(test)]
+mod tests {
+    use rt::crate_map::{CrateMap, ModEntry, iter_crate_map};
 
-    unsafe {
-        let mod_name1 = "c::m1".to_c_str();
+    #[test]
+    fn iter_crate_map_duplicates() {
         let mut level3: u32 = 3;
 
-        let entries: ~[ModEntry] = ~[
-            ModEntry { name: mod_name1.with_ref(|buf| buf), log_level: &mut level3},
-            ModEntry { name: ptr::null(), log_level: ptr::mut_null()}
+        let entries = [
+            ModEntry { name: "c::m1", log_level: &mut level3},
         ];
+
         let child_crate = CrateMap {
-            version: 1,
-            entries: vec::raw::to_ptr(entries),
-            children: [ptr::null()]
+            version: 2,
+            entries: entries,
+            children: []
         };
 
-        let root_crate = CrateMapT3 {
-            version: 1,
-            entries: vec::raw::to_ptr([ModEntry { name: ptr::null(), log_level: ptr::mut_null()}]),
-            children: [&child_crate as *CrateMap, &child_crate as *CrateMap, ptr::null()]
+        let root_crate = CrateMap {
+            version: 2,
+            entries: [],
+            children: [&child_crate, &child_crate]
         };
 
         let mut cnt = 0;
-        do iter_crate_map(transmute(&root_crate)) |entry| {
-            assert!(*(*entry).log_level == 3);
-            cnt += 1;
+        unsafe {
+            do iter_crate_map(&root_crate) |entry| {
+                assert!(*entry.log_level == 3);
+                cnt += 1;
+            }
+            assert!(cnt == 1);
         }
-        assert!(cnt == 1);
     }
-}
-
-#[test]
-fn iter_crate_map_follow_children() {
-    use c_str::ToCStr;
-    use cast::transmute;
 
-    struct CrateMapT2 {
-        version: i32,
-        entries: *ModEntry,
-        children: [*CrateMap, ..2]
-    }
-
-    unsafe {
-        let mod_name1 = "c::m1".to_c_str();
-        let mod_name2 = "c::m2".to_c_str();
+    #[test]
+    fn iter_crate_map_follow_children() {
         let mut level2: u32 = 2;
         let mut level3: u32 = 3;
         let child_crate2 = CrateMap {
-            version: 1,
-            entries: vec::raw::to_ptr([
-                ModEntry { name: mod_name1.with_ref(|buf| buf), log_level: &mut level2},
-                ModEntry { name: mod_name2.with_ref(|buf| buf), log_level: &mut level3},
-                ModEntry { name: ptr::null(), log_level: ptr::mut_null()}
-            ]),
-            children: [ptr::null()]
+            version: 2,
+            entries: [
+                ModEntry { name: "c::m1", log_level: &mut level2},
+                ModEntry { name: "c::m2", log_level: &mut level3},
+            ],
+            children: []
         };
 
-        let child_crate1 = CrateMapT2 {
-            version: 1,
-            entries: vec::raw::to_ptr([
-                ModEntry { name: "t::f1".with_c_str(|buf| buf), log_level: &mut 1},
-                ModEntry { name: ptr::null(), log_level: ptr::mut_null()}
-            ]),
-            children: [&child_crate2 as *CrateMap, ptr::null()]
+        let child_crate1 = CrateMap {
+            version: 2,
+            entries: [
+                ModEntry { name: "t::f1", log_level: &mut 1},
+            ],
+            children: [&child_crate2]
         };
 
-        let child_crate1_ptr: *CrateMap = transmute(&child_crate1);
-        let root_crate = CrateMapT2 {
-            version: 1,
-            entries: vec::raw::to_ptr([
-                ModEntry { name: "t::f1".with_c_str(|buf| buf), log_level: &mut 0},
-                ModEntry { name: ptr::null(), log_level: ptr::mut_null()}
-            ]),
-            children: [child_crate1_ptr, ptr::null()]
+        let root_crate = CrateMap {
+            version: 2,
+            entries: [
+                ModEntry { name: "t::f2", log_level: &mut 0},
+            ],
+            children: [&child_crate1]
         };
 
         let mut cnt = 0;
-        do iter_crate_map(transmute(&root_crate)) |entry| {
-            assert!(*(*entry).log_level == cnt);
-            cnt += 1;
+        unsafe {
+            do iter_crate_map(&root_crate) |entry| {
+                assert!(*entry.log_level == cnt);
+                cnt += 1;
+            }
+            assert!(cnt == 4);
+        }
+    }
+
+
+    /// Tests for old crate map versions
+    #[test]
+    fn iter_crate_map_duplicates_v1() {
+        use c_str::ToCStr;
+        use cast::transmute;
+        use ptr;
+        use rt::crate_map::{CrateMapV1, ModEntryV0, iter_crate_map};
+        use vec;
+
+        struct CrateMapT3 {
+            version: i32,
+            entries: *ModEntryV0,
+            children: [*CrateMapV1, ..3]
+        }
+
+        unsafe {
+            let mod_name1 = "c::m1".to_c_str();
+            let mut level3: u32 = 3;
+
+            let entries: ~[ModEntryV0] = ~[
+                ModEntryV0 { name: mod_name1.with_ref(|buf| buf), log_level: &mut level3},
+                ModEntryV0 { name: ptr::null(), log_level: ptr::mut_null()}
+            ];
+            let child_crate = CrateMapV1 {
+                version: 1,
+                entries: vec::raw::to_ptr(entries),
+                children: [ptr::null()]
+            };
+
+            let root_crate = CrateMapT3 {
+                version: 1,
+                entries: vec::raw::to_ptr([
+                    ModEntryV0 { name: ptr::null(), log_level: ptr::mut_null()}
+                ]),
+                children: [&child_crate as *CrateMapV1, &child_crate as *CrateMapV1, ptr::null()]
+            };
+
+            let mut cnt = 0;
+            do iter_crate_map(transmute(&root_crate)) |entry| {
+                assert!(*(*entry).log_level == 3);
+                cnt += 1;
+            }
+            assert!(cnt == 1);
+        }
+    }
+
+    #[test]
+    fn iter_crate_map_follow_children_v1() {
+        use c_str::ToCStr;
+        use cast::transmute;
+        use ptr;
+        use rt::crate_map::{CrateMapV1, ModEntryV0, iter_crate_map};
+        use vec;
+
+        struct CrateMapT2 {
+            version: i32,
+            entries: *ModEntryV0,
+            children: [*CrateMapV1, ..2]
+        }
+
+        unsafe {
+            let mod_name1 = "c::m1".to_c_str();
+            let mod_name2 = "c::m2".to_c_str();
+            let mut level2: u32 = 2;
+            let mut level3: u32 = 3;
+            let child_crate2 = CrateMapV1 {
+                version: 1,
+                entries: vec::raw::to_ptr([
+                    ModEntryV0 { name: mod_name1.with_ref(|buf| buf), log_level: &mut level2},
+                    ModEntryV0 { name: mod_name2.with_ref(|buf| buf), log_level: &mut level3},
+                    ModEntryV0 { name: ptr::null(), log_level: ptr::mut_null()}
+                ]),
+                children: [ptr::null()]
+            };
+
+            let child_crate1 = CrateMapT2 {
+                version: 1,
+                entries: vec::raw::to_ptr([
+                    ModEntryV0 { name: "t::f1".with_c_str(|buf| buf), log_level: &mut 1},
+                    ModEntryV0 { name: ptr::null(), log_level: ptr::mut_null()}
+                ]),
+                children: [&child_crate2 as *CrateMapV1, ptr::null()]
+            };
+
+            let child_crate1_ptr: *CrateMapV1 = transmute(&child_crate1);
+            let root_crate = CrateMapT2 {
+                version: 1,
+                entries: vec::raw::to_ptr([
+                    ModEntryV0 { name: "t::f1".with_c_str(|buf| buf), log_level: &mut 0},
+                    ModEntryV0 { name: ptr::null(), log_level: ptr::mut_null()}
+                ]),
+                children: [child_crate1_ptr, ptr::null()]
+            };
+
+            let mut cnt = 0;
+            do iter_crate_map(transmute(&root_crate)) |entry| {
+                assert!(*(*entry).log_level == cnt);
+                cnt += 1;
+            }
+            assert!(cnt == 4);
         }
-        assert!(cnt == 4);
     }
 }
diff --git a/src/libstd/rt/logging.rs b/src/libstd/rt/logging.rs
index 299aa1175a7..8b8e2762381 100644
--- a/src/libstd/rt/logging.rs
+++ b/src/libstd/rt/logging.rs
@@ -14,13 +14,11 @@ use libc::{uintptr_t, exit};
 use option::{Some, None, Option};
 use rt;
 use rt::util::dumb_println;
-use rt::crate_map::{ModEntry, iter_crate_map};
-use rt::crate_map::get_crate_map;
+use rt::crate_map::{ModEntry, CrateMap, iter_crate_map, get_crate_map};
 use str::StrSlice;
-use str::raw::from_c_str;
 use u32;
 use vec::ImmutableVector;
-use cast::transmute;
+#[cfg(test)] use cast::transmute;
 
 struct LogDirective {
     name: Option<~str>,
@@ -110,58 +108,52 @@ fn parse_logging_spec(spec: ~str) -> ~[LogDirective]{
 
 /// Set the log level of an entry in the crate map depending on the vector
 /// of log directives
-fn update_entry(dirs: &[LogDirective], entry: *mut ModEntry) -> u32 {
+fn update_entry(dirs: &[LogDirective], entry: &ModEntry) -> u32 {
     let mut new_lvl: u32 = DEFAULT_LOG_LEVEL;
     let mut longest_match = -1i;
-    unsafe {
-        for dir in dirs.iter() {
-            match dir.name {
-                None => {
-                    if longest_match == -1 {
-                        longest_match = 0;
-                        new_lvl = dir.level;
-                    }
+    for dir in dirs.iter() {
+        match dir.name {
+            None => {
+                if longest_match == -1 {
+                    longest_match = 0;
+                    new_lvl = dir.level;
                 }
-                Some(ref dir_name) => {
-                    let name = from_c_str((*entry).name);
-                    let len = dir_name.len() as int;
-                    if name.starts_with(*dir_name) &&
-                        len >= longest_match {
-                        longest_match = len;
-                        new_lvl = dir.level;
-                    }
+            }
+            Some(ref dir_name) => {
+                let name = entry.name;
+                let len = dir_name.len() as int;
+                if name.starts_with(*dir_name) &&
+                    len >= longest_match {
+                    longest_match = len;
+                    new_lvl = dir.level;
                 }
-            };
-        }
-        *(*entry).log_level = new_lvl;
+            }
+        };
     }
+    unsafe { *entry.log_level = new_lvl; }
     if longest_match >= 0 { return 1; } else { return 0; }
 }
 
 #[fixed_stack_segment] #[inline(never)]
 /// Set log level for every entry in crate_map according to the sepecification
 /// in settings
-fn update_log_settings(crate_map: *u8, settings: ~str) {
+fn update_log_settings(crate_map: &CrateMap, settings: ~str) {
     let mut dirs = ~[];
     if settings.len() > 0 {
         if settings == ~"::help" || settings == ~"?" {
-            dumb_println("\nCrate log map:\n");
-            unsafe {
-                do iter_crate_map(transmute(crate_map)) |entry: *mut ModEntry| {
-                    dumb_println(" "+from_c_str((*entry).name));
-                }
-                exit(1);
+        dumb_println("\nCrate log map:\n");
+            do iter_crate_map(crate_map) |entry| {
+                dumb_println(" "+entry.name);
             }
+            unsafe { exit(1); }
         }
         dirs = parse_logging_spec(settings);
     }
 
     let mut n_matches: u32 = 0;
-    unsafe {
-        do iter_crate_map(transmute(crate_map)) |entry: *mut ModEntry| {
-            let m = update_entry(dirs, entry);
-            n_matches += m;
-        }
+    do iter_crate_map(crate_map) |entry| {
+        let m = update_entry(dirs, entry);
+        n_matches += m;
     }
 
     if n_matches < (dirs.len() as u32) {
@@ -207,15 +199,25 @@ impl rt::io::Writer for StdErrLogger {
 pub fn init() {
     use os;
 
-    let crate_map = get_crate_map() as *u8;
-
     let log_spec = os::getenv("RUST_LOG");
-    match log_spec {
-        Some(spec) => {
-            update_log_settings(crate_map, spec);
-        }
-        None => {
-            update_log_settings(crate_map, ~"");
+    match get_crate_map() {
+        Some(crate_map) => {
+            match log_spec {
+                Some(spec) => {
+                    update_log_settings(crate_map, spec);
+                }
+                None => {
+                    update_log_settings(crate_map, ~"");
+                }
+            }
+        },
+        _ => {
+            match log_spec {
+                Some(_) => {
+                    dumb_println("warning: RUST_LOG set, but no crate map found.");
+                },
+                None => {}
+            }
         }
     }
 }
@@ -291,88 +293,71 @@ fn parse_logging_spec_global() {
 // Tests for update_entry
 #[test]
 fn update_entry_match_full_path() {
-    use c_str::ToCStr;
     let dirs = ~[LogDirective {name: Some(~"crate1::mod1"), level: 2 },
                  LogDirective {name: Some(~"crate2"), level: 3}];
     let level = &mut 0;
     unsafe {
-        do "crate1::mod1".with_c_str |ptr| {
-            let entry= &ModEntry {name: ptr, log_level: level};
-            let m = update_entry(dirs, transmute(entry));
-            assert!(*entry.log_level == 2);
-            assert!(m == 1);
-        }
+        let entry= &ModEntry {name:"crate1::mod1", log_level: level};
+        let m = update_entry(dirs, transmute(entry));
+        assert!(*entry.log_level == 2);
+        assert!(m == 1);
     }
 }
 
 #[test]
 fn update_entry_no_match() {
-    use c_str::ToCStr;
     let dirs = ~[LogDirective {name: Some(~"crate1::mod1"), level: 2 },
                  LogDirective {name: Some(~"crate2"), level: 3}];
     let level = &mut 0;
     unsafe {
-        do "crate3::mod1".with_c_str |ptr| {
-            let entry= &ModEntry {name: ptr, log_level: level};
-            let m = update_entry(dirs, transmute(entry));
-            assert!(*entry.log_level == DEFAULT_LOG_LEVEL);
-            assert!(m == 0);
-        }
+        let entry= &ModEntry {name: "crate3::mod1", log_level: level};
+        let m = update_entry(dirs, transmute(entry));
+        assert!(*entry.log_level == DEFAULT_LOG_LEVEL);
+        assert!(m == 0);
     }
 }
 
 #[test]
 fn update_entry_match_beginning() {
-    use c_str::ToCStr;
     let dirs = ~[LogDirective {name: Some(~"crate1::mod1"), level: 2 },
                  LogDirective {name: Some(~"crate2"), level: 3}];
     let level = &mut 0;
     unsafe {
-        do "crate2::mod1".with_c_str |ptr| {
-            let entry= &ModEntry {name: ptr, log_level: level};
-            let m = update_entry(dirs, transmute(entry));
-            assert!(*entry.log_level == 3);
-            assert!(m == 1);
-        }
+        let entry= &ModEntry {name: "crate2::mod1", log_level: level};
+        let m = update_entry(dirs, transmute(entry));
+        assert!(*entry.log_level == 3);
+        assert!(m == 1);
     }
 }
 
 #[test]
 fn update_entry_match_beginning_longest_match() {
-    use c_str::ToCStr;
     let dirs = ~[LogDirective {name: Some(~"crate1::mod1"), level: 2 },
                  LogDirective {name: Some(~"crate2"), level: 3},
                  LogDirective {name: Some(~"crate2::mod"), level: 4}];
     let level = &mut 0;
     unsafe {
-        do "crate2::mod1".with_c_str |ptr| {
-            let entry = &ModEntry {name: ptr, log_level: level};
-            let m = update_entry(dirs, transmute(entry));
-            assert!(*entry.log_level == 4);
-            assert!(m == 1);
-        }
+        let entry = &ModEntry {name: "crate2::mod1", log_level: level};
+        let m = update_entry(dirs, transmute(entry));
+        assert!(*entry.log_level == 4);
+        assert!(m == 1);
     }
 }
 
 #[test]
 fn update_entry_match_default() {
-    use c_str::ToCStr;
     let dirs = ~[LogDirective {name: Some(~"crate1::mod1"), level: 2 },
                  LogDirective {name: None, level: 3}
                 ];
     let level = &mut 0;
     unsafe {
-        do "crate1::mod1".with_c_str |ptr| {
-            let entry= &ModEntry {name: ptr, log_level: level};
-            let m = update_entry(dirs, transmute(entry));
-            assert!(*entry.log_level == 2);
-            assert!(m == 1);
-        }
-        do "crate2::mod2".with_c_str |ptr| {
-            let entry= &ModEntry {name: ptr, log_level: level};
-            let m = update_entry(dirs, transmute(entry));
-            assert!(*entry.log_level == 3);
-            assert!(m == 1);
-        }
+        let entry= &ModEntry {name: "crate1::mod1", log_level: level};
+        let m = update_entry(dirs, transmute(entry));
+        assert!(*entry.log_level == 2);
+        assert!(m == 1);
+        let entry= &ModEntry {name: "crate2::mod2", log_level: level};
+        let m = update_entry(dirs, transmute(entry));
+        assert!(*entry.log_level == 3);
+        assert!(m == 1);
     }
 }