10
10
use cast:: transmute;
11
11
use either:: * ;
12
12
use libc:: { c_void, uintptr_t, c_char, exit, STDERR_FILENO } ;
13
- use option:: { Some , None } ;
13
+ use option:: { Some , None , Option } ;
14
14
use rt:: util:: dumb_println;
15
15
use str:: StrSlice ;
16
16
use str:: raw:: from_c_str;
17
17
use u32;
18
+ use u32:: { min} ;
18
19
use unstable:: raw:: Closure ;
19
20
use vec:: ImmutableVector ;
20
21
@@ -30,7 +31,6 @@ struct ModEntry{
30
31
log_level : * mut u32
31
32
}
32
33
33
- static MAX_LOG_DIRECTIVES : u32 = 255 ;
34
34
static MAX_LOG_LEVEL : u32 = 255 ;
35
35
static DEFAULT_LOG_LEVEL : u32 = 1 ;
36
36
@@ -68,42 +68,68 @@ fn iter_crate_map(map: *u8, f: &fn(*mut ModEntry)) {
68
68
data : * c_void ) ;
69
69
}
70
70
}
71
+ static log_level_names : & ' static [ & ' static str ] = & ' static[ "error" , "warn" , "info" , "debug" ] ;
72
+
73
+ /// Parse an individual log level that is either a number or a symbolic log level
74
+ fn parse_log_level ( level : & str ) -> Option < u32 > {
75
+ let num = u32:: from_str ( level) ;
76
+ let mut log_level;
77
+ match ( num) {
78
+ Some ( num) => {
79
+ if num < MAX_LOG_LEVEL {
80
+ log_level = Some ( num) ;
81
+ } else {
82
+ log_level = Some ( MAX_LOG_LEVEL ) ;
83
+ }
84
+ }
85
+ _ => {
86
+ let position = log_level_names. iter ( ) . position ( |& name| name == level) ;
87
+ match ( position) {
88
+ Some ( position) => {
89
+ log_level = Some ( min ( MAX_LOG_LEVEL , ( position + 1 ) as u32 ) )
90
+ } ,
91
+ _ => {
92
+ log_level = None ;
93
+ }
94
+ }
95
+ }
96
+ }
97
+ log_level
98
+ }
99
+
71
100
72
101
/// Parse a logging specification string (e.g: "crate1,crate2::mod3,crate3::x=1")
73
102
/// and return a vector with log directives.
74
- /// Valid log levels are 0-255, with the most likely ones being 0-3 (defined in std::).
103
+ /// Valid log levels are 0-255, with the most likely ones being 1-4 (defined in std::).
104
+ /// Also supports string log levels of error, warn, info, and debug
105
+
75
106
fn parse_logging_spec ( spec : ~str ) -> ~[ LogDirective ] {
76
107
let mut dirs = ~[ ] ;
77
108
for s in spec. split_iter ( ',' ) {
78
109
let parts: ~[ & str ] = s. split_iter ( '=' ) . collect ( ) ;
79
- let mut loglevel ;
110
+ let mut log_level ;
80
111
match parts. len ( ) {
81
- 1 => loglevel = MAX_LOG_LEVEL ,
112
+ 1 => log_level = MAX_LOG_LEVEL ,
82
113
2 => {
83
- let num = u32 :: from_str ( parts[ 1 ] ) ;
84
- match ( num ) {
114
+ let possible_log_level = parse_log_level ( parts[ 1 ] ) ;
115
+ match possible_log_level {
85
116
Some ( num) => {
86
- if num < MAX_LOG_LEVEL {
87
- loglevel = num;
88
- } else {
89
- loglevel = MAX_LOG_LEVEL ;
90
- }
91
- }
117
+ log_level = num;
118
+ } ,
92
119
_ => {
93
- dumb_println ( fmt ! ( "warning: invalid logging spec \
94
- '%s', ignoring it", s ) ) ;
95
- loop ;
120
+ dumb_println ( fmt ! ( "warning: invalid logging spec \
121
+ '%s', ignoring it", parts [ 1 ] ) ) ;
122
+ loop ;
96
123
}
97
124
}
98
- if loglevel > MAX_LOG_LEVEL { loglevel = MAX_LOG_LEVEL }
99
125
} ,
100
126
_ => {
101
127
dumb_println ( fmt ! ( "warning: invalid logging spec '%s',\
102
128
ignoring it", s) ) ;
103
129
loop ;
104
130
}
105
131
}
106
- let dir = LogDirective { name : parts[ 0 ] . to_owned ( ) , level : loglevel } ;
132
+ let dir = LogDirective { name : parts[ 0 ] . to_owned ( ) , level : log_level } ;
107
133
dirs. push ( dir) ;
108
134
}
109
135
return dirs;
@@ -268,6 +294,15 @@ fn parse_logging_spec_invalid_log_level() {
268
294
assert_eq!(dirs[0].level, 4);
269
295
}
270
296
297
+ #[test]
298
+ fn parse_logging_spec_string_log_level() {
299
+ // test parse_logging_spec with 'warn' as log level
300
+ let dirs: ~[LogDirective] = parse_logging_spec(~" crate1:: mod1=wrong, crate2=warn");
301
+ assert_eq!(dirs.len(), 1);
302
+ assert!(dirs[0].name == ~" crate2");
303
+ assert_eq!(dirs[0].level, 2);
304
+ }
305
+
271
306
// Tests for update_entry
272
307
#[test]
273
308
fn update_entry_match_full_path() {
0 commit comments