about summary refs log tree commit diff
path: root/src/libstd/rt
diff options
context:
space:
mode:
authornovalis <novalis@novalis.org>2013-09-05 21:18:55 -0400
committernovalis <novalis@novalis.org>2013-09-07 09:14:52 -0400
commitc684df103e05a15d4e0403b5fca1197f16d15703 (patch)
tree23f761a8426877be5aa85ec0cbeb80ee03b4375f /src/libstd/rt
parentc891fa326d28818582a653e588463c45f82e5795 (diff)
downloadrust-c684df103e05a15d4e0403b5fca1197f16d15703.tar.gz
rust-c684df103e05a15d4e0403b5fca1197f16d15703.zip
Handle global log levels (fixes #6033)
Diffstat (limited to 'src/libstd/rt')
-rw-r--r--src/libstd/rt/logging.rs136
1 files changed, 100 insertions, 36 deletions
diff --git a/src/libstd/rt/logging.rs b/src/libstd/rt/logging.rs
index a9fd43c23af..8a4aba3eb87 100644
--- a/src/libstd/rt/logging.rs
+++ b/src/libstd/rt/logging.rs
@@ -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);
+        }
+    }
+}