@@ -15,13 +15,12 @@ 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} ;
19
18
use unstable:: raw:: Closure ;
20
19
use vec:: ImmutableVector ;
21
20
22
21
23
22
struct LogDirective {
24
- name : ~str ,
23
+ name : Option < ~str > ,
25
24
level : u32
26
25
}
27
26
@@ -74,7 +73,7 @@ static log_level_names : &'static[&'static str] = &'static["error", "warn", "inf
74
73
fn parse_log_level ( level : & str ) -> Option < u32 > {
75
74
let num = u32:: from_str ( level) ;
76
75
let mut log_level;
77
- match ( num) {
76
+ match num {
78
77
Some ( num) => {
79
78
if num < MAX_LOG_LEVEL {
80
79
log_level = Some ( num) ;
@@ -84,9 +83,9 @@ fn parse_log_level(level: &str) -> Option<u32> {
84
83
}
85
84
_ => {
86
85
let position = log_level_names. iter ( ) . position ( |& name| name == level) ;
87
- match ( position) {
86
+ match position {
88
87
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 ) )
90
89
} ,
91
90
_ => {
92
91
log_level = None ;
@@ -108,8 +107,22 @@ fn parse_logging_spec(spec: ~str) -> ~[LogDirective]{
108
107
for s in spec. split_iter ( ',' ) {
109
108
let parts: ~[ & str ] = s. split_iter ( '=' ) . collect ( ) ;
110
109
let mut log_level;
110
+ let mut name = Some ( parts[ 0 ] . to_owned ( ) ) ;
111
111
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
+ }
113
126
2 => {
114
127
let possible_log_level = parse_log_level ( parts[ 1 ] ) ;
115
128
match possible_log_level {
@@ -129,7 +142,7 @@ fn parse_logging_spec(spec: ~str) -> ~[LogDirective]{
129
142
loop ;
130
143
}
131
144
}
132
- let dir = LogDirective { name : parts [ 0 ] . to_owned ( ) , level : log_level} ;
145
+ let dir = LogDirective { name : name , level : log_level} ;
133
146
dirs. push ( dir) ;
134
147
}
135
148
return dirs;
@@ -139,18 +152,30 @@ fn parse_logging_spec(spec: ~str) -> ~[LogDirective]{
139
152
/// of log directives
140
153
fn update_entry ( dirs : & [ LogDirective ] , entry : * mut ModEntry ) -> u32 {
141
154
let mut new_lvl: u32 = DEFAULT_LOG_LEVEL ;
142
- let mut longest_match = 0 ;
155
+ let mut longest_match = - 1 i ;
143
156
unsafe {
144
157
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
+ } ;
150
175
}
151
176
* ( * entry) . log_level = new_lvl;
152
177
}
153
- if longest_match > 0 { return 1 ; } else { return 0 ; }
178
+ if longest_match >= 0 { return 1 ; } else { return 0 ; }
154
179
}
155
180
156
181
#[ fixed_stack_segment] #[ inline( never) ]
@@ -264,54 +289,66 @@ extern {
264
289
// Tests for parse_logging_spec()
265
290
#[ test]
266
291
fn 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 ") ;
268
293
assert_eq ! ( dirs. len( ) , 3 ) ;
269
- assert ! ( dirs[ 0 ] . name == ~"crate1:: mod1");
294
+ assert!( dirs[ 0 ] . name == Some ( ~"crate1:: mod1") );
270
295
assert_eq!(dirs[0].level, 1);
271
296
272
- assert!(dirs[1].name == ~" crate1:: mod2");
297
+ assert!(dirs[1].name == Some( ~" crate1:: mod2") );
273
298
assert_eq!(dirs[1].level, MAX_LOG_LEVEL);
274
299
275
- assert!(dirs[2].name == ~" crate2");
300
+ assert!(dirs[2].name == Some( ~" crate2") );
276
301
assert_eq!(dirs[2].level, 4);
277
302
}
278
303
279
304
#[test]
280
305
fn parse_logging_spec_invalid_crate() {
281
306
// 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 ");
283
308
assert_eq!(dirs.len(), 1);
284
- assert!(dirs[0].name == ~" crate2");
309
+ assert!(dirs[0].name == Some( ~" crate2") );
285
310
assert_eq!(dirs[0].level, 4);
286
311
}
287
312
288
313
#[test]
289
314
fn parse_logging_spec_invalid_log_level() {
290
315
// 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 ");
292
317
assert_eq!(dirs.len(), 1);
293
- assert!(dirs[0].name == ~" crate2");
318
+ assert!(dirs[0].name == Some( ~" crate2") );
294
319
assert_eq!(dirs[0].level, 4);
295
320
}
296
321
297
322
#[test]
298
323
fn parse_logging_spec_string_log_level() {
299
324
// 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");
301
326
assert_eq!(dirs.len(), 1);
302
- assert!(dirs[0].name == ~" crate2");
327
+ assert!(dirs[0].name == Some( ~" crate2") );
303
328
assert_eq!(dirs[0].level, 2);
304
329
}
305
330
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
+
306
342
// Tests for update_entry
307
343
#[test]
308
344
fn update_entry_match_full_path() {
309
345
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;
312
349
unsafe {
313
350
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 };
315
352
let m = update_entry(dirs, transmute(entry));
316
353
assert!(*entry.log_level == 2);
317
354
assert!(m == 1);
@@ -322,11 +359,12 @@ fn update_entry_match_full_path() {
322
359
#[test]
323
360
fn update_entry_no_match() {
324
361
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;
327
365
unsafe {
328
366
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 };
330
368
let m = update_entry(dirs, transmute(entry));
331
369
assert!(*entry.log_level == DEFAULT_LOG_LEVEL);
332
370
assert!(m == 0);
@@ -337,11 +375,12 @@ fn update_entry_no_match() {
337
375
#[test]
338
376
fn update_entry_match_beginning() {
339
377
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;
342
381
unsafe {
343
382
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 };
345
384
let m = update_entry(dirs, transmute(entry));
346
385
assert!(*entry.log_level == 3);
347
386
assert!(m == 1);
@@ -352,14 +391,39 @@ fn update_entry_match_beginning() {
352
391
#[test]
353
392
fn update_entry_match_beginning_longest_match() {
354
393
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;
357
398
unsafe {
358
399
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 };
360
401
let m = update_entry(dirs, transmute(entry));
361
402
assert!(*entry.log_level == 4);
362
403
assert!(m == 1);
363
404
}
364
405
}
365
406
}
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