about summary refs log tree commit diff
path: root/src/libstd/fmt
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2013-10-19 01:31:21 -0700
committerbors <bors@rust-lang.org>2013-10-19 01:31:21 -0700
commit8f2480420e5412e03d1b046be283573af312bdd8 (patch)
tree0176f143af64d5750072fde361dad0deeb6a9ada /src/libstd/fmt
parent34a1e3dc9a1649b5552d3221c558e6791b709336 (diff)
parenta447c3ca165dda7aa31d2be76ce1ff35a7884579 (diff)
downloadrust-8f2480420e5412e03d1b046be283573af312bdd8.tar.gz
rust-8f2480420e5412e03d1b046be283573af312bdd8.zip
auto merge of #9932 : alexcrichton/rust/better-fmt-errors, r=cmr
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/fmt')
-rw-r--r--src/libstd/fmt/parse.rs51
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");