(index<- )        ./libstd/rt/crate_map.rs

   1  // Copyright 2013 The Rust Project Developers. See the COPYRIGHT
   2  // file at the top-level directory of this distribution and at
   3  // http://rust-lang.org/COPYRIGHT.
   4  //
   5  // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
   6  // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
   7  // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
   8  // option. This file may not be copied, modified, or distributed
   9  // except according to those terms.
  10  
  11  use container::MutableSet;
  12  use hashmap::HashSet;
  13  use option::{Some, None, Option};
  14  use vec::ImmutableVector;
  15  
  16  // Need to tell the linker on OS X to not barf on undefined symbols
  17  // and instead look them up at runtime, which we need to resolve
  18  // the crate_map properly.
  19  #[cfg(target_os = "macos")]
  20  #[link_args = "-undefined dynamic_lookup"]
  21  extern {}
  22  
  23  pub struct ModEntry<'self> {
  24      name: &'self str,
  25      log_level: *mut u32
  26  }
  27  
  28  pub struct CrateMap<'self> {
  29      version: i32,
  30      entries: &'self [ModEntry<'self>],
  31      children: &'self [&'self CrateMap<'self>]
  32  }
  33  
  34  #[cfg(not(windows))]
  35  pub fn get_crate_map() -> Option<&'static CrateMap<'static>> {
  36      extern {
  37          #[weak_linkage]
  38          #[link_name = "_rust_crate_map_toplevel"]
  39          static CRATE_MAP: CrateMap<'static>;
  40      }
  41  
  42      let ptr(*CrateMap) = &'static CRATE_MAP;
  43      if ptr.is_null() {
  44          return None;
  45      } else {
  46          return Some(&'static CRATE_MAP);
  47      }
  48  }
  49  
  50  #[cfg(windows)]
  51  #[fixed_stack_segment]
  52  #[inline(never)]
  53  pub fn get_crate_map() -> Option<&'static CrateMap<'static>> {
  54      use cast::transmute;
  55      use c_str::ToCStr;
  56      use unstable::dynamic_lib::dl;
  57  
  58      let sym = unsafe {
  59          let module = dl::open_internal();
  60          let sym = do "__rust_crate_map_toplevel".with_c_str |buf| {
  61              dl::symbol(module, buf)
  62          };
  63          dl::close(module);
  64          sym
  65      };
  66      let ptr: (*CrateMap) = sym as *CrateMap;
  67      if ptr.is_null() {
  68          return None;
  69      } else {
  70          unsafe {
  71              return Some(transmute(sym));
  72          }
  73      }
  74  }
  75  
  76  fn version(crate_map&CrateMap) -> i32 {
  77      match crate_map.version {
  78          2 => return 2,
  79          _ => return 0
  80      }
  81  }
  82  
  83  fn do_iter_crate_map<'a>(crate_map&'a CrateMap<'a>, f&fn(&ModEntry),
  84                              visited&mut HashSet<*CrateMap<'a>>) {
  85      if visited.insert(crate_map as *CrateMap) {
  86          match version(crate_map) {
  87              2 => {
  88                  let (entries, children) = (crate_map.entries, crate_map.children);
  89                  for entry in entries.iter() {
  90                      f(entry);
  91                  }
  92                  for child in children.iter() {
  93                      do_iter_crate_map(*child, |x| f(x), visited);
  94                  }
  95              },
  96              _ => fail2!("invalid crate map version")
  97          }
  98      }
  99  }
 100  
 101  /// Iterates recursively over `crate_map` and all child crate maps
 102  pub fn iter_crate_map<'a>(crate_map&'a CrateMap<'a>, f&fn(&ModEntry)) {
 103      // XXX: use random numbers as keys from the OS-level RNG when there is a nice
 104      //        way to do this
 105      let mut vHashSet<*CrateMap<'a>> = HashSet::with_capacity_and_keys(0, 0, 32);
 106      do_iter_crate_map(crate_map, f, &mut v);
 107  }
 108  
 109  #[cfg(test)]
 110  mod tests {
 111      use rt::crate_map::{CrateMap, ModEntry, iter_crate_map};
 112  
 113      #[test]
 114      fn iter_crate_map_duplicates() {
 115          let mut level3: u32 = 3;
 116  
 117          let entries = [
 118              ModEntry { name: "c::m1", log_level: &mut level3},
 119          ];
 120  
 121          let child_crate = CrateMap {
 122              version: 2,
 123              entries: entries,
 124              children: []
 125          };
 126  
 127          let root_crate = CrateMap {
 128              version: 2,
 129              entries: [],
 130              children: [&child_crate, &child_crate]
 131          };
 132  
 133          let mut cnt = 0;
 134          unsafe {
 135              do iter_crate_map(&root_crate) |entry| {
 136                  assert!(*entry.log_level == 3);
 137                  cnt += 1;
 138              }
 139              assert!(cnt == 1);
 140          }
 141      }
 142  
 143      #[test]
 144      fn iter_crate_map_follow_children() {
 145          let mut level2: u32 = 2;
 146          let mut level3: u32 = 3;
 147          let child_crate2 = CrateMap {
 148              version: 2,
 149              entries: [
 150                  ModEntry { name: "c::m1", log_level: &mut level2},
 151                  ModEntry { name: "c::m2", log_level: &mut level3},
 152              ],
 153              children: []
 154          };
 155  
 156          let child_crate1 = CrateMap {
 157              version: 2,
 158              entries: [
 159                  ModEntry { name: "t::f1", log_level: &mut 1},
 160              ],
 161              children: [&child_crate2]
 162          };
 163  
 164          let root_crate = CrateMap {
 165              version: 2,
 166              entries: [
 167                  ModEntry { name: "t::f2", log_level: &mut 0},
 168              ],
 169              children: [&child_crate1]
 170          };
 171  
 172          let mut cnt = 0;
 173          unsafe {
 174              do iter_crate_map(&root_crate) |entry| {
 175                  assert!(*entry.log_level == cnt);
 176                  cnt += 1;
 177              }
 178              assert!(cnt == 4);
 179          }
 180      }
 181  }

libstd/rt/crate_map.rs:82:1-82:1 -fn- definition:

fn do_iter_crate_map<'a>(crate_map: &'a CrateMap<'a>, f: &fn(&ModEntry),
references:-
106:     do_iter_crate_map(crate_map, f, &mut v);
93:                     do_iter_crate_map(*child, |x| f(x), visited);


libstd/rt/crate_map.rs:27:1-27:1 -struct- definition:

pub struct CrateMap<'self> {
references:-
76: fn version(crate_map: &CrateMap) -> i32 {
84:                             visited: &mut HashSet<*CrateMap<'a>>) {
85:     if visited.insert(crate_map as *CrateMap) {
35: pub fn get_crate_map() -> Option<&'static CrateMap<'static>> {
102: pub fn iter_crate_map<'a>(crate_map: &'a CrateMap<'a>, f: &fn(&ModEntry)) {
31:     children: &'self [&'self CrateMap<'self>]
105:     let mut v: HashSet<*CrateMap<'a>> = HashSet::with_capacity_and_keys(0, 0, 32);
42:     let ptr: (*CrateMap) = &'static CRATE_MAP;
39:         static CRATE_MAP: CrateMap<'static>;
83: fn do_iter_crate_map<'a>(crate_map: &'a CrateMap<'a>, f: &fn(&ModEntry),
libstd/rt/logging.rs:
138: fn update_log_settings(crate_map: &CrateMap, settings: ~str) {


libstd/rt/crate_map.rs:34:21-34:21 -fn- definition:
#[cfg(not(windows))]
pub fn get_crate_map() -> Option<&'static CrateMap<'static>> {
references:-
libstd/rt/logging.rs:
186:     match get_crate_map() {


libstd/rt/crate_map.rs:75:1-75:1 -fn- definition:

fn version(crate_map: &CrateMap) -> i32 {
references:-
86:         match version(crate_map) {


libstd/rt/crate_map.rs:22:1-22:1 -struct- definition:

pub struct ModEntry<'self> {
references:-
102: pub fn iter_crate_map<'a>(crate_map: &'a CrateMap<'a>, f: &fn(&ModEntry)) {
83: fn do_iter_crate_map<'a>(crate_map: &'a CrateMap<'a>, f: &fn(&ModEntry),
30:     entries: &'self [ModEntry<'self>],
libstd/rt/logging.rs:
109: fn update_entry(dirs: &[LogDirective], entry: &ModEntry) -> u32 {


libstd/rt/crate_map.rs:101:67-101:67 -fn- definition:
/// Iterates recursively over `crate_map` and all child crate maps
pub fn iter_crate_map<'a>(crate_map: &'a CrateMap<'a>, f: &fn(&ModEntry)) {
references:-
libstd/rt/logging.rs:
152:     do iter_crate_map(crate_map) |entry| {
143:             do iter_crate_map(crate_map) |entry| {