Skip to content

Commit

Permalink
auto merge of #5293 : brson/rust/logging, r=brson
Browse files Browse the repository at this point in the history
r? @graydon

This removes `log` from the language. Because we can't quite implement it as a syntax extension (probably need globals at the least) it simply renames the keyword to `__log` and hides it behind macros.

After this the only way to log is with `debug!`, `info!`, etc. I figure that if there is demand for `log!` we can add it back later.

I am not sure that we ever agreed on this course of action, though I *think* there is consensus that `log` shouldn't be a statement.
  • Loading branch information
bors committed Mar 13, 2013
2 parents 0ad3a11 + 9c7e16e commit 695e9fd
Show file tree
Hide file tree
Showing 228 changed files with 892 additions and 995 deletions.
73 changes: 10 additions & 63 deletions doc/rust.md
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ do drop
else enum extern
false fn for
if impl
let log loop
let loop
match mod mut
priv pub pure
ref return
Expand Down Expand Up @@ -805,21 +805,20 @@ Use declarations support a number of "convenience" notations:
An example of `use` declarations:

~~~~
use foo = core::info;
use core::float::sin;
use core::str::{slice, to_upper};
use core::option::Some;
fn main() {
// Equivalent to 'log(core::info, core::float::sin(1.0));'
log(foo, sin(1.0));
// Equivalent to 'info!(core::float::sin(1.0));'
info!(sin(1.0));
// Equivalent to 'log(core::info, core::option::Some(1.0));'
log(info, Some(1.0));
// Equivalent to 'info!(core::option::Some(1.0));'
info!(Some(1.0));
// Equivalent to 'log(core::info,
// core::str::to_upper(core::str::slice("foo", 0, 1)));'
log(info, to_upper(slice("foo", 0, 1)));
// Equivalent to
// 'info!(core::str::to_upper(core::str::slice("foo", 0, 1)));'
info!(to_upper(slice("foo", 0, 1)));
}
~~~~

Expand Down Expand Up @@ -990,7 +989,7 @@ output slot type would normally be. For example:

~~~~
fn my_err(s: &str) -> ! {
log(info, s);
info!(s);
fail!();
}
~~~~
Expand Down Expand Up @@ -2397,58 +2396,6 @@ fn max(a: int, b: int) -> int {
}
~~~~

### Log expressions

~~~~~~~~{.ebnf .gram}
log_expr : "log" '(' level ',' expr ')' ;
~~~~~~~~

Evaluating a `log` expression may, depending on runtime configuration, cause a
value to be appended to an internal diagnostic logging buffer provided by the
runtime or emitted to a system console. Log expressions are enabled or
disabled dynamically at run-time on a per-task and per-item basis. See
[logging system](#logging-system).

Each `log` expression must be provided with a *level* argument in
addition to the value to log. The logging level is a `u32` value, where
lower levels indicate more-urgent levels of logging. By default, the lowest
four logging levels (`1_u32 ... 4_u32`) are predefined as the constants
`error`, `warn`, `info` and `debug` in the `core` library.

Additionally, the macros `error!`, `warn!`, `info!` and `debug!` are defined
in the default syntax-extension namespace. These expand into calls to the
logging facility composed with calls to the `fmt!` string formatting
syntax-extension.

The following examples all produce the same output, logged at the `error`
logging level:

~~~~
# let filename = "bulbasaur";
// Full version, logging a value.
log(core::error, ~"file not found: " + filename);
// Log-level abbreviated, since core::* is used by default.
log(error, ~"file not found: " + filename);
// Formatting the message using a format-string and fmt!
log(error, fmt!("file not found: %s", filename));
// Using the error! macro, that expands to the previous call.
error!("file not found: %s", filename);
~~~~

A `log` expression is *not evaluated* when logging at the specified logging-level, module or task is disabled at runtime.
This makes inactive `log` expressions very cheap;
they should be used extensively in Rust code, as diagnostic aids,
as they add little overhead beyond a single integer-compare and branch at runtime.

Logging is presently implemented as a language built-in feature,
as it makes use of compiler-provided, per-module data tables and flags.
In the future, logging will move into a library, and will no longer be a core expression type.
It is therefore recommended to use the macro forms of logging (`error!`, `debug!`, etc.) to minimize disruption in code that uses logging.


# Type system

Expand Down Expand Up @@ -3149,7 +3096,7 @@ communication facilities.

The runtime contains a system for directing [logging
expressions](#log-expressions) to a logging console and/or internal logging
buffers. Logging expressions can be enabled per module.
buffers. Logging can be enabled per module.

Logging output is enabled by setting the `RUST_LOG` environment
variable. `RUST_LOG` accepts a logging specification made up of a
Expand Down
4 changes: 2 additions & 2 deletions doc/tutorial.md
Original file line number Diff line number Diff line change
Expand Up @@ -744,7 +744,7 @@ unit, `()`, as the empty tuple if you like).
~~~~
let mytup: (int, int, float) = (10, 20, 30.0);
match mytup {
(a, b, c) => log(info, a + b + (c as int))
(a, b, c) => info!(a + b + (c as int))
}
~~~~
Expand All @@ -760,7 +760,7 @@ For example:
struct MyTup(int, int, float);
let mytup: MyTup = MyTup(10, 20, 30.0);
match mytup {
MyTup(a, b, c) => log(info, a + b + (c as int))
MyTup(a, b, c) => info!(a + b + (c as int))
}
~~~~
Expand Down
2 changes: 1 addition & 1 deletion src/compiletest/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,6 @@ pub fn path_div() -> ~str { ~":" }
pub fn path_div() -> ~str { ~";" }
pub fn logv(config: config, s: ~str) {
log(debug, s);
debug!("%s", s);
if config.verbose { io::println(s); }
}
9 changes: 8 additions & 1 deletion src/libcore/core.rc
Original file line number Diff line number Diff line change
Expand Up @@ -216,14 +216,17 @@ pub use clone::Clone;
* more-verbosity. Error is the bottom level, default logging level is
* warn-and-below.
*/

/// The error log level
#[cfg(stage0)]
pub const error : u32 = 1_u32;
/// The warning log level
#[cfg(stage0)]
pub const warn : u32 = 2_u32;
/// The info log level
#[cfg(stage0)]
pub const info : u32 = 3_u32;
/// The debug log level
#[cfg(stage0)]
pub const debug : u32 = 4_u32;


Expand Down Expand Up @@ -251,9 +254,13 @@ pub mod rt;
// can be resolved within libcore.
#[doc(hidden)] // FIXME #3538
pub mod core {
#[cfg(stage0)]
pub const error : u32 = 1_u32;
#[cfg(stage0)]
pub const warn : u32 = 2_u32;
#[cfg(stage0)]
pub const info : u32 = 3_u32;
#[cfg(stage0)]
pub const debug : u32 = 4_u32;

pub use cmp;
Expand Down
11 changes: 5 additions & 6 deletions src/libcore/io.rs
Original file line number Diff line number Diff line change
Expand Up @@ -683,7 +683,7 @@ impl Writer for *libc::FILE {
*self);
if nout != len as size_t {
error!("error writing buffer");
log(error, os::last_os_error());
error!("%s", os::last_os_error());
fail!();
}
}
Expand Down Expand Up @@ -733,7 +733,7 @@ impl Writer for fd_t {
let nout = libc::write(*self, vb, len as size_t);
if nout < 0 as ssize_t {
error!("error writing buffer");
log(error, os::last_os_error());
error!("%s", os::last_os_error());
fail!();
}
count += nout as uint;
Expand Down Expand Up @@ -1288,7 +1288,6 @@ pub mod fsync {

#[cfg(test)]
mod tests {
use debug;
use i32;
use io::{BytesWriter, SeekCur, SeekEnd, SeekSet};
use io;
Expand All @@ -1301,10 +1300,10 @@ mod tests {
#[test]
fn test_simple() {
let tmpfile = &Path("tmp/lib-io-test-simple.tmp");
log(debug, tmpfile);
debug!(tmpfile);
let frood: ~str =
~"A hoopy frood who really knows where his towel is.";
log(debug, copy frood);
debug!(copy frood);
{
let out: io::Writer =
result::get(
Expand All @@ -1313,7 +1312,7 @@ mod tests {
}
let inp: io::Reader = result::get(&io::file_reader(tmpfile));
let frood2: ~str = inp.read_c_str();
log(debug, copy frood2);
debug!(copy frood2);
fail_unless!(frood == frood2);
}

Expand Down
38 changes: 18 additions & 20 deletions src/libcore/os.rs
Original file line number Diff line number Diff line change
Expand Up @@ -208,8 +208,8 @@ pub fn env() -> ~[(~str,~str)] {
let mut result = ~[];
ptr::array_each(environ, |e| {
let env_pair = str::raw::from_c_str(e);
log(debug, fmt!("get_env_pairs: %s",
env_pair));
debug!("get_env_pairs: %s",
env_pair);
result.push(env_pair);
});
result
Expand All @@ -219,9 +219,8 @@ pub fn env() -> ~[(~str,~str)] {
let mut pairs = ~[];
for input.each |p| {
let vs = str::splitn_char(*p, '=', 1);
log(debug,
fmt!("splitting: len: %u",
vs.len()));
debug!("splitting: len: %u",
vs.len());
fail_unless!(vs.len() == 2);
pairs.push((copy vs[0], copy vs[1]));
}
Expand Down Expand Up @@ -682,10 +681,10 @@ pub fn list_dir(p: &Path) -> ~[~str] {
let input = p.to_str();
let mut strings = ~[];
let input_ptr = ::cast::transmute(&input[0]);
log(debug, "os::list_dir -- BEFORE OPENDIR");
debug!("os::list_dir -- BEFORE OPENDIR");
let dir_ptr = opendir(input_ptr);
if (dir_ptr as uint != 0) {
log(debug, "os::list_dir -- opendir() SUCCESS");
debug!("os::list_dir -- opendir() SUCCESS");
let mut entry_ptr = readdir(dir_ptr);
while (entry_ptr as uint != 0) {
strings.push(
Expand All @@ -697,11 +696,11 @@ pub fn list_dir(p: &Path) -> ~[~str] {
closedir(dir_ptr);
}
else {
log(debug, "os::list_dir -- opendir() FAILURE");
debug!("os::list_dir -- opendir() FAILURE");
}
log(debug,
fmt!("os::list_dir -- AFTER -- #: %?",
strings.len()));
debug!(
"os::list_dir -- AFTER -- #: %?",
strings.len());
strings
}
#[cfg(windows)]
Expand Down Expand Up @@ -1258,7 +1257,6 @@ pub mod consts {
#[cfg(test)]
#[allow(non_implicitly_copyable_typarams)]
mod tests {
use debug;
use libc::{c_int, c_void, size_t};
use libc;
use option::{None, Option, Some};
Expand All @@ -1274,7 +1272,7 @@ mod tests {

#[test]
pub fn last_os_error() {
log(debug, os::last_os_error());
debug!(os::last_os_error());
}

#[test]
Expand Down Expand Up @@ -1320,7 +1318,7 @@ mod tests {
while i < 100 { s += ~"aaaaaaaaaa"; i += 1; }
let n = make_rand_name();
setenv(n, s);
log(debug, copy s);
debug!(copy s);
fail_unless!(getenv(n) == option::Some(s));
}

Expand All @@ -1329,7 +1327,7 @@ mod tests {
let path = os::self_exe_path();
fail_unless!(path.is_some());
let path = path.get();
log(debug, copy path);
debug!(copy path);

// Hard to test this function
fail_unless!(path.is_absolute);
Expand All @@ -1342,7 +1340,7 @@ mod tests {
fail_unless!(vec::len(e) > 0u);
for vec::each(e) |p| {
let (n, v) = copy *p;
log(debug, copy n);
debug!(copy n);
let v2 = getenv(n);
// MingW seems to set some funky environment variables like
// "=C:=C:\MinGW\msys\1.0\bin" and "!::=::\" that are returned
Expand All @@ -1367,10 +1365,10 @@ mod tests {
fn test() {
fail_unless!((!Path("test-path").is_absolute));

log(debug, ~"Current working directory: " + getcwd().to_str());
debug!(~"Current working directory: " + getcwd().to_str());

log(debug, make_absolute(&Path("test-path")));
log(debug, make_absolute(&Path("/usr/bin")));
debug!(make_absolute(&Path("test-path")));
debug!(make_absolute(&Path("/usr/bin")));
}

#[test]
Expand Down Expand Up @@ -1433,7 +1431,7 @@ mod tests {
fail_unless!((vec::len(dirs) > 0u));

for vec::each(dirs) |dir| {
log(debug, copy *dir);
debug!(copy *dir);
}
}

Expand Down
15 changes: 0 additions & 15 deletions src/libcore/prelude.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,18 +82,3 @@ pub use u64;
pub use u8;
pub use uint;
pub use vec;

/*
* Export the log levels as global constants. Higher levels mean
* more-verbosity. Error is the bottom level, default logging level is
* warn-and-below.
*/

/// The error log level
pub const error : u32 = 1_u32;
/// The warning log level
pub const warn : u32 = 2_u32;
/// The info log level
pub const info : u32 = 3_u32;
/// The debug log level
pub const debug : u32 = 4_u32;
Loading

0 comments on commit 695e9fd

Please sign in to comment.