Fallout of changing format_args!(f, args) to f(format_args!(args)).
This commit is contained in:
parent
fc3f22bf25
commit
647e54d6d1
|
@ -945,6 +945,15 @@ pub trait ToString {
|
|||
}
|
||||
|
||||
impl<T: fmt::Show> ToString for T {
|
||||
// NOTE(stage0): Remove cfg after a snapshot
|
||||
#[cfg(not(stage0))]
|
||||
fn to_string(&self) -> String {
|
||||
let mut buf = Vec::<u8>::new();
|
||||
let _ = fmt::write(&mut buf, format_args!("{}", *self));
|
||||
String::from_utf8(buf).unwrap()
|
||||
}
|
||||
// NOTE(stage0): Remove method after a snapshot
|
||||
#[cfg(stage0)]
|
||||
fn to_string(&self) -> String {
|
||||
let mut buf = Vec::<u8>::new();
|
||||
let _ = format_args!(|args| fmt::write(&mut buf, args), "{}", self);
|
||||
|
|
|
@ -325,6 +325,13 @@ pub fn float_to_str_bytes_common<T: Float, U, F>(
|
|||
|
||||
let mut filler = Filler { buf: &mut buf, end: &mut end };
|
||||
match sign {
|
||||
// NOTE(stage0): Remove cfg after a snapshot
|
||||
#[cfg(not(stage0))]
|
||||
SignNeg => {
|
||||
let _ = fmt::write(&mut filler, format_args!("{:-}", exp));
|
||||
}
|
||||
// NOTE(stage0): Remove match arm after a snapshot
|
||||
#[cfg(stage0)]
|
||||
SignNeg => {
|
||||
let _ = format_args!(|args| {
|
||||
fmt::write(&mut filler, args)
|
||||
|
|
|
@ -70,6 +70,16 @@ pub trait FormatWriter {
|
|||
/// This function will return an instance of `FormatError` on error.
|
||||
fn write(&mut self, bytes: &[u8]) -> Result;
|
||||
|
||||
// NOTE(stage0): Remove cfg after a snapshot
|
||||
#[cfg(not(stage0))]
|
||||
/// Glue for usage of the `write!` macro with implementers of this trait.
|
||||
///
|
||||
/// This method should generally not be invoked manually, but rather through
|
||||
/// the `write!` macro itself.
|
||||
fn write_fmt(&mut self, args: Arguments) -> Result { write(self, args) }
|
||||
|
||||
// NOTE(stage0): Remove method after a snapshot
|
||||
#[cfg(stage0)]
|
||||
/// Glue for usage of the `write!` macro with implementers of this trait.
|
||||
///
|
||||
/// This method should generally not be invoked manually, but rather through
|
||||
|
@ -180,6 +190,7 @@ impl<'a> Arguments<'a> {
|
|||
/// macro validates the format string at compile-time so usage of the `write`
|
||||
/// and `format` functions can be safely performed.
|
||||
#[stable]
|
||||
#[deriving(Copy)]
|
||||
pub struct Arguments<'a> {
|
||||
// Format string pieces to print.
|
||||
pieces: &'a [&'a str],
|
||||
|
@ -193,6 +204,14 @@ pub struct Arguments<'a> {
|
|||
}
|
||||
|
||||
impl<'a> Show for Arguments<'a> {
|
||||
// NOTE(stage0): Remove cfg after a snapshot
|
||||
#[cfg(not(stage0))]
|
||||
fn fmt(&self, fmt: &mut Formatter) -> Result {
|
||||
write(fmt.buf, *self)
|
||||
}
|
||||
|
||||
// NOTE(stage0): Remove method after a snapshot
|
||||
#[cfg(stage0)]
|
||||
fn fmt(&self, fmt: &mut Formatter) -> Result {
|
||||
write(fmt.buf, self)
|
||||
}
|
||||
|
@ -268,6 +287,63 @@ static DEFAULT_ARGUMENT: rt::Argument<'static> = rt::Argument {
|
|||
}
|
||||
};
|
||||
|
||||
// NOTE(stage0): Remove cfg after a snapshot
|
||||
#[cfg(not(stage0))]
|
||||
/// The `write` function takes an output stream, a precompiled format string,
|
||||
/// and a list of arguments. The arguments will be formatted according to the
|
||||
/// specified format string into the output stream provided.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * output - the buffer to write output to
|
||||
/// * args - the precompiled arguments generated by `format_args!`
|
||||
#[experimental = "libcore and I/O have yet to be reconciled, and this is an \
|
||||
implementation detail which should not otherwise be exported"]
|
||||
pub fn write(output: &mut FormatWriter, args: Arguments) -> Result {
|
||||
let mut formatter = Formatter {
|
||||
flags: 0,
|
||||
width: None,
|
||||
precision: None,
|
||||
buf: output,
|
||||
align: rt::AlignUnknown,
|
||||
fill: ' ',
|
||||
args: args.args,
|
||||
curarg: args.args.iter(),
|
||||
};
|
||||
|
||||
let mut pieces = args.pieces.iter();
|
||||
|
||||
match args.fmt {
|
||||
None => {
|
||||
// We can use default formatting parameters for all arguments.
|
||||
for _ in range(0, args.args.len()) {
|
||||
try!(formatter.buf.write(pieces.next().unwrap().as_bytes()));
|
||||
try!(formatter.run(&DEFAULT_ARGUMENT));
|
||||
}
|
||||
}
|
||||
Some(fmt) => {
|
||||
// Every spec has a corresponding argument that is preceded by
|
||||
// a string piece.
|
||||
for (arg, piece) in fmt.iter().zip(pieces.by_ref()) {
|
||||
try!(formatter.buf.write(piece.as_bytes()));
|
||||
try!(formatter.run(arg));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// There can be only one trailing string piece left.
|
||||
match pieces.next() {
|
||||
Some(piece) => {
|
||||
try!(formatter.buf.write(piece.as_bytes()));
|
||||
}
|
||||
None => {}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
// NOTE(stage0): Remove function after a snapshot
|
||||
#[cfg(stage0)]
|
||||
/// The `write` function takes an output stream, a precompiled format string,
|
||||
/// and a list of arguments. The arguments will be formatted according to the
|
||||
/// specified format string into the output stream provided.
|
||||
|
@ -527,6 +603,16 @@ impl<'a> Formatter<'a> {
|
|||
self.buf.write(data)
|
||||
}
|
||||
|
||||
// NOTE(stage0): Remove cfg after a snapshot
|
||||
#[cfg(not(stage0))]
|
||||
/// Writes some formatted information into this instance
|
||||
#[unstable = "reconciling core and I/O may alter this definition"]
|
||||
pub fn write_fmt(&mut self, fmt: Arguments) -> Result {
|
||||
write(self.buf, fmt)
|
||||
}
|
||||
|
||||
// NOTE(stage0): Remove method after a snapshot
|
||||
#[cfg(stage0)]
|
||||
/// Writes some formatted information into this instance
|
||||
#[unstable = "reconciling core and I/O may alter this definition"]
|
||||
pub fn write_fmt(&mut self, fmt: &Arguments) -> Result {
|
||||
|
|
|
@ -39,7 +39,7 @@
|
|||
//! distribution.
|
||||
//!
|
||||
//! * `rust_begin_unwind` - This function takes three arguments, a
|
||||
//! `&fmt::Arguments`, a `&str`, and a `uint`. These three arguments dictate
|
||||
//! `fmt::Arguments`, a `&str`, and a `uint`. These three arguments dictate
|
||||
//! the panic message, the file at which panic was invoked, and the line.
|
||||
//! It is up to consumers of this core library to define this panic
|
||||
//! function; it is only required to never return.
|
||||
|
|
|
@ -10,6 +10,30 @@
|
|||
|
||||
#![macro_escape]
|
||||
|
||||
// NOTE(stage0): Remove cfg after a snapshot
|
||||
#[cfg(not(stage0))]
|
||||
/// Entry point of task panic, for details, see std::macros
|
||||
#[macro_export]
|
||||
macro_rules! panic {
|
||||
() => (
|
||||
panic!("explicit panic")
|
||||
);
|
||||
($msg:expr) => ({
|
||||
static _MSG_FILE_LINE: (&'static str, &'static str, uint) = ($msg, file!(), line!());
|
||||
::core::panicking::panic(&_MSG_FILE_LINE)
|
||||
});
|
||||
($fmt:expr, $($arg:tt)*) => ({
|
||||
// The leading _'s are to avoid dead code warnings if this is
|
||||
// used inside a dead function. Just `#[allow(dead_code)]` is
|
||||
// insufficient, since the user may have
|
||||
// `#[forbid(dead_code)]` and which cannot be overridden.
|
||||
static _FILE_LINE: (&'static str, uint) = (file!(), line!());
|
||||
::core::panicking::panic_fmt(format_args!($fmt, $($arg)*), &_FILE_LINE)
|
||||
});
|
||||
}
|
||||
|
||||
// NOTE(stage0): Remove macro after a snapshot
|
||||
#[cfg(stage0)]
|
||||
/// Entry point of task panic, for details, see std::macros
|
||||
#[macro_export]
|
||||
macro_rules! panic {
|
||||
|
@ -105,6 +129,16 @@ macro_rules! try {
|
|||
($e:expr) => (match $e { Ok(e) => e, Err(e) => return Err(e) })
|
||||
}
|
||||
|
||||
// NOTE(stage0): Remove cfg after a snapshot
|
||||
#[cfg(not(stage0))]
|
||||
/// Writing a formatted string into a writer
|
||||
#[macro_export]
|
||||
macro_rules! write {
|
||||
($dst:expr, $($arg:tt)*) => ((&mut *$dst).write_fmt(format_args!($($arg)*)))
|
||||
}
|
||||
|
||||
// NOTE(stage0): Remove macro after a snapshot
|
||||
#[cfg(stage0)]
|
||||
/// Writing a formatted string into a writer
|
||||
#[macro_export]
|
||||
macro_rules! write {
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
//! interface for panicking is:
|
||||
//!
|
||||
//! ```ignore
|
||||
//! fn panic_impl(fmt: &fmt::Arguments, &(&'static str, uint)) -> !;
|
||||
//! fn panic_impl(fmt: fmt::Arguments, &(&'static str, uint)) -> !;
|
||||
//! ```
|
||||
//!
|
||||
//! This definition allows for panicking with any general message, but it does not
|
||||
|
@ -31,8 +31,20 @@
|
|||
#![allow(dead_code, missing_docs)]
|
||||
|
||||
use fmt;
|
||||
use intrinsics;
|
||||
// NOTE(stage0): Remove import after a snapshot
|
||||
#[cfg(stage0)] use intrinsics;
|
||||
|
||||
// NOTE(stage0): Remove cfg after a snapshot
|
||||
#[cfg(not(stage0))]
|
||||
#[cold] #[inline(never)] // this is the slow path, always
|
||||
#[lang="panic"]
|
||||
pub fn panic(expr_file_line: &(&'static str, &'static str, uint)) -> ! {
|
||||
let (expr, file, line) = *expr_file_line;
|
||||
panic_fmt(format_args!("{}", expr), &(file, line))
|
||||
}
|
||||
|
||||
// NOTE(stage0): Remove function after a snapshot
|
||||
#[cfg(stage0)]
|
||||
#[cold] #[inline(never)] // this is the slow path, always
|
||||
#[lang="panic"]
|
||||
pub fn panic(expr_file_line: &(&'static str, &'static str, uint)) -> ! {
|
||||
|
@ -45,6 +57,18 @@ pub fn panic(expr_file_line: &(&'static str, &'static str, uint)) -> ! {
|
|||
unsafe { intrinsics::abort() }
|
||||
}
|
||||
|
||||
// NOTE(stage0): Remove cfg after a snapshot
|
||||
#[cfg(not(stage0))]
|
||||
#[cold] #[inline(never)]
|
||||
#[lang="panic_bounds_check"]
|
||||
fn panic_bounds_check(file_line: &(&'static str, uint),
|
||||
index: uint, len: uint) -> ! {
|
||||
panic_fmt(format_args!("index out of bounds: the len is {} but the index is {}",
|
||||
len, index), file_line)
|
||||
}
|
||||
|
||||
// NOTE(stage0): Remove function after a snapshot
|
||||
#[cfg(stage0)]
|
||||
#[cold] #[inline(never)]
|
||||
#[lang="panic_bounds_check"]
|
||||
fn panic_bounds_check(file_line: &(&'static str, uint),
|
||||
|
@ -55,6 +79,21 @@ fn panic_bounds_check(file_line: &(&'static str, uint),
|
|||
unsafe { intrinsics::abort() }
|
||||
}
|
||||
|
||||
// NOTE(stage0): Remove cfg after a snapshot
|
||||
#[cfg(not(stage0))]
|
||||
#[cold] #[inline(never)]
|
||||
pub fn panic_fmt(fmt: fmt::Arguments, file_line: &(&'static str, uint)) -> ! {
|
||||
#[allow(improper_ctypes)]
|
||||
extern {
|
||||
#[lang = "panic_fmt"]
|
||||
fn panic_impl(fmt: fmt::Arguments, file: &'static str, line: uint) -> !;
|
||||
}
|
||||
let (file, line) = *file_line;
|
||||
unsafe { panic_impl(fmt, file, line) }
|
||||
}
|
||||
|
||||
// NOTE(stage0): Remove function after a snapshot
|
||||
#[cfg(stage0)]
|
||||
#[cold] #[inline(never)]
|
||||
pub fn panic_fmt(fmt: &fmt::Arguments, file_line: &(&'static str, uint)) -> ! {
|
||||
#[allow(improper_ctypes)]
|
||||
|
|
|
@ -268,6 +268,8 @@ impl Drop for DefaultLogger {
|
|||
}
|
||||
}
|
||||
|
||||
// NOTE(stage0): Remove cfg after a snapshot
|
||||
#[cfg(not(stage0))]
|
||||
/// This function is called directly by the compiler when using the logging
|
||||
/// macros. This function does not take into account whether the log level
|
||||
/// specified is active or not, it will always log something if this method is
|
||||
|
@ -276,7 +278,7 @@ impl Drop for DefaultLogger {
|
|||
/// It is not recommended to call this function directly, rather it should be
|
||||
/// invoked through the logging family of macros.
|
||||
#[doc(hidden)]
|
||||
pub fn log(level: u32, loc: &'static LogLocation, args: &fmt::Arguments) {
|
||||
pub fn log(level: u32, loc: &'static LogLocation, args: fmt::Arguments) {
|
||||
// Test the literal string from args against the current filter, if there
|
||||
// is one.
|
||||
match unsafe { FILTER.as_ref() } {
|
||||
|
@ -302,6 +304,42 @@ pub fn log(level: u32, loc: &'static LogLocation, args: &fmt::Arguments) {
|
|||
set_logger(logger);
|
||||
}
|
||||
|
||||
// NOTE(stage0): Remove function after a snapshot
|
||||
#[cfg(stage0)]
|
||||
/// This function is called directly by the compiler when using the logging
|
||||
/// macros. This function does not take into account whether the log level
|
||||
/// specified is active or not, it will always log something if this method is
|
||||
/// called.
|
||||
///
|
||||
/// It is not recommended to call this function directly, rather it should be
|
||||
/// invoked through the logging family of macros.
|
||||
#[doc(hidden)]
|
||||
pub fn log(level: u32, loc: &'static LogLocation, args: &fmt::Arguments) {
|
||||
// Test the literal string from args against the current filter, if there
|
||||
// is one.
|
||||
match unsafe { FILTER.as_ref() } {
|
||||
Some(filter) if !filter.is_match(args.to_string().as_slice()) => return,
|
||||
_ => {}
|
||||
}
|
||||
|
||||
// Completely remove the local logger from TLS in case anyone attempts to
|
||||
// frob the slot while we're doing the logging. This will destroy any logger
|
||||
// set during logging.
|
||||
let mut logger = LOCAL_LOGGER.with(|s| {
|
||||
s.borrow_mut().take()
|
||||
}).unwrap_or_else(|| {
|
||||
box DefaultLogger { handle: io::stderr() } as Box<Logger + Send>
|
||||
});
|
||||
logger.log(&LogRecord {
|
||||
level: LogLevel(level),
|
||||
args: *args,
|
||||
file: loc.file,
|
||||
module_path: loc.module_path,
|
||||
line: loc.line,
|
||||
});
|
||||
set_logger(logger);
|
||||
}
|
||||
|
||||
/// Getter for the global log level. This is a function so that it can be called
|
||||
/// safely
|
||||
#[doc(hidden)]
|
||||
|
@ -329,7 +367,7 @@ pub struct LogRecord<'a> {
|
|||
pub level: LogLevel,
|
||||
|
||||
/// The arguments from the log line.
|
||||
pub args: &'a fmt::Arguments<'a>,
|
||||
pub args: fmt::Arguments<'a>,
|
||||
|
||||
/// The file of where the LogRecord originated.
|
||||
pub file: &'a str,
|
||||
|
|
|
@ -12,6 +12,63 @@
|
|||
|
||||
#![macro_escape]
|
||||
|
||||
// NOTE(stage0): Remove cfg after a snapshot
|
||||
#[cfg(not(stage0))]
|
||||
/// The standard logging macro
|
||||
///
|
||||
/// This macro will generically log over a provided level (of type u32) with a
|
||||
/// format!-based argument list. See documentation in `std::fmt` for details on
|
||||
/// how to use the syntax.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// #![feature(phase)]
|
||||
/// #[phase(plugin, link)] extern crate log;
|
||||
///
|
||||
/// fn main() {
|
||||
/// log!(log::WARN, "this is a warning {}", "message");
|
||||
/// log!(log::DEBUG, "this is a debug message");
|
||||
/// log!(6, "this is a custom logging level: {level}", level=6u);
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// Assumes the binary is `main`:
|
||||
///
|
||||
/// ```{.bash}
|
||||
/// $ RUST_LOG=warn ./main
|
||||
/// WARN:main: this is a warning message
|
||||
/// ```
|
||||
///
|
||||
/// ```{.bash}
|
||||
/// $ RUST_LOG=debug ./main
|
||||
/// DEBUG:main: this is a debug message
|
||||
/// WARN:main: this is a warning message
|
||||
/// ```
|
||||
///
|
||||
/// ```{.bash}
|
||||
/// $ RUST_LOG=6 ./main
|
||||
/// DEBUG:main: this is a debug message
|
||||
/// WARN:main: this is a warning message
|
||||
/// 6:main: this is a custom logging level: 6
|
||||
/// ```
|
||||
#[macro_export]
|
||||
macro_rules! log {
|
||||
($lvl:expr, $($arg:tt)+) => ({
|
||||
static LOC: ::log::LogLocation = ::log::LogLocation {
|
||||
line: line!(),
|
||||
file: file!(),
|
||||
module_path: module_path!(),
|
||||
};
|
||||
let lvl = $lvl;
|
||||
if log_enabled!(lvl) {
|
||||
::log::log(lvl, &LOC, format_args!($($arg)+))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// NOTE(stage0): Remove macro after a snapshot
|
||||
#[cfg(stage0)]
|
||||
/// The standard logging macro
|
||||
///
|
||||
/// This macro will generically log over a provided level (of type u32) with a
|
||||
|
|
|
@ -16,13 +16,6 @@
|
|||
//! This macro is implemented in the compiler to emit calls to this module in
|
||||
//! order to format arguments at runtime into strings and streams.
|
||||
//!
|
||||
//! The functions contained in this module should not normally be used in
|
||||
//! everyday use cases of `format!`. The assumptions made by these functions are
|
||||
//! unsafe for all inputs, and the compiler performs a large amount of
|
||||
//! validation on the arguments to `format!` in order to ensure safety at
|
||||
//! runtime. While it is possible to call these functions directly, it is not
|
||||
//! recommended to do so in the general case.
|
||||
//!
|
||||
//! ## Usage
|
||||
//!
|
||||
//! The `format!` macro is intended to be familiar to those coming from C's
|
||||
|
@ -275,35 +268,28 @@
|
|||
//!
|
||||
//! # #[allow(unused_must_use)]
|
||||
//! # fn main() {
|
||||
//! format_args!(fmt::format, "this returns {}", "String");
|
||||
//! fmt::format(format_args!("this returns {}", "String"));
|
||||
//!
|
||||
//! let some_writer: &mut io::Writer = &mut io::stdout();
|
||||
//! format_args!(|args| { write!(some_writer, "{}", args) },
|
||||
//! "print with a {}", "closure");
|
||||
//! write!(some_writer, "{}", format_args!("print with a {}", "macro"));
|
||||
//!
|
||||
//! fn my_fmt_fn(args: &fmt::Arguments) {
|
||||
//! fn my_fmt_fn(args: fmt::Arguments) {
|
||||
//! write!(&mut io::stdout(), "{}", args);
|
||||
//! }
|
||||
//! format_args!(my_fmt_fn, "or a {} too", "function");
|
||||
//! my_fmt_fn(format_args!("or a {} too", "function"));
|
||||
//! # }
|
||||
//! ```
|
||||
//!
|
||||
//! The first argument of the `format_args!` macro is a function (or closure)
|
||||
//! which takes one argument of type `&fmt::Arguments`. This structure can then
|
||||
//! be passed to the `write` and `format` functions inside this module in order
|
||||
//! to process the format string. The goal of this macro is to even further
|
||||
//! prevent intermediate allocations when dealing formatting strings.
|
||||
//! The result of the `format_args!` macro is a value of type `fmt::Arguments`.
|
||||
//! This structure can then be passed to the `write` and `format` functions
|
||||
//! inside this module in order to process the format string.
|
||||
//! The goal of this macro is to even further prevent intermediate allocations
|
||||
//! when dealing formatting strings.
|
||||
//!
|
||||
//! For example, a logging library could use the standard formatting syntax, but
|
||||
//! it would internally pass around this structure until it has been determined
|
||||
//! where output should go to.
|
||||
//!
|
||||
//! It is unsafe to programmatically create an instance of `fmt::Arguments`
|
||||
//! because the operations performed when executing a format string require the
|
||||
//! compile-time checks provided by the compiler. The `format_args!` macro is
|
||||
//! the only method of safely creating these structures, but they can be
|
||||
//! unsafely created with the constructor provided.
|
||||
//!
|
||||
//! ## Syntax
|
||||
//!
|
||||
//! The syntax for the formatting language used is drawn from other languages,
|
||||
|
@ -420,14 +406,39 @@ pub use core::fmt::{Argument, Arguments, write, radix, Radix, RadixFmt};
|
|||
#[doc(hidden)]
|
||||
pub use core::fmt::{argument, argumentuint};
|
||||
|
||||
// NOTE(stage0): Remove cfg after a snapshot
|
||||
#[cfg(not(stage0))]
|
||||
/// The format function takes a precompiled format string and a list of
|
||||
/// arguments, to return the resulting formatted string.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * args - a structure of arguments generated via the `format_args!` macro.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```rust
|
||||
/// use std::fmt;
|
||||
///
|
||||
/// let s = fmt::format(format_args!("Hello, {}!", "world"));
|
||||
/// assert_eq!(s, "Hello, world!".to_string());
|
||||
/// ```
|
||||
#[experimental = "this is an implementation detail of format! and should not \
|
||||
be called directly"]
|
||||
pub fn format(args: Arguments) -> string::String {
|
||||
let mut output = Vec::new();
|
||||
let _ = write!(&mut output as &mut Writer, "{}", args);
|
||||
string::String::from_utf8(output).unwrap()
|
||||
}
|
||||
|
||||
// NOTE(stage0): Remove function after a snapshot
|
||||
#[cfg(stage0)]
|
||||
/// The format function takes a precompiled format string and a list of
|
||||
/// arguments, to return the resulting formatted string.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * args - a structure of arguments generated via the `format_args!` macro.
|
||||
/// Because this structure can only be safely generated at
|
||||
/// compile-time, this function is safe.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
|
|
|
@ -1017,6 +1017,48 @@ pub trait Writer {
|
|||
/// decide whether their stream needs to be buffered or not.
|
||||
fn flush(&mut self) -> IoResult<()> { Ok(()) }
|
||||
|
||||
// NOTE(stage0): Remove cfg after a snapshot
|
||||
#[cfg(not(stage0))]
|
||||
/// Writes a formatted string into this writer, returning any error
|
||||
/// encountered.
|
||||
///
|
||||
/// This method is primarily used to interface with the `format_args!`
|
||||
/// macro, but it is rare that this should explicitly be called. The
|
||||
/// `write!` macro should be favored to invoke this method instead.
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// This function will return any I/O error reported while formatting.
|
||||
fn write_fmt(&mut self, fmt: fmt::Arguments) -> IoResult<()> {
|
||||
// Create a shim which translates a Writer to a FormatWriter and saves
|
||||
// off I/O errors. instead of discarding them
|
||||
struct Adaptor<'a, T:'a> {
|
||||
inner: &'a mut T,
|
||||
error: IoResult<()>,
|
||||
}
|
||||
|
||||
impl<'a, T: Writer> fmt::FormatWriter for Adaptor<'a, T> {
|
||||
fn write(&mut self, bytes: &[u8]) -> fmt::Result {
|
||||
match self.inner.write(bytes) {
|
||||
Ok(()) => Ok(()),
|
||||
Err(e) => {
|
||||
self.error = Err(e);
|
||||
Err(fmt::Error)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let mut output = Adaptor { inner: self, error: Ok(()) };
|
||||
match fmt::write(&mut output, fmt) {
|
||||
Ok(()) => Ok(()),
|
||||
Err(..) => output.error
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// NOTE(stage0): Remove method after a snapshot
|
||||
#[cfg(stage0)]
|
||||
/// Writes a formatted string into this writer, returning any error
|
||||
/// encountered.
|
||||
///
|
||||
|
|
|
@ -378,12 +378,32 @@ pub fn println(s: &str) {
|
|||
})
|
||||
}
|
||||
|
||||
// NOTE(stage0): Remove cfg after a snapshot
|
||||
#[cfg(not(stage0))]
|
||||
/// Similar to `print`, but takes a `fmt::Arguments` structure to be compatible
|
||||
/// with the `format_args!` macro.
|
||||
pub fn print_args(fmt: fmt::Arguments) {
|
||||
with_task_stdout(|io| write!(io, "{}", fmt))
|
||||
}
|
||||
|
||||
// NOTE(stage0): Remove function after a snapshot
|
||||
#[cfg(stage0)]
|
||||
/// Similar to `print`, but takes a `fmt::Arguments` structure to be compatible
|
||||
/// with the `format_args!` macro.
|
||||
pub fn print_args(fmt: &fmt::Arguments) {
|
||||
with_task_stdout(|io| write!(io, "{}", fmt))
|
||||
}
|
||||
|
||||
// NOTE(stage0): Remove cfg after a snapshot
|
||||
#[cfg(not(stage0))]
|
||||
/// Similar to `println`, but takes a `fmt::Arguments` structure to be
|
||||
/// compatible with the `format_args!` macro.
|
||||
pub fn println_args(fmt: fmt::Arguments) {
|
||||
with_task_stdout(|io| writeln!(io, "{}", fmt))
|
||||
}
|
||||
|
||||
// NOTE(stage0): Remove function after a snapshot
|
||||
#[cfg(stage0)]
|
||||
/// Similar to `println`, but takes a `fmt::Arguments` structure to be
|
||||
/// compatible with the `format_args!` macro.
|
||||
pub fn println_args(fmt: &fmt::Arguments) {
|
||||
|
|
|
@ -17,6 +17,50 @@
|
|||
#![experimental]
|
||||
#![macro_escape]
|
||||
|
||||
// NOTE(stage0): Remove cfg after a snapshot
|
||||
#[cfg(not(stage0))]
|
||||
/// The entry point for panic of Rust tasks.
|
||||
///
|
||||
/// This macro is used to inject panic into a Rust task, causing the task to
|
||||
/// unwind and panic entirely. Each task's panic can be reaped as the
|
||||
/// `Box<Any>` type, and the single-argument form of the `panic!` macro will be
|
||||
/// the value which is transmitted.
|
||||
///
|
||||
/// The multi-argument form of this macro panics with a string and has the
|
||||
/// `format!` syntax for building a string.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```should_fail
|
||||
/// # #![allow(unreachable_code)]
|
||||
/// panic!();
|
||||
/// panic!("this is a terrible mistake!");
|
||||
/// panic!(4i); // panic with the value of 4 to be collected elsewhere
|
||||
/// panic!("this is a {} {message}", "fancy", message = "message");
|
||||
/// ```
|
||||
#[macro_export]
|
||||
macro_rules! panic {
|
||||
() => ({
|
||||
panic!("explicit panic")
|
||||
});
|
||||
($msg:expr) => ({
|
||||
// static requires less code at runtime, more constant data
|
||||
static _FILE_LINE: (&'static str, uint) = (file!(), line!());
|
||||
::std::rt::begin_unwind($msg, &_FILE_LINE)
|
||||
});
|
||||
($fmt:expr, $($arg:tt)*) => ({
|
||||
// The leading _'s are to avoid dead code warnings if this is
|
||||
// used inside a dead function. Just `#[allow(dead_code)]` is
|
||||
// insufficient, since the user may have
|
||||
// `#[forbid(dead_code)]` and which cannot be overridden.
|
||||
static _FILE_LINE: (&'static str, uint) = (file!(), line!());
|
||||
::std::rt::begin_unwind_fmt(format_args!($fmt, $($arg)*), &_FILE_LINE)
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
// NOTE(stage0): Remove macro after a snapshot
|
||||
#[cfg(stage0)]
|
||||
/// The entry point for panic of Rust tasks.
|
||||
///
|
||||
/// This macro is used to inject panic into a Rust task, causing the task to
|
||||
|
@ -245,6 +289,26 @@ macro_rules! unimplemented {
|
|||
() => (panic!("not yet implemented"))
|
||||
}
|
||||
|
||||
// NOTE(stage0): Remove cfg after a snapshot
|
||||
#[cfg(not(stage0))]
|
||||
/// Use the syntax described in `std::fmt` to create a value of type `String`.
|
||||
/// See `std::fmt` for more information.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// format!("test");
|
||||
/// format!("hello {}", "world!");
|
||||
/// format!("x = {}, y = {y}", 10i, y = 30i);
|
||||
/// ```
|
||||
#[macro_export]
|
||||
#[stable]
|
||||
macro_rules! format {
|
||||
($($arg:tt)*) => (::std::fmt::format(format_args!($($arg)*)))
|
||||
}
|
||||
|
||||
// NOTE(stage0): Remove macro after a snapshot
|
||||
#[cfg(stage0)]
|
||||
/// Use the syntax described in `std::fmt` to create a value of type `String`.
|
||||
/// See `std::fmt` for more information.
|
||||
///
|
||||
|
@ -263,6 +327,28 @@ macro_rules! format {
|
|||
)
|
||||
}
|
||||
|
||||
// NOTE(stage0): Remove cfg after a snapshot
|
||||
#[cfg(not(stage0))]
|
||||
/// Use the `format!` syntax to write data into a buffer of type `&mut Writer`.
|
||||
/// See `std::fmt` for more information.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// # #![allow(unused_must_use)]
|
||||
///
|
||||
/// let mut w = Vec::new();
|
||||
/// write!(&mut w, "test");
|
||||
/// write!(&mut w, "formatted {}", "arguments");
|
||||
/// ```
|
||||
#[macro_export]
|
||||
#[stable]
|
||||
macro_rules! write {
|
||||
($dst:expr, $($arg:tt)*) => ((&mut *$dst).write_fmt(format_args!($($arg)*)))
|
||||
}
|
||||
|
||||
// NOTE(stage0): Remove macro after a snapshot
|
||||
#[cfg(stage0)]
|
||||
/// Use the `format!` syntax to write data into a buffer of type `&mut Writer`.
|
||||
/// See `std::fmt` for more information.
|
||||
///
|
||||
|
@ -294,6 +380,18 @@ macro_rules! writeln {
|
|||
)
|
||||
}
|
||||
|
||||
// NOTE(stage0): Remove cfg after a snapshot
|
||||
#[cfg(not(stage0))]
|
||||
/// Equivalent to the `println!` macro except that a newline is not printed at
|
||||
/// the end of the message.
|
||||
#[macro_export]
|
||||
#[stable]
|
||||
macro_rules! print {
|
||||
($($arg:tt)*) => (::std::io::stdio::print_args(format_args!($($arg)*)))
|
||||
}
|
||||
|
||||
// NOTE(stage0): Remove macro after a snapshot
|
||||
#[cfg(stage0)]
|
||||
/// Equivalent to the `println!` macro except that a newline is not printed at
|
||||
/// the end of the message.
|
||||
#[macro_export]
|
||||
|
@ -302,6 +400,28 @@ macro_rules! print {
|
|||
($($arg:tt)*) => (format_args!(::std::io::stdio::print_args, $($arg)*))
|
||||
}
|
||||
|
||||
// NOTE(stage0): Remove cfg after a snapshot
|
||||
#[cfg(not(stage0))]
|
||||
/// Macro for printing to a task's stdout handle.
|
||||
///
|
||||
/// Each task can override its stdout handle via `std::io::stdio::set_stdout`.
|
||||
/// The syntax of this macro is the same as that used for `format!`. For more
|
||||
/// information, see `std::fmt` and `std::io::stdio`.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// println!("hello there!");
|
||||
/// println!("format {} arguments", "some");
|
||||
/// ```
|
||||
#[macro_export]
|
||||
#[stable]
|
||||
macro_rules! println {
|
||||
($($arg:tt)*) => (::std::io::stdio::println_args(format_args!($($arg)*)))
|
||||
}
|
||||
|
||||
// NOTE(stage0): Remove macro after a snapshot
|
||||
#[cfg(stage0)]
|
||||
/// Macro for printing to a task's stdout handle.
|
||||
///
|
||||
/// Each task can override its stdout handle via `std::io::stdio::set_stdout`.
|
||||
|
@ -411,11 +531,10 @@ macro_rules! log {
|
|||
pub mod builtin {
|
||||
/// The core macro for formatted string creation & output.
|
||||
///
|
||||
/// This macro takes as its first argument a callable expression which will
|
||||
/// receive as its first argument a value of type `&fmt::Arguments`. This
|
||||
/// value can be passed to the functions in `std::fmt` for performing useful
|
||||
/// functions. All other formatting macros (`format!`, `write!`,
|
||||
/// `println!`, etc) are proxied through this one.
|
||||
/// This macro produces a value of type `fmt::Arguments`. This value can be
|
||||
/// passed to the functions in `std::fmt` for performing useful functions.
|
||||
/// All other formatting macros (`format!`, `write!`, `println!`, etc) are
|
||||
/// proxied through this one.
|
||||
///
|
||||
/// For more information, see the documentation in `std::fmt`.
|
||||
///
|
||||
|
@ -424,15 +543,12 @@ pub mod builtin {
|
|||
/// ```rust
|
||||
/// use std::fmt;
|
||||
///
|
||||
/// let s = format_args!(fmt::format, "hello {}", "world");
|
||||
/// let s = fmt::format(format_args!("hello {}", "world"));
|
||||
/// assert_eq!(s, format!("hello {}", "world"));
|
||||
///
|
||||
/// format_args!(|args| {
|
||||
/// // pass `args` to another function, etc.
|
||||
/// }, "hello {}", "world");
|
||||
/// ```
|
||||
#[macro_export]
|
||||
macro_rules! format_args { ($closure:expr, $fmt:expr $($args:tt)*) => ({
|
||||
macro_rules! format_args { ($fmt:expr $($args:tt)*) => ({
|
||||
/* compiler built-in */
|
||||
}) }
|
||||
|
||||
|
|
|
@ -15,6 +15,16 @@
|
|||
|
||||
#![macro_escape]
|
||||
|
||||
// NOTE(stage0): Remove cfg after a snapshot
|
||||
#[cfg(not(stage0))]
|
||||
macro_rules! rterrln {
|
||||
($fmt:expr $($arg:tt)*) => ( {
|
||||
::rt::util::dumb_print(format_args!(concat!($fmt, "\n") $($arg)*))
|
||||
} )
|
||||
}
|
||||
|
||||
// NOTE(stage0): Remove macro after a snapshot
|
||||
#[cfg(stage0)]
|
||||
macro_rules! rterrln {
|
||||
($fmt:expr $($arg:tt)*) => ( {
|
||||
format_args!(::rt::util::dumb_print, concat!($fmt, "\n") $($arg)*)
|
||||
|
@ -40,6 +50,14 @@ macro_rules! rtassert {
|
|||
} )
|
||||
}
|
||||
|
||||
// NOTE(stage0): Remove cfg after a snapshot
|
||||
#[cfg(not(stage0))]
|
||||
macro_rules! rtabort {
|
||||
($($arg:tt)*) => (::rt::util::abort(format_args!($($arg)*)))
|
||||
}
|
||||
|
||||
// NOTE(stage0): Remove macro after a snapshot
|
||||
#[cfg(stage0)]
|
||||
macro_rules! rtabort {
|
||||
($($arg:tt)*) => (format_args!(::rt::util::abort, $($arg)*))
|
||||
}
|
||||
|
|
|
@ -477,14 +477,61 @@ pub mod eabi {
|
|||
}
|
||||
}
|
||||
|
||||
// Entry point of panic from the libcore crate
|
||||
// NOTE(stage0): Remove cfg after a snapshot
|
||||
#[cfg(not(stage0))]
|
||||
#[cfg(not(test))]
|
||||
/// Entry point of panic from the libcore crate.
|
||||
#[lang = "panic_fmt"]
|
||||
pub extern fn rust_begin_unwind(msg: fmt::Arguments,
|
||||
file: &'static str, line: uint) -> ! {
|
||||
begin_unwind_fmt(msg, &(file, line))
|
||||
}
|
||||
|
||||
// NOTE(stage0): Remove function after a snapshot
|
||||
#[cfg(stage0)]
|
||||
#[cfg(not(test))]
|
||||
/// Entry point of panic from the libcore crate.
|
||||
#[lang = "panic_fmt"]
|
||||
pub extern fn rust_begin_unwind(msg: &fmt::Arguments,
|
||||
file: &'static str, line: uint) -> ! {
|
||||
begin_unwind_fmt(msg, &(file, line))
|
||||
}
|
||||
|
||||
// NOTE(stage0): Remove cfg after a snapshot
|
||||
#[cfg(not(stage0))]
|
||||
/// The entry point for unwinding with a formatted message.
|
||||
///
|
||||
/// This is designed to reduce the amount of code required at the call
|
||||
/// site as much as possible (so that `panic!()` has as low an impact
|
||||
/// on (e.g.) the inlining of other functions as possible), by moving
|
||||
/// the actual formatting into this shared place.
|
||||
#[inline(never)] #[cold]
|
||||
pub fn begin_unwind_fmt(msg: fmt::Arguments, file_line: &(&'static str, uint)) -> ! {
|
||||
use fmt::FormatWriter;
|
||||
|
||||
// We do two allocations here, unfortunately. But (a) they're
|
||||
// required with the current scheme, and (b) we don't handle
|
||||
// panic + OOM properly anyway (see comment in begin_unwind
|
||||
// below).
|
||||
|
||||
struct VecWriter<'a> { v: &'a mut Vec<u8> }
|
||||
|
||||
impl<'a> fmt::FormatWriter for VecWriter<'a> {
|
||||
fn write(&mut self, buf: &[u8]) -> fmt::Result {
|
||||
self.v.push_all(buf);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
let mut v = Vec::new();
|
||||
let _ = write!(&mut VecWriter { v: &mut v }, "{}", msg);
|
||||
|
||||
let msg = box String::from_utf8_lossy(v.as_slice()).into_owned();
|
||||
begin_unwind_inner(msg, file_line)
|
||||
}
|
||||
|
||||
// NOTE(stage0): Remove function after a snapshot
|
||||
#[cfg(stage0)]
|
||||
/// The entry point for unwinding with a formatted message.
|
||||
///
|
||||
/// This is designed to reduce the amount of code required at the call
|
||||
|
|
|
@ -112,12 +112,25 @@ impl fmt::FormatWriter for Stdio {
|
|||
}
|
||||
}
|
||||
|
||||
// NOTE(stage0): Remove cfg after a snapshot
|
||||
#[cfg(not(stage0))]
|
||||
pub fn dumb_print(args: fmt::Arguments) {
|
||||
let _ = Stderr.write_fmt(args);
|
||||
}
|
||||
|
||||
// NOTE(stage0): Remove function after a snapshot
|
||||
#[cfg(stage0)]
|
||||
pub fn dumb_print(args: &fmt::Arguments) {
|
||||
let mut w = Stderr;
|
||||
let _ = write!(&mut w, "{}", args);
|
||||
}
|
||||
|
||||
pub fn abort(args: &fmt::Arguments) -> ! {
|
||||
// NOTE(stage0): Remove wrappers after a snapshot
|
||||
#[cfg(not(stage0))] pub fn abort(args: fmt::Arguments) -> ! { abort_(&args) }
|
||||
#[cfg(stage0)] pub fn abort(args: &fmt::Arguments) -> ! { abort_(args) }
|
||||
|
||||
// NOTE(stage0): Change to `pub fn abort(args: fmt::Arguments) -> !` after a snapshot
|
||||
fn abort_(args: &fmt::Arguments) -> ! {
|
||||
use fmt::FormatWriter;
|
||||
|
||||
struct BufWriter<'a> {
|
||||
|
|
|
@ -13,5 +13,5 @@
|
|||
fn main() {
|
||||
let x: || -> ! = || panic!();
|
||||
x();
|
||||
println!("Foo bar"); //~ ERROR: unreachable statement
|
||||
std::io::println("Foo bar"); //~ ERROR: unreachable statement
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
|
||||
// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
|
@ -9,6 +9,6 @@
|
|||
// except according to those terms.
|
||||
|
||||
fn main() {
|
||||
format_args!("test"); //~ ERROR: expected token
|
||||
format_args!("", || {}); //~ ERROR: must be a string literal
|
||||
format_args!(); //~ ERROR: requires at least a format string argument
|
||||
format_args!(|| {}); //~ ERROR: must be a string literal
|
||||
}
|
||||
|
|
|
@ -1,13 +0,0 @@
|
|||
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
fn main() {
|
||||
format_args!("{}", ""); //~ ERROR: expected function
|
||||
}
|
|
@ -34,13 +34,6 @@ pub fn bar() {
|
|||
[int; 3]) as &[int; 3]) as *const _ as *const [int; 3]) as
|
||||
*const [int; (3u as uint)] as *const [int; 3]);
|
||||
|
||||
(match (() as ()) {
|
||||
() => {
|
||||
#[inline]
|
||||
#[allow(dead_code)]
|
||||
static __STATIC_FMTSTR: &'static [&'static str] =
|
||||
(&([("test" as &'static str)] as [&'static str; 1]) as
|
||||
&'static [&'static str; 1]);
|
||||
|
||||
|
||||
|
||||
|
@ -49,24 +42,45 @@ pub fn bar() {
|
|||
|
||||
|
||||
|
||||
((::std::fmt::format as
|
||||
fn(&core::fmt::Arguments<'_>) -> collections::string::String {std::fmt::format})((&((::std::fmt::Arguments::new
|
||||
as
|
||||
fn(&[&str], &[core::fmt::Argument<'_>]) -> core::fmt::Arguments<'_> {core::fmt::Arguments<'a>::new})((__STATIC_FMTSTR
|
||||
as
|
||||
&'static [&'static str]),
|
||||
(&([]
|
||||
as
|
||||
[core::fmt::Argument<'_>; 0])
|
||||
as
|
||||
&[core::fmt::Argument<'_>; 0]))
|
||||
as
|
||||
core::fmt::Arguments<'_>)
|
||||
as
|
||||
&core::fmt::Arguments<'_>))
|
||||
as collections::string::String)
|
||||
}
|
||||
} as collections::string::String);
|
||||
((::std::fmt::format as
|
||||
fn(core::fmt::Arguments<'_>) -> collections::string::String {std::fmt::format})(((::std::fmt::Arguments::new
|
||||
as
|
||||
fn(&[&str], &[core::fmt::Argument<'_>]) -> core::fmt::Arguments<'_> {core::fmt::Arguments<'a>::new})(({
|
||||
#[inline]
|
||||
#[allow(dead_code)]
|
||||
static __STATIC_FMTSTR:
|
||||
&'static [&'static str]
|
||||
=
|
||||
(&([("test"
|
||||
as
|
||||
&'static str)]
|
||||
as
|
||||
[&'static str; 1])
|
||||
as
|
||||
&'static [&'static str; 1]);
|
||||
(__STATIC_FMTSTR
|
||||
as
|
||||
&'static [&'static str])
|
||||
}
|
||||
as
|
||||
&[&str]),
|
||||
(&(match (()
|
||||
as
|
||||
())
|
||||
{
|
||||
()
|
||||
=>
|
||||
([]
|
||||
as
|
||||
[core::fmt::Argument<'_>; 0]),
|
||||
}
|
||||
as
|
||||
[core::fmt::Argument<'_>; 0])
|
||||
as
|
||||
&[core::fmt::Argument<'_>; 0]))
|
||||
as
|
||||
core::fmt::Arguments<'_>))
|
||||
as collections::string::String);
|
||||
}
|
||||
pub type Foo = [int; (3u as uint)];
|
||||
pub struct Bar {
|
||||
|
|
|
@ -190,18 +190,16 @@ fn test_format_args() {
|
|||
let mut buf = Vec::new();
|
||||
{
|
||||
let w = &mut buf as &mut io::Writer;
|
||||
format_args!(|args| { write!(w, "{}", args); }, "{}", 1i);
|
||||
format_args!(|args| { write!(w, "{}", args); }, "test");
|
||||
format_args!(|args| { write!(w, "{}", args); }, "{test}", test=3i);
|
||||
write!(w, "{}", format_args!("{}", 1i));
|
||||
write!(w, "{}", format_args!("test"));
|
||||
write!(w, "{}", format_args!("{test}", test=3i));
|
||||
}
|
||||
let s = String::from_utf8(buf).unwrap();
|
||||
t!(s, "1test3");
|
||||
|
||||
let s = format_args!(fmt::format, "hello {}", "world");
|
||||
let s = fmt::format(format_args!("hello {}", "world"));
|
||||
t!(s, "hello world");
|
||||
let s = format_args!(|args| {
|
||||
format!("{}: {}", "args were", args)
|
||||
}, "hello {}", "world");
|
||||
let s = format!("{}: {}", "args were", format_args!("hello {}", "world"));
|
||||
t!(s, "args were: hello world");
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue