diff options
| author | Alex Crichton <alex@alexcrichton.com> | 2013-10-18 10:30:40 -0700 |
|---|---|---|
| committer | Alex Crichton <alex@alexcrichton.com> | 2013-10-18 21:28:00 -0700 |
| commit | a447c3ca165dda7aa31d2be76ce1ff35a7884579 (patch) | |
| tree | b687f8013be1ff68a524aef31642ccedd44212ff /src/libstd | |
| parent | a1848bc755411285afb15f2453df7567e10ebc04 (diff) | |
| download | rust-a447c3ca165dda7aa31d2be76ce1ff35a7884579.tar.gz rust-a447c3ca165dda7aa31d2be76ce1ff35a7884579.zip | |
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
Diffstat (limited to 'src/libstd')
| -rw-r--r-- | src/libstd/fmt/parse.rs | 51 |
1 files changed, 27 insertions, 24 deletions
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<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"); |
