diff options
| author | bors <bors@rust-lang.org> | 2014-03-15 23:01:24 -0700 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2014-03-15 23:01:24 -0700 |
| commit | f6fcdbb68718380beca798d087c46152cad0949c (patch) | |
| tree | c6b7fd10bb869fba19561852cf4eb286b0f96a4f /src/libstd | |
| parent | abd844e4df068196d1150ac39d596f73e210d95d (diff) | |
| parent | 0015cab1fd7b4b47030c808a825bb5594cc1d4ac (diff) | |
| download | rust-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')
| -rw-r--r-- | src/libstd/cleanup.rs | 2 | ||||
| -rw-r--r-- | src/libstd/io/mod.rs | 4 | ||||
| -rw-r--r-- | src/libstd/io/test.rs | 9 | ||||
| -rw-r--r-- | src/libstd/iter.rs | 4 | ||||
| -rw-r--r-- | src/libstd/lib.rs | 5 | ||||
| -rw-r--r-- | src/libstd/logging.rs | 184 | ||||
| -rw-r--r-- | src/libstd/macros.rs | 113 | ||||
| -rw-r--r-- | src/libstd/os.rs | 21 | ||||
| -rw-r--r-- | src/libstd/ptr.rs | 3 | ||||
| -rw-r--r-- | src/libstd/rt/backtrace.rs | 22 | ||||
| -rw-r--r-- | src/libstd/rt/crate_map.rs | 99 | ||||
| -rw-r--r-- | src/libstd/rt/logging.rs | 314 | ||||
| -rw-r--r-- | src/libstd/rt/mod.rs | 4 | ||||
| -rw-r--r-- | src/libstd/rt/task.rs | 5 | ||||
| -rw-r--r-- | src/libstd/rt/unwind.rs | 2 | ||||
| -rw-r--r-- | src/libstd/task.rs | 4 |
16 files changed, 63 insertions, 732 deletions
diff --git a/src/libstd/cleanup.rs b/src/libstd/cleanup.rs index 39c7932cdc8..243f7b2055f 100644 --- a/src/libstd/cleanup.rs +++ b/src/libstd/cleanup.rs @@ -97,6 +97,6 @@ pub unsafe fn annihilate() { if debug_mem() { // We do logging here w/o allocation. - debug!("total boxes annihilated: {}", n_total_boxes); + println!("total boxes annihilated: {}", n_total_boxes); } } diff --git a/src/libstd/io/mod.rs b/src/libstd/io/mod.rs index 28f6d13070e..c18d4e273c4 100644 --- a/src/libstd/io/mod.rs +++ b/src/libstd/io/mod.rs @@ -352,9 +352,7 @@ pub trait Reader { let mut buf = [0]; loop { match self.read(buf) { - Ok(0) => { - debug!("read 0 bytes. trying again"); - } + Ok(0) => {} Ok(1) => return Ok(buf[0]), Ok(_) => unreachable!(), Err(e) => return Err(e) diff --git a/src/libstd/io/test.rs b/src/libstd/io/test.rs index a3e5bac89d6..9eeaf4635a4 100644 --- a/src/libstd/io/test.rs +++ b/src/libstd/io/test.rs @@ -176,16 +176,14 @@ mod darwin_fd_limit { if sysctl(&mut mib[0], 2, &mut maxfiles as *mut libc::c_int as *mut libc::c_void, &mut size, mut_null(), 0) != 0 { let err = last_os_error(); - error!("raise_fd_limit: error calling sysctl: {}", err); - return; + fail!("raise_fd_limit: error calling sysctl: {}", err); } // Fetch the current resource limits let mut rlim = rlimit{rlim_cur: 0, rlim_max: 0}; if getrlimit(RLIMIT_NOFILE, &mut rlim) != 0 { let err = last_os_error(); - error!("raise_fd_limit: error calling getrlimit: {}", err); - return; + fail!("raise_fd_limit: error calling getrlimit: {}", err); } // Bump the soft limit to the smaller of kern.maxfilesperproc and the hard limit @@ -194,8 +192,7 @@ mod darwin_fd_limit { // Set our newly-increased resource limit if setrlimit(RLIMIT_NOFILE, &rlim) != 0 { let err = last_os_error(); - error!("raise_fd_limit: error calling setrlimit: {}", err); - return; + fail!("raise_fd_limit: error calling setrlimit: {}", err); } } } diff --git a/src/libstd/iter.rs b/src/libstd/iter.rs index 6bcac425420..9e988eb4094 100644 --- a/src/libstd/iter.rs +++ b/src/libstd/iter.rs @@ -398,9 +398,9 @@ pub trait Iterator<A> { /// let xs = [1u, 4, 2, 3, 8, 9, 6]; /// let sum = xs.iter() /// .map(|&x| x) - /// .inspect(|&x| debug!("filtering {}", x)) + /// .inspect(|&x| println!("filtering {}", x)) /// .filter(|&x| x % 2 == 0) - /// .inspect(|&x| debug!("{} made it through", x)) + /// .inspect(|&x| println!("{} made it through", x)) /// .sum(); /// println!("{}", sum); /// ``` diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index 6b1773ec7ff..17c0e2235c0 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -53,7 +53,7 @@ html_root_url = "http://static.rust-lang.org/doc/master")]; #[feature(macro_rules, globs, asm, managed_boxes, thread_local, link_args, - simd, linkage, default_type_params)]; + simd, linkage, default_type_params, phase)]; // NOTE remove the following two attributes after the next snapshot. #[allow(unrecognized_lint)]; @@ -73,6 +73,7 @@ #[cfg(test)] extern crate rustuv; #[cfg(test)] extern crate native; #[cfg(test)] extern crate green; +#[cfg(test)] #[phase(syntax, link)] extern crate log; // Make and rand accessible for benchmarking/testcases #[cfg(test)] extern crate rand; @@ -178,7 +179,6 @@ pub mod path; pub mod cast; pub mod fmt; pub mod cleanup; -pub mod logging; pub mod mem; @@ -221,7 +221,6 @@ mod std { pub use io; pub use kinds; pub use local_data; - pub use logging; pub use option; pub use os; pub use rt; diff --git a/src/libstd/logging.rs b/src/libstd/logging.rs deleted file mode 100644 index 2271a7c2380..00000000000 --- a/src/libstd/logging.rs +++ /dev/null @@ -1,184 +0,0 @@ -// Copyright 2012 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. - -/*! - -Utilities for program-wide and customizable logging - -This module is used by the compiler when emitting output for the logging family -of macros. The methods of this module shouldn't necessarily be used directly, -but rather through the logging macros defined. - -There are five macros that the logging subsystem uses: - -* `log!(level, ...)` - the generic logging macro, takes a level as a u32 and any - related `format!` arguments -* `debug!(...)` - a macro hard-wired to the log level of `DEBUG` -* `info!(...)` - a macro hard-wired to the log level of `INFO` -* `warn!(...)` - a macro hard-wired to the log level of `WARN` -* `error!(...)` - a macro hard-wired to the log level of `ERROR` - -All of these macros use the same style of syntax as the `format!` syntax -extension. Details about the syntax can be found in the documentation of -`std::fmt` along with the Rust tutorial/manual. - -If you want to check at runtime if a given logging level is enabled (e.g. if the -information you would want to log is expensive to produce), you can use the -following macro: - -* `log_enabled!(level)` - returns true if logging of the given level is enabled - -## Enabling logging - -Log levels are controlled on a per-module basis, and by default all logging is -disabled except for `error!` (a log level of 1). Logging is controlled via the -`RUST_LOG` environment variable. The value of this environment variable is a -comma-separated list of logging directives. A logging directive is of the form: - -```ignore -path::to::module=log_level -``` - -The path to the module is rooted in the name of the crate it was compiled for, -so if your program is contained in a file `hello.rs`, for example, to turn on -logging for this file you would use a value of `RUST_LOG=hello`. Furthermore, -this path is a prefix-search, so all modules nested in the specified module will -also have logging enabled. - -The actual `log_level` is optional to specify. If omitted, all logging will be -enabled. If specified, the it must be either a numeric in the range of 1-255, or -it must be one of the strings `debug`, `error`, `info`, or `warn`. If a numeric -is specified, then all logging less than or equal to that numeral is enabled. -For example, if logging level 3 is active, error, warn, and info logs will be -printed, but debug will be omitted. - -As the log level for a module is optional, the module to enable logging for is -also optional. If only a `log_level` is provided, then the global log level for -all modules is set to this value. - -Some examples of valid values of `RUST_LOG` are: - -```ignore -hello // turns on all logging for the 'hello' module -info // turns on all info logging -hello=debug // turns on debug logging for 'hello' -hello=3 // turns on info logging for 'hello' -hello,std::option // turns on hello, and std's option logging -error,hello=warn // turn on global error logging and also warn for hello -``` - -## Performance and Side Effects - -Each of these macros will expand to code similar to: - -```rust,ignore -if log_level <= my_module_log_level() { - ::std::logging::log(log_level, format!(...)); -} -``` - -What this means is that each of these macros are very cheap at runtime if -they're turned off (just a load and an integer comparison). This also means that -if logging is disabled, none of the components of the log will be executed. - -## Useful Values - -For convenience, if a value of `::help` is set for `RUST_LOG`, a program will -start, print out all modules registered for logging, and then exit. - -*/ - -use fmt; -use io::LineBufferedWriter; -use io; -use io::Writer; -use mem::replace; -use ops::Drop; -use option::{Some, None, Option}; -use prelude::drop; -use result::{Ok, Err}; -use rt::local::Local; -use rt::task::Task; - -/// Debug log level -pub static DEBUG: u32 = 4; -/// Info log level -pub static INFO: u32 = 3; -/// Warn log level -pub static WARN: u32 = 2; -/// Error log level -pub static ERROR: u32 = 1; - -/// A trait used to represent an interface to a task-local logger. Each task -/// can have its own custom logger which can respond to logging messages -/// however it likes. -pub trait Logger { - /// Logs a single message described by the `args` structure. The level is - /// provided in case you want to do things like color the message, etc. - fn log(&mut self, level: u32, args: &fmt::Arguments); -} - -struct DefaultLogger { - handle: LineBufferedWriter<io::stdio::StdWriter>, -} - -impl Logger for DefaultLogger { - // by default, just ignore the level - fn log(&mut self, _level: u32, args: &fmt::Arguments) { - match fmt::writeln(&mut self.handle, args) { - Err(e) => fail!("failed to log: {}", e), - Ok(()) => {} - } - } -} - -impl Drop for DefaultLogger { - fn drop(&mut self) { - match self.handle.flush() { - Err(e) => fail!("failed to flush a logger: {}", e), - Ok(()) => {} - } - } -} - -/// This function is called directly by the compiler when using the logging -/// macros. This function does not take into account whether the log level -/// specified is active or not, it will always log something if this method is -/// called. -/// -/// It is not recommended to call this function directly, rather it should be -/// invoked through the logging family of macros. -pub fn log(level: u32, args: &fmt::Arguments) { - // See io::stdio::with_task_stdout for why there's a few dances here. The - // gist of it is that arbitrary code can run during logging (and set an - // arbitrary logging handle into the task) so we need to be careful that the - // local task is in TLS while we're running arbitrary code. - let mut logger = { - let mut task = Local::borrow(None::<Task>); - task.get().logger.take() - }; - - if logger.is_none() { - logger = Some(~DefaultLogger { handle: io::stderr(), } as ~Logger); - } - logger.get_mut_ref().log(level, args); - - let mut task = Local::borrow(None::<Task>); - let prev = replace(&mut task.get().logger, logger); - drop(task); - drop(prev); -} - -/// Replaces the task-local logger with the specified logger, returning the old -/// logger. -pub fn set_logger(logger: ~Logger) -> Option<~Logger> { - let mut task = Local::borrow(None::<Task>); - replace(&mut task.get().logger, Some(logger)) -} diff --git a/src/libstd/macros.rs b/src/libstd/macros.rs index ece9c1bfd20..6d96ea94d31 100644 --- a/src/libstd/macros.rs +++ b/src/libstd/macros.rs @@ -16,107 +16,6 @@ #[macro_escape]; -/// The standard logging macro -/// -/// This macro will generically log over a provided level (of type u32) with a -/// format!-based argument list. See documentation in `std::fmt` for details on -/// how to use the syntax, and documentation in `std::logging` for info about -/// logging macros. -/// -/// # Example -/// -/// ``` -/// log!(::std::logging::DEBUG, "this is a debug message"); -/// log!(::std::logging::WARN, "this is a warning {}", "message"); -/// log!(6, "this is a custom logging level: {level}", level=6); -/// ``` -#[macro_export] -macro_rules! log( - ($lvl:expr, $($arg:tt)+) => ({ - let lvl = $lvl; - if lvl <= __log_level() { - format_args!(|args| { - ::std::logging::log(lvl, args) - }, $($arg)+) - } - }) -) - -/// A convenience macro for logging at the error log level. See `std::logging` -/// for more information. about logging. -/// -/// # Example -/// -/// ``` -/// # let error = 3; -/// error!("the build has failed with error code: {}", error); -/// ``` -#[macro_export] -macro_rules! error( - ($($arg:tt)*) => (log!(1u32, $($arg)*)) -) - -/// A convenience macro for logging at the warning log level. See `std::logging` -/// for more information. about logging. -/// -/// # Example -/// -/// ``` -/// # let code = 3; -/// warn!("you may like to know that a process exited with: {}", code); -/// ``` -#[macro_export] -macro_rules! warn( - ($($arg:tt)*) => (log!(2u32, $($arg)*)) -) - -/// A convenience macro for logging at the info log level. See `std::logging` -/// for more information. about logging. -/// -/// # Example -/// -/// ``` -/// # let ret = 3; -/// info!("this function is about to return: {}", ret); -/// ``` -#[macro_export] -macro_rules! info( - ($($arg:tt)*) => (log!(3u32, $($arg)*)) -) - -/// A convenience macro for logging at the debug log level. See `std::logging` -/// for more information. about logging. -/// -/// # Example -/// -/// ``` -/// debug!("x = {x}, y = {y}", x=10, y=20); -/// ``` -#[macro_export] -macro_rules! debug( - ($($arg:tt)*) => (if cfg!(not(ndebug)) { log!(4u32, $($arg)*) }) -) - -/// A macro to test whether a log level is enabled for the current module. -/// -/// # Example -/// -/// ``` -/// # struct Point { x: int, y: int } -/// # fn some_expensive_computation() -> Point { Point { x: 1, y: 2 } } -/// if log_enabled!(std::logging::DEBUG) { -/// let x = some_expensive_computation(); -/// debug!("x.x = {}, x.y = {}", x.x, x.y); -/// } -/// ``` -#[macro_export] -macro_rules! log_enabled( - ($lvl:expr) => ({ - let lvl = $lvl; - lvl <= __log_level() && (lvl != 4 || cfg!(not(ndebug))) - }) -) - /// The entry point for failure of rust tasks. /// /// This macro is used to inject failure into a rust task, causing the task to @@ -421,3 +320,15 @@ macro_rules! select { { unreachable!() } }) } + +// When testing the standard library, we link to the liblog crate to get the +// logging macros. In doing so, the liblog crate was linked against the real +// version of libstd, and uses a different std::fmt module than the test crate +// uses. To get around this difference, we redefine the log!() macro here to be +// just a dumb version of what it should be. +#[cfg(test)] +macro_rules! log ( + ($lvl:expr, $($args:tt)*) => ( + if log_enabled!($lvl) { println!($($args)*) } + ) +) diff --git a/src/libstd/os.rs b/src/libstd/os.rs index b8f00d1b692..040d5c0e175 100644 --- a/src/libstd/os.rs +++ b/src/libstd/os.rs @@ -1127,14 +1127,8 @@ impl Drop for MemoryMap { if self.len == 0 { /* workaround for dummy_stack */ return; } unsafe { - match libc::munmap(self.data as *c_void, self.len as libc::size_t) { - 0 => (), - -1 => match errno() as c_int { - libc::EINVAL => error!("invalid addr or len"), - e => error!("unknown errno={}", e) - }, - r => error!("Unexpected result {}", r) - } + // FIXME: what to do if this fails? + let _ = libc::munmap(self.data as *c_void, self.len as libc::size_t); } } } @@ -1161,10 +1155,7 @@ impl MemoryMap { MapAddr(addr_) => { lpAddress = addr_ as LPVOID; }, MapFd(fd_) => { fd = fd_; }, MapOffset(offset_) => { offset = offset_; }, - MapNonStandardFlags(f) => { - info!("MemoryMap::new: MapNonStandardFlags used on \ - Windows: {}", f) - } + MapNonStandardFlags(..) => {} } } @@ -1262,15 +1253,15 @@ impl Drop for MemoryMap { MapVirtual => { if libc::VirtualFree(self.data as *mut c_void, 0, libc::MEM_RELEASE) == 0 { - error!("VirtualFree failed: {}", errno()); + println!("VirtualFree failed: {}", errno()); } }, MapFile(mapping) => { if libc::UnmapViewOfFile(self.data as LPCVOID) == FALSE { - error!("UnmapViewOfFile failed: {}", errno()); + println!("UnmapViewOfFile failed: {}", errno()); } if libc::CloseHandle(mapping as HANDLE) == FALSE { - error!("CloseHandle failed: {}", errno()); + println!("CloseHandle failed: {}", errno()); } } } diff --git a/src/libstd/ptr.rs b/src/libstd/ptr.rs index 95eda1cecc0..bf5ba6db5c3 100644 --- a/src/libstd/ptr.rs +++ b/src/libstd/ptr.rs @@ -163,7 +163,6 @@ pub unsafe fn read_and_zero<T>(dest: *mut T) -> T { SAFETY NOTE: Pointer-arithmetic. Dragons be here. */ pub unsafe fn array_each_with_len<T>(arr: **T, len: uint, cb: |*T|) { - debug!("array_each_with_len: before iterate"); if arr.is_null() { fail!("ptr::array_each_with_len failure: arr input is null pointer"); } @@ -172,7 +171,6 @@ pub unsafe fn array_each_with_len<T>(arr: **T, len: uint, cb: |*T|) { let n = arr.offset(e as int); cb(*n); } - debug!("array_each_with_len: after iterate"); } /** @@ -189,7 +187,6 @@ pub unsafe fn array_each<T>(arr: **T, cb: |*T|) { fail!("ptr::array_each_with_len failure: arr input is null pointer"); } let len = buf_len(arr); - debug!("array_each inferred len: {}", len); array_each_with_len(arr, len, cb); } 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() } } diff --git a/src/libstd/task.rs b/src/libstd/task.rs index 19f41c6fa1c..9c88db6beb5 100644 --- a/src/libstd/task.rs +++ b/src/libstd/task.rs @@ -40,7 +40,6 @@ use any::Any; use comm::{Sender, Receiver, channel}; use io::Writer; use kinds::{Send, marker}; -use logging::Logger; use option::{None, Some, Option}; use result::{Result, Ok, Err}; use rt::local::Local; @@ -66,8 +65,6 @@ pub struct TaskOpts { name: Option<SendStr>, /// The size of the stack for the spawned task stack_size: Option<uint>, - /// Task-local logger (see std::logging) - logger: Option<~Logger>, /// Task-local stdout stdout: Option<~Writer>, /// Task-local stderr @@ -230,7 +227,6 @@ impl TaskOpts { notify_chan: None, name: None, stack_size: None, - logger: None, stdout: None, stderr: None, } |
