@@ -36,7 +36,7 @@ Some examples of the `format!` extension are:
3636format!("Hello") // => ~"Hello"
3737format!("Hello, {:s}!", "world") // => ~"Hello, world!"
3838format!("The number is {:d}", 1) // => ~"The number is 1"
39- format!("{}", ~[3, 4]) // => ~"~[3, 4]"
39+ format!("{:? }", ~[3, 4]) // => ~"~[3, 4]"
4040format!("{value}", value=4) // => ~"4"
4141format!("{} {}", 1, 2) // => ~"1 2"
4242~~~
@@ -363,6 +363,32 @@ pub struct Argument<'self> {
363363 priv value : & ' self util:: Void ,
364364}
365365
366+ impl < ' self > Arguments < ' self > {
367+ /// When using the format_args!() macro, this function is used to generate the
368+ /// Arguments structure. The compiler inserts an `unsafe` block to call this,
369+ /// which is valid because the compiler performs all necessary validation to
370+ /// ensure that the resulting call to format/write would be safe.
371+ #[ doc( hidden) ] #[ inline]
372+ pub unsafe fn new < ' a > ( fmt : & ' static [ rt:: Piece < ' static > ] ,
373+ args : & ' a [ Argument < ' a > ] ) -> Arguments < ' a > {
374+ Arguments { fmt : cast:: transmute ( fmt) , args : args }
375+ }
376+ }
377+
378+ /// This structure represents a safely precompiled version of a format string
379+ /// and its arguments. This cannot be generated at runtime because it cannot
380+ /// safely be done so, so no constructors are given and the fields are private
381+ /// to prevent modification.
382+ ///
383+ /// The `format_args!` macro will safely create an instance of this structure
384+ /// and pass it to a user-supplied function. The macro validates the format
385+ /// string at compile-time so usage of the `write` and `format` functions can
386+ /// be safely performed.
387+ pub struct Arguments < ' self > {
388+ priv fmt: & ' self [ rt:: Piece < ' self > ] ,
389+ priv args : & ' self [ Argument < ' self > ] ,
390+ }
391+
366392/// When a format is not otherwise specified, types are formatted by ascribing
367393/// to this trait. There is not an explicit way of selecting this trait to be
368394/// used for formatting, it is only if no other format is specified.
@@ -410,6 +436,26 @@ pub trait Float { fn fmt(&Self, &mut Formatter); }
410436/// and a list of arguments. The arguments will be formatted according to the
411437/// specified format string into the output stream provided.
412438///
439+ /// # Arguments
440+ ///
441+ /// * output - the buffer to write output to
442+ /// * args - the precompiled arguments generated by `format_args!`
443+ ///
444+ /// # Example
445+ ///
446+ /// ~~~{.rust}
447+ /// use std::fmt;
448+ /// let w: &mut io::Writer = ...;
449+ /// format_args!(|args| { fmt::write(w, args) }, "Hello, {}!", "world");
450+ /// ~~~
451+ pub fn write ( output : & mut io:: Writer , args : & Arguments ) {
452+ unsafe { write_unsafe ( output, args. fmt , args. args ) }
453+ }
454+
455+ /// The `write_unsafe` function takes an output stream, a precompiled format
456+ /// string, and a list of arguments. The arguments will be formatted according
457+ /// to the specified format string into the output stream provided.
458+ ///
413459/// See the documentation for `format` for why this function is unsafe and care
414460/// should be taken if calling it manually.
415461///
@@ -426,8 +472,9 @@ pub trait Float { fn fmt(&Self, &mut Formatter); }
426472///
427473/// Note that this function assumes that there are enough arguments for the
428474/// format string.
429- pub unsafe fn write ( output : & mut io:: Writer ,
430- fmt : & [ rt:: Piece ] , args : & [ Argument ] ) {
475+ pub unsafe fn write_unsafe ( output : & mut io:: Writer ,
476+ fmt : & [ rt:: Piece ] ,
477+ args : & [ Argument ] ) {
431478 let mut formatter = Formatter {
432479 flags : 0 ,
433480 width : None ,
@@ -446,6 +493,25 @@ pub unsafe fn write(output: &mut io::Writer,
446493/// The format function takes a precompiled format string and a list of
447494/// arguments, to return the resulting formatted string.
448495///
496+ /// # Arguments
497+ ///
498+ /// * args - a structure of arguments generated via the `format_args!` macro.
499+ /// Because this structure can only be safely generated at
500+ /// compile-time, this function is safe.
501+ ///
502+ /// # Example
503+ ///
504+ /// ~~~{.rust}
505+ /// use std::fmt;
506+ /// let s = format_args!(fmt::format, "Hello, {}!", "world");
507+ /// assert_eq!(s, "Hello, world!");
508+ /// ~~~
509+ pub fn format ( args : & Arguments ) -> ~str {
510+ unsafe { format_unsafe ( args. fmt , args. args ) }
511+ }
512+
513+ /// The unsafe version of the formatting function.
514+ ///
449515/// This is currently an unsafe function because the types of all arguments
450516/// aren't verified by immediate callers of this function. This currently does
451517/// not validate that the correct types of arguments are specified for each
@@ -465,9 +531,9 @@ pub unsafe fn write(output: &mut io::Writer,
465531///
466532/// Note that this function assumes that there are enough arguments for the
467533/// format string.
468- pub unsafe fn format ( fmt : & [ rt:: Piece ] , args : & [ Argument ] ) -> ~str {
534+ pub unsafe fn format_unsafe ( fmt : & [ rt:: Piece ] , args : & [ Argument ] ) -> ~str {
469535 let mut output = MemWriter :: new ( ) ;
470- write ( & mut output as & mut io:: Writer , fmt, args) ;
536+ write_unsafe ( & mut output as & mut io:: Writer , fmt, args) ;
471537 return str:: from_utf8_owned ( output. inner ( ) ) ;
472538}
473539
@@ -740,7 +806,7 @@ impl<'self> Formatter<'self> {
740806
741807/// This is a function which calls are emitted to by the compiler itself to
742808/// create the Argument structures that are passed into the `format` function.
743- #[ doc( hidden) ]
809+ #[ doc( hidden) ] # [ inline ]
744810pub fn argument < ' a , T > ( f : extern "Rust" fn ( & T , & mut Formatter ) ,
745811 t : & ' a T ) -> Argument < ' a > {
746812 unsafe {
@@ -753,14 +819,14 @@ pub fn argument<'a, T>(f: extern "Rust" fn(&T, &mut Formatter),
753819
754820/// When the compiler determines that the type of an argument *must* be a string
755821/// (such as for select), then it invokes this method.
756- #[ doc( hidden) ]
822+ #[ doc( hidden) ] # [ inline ]
757823pub fn argumentstr < ' a > ( s : & ' a & str ) -> Argument < ' a > {
758824 argument ( String :: fmt, s)
759825}
760826
761827/// When the compiler determines that the type of an argument *must* be a uint
762828/// (such as for plural), then it invokes this method.
763- #[ doc( hidden) ]
829+ #[ doc( hidden) ] # [ inline ]
764830pub fn argumentuint < ' a > ( s : & ' a uint ) -> Argument < ' a > {
765831 argument ( Unsigned :: fmt, s)
766832}
@@ -899,14 +965,8 @@ impl<T> Pointer for *T {
899965 }
900966 }
901967}
902-
903968impl < T > Pointer for * mut T {
904- fn fmt ( t : & * mut T , f : & mut Formatter ) {
905- f. flags |= 1 << ( parse:: FlagAlternate as uint ) ;
906- do :: uint:: to_str_bytes ( * t as uint , 16 ) |buf| {
907- f. pad_integral ( buf, "0x" , true ) ;
908- }
909- }
969+ fn fmt ( t : & * mut T , f : & mut Formatter ) { Pointer :: fmt ( & ( * t as * T ) , f) }
910970}
911971
912972// Implementation of Default for various core types
@@ -940,7 +1000,6 @@ delegate!(f64 to Float)
9401000impl < T > Default for * T {
9411001 fn fmt ( me : & * T , f : & mut Formatter ) { Pointer :: fmt ( me, f) }
9421002}
943-
9441003impl < T > Default for * mut T {
9451004 fn fmt ( me : & * mut T , f : & mut Formatter ) { Pointer :: fmt ( me, f) }
9461005}
0 commit comments