about summary refs log tree commit diff
path: root/src/libstd
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2013-10-16 18:11:22 -0700
committerbors <bors@rust-lang.org>2013-10-16 18:11:22 -0700
commitc92f2168d49ee330992b9e23cd3dabf695e0d248 (patch)
tree0c46e9f339892186b981cdf253d9cf9e4d0e543b /src/libstd
parent63e097d8c34143411ea6d3146493bd6d8f3428d7 (diff)
parentfc06f7922db0b4d1063f4f29157635117d853426 (diff)
downloadrust-c92f2168d49ee330992b9e23cd3dabf695e0d248.tar.gz
rust-c92f2168d49ee330992b9e23cd3dabf695e0d248.zip
auto merge of #9833 : alexcrichton/rust/fixes, r=brson
Commits have all the fun details
Diffstat (limited to 'src/libstd')
-rw-r--r--src/libstd/at_vec.rs2
-rw-r--r--src/libstd/fmt/mod.rs52
-rw-r--r--src/libstd/fmt/parse.rs93
-rw-r--r--src/libstd/fmt/rt.rs15
-rw-r--r--src/libstd/select.rs2
-rw-r--r--src/libstd/str.rs1
-rw-r--r--src/libstd/vec.rs1
7 files changed, 147 insertions, 19 deletions
diff --git a/src/libstd/at_vec.rs b/src/libstd/at_vec.rs
index 93a66f6d917..f6669893170 100644
--- a/src/libstd/at_vec.rs
+++ b/src/libstd/at_vec.rs
@@ -135,6 +135,7 @@ impl<T> Clone for @[T] {
 }
 
 #[cfg(not(test))]
+#[allow(missing_doc)]
 pub mod traits {
     use at_vec::append;
     use clone::Clone;
@@ -152,6 +153,7 @@ pub mod traits {
 #[cfg(test)]
 pub mod traits {}
 
+#[allow(missing_doc)]
 pub mod raw {
     use at_vec::capacity;
     use cast;
diff --git a/src/libstd/fmt/mod.rs b/src/libstd/fmt/mod.rs
index a03f21d69c8..4032515f985 100644
--- a/src/libstd/fmt/mod.rs
+++ b/src/libstd/fmt/mod.rs
@@ -647,21 +647,6 @@ impl<'self> Formatter<'self> {
     // the format! syntax extension.
 
     fn run(&mut self, piece: &rt::Piece, cur: Option<&str>) {
-        let setcount = |slot: &mut Option<uint>, cnt: &parse::Count| {
-            match *cnt {
-                parse::CountIs(n) => { *slot = Some(n); }
-                parse::CountImplied => { *slot = None; }
-                parse::CountIsParam(i) => {
-                    let v = self.args[i].value;
-                    unsafe { *slot = Some(*(v as *util::Void as *uint)); }
-                }
-                parse::CountIsNextParam => {
-                    let v = self.curarg.next().unwrap().value;
-                    unsafe { *slot = Some(*(v as *util::Void as *uint)); }
-                }
-            }
-        };
-
         match *piece {
             rt::String(s) => { self.buf.write(s.as_bytes()); }
             rt::CurrentArgument(()) => { self.buf.write(cur.unwrap().as_bytes()); }
@@ -670,8 +655,8 @@ impl<'self> Formatter<'self> {
                 self.fill = arg.format.fill;
                 self.align = arg.format.align;
                 self.flags = arg.format.flags;
-                setcount(&mut self.width, &arg.format.width);
-                setcount(&mut self.precision, &arg.format.precision);
+                self.width = self.getcount(&arg.format.width);
+                self.precision = self.getcount(&arg.format.precision);
 
                 // Extract the correct argument
                 let value = match arg.position {
@@ -688,6 +673,39 @@ impl<'self> Formatter<'self> {
         }
     }
 
+    #[cfg(stage0)]
+    fn getcount(&mut self, cnt: &parse::Count) -> Option<uint> {
+        match *cnt {
+            parse::CountIs(n) => { Some(n) }
+            parse::CountImplied => { None }
+            parse::CountIsParam(i) => {
+                let v = self.args[i].value;
+                unsafe { Some(*(v as *util::Void as *uint)) }
+            }
+            parse::CountIsNextParam => {
+                let v = self.curarg.next().unwrap().value;
+                unsafe { Some(*(v as *util::Void as *uint)) }
+            }
+            parse::CountIsName(*) => unreachable!()
+        }
+    }
+
+    #[cfg(not(stage0))]
+    fn getcount(&mut self, cnt: &rt::Count) -> Option<uint> {
+        match *cnt {
+            rt::CountIs(n) => { Some(n) }
+            rt::CountImplied => { None }
+            rt::CountIsParam(i) => {
+                let v = self.args[i].value;
+                unsafe { Some(*(v as *util::Void as *uint)) }
+            }
+            rt::CountIsNextParam => {
+                let v = self.curarg.next().unwrap().value;
+                unsafe { Some(*(v as *util::Void as *uint)) }
+            }
+        }
+    }
+
     fn execute(&mut self, method: &rt::Method, arg: Argument) {
         match *method {
             // Pluralization is selection upon a numeric value specified as the
diff --git a/src/libstd/fmt/parse.rs b/src/libstd/fmt/parse.rs
index a95bd563a81..11b869c930e 100644
--- a/src/libstd/fmt/parse.rs
+++ b/src/libstd/fmt/parse.rs
@@ -8,6 +8,12 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+//! Parsing of format strings
+//!
+//! These structures are used when parsing format strings for the compiler.
+//! Parsing does not currently happen at runtime (structures of std::fmt::rt are
+//! generated instead).
+
 use prelude::*;
 
 use char;
@@ -42,6 +48,7 @@ pub struct Argument<'self> {
 
 /// Specification for the formatting of an argument in the format string.
 #[deriving(Eq)]
+#[cfg(stage0)]
 pub struct FormatSpec<'self> {
     /// Optionally specified character to fill alignment with
     fill: Option<char>,
@@ -59,6 +66,26 @@ pub struct FormatSpec<'self> {
     ty: &'self str
 }
 
+/// Specification for the formatting of an argument in the format string.
+#[deriving(Eq)]
+#[cfg(not(stage0))]
+pub struct FormatSpec<'self> {
+    /// Optionally specified character to fill alignment with
+    fill: Option<char>,
+    /// Optionally specified alignment
+    align: Alignment,
+    /// Packed version of various flags provided
+    flags: uint,
+    /// The integer precision to use
+    precision: Count<'self>,
+    /// The string width requested for the resulting format
+    width: Count<'self>,
+    /// The descriptor string representing the name of the format desired for
+    /// this argument, this can be empty or any number of characters, although
+    /// it is required to be one word.
+    ty: &'self str
+}
+
 /// Enum describing where an argument for a format can be located.
 #[deriving(Eq)]
 #[allow(missing_doc)]
@@ -86,9 +113,22 @@ pub enum Flag {
 /// can reference either an argument or a literal integer.
 #[deriving(Eq)]
 #[allow(missing_doc)]
+#[cfg(stage0)]
 pub enum Count {
     CountIs(uint),
     CountIsParam(uint),
+    CountIsName(&'static str), // not actually used, see stage1
+    CountIsNextParam,
+    CountImplied,
+}
+
+#[deriving(Eq)]
+#[allow(missing_doc)]
+#[cfg(not(stage0))]
+pub enum Count<'self> {
+    CountIs(uint),
+    CountIsName(&'self str),
+    CountIsParam(uint),
     CountIsNextParam,
     CountImplied,
 }
@@ -338,10 +378,22 @@ impl<'self> Parser<'self> {
             spec.flags |= 1 << (FlagAlternate as uint);
         }
         // Width and precision
+        let mut havewidth = false;
         if self.consume('0') {
-            spec.flags |= 1 << (FlagSignAwareZeroPad as uint);
+            // small ambiguity with '0$' as a format string. In theory this is a
+            // '0' flag and then an ill-formatted format string with just a '$'
+            // and no count, but this is better if we instead interpret this as
+            // no '0' flag and '0$' as the width instead.
+            if self.consume('$') {
+                spec.width = CountIsParam(0);
+                havewidth = true;
+            } else {
+                spec.flags |= 1 << (FlagSignAwareZeroPad as uint);
+            }
+        }
+        if !havewidth {
+            spec.width = self.count();
         }
-        spec.width = self.count();
         if self.consume('.') {
             if self.consume('*') {
                 spec.precision = CountIsNextParam;
@@ -542,6 +594,7 @@ impl<'self> Parser<'self> {
     /// Parses a Count parameter at the current position. This does not check
     /// for 'CountIsNextParam' because that is only used in precision, not
     /// width.
+    #[cfg(stage0)]
     fn count(&mut self) -> Count {
         match self.integer() {
             Some(i) => {
@@ -554,6 +607,30 @@ impl<'self> Parser<'self> {
             None => { CountImplied }
         }
     }
+    #[cfg(not(stage0))]
+    fn count(&mut self) -> Count<'self> {
+        match self.integer() {
+            Some(i) => {
+                if self.consume('$') {
+                    CountIsParam(i)
+                } else {
+                    CountIs(i)
+                }
+            }
+            None => {
+                let tmp = self.cur.clone();
+                match self.word() {
+                    word if word.len() > 0 && self.consume('$') => {
+                        CountIsName(word)
+                    }
+                    _ => {
+                        self.cur = tmp;
+                        CountImplied
+                    }
+                }
+            }
+        }
+    }
 
     /// Parses a word starting at the current position. A word is considered to
     /// be an alphabetic character followed by any number of alphanumeric
@@ -777,6 +854,18 @@ mod tests {
             },
             method: None,
         })]);
+        same("{:a$.b$s}", ~[Argument(Argument {
+            position: ArgumentNext,
+            format: FormatSpec {
+                fill: None,
+                align: AlignUnknown,
+                flags: 0,
+                precision: CountIsName("b"),
+                width: CountIsName("a"),
+                ty: "s",
+            },
+            method: None,
+        })]);
     }
     #[test]
     fn format_flags() {
diff --git a/src/libstd/fmt/rt.rs b/src/libstd/fmt/rt.rs
index 90763836fc6..063d712dfa9 100644
--- a/src/libstd/fmt/rt.rs
+++ b/src/libstd/fmt/rt.rs
@@ -34,6 +34,7 @@ pub struct Argument<'self> {
     method: Option<&'self Method<'self>>
 }
 
+#[cfg(stage0)]
 pub struct FormatSpec {
     fill: char,
     align: parse::Alignment,
@@ -42,6 +43,20 @@ pub struct FormatSpec {
     width: parse::Count,
 }
 
+#[cfg(not(stage0))]
+pub struct FormatSpec {
+    fill: char,
+    align: parse::Alignment,
+    flags: uint,
+    precision: Count,
+    width: Count,
+}
+
+#[cfg(not(stage0))]
+pub enum Count {
+    CountIs(uint), CountIsParam(uint), CountIsNextParam, CountImplied,
+}
+
 pub enum Position {
     ArgumentNext, ArgumentIs(uint)
 }
diff --git a/src/libstd/select.rs b/src/libstd/select.rs
index 049b301144b..8ce23f4b53b 100644
--- a/src/libstd/select.rs
+++ b/src/libstd/select.rs
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#[allow(missing_doc)];
+
 use cell::Cell;
 use comm;
 use container::Container;
diff --git a/src/libstd/str.rs b/src/libstd/str.rs
index 88497bdaa82..decfbb0785c 100644
--- a/src/libstd/str.rs
+++ b/src/libstd/str.rs
@@ -1253,6 +1253,7 @@ Section: Trait implementations
 */
 
 #[cfg(not(test))]
+#[allow(missing_doc)]
 pub mod traits {
     use ops::Add;
     use cmp::{TotalOrd, Ordering, Less, Equal, Greater, Eq, Ord, Equiv, TotalEq};
diff --git a/src/libstd/vec.rs b/src/libstd/vec.rs
index 93374d97db5..3962df8e3bd 100644
--- a/src/libstd/vec.rs
+++ b/src/libstd/vec.rs
@@ -603,6 +603,7 @@ impl<'self, T> RandomAccessIterator<&'self [T]> for ChunkIter<'self, T> {
 // Equality
 
 #[cfg(not(test))]
+#[allow(missing_doc)]
 pub mod traits {
     use super::*;