Try to improve format! error messages
Instead of just saying "unterminated format string" and friends, instead print information about what was expected and what was found. Closes #9931
This commit is contained in:
parent
a1848bc755
commit
a447c3ca16
2 changed files with 32 additions and 29 deletions
|
@ -170,9 +170,7 @@ impl<'self> Iterator<Piece<'self>> for Parser<'self> {
|
|||
Some((_, '{')) => {
|
||||
self.cur.next();
|
||||
let ret = Some(Argument(self.argument()));
|
||||
if !self.consume('}') {
|
||||
self.err(~"unterminated format string");
|
||||
}
|
||||
self.must_consume('}');
|
||||
ret
|
||||
}
|
||||
Some((pos, '\\')) => {
|
||||
|
@ -223,6 +221,25 @@ impl<'self> Parser<'self> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Forces consumption of the specified character. If the character is not
|
||||
/// found, an error is emitted.
|
||||
fn must_consume(&mut self, c: char) {
|
||||
self.ws();
|
||||
match self.cur.clone().next() {
|
||||
Some((_, maybe)) if c == maybe => {
|
||||
self.cur.next();
|
||||
}
|
||||
Some((_, other)) => {
|
||||
parse_error::cond.raise(
|
||||
format!("expected `{}` but found `{}`", c, other));
|
||||
}
|
||||
None => {
|
||||
parse_error::cond.raise(
|
||||
format!("expected `{}` but string was terminated", c));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Attempts to consume any amount of whitespace followed by a character
|
||||
fn wsconsume(&mut self, c: char) -> bool {
|
||||
self.ws(); self.consume(c)
|
||||
|
@ -386,15 +403,11 @@ impl<'self> Parser<'self> {
|
|||
self.ws();
|
||||
match self.word() {
|
||||
"select" => {
|
||||
if !self.wsconsume(',') {
|
||||
self.err(~"`select` must be followed by `,`");
|
||||
}
|
||||
self.must_consume(',');
|
||||
Some(self.select())
|
||||
}
|
||||
"plural" => {
|
||||
if !self.wsconsume(',') {
|
||||
self.err(~"`plural` must be followed by `,`");
|
||||
}
|
||||
self.must_consume(',');
|
||||
Some(self.plural())
|
||||
}
|
||||
"" => {
|
||||
|
@ -420,15 +433,11 @@ impl<'self> Parser<'self> {
|
|||
self.err(~"cannot have an empty selector");
|
||||
break
|
||||
}
|
||||
if !self.wsconsume('{') {
|
||||
self.err(~"selector must be followed by `{`");
|
||||
}
|
||||
self.must_consume('{');
|
||||
self.depth += 1;
|
||||
let pieces = self.collect();
|
||||
self.depth -= 1;
|
||||
if !self.wsconsume('}') {
|
||||
self.err(~"selector case must be terminated by `}`");
|
||||
}
|
||||
self.must_consume('}');
|
||||
if selector == "other" {
|
||||
if !other.is_none() {
|
||||
self.err(~"multiple `other` statements in `select");
|
||||
|
@ -475,9 +484,7 @@ impl<'self> Parser<'self> {
|
|||
self.err(format!("expected `offset`, found `{}`",
|
||||
word));
|
||||
} else {
|
||||
if !self.consume(':') {
|
||||
self.err(~"`offset` must be followed by `:`");
|
||||
}
|
||||
self.must_consume(':');
|
||||
match self.integer() {
|
||||
Some(i) => { offset = Some(i); }
|
||||
None => {
|
||||
|
@ -524,15 +531,11 @@ impl<'self> Parser<'self> {
|
|||
}
|
||||
}
|
||||
};
|
||||
if !self.wsconsume('{') {
|
||||
self.err(~"selector must be followed by `{`");
|
||||
}
|
||||
self.must_consume('{');
|
||||
self.depth += 1;
|
||||
let pieces = self.collect();
|
||||
self.depth -= 1;
|
||||
if !self.wsconsume('}') {
|
||||
self.err(~"selector case must be terminated by `}`");
|
||||
}
|
||||
self.must_consume('}');
|
||||
if isother {
|
||||
if !other.is_none() {
|
||||
self.err(~"multiple `other` statements in `select");
|
||||
|
|
|
@ -36,20 +36,20 @@ fn main() {
|
|||
|
||||
// bad syntax of the format string
|
||||
|
||||
format!("{"); //~ ERROR: unterminated format string
|
||||
format!("{"); //~ ERROR: expected `}` but string was terminated
|
||||
format!("\\ "); //~ ERROR: invalid escape
|
||||
format!("\\"); //~ ERROR: expected an escape
|
||||
|
||||
format!("{0, }", 1); //~ ERROR: expected method
|
||||
format!("{0, foo}", 1); //~ ERROR: unknown method
|
||||
format!("{0, select}", "a"); //~ ERROR: must be followed by
|
||||
format!("{0, plural}", 1); //~ ERROR: must be followed by
|
||||
format!("{0, select}", "a"); //~ ERROR: expected `,` but found `}`
|
||||
format!("{0, plural}", 1); //~ ERROR: expected `,` but found `}`
|
||||
|
||||
format!("{0, select, a{{}", 1); //~ ERROR: must be terminated
|
||||
format!("{0, select, a{{}", 1); //~ ERROR: expected `}` but string was terminated
|
||||
format!("{0, select, {} other{}}", "a"); //~ ERROR: empty selector
|
||||
format!("{0, select, other{} other{}}", "a"); //~ ERROR: multiple `other`
|
||||
format!("{0, plural, offset: other{}}", "a"); //~ ERROR: must be an integer
|
||||
format!("{0, plural, offset 1 other{}}", "a"); //~ ERROR: be followed by `:`
|
||||
format!("{0, plural, offset 1 other{}}", "a"); //~ ERROR: expected `:` but found `1`
|
||||
format!("{0, plural, =a{} other{}}", "a"); //~ ERROR: followed by an integer
|
||||
format!("{0, plural, a{} other{}}", "a"); //~ ERROR: unexpected plural
|
||||
format!("{0, select, a{}}", "a"); //~ ERROR: must provide an `other`
|
||||
|
|
Loading…
Add table
Reference in a new issue