@@ -15,13 +15,12 @@ use rt::util::dumb_println;
1515use str:: StrSlice ;
1616use str:: raw:: from_c_str;
1717use u32;
18- use u32:: { min} ;
1918use unstable:: raw:: Closure ;
2019use vec:: ImmutableVector ;
2120
2221
2322struct LogDirective {
24- name : ~str ,
23+ name : Option < ~str > ,
2524 level : u32
2625}
2726
@@ -74,7 +73,7 @@ static log_level_names : &'static[&'static str] = &'static["error", "warn", "inf
7473fn parse_log_level ( level : & str ) -> Option < u32 > {
7574 let num = u32:: from_str ( level) ;
7675 let mut log_level;
77- match ( num) {
76+ match num {
7877 Some ( num) => {
7978 if num < MAX_LOG_LEVEL {
8079 log_level = Some ( num) ;
@@ -84,9 +83,9 @@ fn parse_log_level(level: &str) -> Option<u32> {
8483 }
8584 _ => {
8685 let position = log_level_names. iter ( ) . position ( |& name| name == level) ;
87- match ( position) {
86+ match position {
8887 Some ( position) => {
89- log_level = Some ( min ( MAX_LOG_LEVEL , ( position + 1 ) as u32 ) )
88+ log_level = Some ( u32 :: min ( MAX_LOG_LEVEL , ( position + 1 ) as u32 ) )
9089 } ,
9190 _ => {
9291 log_level = None ;
@@ -108,8 +107,22 @@ fn parse_logging_spec(spec: ~str) -> ~[LogDirective]{
108107 for s in spec. split_iter ( ',' ) {
109108 let parts: ~[ & str ] = s. split_iter ( '=' ) . collect ( ) ;
110109 let mut log_level;
110+ let mut name = Some ( parts[ 0 ] . to_owned ( ) ) ;
111111 match parts. len ( ) {
112- 1 => log_level = MAX_LOG_LEVEL ,
112+ 1 => {
113+ //if the single argument is a log-level string or number,
114+ //treat that as a global fallback
115+ let possible_log_level = parse_log_level ( parts[ 0 ] ) ;
116+ match possible_log_level {
117+ Some ( num) => {
118+ name = None ;
119+ log_level = num;
120+ } ,
121+ _ => {
122+ log_level = MAX_LOG_LEVEL
123+ }
124+ }
125+ }
113126 2 => {
114127 let possible_log_level = parse_log_level ( parts[ 1 ] ) ;
115128 match possible_log_level {
@@ -129,7 +142,7 @@ fn parse_logging_spec(spec: ~str) -> ~[LogDirective]{
129142 loop ;
130143 }
131144 }
132- let dir = LogDirective { name : parts [ 0 ] . to_owned ( ) , level : log_level} ;
145+ let dir = LogDirective { name : name , level : log_level} ;
133146 dirs. push ( dir) ;
134147 }
135148 return dirs;
@@ -139,18 +152,30 @@ fn parse_logging_spec(spec: ~str) -> ~[LogDirective]{
139152/// of log directives
140153fn update_entry ( dirs : & [ LogDirective ] , entry : * mut ModEntry ) -> u32 {
141154 let mut new_lvl: u32 = DEFAULT_LOG_LEVEL ;
142- let mut longest_match = 0 ;
155+ let mut longest_match = - 1 i ;
143156 unsafe {
144157 for dir in dirs. iter ( ) {
145- let name = from_c_str ( ( * entry) . name ) ;
146- if name. starts_with ( dir. name ) && dir. name . len ( ) > longest_match {
147- longest_match = dir. name . len ( ) ;
148- new_lvl = dir. level ;
149- }
158+ match dir. name {
159+ None => {
160+ if longest_match == -1 {
161+ longest_match = 0 ;
162+ new_lvl = dir. level ;
163+ }
164+ }
165+ Some ( ref dir_name) => {
166+ let name = from_c_str ( ( * entry) . name ) ;
167+ let len = dir_name. len ( ) as int ;
168+ if name. starts_with ( * dir_name) &&
169+ len >= longest_match {
170+ longest_match = len;
171+ new_lvl = dir. level ;
172+ }
173+ }
174+ } ;
150175 }
151176 * ( * entry) . log_level = new_lvl;
152177 }
153- if longest_match > 0 { return 1 ; } else { return 0 ; }
178+ if longest_match >= 0 { return 1 ; } else { return 0 ; }
154179}
155180
156181#[ fixed_stack_segment] #[ inline( never) ]
@@ -264,54 +289,66 @@ extern {
264289// Tests for parse_logging_spec()
265290#[ test]
266291fn parse_logging_spec_valid( ) {
267- let dirs: ~ [ LogDirective ] = parse_logging_spec ( ~"crate1:: mod1=1 , crate1:: mod2, crate2=4 ") ;
292+ let dirs = parse_logging_spec ( ~"crate1:: mod1=1 , crate1:: mod2, crate2=4 ") ;
268293 assert_eq ! ( dirs. len( ) , 3 ) ;
269- assert ! ( dirs[ 0 ] . name == ~"crate1:: mod1");
294+ assert!( dirs[ 0 ] . name == Some ( ~"crate1:: mod1") );
270295 assert_eq!(dirs[0].level, 1);
271296
272- assert!(dirs[1].name == ~" crate1:: mod2");
297+ assert!(dirs[1].name == Some( ~" crate1:: mod2") );
273298 assert_eq!(dirs[1].level, MAX_LOG_LEVEL);
274299
275- assert!(dirs[2].name == ~" crate2");
300+ assert!(dirs[2].name == Some( ~" crate2") );
276301 assert_eq!(dirs[2].level, 4);
277302}
278303
279304#[test]
280305fn parse_logging_spec_invalid_crate() {
281306 // test parse_logging_spec with multiple = in specification
282- let dirs: ~[LogDirective] = parse_logging_spec(~" crate1:: mod1=1 =2 , crate2=4 ");
307+ let dirs = parse_logging_spec(~" crate1:: mod1=1 =2 , crate2=4 ");
283308 assert_eq!(dirs.len(), 1);
284- assert!(dirs[0].name == ~" crate2");
309+ assert!(dirs[0].name == Some( ~" crate2") );
285310 assert_eq!(dirs[0].level, 4);
286311}
287312
288313#[test]
289314fn parse_logging_spec_invalid_log_level() {
290315 // test parse_logging_spec with 'noNumber' as log level
291- let dirs: ~[LogDirective] = parse_logging_spec(~" crate1:: mod1=noNumber, crate2=4 ");
316+ let dirs = parse_logging_spec(~" crate1:: mod1=noNumber, crate2=4 ");
292317 assert_eq!(dirs.len(), 1);
293- assert!(dirs[0].name == ~" crate2");
318+ assert!(dirs[0].name == Some( ~" crate2") );
294319 assert_eq!(dirs[0].level, 4);
295320}
296321
297322#[test]
298323fn parse_logging_spec_string_log_level() {
299324 // test parse_logging_spec with 'warn' as log level
300- let dirs: ~[LogDirective] = parse_logging_spec(~" crate1:: mod1=wrong, crate2=warn");
325+ let dirs = parse_logging_spec(~" crate1:: mod1=wrong, crate2=warn");
301326 assert_eq!(dirs.len(), 1);
302- assert!(dirs[0].name == ~" crate2");
327+ assert!(dirs[0].name == Some( ~" crate2") );
303328 assert_eq!(dirs[0].level, 2);
304329}
305330
331+ #[test]
332+ fn parse_logging_spec_global() {
333+ // test parse_logging_spec with no crate
334+ let dirs = parse_logging_spec(~" warn, crate2=4 ");
335+ assert_eq!(dirs.len(), 2);
336+ assert!(dirs[0].name == None);
337+ assert_eq!(dirs[0].level, 2);
338+ assert!(dirs[1].name == Some(~" crate2"));
339+ assert_eq!(dirs[1].level, 4);
340+ }
341+
306342// Tests for update_entry
307343#[test]
308344fn update_entry_match_full_path() {
309345 use c_str::ToCStr;
310- let dirs = ~[LogDirective {name: ~" crate1:: mod1", level: 2 },
311- LogDirective {name: ~" crate2", level: 3}];
346+ let dirs = ~[LogDirective {name: Some(~" crate1:: mod1"), level: 2 },
347+ LogDirective {name: Some(~" crate2"), level: 3}];
348+ let level = &mut 0;
312349 unsafe {
313350 do " crate1:: mod1".to_c_str().with_ref |ptr| {
314- let entry= &ModEntry {name: ptr, log_level: &mut 0 };
351+ let entry= &ModEntry {name: ptr, log_level: level };
315352 let m = update_entry(dirs, transmute(entry));
316353 assert!(*entry.log_level == 2);
317354 assert!(m == 1);
@@ -322,11 +359,12 @@ fn update_entry_match_full_path() {
322359#[test]
323360fn update_entry_no_match() {
324361 use c_str::ToCStr;
325- let dirs = ~[LogDirective {name: ~" crate1:: mod1", level: 2 },
326- LogDirective {name: ~" crate2", level: 3}];
362+ let dirs = ~[LogDirective {name: Some(~" crate1:: mod1"), level: 2 },
363+ LogDirective {name: Some(~" crate2"), level: 3}];
364+ let level = &mut 0;
327365 unsafe {
328366 do " crate3:: mod1".to_c_str().with_ref |ptr| {
329- let entry= &ModEntry {name: ptr, log_level: &mut 0 };
367+ let entry= &ModEntry {name: ptr, log_level: level };
330368 let m = update_entry(dirs, transmute(entry));
331369 assert!(*entry.log_level == DEFAULT_LOG_LEVEL);
332370 assert!(m == 0);
@@ -337,11 +375,12 @@ fn update_entry_no_match() {
337375#[test]
338376fn update_entry_match_beginning() {
339377 use c_str::ToCStr;
340- let dirs = ~[LogDirective {name: ~" crate1:: mod1", level: 2 },
341- LogDirective {name: ~" crate2", level: 3}];
378+ let dirs = ~[LogDirective {name: Some(~" crate1:: mod1"), level: 2 },
379+ LogDirective {name: Some(~" crate2"), level: 3}];
380+ let level = &mut 0;
342381 unsafe {
343382 do " crate2:: mod1".to_c_str().with_ref |ptr| {
344- let entry= &ModEntry {name: ptr, log_level: &mut 0 };
383+ let entry= &ModEntry {name: ptr, log_level: level };
345384 let m = update_entry(dirs, transmute(entry));
346385 assert!(*entry.log_level == 3);
347386 assert!(m == 1);
@@ -352,14 +391,39 @@ fn update_entry_match_beginning() {
352391#[test]
353392fn update_entry_match_beginning_longest_match() {
354393 use c_str::ToCStr;
355- let dirs = ~[LogDirective {name: ~" crate1:: mod1", level: 2 },
356- LogDirective {name: ~" crate2", level: 3}, LogDirective {name: ~" crate2:: mod ", level: 4}];
394+ let dirs = ~[LogDirective {name: Some(~" crate1:: mod1"), level: 2 },
395+ LogDirective {name: Some(~" crate2"), level: 3},
396+ LogDirective {name: Some(~" crate2:: mod "), level: 4}];
397+ let level = &mut 0;
357398 unsafe {
358399 do " crate2:: mod1".to_c_str().with_ref |ptr| {
359- let entry = & ModEntry { name: ptr, log_level: & mut 0 } ;
400+ let entry = &ModEntry {name: ptr, log_level: level };
360401 let m = update_entry(dirs, transmute(entry));
361402 assert!(*entry.log_level == 4);
362403 assert!(m == 1);
363404 }
364405 }
365406}
407+
408+ #[test]
409+ fn update_entry_match_default() {
410+ use c_str::ToCStr;
411+ let dirs = ~[LogDirective {name: Some(~" crate1:: mod1"), level: 2 },
412+ LogDirective {name: None, level: 3}
413+ ];
414+ let level = &mut 0;
415+ unsafe {
416+ do " crate1:: mod1".to_c_str().with_ref |ptr| {
417+ let entry= &ModEntry {name: ptr, log_level: level};
418+ let m = update_entry(dirs, transmute(entry));
419+ assert!(*entry.log_level == 2);
420+ assert!(m == 1);
421+ }
422+ do " crate2:: mod2" . to_c_str( ) . with_ref |ptr| {
423+ let entry= & ModEntry { name: ptr, log_level: level} ;
424+ let m = update_entry( dirs, transmute( entry) ) ;
425+ assert!( * entry. log_level == 3 ) ;
426+ assert!( m == 1 ) ;
427+ }
428+ }
429+ }
0 commit comments