about summary refs log tree commit diff
path: root/src/libstd/rt
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2014-03-15 23:01:24 -0700
committerbors <bors@rust-lang.org>2014-03-15 23:01:24 -0700
commitf6fcdbb68718380beca798d087c46152cad0949c (patch)
treec6b7fd10bb869fba19561852cf4eb286b0f96a4f /src/libstd/rt
parentabd844e4df068196d1150ac39d596f73e210d95d (diff)
parent0015cab1fd7b4b47030c808a825bb5594cc1d4ac (diff)
downloadrust-f6fcdbb68718380beca798d087c46152cad0949c.tar.gz
rust-f6fcdbb68718380beca798d087c46152cad0949c.zip
auto merge of #12791 : alexcrichton/rust/liblog, r=brson
The rationale and modifications can be found in the first commit message.

This does make logging a bit more painful to use initially because it involves a feature gate and some `phase` attributes, but I think it may be reasonable to not require the `phase` attribute for loading `macro_rules!` macros because defining them will still be gated.
Diffstat (limited to 'src/libstd/rt')
-rw-r--r--src/libstd/rt/backtrace.rs22
-rw-r--r--src/libstd/rt/crate_map.rs99
-rw-r--r--src/libstd/rt/logging.rs314
-rw-r--r--src/libstd/rt/mod.rs4
-rw-r--r--src/libstd/rt/task.rs5
-rw-r--r--src/libstd/rt/unwind.rs2
6 files changed, 36 insertions, 410 deletions
diff --git a/src/libstd/rt/backtrace.rs b/src/libstd/rt/backtrace.rs
index 831f6c73e35..bc75a98e085 100644
--- a/src/libstd/rt/backtrace.rs
+++ b/src/libstd/rt/backtrace.rs
@@ -16,15 +16,31 @@ use from_str::from_str;
 use io::{IoResult, Writer};
 use iter::Iterator;
 use option::{Some, None};
+use os;
 use result::{Ok, Err};
 use str::StrSlice;
+use sync::atomics;
 
 pub use self::imp::write;
 
-// This function is defined in this module so that the way to enable logging of
-// backtraces has the word 'backtrace' in it: std::rt::backtrace.
+// For now logging is turned off by default, and this function checks to see
+// whether the magical environment variable is present to see if it's turned on.
 pub fn log_enabled() -> bool {
-    log_enabled!(::logging::DEBUG)
+    static mut ENABLED: atomics::AtomicInt = atomics::INIT_ATOMIC_INT;
+    unsafe {
+        match ENABLED.load(atomics::SeqCst) {
+            1 => return false,
+            2 => return true,
+            _ => {}
+        }
+    }
+
+    let val = match os::getenv("RUST_BACKTRACE") {
+        Some(..) => 2,
+        None => 1,
+    };
+    unsafe { ENABLED.store(val, atomics::SeqCst); }
+    val == 2
 }
 
 #[cfg(target_word_size = "64")] static HEX_WIDTH: uint = 18;
diff --git a/src/libstd/rt/crate_map.rs b/src/libstd/rt/crate_map.rs
index ff54a80ce99..c6d5a80208b 100644
--- a/src/libstd/rt/crate_map.rs
+++ b/src/libstd/rt/crate_map.rs
@@ -9,13 +9,14 @@
 // except according to those terms.
 
 use cast;
-use cmp::TotalOrd;
-use container::MutableSet;
-use iter::Iterator;
 use option::{Some, None, Option};
 use ptr::RawPtr;
 use rt::rtio::EventLoop;
-use vec::{ImmutableVector, OwnedVector};
+
+#[cfg(stage0)] use cmp::TotalOrd;
+#[cfg(stage0)] use container::MutableSet;
+#[cfg(stage0)] use iter::Iterator;
+#[cfg(stage0)] use vec::{ImmutableVector, OwnedVector};
 
 // 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
@@ -24,17 +25,24 @@ use vec::{ImmutableVector, OwnedVector};
 #[link_args = "-Wl,-U,__rust_crate_map_toplevel"]
 extern {}
 
+#[cfg(stage0)]
 pub struct ModEntry<'a> {
     name: &'a str,
     log_level: *mut u32
 }
 
+#[cfg(stage0)]
 pub struct CrateMap<'a> {
     version: i32,
     entries: &'a [ModEntry<'a>],
     children: &'a [&'a CrateMap<'a>],
     event_loop_factory: Option<fn() -> ~EventLoop>,
 }
+#[cfg(not(stage0))]
+pub struct CrateMap<'a> {
+    version: i32,
+    event_loop_factory: Option<fn() -> ~EventLoop>,
+}
 
 // When working on android, apparently weak symbols don't work so well for
 // finding the crate map, and neither does dlopen + dlsym. This is mainly a
@@ -114,6 +122,7 @@ pub fn get_crate_map() -> Option<&'static CrateMap<'static>> {
     }
 }
 
+#[cfg(stage0)]
 fn version(crate_map: &CrateMap) -> i32 {
     match crate_map.version {
         2 => return 2,
@@ -121,6 +130,7 @@ fn version(crate_map: &CrateMap) -> i32 {
     }
 }
 
+#[cfg(stage0)]
 fn do_iter_crate_map<'a>(
                      crate_map: &'a CrateMap<'a>,
                      f: |&'a ModEntry<'a>|,
@@ -149,87 +159,8 @@ fn do_iter_crate_map<'a>(
 }
 
 /// Iterates recursively over `crate_map` and all child crate maps
+#[cfg(stage0)]
 pub fn iter_crate_map<'a>(crate_map: &'a CrateMap<'a>, f: |&'a ModEntry<'a>|) {
     let mut v = ~[];
     do_iter_crate_map(crate_map, f, &mut v);
 }
-
-#[cfg(test)]
-mod tests {
-    use option::None;
-    use rt::crate_map::{CrateMap, ModEntry, iter_crate_map};
-
-    #[test]
-    fn iter_crate_map_duplicates() {
-        let mut level3: u32 = 3;
-
-        let entries = [
-            ModEntry { name: "c::m1", log_level: &mut level3},
-        ];
-
-        let child_crate = CrateMap {
-            version: 2,
-            entries: entries,
-            children: &[],
-            event_loop_factory: None,
-        };
-
-        let root_crate = CrateMap {
-            version: 2,
-            entries: &[],
-            children: &[&child_crate, &child_crate],
-            event_loop_factory: None,
-        };
-
-        let mut cnt = 0;
-        unsafe {
-            iter_crate_map(&root_crate, |entry| {
-                assert!(*entry.log_level == 3);
-                cnt += 1;
-            });
-            assert!(cnt == 1);
-        }
-    }
-
-    #[test]
-    fn iter_crate_map_follow_children() {
-        let mut level2: u32 = 2;
-        let mut level3: u32 = 3;
-        let child_crate2 = CrateMap {
-            version: 2,
-            entries: &[
-                ModEntry { name: "c::m1", log_level: &mut level2},
-                ModEntry { name: "c::m2", log_level: &mut level3},
-            ],
-            children: &[],
-            event_loop_factory: None,
-        };
-
-        let child_crate1 = CrateMap {
-            version: 2,
-            entries: &[
-                ModEntry { name: "t::f1", log_level: &mut 1},
-            ],
-            children: &[&child_crate2],
-            event_loop_factory: None,
-        };
-
-        let root_crate = CrateMap {
-            version: 2,
-            entries: &[
-                ModEntry { name: "t::f2", log_level: &mut 0},
-            ],
-            children: &[&child_crate1],
-            event_loop_factory: None,
-        };
-
-        let mut cnt = 0;
-        unsafe {
-            iter_crate_map(&root_crate, |entry| {
-                assert!(*entry.log_level == cnt);
-                cnt += 1;
-            });
-            assert!(cnt == 4);
-        }
-    }
-}
diff --git a/src/libstd/rt/logging.rs b/src/libstd/rt/logging.rs
deleted file mode 100644
index aa024a53b89..00000000000
--- a/src/libstd/rt/logging.rs
+++ /dev/null
@@ -1,314 +0,0 @@
-// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use container::Container;
-use from_str::from_str;
-use iter::Iterator;
-use libc::exit;
-use option::{Some, None, Option};
-use os;
-use rt::crate_map::{ModEntry, CrateMap, iter_crate_map, get_crate_map};
-use str::{Str, StrSlice};
-use vec::{ImmutableVector, MutableTotalOrdVector, OwnedVector};
-use vec_ng::Vec;
-
-struct LogDirective<'a> {
-    name: Option<&'a str>,
-    level: u32
-}
-
-static MAX_LOG_LEVEL: u32 = 255;
-static DEFAULT_LOG_LEVEL: u32 = 1;
-static log_level_names : &'static[&'static str] = &'static["error", "warn", "info", "debug"];
-
-/// Parse an individual log level that is either a number or a symbolic log level
-fn parse_log_level(level: &str) -> Option<u32> {
-    let num = from_str::<u32>(level);
-    let mut log_level;
-    match num {
-        Some(num) => {
-            if num < MAX_LOG_LEVEL {
-                log_level = Some(num);
-            } else {
-                log_level = Some(MAX_LOG_LEVEL);
-            }
-        }
-        _ => {
-            let position = log_level_names.iter().position(|&name| name == level);
-            match position {
-                Some(position) => {
-                    log_level = Some(::cmp::min(MAX_LOG_LEVEL, (position + 1) as u32))
-                },
-                _ => {
-                    log_level = None;
-                }
-            }
-        }
-    }
-    log_level
-}
-
-/// Parse a logging specification string (e.g: "crate1,crate2::mod3,crate3::x=1")
-/// and return a vector with log directives.
-/// Valid log levels are 0-255, with the most likely ones being 1-4 (defined in std::).
-/// Also supports string log levels of error, warn, info, and debug
-fn parse_logging_spec<'a>(spec: &'a str) -> Vec<LogDirective<'a>> {
-    let mut dirs = Vec::new();
-    for s in spec.split(',') {
-        if s.len() == 0 { continue }
-        let mut parts = s.split('=');
-        let log_level;
-        let name;
-        match (parts.next(), parts.next(), parts.next()) {
-            (Some(part0), None, None) => {
-                //if the single argument is a log-level string or number,
-                //treat that as a global fallback
-                let possible_log_level = parse_log_level(part0);
-                match possible_log_level {
-                    Some(num) => {
-                        name = None;
-                        log_level = num;
-                    },
-                    None => {
-                        log_level = MAX_LOG_LEVEL;
-                        name = Some(part0);
-                    }
-                }
-            }
-            (Some(part0), Some(part1), None) => {
-                let possible_log_level = parse_log_level(part1);
-                match possible_log_level {
-                    Some(num) => {
-                        name = Some(part0);
-                        log_level = num;
-                    },
-                    _ => {
-                        rterrln!("warning: invalid logging spec '{}', \
-                                  ignoring it", part1);
-                        continue
-                    }
-                }
-            },
-            _ => {
-                rterrln!("warning: invalid logging spec '{}', \
-                          ignoring it", s);
-                continue
-            }
-        }
-        dirs.push(LogDirective { name: name, level: log_level });
-    }
-    return dirs;
-}
-
-/// Set the log level of an entry in the crate map depending on the vector
-/// of log directives
-fn update_entry(dirs: &[LogDirective], entry: &ModEntry) -> u32 {
-    let mut new_lvl: u32 = DEFAULT_LOG_LEVEL;
-    let mut longest_match = -1i;
-    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 = 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;
-                }
-            }
-        };
-    }
-    unsafe { *entry.log_level = new_lvl; }
-    if longest_match >= 0 { return 1; } else { return 0; }
-}
-
-/// Set log level for every entry in crate_map according to the sepecification
-/// in settings
-fn update_log_settings(crate_map: &CrateMap, settings: &str) {
-    if settings == "::help" || settings == "?" {
-        rterrln!("\nCrate log map:\n");
-
-        let mut entries = Vec::new();
-        iter_crate_map(crate_map, |entry| entries.push(entry.name));
-        entries.as_mut_slice().sort();
-
-        for name in entries.iter() {
-            rterrln!(" {}", *name);
-        }
-        unsafe { exit(1); }
-    }
-    let dirs = parse_logging_spec(settings);
-
-    let mut n_matches: u32 = 0;
-    iter_crate_map(crate_map, |entry| {
-        let m = update_entry(dirs.as_slice(), entry);
-        n_matches += m;
-    });
-
-    if n_matches < (dirs.len() as u32) {
-        rterrln!("warning: got {} RUST_LOG specs but only matched\n\
-                  {} of them. You may have mistyped a RUST_LOG spec. \n\
-                  Use RUST_LOG=::help to see the list of crates and modules.\n",
-                 dirs.len(), n_matches);
-    }
-}
-
-/// Configure logging by traversing the crate map and setting the
-/// per-module global logging flags based on the logging spec
-pub fn init() {
-    let log_spec = os::getenv("RUST_LOG");
-    match get_crate_map() {
-        Some(crate_map) => {
-            match log_spec {
-                Some(spec) => update_log_settings(crate_map, spec.as_slice()),
-                None => update_log_settings(crate_map, ""),
-            }
-        },
-        _ => {
-            match log_spec {
-                Some(_) => {
-                    rterrln!("warning: RUST_LOG set, but no crate map found.");
-                },
-                None => {}
-            }
-        }
-    }
-}
-
-// Tests for parse_logging_spec()
-#[test]
-fn parse_logging_spec_valid() {
-    let dirs = parse_logging_spec("crate1::mod1=1,crate1::mod2,crate2=4");
-    let dirs = dirs.as_slice();
-    assert_eq!(dirs.len(), 3);
-    assert_eq!(dirs[0].name, Some("crate1::mod1"));
-    assert_eq!(dirs[0].level, 1);
-
-    assert_eq!(dirs[1].name, Some("crate1::mod2"));
-    assert_eq!(dirs[1].level, MAX_LOG_LEVEL);
-
-    assert_eq!(dirs[2].name, Some("crate2"));
-    assert_eq!(dirs[2].level, 4);
-}
-
-#[test]
-fn parse_logging_spec_invalid_crate() {
-    // test parse_logging_spec with multiple = in specification
-    let dirs = parse_logging_spec("crate1::mod1=1=2,crate2=4");
-    let dirs = dirs.as_slice();
-    assert_eq!(dirs.len(), 1);
-    assert_eq!(dirs[0].name, Some("crate2"));
-    assert_eq!(dirs[0].level, 4);
-}
-
-#[test]
-fn parse_logging_spec_invalid_log_level() {
-    // test parse_logging_spec with 'noNumber' as log level
-    let dirs = parse_logging_spec("crate1::mod1=noNumber,crate2=4");
-    let dirs = dirs.as_slice();
-    assert_eq!(dirs.len(), 1);
-    assert_eq!(dirs[0].name, Some("crate2"));
-    assert_eq!(dirs[0].level, 4);
-}
-
-#[test]
-fn parse_logging_spec_string_log_level() {
-    // test parse_logging_spec with 'warn' as log level
-    let dirs = parse_logging_spec("crate1::mod1=wrong,crate2=warn");
-    let dirs = dirs.as_slice();
-    assert_eq!(dirs.len(), 1);
-    assert_eq!(dirs[0].name, Some("crate2"));
-    assert_eq!(dirs[0].level, 2);
-}
-
-#[test]
-fn parse_logging_spec_global() {
-    // test parse_logging_spec with no crate
-    let dirs = parse_logging_spec("warn,crate2=4");
-    let dirs = dirs.as_slice();
-    assert_eq!(dirs.len(), 2);
-    assert_eq!(dirs[0].name, None);
-    assert_eq!(dirs[0].level, 2);
-    assert_eq!(dirs[1].name, Some("crate2"));
-    assert_eq!(dirs[1].level, 4);
-}
-
-// Tests for update_entry
-#[test]
-fn update_entry_match_full_path() {
-    let dirs = [LogDirective { name: Some("crate1::mod1"), level: 2 },
-                LogDirective { name: Some("crate2"), level: 3 }];
-    let mut level = 0;
-    {
-        let entry = &ModEntry { name: "crate1::mod1", log_level: &mut level };
-        assert_eq!(update_entry(dirs, entry), 1);
-    }
-    assert_eq!(level, 2);
-}
-
-#[test]
-fn update_entry_no_match() {
-    let dirs = [LogDirective { name: Some("crate1::mod1"), level: 2 },
-                LogDirective { name: Some("crate2"), level: 3 }];
-    let mut level = 0;
-    {
-        let entry = &ModEntry { name: "crate3::mod1", log_level: &mut level };
-        assert_eq!(update_entry(dirs, entry), 0);
-    }
-    assert_eq!(level, DEFAULT_LOG_LEVEL);
-}
-
-#[test]
-fn update_entry_match_beginning() {
-    let dirs = [LogDirective { name: Some("crate1::mod1"), level: 2 },
-                LogDirective { name: Some("crate2"), level: 3 }];
-    let mut level = 0;
-    {
-        let entry= &ModEntry {name: "crate2::mod1", log_level: &mut level};
-        assert_eq!(update_entry(dirs, entry), 1);
-    }
-    assert_eq!(level, 3);
-}
-
-#[test]
-fn update_entry_match_beginning_longest_match() {
-    let dirs = [LogDirective { name: Some("crate1::mod1"), level: 2 },
-                LogDirective { name: Some("crate2"), level: 3 },
-                LogDirective { name: Some("crate2::mod"), level: 4 }];
-    let mut level = 0;
-    {
-        let entry = &ModEntry { name: "crate2::mod1", log_level: &mut level };
-        assert_eq!(update_entry(dirs, entry), 1);
-    }
-    assert_eq!(level, 4);
-}
-
-#[test]
-fn update_entry_match_default() {
-    let dirs = [LogDirective { name: Some("crate1::mod1"), level: 2 },
-                LogDirective { name: None, level: 3 }];
-    let mut level = 0;
-    {
-        let entry = &ModEntry { name: "crate1::mod1", log_level: &mut level };
-        assert_eq!(update_entry(dirs, entry), 1);
-    }
-    assert_eq!(level, 2);
-    {
-        let entry = &ModEntry { name: "crate2::mod2", log_level: &mut level };
-        assert_eq!(update_entry(dirs, entry), 1);
-    }
-    assert_eq!(level, 3);
-}
diff --git a/src/libstd/rt/mod.rs b/src/libstd/rt/mod.rs
index a58826daa49..84e547619df 100644
--- a/src/libstd/rt/mod.rs
+++ b/src/libstd/rt/mod.rs
@@ -104,9 +104,6 @@ pub mod env;
 /// The local, managed heap
 pub mod local_heap;
 
-/// The Logger trait and implementations
-pub mod logging;
-
 /// Crate map
 pub mod crate_map;
 
@@ -183,7 +180,6 @@ pub fn init(argc: int, argv: **u8) {
     unsafe {
         args::init(argc, argv);
         env::init();
-        logging::init();
         local_ptr::init();
         at_exit_imp::init();
     }
diff --git a/src/libstd/rt/task.rs b/src/libstd/rt/task.rs
index 86e69560e9d..8c617c1b59b 100644
--- a/src/libstd/rt/task.rs
+++ b/src/libstd/rt/task.rs
@@ -21,7 +21,6 @@ use comm::Sender;
 use io::Writer;
 use iter::{Iterator, Take};
 use local_data;
-use logging::Logger;
 use ops::Drop;
 use option::{Option, Some, None};
 use prelude::drop;
@@ -51,7 +50,6 @@ pub struct Task {
     destroyed: bool,
     name: Option<SendStr>,
 
-    logger: Option<~Logger>,
     stdout: Option<~Writer>,
     stderr: Option<~Writer>,
 
@@ -95,7 +93,6 @@ impl Task {
             death: Death::new(),
             destroyed: false,
             name: None,
-            logger: None,
             stdout: None,
             stderr: None,
             imp: None,
@@ -129,11 +126,9 @@ impl Task {
                 #[allow(unused_must_use)]
                 fn close_outputs() {
                     let mut task = Local::borrow(None::<Task>);
-                    let logger = task.get().logger.take();
                     let stderr = task.get().stderr.take();
                     let stdout = task.get().stdout.take();
                     drop(task);
-                    drop(logger); // loggers are responsible for flushing
                     match stdout { Some(mut w) => { w.flush(); }, None => {} }
                     match stderr { Some(mut w) => { w.flush(); }, None => {} }
                 }
diff --git a/src/libstd/rt/unwind.rs b/src/libstd/rt/unwind.rs
index 3a06075ce48..7f54b8b3320 100644
--- a/src/libstd/rt/unwind.rs
+++ b/src/libstd/rt/unwind.rs
@@ -398,6 +398,8 @@ fn begin_unwind_inner(msg: ~Any, file: &'static str, line: uint) -> ! {
                 if backtrace::log_enabled() {
                     let mut err = ::rt::util::Stderr;
                     let _err = backtrace::write(&mut err);
+                } else {
+                    rterrln!("run with `RUST_BACKTRACE=1` to see a backtrace");
                 }
                 unsafe { intrinsics::abort() }
             }