about summary refs log tree commit diff
path: root/src/libstd
diff options
context:
space:
mode:
authorAlex Crichton <alex@alexcrichton.com>2013-10-18 10:30:40 -0700
committerAlex Crichton <alex@alexcrichton.com>2013-10-18 21:28:00 -0700
commita447c3ca165dda7aa31d2be76ce1ff35a7884579 (patch)
treeb687f8013be1ff68a524aef31642ccedd44212ff /src/libstd
parenta1848bc755411285afb15f2453df7567e10ebc04 (diff)
downloadrust-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.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");