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.
This commit is contained in:
commit
f6fcdbb687
11
mk/crates.mk
11
mk/crates.mk
@ -51,7 +51,7 @@
|
||||
|
||||
TARGET_CRATES := std green rustuv native flate arena glob term semver \
|
||||
uuid serialize sync getopts collections num test time rand \
|
||||
workcache url
|
||||
workcache url log
|
||||
HOST_CRATES := syntax rustc rustdoc fourcc hexfloat
|
||||
CRATES := $(TARGET_CRATES) $(HOST_CRATES)
|
||||
TOOLS := compiletest rustdoc rustc
|
||||
@ -60,15 +60,15 @@ DEPS_std := native:rustrt native:compiler-rt native:backtrace
|
||||
DEPS_green := std rand native:context_switch
|
||||
DEPS_rustuv := std native:uv native:uv_support
|
||||
DEPS_native := std
|
||||
DEPS_syntax := std term serialize collections
|
||||
DEPS_syntax := std term serialize collections log
|
||||
DEPS_rustc := syntax native:rustllvm flate arena serialize sync getopts \
|
||||
collections time
|
||||
collections time log
|
||||
DEPS_rustdoc := rustc native:sundown serialize sync getopts collections \
|
||||
test time
|
||||
DEPS_flate := std native:miniz
|
||||
DEPS_arena := std collections
|
||||
DEPS_glob := std
|
||||
DEPS_serialize := std collections
|
||||
DEPS_serialize := std collections log
|
||||
DEPS_term := std collections
|
||||
DEPS_semver := std
|
||||
DEPS_uuid := std serialize rand
|
||||
@ -82,7 +82,8 @@ DEPS_test := std collections getopts serialize term time
|
||||
DEPS_time := std serialize
|
||||
DEPS_rand := std
|
||||
DEPS_url := std collections
|
||||
DEPS_workcache := std serialize collections std
|
||||
DEPS_workcache := std serialize collections log
|
||||
DEPS_log := std sync
|
||||
|
||||
TOOL_DEPS_compiletest := test green rustuv getopts
|
||||
TOOL_DEPS_rustdoc := rustdoc native
|
||||
|
@ -9,6 +9,7 @@
|
||||
// except according to those terms.
|
||||
|
||||
#[crate_type = "bin"];
|
||||
#[feature(phase)];
|
||||
|
||||
#[allow(non_camel_case_types)];
|
||||
#[deny(warnings)];
|
||||
@ -16,6 +17,8 @@
|
||||
|
||||
extern crate test;
|
||||
extern crate getopts;
|
||||
#[phase(link, syntax)]
|
||||
extern crate log;
|
||||
|
||||
use std::os;
|
||||
use std::io;
|
||||
|
@ -51,6 +51,7 @@ li {list-style-type: none; }
|
||||
* [The `uuid` 128-bit universally unique identifier library](uuid/index.html)
|
||||
* [The `url` library](url/index.html)
|
||||
* [The `workcache` library](workcache/index.html)
|
||||
* [The `log` library](log/index.html)
|
||||
|
||||
# Tooling
|
||||
|
||||
|
@ -1055,7 +1055,7 @@ output slot type would normally be. For example:
|
||||
|
||||
~~~~
|
||||
fn my_err(s: &str) -> ! {
|
||||
info!("{}", s);
|
||||
println!("{}", s);
|
||||
fail!();
|
||||
}
|
||||
~~~~
|
||||
@ -3885,6 +3885,9 @@ Rust provides several macros to log information. Here's a simple Rust program
|
||||
that demonstrates all four of them:
|
||||
|
||||
~~~~
|
||||
#[feature(phase)];
|
||||
#[phase(syntax, link)] extern crate log;
|
||||
|
||||
fn main() {
|
||||
error!("This is an error log")
|
||||
warn!("This is a warn log")
|
||||
|
@ -796,7 +796,7 @@ unit, `()`, as the empty tuple if you like).
|
||||
~~~~
|
||||
let mytup: (int, int, f64) = (10, 20, 30.0);
|
||||
match mytup {
|
||||
(a, b, c) => info!("{}", a + b + (c as int))
|
||||
(a, b, c) => println!("{}", a + b + (c as int))
|
||||
}
|
||||
~~~~
|
||||
|
||||
@ -813,7 +813,7 @@ For example:
|
||||
struct MyTup(int, int, f64);
|
||||
let mytup: MyTup = MyTup(10, 20, 30.0);
|
||||
match mytup {
|
||||
MyTup(a, b, c) => info!("{}", a + b + (c as int))
|
||||
MyTup(a, b, c) => println!("{}", a + b + (c as int))
|
||||
}
|
||||
~~~~
|
||||
|
||||
@ -1794,7 +1794,7 @@ use std::task::spawn;
|
||||
|
||||
// proc is the closure which will be spawned.
|
||||
spawn(proc() {
|
||||
debug!("I'm a new task")
|
||||
println!("I'm a new task")
|
||||
});
|
||||
~~~~
|
||||
|
||||
|
@ -20,7 +20,7 @@
|
||||
html_favicon_url = "http://www.rust-lang.org/favicon.ico",
|
||||
html_root_url = "http://static.rust-lang.org/doc/master")];
|
||||
|
||||
#[feature(macro_rules, managed_boxes, default_type_params)];
|
||||
#[feature(macro_rules, managed_boxes, default_type_params, phase)];
|
||||
|
||||
// NOTE remove the following two attributes after the next snapshot.
|
||||
#[allow(unrecognized_lint)];
|
||||
@ -30,6 +30,7 @@
|
||||
extern crate rand;
|
||||
|
||||
#[cfg(test)] extern crate test;
|
||||
#[cfg(test)] #[phase(syntax, link)] extern crate log;
|
||||
|
||||
pub use bitv::Bitv;
|
||||
pub use btree::BTree;
|
||||
|
@ -21,6 +21,9 @@ Simple compression
|
||||
#[doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
|
||||
html_favicon_url = "http://www.rust-lang.org/favicon.ico",
|
||||
html_root_url = "http://static.rust-lang.org/doc/master")];
|
||||
#[feature(phase)];
|
||||
|
||||
#[cfg(test)] #[phase(syntax, link)] extern crate log;
|
||||
|
||||
use std::libc::{c_void, size_t, c_int};
|
||||
use std::libc;
|
||||
|
@ -86,7 +86,9 @@
|
||||
#[allow(missing_doc)];
|
||||
#[allow(deprecated_owned_vector)];
|
||||
|
||||
#[feature(globs)];
|
||||
#[feature(globs, phase)];
|
||||
|
||||
#[cfg(test)] #[phase(syntax, link)] extern crate log;
|
||||
|
||||
use std::cmp::Eq;
|
||||
use std::result::{Err, Ok};
|
||||
|
@ -172,10 +172,11 @@
|
||||
html_root_url = "http://static.rust-lang.org/doc/master")];
|
||||
|
||||
// NB this does *not* include globs, please keep it that way.
|
||||
#[feature(macro_rules)];
|
||||
#[feature(macro_rules, phase)];
|
||||
#[allow(visible_private_types)];
|
||||
#[allow(deprecated_owned_vector)];
|
||||
|
||||
#[cfg(test)] #[phase(syntax, link)] extern crate log;
|
||||
extern crate rand;
|
||||
|
||||
use std::mem::replace;
|
||||
|
@ -178,14 +178,13 @@ impl GreenTask {
|
||||
f: proc()) -> ~GreenTask {
|
||||
let TaskOpts {
|
||||
notify_chan, name, stack_size,
|
||||
stderr, stdout, logger,
|
||||
stderr, stdout,
|
||||
} = opts;
|
||||
|
||||
let mut green = GreenTask::new(pool, stack_size, f);
|
||||
{
|
||||
let task = green.task.get_mut_ref();
|
||||
task.name = name;
|
||||
task.logger = logger;
|
||||
task.stderr = stderr;
|
||||
task.stdout = stdout;
|
||||
match notify_chan {
|
||||
|
134
src/liblog/directive.rs
Normal file
134
src/liblog/directive.rs
Normal file
@ -0,0 +1,134 @@
|
||||
// Copyright 2014 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 std::cmp;
|
||||
use std::vec_ng::Vec;
|
||||
|
||||
#[deriving(Show, Clone)]
|
||||
pub struct LogDirective {
|
||||
name: Option<~str>,
|
||||
level: u32,
|
||||
}
|
||||
|
||||
static LOG_LEVEL_NAMES: [&'static str, ..4] = ["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> {
|
||||
from_str::<u32>(level).or_else(|| {
|
||||
let pos = LOG_LEVEL_NAMES.iter().position(|&name| name == level);
|
||||
pos.map(|p| p as u32 + 1)
|
||||
}).map(|p| cmp::min(p, ::MAX_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
|
||||
pub fn parse_logging_spec(spec: &str) -> Vec<LogDirective> {
|
||||
let mut dirs = Vec::new();
|
||||
for s in spec.split(',') {
|
||||
if s.len() == 0 { continue }
|
||||
let mut parts = s.split('=');
|
||||
let (log_level, 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
|
||||
match parse_log_level(part0) {
|
||||
Some(num) => (num, None),
|
||||
None => (::MAX_LOG_LEVEL, Some(part0)),
|
||||
}
|
||||
}
|
||||
(Some(part0), Some(part1), None) => {
|
||||
match parse_log_level(part1) {
|
||||
Some(num) => (num, Some(part0)),
|
||||
_ => {
|
||||
println!("warning: invalid logging spec '{}', \
|
||||
ignoring it", part1);
|
||||
continue
|
||||
}
|
||||
}
|
||||
},
|
||||
_ => {
|
||||
println!("warning: invalid logging spec '{}', \
|
||||
ignoring it", s);
|
||||
continue
|
||||
}
|
||||
};
|
||||
dirs.push(LogDirective {
|
||||
name: name.map(|s| s.to_owned()),
|
||||
level: log_level,
|
||||
});
|
||||
}
|
||||
return dirs;
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::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, ::WARN);
|
||||
}
|
||||
|
||||
#[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);
|
||||
}
|
||||
}
|
355
src/liblog/lib.rs
Normal file
355
src/liblog/lib.rs
Normal file
@ -0,0 +1,355 @@
|
||||
// Copyright 2015 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
|
||||
|
||||
## Example
|
||||
|
||||
```
|
||||
#[feature(phase)];
|
||||
#[phase(syntax, link)] extern crate log;
|
||||
|
||||
fn main() {
|
||||
debug!("this is a debug {}", "message");
|
||||
error!("this is printed by default");
|
||||
|
||||
if log_enabled!(log::INFO) {
|
||||
let x = 3 * 4; // expensive computation
|
||||
info!("the answer was: {}", x);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Logging Macros
|
||||
|
||||
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 std::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 std::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:
|
||||
|
||||
```notrust
|
||||
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 std::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:
|
||||
|
||||
```notrust
|
||||
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() {
|
||||
::log::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.
|
||||
|
||||
*/
|
||||
|
||||
#[crate_id = "log#0.10-pre"];
|
||||
#[license = "MIT/ASL2"];
|
||||
#[crate_type = "rlib"];
|
||||
#[crate_type = "dylib"];
|
||||
#[doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
|
||||
html_favicon_url = "http://www.rust-lang.org/favicon.ico",
|
||||
html_root_url = "http://static.rust-lang.org/doc/master")];
|
||||
|
||||
#[feature(macro_rules)];
|
||||
#[deny(missing_doc)];
|
||||
|
||||
extern crate sync;
|
||||
|
||||
use std::cast;
|
||||
use std::fmt;
|
||||
use std::io::LineBufferedWriter;
|
||||
use std::io;
|
||||
use std::local_data;
|
||||
use std::os;
|
||||
use std::rt;
|
||||
use std::vec;
|
||||
use std::vec_ng::Vec;
|
||||
|
||||
use sync::one::{Once, ONCE_INIT};
|
||||
|
||||
pub mod macros;
|
||||
mod directive;
|
||||
|
||||
/// Maximum logging level of a module that can be specified. Common logging
|
||||
/// levels are found in the DEBUG/INFO/WARN/ERROR constants.
|
||||
pub static MAX_LOG_LEVEL: u32 = 255;
|
||||
|
||||
/// The default logging level of a crate if no other is specified.
|
||||
static DEFAULT_LOG_LEVEL: u32 = 1;
|
||||
|
||||
/// An unsafe constant that is the maximum logging level of any module
|
||||
/// specified. This is the first line of defense to determining whether a
|
||||
/// logging statement should be run.
|
||||
static mut LOG_LEVEL: u32 = MAX_LOG_LEVEL;
|
||||
|
||||
static mut DIRECTIVES: *Vec<directive::LogDirective> =
|
||||
0 as *Vec<directive::LogDirective>;
|
||||
|
||||
/// 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;
|
||||
|
||||
local_data_key!(local_logger: ~Logger)
|
||||
|
||||
/// 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) {
|
||||
// FIXME(#12628): is failure the right thing to do?
|
||||
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) {
|
||||
// Completely remove the local logger from TLS in case anyone attempts to
|
||||
// frob the slot while we're doing the logging. This will destroy any logger
|
||||
// set during logging.
|
||||
let mut logger = local_data::pop(local_logger).unwrap_or_else(|| {
|
||||
~DefaultLogger { handle: io::stderr() } as ~Logger
|
||||
});
|
||||
logger.log(level, args);
|
||||
local_data::set(local_logger, logger);
|
||||
}
|
||||
|
||||
/// Getter for the global log level. This is a function so that it can be called
|
||||
/// safely
|
||||
#[doc(hidden)]
|
||||
#[inline(always)]
|
||||
pub fn log_level() -> u32 { unsafe { LOG_LEVEL } }
|
||||
|
||||
/// Replaces the task-local logger with the specified logger, returning the old
|
||||
/// logger.
|
||||
pub fn set_logger(logger: ~Logger) -> Option<~Logger> {
|
||||
let prev = local_data::pop(local_logger);
|
||||
local_data::set(local_logger, logger);
|
||||
return prev;
|
||||
}
|
||||
|
||||
/// Tests whether a given module's name is enabled for a particular level of
|
||||
/// logging. This is the second layer of defense about determining whether a
|
||||
/// module's log statement should be emitted or not.
|
||||
#[doc(hidden)]
|
||||
pub fn mod_enabled(level: u32, module: &str) -> bool {
|
||||
static mut INIT: Once = ONCE_INIT;
|
||||
unsafe { INIT.doit(init); }
|
||||
|
||||
// It's possible for many threads are in this function, only one of them
|
||||
// will peform the global initialization, but all of them will need to check
|
||||
// again to whether they should really be here or not. Hence, despite this
|
||||
// check being expanded manually in the logging macro, this function checks
|
||||
// the log level again.
|
||||
if level > unsafe { LOG_LEVEL } { return false }
|
||||
|
||||
// This assertion should never get tripped unless we're in an at_exit
|
||||
// handler after logging has been torn down and a logging attempt was made.
|
||||
assert!(unsafe { !DIRECTIVES.is_null() });
|
||||
|
||||
enabled(level, module, unsafe { (*DIRECTIVES).iter() })
|
||||
}
|
||||
|
||||
fn enabled(level: u32, module: &str,
|
||||
iter: vec::Items<directive::LogDirective>) -> bool {
|
||||
// Search for the longest match, the vector is assumed to be pre-sorted.
|
||||
for directive in iter.rev() {
|
||||
match directive.name {
|
||||
Some(ref name) if !module.starts_with(*name) => {},
|
||||
Some(..) | None => {
|
||||
return level <= directive.level
|
||||
}
|
||||
}
|
||||
}
|
||||
level <= DEFAULT_LOG_LEVEL
|
||||
}
|
||||
|
||||
/// Initialize logging for the current process.
|
||||
///
|
||||
/// This is not threadsafe at all, so initialization os performed through a
|
||||
/// `Once` primitive (and this function is called from that primitive).
|
||||
fn init() {
|
||||
let mut directives = match os::getenv("RUST_LOG") {
|
||||
Some(spec) => directive::parse_logging_spec(spec),
|
||||
None => Vec::new(),
|
||||
};
|
||||
|
||||
// Sort the provided directives by length of their name, this allows a
|
||||
// little more efficient lookup at runtime.
|
||||
directives.sort_by(|a, b| {
|
||||
let alen = a.name.as_ref().map(|a| a.len()).unwrap_or(0);
|
||||
let blen = b.name.as_ref().map(|b| b.len()).unwrap_or(0);
|
||||
alen.cmp(&blen)
|
||||
});
|
||||
|
||||
let max_level = {
|
||||
let max = directives.iter().max_by(|d| d.level);
|
||||
max.map(|d| d.level).unwrap_or(DEFAULT_LOG_LEVEL)
|
||||
};
|
||||
|
||||
unsafe {
|
||||
LOG_LEVEL = max_level;
|
||||
|
||||
assert!(DIRECTIVES.is_null());
|
||||
DIRECTIVES = cast::transmute(~directives);
|
||||
|
||||
// Schedule the cleanup for this global for when the runtime exits.
|
||||
rt::at_exit(proc() {
|
||||
assert!(!DIRECTIVES.is_null());
|
||||
let _directives: ~Vec<directive::LogDirective> =
|
||||
cast::transmute(DIRECTIVES);
|
||||
DIRECTIVES = 0 as *Vec<directive::LogDirective>;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::enabled;
|
||||
use directive::LogDirective;
|
||||
|
||||
#[test]
|
||||
fn match_full_path() {
|
||||
let dirs = [LogDirective { name: Some(~"crate2"), level: 3 },
|
||||
LogDirective { name: Some(~"crate1::mod1"), level: 2 }];
|
||||
assert!(enabled(2, "crate1::mod1", dirs.iter()));
|
||||
assert!(!enabled(3, "crate1::mod1", dirs.iter()));
|
||||
assert!(enabled(3, "crate2", dirs.iter()));
|
||||
assert!(!enabled(4, "crate2", dirs.iter()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn no_match() {
|
||||
let dirs = [LogDirective { name: Some(~"crate2"), level: 3 },
|
||||
LogDirective { name: Some(~"crate1::mod1"), level: 2 }];
|
||||
assert!(!enabled(2, "crate3", dirs.iter()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn match_beginning() {
|
||||
let dirs = [LogDirective { name: Some(~"crate2"), level: 3 },
|
||||
LogDirective { name: Some(~"crate1::mod1"), level: 2 }];
|
||||
assert!(enabled(3, "crate2::mod1", dirs.iter()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn match_beginning_longest_match() {
|
||||
let dirs = [LogDirective { name: Some(~"crate2"), level: 3 },
|
||||
LogDirective { name: Some(~"crate2::mod"), level: 4 },
|
||||
LogDirective { name: Some(~"crate1::mod1"), level: 2 }];
|
||||
assert!(enabled(4, "crate2::mod1", dirs.iter()));
|
||||
assert!(!enabled(4, "crate2", dirs.iter()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn match_default() {
|
||||
let dirs = [LogDirective { name: None, level: 3 },
|
||||
LogDirective { name: Some(~"crate1::mod1"), level: 2 }];
|
||||
assert!(enabled(2, "crate1::mod1", dirs.iter()));
|
||||
assert!(enabled(3, "crate2::mod2", dirs.iter()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn zero_level() {
|
||||
let dirs = [LogDirective { name: None, level: 3 },
|
||||
LogDirective { name: Some(~"crate1::mod1"), level: 0 }];
|
||||
assert!(!enabled(1, "crate1::mod1", dirs.iter()));
|
||||
assert!(enabled(3, "crate2::mod2", dirs.iter()));
|
||||
}
|
||||
}
|
141
src/liblog/macros.rs
Normal file
141
src/liblog/macros.rs
Normal file
@ -0,0 +1,141 @@
|
||||
// Copyright 2014 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.
|
||||
|
||||
//! Logging macros
|
||||
|
||||
#[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.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// #[feature(phase)];
|
||||
/// #[phase(syntax, link)] extern crate log;
|
||||
///
|
||||
/// # fn main() {
|
||||
/// log!(log::DEBUG, "this is a debug message");
|
||||
/// log!(log::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 log_enabled!(lvl) {
|
||||
format_args!(|args| { ::log::log(lvl, args) }, $($arg)+)
|
||||
}
|
||||
})
|
||||
)
|
||||
|
||||
/// A convenience macro for logging at the error log level.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// #[feature(phase)];
|
||||
/// #[phase(syntax, link)] extern crate log;
|
||||
///
|
||||
/// # fn main() {
|
||||
/// # let error = 3;
|
||||
/// error!("the build has failed with error code: {}", error);
|
||||
/// # }
|
||||
/// ```
|
||||
#[macro_export]
|
||||
macro_rules! error(
|
||||
($($arg:tt)*) => (log!(::log::ERROR, $($arg)*))
|
||||
)
|
||||
|
||||
/// A convenience macro for logging at the warning log level.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// #[feature(phase)];
|
||||
/// #[phase(syntax, link)] extern crate log;
|
||||
///
|
||||
/// # fn main() {
|
||||
/// # let code = 3;
|
||||
/// warn!("you may like to know that a process exited with: {}", code);
|
||||
/// # }
|
||||
/// ```
|
||||
#[macro_export]
|
||||
macro_rules! warn(
|
||||
($($arg:tt)*) => (log!(::log::WARN, $($arg)*))
|
||||
)
|
||||
|
||||
/// A convenience macro for logging at the info log level.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// #[feature(phase)];
|
||||
/// #[phase(syntax, link)] extern crate log;
|
||||
///
|
||||
/// # fn main() {
|
||||
/// # let ret = 3;
|
||||
/// info!("this function is about to return: {}", ret);
|
||||
/// # }
|
||||
/// ```
|
||||
#[macro_export]
|
||||
macro_rules! info(
|
||||
($($arg:tt)*) => (log!(::log::INFO, $($arg)*))
|
||||
)
|
||||
|
||||
/// A convenience macro for logging at the debug log level. This macro can also
|
||||
/// be omitted at compile time by passing `--cfg ndebug` to the compiler. If
|
||||
/// this option is not passed, then debug statements will be compiled.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// #[feature(phase)];
|
||||
/// #[phase(syntax, link)] extern crate log;
|
||||
///
|
||||
/// # fn main() {
|
||||
/// debug!("x = {x}, y = {y}", x=10, y=20);
|
||||
/// # }
|
||||
/// ```
|
||||
#[macro_export]
|
||||
macro_rules! debug(
|
||||
($($arg:tt)*) => (if cfg!(not(ndebug)) { log!(::log::DEBUG, $($arg)*) })
|
||||
)
|
||||
|
||||
/// A macro to test whether a log level is enabled for the current module.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// #[feature(phase)];
|
||||
/// #[phase(syntax, link)] extern crate log;
|
||||
///
|
||||
/// # fn main() {
|
||||
/// # struct Point { x: int, y: int }
|
||||
/// # fn some_expensive_computation() -> Point { Point { x: 1, y: 2 } }
|
||||
/// if log_enabled!(log::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::DEBUG || cfg!(not(ndebug))) &&
|
||||
lvl <= ::log::log_level() &&
|
||||
::log::mod_enabled(lvl, module_path!())
|
||||
})
|
||||
)
|
@ -209,7 +209,8 @@ impl Drop for Inner {
|
||||
if self.close_on_drop && self.fd > libc::STDERR_FILENO {
|
||||
let n = unsafe { libc::close(self.fd) };
|
||||
if n != 0 {
|
||||
warn!("error {} when closing file descriptor {}", n, self.fd);
|
||||
println!("error {} when closing file descriptor {}", n,
|
||||
self.fd);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -362,13 +363,10 @@ pub fn readdir(p: &CString) -> IoResult<~[Path]> {
|
||||
let mut buf = Vec::<u8>::with_capacity(size as uint);
|
||||
let ptr = buf.as_mut_slice().as_mut_ptr() as *mut dirent_t;
|
||||
|
||||
debug!("os::list_dir -- BEFORE OPENDIR");
|
||||
|
||||
let dir_ptr = p.with_ref(|buf| unsafe { opendir(buf) });
|
||||
|
||||
if dir_ptr as uint != 0 {
|
||||
let mut paths = ~[];
|
||||
debug!("os::list_dir -- opendir() SUCCESS");
|
||||
let mut entry_ptr = 0 as *mut dirent_t;
|
||||
while unsafe { readdir_r(dir_ptr, ptr, &mut entry_ptr) == 0 } {
|
||||
if entry_ptr.is_null() { break }
|
||||
|
@ -238,7 +238,7 @@ impl Drop for Inner {
|
||||
if self.close_on_drop && self.fd > libc::STDERR_FILENO {
|
||||
let n = unsafe { libc::close(self.fd) };
|
||||
if n != 0 {
|
||||
warn!("error {} when closing file descriptor {}", n, self.fd);
|
||||
println!("error {} when closing file descriptor {}", n, self.fd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -112,10 +112,7 @@ fn translate_error(errno: i32, detail: bool) -> IoError {
|
||||
libc::ERROR_INVALID_FUNCTION => (io::InvalidInput,
|
||||
"illegal operation on a directory"),
|
||||
|
||||
x => {
|
||||
debug!("ignoring {}: {}", x, os::last_os_error());
|
||||
(io::OtherIoError, "unknown error")
|
||||
}
|
||||
_ => (io::OtherIoError, "unknown error")
|
||||
}
|
||||
}
|
||||
|
||||
@ -141,10 +138,7 @@ fn translate_error(errno: i32, detail: bool) -> IoError {
|
||||
x if x == libc::EAGAIN || x == libc::EWOULDBLOCK =>
|
||||
(io::ResourceUnavailable, "resource temporarily unavailable"),
|
||||
|
||||
x => {
|
||||
debug!("ignoring {}: {}", x, os::last_os_error());
|
||||
(io::OtherIoError, "unknown error")
|
||||
}
|
||||
_ => (io::OtherIoError, "unknown error")
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -89,10 +89,8 @@ fn helper(input: libc::c_int, messages: Receiver<Req>) {
|
||||
};
|
||||
|
||||
let mut incoming = false;
|
||||
debug!("{} events to process", n);
|
||||
for event in events.slice_to(n as uint).iter() {
|
||||
let fd = event.data as libc::c_int;
|
||||
debug!("data on fd {} (input = {})", fd, input);
|
||||
if fd == input {
|
||||
let mut buf = [0, ..1];
|
||||
// drain the input file descriptor of its input
|
||||
|
@ -59,12 +59,11 @@ pub fn spawn(f: proc()) {
|
||||
pub fn spawn_opts(opts: TaskOpts, f: proc()) {
|
||||
let TaskOpts {
|
||||
notify_chan, name, stack_size,
|
||||
logger, stderr, stdout,
|
||||
stderr, stdout,
|
||||
} = opts;
|
||||
|
||||
let mut task = ~Task::new();
|
||||
task.name = name;
|
||||
task.logger = logger;
|
||||
task.stderr = stderr;
|
||||
task.stdout = stdout;
|
||||
match notify_chan {
|
||||
|
@ -70,9 +70,12 @@ println!("{:?}", tuple_ptr)
|
||||
html_favicon_url = "http://www.rust-lang.org/favicon.ico",
|
||||
html_root_url = "http://static.rust-lang.org/doc/master")];
|
||||
|
||||
#[feature(macro_rules, managed_boxes)];
|
||||
#[feature(macro_rules, managed_boxes, phase)];
|
||||
#[allow(deprecated_owned_vector)];
|
||||
|
||||
#[cfg(test)]
|
||||
#[phase(syntax, link)] extern crate log;
|
||||
|
||||
use std::cast;
|
||||
use std::kinds::marker;
|
||||
use std::local_data;
|
||||
|
@ -501,10 +501,9 @@ pub mod write {
|
||||
* system linkers understand.
|
||||
*/
|
||||
|
||||
pub fn find_crate_id(attrs: &[ast::Attribute],
|
||||
output: &OutputFilenames) -> CrateId {
|
||||
pub fn find_crate_id(attrs: &[ast::Attribute], out_filestem: &str) -> CrateId {
|
||||
match attr::find_crateid(attrs) {
|
||||
None => from_str(output.out_filestem).unwrap(),
|
||||
None => from_str(out_filestem).unwrap(),
|
||||
Some(s) => s,
|
||||
}
|
||||
}
|
||||
@ -518,10 +517,9 @@ pub fn crate_id_hash(crate_id: &CrateId) -> ~str {
|
||||
truncated_hash_result(&mut s).slice_to(8).to_owned()
|
||||
}
|
||||
|
||||
pub fn build_link_meta(krate: &ast::Crate,
|
||||
output: &OutputFilenames) -> LinkMeta {
|
||||
pub fn build_link_meta(krate: &ast::Crate, out_filestem: &str) -> LinkMeta {
|
||||
let r = LinkMeta {
|
||||
crateid: find_crate_id(krate.attrs.as_slice(), output),
|
||||
crateid: find_crate_id(krate.attrs.as_slice(), out_filestem),
|
||||
crate_hash: Svh::calculate(krate),
|
||||
};
|
||||
info!("{}", r);
|
||||
@ -1087,6 +1085,23 @@ fn link_args(sess: Session,
|
||||
~"-o", out_filename.as_str().unwrap().to_owned(),
|
||||
obj_filename.as_str().unwrap().to_owned()]);
|
||||
|
||||
// Stack growth requires statically linking a __morestack function. Note
|
||||
// that this is listed *before* all other libraries, even though it may be
|
||||
// used to resolve symbols in other libraries. The only case that this
|
||||
// wouldn't be pulled in by the object file is if the object file had no
|
||||
// functions.
|
||||
//
|
||||
// If we're building an executable, there must be at least one function (the
|
||||
// main function), and if we're building a dylib then we don't need it for
|
||||
// later libraries because they're all dylibs (not rlibs).
|
||||
//
|
||||
// I'm honestly not entirely sure why this needs to come first. Apparently
|
||||
// the --as-needed flag above sometimes strips out libstd from the command
|
||||
// line, but inserting this farther to the left makes the
|
||||
// "rust_stack_exhausted" symbol an outstanding undefined symbol, which
|
||||
// flags libstd as a required library (or whatever provides the symbol).
|
||||
args.push(~"-lmorestack");
|
||||
|
||||
// When linking a dynamic library, we put the metadata into a section of the
|
||||
// executable. This metadata is in a separate object file from the main
|
||||
// object file, so we link that in here.
|
||||
@ -1202,11 +1217,13 @@ fn link_args(sess: Session,
|
||||
args.push_all(rpath::get_rpath_flags(sess, out_filename).as_slice());
|
||||
}
|
||||
|
||||
// Stack growth requires statically linking a __morestack function
|
||||
args.push(~"-lmorestack");
|
||||
// compiler-rt contains implementations of low-level LLVM helpers
|
||||
// It should go before platform and user libraries, so it has first dibs
|
||||
// at resolving symbols that also appear in libgcc.
|
||||
// compiler-rt contains implementations of low-level LLVM helpers. This is
|
||||
// used to resolve symbols from the object file we just created, as well as
|
||||
// any system static libraries that may be expecting gcc instead. Most
|
||||
// symbols in libgcc also appear in compiler-rt.
|
||||
//
|
||||
// This is the end of the command line, so this library is used to resolve
|
||||
// *all* undefined symbols in all other libraries, and this is intentional.
|
||||
args.push(~"-lcompiler-rt");
|
||||
|
||||
// Finally add all the linker arguments provided on the command line along
|
||||
|
@ -46,6 +46,7 @@ use syntax::abi;
|
||||
use syntax::attr;
|
||||
use syntax::attr::{AttrMetaMethods};
|
||||
use syntax::codemap;
|
||||
use syntax::crateid::CrateId;
|
||||
use syntax::diagnostic;
|
||||
use syntax::diagnostic::Emitter;
|
||||
use syntax::ext::base::CrateLoader;
|
||||
@ -160,6 +161,15 @@ pub enum Input {
|
||||
StrInput(~str)
|
||||
}
|
||||
|
||||
impl Input {
|
||||
fn filestem(&self) -> ~str {
|
||||
match *self {
|
||||
FileInput(ref ifile) => ifile.filestem_str().unwrap().to_str(),
|
||||
StrInput(_) => ~"rust_out",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn phase_1_parse_input(sess: Session, cfg: ast::CrateConfig, input: &Input)
|
||||
-> ast::Crate {
|
||||
let krate = time(sess.time_passes(), "parsing", (), |_| {
|
||||
@ -182,6 +192,10 @@ pub fn phase_1_parse_input(sess: Session, cfg: ast::CrateConfig, input: &Input)
|
||||
krate.encode(&mut json);
|
||||
}
|
||||
|
||||
if sess.show_span() {
|
||||
front::show_span::run(sess, &krate);
|
||||
}
|
||||
|
||||
krate
|
||||
}
|
||||
|
||||
@ -194,7 +208,8 @@ pub fn phase_1_parse_input(sess: Session, cfg: ast::CrateConfig, input: &Input)
|
||||
/// standard library and prelude.
|
||||
pub fn phase_2_configure_and_expand(sess: Session,
|
||||
loader: &mut CrateLoader,
|
||||
mut krate: ast::Crate)
|
||||
mut krate: ast::Crate,
|
||||
crate_id: &CrateId)
|
||||
-> (ast::Crate, syntax::ast_map::Map) {
|
||||
let time_passes = sess.time_passes();
|
||||
|
||||
@ -223,7 +238,8 @@ pub fn phase_2_configure_and_expand(sess: Session,
|
||||
krate = time(time_passes, "expansion", krate, |krate| {
|
||||
let cfg = syntax::ext::expand::ExpansionConfig {
|
||||
loader: loader,
|
||||
deriving_hash_type_parameter: sess.features.default_type_params.get()
|
||||
deriving_hash_type_parameter: sess.features.default_type_params.get(),
|
||||
crate_id: crate_id.clone(),
|
||||
};
|
||||
syntax::ext::expand::expand_crate(sess.parse_sess,
|
||||
cfg,
|
||||
@ -461,6 +477,9 @@ pub fn stop_after_phase_1(sess: Session) -> bool {
|
||||
debug!("invoked with --parse-only, returning early from compile_input");
|
||||
return true;
|
||||
}
|
||||
if sess.show_span() {
|
||||
return true;
|
||||
}
|
||||
return sess.opts.debugging_opts & session::AST_JSON_NOEXPAND != 0;
|
||||
}
|
||||
|
||||
@ -484,7 +503,7 @@ fn write_out_deps(sess: Session,
|
||||
input: &Input,
|
||||
outputs: &OutputFilenames,
|
||||
krate: &ast::Crate) -> io::IoResult<()> {
|
||||
let id = link::find_crate_id(krate.attrs.as_slice(), outputs);
|
||||
let id = link::find_crate_id(krate.attrs.as_slice(), outputs.out_filestem);
|
||||
|
||||
let mut out_filenames = Vec::new();
|
||||
for output_type in sess.opts.output_types.iter() {
|
||||
@ -547,22 +566,21 @@ pub fn compile_input(sess: Session, cfg: ast::CrateConfig, input: &Input,
|
||||
// We need nested scopes here, because the intermediate results can keep
|
||||
// large chunks of memory alive and we want to free them as soon as
|
||||
// possible to keep the peak memory usage low
|
||||
let (outputs, trans) = {
|
||||
let outputs;
|
||||
let trans = {
|
||||
let (expanded_crate, ast_map) = {
|
||||
let krate = phase_1_parse_input(sess, cfg, input);
|
||||
if sess.show_span() {
|
||||
front::show_span::run(sess, &krate);
|
||||
return;
|
||||
}
|
||||
if stop_after_phase_1(sess) { return; }
|
||||
let loader = &mut Loader::new(sess);
|
||||
phase_2_configure_and_expand(sess, loader, krate)
|
||||
};
|
||||
let outputs = build_output_filenames(input,
|
||||
outputs = build_output_filenames(input,
|
||||
outdir,
|
||||
output,
|
||||
expanded_crate.attrs.as_slice(),
|
||||
krate.attrs.as_slice(),
|
||||
sess);
|
||||
let loader = &mut Loader::new(sess);
|
||||
let id = link::find_crate_id(krate.attrs.as_slice(),
|
||||
outputs.out_filestem);
|
||||
phase_2_configure_and_expand(sess, loader, krate, &id)
|
||||
};
|
||||
|
||||
write_out_deps(sess, input, &outputs, &expanded_crate).unwrap();
|
||||
|
||||
@ -570,9 +588,7 @@ pub fn compile_input(sess: Session, cfg: ast::CrateConfig, input: &Input,
|
||||
|
||||
let analysis = phase_3_run_analysis_passes(sess, &expanded_crate, ast_map);
|
||||
if stop_after_phase_3(sess) { return; }
|
||||
let trans = phase_4_translate_to_llvm(sess, expanded_crate,
|
||||
&analysis, &outputs);
|
||||
(outputs, trans)
|
||||
phase_4_translate_to_llvm(sess, expanded_crate, &analysis, &outputs)
|
||||
};
|
||||
phase_5_run_llvm_passes(sess, &trans, &outputs);
|
||||
if stop_after_phase_5(sess) { return; }
|
||||
@ -645,11 +661,13 @@ pub fn pretty_print_input(sess: Session,
|
||||
input: &Input,
|
||||
ppm: PpMode) {
|
||||
let krate = phase_1_parse_input(sess, cfg, input);
|
||||
let id = link::find_crate_id(krate.attrs.as_slice(), input.filestem());
|
||||
|
||||
let (krate, ast_map, is_expanded) = match ppm {
|
||||
PpmExpanded | PpmExpandedIdentified | PpmTyped => {
|
||||
let loader = &mut Loader::new(sess);
|
||||
let (krate, ast_map) = phase_2_configure_and_expand(sess, loader, krate);
|
||||
let (krate, ast_map) = phase_2_configure_and_expand(sess, loader,
|
||||
krate, &id);
|
||||
(krate, Some(ast_map), true)
|
||||
}
|
||||
_ => (krate, None, false)
|
||||
@ -1137,11 +1155,7 @@ pub fn build_output_filenames(input: &Input,
|
||||
None => Path::new(".")
|
||||
};
|
||||
|
||||
let mut stem = match *input {
|
||||
// FIXME (#9639): This needs to handle non-utf8 paths
|
||||
FileInput(ref ifile) => ifile.filestem_str().unwrap().to_str(),
|
||||
StrInput(_) => ~"rust_out"
|
||||
};
|
||||
let mut stem = input.filestem();
|
||||
|
||||
// If a crateid is present, we use it as the link name
|
||||
let crateid = attr::find_crateid(attrs);
|
||||
|
@ -170,6 +170,7 @@ fn generate_test_harness(sess: session::Session, krate: ast::Crate)
|
||||
ExpansionConfig {
|
||||
loader: loader,
|
||||
deriving_hash_type_parameter: false,
|
||||
crate_id: from_str("test").unwrap(),
|
||||
}),
|
||||
path: RefCell::new(Vec::new()),
|
||||
testfns: RefCell::new(Vec::new()),
|
||||
|
@ -30,7 +30,7 @@ This API is completely unstable and subject to change.
|
||||
#[allow(deprecated)];
|
||||
#[allow(deprecated_owned_vector)];
|
||||
#[feature(macro_rules, globs, struct_variant, managed_boxes)];
|
||||
#[feature(quote, default_type_params)];
|
||||
#[feature(quote, default_type_params, phase)];
|
||||
|
||||
extern crate flate;
|
||||
extern crate arena;
|
||||
@ -40,6 +40,8 @@ extern crate sync;
|
||||
extern crate getopts;
|
||||
extern crate collections;
|
||||
extern crate time;
|
||||
#[phase(syntax, link)]
|
||||
extern crate log;
|
||||
|
||||
use back::link;
|
||||
use driver::session;
|
||||
@ -318,7 +320,7 @@ pub fn run_compiler(args: &[~str]) {
|
||||
let attrs = parse_crate_attrs(sess, &input);
|
||||
let t_outputs = d::build_output_filenames(&input, &odir, &ofile,
|
||||
attrs.as_slice(), sess);
|
||||
let id = link::find_crate_id(attrs.as_slice(), &t_outputs);
|
||||
let id = link::find_crate_id(attrs.as_slice(), t_outputs.out_filestem);
|
||||
|
||||
if crate_id {
|
||||
println!("{}", id.to_str());
|
||||
@ -408,7 +410,7 @@ pub fn monitor(f: proc()) {
|
||||
let xs = [
|
||||
~"the compiler hit an unexpected failure path. this is a bug.",
|
||||
"we would appreciate a bug report: " + BUG_REPORT_URL,
|
||||
~"run with `RUST_LOG=std::rt::backtrace` for a backtrace",
|
||||
~"run with `RUST_BACKTRACE=1` for a backtrace",
|
||||
];
|
||||
for note in xs.iter() {
|
||||
emitter.emit(None, *note, diagnostic::Note)
|
||||
|
@ -143,16 +143,44 @@ impl CStore {
|
||||
self.used_link_args.with_mut(|s| s.clear());
|
||||
}
|
||||
|
||||
// This method is used when generating the command line to pass through to
|
||||
// system linker. The linker expects undefined symbols on the left of the
|
||||
// command line to be defined in libraries on the right, not the other way
|
||||
// around. For more info, see some comments in the add_used_library function
|
||||
// below.
|
||||
//
|
||||
// In order to get this left-to-right dependency ordering, we perform a
|
||||
// topological sort of all crates putting the leaves at the right-most
|
||||
// positions.
|
||||
pub fn get_used_crates(&self, prefer: LinkagePreference)
|
||||
-> Vec<(ast::CrateNum, Option<Path>)> {
|
||||
let mut ordering = Vec::new();
|
||||
fn visit(cstore: &CStore, cnum: ast::CrateNum,
|
||||
ordering: &mut Vec<ast::CrateNum>) {
|
||||
if ordering.as_slice().contains(&cnum) { return }
|
||||
let meta = cstore.get_crate_data(cnum);
|
||||
for (_, &dep) in meta.cnum_map.borrow().get().iter() {
|
||||
visit(cstore, dep, ordering);
|
||||
}
|
||||
ordering.push(cnum);
|
||||
};
|
||||
for (&num, _) in self.metas.borrow().get().iter() {
|
||||
visit(self, num, &mut ordering);
|
||||
}
|
||||
ordering.as_mut_slice().reverse();
|
||||
let ordering = ordering.as_slice();
|
||||
let used_crate_sources = self.used_crate_sources.borrow();
|
||||
used_crate_sources.get()
|
||||
let mut libs = used_crate_sources.get()
|
||||
.iter()
|
||||
.map(|src| (src.cnum, match prefer {
|
||||
RequireDynamic => src.dylib.clone(),
|
||||
RequireStatic => src.rlib.clone(),
|
||||
}))
|
||||
.collect()
|
||||
.collect::<Vec<(ast::CrateNum, Option<Path>)>>();
|
||||
libs.sort_by(|&(a, _), &(b, _)| {
|
||||
ordering.position_elem(&a).cmp(&ordering.position_elem(&b))
|
||||
});
|
||||
libs
|
||||
}
|
||||
|
||||
pub fn add_used_library(&self, lib: ~str, kind: NativeLibaryKind) {
|
||||
|
@ -408,7 +408,6 @@ impl CFGBuilder {
|
||||
self.straightline(expr, pred, [e])
|
||||
}
|
||||
|
||||
ast::ExprLogLevel |
|
||||
ast::ExprMac(..) |
|
||||
ast::ExprInlineAsm(..) |
|
||||
ast::ExprFnBlock(..) |
|
||||
|
@ -613,7 +613,6 @@ impl<'a, O:DataFlowOperator> PropagationContext<'a, O> {
|
||||
self.walk_exprs([l, r], in_out, loop_scopes);
|
||||
}
|
||||
|
||||
ast::ExprLogLevel |
|
||||
ast::ExprLit(..) |
|
||||
ast::ExprPath(..) => {}
|
||||
|
||||
|
@ -541,7 +541,7 @@ fn visit_expr(v: &mut LivenessVisitor, expr: &Expr, this: @IrMaps) {
|
||||
|
||||
// otherwise, live nodes are not required:
|
||||
ExprIndex(..) | ExprField(..) | ExprVstore(..) | ExprVec(..) |
|
||||
ExprCall(..) | ExprMethodCall(..) | ExprTup(..) | ExprLogLevel |
|
||||
ExprCall(..) | ExprMethodCall(..) | ExprTup(..) |
|
||||
ExprBinary(..) | ExprAddrOf(..) |
|
||||
ExprCast(..) | ExprUnary(..) | ExprBreak(_) |
|
||||
ExprAgain(_) | ExprLit(_) | ExprRet(..) | ExprBlock(..) |
|
||||
@ -1271,7 +1271,6 @@ impl Liveness {
|
||||
})
|
||||
}
|
||||
|
||||
ExprLogLevel |
|
||||
ExprLit(..) => {
|
||||
succ
|
||||
}
|
||||
@ -1521,7 +1520,7 @@ fn check_expr(this: &mut Liveness, expr: &Expr) {
|
||||
// no correctness conditions related to liveness
|
||||
ExprCall(..) | ExprMethodCall(..) | ExprIf(..) | ExprMatch(..) |
|
||||
ExprWhile(..) | ExprLoop(..) | ExprIndex(..) | ExprField(..) |
|
||||
ExprVstore(..) | ExprVec(..) | ExprTup(..) | ExprLogLevel |
|
||||
ExprVstore(..) | ExprVec(..) | ExprTup(..) |
|
||||
ExprBinary(..) |
|
||||
ExprCast(..) | ExprUnary(..) | ExprRet(..) | ExprBreak(..) |
|
||||
ExprAgain(..) | ExprLit(_) | ExprBlock(..) |
|
||||
|
@ -469,7 +469,7 @@ impl<TYPER:Typer> MemCategorizationContext<TYPER> {
|
||||
ast::ExprUnary(..) |
|
||||
ast::ExprMethodCall(..) | ast::ExprCast(..) | ast::ExprVstore(..) |
|
||||
ast::ExprVec(..) | ast::ExprTup(..) | ast::ExprIf(..) |
|
||||
ast::ExprLogLevel | ast::ExprBinary(..) | ast::ExprWhile(..) |
|
||||
ast::ExprBinary(..) | ast::ExprWhile(..) |
|
||||
ast::ExprBlock(..) | ast::ExprLoop(..) | ast::ExprMatch(..) |
|
||||
ast::ExprLit(..) | ast::ExprBreak(..) | ast::ExprMac(..) |
|
||||
ast::ExprAgain(..) | ast::ExprStruct(..) | ast::ExprRepeat(..) |
|
||||
|
@ -503,7 +503,6 @@ impl VisitContext {
|
||||
self.use_expr(base, Read);
|
||||
}
|
||||
|
||||
ExprLogLevel |
|
||||
ExprInlineAsm(..) |
|
||||
ExprBreak(..) |
|
||||
ExprAgain(..) |
|
||||
|
@ -32,7 +32,7 @@ use driver::session::{Session, NoDebugInfo, FullDebugInfo};
|
||||
use driver::driver::OutputFilenames;
|
||||
use driver::driver::{CrateAnalysis, CrateTranslation};
|
||||
use lib::llvm::{ModuleRef, ValueRef, BasicBlockRef};
|
||||
use lib::llvm::{llvm, True, Vector};
|
||||
use lib::llvm::{llvm, Vector};
|
||||
use lib;
|
||||
use metadata::common::LinkMeta;
|
||||
use metadata::{csearch, encoder};
|
||||
@ -2404,70 +2404,6 @@ pub fn trap(bcx: &Block) {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn decl_gc_metadata(ccx: &CrateContext, llmod_id: &str) {
|
||||
if !ccx.sess.opts.gc || !ccx.uses_gc {
|
||||
return;
|
||||
}
|
||||
|
||||
let gc_metadata_name = ~"_gc_module_metadata_" + llmod_id;
|
||||
let gc_metadata = gc_metadata_name.with_c_str(|buf| {
|
||||
unsafe {
|
||||
llvm::LLVMAddGlobal(ccx.llmod, Type::i32().to_ref(), buf)
|
||||
}
|
||||
});
|
||||
unsafe {
|
||||
llvm::LLVMSetGlobalConstant(gc_metadata, True);
|
||||
lib::llvm::SetLinkage(gc_metadata, lib::llvm::ExternalLinkage);
|
||||
|
||||
let mut module_data = ccx.module_data.borrow_mut();
|
||||
module_data.get().insert(~"_gc_module_metadata", gc_metadata);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn create_module_map(ccx: &CrateContext) -> (ValueRef, 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 = {
|
||||
let module_data = ccx.module_data.borrow();
|
||||
Type::array(&elttype, module_data.get().len() as u64)
|
||||
};
|
||||
let map = "_rust_mod_map".with_c_str(|buf| {
|
||||
unsafe {
|
||||
llvm::LLVMAddGlobal(ccx.llmod, maptype.to_ref(), buf)
|
||||
}
|
||||
});
|
||||
lib::llvm::SetLinkage(map, lib::llvm::InternalLinkage);
|
||||
let mut elts: Vec<ValueRef> = Vec::new();
|
||||
|
||||
// This is not ideal, but the borrow checker doesn't
|
||||
// like the multiple borrows. At least, it doesn't
|
||||
// like them on the current snapshot. (2013-06-14)
|
||||
let keys = {
|
||||
let mut keys = Vec::new();
|
||||
let module_data = ccx.module_data.borrow();
|
||||
for (k, _) in module_data.get().iter() {
|
||||
keys.push(k.clone());
|
||||
}
|
||||
keys
|
||||
};
|
||||
|
||||
for key in keys.iter() {
|
||||
let llstrval = C_str_slice(ccx, token::intern_and_get_ident(*key));
|
||||
let module_data = ccx.module_data.borrow();
|
||||
let val = *module_data.get().find_equiv(key).unwrap();
|
||||
let v_ptr = p2i(ccx, val);
|
||||
let elt = C_struct([
|
||||
llstrval,
|
||||
v_ptr
|
||||
], false);
|
||||
elts.push(elt);
|
||||
}
|
||||
unsafe {
|
||||
llvm::LLVMSetInitializer(map, C_array(elttype, elts.as_slice()));
|
||||
}
|
||||
return (map, keys.len())
|
||||
}
|
||||
|
||||
pub fn symname(name: &str, hash: &str, vers: &str) -> ~str {
|
||||
let path = [PathName(token::intern(name))];
|
||||
link::exported_name(ast_map::Values(path.iter()).chain(None), hash, vers)
|
||||
@ -2489,11 +2425,8 @@ pub fn decl_crate_map(sess: session::Session, mapmeta: LinkMeta,
|
||||
mapmeta.crateid.version_or_default())
|
||||
};
|
||||
|
||||
let slicetype = Type::struct_([int_type, int_type], false);
|
||||
let maptype = Type::struct_([
|
||||
Type::i32(), // version
|
||||
slicetype, // child modules
|
||||
slicetype, // sub crate-maps
|
||||
int_type.ptr_to(), // event loop factory
|
||||
], false);
|
||||
let map = sym_name.with_c_str(|buf| {
|
||||
@ -2513,22 +2446,6 @@ pub fn decl_crate_map(sess: session::Session, mapmeta: LinkMeta,
|
||||
}
|
||||
|
||||
pub fn fill_crate_map(ccx: @CrateContext, map: ValueRef) {
|
||||
let mut subcrates: Vec<ValueRef> = Vec::new();
|
||||
let mut i = 1;
|
||||
let cstore = ccx.sess.cstore;
|
||||
while cstore.have_crate_data(i) {
|
||||
let cdata = cstore.get_crate_data(i);
|
||||
let nm = symname(format!("_rust_crate_map_{}", cdata.name),
|
||||
cstore.get_crate_hash(i).as_str(),
|
||||
cstore.get_crate_id(i).version_or_default());
|
||||
let cr = nm.with_c_str(|buf| {
|
||||
unsafe {
|
||||
llvm::LLVMAddGlobal(ccx.llmod, ccx.int_type.to_ref(), buf)
|
||||
}
|
||||
});
|
||||
subcrates.push(p2i(ccx, cr));
|
||||
i += 1;
|
||||
}
|
||||
let event_loop_factory = match ccx.tcx.lang_items.event_loop_factory() {
|
||||
Some(did) => unsafe {
|
||||
if is_local(did) {
|
||||
@ -2545,26 +2462,8 @@ pub fn fill_crate_map(ccx: @CrateContext, map: ValueRef) {
|
||||
None => C_null(ccx.int_type.ptr_to())
|
||||
};
|
||||
unsafe {
|
||||
let maptype = Type::array(&ccx.int_type, subcrates.len() as u64);
|
||||
let vec_elements = "_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.as_slice()));
|
||||
let (mod_map, mod_count) = create_module_map(ccx);
|
||||
|
||||
llvm::LLVMSetInitializer(map, C_struct(
|
||||
[C_i32(2),
|
||||
C_struct([
|
||||
p2i(ccx, mod_map),
|
||||
C_uint(ccx, mod_count)
|
||||
], false),
|
||||
C_struct([
|
||||
p2i(ccx, vec_elements),
|
||||
C_uint(ccx, subcrates.len())
|
||||
], false),
|
||||
event_loop_factory,
|
||||
], false));
|
||||
}
|
||||
@ -2642,7 +2541,7 @@ pub fn trans_crate(sess: session::Session,
|
||||
}
|
||||
}
|
||||
|
||||
let link_meta = link::build_link_meta(&krate, output);
|
||||
let link_meta = link::build_link_meta(&krate, output.out_filestem);
|
||||
|
||||
// Append ".rs" to crate name as LLVM module identifier.
|
||||
//
|
||||
@ -2667,7 +2566,6 @@ pub fn trans_crate(sess: session::Session,
|
||||
trans_mod(ccx, &krate.module);
|
||||
}
|
||||
|
||||
decl_gc_metadata(ccx, llmod_id);
|
||||
fill_crate_map(ccx, ccx.crate_map);
|
||||
|
||||
// win32: wart with exporting crate_map symbol
|
||||
|
@ -95,7 +95,6 @@ pub struct CrateContext {
|
||||
// Cache of closure wrappers for bare fn's.
|
||||
closure_bare_wrapper_cache: RefCell<HashMap<ValueRef, ValueRef>>,
|
||||
|
||||
module_data: RefCell<HashMap<~str, ValueRef>>,
|
||||
lltypes: RefCell<HashMap<ty::t, Type>>,
|
||||
llsizingtypes: RefCell<HashMap<ty::t, Type>>,
|
||||
adt_reprs: RefCell<HashMap<ty::t, @adt::Repr>>,
|
||||
@ -207,7 +206,6 @@ impl CrateContext {
|
||||
extern_const_values: RefCell::new(DefIdMap::new()),
|
||||
impl_method_cache: RefCell::new(HashMap::new()),
|
||||
closure_bare_wrapper_cache: RefCell::new(HashMap::new()),
|
||||
module_data: RefCell::new(HashMap::new()),
|
||||
lltypes: RefCell::new(HashMap::new()),
|
||||
llsizingtypes: RefCell::new(HashMap::new()),
|
||||
adt_reprs: RefCell::new(HashMap::new()),
|
||||
|
@ -2539,7 +2539,6 @@ fn populate_scope_map(cx: &CrateContext,
|
||||
scope_map.insert(exp.id, scope_stack.last().unwrap().scope_metadata);
|
||||
|
||||
match exp.node {
|
||||
ast::ExprLogLevel |
|
||||
ast::ExprLit(_) |
|
||||
ast::ExprBreak(_) |
|
||||
ast::ExprAgain(_) |
|
||||
|
@ -34,8 +34,7 @@
|
||||
#[allow(non_camel_case_types)];
|
||||
|
||||
use back::abi;
|
||||
use back::link;
|
||||
use lib::llvm::{ValueRef, llvm, SetLinkage, False};
|
||||
use lib::llvm::{ValueRef, llvm};
|
||||
use lib;
|
||||
use metadata::csearch;
|
||||
use middle::trans::_match;
|
||||
@ -74,9 +73,7 @@ use middle::trans::type_::Type;
|
||||
use std::vec;
|
||||
use std::vec_ng::Vec;
|
||||
use syntax::ast;
|
||||
use syntax::ast_map;
|
||||
use syntax::codemap;
|
||||
use syntax::parse::token;
|
||||
use syntax::print::pprust::{expr_to_str};
|
||||
|
||||
// Destinations
|
||||
@ -455,9 +452,6 @@ fn trans_datum_unadjusted<'a>(bcx: &'a Block<'a>,
|
||||
// Datum output mode means this is a scalar cast:
|
||||
trans_imm_cast(bcx, val, expr.id)
|
||||
}
|
||||
ast::ExprLogLevel => {
|
||||
trans_log_level(bcx)
|
||||
}
|
||||
_ => {
|
||||
bcx.tcx().sess.span_bug(
|
||||
expr.span,
|
||||
@ -1671,64 +1665,6 @@ fn trans_assign_op<'a>(
|
||||
return result_datum.store_to(bcx, dst_datum.val);
|
||||
}
|
||||
|
||||
fn trans_log_level<'a>(bcx: &'a Block<'a>) -> DatumBlock<'a, Expr> {
|
||||
let _icx = push_ctxt("trans_log_level");
|
||||
let ccx = bcx.ccx();
|
||||
|
||||
let (modpath, modname) = {
|
||||
let srccrate = {
|
||||
let external_srcs = ccx.external_srcs.borrow();
|
||||
match external_srcs.get().find(&bcx.fcx.id) {
|
||||
Some(&src) => {
|
||||
ccx.sess.cstore.get_crate_data(src.krate).name.clone()
|
||||
}
|
||||
None => ccx.link_meta.crateid.name.to_str(),
|
||||
}
|
||||
};
|
||||
bcx.tcx().map.with_path(bcx.fcx.id, |path| {
|
||||
let first = ast_map::PathMod(token::intern(srccrate));
|
||||
let mut path = Some(first).move_iter().chain(path).filter(|e| {
|
||||
match *e {
|
||||
ast_map::PathMod(_) => true,
|
||||
_ => false
|
||||
}
|
||||
});
|
||||
let modpath: Vec<ast_map::PathElem> = path.collect();
|
||||
let modname = ast_map::path_to_str(ast_map::Values(modpath.iter()));
|
||||
(modpath, modname)
|
||||
})
|
||||
};
|
||||
|
||||
let module_data_exists;
|
||||
{
|
||||
let module_data = ccx.module_data.borrow();
|
||||
module_data_exists = module_data.get().contains_key(&modname);
|
||||
}
|
||||
|
||||
let global = if module_data_exists {
|
||||
let mut module_data = ccx.module_data.borrow_mut();
|
||||
module_data.get().get_copy(&modname)
|
||||
} else {
|
||||
let s = link::mangle_internal_name_by_path_and_seq(
|
||||
ast_map::Values(modpath.iter()).chain(None), "loglevel");
|
||||
let global;
|
||||
unsafe {
|
||||
global = s.with_c_str(|buf| {
|
||||
llvm::LLVMAddGlobal(ccx.llmod, Type::i32().to_ref(), buf)
|
||||
});
|
||||
llvm::LLVMSetGlobalConstant(global, False);
|
||||
llvm::LLVMSetInitializer(global, C_null(Type::i32()));
|
||||
lib::llvm::SetLinkage(global, lib::llvm::InternalLinkage);
|
||||
}
|
||||
{
|
||||
let mut module_data = ccx.module_data.borrow_mut();
|
||||
module_data.get().insert(modname, global);
|
||||
global
|
||||
}
|
||||
};
|
||||
|
||||
immediate_rvalue_bcx(bcx, Load(bcx, global), ty::mk_u32()).to_expr_datumblock()
|
||||
}
|
||||
|
||||
fn auto_ref<'a>(bcx: &'a Block<'a>,
|
||||
datum: Datum<Expr>,
|
||||
|
@ -3391,7 +3391,6 @@ pub fn expr_kind(tcx: ctxt,
|
||||
|
||||
ast::ExprForLoop(..) => fail!("non-desugared expr_for_loop"),
|
||||
|
||||
ast::ExprLogLevel |
|
||||
ast::ExprLit(_) | // Note: LitStr is carved out above
|
||||
ast::ExprUnary(..) |
|
||||
ast::ExprAddrOf(..) |
|
||||
|
@ -2848,9 +2848,6 @@ fn check_expr_with_unifier(fcx: @FnCtxt,
|
||||
}
|
||||
fcx.write_bot(id);
|
||||
}
|
||||
ast::ExprLogLevel => {
|
||||
fcx.write_ty(id, ty::mk_u32())
|
||||
}
|
||||
ast::ExprParen(a) => {
|
||||
check_expr_with_opt_hint_and_lvalue_pref(fcx, a, expected, lvalue_pref);
|
||||
fcx.write_ty(id, fcx.expr_ty(a));
|
||||
|
@ -75,7 +75,9 @@ fn get_ast_and_resolve(cpath: &Path,
|
||||
|
||||
let krate = phase_1_parse_input(sess, cfg, &input);
|
||||
let loader = &mut Loader::new(sess);
|
||||
let (krate, ast_map) = phase_2_configure_and_expand(sess, loader, krate);
|
||||
let id = from_str("rustdoc").unwrap();
|
||||
let (krate, ast_map) = phase_2_configure_and_expand(sess, loader,
|
||||
krate, &id);
|
||||
let driver::driver::CrateAnalysis {
|
||||
exported_items, public_items, ty_cx, ..
|
||||
} = phase_3_run_analysis_passes(sess, &krate, ast_map);
|
||||
|
@ -15,7 +15,7 @@
|
||||
#[crate_type = "rlib"];
|
||||
|
||||
#[allow(deprecated_owned_vector)];
|
||||
#[feature(globs, struct_variant, managed_boxes, macro_rules)];
|
||||
#[feature(globs, struct_variant, managed_boxes, macro_rules, phase)];
|
||||
|
||||
extern crate syntax;
|
||||
extern crate rustc;
|
||||
@ -25,6 +25,8 @@ extern crate getopts;
|
||||
extern crate collections;
|
||||
extern crate testing = "test";
|
||||
extern crate time;
|
||||
#[phase(syntax, link)]
|
||||
extern crate log;
|
||||
|
||||
use std::cell::RefCell;
|
||||
use std::local_data;
|
||||
|
@ -61,7 +61,9 @@ pub fn run(input: &str, libs: @RefCell<HashSet<Path>>, mut test_args: ~[~str]) -
|
||||
let cfg = driver::build_configuration(sess);
|
||||
let krate = driver::phase_1_parse_input(sess, cfg, &input);
|
||||
let loader = &mut Loader::new(sess);
|
||||
let (krate, _) = driver::phase_2_configure_and_expand(sess, loader, krate);
|
||||
let id = from_str("rustdoc-test").unwrap();
|
||||
let (krate, _) = driver::phase_2_configure_and_expand(sess, loader, krate,
|
||||
&id);
|
||||
|
||||
let ctx = @core::DocContext {
|
||||
krate: krate,
|
||||
|
@ -170,7 +170,6 @@ fn take_nonempty_prefix<T:Iterator<char>>(rdr: &mut T, pred: |char| -> bool)
|
||||
}
|
||||
}
|
||||
}
|
||||
debug!("extracted nonempty prefix: {}", buf);
|
||||
(buf, ch)
|
||||
}
|
||||
|
||||
|
@ -23,7 +23,7 @@ Core encoding and decoding interfaces.
|
||||
html_root_url = "http://static.rust-lang.org/doc/master")];
|
||||
#[allow(missing_doc)];
|
||||
#[forbid(non_camel_case_types)];
|
||||
#[feature(macro_rules, managed_boxes, default_type_params)];
|
||||
#[feature(macro_rules, managed_boxes, default_type_params, phase)];
|
||||
|
||||
// NOTE remove the following two attributes after the next snapshot.
|
||||
#[allow(unrecognized_lint)];
|
||||
@ -33,6 +33,8 @@ Core encoding and decoding interfaces.
|
||||
// test harness access
|
||||
#[cfg(test)]
|
||||
extern crate test;
|
||||
#[phase(syntax, link)]
|
||||
extern crate log;
|
||||
|
||||
extern crate collections;
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
/// ```
|
||||
|
@ -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;
|
||||
|
@ -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))
|
||||
}
|
@ -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)*) }
|
||||
)
|
||||
)
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
@ -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();
|
||||
}
|
||||
|
@ -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 => {} }
|
||||
}
|
||||
|
@ -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() }
|
||||
}
|
||||
|
@ -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,
|
||||
}
|
||||
|
@ -19,9 +19,12 @@
|
||||
#[doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
|
||||
html_favicon_url = "http://www.rust-lang.org/favicon.ico",
|
||||
html_root_url = "http://static.rust-lang.org/doc/master")];
|
||||
#[feature(phase)];
|
||||
|
||||
#[allow(deprecated_owned_vector)];
|
||||
|
||||
#[cfg(test)] #[phase(syntax, link)] extern crate log;
|
||||
|
||||
pub use arc::{Arc, MutexArc, RWArc, RWWriteMode, RWReadMode, ArcCondvar, CowArc};
|
||||
pub use sync::{Mutex, RWLock, Condvar, Semaphore, RWLockWriteMode,
|
||||
RWLockReadMode, Barrier, one, mutex};
|
||||
|
@ -529,9 +529,6 @@ pub enum Expr_ {
|
||||
ExprAgain(Option<Ident>),
|
||||
ExprRet(Option<@Expr>),
|
||||
|
||||
/// Gets the log level for the enclosing module
|
||||
ExprLogLevel,
|
||||
|
||||
ExprInlineAsm(InlineAsm),
|
||||
|
||||
ExprMac(Mac),
|
||||
|
@ -18,7 +18,6 @@ use parse::token;
|
||||
use print::pprust;
|
||||
use util::small_vector::SmallVector;
|
||||
|
||||
use std::logging;
|
||||
use std::cell::RefCell;
|
||||
use std::iter;
|
||||
use std::vec;
|
||||
@ -538,7 +537,7 @@ pub fn map_crate<F: FoldOps>(krate: Crate, fold_ops: F) -> (Crate, Map) {
|
||||
cx.fold_crate(krate)
|
||||
};
|
||||
|
||||
if log_enabled!(logging::DEBUG) {
|
||||
if log_enabled!(::log::DEBUG) {
|
||||
let map = map.map.borrow();
|
||||
// This only makes sense for ordered stores; note the
|
||||
// enumerate to count the number of entries.
|
||||
|
@ -120,7 +120,7 @@ impl MacResult {
|
||||
pub fn raw_dummy_expr(sp: codemap::Span) -> @ast::Expr {
|
||||
@ast::Expr {
|
||||
id: ast::DUMMY_NODE_ID,
|
||||
node: ast::ExprLogLevel,
|
||||
node: ast::ExprTup(Vec::new()),
|
||||
span: sp
|
||||
}
|
||||
}
|
||||
@ -339,7 +339,12 @@ impl<'a> ExtCtxt<'a> {
|
||||
pub fn backtrace(&self) -> Option<@ExpnInfo> { self.backtrace }
|
||||
pub fn mod_push(&mut self, i: ast::Ident) { self.mod_path.push(i); }
|
||||
pub fn mod_pop(&mut self) { self.mod_path.pop().unwrap(); }
|
||||
pub fn mod_path(&self) -> Vec<ast::Ident> { self.mod_path.clone() }
|
||||
pub fn mod_path(&self) -> Vec<ast::Ident> {
|
||||
let mut v = Vec::new();
|
||||
v.push(token::str_to_ident(self.ecfg.crate_id.name));
|
||||
v.extend(&mut self.mod_path.iter().map(|a| *a));
|
||||
return v;
|
||||
}
|
||||
pub fn bt_push(&mut self, ei: codemap::ExpnInfo) {
|
||||
match ei {
|
||||
ExpnInfo {call_site: cs, callee: ref callee} => {
|
||||
|
@ -19,6 +19,7 @@ use attr;
|
||||
use attr::AttrMetaMethods;
|
||||
use codemap;
|
||||
use codemap::{Span, Spanned, ExpnInfo, NameAndSpan, MacroBang, MacroAttribute};
|
||||
use crateid::CrateId;
|
||||
use ext::base::*;
|
||||
use fold::*;
|
||||
use parse;
|
||||
@ -871,6 +872,7 @@ impl<'a> Folder for MacroExpander<'a> {
|
||||
pub struct ExpansionConfig<'a> {
|
||||
loader: &'a mut CrateLoader,
|
||||
deriving_hash_type_parameter: bool,
|
||||
crate_id: CrateId,
|
||||
}
|
||||
|
||||
pub fn expand_crate(parse_sess: @parse::ParseSess,
|
||||
@ -1048,6 +1050,7 @@ mod test {
|
||||
let cfg = ::syntax::ext::expand::ExpansionConfig {
|
||||
loader: &mut loader,
|
||||
deriving_hash_type_parameter: false,
|
||||
crate_id: from_str("test").unwrap(),
|
||||
};
|
||||
expand_crate(sess,cfg,crate_ast);
|
||||
}
|
||||
@ -1067,6 +1070,7 @@ mod test {
|
||||
let cfg = ::syntax::ext::expand::ExpansionConfig {
|
||||
loader: &mut loader,
|
||||
deriving_hash_type_parameter: false,
|
||||
crate_id: from_str("test").unwrap(),
|
||||
};
|
||||
expand_crate(sess,cfg,crate_ast);
|
||||
}
|
||||
@ -1085,6 +1089,7 @@ mod test {
|
||||
let cfg = ::syntax::ext::expand::ExpansionConfig {
|
||||
loader: &mut loader,
|
||||
deriving_hash_type_parameter: false,
|
||||
crate_id: from_str("test").unwrap(),
|
||||
};
|
||||
expand_crate(sess, cfg, crate_ast);
|
||||
}
|
||||
@ -1127,6 +1132,7 @@ mod test {
|
||||
let cfg = ::syntax::ext::expand::ExpansionConfig {
|
||||
loader: &mut loader,
|
||||
deriving_hash_type_parameter: false,
|
||||
crate_id: from_str("test").unwrap(),
|
||||
};
|
||||
expand_crate(ps,cfg,crate_ast)
|
||||
}
|
||||
|
@ -816,7 +816,6 @@ pub fn noop_fold_expr<T: Folder>(e: @Expr, folder: &mut T) -> @Expr {
|
||||
ExprIndex(folder.fold_expr(el), folder.fold_expr(er))
|
||||
}
|
||||
ExprPath(ref pth) => ExprPath(folder.fold_path(pth)),
|
||||
ExprLogLevel => ExprLogLevel,
|
||||
ExprBreak(opt_ident) => ExprBreak(opt_ident.map(|x| folder.fold_ident(x))),
|
||||
ExprAgain(opt_ident) => ExprAgain(opt_ident.map(|x| folder.fold_ident(x))),
|
||||
ExprRet(ref e) => {
|
||||
|
@ -26,9 +26,7 @@ This API is completely unstable and subject to change.
|
||||
html_favicon_url = "http://www.rust-lang.org/favicon.ico",
|
||||
html_root_url = "http://static.rust-lang.org/doc/master")];
|
||||
|
||||
#[feature(macro_rules, globs, managed_boxes, default_type_params)];
|
||||
#[allow(unknown_features)];// Note: remove it after a snapshot.
|
||||
#[feature(quote)];
|
||||
#[feature(macro_rules, globs, managed_boxes, default_type_params, phase, quote)];
|
||||
|
||||
#[allow(deprecated)];
|
||||
#[deny(non_camel_case_types)];
|
||||
@ -37,6 +35,8 @@ This API is completely unstable and subject to change.
|
||||
extern crate serialize;
|
||||
extern crate term;
|
||||
extern crate collections;
|
||||
#[phase(syntax, link)]
|
||||
extern crate log;
|
||||
|
||||
pub mod util {
|
||||
pub mod interner;
|
||||
|
@ -25,7 +25,7 @@ use ast::{Expr, Expr_, ExprAddrOf, ExprMatch, ExprAgain};
|
||||
use ast::{ExprAssign, ExprAssignOp, ExprBinary, ExprBlock, ExprBox};
|
||||
use ast::{ExprBreak, ExprCall, ExprCast};
|
||||
use ast::{ExprField, ExprFnBlock, ExprIf, ExprIndex};
|
||||
use ast::{ExprLit, ExprLogLevel, ExprLoop, ExprMac};
|
||||
use ast::{ExprLit, ExprLoop, ExprMac};
|
||||
use ast::{ExprMethodCall, ExprParen, ExprPath, ExprProc};
|
||||
use ast::{ExprRepeat, ExprRet, ExprStruct, ExprTup, ExprUnary};
|
||||
use ast::{ExprVec, ExprVstore, ExprVstoreSlice};
|
||||
@ -1886,12 +1886,6 @@ impl Parser {
|
||||
}
|
||||
}
|
||||
hi = self.last_span.hi;
|
||||
} else if self.eat_keyword(keywords::__LogLevel) {
|
||||
// LOG LEVEL expression
|
||||
self.expect(&token::LPAREN);
|
||||
ex = ExprLogLevel;
|
||||
hi = self.span.hi;
|
||||
self.expect(&token::RPAREN);
|
||||
} else if self.eat_keyword(keywords::Return) {
|
||||
// RETURN expression
|
||||
if can_begin_expr(&self.token) {
|
||||
|
@ -462,41 +462,40 @@ declare_special_idents_and_keywords! {
|
||||
(20, Impl, "impl");
|
||||
(21, In, "in");
|
||||
(22, Let, "let");
|
||||
(23, __LogLevel, "__log_level");
|
||||
(24, Loop, "loop");
|
||||
(25, Match, "match");
|
||||
(26, Mod, "mod");
|
||||
(27, Mut, "mut");
|
||||
(28, Once, "once");
|
||||
(29, Priv, "priv");
|
||||
(30, Pub, "pub");
|
||||
(31, Ref, "ref");
|
||||
(32, Return, "return");
|
||||
(23, Loop, "loop");
|
||||
(24, Match, "match");
|
||||
(25, Mod, "mod");
|
||||
(26, Mut, "mut");
|
||||
(27, Once, "once");
|
||||
(28, Priv, "priv");
|
||||
(29, Pub, "pub");
|
||||
(30, Ref, "ref");
|
||||
(31, Return, "return");
|
||||
// Static and Self are also special idents (prefill de-dupes)
|
||||
(super::STATIC_KEYWORD_NAME, Static, "static");
|
||||
(super::SELF_KEYWORD_NAME, Self, "self");
|
||||
(33, Struct, "struct");
|
||||
(34, Super, "super");
|
||||
(35, True, "true");
|
||||
(36, Trait, "trait");
|
||||
(37, Type, "type");
|
||||
(38, Unsafe, "unsafe");
|
||||
(39, Use, "use");
|
||||
(40, While, "while");
|
||||
(41, Continue, "continue");
|
||||
(42, Proc, "proc");
|
||||
(43, Box, "box");
|
||||
(32, Struct, "struct");
|
||||
(33, Super, "super");
|
||||
(34, True, "true");
|
||||
(35, Trait, "trait");
|
||||
(36, Type, "type");
|
||||
(37, Unsafe, "unsafe");
|
||||
(38, Use, "use");
|
||||
(39, While, "while");
|
||||
(40, Continue, "continue");
|
||||
(41, Proc, "proc");
|
||||
(42, Box, "box");
|
||||
|
||||
'reserved:
|
||||
(44, Alignof, "alignof");
|
||||
(45, Be, "be");
|
||||
(46, Offsetof, "offsetof");
|
||||
(47, Pure, "pure");
|
||||
(48, Sizeof, "sizeof");
|
||||
(49, Typeof, "typeof");
|
||||
(50, Unsized, "unsized");
|
||||
(51, Yield, "yield");
|
||||
(52, Do, "do");
|
||||
(43, Alignof, "alignof");
|
||||
(44, Be, "be");
|
||||
(45, Offsetof, "offsetof");
|
||||
(46, Pure, "pure");
|
||||
(47, Sizeof, "sizeof");
|
||||
(48, Typeof, "typeof");
|
||||
(49, Unsized, "unsized");
|
||||
(50, Yield, "yield");
|
||||
(51, Do, "do");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1490,11 +1490,6 @@ pub fn print_expr(s: &mut State, expr: &ast::Expr) -> io::IoResult<()> {
|
||||
_ => ()
|
||||
}
|
||||
}
|
||||
ast::ExprLogLevel => {
|
||||
try!(word(&mut s.s, "__log_level"));
|
||||
try!(popen(s));
|
||||
try!(pclose(s));
|
||||
}
|
||||
ast::ExprInlineAsm(ref a) => {
|
||||
if a.volatile {
|
||||
try!(word(&mut s.s, "__volatile__ asm!"));
|
||||
|
@ -743,7 +743,6 @@ pub fn walk_expr<E: Clone, V: Visitor<E>>(visitor: &mut V, expression: &Expr, en
|
||||
ExprRet(optional_expression) => {
|
||||
walk_expr_opt(visitor, optional_expression, env.clone())
|
||||
}
|
||||
ExprLogLevel => {}
|
||||
ExprMac(ref macro) => visitor.visit_mac(macro, env.clone()),
|
||||
ExprParen(subexpression) => {
|
||||
visitor.visit_expr(subexpression, env.clone())
|
||||
|
@ -156,8 +156,6 @@ impl<T: Writer> Terminal<T> {
|
||||
if s.is_ok() {
|
||||
try!(self.out.write(s.unwrap()));
|
||||
return Ok(true)
|
||||
} else {
|
||||
warn!("{}", s.unwrap_err());
|
||||
}
|
||||
}
|
||||
Ok(false)
|
||||
@ -177,8 +175,6 @@ impl<T: Writer> Terminal<T> {
|
||||
if s.is_ok() {
|
||||
try!(self.out.write(s.unwrap()));
|
||||
return Ok(true)
|
||||
} else {
|
||||
warn!("{}", s.unwrap_err());
|
||||
}
|
||||
}
|
||||
Ok(false)
|
||||
@ -199,8 +195,6 @@ impl<T: Writer> Terminal<T> {
|
||||
if s.is_ok() {
|
||||
try!(self.out.write(s.unwrap()));
|
||||
return Ok(true)
|
||||
} else {
|
||||
warn!("{}", s.unwrap_err());
|
||||
}
|
||||
}
|
||||
Ok(false)
|
||||
@ -237,12 +231,6 @@ impl<T: Writer> Terminal<T> {
|
||||
});
|
||||
if s.is_ok() {
|
||||
return self.out.write(s.unwrap())
|
||||
} else if self.num_colors > 0 {
|
||||
warn!("{}", s.unwrap_err());
|
||||
} else {
|
||||
// if we support attributes but not color, it would be nice to still warn!()
|
||||
// but it's not worth testing all known attributes just for this.
|
||||
debug!("{}", s.unwrap_err());
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
@ -195,27 +195,15 @@ pub fn parse(file: &mut io::Reader,
|
||||
|
||||
assert!(names_bytes > 0);
|
||||
|
||||
debug!("names_bytes = {}", names_bytes);
|
||||
debug!("bools_bytes = {}", bools_bytes);
|
||||
debug!("numbers_count = {}", numbers_count);
|
||||
debug!("string_offsets_count = {}", string_offsets_count);
|
||||
debug!("string_table_bytes = {}", string_table_bytes);
|
||||
|
||||
if (bools_bytes as uint) > boolnames.len() {
|
||||
error!("expected bools_bytes to be less than {} but found {}", boolnames.len(),
|
||||
bools_bytes);
|
||||
return Err(~"incompatible file: more booleans than expected");
|
||||
}
|
||||
|
||||
if (numbers_count as uint) > numnames.len() {
|
||||
error!("expected numbers_count to be less than {} but found {}", numnames.len(),
|
||||
numbers_count);
|
||||
return Err(~"incompatible file: more numbers than expected");
|
||||
}
|
||||
|
||||
if (string_offsets_count as uint) > stringnames.len() {
|
||||
error!("expected string_offsets_count to be less than {} but found {}", stringnames.len(),
|
||||
string_offsets_count);
|
||||
return Err(~"incompatible file: more string offsets than expected");
|
||||
}
|
||||
|
||||
@ -229,26 +217,19 @@ pub fn parse(file: &mut io::Reader,
|
||||
|
||||
try!(file.read_byte()); // consume NUL
|
||||
|
||||
debug!("term names: {:?}", term_names);
|
||||
|
||||
let mut bools_map = HashMap::new();
|
||||
if bools_bytes != 0 {
|
||||
for i in range(0, bools_bytes) {
|
||||
let b = try!(file.read_byte());
|
||||
if b < 0 {
|
||||
error!("EOF reading bools after {} entries", i);
|
||||
return Err(~"error: expected more bools but hit EOF");
|
||||
} else if b == 1 {
|
||||
debug!("{} set", bnames[i]);
|
||||
bools_map.insert(bnames[i].to_owned(), true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
debug!("bools: {:?}", bools_map);
|
||||
|
||||
if (bools_bytes + names_bytes) % 2 == 1 {
|
||||
debug!("adjusting for padding between bools and numbers");
|
||||
try!(file.read_byte()); // compensate for padding
|
||||
}
|
||||
|
||||
@ -257,14 +238,11 @@ pub fn parse(file: &mut io::Reader,
|
||||
for i in range(0, numbers_count) {
|
||||
let n = try!(file.read_le_u16());
|
||||
if n != 0xFFFF {
|
||||
debug!("{}\\#{}", nnames[i], n);
|
||||
numbers_map.insert(nnames[i].to_owned(), n);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
debug!("numbers: {:?}", numbers_map);
|
||||
|
||||
let mut string_map = HashMap::new();
|
||||
|
||||
if string_offsets_count != 0 {
|
||||
@ -273,13 +251,9 @@ pub fn parse(file: &mut io::Reader,
|
||||
string_offsets.push(try!(file.read_le_u16()));
|
||||
}
|
||||
|
||||
debug!("offsets: {:?}", string_offsets);
|
||||
|
||||
let string_table = try!(file.read_bytes(string_table_bytes as uint));
|
||||
|
||||
if string_table.len() != string_table_bytes as uint {
|
||||
error!("EOF reading string table after {} bytes, wanted {}", string_table.len(),
|
||||
string_table_bytes);
|
||||
return Err(~"error: hit EOF before end of string table");
|
||||
}
|
||||
|
||||
|
@ -692,7 +692,6 @@ pub fn run_tests_console(opts: &TestOpts,
|
||||
tests: ~[TestDescAndFn]) -> io::IoResult<bool> {
|
||||
fn callback<T: Writer>(event: &TestEvent,
|
||||
st: &mut ConsoleTestState<T>) -> io::IoResult<()> {
|
||||
debug!("callback(event={:?})", event);
|
||||
match (*event).clone() {
|
||||
TeFiltered(ref filtered_tests) => st.write_run_start(filtered_tests.len()),
|
||||
TeWait(ref test, padding) => st.write_test_start(test, padding),
|
||||
@ -736,7 +735,6 @@ pub fn run_tests_console(opts: &TestOpts,
|
||||
match tests.iter().max_by(|t|len_if_padded(*t)) {
|
||||
Some(t) => {
|
||||
let n = t.desc.name.to_str();
|
||||
debug!("Setting max_name_len from: {}", n);
|
||||
st.max_name_len = n.len();
|
||||
},
|
||||
None => {}
|
||||
@ -825,7 +823,6 @@ fn run_tests(opts: &TestOpts,
|
||||
// It's tempting to just spawn all the tests at once, but since we have
|
||||
// many tests that run in other processes we would be making a big mess.
|
||||
let concurrency = get_concurrency();
|
||||
debug!("using {} test tasks", concurrency);
|
||||
|
||||
let mut remaining = filtered_tests;
|
||||
remaining.reverse();
|
||||
@ -1151,7 +1148,6 @@ impl MetricMap {
|
||||
});
|
||||
|
||||
if ok {
|
||||
debug!("rewriting file '{:?}' with updated metrics", p);
|
||||
self.save(p).unwrap();
|
||||
}
|
||||
return (diff, ok)
|
||||
@ -1202,8 +1198,6 @@ impl BenchHarness {
|
||||
|
||||
pub fn bench_n(&mut self, n: u64, f: |&mut BenchHarness|) {
|
||||
self.iterations = n;
|
||||
debug!("running benchmark for {} iterations",
|
||||
n as uint);
|
||||
f(self);
|
||||
}
|
||||
|
||||
@ -1228,9 +1222,6 @@ impl BenchHarness {
|
||||
// (i.e. larger error bars).
|
||||
if n == 0 { n = 1; }
|
||||
|
||||
debug!("Initial run took {} ns, iter count that takes 1ms estimated as {}",
|
||||
self.ns_per_iter(), n);
|
||||
|
||||
let mut total_run = 0;
|
||||
let samples : &mut [f64] = [0.0_f64, ..50];
|
||||
loop {
|
||||
@ -1252,12 +1243,6 @@ impl BenchHarness {
|
||||
stats::winsorize(samples, 5.0);
|
||||
let summ5 = stats::Summary::new(samples);
|
||||
|
||||
debug!("{} samples, median {}, MAD={}, MADP={}",
|
||||
samples.len(),
|
||||
summ.median as f64,
|
||||
summ.median_abs_dev as f64,
|
||||
summ.median_abs_dev_pct as f64);
|
||||
|
||||
let now = precise_time_ns();
|
||||
let loop_run = now - loop_start;
|
||||
|
||||
|
@ -16,9 +16,10 @@
|
||||
html_favicon_url = "http://www.rust-lang.org/favicon.ico",
|
||||
html_root_url = "http://static.rust-lang.org/doc/master")];
|
||||
|
||||
#[allow(missing_doc)];
|
||||
#[feature(phase)];
|
||||
#[allow(deprecated_owned_vector)];
|
||||
|
||||
#[cfg(test)] #[phase(syntax, link)] extern crate log;
|
||||
extern crate serialize;
|
||||
|
||||
use std::io::BufReader;
|
||||
|
@ -15,8 +15,10 @@
|
||||
#[doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
|
||||
html_favicon_url = "http://www.rust-lang.org/favicon.ico",
|
||||
html_root_url = "http://static.rust-lang.org/doc/master")];
|
||||
#[feature(phase)];
|
||||
#[allow(deprecated_owned_vector, visible_private_types)];
|
||||
|
||||
#[phase(syntax, link)] extern crate log;
|
||||
extern crate serialize;
|
||||
extern crate collections;
|
||||
extern crate sync;
|
||||
|
@ -21,11 +21,11 @@ pub mod kitties {
|
||||
|
||||
pub fn eat(&mut self) -> bool {
|
||||
if self.how_hungry > 0 {
|
||||
error!("OM NOM NOM");
|
||||
println!("OM NOM NOM");
|
||||
self.how_hungry -= 2;
|
||||
return true;
|
||||
} else {
|
||||
error!("Not hungry!");
|
||||
println!("Not hungry!");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -33,7 +33,7 @@ pub mod kitties {
|
||||
|
||||
impl cat {
|
||||
pub fn meow(&mut self) {
|
||||
error!("Meow");
|
||||
println!("Meow");
|
||||
self.meows += 1u;
|
||||
if self.meows % 5u == 0u {
|
||||
self.how_hungry += 1;
|
||||
|
@ -25,7 +25,7 @@ pub mod kitty {
|
||||
|
||||
impl cat {
|
||||
fn meow(&mut self) {
|
||||
error!("Meow");
|
||||
println!("Meow");
|
||||
self.meows += 1u;
|
||||
if self.meows % 5u == 0u {
|
||||
self.how_hungry += 1;
|
||||
@ -39,12 +39,12 @@ pub mod kitty {
|
||||
|
||||
pub fn eat(&mut self) -> bool {
|
||||
if self.how_hungry > 0 {
|
||||
error!("OM NOM NOM");
|
||||
println!("OM NOM NOM");
|
||||
self.how_hungry -= 2;
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
error!("Not hungry!");
|
||||
println!("Not hungry!");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -26,7 +26,7 @@ pub mod rustrt {
|
||||
|
||||
pub fn fact(n: uint) -> uint {
|
||||
unsafe {
|
||||
info!("n = {}", n);
|
||||
println!("n = {}", n);
|
||||
rustrt::rust_dbg_call(cb, n)
|
||||
}
|
||||
}
|
||||
|
@ -8,6 +8,9 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#[feature(phase)];
|
||||
#[phase(syntax, link)] extern crate log;
|
||||
|
||||
pub fn foo<T>() {
|
||||
fn death() -> int { fail!() }
|
||||
debug!("{:?}", (||{ death() })());
|
||||
|
@ -25,6 +25,6 @@ fn main() {
|
||||
|
||||
for i in range(0u, n) {
|
||||
let x = i.to_str();
|
||||
info!("{}", x);
|
||||
println!("{}", x);
|
||||
}
|
||||
}
|
||||
|
@ -40,7 +40,7 @@ fn server(requests: &Receiver<request>, responses: &Sender<uint>) {
|
||||
match requests.recv_opt() {
|
||||
Some(get_count) => { responses.send(count.clone()); }
|
||||
Some(bytes(b)) => {
|
||||
//error!("server: received {:?} bytes", b);
|
||||
//println!("server: received {:?} bytes", b);
|
||||
count += b;
|
||||
}
|
||||
None => { done = true; }
|
||||
@ -48,7 +48,7 @@ fn server(requests: &Receiver<request>, responses: &Sender<uint>) {
|
||||
}
|
||||
}
|
||||
responses.send(count);
|
||||
//error!("server exiting");
|
||||
//println!("server exiting");
|
||||
}
|
||||
|
||||
fn run(args: &[~str]) {
|
||||
@ -66,10 +66,10 @@ fn run(args: &[~str]) {
|
||||
worker_results.push(builder.future_result());
|
||||
builder.spawn(proc() {
|
||||
for _ in range(0u, size / workers) {
|
||||
//error!("worker {:?}: sending {:?} bytes", i, num_bytes);
|
||||
//println!("worker {:?}: sending {:?} bytes", i, num_bytes);
|
||||
to_child.send(bytes(num_bytes));
|
||||
}
|
||||
//error!("worker {:?} exiting", i);
|
||||
//println!("worker {:?} exiting", i);
|
||||
});
|
||||
}
|
||||
task::spawn(proc() {
|
||||
@ -80,7 +80,7 @@ fn run(args: &[~str]) {
|
||||
r.recv();
|
||||
}
|
||||
|
||||
//error!("sending stop message");
|
||||
//println!("sending stop message");
|
||||
to_child.send(stop);
|
||||
move_out(to_child);
|
||||
let result = from_child.recv();
|
||||
@ -103,6 +103,6 @@ fn main() {
|
||||
args.clone()
|
||||
};
|
||||
|
||||
info!("{:?}", args);
|
||||
println!("{:?}", args);
|
||||
run(args);
|
||||
}
|
||||
|
@ -35,7 +35,7 @@ fn server(requests: &Receiver<request>, responses: &Sender<uint>) {
|
||||
match requests.recv_opt() {
|
||||
Some(get_count) => { responses.send(count.clone()); }
|
||||
Some(bytes(b)) => {
|
||||
//error!("server: received {:?} bytes", b);
|
||||
//println!("server: received {:?} bytes", b);
|
||||
count += b;
|
||||
}
|
||||
None => { done = true; }
|
||||
@ -43,7 +43,7 @@ fn server(requests: &Receiver<request>, responses: &Sender<uint>) {
|
||||
}
|
||||
}
|
||||
responses.send(count);
|
||||
//error!("server exiting");
|
||||
//println!("server exiting");
|
||||
}
|
||||
|
||||
fn run(args: &[~str]) {
|
||||
@ -60,10 +60,10 @@ fn run(args: &[~str]) {
|
||||
worker_results.push(builder.future_result());
|
||||
builder.spawn(proc() {
|
||||
for _ in range(0u, size / workers) {
|
||||
//error!("worker {:?}: sending {:?} bytes", i, num_bytes);
|
||||
//println!("worker {:?}: sending {:?} bytes", i, num_bytes);
|
||||
to_child.send(bytes(num_bytes));
|
||||
}
|
||||
//error!("worker {:?} exiting", i);
|
||||
//println!("worker {:?} exiting", i);
|
||||
});
|
||||
from_parent
|
||||
} else {
|
||||
@ -74,10 +74,10 @@ fn run(args: &[~str]) {
|
||||
worker_results.push(builder.future_result());
|
||||
builder.spawn(proc() {
|
||||
for _ in range(0u, size / workers) {
|
||||
//error!("worker {:?}: sending {:?} bytes", i, num_bytes);
|
||||
//println!("worker {:?}: sending {:?} bytes", i, num_bytes);
|
||||
to_child.send(bytes(num_bytes));
|
||||
}
|
||||
//error!("worker {:?} exiting", i);
|
||||
//println!("worker {:?} exiting", i);
|
||||
});
|
||||
}
|
||||
from_parent
|
||||
@ -90,7 +90,7 @@ fn run(args: &[~str]) {
|
||||
r.recv();
|
||||
}
|
||||
|
||||
//error!("sending stop message");
|
||||
//println!("sending stop message");
|
||||
//to_child.send(stop);
|
||||
//move_out(to_child);
|
||||
let result = from_child.recv();
|
||||
@ -113,6 +113,6 @@ fn main() {
|
||||
args.clone()
|
||||
};
|
||||
|
||||
info!("{:?}", args);
|
||||
println!("{:?}", args);
|
||||
run(args);
|
||||
}
|
||||
|
@ -57,7 +57,7 @@ fn thread_ring(i: uint, count: uint, num_chan: pipe, num_port: pipe) {
|
||||
let mut num_port = Some(num_port);
|
||||
// Send/Receive lots of messages.
|
||||
for j in range(0u, count) {
|
||||
//error!("task %?, iter %?", i, j);
|
||||
//println!("task %?, iter %?", i, j);
|
||||
let num_chan2 = num_chan.take_unwrap();
|
||||
let num_port2 = num_port.take_unwrap();
|
||||
send(&num_chan2, i * j);
|
||||
@ -89,7 +89,7 @@ fn main() {
|
||||
let mut futures = ~[];
|
||||
|
||||
for i in range(1u, num_tasks) {
|
||||
//error!("spawning %?", i);
|
||||
//println!("spawning %?", i);
|
||||
let (new_chan, num_port) = init();
|
||||
let num_chan_2 = num_chan.clone();
|
||||
let new_future = Future::spawn(proc() {
|
||||
|
@ -52,7 +52,7 @@ fn thread_ring(i: uint, count: uint, num_chan: pipe, num_port: pipe) {
|
||||
let mut num_port = Some(num_port);
|
||||
// Send/Receive lots of messages.
|
||||
for j in range(0u, count) {
|
||||
//error!("task %?, iter %?", i, j);
|
||||
//println!("task %?, iter %?", i, j);
|
||||
let num_chan2 = num_chan.take_unwrap();
|
||||
let num_port2 = num_port.take_unwrap();
|
||||
send(&num_chan2, i * j);
|
||||
@ -84,7 +84,7 @@ fn main() {
|
||||
let mut futures = ~[];
|
||||
|
||||
for i in range(1u, num_tasks) {
|
||||
//error!("spawning %?", i);
|
||||
//println!("spawning %?", i);
|
||||
let (new_chan, num_port) = init();
|
||||
let num_chan_2 = num_chan.clone();
|
||||
let new_future = Future::spawn(proc() {
|
||||
|
@ -70,7 +70,7 @@ fn stress_task(id: int) {
|
||||
let n = 15;
|
||||
assert_eq!(fib(n), fib(n));
|
||||
i += 1;
|
||||
error!("{}: Completed {} iterations", id, i);
|
||||
println!("{}: Completed {} iterations", id, i);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -41,7 +41,7 @@ fn roundtrip(id: int, n_tasks: int, p: &Receiver<int>, ch: &Sender<int>) {
|
||||
return;
|
||||
}
|
||||
token => {
|
||||
info!("thread: {} got token: {}", id, token);
|
||||
println!("thread: {} got token: {}", id, token);
|
||||
ch.send(token - 1);
|
||||
if token <= n_tasks {
|
||||
return;
|
||||
|
@ -34,11 +34,11 @@ fn main() {
|
||||
|
||||
fn run(repeat: int, depth: int) {
|
||||
for _ in range(0, repeat) {
|
||||
info!("starting {:.4f}", precise_time_s());
|
||||
println!("starting {:.4f}", precise_time_s());
|
||||
task::try(proc() {
|
||||
recurse_or_fail(depth, None)
|
||||
});
|
||||
info!("stopping {:.4f}", precise_time_s());
|
||||
println!("stopping {:.4f}", precise_time_s());
|
||||
}
|
||||
}
|
||||
|
||||
@ -71,7 +71,7 @@ fn r(l: @nillist) -> r {
|
||||
|
||||
fn recurse_or_fail(depth: int, st: Option<State>) {
|
||||
if depth == 0 {
|
||||
info!("unwinding {:.4f}", precise_time_s());
|
||||
println!("unwinding {:.4f}", precise_time_s());
|
||||
fail!();
|
||||
} else {
|
||||
let depth = depth - 1;
|
||||
|
@ -66,5 +66,5 @@ fn main() {
|
||||
let (sum_port, sum_chan) = stream::<int>();
|
||||
start_chan.send(sum_chan);
|
||||
let sum = sum_port.recv();
|
||||
error!("How many tasks? {} tasks.", sum);
|
||||
println!("How many tasks? {} tasks.", sum);
|
||||
}
|
||||
|
@ -11,7 +11,7 @@
|
||||
// ignore-fast #[feature] doesn't work with check-fast
|
||||
#[feature(asm)];
|
||||
|
||||
fn foo(x: int) { info!("{}", x); }
|
||||
fn foo(x: int) { println!("{}", x); }
|
||||
|
||||
#[cfg(target_arch = "x86")]
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
|
@ -11,7 +11,7 @@
|
||||
// ignore-fast #[feature] doesn't work with check-fast
|
||||
#[feature(asm)];
|
||||
|
||||
fn foo(x: int) { info!("{}", x); }
|
||||
fn foo(x: int) { println!("{}", x); }
|
||||
|
||||
#[cfg(target_arch = "x86")]
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
|
@ -11,7 +11,7 @@
|
||||
// ignore-fast #[feature] doesn't work with check-fast
|
||||
#[feature(asm)];
|
||||
|
||||
fn foo(x: int) { info!("{}", x); }
|
||||
fn foo(x: int) { println!("{}", x); }
|
||||
|
||||
#[cfg(target_arch = "x86")]
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
|
@ -11,7 +11,7 @@
|
||||
// ignore-fast #[feature] doesn't work with check-fast
|
||||
#[feature(asm)];
|
||||
|
||||
fn foo(x: int) { info!("{}", x); }
|
||||
fn foo(x: int) { println!("{}", x); }
|
||||
|
||||
#[cfg(target_arch = "x86")]
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
|
@ -11,9 +11,9 @@
|
||||
fn test() {
|
||||
let v: int;
|
||||
v = 1; //~ NOTE prior assignment occurs here
|
||||
info!("v={}", v);
|
||||
println!("v={}", v);
|
||||
v = 2; //~ ERROR re-assignment of immutable variable
|
||||
info!("v={}", v);
|
||||
println!("v={}", v);
|
||||
}
|
||||
|
||||
fn main() {
|
||||
|
@ -27,5 +27,5 @@ fn cat(in_x : uint, in_y : int) -> cat {
|
||||
|
||||
fn main() {
|
||||
let nyan : cat = cat(52u, 99);
|
||||
nyan.speak = || info!("meow"); //~ ERROR attempted to take value of method
|
||||
nyan.speak = || println!("meow"); //~ ERROR attempted to take value of method
|
||||
}
|
||||
|
@ -10,5 +10,5 @@
|
||||
|
||||
fn main() {
|
||||
#[attr] //~ ERROR expected item after attributes
|
||||
info!("hi");
|
||||
println!("hi");
|
||||
}
|
||||
|
@ -23,12 +23,12 @@ fn main() {
|
||||
let a: clam = clam{x: @1, y: @2};
|
||||
let b: clam = clam{x: @10, y: @20};
|
||||
let z: int = a.x + b.y; //~ ERROR binary operation `+` cannot be applied to type `@int`
|
||||
info!("{:?}", z);
|
||||
println!("{:?}", z);
|
||||
assert_eq!(z, 21);
|
||||
let forty: fish = fish{a: @40};
|
||||
let two: fish = fish{a: @2};
|
||||
let answer: int = forty.a + two.a;
|
||||
//~^ ERROR binary operation `+` cannot be applied to type `@int`
|
||||
info!("{:?}", answer);
|
||||
println!("{:?}", answer);
|
||||
assert_eq!(answer, 42);
|
||||
}
|
||||
|
@ -11,4 +11,4 @@
|
||||
// error-pattern:expected `~str` but found `int`
|
||||
|
||||
static i: ~str = 10i;
|
||||
fn main() { info!("{:?}", i); }
|
||||
fn main() { println!("{:?}", i); }
|
||||
|
@ -12,7 +12,7 @@ struct X { x: () }
|
||||
|
||||
impl Drop for X {
|
||||
fn drop(&mut self) {
|
||||
error!("destructor runs");
|
||||
println!("destructor runs");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -12,7 +12,7 @@ struct X { x: (), }
|
||||
|
||||
impl Drop for X {
|
||||
fn drop(&mut self) {
|
||||
error!("destructor runs");
|
||||
println!("destructor runs");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -12,7 +12,7 @@ struct X { x: (), }
|
||||
|
||||
impl Drop for X {
|
||||
fn drop(&mut self) {
|
||||
error!("destructor runs");
|
||||
println!("destructor runs");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -12,7 +12,7 @@ struct X { x: (), }
|
||||
|
||||
impl Drop for X {
|
||||
fn drop(&mut self) {
|
||||
error!("destructor runs");
|
||||
println!("destructor runs");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -12,7 +12,7 @@ struct X { x: (), }
|
||||
|
||||
impl Drop for X {
|
||||
fn drop(&mut self) {
|
||||
error!("destructor runs");
|
||||
println!("destructor runs");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -21,6 +21,6 @@ fn coerce(b: ||) -> extern fn() {
|
||||
|
||||
fn main() {
|
||||
let i = 8;
|
||||
let f = coerce(|| error!("{:?}", i) );
|
||||
let f = coerce(|| println!("{:?}", i) );
|
||||
f();
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user