123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181 |
- /// Print to stdout
- #[macro_export]
- macro_rules! print {
- ($($arg:tt)*) => ({
- use core::fmt::Write;
- let _ = write!($crate::platform::FileWriter(1), $($arg)*);
- });
- }
- /// Print with new line to stdout
- #[macro_export]
- macro_rules! println {
- () => (print!("\n"));
- ($fmt:expr) => (print!(concat!($fmt, "\n")));
- ($fmt:expr, $($arg:tt)*) => (print!(concat!($fmt, "\n"), $($arg)*));
- }
- /// Print to stderr
- #[macro_export]
- macro_rules! eprint {
- ($($arg:tt)*) => ({
- use core::fmt::Write;
- let _ = write!($crate::platform::FileWriter(2), $($arg)*);
- });
- }
- /// Print with new line to stderr
- #[macro_export]
- macro_rules! eprintln {
- () => (eprint!("\n"));
- ($fmt:expr) => (eprint!(concat!($fmt, "\n")));
- ($fmt:expr, $($arg:tt)*) => (eprint!(concat!($fmt, "\n"), $($arg)*));
- }
- #[macro_export]
- #[cfg(not(feature = "trace"))]
- macro_rules! trace {
- ($($arg:tt)*) => ();
- }
- #[macro_export]
- #[cfg(feature = "trace")]
- macro_rules! trace {
- ($($arg:tt)*) => (eprintln!($($arg)*));
- }
- #[macro_export]
- #[cfg(not(feature = "trace"))]
- macro_rules! trace_expr {
- ($expr:expr, $($arg:tt)*) => ($expr);
- }
- #[cfg(feature = "trace")]
- pub fn trace_error() -> (isize, &'static str) {
- use header::errno::STR_ERROR;
- let errno = unsafe { ::platform::errno } as isize;
- if errno >= 0 && errno < STR_ERROR.len() as isize {
- (errno, STR_ERROR[errno as usize])
- } else {
- (errno, "Unknown error")
- }
- }
- #[macro_export]
- #[cfg(feature = "trace")]
- macro_rules! trace_expr {
- ($expr:expr, $($arg:tt)*) => ({
- trace!("{}", format_args!($($arg)*));
- unsafe {
- ::platform::errno = 0;
- }
- let ret = $expr;
- trace!("{} = {} {:?}", format_args!($($arg)*), ret, $crate::macros::trace_error());
- ret
- });
- }
- #[macro_export]
- macro_rules! strto_impl {
- (
- $rettype:ty, $signed:expr, $maxval:expr, $minval:expr, $s:ident, $endptr:ident, $base:ident
- ) => {{
- // ensure these are constants
- const CHECK_SIGN: bool = $signed;
- const MAX_VAL: $rettype = $maxval;
- const MIN_VAL: $rettype = $minval;
- let set_endptr = |idx: isize| {
- if !$endptr.is_null() {
- // This is stupid, but apparently strto* functions want
- // const input but mut output, yet the man page says
- // "stores the address of the first invalid character in *endptr"
- // so obviously it doesn't want us to clone it.
- *$endptr = $s.offset(idx) as *mut _;
- }
- };
- let invalid_input = || {
- platform::errno = EINVAL;
- set_endptr(0);
- };
- // only valid bases are 2 through 36
- if $base != 0 && ($base < 2 || $base > 36) {
- invalid_input();
- return 0;
- }
- let mut idx = 0;
- // skip any whitespace at the beginning of the string
- while ctype::isspace(*$s.offset(idx) as c_int) != 0 {
- idx += 1;
- }
- // check for +/-
- let positive = match is_positive(*$s.offset(idx)) {
- Some((pos, i)) => {
- idx += i;
- pos
- }
- None => {
- invalid_input();
- return 0;
- }
- };
- // convert the string to a number
- let num_str = $s.offset(idx);
- let res = match $base {
- 0 => detect_base(num_str)
- .and_then(|($base, i)| convert_integer(num_str.offset(i), $base)),
- 8 => convert_octal(num_str),
- 16 => convert_hex(num_str),
- _ => convert_integer(num_str, $base),
- };
- // check for error parsing octal/hex prefix
- // also check to ensure a number was indeed parsed
- let (num, i, overflow) = match res {
- Some(res) => res,
- None => {
- invalid_input();
- return 0;
- }
- };
- idx += i;
- let overflow = if CHECK_SIGN {
- overflow || (num as c_long).is_negative()
- } else {
- overflow
- };
- // account for the sign
- let num = num as $rettype;
- let num = if overflow {
- platform::errno = ERANGE;
- if CHECK_SIGN {
- if positive {
- MAX_VAL
- } else {
- MIN_VAL
- }
- } else {
- MAX_VAL
- }
- } else {
- if positive {
- num
- } else {
- // not using -num to keep the compiler happy
- num.overflowing_neg().0
- }
- };
- set_endptr(idx);
- num
- }};
- }
|