Skip to content

Commit f6fcdbb

Browse files
committed
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.
2 parents abd844e + 0015cab commit f6fcdbb

File tree

392 files changed

+1709
-1880
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

392 files changed

+1709
-1880
lines changed

mk/crates.mk

+6-5
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@
5151

5252
TARGET_CRATES := std green rustuv native flate arena glob term semver \
5353
uuid serialize sync getopts collections num test time rand \
54-
workcache url
54+
workcache url log
5555
HOST_CRATES := syntax rustc rustdoc fourcc hexfloat
5656
CRATES := $(TARGET_CRATES) $(HOST_CRATES)
5757
TOOLS := compiletest rustdoc rustc
@@ -60,15 +60,15 @@ DEPS_std := native:rustrt native:compiler-rt native:backtrace
6060
DEPS_green := std rand native:context_switch
6161
DEPS_rustuv := std native:uv native:uv_support
6262
DEPS_native := std
63-
DEPS_syntax := std term serialize collections
63+
DEPS_syntax := std term serialize collections log
6464
DEPS_rustc := syntax native:rustllvm flate arena serialize sync getopts \
65-
collections time
65+
collections time log
6666
DEPS_rustdoc := rustc native:sundown serialize sync getopts collections \
6767
test time
6868
DEPS_flate := std native:miniz
6969
DEPS_arena := std collections
7070
DEPS_glob := std
71-
DEPS_serialize := std collections
71+
DEPS_serialize := std collections log
7272
DEPS_term := std collections
7373
DEPS_semver := std
7474
DEPS_uuid := std serialize rand
@@ -82,7 +82,8 @@ DEPS_test := std collections getopts serialize term time
8282
DEPS_time := std serialize
8383
DEPS_rand := std
8484
DEPS_url := std collections
85-
DEPS_workcache := std serialize collections std
85+
DEPS_workcache := std serialize collections log
86+
DEPS_log := std sync
8687

8788
TOOL_DEPS_compiletest := test green rustuv getopts
8889
TOOL_DEPS_rustdoc := rustdoc native

src/compiletest/compiletest.rs

+3
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,16 @@
99
// except according to those terms.
1010

1111
#[crate_type = "bin"];
12+
#[feature(phase)];
1213

1314
#[allow(non_camel_case_types)];
1415
#[deny(warnings)];
1516
#[allow(deprecated_owned_vector)];
1617

1718
extern crate test;
1819
extern crate getopts;
20+
#[phase(link, syntax)]
21+
extern crate log;
1922

2023
use std::os;
2124
use std::io;

src/doc/index.md

+1
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ li {list-style-type: none; }
5151
* [The `uuid` 128-bit universally unique identifier library](uuid/index.html)
5252
* [The `url` library](url/index.html)
5353
* [The `workcache` library](workcache/index.html)
54+
* [The `log` library](log/index.html)
5455

5556
# Tooling
5657

src/doc/rust.md

+4-1
Original file line numberDiff line numberDiff line change
@@ -1055,7 +1055,7 @@ output slot type would normally be. For example:
10551055

10561056
~~~~
10571057
fn my_err(s: &str) -> ! {
1058-
info!("{}", s);
1058+
println!("{}", s);
10591059
fail!();
10601060
}
10611061
~~~~
@@ -3885,6 +3885,9 @@ Rust provides several macros to log information. Here's a simple Rust program
38853885
that demonstrates all four of them:
38863886

38873887
~~~~
3888+
#[feature(phase)];
3889+
#[phase(syntax, link)] extern crate log;
3890+
38883891
fn main() {
38893892
error!("This is an error log")
38903893
warn!("This is a warn log")

src/doc/tutorial.md

+3-3
Original file line numberDiff line numberDiff line change
@@ -796,7 +796,7 @@ unit, `()`, as the empty tuple if you like).
796796
~~~~
797797
let mytup: (int, int, f64) = (10, 20, 30.0);
798798
match mytup {
799-
(a, b, c) => info!("{}", a + b + (c as int))
799+
(a, b, c) => println!("{}", a + b + (c as int))
800800
}
801801
~~~~
802802

@@ -813,7 +813,7 @@ For example:
813813
struct MyTup(int, int, f64);
814814
let mytup: MyTup = MyTup(10, 20, 30.0);
815815
match mytup {
816-
MyTup(a, b, c) => info!("{}", a + b + (c as int))
816+
MyTup(a, b, c) => println!("{}", a + b + (c as int))
817817
}
818818
~~~~
819819

@@ -1794,7 +1794,7 @@ use std::task::spawn;
17941794
17951795
// proc is the closure which will be spawned.
17961796
spawn(proc() {
1797-
debug!("I'm a new task")
1797+
println!("I'm a new task")
17981798
});
17991799
~~~~
18001800

src/libcollections/lib.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
html_favicon_url = "http://www.rust-lang.org/favicon.ico",
2121
html_root_url = "http://static.rust-lang.org/doc/master")];
2222

23-
#[feature(macro_rules, managed_boxes, default_type_params)];
23+
#[feature(macro_rules, managed_boxes, default_type_params, phase)];
2424

2525
// NOTE remove the following two attributes after the next snapshot.
2626
#[allow(unrecognized_lint)];
@@ -30,6 +30,7 @@
3030
extern crate rand;
3131

3232
#[cfg(test)] extern crate test;
33+
#[cfg(test)] #[phase(syntax, link)] extern crate log;
3334

3435
pub use bitv::Bitv;
3536
pub use btree::BTree;

src/libflate/lib.rs

+3
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ Simple compression
2121
#[doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
2222
html_favicon_url = "http://www.rust-lang.org/favicon.ico",
2323
html_root_url = "http://static.rust-lang.org/doc/master")];
24+
#[feature(phase)];
25+
26+
#[cfg(test)] #[phase(syntax, link)] extern crate log;
2427

2528
use std::libc::{c_void, size_t, c_int};
2629
use std::libc;

src/libgetopts/lib.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,9 @@
8686
#[allow(missing_doc)];
8787
#[allow(deprecated_owned_vector)];
8888

89-
#[feature(globs)];
89+
#[feature(globs, phase)];
90+
91+
#[cfg(test)] #[phase(syntax, link)] extern crate log;
9092

9193
use std::cmp::Eq;
9294
use std::result::{Err, Ok};

src/libgreen/lib.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -172,10 +172,11 @@
172172
html_root_url = "http://static.rust-lang.org/doc/master")];
173173

174174
// NB this does *not* include globs, please keep it that way.
175-
#[feature(macro_rules)];
175+
#[feature(macro_rules, phase)];
176176
#[allow(visible_private_types)];
177177
#[allow(deprecated_owned_vector)];
178178

179+
#[cfg(test)] #[phase(syntax, link)] extern crate log;
179180
extern crate rand;
180181

181182
use std::mem::replace;

src/libgreen/task.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -178,14 +178,13 @@ impl GreenTask {
178178
f: proc()) -> ~GreenTask {
179179
let TaskOpts {
180180
notify_chan, name, stack_size,
181-
stderr, stdout, logger,
181+
stderr, stdout,
182182
} = opts;
183183

184184
let mut green = GreenTask::new(pool, stack_size, f);
185185
{
186186
let task = green.task.get_mut_ref();
187187
task.name = name;
188-
task.logger = logger;
189188
task.stderr = stderr;
190189
task.stdout = stdout;
191190
match notify_chan {

src/liblog/directive.rs

+134
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
use std::cmp;
12+
use std::vec_ng::Vec;
13+
14+
#[deriving(Show, Clone)]
15+
pub struct LogDirective {
16+
name: Option<~str>,
17+
level: u32,
18+
}
19+
20+
static LOG_LEVEL_NAMES: [&'static str, ..4] = ["error", "warn", "info",
21+
"debug"];
22+
23+
/// Parse an individual log level that is either a number or a symbolic log level
24+
fn parse_log_level(level: &str) -> Option<u32> {
25+
from_str::<u32>(level).or_else(|| {
26+
let pos = LOG_LEVEL_NAMES.iter().position(|&name| name == level);
27+
pos.map(|p| p as u32 + 1)
28+
}).map(|p| cmp::min(p, ::MAX_LOG_LEVEL))
29+
}
30+
31+
/// Parse a logging specification string (e.g: "crate1,crate2::mod3,crate3::x=1")
32+
/// and return a vector with log directives.
33+
///
34+
/// Valid log levels are 0-255, with the most likely ones being 1-4 (defined in
35+
/// std::). Also supports string log levels of error, warn, info, and debug
36+
pub fn parse_logging_spec(spec: &str) -> Vec<LogDirective> {
37+
let mut dirs = Vec::new();
38+
for s in spec.split(',') {
39+
if s.len() == 0 { continue }
40+
let mut parts = s.split('=');
41+
let (log_level, name) = match (parts.next(), parts.next(), parts.next()) {
42+
(Some(part0), None, None) => {
43+
// if the single argument is a log-level string or number,
44+
// treat that as a global fallback
45+
match parse_log_level(part0) {
46+
Some(num) => (num, None),
47+
None => (::MAX_LOG_LEVEL, Some(part0)),
48+
}
49+
}
50+
(Some(part0), Some(part1), None) => {
51+
match parse_log_level(part1) {
52+
Some(num) => (num, Some(part0)),
53+
_ => {
54+
println!("warning: invalid logging spec '{}', \
55+
ignoring it", part1);
56+
continue
57+
}
58+
}
59+
},
60+
_ => {
61+
println!("warning: invalid logging spec '{}', \
62+
ignoring it", s);
63+
continue
64+
}
65+
};
66+
dirs.push(LogDirective {
67+
name: name.map(|s| s.to_owned()),
68+
level: log_level,
69+
});
70+
}
71+
return dirs;
72+
}
73+
74+
#[cfg(test)]
75+
mod tests {
76+
use super::parse_logging_spec;
77+
78+
#[test]
79+
fn parse_logging_spec_valid() {
80+
let dirs = parse_logging_spec("crate1::mod1=1,crate1::mod2,crate2=4");
81+
let dirs = dirs.as_slice();
82+
assert_eq!(dirs.len(), 3);
83+
assert_eq!(dirs[0].name, Some(~"crate1::mod1"));
84+
assert_eq!(dirs[0].level, 1);
85+
86+
assert_eq!(dirs[1].name, Some(~"crate1::mod2"));
87+
assert_eq!(dirs[1].level, ::MAX_LOG_LEVEL);
88+
89+
assert_eq!(dirs[2].name, Some(~"crate2"));
90+
assert_eq!(dirs[2].level, 4);
91+
}
92+
93+
#[test]
94+
fn parse_logging_spec_invalid_crate() {
95+
// test parse_logging_spec with multiple = in specification
96+
let dirs = parse_logging_spec("crate1::mod1=1=2,crate2=4");
97+
let dirs = dirs.as_slice();
98+
assert_eq!(dirs.len(), 1);
99+
assert_eq!(dirs[0].name, Some(~"crate2"));
100+
assert_eq!(dirs[0].level, 4);
101+
}
102+
103+
#[test]
104+
fn parse_logging_spec_invalid_log_level() {
105+
// test parse_logging_spec with 'noNumber' as log level
106+
let dirs = parse_logging_spec("crate1::mod1=noNumber,crate2=4");
107+
let dirs = dirs.as_slice();
108+
assert_eq!(dirs.len(), 1);
109+
assert_eq!(dirs[0].name, Some(~"crate2"));
110+
assert_eq!(dirs[0].level, 4);
111+
}
112+
113+
#[test]
114+
fn parse_logging_spec_string_log_level() {
115+
// test parse_logging_spec with 'warn' as log level
116+
let dirs = parse_logging_spec("crate1::mod1=wrong,crate2=warn");
117+
let dirs = dirs.as_slice();
118+
assert_eq!(dirs.len(), 1);
119+
assert_eq!(dirs[0].name, Some(~"crate2"));
120+
assert_eq!(dirs[0].level, ::WARN);
121+
}
122+
123+
#[test]
124+
fn parse_logging_spec_global() {
125+
// test parse_logging_spec with no crate
126+
let dirs = parse_logging_spec("warn,crate2=4");
127+
let dirs = dirs.as_slice();
128+
assert_eq!(dirs.len(), 2);
129+
assert_eq!(dirs[0].name, None);
130+
assert_eq!(dirs[0].level, 2);
131+
assert_eq!(dirs[1].name, Some(~"crate2"));
132+
assert_eq!(dirs[1].level, 4);
133+
}
134+
}

0 commit comments

Comments
 (0)