@@ -7,7 +7,9 @@ use std::io::BufReader;
7
7
use std:: path:: Path ;
8
8
use std:: str:: FromStr ;
9
9
10
+ use lazy_static:: lazy_static;
10
11
use log:: * ;
12
+ use regex:: Regex ;
11
13
12
14
#[ derive( Clone , Debug , PartialEq ) ]
13
15
pub enum ErrorKind {
@@ -85,20 +87,16 @@ pub fn load_errors(testfile: &Path, cfg: Option<&str>) -> Vec<Error> {
85
87
// updating it in the map callback below.)
86
88
let mut last_nonfollow_error = None ;
87
89
88
- let tag = match cfg {
89
- Some ( rev) => format ! ( "//[{}]~" , rev) ,
90
- None => "//~" . to_string ( ) ,
91
- } ;
92
-
93
90
rdr. lines ( )
94
91
. enumerate ( )
95
92
. 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 (
97
94
|( which, error) | {
98
95
match which {
99
96
FollowPrevious ( _) => { }
100
97
_ => last_nonfollow_error = Some ( error. line_num ) ,
101
98
}
99
+
102
100
error
103
101
} ,
104
102
)
@@ -110,46 +108,54 @@ fn parse_expected(
110
108
last_nonfollow_error : Option < usize > ,
111
109
line_num : usize ,
112
110
line : & str ,
113
- tag : & str ,
111
+ cfg : Option < & str > ,
114
112
) -> 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 ( ) ) ,
126
142
} ;
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
130
149
. split_whitespace ( )
131
150
. 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 ;
152
157
}
158
+
153
159
let msg = msg. trim ( ) . to_owned ( ) ;
154
160
155
161
let ( which, line_num) = if follow {
@@ -171,7 +177,7 @@ fn parse_expected(
171
177
172
178
debug ! (
173
179
"line={} tag={:?} which={:?} kind={:?} msg={:?}" ,
174
- line_num, tag , which, kind, msg
180
+ line_num, whole_match . as_str ( ) , which, kind, msg
175
181
) ;
176
182
Some ( (
177
183
which,
0 commit comments