]>
git.proxmox.com Git - rustc.git/blob - src/tools/compiletest/src/errors.rs
1 // Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10 use self::WhichLine
::*;
14 use std
::io
::BufReader
;
15 use std
::io
::prelude
::*;
17 use std
::str::FromStr
;
19 #[derive(Clone, Debug, PartialEq)]
28 impl FromStr
for ErrorKind
{
30 fn from_str(s
: &str) -> Result
<Self, Self::Err
> {
31 let s
= s
.to_uppercase();
32 let part0
: &str = s
.split('
:'
).next().unwrap();
34 "HELP" => Ok(ErrorKind
::Help
),
35 "ERROR" => Ok(ErrorKind
::Error
),
36 "NOTE" => Ok(ErrorKind
::Note
),
37 "SUGGESTION" => Ok(ErrorKind
::Suggestion
),
39 "WARNING" => Ok(ErrorKind
::Warning
),
45 impl fmt
::Display
for ErrorKind
{
46 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
48 ErrorKind
::Help
=> write
!(f
, "help message"),
49 ErrorKind
::Error
=> write
!(f
, "error"),
50 ErrorKind
::Note
=> write
!(f
, "note"),
51 ErrorKind
::Suggestion
=> write
!(f
, "suggestion"),
52 ErrorKind
::Warning
=> write
!(f
, "warning"),
60 /// What kind of message we expect (e.g. warning, error, suggestion).
61 /// `None` if not specified or unknown message kind.
62 pub kind
: Option
<ErrorKind
>,
66 #[derive(PartialEq, Debug)]
69 FollowPrevious(usize),
70 AdjustBackward(usize),
73 /// Looks for either "//~| KIND MESSAGE" or "//~^^... KIND MESSAGE"
74 /// The former is a "follow" that inherits its target from the preceding line;
75 /// the latter is an "adjusts" that goes that many lines up.
77 /// Goal is to enable tests both like: //~^^^ ERROR go up three
78 /// and also //~^ ERROR message one for the preceding line, and
79 /// //~| ERROR message two for that same line.
81 /// If cfg is not None (i.e., in an incremental test), then we look
82 /// for `//[X]~` instead, where `X` is the current `cfg`.
83 pub fn load_errors(testfile
: &Path
, cfg
: Option
<&str>) -> Vec
<Error
> {
84 let rdr
= BufReader
::new(File
::open(testfile
).unwrap());
86 // `last_nonfollow_error` tracks the most recently seen
87 // line with an error template that did not use the
88 // follow-syntax, "//~| ...".
90 // (pnkfelix could not find an easy way to compose Iterator::scan
91 // and Iterator::filter_map to pass along this information into
92 // `parse_expected`. So instead I am storing that state here and
93 // updating it in the map callback below.)
94 let mut last_nonfollow_error
= None
;
97 Some(rev
) => format
!("//[{}]~", rev
),
98 None
=> "//~".to_string(),
103 .filter_map(|(line_num
, line
)| {
104 parse_expected(last_nonfollow_error
, line_num
+ 1, &line
.unwrap(), &tag
)
105 .map(|(which
, error
)| {
107 FollowPrevious(_
) => {}
108 _
=> last_nonfollow_error
= Some(error
.line_num
),
116 fn parse_expected(last_nonfollow_error
: Option
<usize>,
120 -> Option
<(WhichLine
, Error
)> {
121 let start
= match line
.find(tag
) {
125 let (follow
, adjusts
) = if line
[start
+ tag
.len()..].chars().next().unwrap() == '
|'
{
128 (false, line
[start
+ tag
.len()..].chars().take_while(|c
| *c
== '
^').count())
130 let kind_start
= start
+ tag
.len() + adjusts
+ (follow
as usize);
132 match line
[kind_start
..]
135 .expect("Encountered unexpected empty comment")
136 .parse
::<ErrorKind
>() {
138 // If we find `//~ ERROR foo` or something like that:
140 let letters
= line
[kind_start
..].chars();
141 msg
= letters
.skip_while(|c
| c
.is_whitespace())
142 .skip_while(|c
| !c
.is_whitespace())
143 .collect
::<String
>();
146 // Otherwise we found `//~ foo`:
148 let letters
= line
[kind_start
..].chars();
149 msg
= letters
.skip_while(|c
| c
.is_whitespace())
150 .collect
::<String
>();
153 let msg
= msg
.trim().to_owned();
155 let (which
, line_num
) = if follow
{
156 assert_eq
!(adjusts
, 0, "use either //~| or //~^, not both.");
157 let line_num
= last_nonfollow_error
.expect("encountered //~| without \
158 preceding //~^ line.");
159 (FollowPrevious(line_num
), line_num
)
161 let which
= if adjusts
> 0 {
162 AdjustBackward(adjusts
)
166 let line_num
= line_num
- adjusts
;
170 debug
!("line={} tag={:?} which={:?} kind={:?} msg={:?}",