Handle global log levels (fixes #6033)
This commit is contained in:
parent
c891fa326d
commit
c684df103e
1 changed files with 100 additions and 36 deletions
|
|
@ -15,13 +15,12 @@ use rt::util::dumb_println;
|
|||
use str::StrSlice;
|
||||
use str::raw::from_c_str;
|
||||
use u32;
|
||||
use u32::{min};
|
||||
use unstable::raw::Closure;
|
||||
use vec::ImmutableVector;
|
||||
|
||||
|
||||
struct LogDirective {
|
||||
name: ~str,
|
||||
name: Option<~str>,
|
||||
level: u32
|
||||
}
|
||||
|
||||
|
|
@ -74,7 +73,7 @@ static log_level_names : &'static[&'static str] = &'static["error", "warn", "inf
|
|||
fn parse_log_level(level: &str) -> Option<u32> {
|
||||
let num = u32::from_str(level);
|
||||
let mut log_level;
|
||||
match (num) {
|
||||
match num {
|
||||
Some(num) => {
|
||||
if num < MAX_LOG_LEVEL {
|
||||
log_level = Some(num);
|
||||
|
|
@ -84,9 +83,9 @@ fn parse_log_level(level: &str) -> Option<u32> {
|
|||
}
|
||||
_ => {
|
||||
let position = log_level_names.iter().position(|&name| name == level);
|
||||
match (position) {
|
||||
match position {
|
||||
Some(position) => {
|
||||
log_level = Some(min(MAX_LOG_LEVEL, (position + 1) as u32))
|
||||
log_level = Some(u32::min(MAX_LOG_LEVEL, (position + 1) as u32))
|
||||
},
|
||||
_ => {
|
||||
log_level = None;
|
||||
|
|
@ -108,8 +107,22 @@ fn parse_logging_spec(spec: ~str) -> ~[LogDirective]{
|
|||
for s in spec.split_iter(',') {
|
||||
let parts: ~[&str] = s.split_iter('=').collect();
|
||||
let mut log_level;
|
||||
let mut name = Some(parts[0].to_owned());
|
||||
match parts.len() {
|
||||
1 => log_level = MAX_LOG_LEVEL,
|
||||
1 => {
|
||||
//if the single argument is a log-level string or number,
|
||||
//treat that as a global fallback
|
||||
let possible_log_level = parse_log_level(parts[0]);
|
||||
match possible_log_level {
|
||||
Some(num) => {
|
||||
name = None;
|
||||
log_level = num;
|
||||
},
|
||||
_ => {
|
||||
log_level = MAX_LOG_LEVEL
|
||||
}
|
||||
}
|
||||
}
|
||||
2 => {
|
||||
let possible_log_level = parse_log_level(parts[1]);
|
||||
match possible_log_level {
|
||||
|
|
@ -129,7 +142,7 @@ fn parse_logging_spec(spec: ~str) -> ~[LogDirective]{
|
|||
loop;
|
||||
}
|
||||
}
|
||||
let dir = LogDirective {name: parts[0].to_owned(), level: log_level};
|
||||
let dir = LogDirective {name: name, level: log_level};
|
||||
dirs.push(dir);
|
||||
}
|
||||
return dirs;
|
||||
|
|
@ -139,18 +152,30 @@ fn parse_logging_spec(spec: ~str) -> ~[LogDirective]{
|
|||
/// of log directives
|
||||
fn update_entry(dirs: &[LogDirective], entry: *mut ModEntry) -> u32 {
|
||||
let mut new_lvl: u32 = DEFAULT_LOG_LEVEL;
|
||||
let mut longest_match = 0;
|
||||
let mut longest_match = -1i;
|
||||
unsafe {
|
||||
for dir in dirs.iter() {
|
||||
let name = from_c_str((*entry).name);
|
||||
if name.starts_with(dir.name) && dir.name.len() > longest_match {
|
||||
longest_match = dir.name.len();
|
||||
new_lvl = dir.level;
|
||||
}
|
||||
match dir.name {
|
||||
None => {
|
||||
if longest_match == -1 {
|
||||
longest_match = 0;
|
||||
new_lvl = dir.level;
|
||||
}
|
||||
}
|
||||
Some(ref dir_name) => {
|
||||
let name = from_c_str((*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;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
*(*entry).log_level = new_lvl;
|
||||
}
|
||||
if longest_match > 0 { return 1; } else { return 0; }
|
||||
if longest_match >= 0 { return 1; } else { return 0; }
|
||||
}
|
||||
|
||||
#[fixed_stack_segment] #[inline(never)]
|
||||
|
|
@ -264,54 +289,66 @@ extern {
|
|||
// Tests for parse_logging_spec()
|
||||
#[test]
|
||||
fn parse_logging_spec_valid() {
|
||||
let dirs: ~[LogDirective] = parse_logging_spec(~"crate1::mod1=1,crate1::mod2,crate2=4");
|
||||
let dirs = parse_logging_spec(~"crate1::mod1=1,crate1::mod2,crate2=4");
|
||||
assert_eq!(dirs.len(), 3);
|
||||
assert!(dirs[0].name == ~"crate1::mod1");
|
||||
assert!(dirs[0].name == Some(~"crate1::mod1"));
|
||||
assert_eq!(dirs[0].level, 1);
|
||||
|
||||
assert!(dirs[1].name == ~"crate1::mod2");
|
||||
assert!(dirs[1].name == Some(~"crate1::mod2"));
|
||||
assert_eq!(dirs[1].level, MAX_LOG_LEVEL);
|
||||
|
||||
assert!(dirs[2].name == ~"crate2");
|
||||
assert!(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: ~[LogDirective] = parse_logging_spec(~"crate1::mod1=1=2,crate2=4");
|
||||
let dirs = parse_logging_spec(~"crate1::mod1=1=2,crate2=4");
|
||||
assert_eq!(dirs.len(), 1);
|
||||
assert!(dirs[0].name == ~"crate2");
|
||||
assert!(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: ~[LogDirective] = parse_logging_spec(~"crate1::mod1=noNumber,crate2=4");
|
||||
let dirs = parse_logging_spec(~"crate1::mod1=noNumber,crate2=4");
|
||||
assert_eq!(dirs.len(), 1);
|
||||
assert!(dirs[0].name == ~"crate2");
|
||||
assert!(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: ~[LogDirective] = parse_logging_spec(~"crate1::mod1=wrong,crate2=warn");
|
||||
let dirs = parse_logging_spec(~"crate1::mod1=wrong,crate2=warn");
|
||||
assert_eq!(dirs.len(), 1);
|
||||
assert!(dirs[0].name == ~"crate2");
|
||||
assert!(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");
|
||||
assert_eq!(dirs.len(), 2);
|
||||
assert!(dirs[0].name == None);
|
||||
assert_eq!(dirs[0].level, 2);
|
||||
assert!(dirs[1].name == Some(~"crate2"));
|
||||
assert_eq!(dirs[1].level, 4);
|
||||
}
|
||||
|
||||
// Tests for update_entry
|
||||
#[test]
|
||||
fn update_entry_match_full_path() {
|
||||
use c_str::ToCStr;
|
||||
let dirs = ~[LogDirective {name: ~"crate1::mod1", level: 2 },
|
||||
LogDirective {name: ~"crate2", level: 3}];
|
||||
let dirs = ~[LogDirective {name: Some(~"crate1::mod1"), level: 2 },
|
||||
LogDirective {name: Some(~"crate2"), level: 3}];
|
||||
let level = &mut 0;
|
||||
unsafe {
|
||||
do "crate1::mod1".to_c_str().with_ref |ptr| {
|
||||
let entry= &ModEntry {name: ptr, log_level: &mut 0};
|
||||
let entry= &ModEntry {name: ptr, log_level: level};
|
||||
let m = update_entry(dirs, transmute(entry));
|
||||
assert!(*entry.log_level == 2);
|
||||
assert!(m == 1);
|
||||
|
|
@ -322,11 +359,12 @@ fn update_entry_match_full_path() {
|
|||
#[test]
|
||||
fn update_entry_no_match() {
|
||||
use c_str::ToCStr;
|
||||
let dirs = ~[LogDirective {name: ~"crate1::mod1", level: 2 },
|
||||
LogDirective {name: ~"crate2", level: 3}];
|
||||
let dirs = ~[LogDirective {name: Some(~"crate1::mod1"), level: 2 },
|
||||
LogDirective {name: Some(~"crate2"), level: 3}];
|
||||
let level = &mut 0;
|
||||
unsafe {
|
||||
do "crate3::mod1".to_c_str().with_ref |ptr| {
|
||||
let entry= &ModEntry {name: ptr, log_level: &mut 0};
|
||||
let entry= &ModEntry {name: ptr, log_level: level};
|
||||
let m = update_entry(dirs, transmute(entry));
|
||||
assert!(*entry.log_level == DEFAULT_LOG_LEVEL);
|
||||
assert!(m == 0);
|
||||
|
|
@ -337,11 +375,12 @@ fn update_entry_no_match() {
|
|||
#[test]
|
||||
fn update_entry_match_beginning() {
|
||||
use c_str::ToCStr;
|
||||
let dirs = ~[LogDirective {name: ~"crate1::mod1", level: 2 },
|
||||
LogDirective {name: ~"crate2", level: 3}];
|
||||
let dirs = ~[LogDirective {name: Some(~"crate1::mod1"), level: 2 },
|
||||
LogDirective {name: Some(~"crate2"), level: 3}];
|
||||
let level = &mut 0;
|
||||
unsafe {
|
||||
do "crate2::mod1".to_c_str().with_ref |ptr| {
|
||||
let entry= &ModEntry {name: ptr, log_level: &mut 0};
|
||||
let entry= &ModEntry {name: ptr, log_level: level};
|
||||
let m = update_entry(dirs, transmute(entry));
|
||||
assert!(*entry.log_level == 3);
|
||||
assert!(m == 1);
|
||||
|
|
@ -352,14 +391,39 @@ fn update_entry_match_beginning() {
|
|||
#[test]
|
||||
fn update_entry_match_beginning_longest_match() {
|
||||
use c_str::ToCStr;
|
||||
let dirs = ~[LogDirective {name: ~"crate1::mod1", level: 2 },
|
||||
LogDirective {name: ~"crate2", level: 3}, LogDirective {name: ~"crate2::mod", level: 4}];
|
||||
let dirs = ~[LogDirective {name: Some(~"crate1::mod1"), level: 2 },
|
||||
LogDirective {name: Some(~"crate2"), level: 3},
|
||||
LogDirective {name: Some(~"crate2::mod"), level: 4}];
|
||||
let level = &mut 0;
|
||||
unsafe {
|
||||
do "crate2::mod1".to_c_str().with_ref |ptr| {
|
||||
let entry = &ModEntry {name: ptr, log_level: &mut 0};
|
||||
let entry = &ModEntry {name: ptr, log_level: level};
|
||||
let m = update_entry(dirs, transmute(entry));
|
||||
assert!(*entry.log_level == 4);
|
||||
assert!(m == 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn update_entry_match_default() {
|
||||
use c_str::ToCStr;
|
||||
let dirs = ~[LogDirective {name: Some(~"crate1::mod1"), level: 2 },
|
||||
LogDirective {name: None, level: 3}
|
||||
];
|
||||
let level = &mut 0;
|
||||
unsafe {
|
||||
do "crate1::mod1".to_c_str().with_ref |ptr| {
|
||||
let entry= &ModEntry {name: ptr, log_level: level};
|
||||
let m = update_entry(dirs, transmute(entry));
|
||||
assert!(*entry.log_level == 2);
|
||||
assert!(m == 1);
|
||||
}
|
||||
do "crate2::mod2".to_c_str().with_ref |ptr| {
|
||||
let entry= &ModEntry {name: ptr, log_level: level};
|
||||
let m = update_entry(dirs, transmute(entry));
|
||||
assert!(*entry.log_level == 3);
|
||||
assert!(m == 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue