// except according to those terms.
use self::WhichLine::*;
+use std::fmt;
use std::fs::File;
use std::io::BufReader;
use std::io::prelude::*;
use std::path::Path;
+use std::str::FromStr;
+
+#[derive(Clone, Debug, PartialEq)]
+pub enum ErrorKind {
+ Help,
+ Error,
+ Note,
+ Suggestion,
+ Warning,
+}
+
+impl FromStr for ErrorKind {
+ type Err = ();
+ fn from_str(s: &str) -> Result<Self, Self::Err> {
+ match &s.trim_right_matches(':') as &str {
+ "HELP" => Ok(ErrorKind::Help),
+ "ERROR" => Ok(ErrorKind::Error),
+ "NOTE" => Ok(ErrorKind::Note),
+ "SUGGESTION" => Ok(ErrorKind::Suggestion),
+ "WARN" => Ok(ErrorKind::Warning),
+ "WARNING" => Ok(ErrorKind::Warning),
+ _ => Err(()),
+ }
+ }
+}
+
+impl fmt::Display for ErrorKind {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ match *self {
+ ErrorKind::Help => write!(f, "help"),
+ ErrorKind::Error => write!(f, "error"),
+ ErrorKind::Note => write!(f, "note"),
+ ErrorKind::Suggestion => write!(f, "suggestion"),
+ ErrorKind::Warning => write!(f, "warning"),
+ }
+ }
+}
pub struct ExpectedError {
pub line_num: usize,
- pub kind: String,
+ /// What kind of message we expect (e.g. warning, error, suggestion).
+ /// `None` if not specified or unknown message kind.
+ pub kind: Option<ErrorKind>,
pub msg: String,
}
let letters = line[kind_start..].chars();
let kind = letters.skip_while(|c| c.is_whitespace())
.take_while(|c| !c.is_whitespace())
- .flat_map(|c| c.to_lowercase())
- .collect::<String>();
+ .collect::<String>()
+ .parse::<ErrorKind>()
+ .ok();
let letters = line[kind_start..].chars();
let msg = letters.skip_while(|c| c.is_whitespace())
.skip_while(|c| !c.is_whitespace())
use common::Config;
use common::{CompileFail, ParseFail, Pretty, RunFail, RunPass, RunPassValgrind};
use common::{Codegen, DebugInfoLldb, DebugInfoGdb, Rustdoc, CodegenUnits};
-use errors;
+use errors::{self, ErrorKind};
use header::TestProps;
use header;
use procsrv;
expected_errors.iter()
.fold((false, false),
|(acc_help, acc_note), ee|
- (acc_help || ee.kind == "help:" || ee.kind == "help",
- acc_note || ee.kind == "note:" || ee.kind == "note"));
+ (acc_help || ee.kind == Some(ErrorKind::Help),
+ acc_note || ee.kind == Some(ErrorKind::Note)));
// Scan and extract our error/warning messages,
// which look like:
let mut prev = 0;
for (i, ee) in expected_errors.iter().enumerate() {
if !found_flags[i] {
- debug!("prefix={} ee.kind={} ee.msg={} line={}",
+ debug!("prefix={} ee.kind={:?} ee.msg={} line={}",
prefixes[i],
ee.kind,
ee.msg,
line);
// Suggestions have no line number in their output, so take on the line number of
// the previous expected error
- if ee.kind == "suggestion" {
- assert!(expected_errors[prev].kind == "help",
+ if ee.kind == Some(ErrorKind::Suggestion) {
+ assert!(expected_errors[prev].kind == Some(ErrorKind::Help),
"SUGGESTIONs must be preceded by a HELP");
if line.contains(&ee.msg) {
found_flags[i] = true;
}
if
(prefix_matches(line, &prefixes[i]) || continuation(line)) &&
- line.contains(&ee.kind) &&
+ (ee.kind.is_none() || line.contains(&ee.kind.as_ref().unwrap().to_string())) &&
line.contains(&ee.msg)
{
found_flags[i] = true;
if !flag {
let ee = &expected_errors[i];
error(revision, &format!("expected {} on line {} not found: {}",
- ee.kind, ee.line_num, ee.msg));
+ ee.kind.as_ref()
+ .map_or("message".into(),
+ |k| k.to_string()),
+ ee.line_num, ee.msg));
not_found += 1;
}
}