diff --git a/src/libstd/fmt/parse.rs b/src/libstd/fmt/parse.rs index 8903d817c3f..504050f9a77 100644 --- a/src/libstd/fmt/parse.rs +++ b/src/libstd/fmt/parse.rs @@ -170,9 +170,7 @@ impl<'self> Iterator> 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"); diff --git a/src/test/compile-fail/ifmt-bad-arg.rs b/src/test/compile-fail/ifmt-bad-arg.rs index aace3815e84..bf8f625f922 100644 --- a/src/test/compile-fail/ifmt-bad-arg.rs +++ b/src/test/compile-fail/ifmt-bad-arg.rs @@ -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`