@@ -7,7 +7,9 @@ use std::io::BufReader;
77use std:: path:: Path ;
88use std:: str:: FromStr ;
99
10+ use lazy_static:: lazy_static;
1011use log:: * ;
12+ use regex:: Regex ;
1113
1214#[ derive( Clone , Debug , PartialEq ) ]
1315pub enum ErrorKind {
@@ -85,20 +87,16 @@ pub fn load_errors(testfile: &Path, cfg: Option<&str>) -> Vec<Error> {
8587 // updating it in the map callback below.)
8688 let mut last_nonfollow_error = None ;
8789
88- let tag = match cfg {
89- Some ( rev) => format ! ( "//[{}]~" , rev) ,
90- None => "//~" . to_string ( ) ,
91- } ;
92-
9390 rdr. lines ( )
9491 . enumerate ( )
9592 . filter_map ( |( line_num, line) | {
96- parse_expected ( last_nonfollow_error, line_num + 1 , & line. unwrap ( ) , & tag ) . map (
93+ parse_expected ( last_nonfollow_error, line_num + 1 , & line. unwrap ( ) , cfg ) . map (
9794 |( which, error) | {
9895 match which {
9996 FollowPrevious ( _) => { }
10097 _ => last_nonfollow_error = Some ( error. line_num ) ,
10198 }
99+
102100 error
103101 } ,
104102 )
@@ -110,46 +108,54 @@ fn parse_expected(
110108 last_nonfollow_error : Option < usize > ,
111109 line_num : usize ,
112110 line : & str ,
113- tag : & str ,
111+ cfg : Option < & str > ,
114112) -> Option < ( WhichLine , Error ) > {
115- let start = line. find ( tag) ?;
116- let ( follow, adjusts) = if line[ start + tag. len ( ) ..] . chars ( ) . next ( ) . unwrap ( ) == '|' {
117- ( true , 0 )
118- } else {
119- (
120- false ,
121- line[ start + tag. len ( ) ..]
122- . chars ( )
123- . take_while ( |c| * c == '^' )
124- . count ( ) ,
125- )
113+ // Matches comments like:
114+ // //~
115+ // //~|
116+ // //~^
117+ // //~^^^^^
118+ // //[cfg1]~
119+ // //[cfg1,cfg2]~^^
120+ lazy_static ! {
121+ static ref RE : Regex =
122+ Regex :: new( r"//(?:\[(?P<cfgs>[\w,]+)])?~(?P<adjust>\||\^*)" ) . unwrap( ) ;
123+ }
124+
125+ let captures = RE . captures ( line) ?;
126+
127+ match ( cfg, captures. name ( "cfgs" ) ) {
128+ // Only error messages that contain our `cfg` betweeen the square brackets apply to us.
129+ ( Some ( cfg) , Some ( filter) ) if !filter. as_str ( ) . split ( ',' ) . any ( |s| s == cfg)
130+ => return None ,
131+ ( Some ( _) , Some ( _) ) => { }
132+
133+ ( None , Some ( _) ) => panic ! ( "Only tests with revisions should use `//[X]~`" ) ,
134+
135+ // If an error has no list of revisions, it applies to all revisions.
136+ ( Some ( _) , None ) | ( None , None ) => { }
137+ }
138+
139+ let ( follow, adjusts) = match & captures[ "adjust" ] {
140+ "|" => ( true , 0 ) ,
141+ circumflexes => ( false , circumflexes. len ( ) ) ,
126142 } ;
127- let kind_start = start + tag. len ( ) + adjusts + ( follow as usize ) ;
128- let ( kind, msg) ;
129- match line[ kind_start..]
143+
144+ // Get the part of the comment after the sigil (e.g. `~^^` or ~|).
145+ let whole_match = captures. get ( 0 ) . unwrap ( ) ;
146+ let ( _, mut msg) = line. split_at ( whole_match. end ( ) ) ;
147+
148+ let first_word = msg
130149 . split_whitespace ( )
131150 . next ( )
132- . expect ( "Encountered unexpected empty comment" )
133- . parse :: < ErrorKind > ( )
134- {
135- Ok ( k) => {
136- // If we find `//~ ERROR foo` or something like that:
137- kind = Some ( k) ;
138- let letters = line[ kind_start..] . chars ( ) ;
139- msg = letters
140- . skip_while ( |c| c. is_whitespace ( ) )
141- . skip_while ( |c| !c. is_whitespace ( ) )
142- . collect :: < String > ( ) ;
143- }
144- Err ( _) => {
145- // Otherwise we found `//~ foo`:
146- kind = None ;
147- let letters = line[ kind_start..] . chars ( ) ;
148- msg = letters
149- . skip_while ( |c| c. is_whitespace ( ) )
150- . collect :: < String > ( ) ;
151- }
151+ . expect ( "Encountered unexpected empty comment" ) ;
152+
153+ // If we find `//~ ERROR foo` or something like that, skip the first word.
154+ let kind = first_word. parse :: < ErrorKind > ( ) . ok ( ) ;
155+ if let Some ( _) = kind {
156+ msg = & msg. trim_start ( ) . split_at ( first_word. len ( ) ) . 1 ;
152157 }
158+
153159 let msg = msg. trim ( ) . to_owned ( ) ;
154160
155161 let ( which, line_num) = if follow {
@@ -171,7 +177,7 @@ fn parse_expected(
171177
172178 debug ! (
173179 "line={} tag={:?} which={:?} kind={:?} msg={:?}" ,
174- line_num, tag , which, kind, msg
180+ line_num, whole_match . as_str ( ) , which, kind, msg
175181 ) ;
176182 Some ( (
177183 which,
0 commit comments