<commit_before>// This file is part of the uutils coreutils package.
//
// (c) Alex Lyon <arcterus@mail.com>
//
// For the full copyright and license information, please view the LICENSE
// file that was distributed with this source code.

// spell-checker:ignore (ToDO) Chmoder cmode fmode fperm fref ugoa RFILE RFILE's

#[macro_use]
extern crate uucore;

use clap::{App, Arg};
use std::fs;
use std::os::unix::fs::{MetadataExt, PermissionsExt};
use std::path::Path;
use uucore::fs::display_permissions_unix;
use uucore::libc::mode_t;
#[cfg(not(windows))]
use uucore::mode;
use uucore::InvalidEncodingHandling;
use walkdir::WalkDir;

static VERSION: &str = env!("CARGO_PKG_VERSION");
static ABOUT: &str = "Change the mode of each FILE to MODE.
 With --reference, change the mode of each FILE to that of RFILE.";

mod options {
    pub const CHANGES: &str = "changes";
    pub const QUIET: &str = "quiet"; // visible_alias("silent")
    pub const VERBOSE: &str = "verbose";
    pub const NO_PRESERVE_ROOT: &str = "no-preserve-root";
    pub const PRESERVE_ROOT: &str = "preserve-root";
    pub const REFERENCE: &str = "RFILE";
    pub const RECURSIVE: &str = "recursive";
    pub const MODE: &str = "MODE";
    pub const FILE: &str = "FILE";
}

fn get_usage() -> String {
    format!(
        "{0} [OPTION]... MODE[,MODE]... FILE...
or: {0} [OPTION]... OCTAL-MODE FILE...
or: {0} [OPTION]... --reference=RFILE FILE...",
        executable!()
    )
}

fn get_long_usage() -> String {
    String::from("Each MODE is of the form '[ugoa]*([-+=]([rwxXst]*|[ugo]))+|[-+=]?[0-7]+'.")
}

pub fn uumain(args: impl uucore::Args) -> i32 {
    let mut args = args
        .collect_str(InvalidEncodingHandling::ConvertLossy)
        .accept_any();

    // Before we can parse 'args' with clap (and previously getopts),
    // a possible MODE prefix '-' needs to be removed (e.g. "chmod -x FILE").
    let mode_had_minus_prefix = strip_minus_from_mode(&mut args);

    let usage = get_usage();
    let after_help = get_long_usage();

    let matches = App::new(executable!())
        .version(VERSION)
        .about(ABOUT)
        .usage(&usage[..])
        .after_help(&after_help[..])
        .arg(
            Arg::with_name(options::CHANGES)
                .long(options::CHANGES)
                .short("c")
                .help("like verbose but report only when a change is made"),
        )
        .arg(
            Arg::with_name(options::QUIET)
                .long(options::QUIET)
                .visible_alias("silent")
                .short("f")
                .help("suppress most error messages"),
        )
        .arg(
            Arg::with_name(options::VERBOSE)
                .long(options::VERBOSE)
                .short("v")
                .help("output a diagnostic for every file processed"),
        )
        .arg(
            Arg::with_name(options::NO_PRESERVE_ROOT)
                .long(options::NO_PRESERVE_ROOT)
                .help("do not treat '/' specially (the default)"),
        )
        .arg(
            Arg::with_name(options::PRESERVE_ROOT)
                .long(options::PRESERVE_ROOT)
                .help("fail to operate recursively on '/'"),
        )
        .arg(
            Arg::with_name(options::RECURSIVE)
                .long(options::RECURSIVE)
                .short("R")
                .help("change files and directories recursively"),
        )
        .arg(
            Arg::with_name(options::REFERENCE)
                .long("reference")
                .takes_value(true)
                .help("use RFILE's mode instead of MODE values"),
        )
        .arg(
            Arg::with_name(options::MODE)
                .required_unless(options::REFERENCE)
                .takes_value(true),
            // It would be nice if clap could parse with delimeter, e.g. "g-x,u+x",
            // however .multiple(true) cannot be used here because FILE already needs that.
            // Only one positional argument with .multiple(true) set is allowed per command
        )
        .arg(
            Arg::with_name(options::FILE)
                .required_unless(options::MODE)
                .multiple(true),
        )
        .get_matches_from(args);

    let changes = matches.is_present(options::CHANGES);
    let quiet = matches.is_present(options::QUIET);
    let verbose = matches.is_present(options::VERBOSE);
    let preserve_root = matches.is_present(options::PRESERVE_ROOT);
    let recursive = matches.is_present(options::RECURSIVE);
    let fmode =
        matches
            .value_of(options::REFERENCE)
            .and_then(|ref fref| match fs::metadata(fref) {
                Ok(meta) => Some(meta.mode()),
                Err(err) => crash!(1, "cannot stat attributes of '{}': {}", fref, err),
            });
    let modes = matches.value_of(options::MODE).unwrap(); // should always be Some because required
    let mut cmode = if mode_had_minus_prefix {
        // clap parsing is finished, now put prefix back
        Some(format!("-{}", modes))
    } else {
        Some(modes.to_string())
    };
    let mut files: Vec<String> = matches
        .values_of(options::FILE)
        .map(|v| v.map(ToString::to_string).collect())
        .unwrap_or_default();
    if fmode.is_some() {
        // "--reference" and MODE are mutually exclusive
        // if "--reference" was used MODE needs to be interpreted as another FILE
        // it wasn't possible to implement this behavior directly with clap
        files.push(cmode.unwrap());
        cmode = None;
    }

    let chmoder = Chmoder {
        changes,
        quiet,
        verbose,
        preserve_root,
        recursive,
        fmode,
        cmode,
    };
    match chmoder.chmod(files) {
        Ok(()) => {}
        Err(e) => return e,
    }

    0
}

// Iterate 'args' and delete the first occurrence
// of a prefix '-' if it's associated with MODE
// e.g. "chmod -v -xw -R FILE" -> "chmod -v xw -R FILE"
pub fn strip_minus_from_mode(args: &mut Vec<String>) -> bool {
    for arg in args {
        if arg.starts_with('-') {
            if let Some(second) = arg.chars().nth(1) {
                match second {
                    'r' | 'w' | 'x' | 'X' | 's' | 't' | 'u' | 'g' | 'o' | '0'..='7' => {
                        // TODO: use strip_prefix() once minimum rust version reaches 1.45.0
                        *arg = arg[1..arg.len()].to_string();
                        return true;
                    }
                    _ => {}
                }
            }
        }
    }
    false
}

struct Chmoder {
    changes: bool,
    quiet: bool,
    verbose: bool,
    preserve_root: bool,
    recursive: bool,
    fmode: Option<u32>,
    cmode: Option<String>,
}

impl Chmoder {
    fn chmod(&self, files: Vec<String>) -> Result<(), i32> {
        let mut r = Ok(());

        for filename in &files {
            let filename = &filename[..];
            let file = Path::new(filename);
            if !file.exists() {
                if is_symlink(file) {
                    println!(
                        "failed to change mode of '{}' from 0000 (---------) to 0000 (---------)",
                        filename
                    );
                    if !self.quiet {
                        show_error!("cannot operate on dangling symlink '{}'", filename);
                    }
                } else {
                    show_error!("cannot access '{}': No such file or directory", filename);
                }
                return Err(1);
            }
            if self.recursive && self.preserve_root && filename == "/" {
                show_error!(
                    "it is dangerous to operate recursively on '{}'\nuse --no-preserve-root to override this failsafe",
                    filename
                );
                return Err(1);
            }
            if !self.recursive {
                r = self.chmod_file(&file).and(r);
            } else {
                for entry in WalkDir::new(&filename).into_iter().filter_map(|e| e.ok()) {
                    let file = entry.path();
                    r = self.chmod_file(&file).and(r);
                }
            }
        }
        r
    }

    #[cfg(windows)]
    fn chmod_file(&self, file: &Path) -> Result<(), i32> {
        // chmod is useless on Windows
        // it doesn't set any permissions at all
        // instead it just sets the readonly attribute on the file
        Err(0)
    }
    #[cfg(any(unix, target_os = "redox"))]
    fn chmod_file(&self, file: &Path) -> Result<(), i32> {
        let mut fperm = match fs::metadata(file) {
            Ok(meta) => meta.mode() & 0o7777,
            Err(err) => {
                if is_symlink(file) {
                    if self.verbose {
                        println!(
                            "neither symbolic link '{}' nor referent has been changed",
                            file.display()
                        );
                    }
                    return Ok(());
                } else if err.kind() == std::io::ErrorKind::PermissionDenied {
                    show_error!("'{}': Permission denied", file.display());
                } else {
                    show_error!("'{}': {}", file.display(), err);
                }
                return Err(1);
            }
        };
        match self.fmode {
            Some(mode) => self.change_file(fperm, mode, file)?,
            None => {
                let cmode_unwrapped = self.cmode.clone().unwrap();
                for mode in cmode_unwrapped.split(',') {
                    // cmode is guaranteed to be Some in this case
                    let arr: &[char] = &['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'];
                    let result = if mode.contains(arr) {
                        mode::parse_numeric(fperm, mode)
                    } else {
                        mode::parse_symbolic(fperm, mode, file.is_dir())
                    };
                    match result {
                        Ok(mode) => {
                            self.change_file(fperm, mode, file)?;
                            fperm = mode;
                        }
                        Err(f) => {
                            if !self.quiet {
                                show_error!("{}", f);
                            }
                            return Err(1);
                        }
                    }
                }
            }
        }

        Ok(())
    }

    #[cfg(unix)]
    fn change_file(&self, fperm: u32, mode: u32, file: &Path) -> Result<(), i32> {
        if fperm == mode {
            if self.verbose && !self.changes {
                println!(
                    "mode of '{}' retained as {:04o} ({})",
                    file.display(),
                    fperm,
                    display_permissions_unix(fperm as mode_t, false),
                );
            }
            Ok(())
        } else if let Err(err) = fs::set_permissions(file, fs::Permissions::from_mode(mode)) {
            if !self.quiet {
                show_error!("{}", err);
            }
            if self.verbose {
                show_error!(
                    "failed to change mode of file '{}' from {:o} ({}) to {:o} ({})",
                    file.display(),
                    fperm,
                    display_permissions_unix(fperm as mode_t, false),
                    mode,
                    display_permissions_unix(mode as mode_t, false)
                );
            }
            Err(1)
        } else {
            if self.verbose || self.changes {
                show_error!(
                    "mode of '{}' changed from {:o} ({}) to {:o} ({})",
                    file.display(),
                    fperm,
                    display_permissions_unix(fperm as mode_t, false),
                    mode,
                    display_permissions_unix(mode as mode_t, false)
                );
            }
            Ok(())
        }
    }
}

pub fn is_symlink<P: AsRef<Path>>(path: P) -> bool {
    match fs::symlink_metadata(path) {
        Ok(m) => m.file_type().is_symlink(),
        Err(_) => false,
    }
}
<commit_msg>refactor/chmod ~ polish spelling (comments, names, and exceptions)<commit_after>// This file is part of the uutils coreutils package.
//
// (c) Alex Lyon <arcterus@mail.com>
//
// For the full copyright and license information, please view the LICENSE
// file that was distributed with this source code.

// spell-checker:ignore (ToDO) Chmoder cmode fmode fperm fref ugoa RFILE RFILE's

#[macro_use]
extern crate uucore;

use clap::{App, Arg};
use std::fs;
use std::os::unix::fs::{MetadataExt, PermissionsExt};
use std::path::Path;
use uucore::fs::display_permissions_unix;
use uucore::libc::mode_t;
#[cfg(not(windows))]
use uucore::mode;
use uucore::InvalidEncodingHandling;
use walkdir::WalkDir;

static VERSION: &str = env!("CARGO_PKG_VERSION");
static ABOUT: &str = "Change the mode of each FILE to MODE.
 With --reference, change the mode of each FILE to that of RFILE.";

mod options {
    pub const CHANGES: &str = "changes";
    pub const QUIET: &str = "quiet"; // visible_alias("silent")
    pub const VERBOSE: &str = "verbose";
    pub const NO_PRESERVE_ROOT: &str = "no-preserve-root";
    pub const PRESERVE_ROOT: &str = "preserve-root";
    pub const REFERENCE: &str = "RFILE";
    pub const RECURSIVE: &str = "recursive";
    pub const MODE: &str = "MODE";
    pub const FILE: &str = "FILE";
}

fn get_usage() -> String {
    format!(
        "{0} [OPTION]... MODE[,MODE]... FILE...
or: {0} [OPTION]... OCTAL-MODE FILE...
or: {0} [OPTION]... --reference=RFILE FILE...",
        executable!()
    )
}

fn get_long_usage() -> String {
    String::from("Each MODE is of the form '[ugoa]*([-+=]([rwxXst]*|[ugo]))+|[-+=]?[0-7]+'.")
}

pub fn uumain(args: impl uucore::Args) -> i32 {
    let mut args = args
        .collect_str(InvalidEncodingHandling::ConvertLossy)
        .accept_any();

    // Before we can parse 'args' with clap (and previously getopts),
    // a possible MODE prefix '-' needs to be removed (e.g. "chmod -x FILE").
    let mode_had_minus_prefix = strip_minus_from_mode(&mut args);

    let usage = get_usage();
    let after_help = get_long_usage();

    let matches = App::new(executable!())
        .version(VERSION)
        .about(ABOUT)
        .usage(&usage[..])
        .after_help(&after_help[..])
        .arg(
            Arg::with_name(options::CHANGES)
                .long(options::CHANGES)
                .short("c")
                .help("like verbose but report only when a change is made"),
        )
        .arg(
            Arg::with_name(options::QUIET)
                .long(options::QUIET)
                .visible_alias("silent")
                .short("f")
                .help("suppress most error messages"),
        )
        .arg(
            Arg::with_name(options::VERBOSE)
                .long(options::VERBOSE)
                .short("v")
                .help("output a diagnostic for every file processed"),
        )
        .arg(
            Arg::with_name(options::NO_PRESERVE_ROOT)
                .long(options::NO_PRESERVE_ROOT)
                .help("do not treat '/' specially (the default)"),
        )
        .arg(
            Arg::with_name(options::PRESERVE_ROOT)
                .long(options::PRESERVE_ROOT)
                .help("fail to operate recursively on '/'"),
        )
        .arg(
            Arg::with_name(options::RECURSIVE)
                .long(options::RECURSIVE)
                .short("R")
                .help("change files and directories recursively"),
        )
        .arg(
            Arg::with_name(options::REFERENCE)
                .long("reference")
                .takes_value(true)
                .help("use RFILE's mode instead of MODE values"),
        )
        .arg(
            Arg::with_name(options::MODE)
                .required_unless(options::REFERENCE)
                .takes_value(true),
            // It would be nice if clap could parse with delimiter, e.g. "g-x,u+x",
            // however .multiple(true) cannot be used here because FILE already needs that.
            // Only one positional argument with .multiple(true) set is allowed per command
        )
        .arg(
            Arg::with_name(options::FILE)
                .required_unless(options::MODE)
                .multiple(true),
        )
        .get_matches_from(args);

    let changes = matches.is_present(options::CHANGES);
    let quiet = matches.is_present(options::QUIET);
    let verbose = matches.is_present(options::VERBOSE);
    let preserve_root = matches.is_present(options::PRESERVE_ROOT);
    let recursive = matches.is_present(options::RECURSIVE);
    let fmode =
        matches
            .value_of(options::REFERENCE)
            .and_then(|ref fref| match fs::metadata(fref) {
                Ok(meta) => Some(meta.mode()),
                Err(err) => crash!(1, "cannot stat attributes of '{}': {}", fref, err),
            });
    let modes = matches.value_of(options::MODE).unwrap(); // should always be Some because required
    let mut cmode = if mode_had_minus_prefix {
        // clap parsing is finished, now put prefix back
        Some(format!("-{}", modes))
    } else {
        Some(modes.to_string())
    };
    let mut files: Vec<String> = matches
        .values_of(options::FILE)
        .map(|v| v.map(ToString::to_string).collect())
        .unwrap_or_default();
    if fmode.is_some() {
        // "--reference" and MODE are mutually exclusive
        // if "--reference" was used MODE needs to be interpreted as another FILE
        // it wasn't possible to implement this behavior directly with clap
        files.push(cmode.unwrap());
        cmode = None;
    }

    let chmoder = Chmoder {
        changes,
        quiet,
        verbose,
        preserve_root,
        recursive,
        fmode,
        cmode,
    };
    match chmoder.chmod(files) {
        Ok(()) => {}
        Err(e) => return e,
    }

    0
}

// Iterate 'args' and delete the first occurrence
// of a prefix '-' if it's associated with MODE
// e.g. "chmod -v -xw -R FILE" -> "chmod -v xw -R FILE"
pub fn strip_minus_from_mode(args: &mut Vec<String>) -> bool {
    for arg in args {
        if arg.starts_with('-') {
            if let Some(second) = arg.chars().nth(1) {
                match second {
                    'r' | 'w' | 'x' | 'X' | 's' | 't' | 'u' | 'g' | 'o' | '0'..='7' => {
                        // TODO: use strip_prefix() once minimum rust version reaches 1.45.0
                        *arg = arg[1..arg.len()].to_string();
                        return true;
                    }
                    _ => {}
                }
            }
        }
    }
    false
}

struct Chmoder {
    changes: bool,
    quiet: bool,
    verbose: bool,
    preserve_root: bool,
    recursive: bool,
    fmode: Option<u32>,
    cmode: Option<String>,
}

impl Chmoder {
    fn chmod(&self, files: Vec<String>) -> Result<(), i32> {
        let mut r = Ok(());

        for filename in &files {
            let filename = &filename[..];
            let file = Path::new(filename);
            if !file.exists() {
                if is_symlink(file) {
                    println!(
                        "failed to change mode of '{}' from 0000 (---------) to 0000 (---------)",
                        filename
                    );
                    if !self.quiet {
                        show_error!("cannot operate on dangling symlink '{}'", filename);
                    }
                } else {
                    show_error!("cannot access '{}': No such file or directory", filename);
                }
                return Err(1);
            }
            if self.recursive && self.preserve_root && filename == "/" {
                show_error!(
                    "it is dangerous to operate recursively on '{}'\nuse --no-preserve-root to override this failsafe",
                    filename
                );
                return Err(1);
            }
            if !self.recursive {
                r = self.chmod_file(&file).and(r);
            } else {
                for entry in WalkDir::new(&filename).into_iter().filter_map(|e| e.ok()) {
                    let file = entry.path();
                    r = self.chmod_file(&file).and(r);
                }
            }
        }
        r
    }

    #[cfg(windows)]
    fn chmod_file(&self, file: &Path) -> Result<(), i32> {
        // chmod is useless on Windows
        // it doesn't set any permissions at all
        // instead it just sets the readonly attribute on the file
        Err(0)
    }
    #[cfg(any(unix, target_os = "redox"))]
    fn chmod_file(&self, file: &Path) -> Result<(), i32> {
        let mut fperm = match fs::metadata(file) {
            Ok(meta) => meta.mode() & 0o7777,
            Err(err) => {
                if is_symlink(file) {
                    if self.verbose {
                        println!(
                            "neither symbolic link '{}' nor referent has been changed",
                            file.display()
                        );
                    }
                    return Ok(());
                } else if err.kind() == std::io::ErrorKind::PermissionDenied {
                    show_error!("'{}': Permission denied", file.display());
                } else {
                    show_error!("'{}': {}", file.display(), err);
                }
                return Err(1);
            }
        };
        match self.fmode {
            Some(mode) => self.change_file(fperm, mode, file)?,
            None => {
                let cmode_unwrapped = self.cmode.clone().unwrap();
                for mode in cmode_unwrapped.split(',') {
                    // cmode is guaranteed to be Some in this case
                    let arr: &[char] = &['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'];
                    let result = if mode.contains(arr) {
                        mode::parse_numeric(fperm, mode)
                    } else {
                        mode::parse_symbolic(fperm, mode, file.is_dir())
                    };
                    match result {
                        Ok(mode) => {
                            self.change_file(fperm, mode, file)?;
                            fperm = mode;
                        }
                        Err(f) => {
                            if !self.quiet {
                                show_error!("{}", f);
                            }
                            return Err(1);
                        }
                    }
                }
            }
        }

        Ok(())
    }

    #[cfg(unix)]
    fn change_file(&self, fperm: u32, mode: u32, file: &Path) -> Result<(), i32> {
        if fperm == mode {
            if self.verbose && !self.changes {
                println!(
                    "mode of '{}' retained as {:04o} ({})",
                    file.display(),
                    fperm,
                    display_permissions_unix(fperm as mode_t, false),
                );
            }
            Ok(())
        } else if let Err(err) = fs::set_permissions(file, fs::Permissions::from_mode(mode)) {
            if !self.quiet {
                show_error!("{}", err);
            }
            if self.verbose {
                show_error!(
                    "failed to change mode of file '{}' from {:o} ({}) to {:o} ({})",
                    file.display(),
                    fperm,
                    display_permissions_unix(fperm as mode_t, false),
                    mode,
                    display_permissions_unix(mode as mode_t, false)
                );
            }
            Err(1)
        } else {
            if self.verbose || self.changes {
                show_error!(
                    "mode of '{}' changed from {:o} ({}) to {:o} ({})",
                    file.display(),
                    fperm,
                    display_permissions_unix(fperm as mode_t, false),
                    mode,
                    display_permissions_unix(mode as mode_t, false)
                );
            }
            Ok(())
        }
    }
}

pub fn is_symlink<P: AsRef<Path>>(path: P) -> bool {
    match fs::symlink_metadata(path) {
        Ok(m) => m.file_type().is_symlink(),
        Err(_) => false,
    }
}
<|endoftext|>


<commit_before>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

//! Memory profiling functions.

use libc::{c_char,c_int,c_void,size_t};
use std::borrow::ToOwned;
use std::ffi::CString;
use std::old_io::timer::sleep;
#[cfg(target_os="linux")]
use std::old_io::File;
use std::mem;
use std::mem::size_of;
#[cfg(target_os="linux")]
use std::env::page_size;
use std::ptr::null_mut;
use std::sync::mpsc::{Sender, channel, Receiver};
use std::time::duration::Duration;
use task::spawn_named;
#[cfg(target_os="macos")]
use task_info::task_basic_info::{virtual_size,resident_size};

pub struct MemoryProfilerChan(pub Sender<MemoryProfilerMsg>);

impl MemoryProfilerChan {
    pub fn send(&self, msg: MemoryProfilerMsg) {
        let MemoryProfilerChan(ref c) = *self;
        c.send(msg).unwrap();
    }
}

pub enum MemoryProfilerMsg {
    /// Message used to force print the memory profiling metrics.
    Print,
    /// Tells the memory profiler to shut down.
    Exit,
}

pub struct MemoryProfiler {
    pub port: Receiver<MemoryProfilerMsg>,
}

impl MemoryProfiler {
    pub fn create(period: Option<f64>) -> MemoryProfilerChan {
        let (chan, port) = channel();
        match period {
            Some(period) => {
                let period = Duration::milliseconds((period * 1000f64) as i64);
                let chan = chan.clone();
                spawn_named("Memory profiler timer".to_owned(), move || {
                    loop {
                        sleep(period);
                        if chan.send(MemoryProfilerMsg::Print).is_err() {
                            break;
                        }
                    }
                });
                // Spawn the memory profiler.
                spawn_named("Memory profiler".to_owned(), move || {
                    let memory_profiler = MemoryProfiler::new(port);
                    memory_profiler.start();
                });
            }
            None => {
                // No-op to handle messages when the memory profiler is
                // inactive.
                spawn_named("Memory profiler".to_owned(), move || {
                    loop {
                        match port.recv() {
                            Err(_) | Ok(MemoryProfilerMsg::Exit) => break,
                            _ => {}
                        }
                    }
                });
            }
        }

        MemoryProfilerChan(chan)
    }

    pub fn new(port: Receiver<MemoryProfilerMsg>) -> MemoryProfiler {
        MemoryProfiler {
            port: port
        }
    }

    pub fn start(&self) {
        loop {
            match self.port.recv() {
               Ok(msg) => {
                   if !self.handle_msg(msg) {
                       break
                   }
               }
               _ => break
            }
        }
    }

    fn handle_msg(&self, msg: MemoryProfilerMsg) -> bool {
        match msg {
            MemoryProfilerMsg::Print => {
                self.handle_print_msg();
                true
            },
            MemoryProfilerMsg::Exit => false
        }
    }

    fn print_measurement(path: &str, nbytes: Option<u64>) {
        match nbytes {
            Some(nbytes) => {
                let mebi = 1024f64 * 1024f64;
                println!("{:24}: {:12.2}", path, (nbytes as f64) / mebi);
            }
            None => {
                println!("{:24}: {:>12}", path, "???");
            }
        }
    }

    fn handle_print_msg(&self) {
        println!("{:24}: {:12}", "_category_", "_size (MiB)_");

        // Virtual and physical memory usage, as reported by the OS.
        MemoryProfiler::print_measurement("vsize", get_vsize());
        MemoryProfiler::print_measurement("resident", get_resident());

        // Total number of bytes allocated by the application on the system
        // heap.
        MemoryProfiler::print_measurement("system-heap-allocated",
                                          get_system_heap_allocated());

        // The descriptions of the following jemalloc measurements are taken
        // directly from the jemalloc documentation.

        // "Total number of bytes allocated by the application."
        MemoryProfiler::print_measurement("jemalloc-heap-allocated",
                                          get_jemalloc_stat("stats.allocated"));

        // "Total number of bytes in active pages allocated by the application.
        // This is a multiple of the page size, and greater than or equal to
        // |stats.allocated|."
        MemoryProfiler::print_measurement("jemalloc-heap-active",
                                          get_jemalloc_stat("stats.active"));

        // "Total number of bytes in chunks mapped on behalf of the application.
        // This is a multiple of the chunk size, and is at least as large as
        // |stats.active|. This does not include inactive chunks."
        MemoryProfiler::print_measurement("jemalloc-heap-mapped",
                                          get_jemalloc_stat("stats.mapped"));

        println!("");
    }
}

#[cfg(target_os="linux")]
extern {
    fn mallinfo() -> struct_mallinfo;
}

#[cfg(target_os="linux")]
#[repr(C)]
pub struct struct_mallinfo {
    arena:    c_int,
    ordblks:  c_int,
    smblks:   c_int,
    hblks:    c_int,
    hblkhd:   c_int,
    usmblks:  c_int,
    fsmblks:  c_int,
    uordblks: c_int,
    fordblks: c_int,
    keepcost: c_int,
}

#[cfg(target_os="linux")]
fn get_system_heap_allocated() -> Option<u64> {
    let mut info: struct_mallinfo;
    unsafe {
        info = mallinfo();
    }
    // The documentation in the glibc man page makes it sound like |uordblks|
    // would suffice, but that only gets the small allocations that are put in
    // the brk heap. We need |hblkhd| as well to get the larger allocations
    // that are mmapped.
    Some((info.hblkhd + info.uordblks) as u64)
}

#[cfg(not(target_os="linux"))]
fn get_system_heap_allocated() -> Option<u64> {
    None
}

extern {
    fn je_mallctl(name: *const c_char, oldp: *mut c_void, oldlenp: *mut size_t,
                  newp: *mut c_void, newlen: size_t) -> c_int;
}

fn get_jemalloc_stat(name: &'static str) -> Option<u64> {
    let mut old: size_t = 0;
    let c_name = CString::from_slice(name.as_bytes());
    let oldp = &mut old as *mut _ as *mut c_void;
    let mut oldlen = size_of::<size_t>() as size_t;
    let rv: c_int;
    unsafe {
        rv = je_mallctl(c_name.as_ptr(), oldp, &mut oldlen, null_mut(), 0);
        mem::forget(c_name); // XXX correct?
    }
    if rv == 0 { Some(old as u64) } else { None }
}

// Like std::macros::try!, but for Option<>.
macro_rules! option_try(
    ($e:expr) => (match $e { Some(e) => e, None => return None })
);

#[cfg(target_os="linux")]
fn get_proc_self_statm_field(field: uint) -> Option<u64> {
    let mut f = File::open(&Path::new("/proc/self/statm"));
    match f.read_to_string() {
        Ok(contents) => {
            let s = option_try!(contents.as_slice().words().nth(field));
            let npages: u64 = option_try!(s.parse().ok());
            Some(npages * (page_size() as u64))
        }
        Err(_) => None
    }
}

#[cfg(target_os="linux")]
fn get_vsize() -> Option<u64> {
    get_proc_self_statm_field(0)
}

#[cfg(target_os="linux")]
fn get_resident() -> Option<u64> {
    get_proc_self_statm_field(1)
}

#[cfg(target_os="macos")]
fn get_vsize() -> Option<u64> {
    virtual_size()
}

#[cfg(target_os="macos")]
fn get_resident() -> Option<u64> {
    resident_size()
}

#[cfg(not(any(target_os="linux", target_os = "macos")))]
fn get_vsize() -> Option<u64> {
    None
}

#[cfg(not(any(target_os="linux", target_os = "macos")))]
fn get_resident() -> Option<u64> {
    None
}
<commit_msg>auto merge of #4917 : nnethercote/servo/fix-jemalloc-reporting, r=jdm<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

//! Memory profiling functions.

use libc::{c_char,c_int,c_void,size_t};
use std::borrow::ToOwned;
use std::ffi::CString;
use std::old_io::timer::sleep;
#[cfg(target_os="linux")]
use std::old_io::File;
use std::mem;
use std::mem::size_of;
#[cfg(target_os="linux")]
use std::env::page_size;
use std::ptr::null_mut;
use std::sync::mpsc::{Sender, channel, Receiver};
use std::time::duration::Duration;
use task::spawn_named;
#[cfg(target_os="macos")]
use task_info::task_basic_info::{virtual_size,resident_size};

pub struct MemoryProfilerChan(pub Sender<MemoryProfilerMsg>);

impl MemoryProfilerChan {
    pub fn send(&self, msg: MemoryProfilerMsg) {
        let MemoryProfilerChan(ref c) = *self;
        c.send(msg).unwrap();
    }
}

pub enum MemoryProfilerMsg {
    /// Message used to force print the memory profiling metrics.
    Print,
    /// Tells the memory profiler to shut down.
    Exit,
}

pub struct MemoryProfiler {
    pub port: Receiver<MemoryProfilerMsg>,
}

impl MemoryProfiler {
    pub fn create(period: Option<f64>) -> MemoryProfilerChan {
        let (chan, port) = channel();
        match period {
            Some(period) => {
                let period = Duration::milliseconds((period * 1000f64) as i64);
                let chan = chan.clone();
                spawn_named("Memory profiler timer".to_owned(), move || {
                    loop {
                        sleep(period);
                        if chan.send(MemoryProfilerMsg::Print).is_err() {
                            break;
                        }
                    }
                });
                // Spawn the memory profiler.
                spawn_named("Memory profiler".to_owned(), move || {
                    let memory_profiler = MemoryProfiler::new(port);
                    memory_profiler.start();
                });
            }
            None => {
                // No-op to handle messages when the memory profiler is
                // inactive.
                spawn_named("Memory profiler".to_owned(), move || {
                    loop {
                        match port.recv() {
                            Err(_) | Ok(MemoryProfilerMsg::Exit) => break,
                            _ => {}
                        }
                    }
                });
            }
        }

        MemoryProfilerChan(chan)
    }

    pub fn new(port: Receiver<MemoryProfilerMsg>) -> MemoryProfiler {
        MemoryProfiler {
            port: port
        }
    }

    pub fn start(&self) {
        loop {
            match self.port.recv() {
               Ok(msg) => {
                   if !self.handle_msg(msg) {
                       break
                   }
               }
               _ => break
            }
        }
    }

    fn handle_msg(&self, msg: MemoryProfilerMsg) -> bool {
        match msg {
            MemoryProfilerMsg::Print => {
                self.handle_print_msg();
                true
            },
            MemoryProfilerMsg::Exit => false
        }
    }

    fn print_measurement(path: &str, nbytes: Option<u64>) {
        match nbytes {
            Some(nbytes) => {
                let mebi = 1024f64 * 1024f64;
                println!("{:24}: {:12.2}", path, (nbytes as f64) / mebi);
            }
            None => {
                println!("{:24}: {:>12}", path, "???");
            }
        }
    }

    fn handle_print_msg(&self) {
        println!("{:24}: {:12}", "_category_", "_size (MiB)_");

        // Virtual and physical memory usage, as reported by the OS.
        MemoryProfiler::print_measurement("vsize", get_vsize());
        MemoryProfiler::print_measurement("resident", get_resident());

        // Total number of bytes allocated by the application on the system
        // heap.
        MemoryProfiler::print_measurement("system-heap-allocated",
                                          get_system_heap_allocated());

        // The descriptions of the following jemalloc measurements are taken
        // directly from the jemalloc documentation.

        // "Total number of bytes allocated by the application."
        MemoryProfiler::print_measurement("jemalloc-heap-allocated",
                                          get_jemalloc_stat("stats.allocated"));

        // "Total number of bytes in active pages allocated by the application.
        // This is a multiple of the page size, and greater than or equal to
        // |stats.allocated|."
        MemoryProfiler::print_measurement("jemalloc-heap-active",
                                          get_jemalloc_stat("stats.active"));

        // "Total number of bytes in chunks mapped on behalf of the application.
        // This is a multiple of the chunk size, and is at least as large as
        // |stats.active|. This does not include inactive chunks."
        MemoryProfiler::print_measurement("jemalloc-heap-mapped",
                                          get_jemalloc_stat("stats.mapped"));

        println!("");
    }
}

#[cfg(target_os="linux")]
extern {
    fn mallinfo() -> struct_mallinfo;
}

#[cfg(target_os="linux")]
#[repr(C)]
pub struct struct_mallinfo {
    arena:    c_int,
    ordblks:  c_int,
    smblks:   c_int,
    hblks:    c_int,
    hblkhd:   c_int,
    usmblks:  c_int,
    fsmblks:  c_int,
    uordblks: c_int,
    fordblks: c_int,
    keepcost: c_int,
}

#[cfg(target_os="linux")]
fn get_system_heap_allocated() -> Option<u64> {
    let mut info: struct_mallinfo;
    unsafe {
        info = mallinfo();
    }
    // The documentation in the glibc man page makes it sound like |uordblks|
    // would suffice, but that only gets the small allocations that are put in
    // the brk heap. We need |hblkhd| as well to get the larger allocations
    // that are mmapped.
    Some((info.hblkhd + info.uordblks) as u64)
}

#[cfg(not(target_os="linux"))]
fn get_system_heap_allocated() -> Option<u64> {
    None
}

extern {
    fn je_mallctl(name: *const c_char, oldp: *mut c_void, oldlenp: *mut size_t,
                  newp: *mut c_void, newlen: size_t) -> c_int;
}

fn get_jemalloc_stat(value_name: &str) -> Option<u64> {
    // Before we request the measurement of interest, we first send an "epoch"
    // request. Without that jemalloc gives cached statistics(!) which can be
    // highly inaccurate.
    let epoch_name = "epoch";
    let epoch_c_name = CString::from_slice(epoch_name.as_bytes());
    let mut epoch: u64 = 0;
    let epoch_ptr = &mut epoch as *mut _ as *mut c_void;
    let mut epoch_len = size_of::<u64>() as size_t;

    let value_c_name = CString::from_slice(value_name.as_bytes());
    let mut value: size_t = 0;
    let value_ptr = &mut value as *mut _ as *mut c_void;
    let mut value_len = size_of::<size_t>() as size_t;

    let mut rv: c_int;
    unsafe {
        // Using the same values for the `old` and `new` parameters is enough
        // to get the statistics updated.
        rv = je_mallctl(epoch_c_name.as_ptr(), epoch_ptr, &mut epoch_len, epoch_ptr, epoch_len);
        if rv == 0 {
            rv = je_mallctl(value_c_name.as_ptr(), value_ptr, &mut value_len, null_mut(), 0);
        }
    }
    if rv == 0 { Some(value as u64) } else { None }
}

// Like std::macros::try!, but for Option<>.
macro_rules! option_try(
    ($e:expr) => (match $e { Some(e) => e, None => return None })
);

#[cfg(target_os="linux")]
fn get_proc_self_statm_field(field: uint) -> Option<u64> {
    let mut f = File::open(&Path::new("/proc/self/statm"));
    match f.read_to_string() {
        Ok(contents) => {
            let s = option_try!(contents.as_slice().words().nth(field));
            let npages: u64 = option_try!(s.parse().ok());
            Some(npages * (page_size() as u64))
        }
        Err(_) => None
    }
}

#[cfg(target_os="linux")]
fn get_vsize() -> Option<u64> {
    get_proc_self_statm_field(0)
}

#[cfg(target_os="linux")]
fn get_resident() -> Option<u64> {
    get_proc_self_statm_field(1)
}

#[cfg(target_os="macos")]
fn get_vsize() -> Option<u64> {
    virtual_size()
}

#[cfg(target_os="macos")]
fn get_resident() -> Option<u64> {
    resident_size()
}

#[cfg(not(any(target_os="linux", target_os = "macos")))]
fn get_vsize() -> Option<u64> {
    None
}

#[cfg(not(any(target_os="linux", target_os = "macos")))]
fn get_resident() -> Option<u64> {
    None
}
<|endoftext|>


<commit_before>use shared::client::Client;
use server::Store;
use getopts;

use db::sql_exec;

pub fn create (matches: &getopts::Matches) {
    if matches.opt_present("c") {
        let ip_addr = "127.0.0.1:9996";

        let (mut c, _) = Client::default();
        c.connect(ip_addr);
        if c.stream.is_none() { panic!("Client unable to connect to server") }
        c.register();

        let r = sql_exec(matches, "Update Clients set is_admin = true where UUID = $1;", &[&c.id()]);
        if r.is_err() {
            panic!("Unable to set user as admin {:?}", r)
        }

        Client::save(&c,"admin.key");
    }
}
<commit_msg>use datastore<commit_after>use shared::client::Client;
use server::{Store,DataStore};
use getopts;

use db::sql_exec;

pub fn create (matches: &getopts::Matches) {
    if matches.opt_present("c") {
        let (c, _) = Client::default();
        let store = Store::default();
        store.client_put(&c.base);

        let r = sql_exec(matches, "update clients set is_admin = true where UUID = $1;", &[&c.id()]);
        if r.is_err() {
            panic!("Unable to set user as admin {:?}", r)
        }

        Client::save(&c,"admin.key");
    }
}
<|endoftext|>


<commit_before>extern crate cfg_if;

use cfg_if::cfg_if;

cfg_if! {
    if #[cfg(all(windows, feature = "neon-sys"))] {
        use std::env::var;
        use std::path::Path;

        const NODE_ROOT_DIR: &'static str = include_str!(concat!(env!("OUT_DIR"), "\\node_root_dir"));
        const NODE_ARCH:     &'static str = include_str!(concat!(env!("OUT_DIR"), "\\node_arch"));
        const NODE_LIB_FILE: &'static str = include_str!(concat!(env!("OUT_DIR"), "\\node_lib_file"));

        /// Set up the build environment by setting Cargo configuration variables.
        pub fn setup() {
            let debug = var("DEBUG").ok().map_or(false, |s| s == "true");
            let configuration = if debug { "Debug" } else { "Release" };
            let node_lib_file_path = Path::new(NODE_LIB_FILE);
            let mut node_lib_path = Path::new(NODE_ROOT_DIR).to_path_buf();
            node_lib_path.push(NODE_ARCH);
            println!("cargo:rustc-link-search={}\\{}", NODE_ROOT_DIR, configuration);
            println!("cargo:rustc-link-search=native={}", &node_lib_path.display());
            println!("cargo:rustc-link-lib={}", &node_lib_file_path.file_stem().unwrap().to_str().unwrap());

            // Link `win_delay_load_hook.obj` for windows electron
            let node_runtime_env = "npm_config_runtime";
            println!("cargo:rerun-if-env-changed={}", node_runtime_env);
            if var(node_runtime_env).map(|s| s == "electron") == Ok(true) {
                println!("cargo:rustc-cdylib-link-arg=win_delay_load_hook.obj");
                println!("cargo:rustc-cdylib-link-arg=delayimp.lib");
                println!("cargo:rustc-cdylib-link-arg=/DELAYLOAD:node.exe");
            }
        }
    } else if #[cfg(windows)] {
        // ^ automatically not neon-sys
        use std::io::{Error, ErrorKind, Write, Result};
        use std::process::Command;
        use std::path::Path;

        fn node_version() -> Result<String> {
            let output = Command::new("node").arg("-v").output()?;
            if !output.status.success() {
                let _ = std::io::stderr().write_all(&output.stderr);
                panic!("Could not download node.lib. There is likely more information from stderr above.");
            }
            let stdout = String::from_utf8(output.stdout).map_err(|error| {
                Error::new(ErrorKind::InvalidData, error)
            })?;
            Ok(stdout.trim().to_string())
        }

        fn download_node_lib(version: &str, arch: &str) -> Result<Vec<u8>> {
            let script = r#"
                var url = process.argv[1]
                require("https").get(url, function (res) {
                    res.pipe(process.stdout);
                });
            "#;
            let url = format!("https://nodejs.org/dist/{version}/win-{arch}/node.lib", version = version, arch = arch);

            let output = Command::new("node")
                .arg("-e").arg(script)
                .arg(url)
                .output()?;

            Ok(output.stdout)
        }

        /// Set up the build environment by setting Cargo configuration variables.
        pub fn setup() {
            // If the user specified a node.lib path, we do not need to download
            if let Some(node_lib_path) = std::env::var_os("NEON_NODE_LIB") {
                let node_lib_path = Path::new(&node_lib_path);
                // Clearing the file name returns the root+directory name
                let dir = node_lib_path.with_file_name("");
                let basename = node_lib_path.file_stem().expect("Could not parse lib name from NEON_NODE_LIB. Does the path include the full file name?");

                println!("cargo:rustc-link-search=native={}", dir.display());
                // Littul hack to output the OsStr file stem
                println!("cargo:rustc-link-lib={}", Path::new(basename).display());
                return;
            }

            let version = std::env::var("npm_config_target")
                .or_else(|_| node_version())
                .expect("Could not determine Node.js version");
            let arch = if std::env::var("CARGO_CFG_TARGET_ARCH").unwrap() == "x86" {
                "x86"
            } else {
                "x64"
            };

            let node_lib_store_path = format!(r"{}/node-{}.lib", env!("OUT_DIR"), arch);

            // Download node.lib if it does not exist
            if let Err(_) = std::fs::metadata(&node_lib_store_path) {
                let node_lib = download_node_lib(&version, arch).expect("Could not download `node.lib`");
                std::fs::write(&node_lib_store_path, &node_lib).expect("Could not save `node.lib`");
            }

            println!("cargo:rustc-link-search=native={}", env!("OUT_DIR"));
            println!("cargo:rustc-link-lib=node-{}", arch);
        }
    } else if #[cfg(target_os = "macos")] {
        /// Set up the build environment by setting Cargo configuration variables.
        pub fn setup() {
            println!("cargo:rustc-cdylib-link-arg=-undefined");
            println!("cargo:rustc-cdylib-link-arg=dynamic_lookup");
        }
    } else {
        pub fn setup() { }
    }
}
<commit_msg>tweak the Path::new() hack comment<commit_after>extern crate cfg_if;

use cfg_if::cfg_if;

cfg_if! {
    if #[cfg(all(windows, feature = "neon-sys"))] {
        use std::env::var;
        use std::path::Path;

        const NODE_ROOT_DIR: &'static str = include_str!(concat!(env!("OUT_DIR"), "\\node_root_dir"));
        const NODE_ARCH:     &'static str = include_str!(concat!(env!("OUT_DIR"), "\\node_arch"));
        const NODE_LIB_FILE: &'static str = include_str!(concat!(env!("OUT_DIR"), "\\node_lib_file"));

        /// Set up the build environment by setting Cargo configuration variables.
        pub fn setup() {
            let debug = var("DEBUG").ok().map_or(false, |s| s == "true");
            let configuration = if debug { "Debug" } else { "Release" };
            let node_lib_file_path = Path::new(NODE_LIB_FILE);
            let mut node_lib_path = Path::new(NODE_ROOT_DIR).to_path_buf();
            node_lib_path.push(NODE_ARCH);
            println!("cargo:rustc-link-search={}\\{}", NODE_ROOT_DIR, configuration);
            println!("cargo:rustc-link-search=native={}", &node_lib_path.display());
            println!("cargo:rustc-link-lib={}", &node_lib_file_path.file_stem().unwrap().to_str().unwrap());

            // Link `win_delay_load_hook.obj` for windows electron
            let node_runtime_env = "npm_config_runtime";
            println!("cargo:rerun-if-env-changed={}", node_runtime_env);
            if var(node_runtime_env).map(|s| s == "electron") == Ok(true) {
                println!("cargo:rustc-cdylib-link-arg=win_delay_load_hook.obj");
                println!("cargo:rustc-cdylib-link-arg=delayimp.lib");
                println!("cargo:rustc-cdylib-link-arg=/DELAYLOAD:node.exe");
            }
        }
    } else if #[cfg(windows)] {
        // ^ automatically not neon-sys
        use std::io::{Error, ErrorKind, Write, Result};
        use std::process::Command;
        use std::path::Path;

        fn node_version() -> Result<String> {
            let output = Command::new("node").arg("-v").output()?;
            if !output.status.success() {
                let _ = std::io::stderr().write_all(&output.stderr);
                panic!("Could not download node.lib. There is likely more information from stderr above.");
            }
            let stdout = String::from_utf8(output.stdout).map_err(|error| {
                Error::new(ErrorKind::InvalidData, error)
            })?;
            Ok(stdout.trim().to_string())
        }

        fn download_node_lib(version: &str, arch: &str) -> Result<Vec<u8>> {
            let script = r#"
                var url = process.argv[1]
                require("https").get(url, function (res) {
                    res.pipe(process.stdout);
                });
            "#;
            let url = format!("https://nodejs.org/dist/{version}/win-{arch}/node.lib", version = version, arch = arch);

            let output = Command::new("node")
                .arg("-e").arg(script)
                .arg(url)
                .output()?;

            Ok(output.stdout)
        }

        /// Set up the build environment by setting Cargo configuration variables.
        pub fn setup() {
            // If the user specified a node.lib path, we do not need to download
            if let Some(node_lib_path) = std::env::var_os("NEON_NODE_LIB") {
                let node_lib_path = Path::new(&node_lib_path);
                // Clearing the file name returns the root+directory name
                let dir = node_lib_path.with_file_name("");
                let basename = node_lib_path.file_stem().expect("Could not parse lib name from NEON_NODE_LIB. Does the path include the full file name?");

                println!("cargo:rustc-link-search=native={}", dir.display());
                // `basename` is an OsStr, we can output it anyway by re-wrapping it in a Path
                // Both `dir` and `basename` will be mangled (contain replacement characters) if
                // they are not UTF-8 paths. If we don't mangle them though, Cargo will: so
                // non-UTF-8 paths are simply not supported.
                println!("cargo:rustc-link-lib={}", Path::new(basename).display());
                return;
            }

            let version = std::env::var("npm_config_target")
                .or_else(|_| node_version())
                .expect("Could not determine Node.js version");
            let arch = if std::env::var("CARGO_CFG_TARGET_ARCH").unwrap() == "x86" {
                "x86"
            } else {
                "x64"
            };

            let node_lib_store_path = format!(r"{}/node-{}.lib", env!("OUT_DIR"), arch);

            // Download node.lib if it does not exist
            if let Err(_) = std::fs::metadata(&node_lib_store_path) {
                let node_lib = download_node_lib(&version, arch).expect("Could not download `node.lib`");
                std::fs::write(&node_lib_store_path, &node_lib).expect("Could not save `node.lib`");
            }

            println!("cargo:rustc-link-search=native={}", env!("OUT_DIR"));
            println!("cargo:rustc-link-lib=node-{}", arch);
        }
    } else if #[cfg(target_os = "macos")] {
        /// Set up the build environment by setting Cargo configuration variables.
        pub fn setup() {
            println!("cargo:rustc-cdylib-link-arg=-undefined");
            println!("cargo:rustc-cdylib-link-arg=dynamic_lookup");
        }
    } else {
        pub fn setup() { }
    }
}
<|endoftext|>


<commit_before>enum List<T> {
    Cons(T, ~List<T>),
    Nil
}

fn length<T>(list: &List<T>) -> uint {
    match *list {
        Nil => 0,
        Cons(_, ~ref rest) => length(rest)+1
    }
}

fn main() {
    let list: List<char> = Cons('a', ~Cons('b', ~Cons('c', ~Cons('d', ~Nil))));
    println!("{}", length(&list));
}
<commit_msg>Redo Problem 04 with vectors<commit_after>fn main() {
    let list = ~['a', 'b', 'c'];
    println!("{}", list.len());

    let list: ~[uint] = ~[];
    println!("{}", list.len());
}
<|endoftext|>


<commit_before>extern crate rand;

use std::io;
use rand::Rng;

fn main() {

    println!("Guess the number!");
    println!("Please input your guess: ");

    let secret_num = rand::thread_rng().gen_range(1,101);

    let mut guess = String::new();
    io::stdin().read_line(&mut guess)
        .expect("Failed to read line :(");

    println!("You guessed: {}", guess);
    println!("The secret number is {}.",secret_num);
}
<commit_msg>Finished guessing game example<commit_after>extern crate rand;

use std::io;
use rand::Rng;
use std::cmp::Ordering;

fn main() {

    println!("Guess the number!");
    println!("Please input your guess: ");

    let secret_num = rand::thread_rng().gen_range(1,101);

    loop {

        let mut guess = String::new();
        io::stdin().read_line(&mut guess)
            .expect("Failed to read line :(");

        let guess: i32 = match guess.trim().parse() {
            Ok(num) => num,
            Err(_) => {
                println!("Please type a number");
                continue;
            },
        };

        println!("You guessed: {}", guess);

        match guess.cmp(&secret_num){
            Ordering::Less => println!("Too small!"),
            Ordering::Greater => println!("Too Big!"),
            Ordering::Equal =>  {
                println!("Too You win!");
                break;
            }
        }

    }
    println!("The secret number is {}.",secret_num);
}
<|endoftext|>


<commit_before>use super::camera::*;
use super::event_manager::*;
use GameContext;
use glium::glutin::{CursorState, ElementState, Event, MouseButton, VirtualKeyCode};
use base::math::*;
use base::world::*;
use std::rc::Rc;
use super::world_manager::*;

const GRAVITY: f32 = 9.81;
/// Represents a `Player` in the world, the `Player` can move up, right, down
/// left, right with w, a, s, d, jump with space and speed with shift
pub struct Player {
    cam: Camera,
    context: Rc<GameContext>,
    world_manager: WorldManager,
    acceleration: Vector3f,
    velocity: Vector3f,
    timer_jump: f32,
    timer_vel: f32,
    mouselock: bool,
    shift_speed: f32,
}

impl Player {
    pub fn new(context: Rc<GameContext>, world_manager: WorldManager) -> Self {
        Player {
            cam: Camera {
                position: Point3::new(15.0, 10.0, 50.0),
                phi: -0.27,
                theta: 2.6,
            },
            world_manager: world_manager,
            context: context,
            timer_jump: 1.0,
            timer_vel: 1.0,
            acceleration: Vector3::new(0.0, 0.0, 0.0),
            velocity: Vector3::new(0.0, 0.0, 0.0),
            mouselock: false,
            shift_speed: 1.0,
        }
    }
    /// Gets the actual `Height` of the `HexPillar`
    pub fn get_ground_height(&self) -> Option<f32> {
        let world = self.world_manager.get_world();
        let real_pos = Point2f::new(self.cam.position.x, self.cam.position.y);
        let pillar_index = PillarIndex(AxialPoint::from_real(real_pos));

        world.pillar_at(pillar_index).map(|pillar| pillar.sections()[0].top.to_real())
    }
    /// Getter method for the `Camera`
    pub fn get_camera(&self) -> Camera {
        self.cam
    }
    /// Updates the `Player` after every iteration
    pub fn update(&mut self, delta: f32) {
        let mut height = 0.0;
        let mut test = self.get_ground_height();
        if test.is_some() {
            height = test.unwrap();
            height = height + 1.75;
        }
        // Moves the Player forward or backward with the acceleration and delta
        // (1.0 - (-((self.timer_vel * delta) / (1.0))).exp()) -> this is a formula
        // that calculates a
        // number from 0 to 1. So the player has a maximum velocity
        if self.acceleration.x != 0.0 {
            self.cam.move_forward(self.acceleration.x * delta * delta * self.shift_speed *
                                  (1.0 - (-((self.timer_vel * delta) / (1.0))).exp()));
            if self.timer_vel != 100.0 {
                self.timer_vel += 1.0;
            }
            if self.acceleration.x == 0.0 {
                self.timer_vel = 1.0;
            }
        }
        // Moves the Player left an right with the acceleration and delta
        if self.acceleration.y != 0.0 {
            self.cam
                .move_right(self.acceleration.y * delta * delta *
                            (1.0 - (-((self.timer_vel * delta) / (1.0))).exp()));
            if self.timer_vel != 100.0 {
                self.timer_vel += 1.0;
            }
            if self.acceleration.y == 0.0 {
                self.timer_vel = 1.0;
            }
        }
        // Let the player jump with the given start-velocity
        if self.velocity.z != 0.0 {
            self.cam.move_up((self.velocity.z * self.timer_jump * delta -
                              self.timer_jump * self.timer_jump * delta * delta * GRAVITY) /
                             16.0);
            self.timer_jump += 1.0;
            if self.cam.position.z < height {
                self.velocity.z = 0.0;
                self.timer_jump = 1.0;
            }
        }
        // Places the `Player` on the actual `HexPillar` if the position of the
        // `Player` is less than
        // the `HexPillar`
        if self.velocity.z == 0.0 && self.cam.position.z < height {
            self.cam.position.z = height;
        }
        // Checks if the `Player` is higher than the actual `Player` on wich he is
        // standing and let
        // him fall on that
        if self.cam.position.z > height && self.velocity.z == 0.0 {
            self.cam
                .move_down((self.timer_jump * self.timer_jump * delta * delta * GRAVITY) / 16.0);
            self.timer_jump += 1.0;
            if self.cam.position.z < height {
                self.timer_jump = 1.0;
            }
        }
    }
}
/// `EventHandler` for the `Player`
impl EventHandler for Player {
    fn handle_event(&mut self, e: &Event) -> EventResponse {
        match *e {
            Event::KeyboardInput(ElementState::Pressed, _, Some(VirtualKeyCode::W)) => {
                self.acceleration.x = 500.5;
                EventResponse::Continue
            }
            Event::KeyboardInput(ElementState::Released, _, Some(VirtualKeyCode::W)) => {
                self.acceleration.x = 0.0;
                EventResponse::Continue
            }
            Event::KeyboardInput(ElementState::Pressed, _, Some(VirtualKeyCode::S)) => {
                self.acceleration.x = -400.0;
                EventResponse::Continue
            }
            Event::KeyboardInput(ElementState::Released, _, Some(VirtualKeyCode::S)) => {
                self.acceleration.x = 0.0;
                EventResponse::Continue
            }
            Event::KeyboardInput(ElementState::Pressed, _, Some(VirtualKeyCode::A)) => {
                self.acceleration.y = -400.5;
                EventResponse::Continue
            }
            Event::KeyboardInput(ElementState::Released, _, Some(VirtualKeyCode::A)) => {
                self.acceleration.y = 0.0;
                EventResponse::Continue
            }
            Event::KeyboardInput(ElementState::Pressed, _, Some(VirtualKeyCode::D)) => {
                self.acceleration.y = 400.5;
                EventResponse::Continue
            }
            Event::KeyboardInput(ElementState::Released, _, Some(VirtualKeyCode::D)) => {
                self.acceleration.y = 0.0;
                EventResponse::Continue
            }
            Event::KeyboardInput(ElementState::Pressed, _, Some(VirtualKeyCode::Space)) => {
                self.velocity.z = 6.0;
                EventResponse::Continue
            }
            Event::KeyboardInput(ElementState::Released, _, Some(VirtualKeyCode::Space)) => {
                EventResponse::Continue
            }
            Event::KeyboardInput(ElementState::Pressed, _, Some(VirtualKeyCode::LControl)) => {
                EventResponse::Continue
            }
            Event::KeyboardInput(ElementState::Released, _, Some(VirtualKeyCode::LControl)) => {
                EventResponse::Continue
            }
            Event::KeyboardInput(ElementState::Pressed, _, Some(VirtualKeyCode::LShift)) => {
                self.shift_speed = 2.0;
                EventResponse::Continue
            }
            Event::KeyboardInput(ElementState::Released, _, Some(VirtualKeyCode::LShift)) => {
                self.shift_speed = 1.0;
                EventResponse::Continue
            }
            Event::KeyboardInput(ElementState::Pressed, _, Some(VirtualKeyCode::F)) => {
                EventResponse::Continue
            }
            Event::KeyboardInput(ElementState::Released, _, Some(VirtualKeyCode::F)) => {
                EventResponse::Continue
            }
            Event::MouseInput(ElementState::Pressed, MouseButton::Left) => {
                if !self.mouselock {
                    self.mouselock = true;
                    if let Some(window) = self.context.get_facade().get_window() {
                        window.set_cursor_state(CursorState::Hide)
                            .expect("failed to set cursor state");
                    } else {
                        warn!("Failed to obtain window from facade");
                    }
                } else if self.mouselock {
                    self.mouselock = false;

                    if let Some(window) = self.context.get_facade().get_window() {
                        window.set_cursor_state(CursorState::Normal)
                            .expect("failed to set cursor state");
                    } else {
                        warn!("Failed to obtain window from facade");
                    }
                }

                EventResponse::Continue
            }

            Event::MouseMoved(x, y) => {
                if self.mouselock {
                    if let Some(window) = self.context.get_facade().get_window() {
                        // Possibility of mouse being outside of window without it resetting to the
                        // middle?
                        if let Some(middle) = window.get_inner_size_pixels() {
                            let middle_x = (middle.0 as i32) / 2;
                            let middle_y = (middle.1 as i32) / 2;
                            let x_diff = x - middle_x;
                            let y_diff = y - middle_y;
                            self.cam.change_dir(y_diff as f32 / 300.0, -x_diff as f32 / 300.0);
                            window.set_cursor_position(middle_x as i32, middle_y as i32)
                                .expect("setting cursor position failed");
                        }
                    }
                }
                EventResponse::Continue
            }

            _ => EventResponse::NotHandled,
        }
    }
}
<commit_msg>Improvement of get_ground_height<commit_after>use super::camera::*;
use super::event_manager::*;
use GameContext;
use glium::glutin::{CursorState, ElementState, Event, MouseButton, VirtualKeyCode};
use base::math::*;
use base::world::*;
use std::rc::Rc;
use super::world_manager::*;

const GRAVITY: f32 = 9.81;
/// Represents a `Player` in the world, the `Player` can move up, right, down
/// left, right with w, a, s, d, jump with space and speed with shift
pub struct Player {
    cam: Camera,
    context: Rc<GameContext>,
    world_manager: WorldManager,
    acceleration: Vector3f,
    velocity: Vector3f,
    timer_jump: f32,
    timer_vel: f32,
    mouselock: bool,
    shift_speed: f32,
}

impl Player {
    pub fn new(context: Rc<GameContext>, world_manager: WorldManager) -> Self {
        Player {
            cam: Camera {
                position: Point3::new(15.0, 10.0, 50.0),
                phi: -0.27,
                theta: 2.6,
            },
            world_manager: world_manager,
            context: context,
            timer_jump: 1.0,
            timer_vel: 1.0,
            acceleration: Vector3::new(0.0, 0.0, 0.0),
            velocity: Vector3::new(0.0, 0.0, 0.0),
            mouselock: false,
            shift_speed: 1.0,
        }
    }
    /// Gets the actual `Height` of the `HexPillar`
    pub fn get_ground_height(&self) -> Option<f32> {
        let world = self.world_manager.get_world();
        let real_pos = Point2f::new(self.cam.position.x, self.cam.position.y);
        let pillar_index = PillarIndex(AxialPoint::from_real(real_pos));

        world.pillar_at(pillar_index).map(|pillar| pillar.sections()[0].top.to_real())
    }
    /// Getter method for the `Camera`
    pub fn get_camera(&self) -> Camera {
        self.cam
    }
    /// Updates the `Player` after every iteration
    pub fn update(&mut self, delta: f32) {
        let height = self.get_ground_height().unwrap_or(0.0) + 1.70;

        // Moves the Player forward or backward with the acceleration and delta
        // (1.0 - (-((self.timer_vel * delta) / (1.0))).exp()) -> this is a formula
        // that calculates a
        // number from 0 to 1. So the player has a maximum velocity
        if self.acceleration.x != 0.0 {
            self.cam.move_forward(self.acceleration.x * delta * delta * self.shift_speed *
                                  (1.0 - (-((self.timer_vel * delta) / (1.0))).exp()));
            if self.timer_vel != 100.0 {
                self.timer_vel += 1.0;
            }
            if self.acceleration.x == 0.0 {
                self.timer_vel = 1.0;
            }
        }
        // Moves the Player left an right with the acceleration and delta
        if self.acceleration.y != 0.0 {
            self.cam
                .move_right(self.acceleration.y * delta * delta *
                            (1.0 - (-((self.timer_vel * delta) / (1.0))).exp()));
            if self.timer_vel != 100.0 {
                self.timer_vel += 1.0;
            }
            if self.acceleration.y == 0.0 {
                self.timer_vel = 1.0;
            }
        }
        // Let the player jump with the given start-velocity
        if self.velocity.z != 0.0 {
            self.cam.move_up((self.velocity.z * self.timer_jump * delta -
                              self.timer_jump * self.timer_jump * delta * delta * GRAVITY) /
                             16.0);
            self.timer_jump += 1.0;
            if self.cam.position.z < height {
                self.velocity.z = 0.0;
                self.timer_jump = 1.0;
            }
        }
        // Places the `Player` on the actual `HexPillar` if the position of the
        // `Player` is less than
        // the `HexPillar`
        if self.velocity.z == 0.0 && self.cam.position.z < height {
            self.cam.position.z = height;
        }
        // Checks if the `Player` is higher than the actual `Player` on wich he is
        // standing and let
        // him fall on that
        if self.cam.position.z > height && self.velocity.z == 0.0 {
            self.cam
                .move_down((self.timer_jump * self.timer_jump * delta * delta * GRAVITY) / 16.0);
            self.timer_jump += 1.0;
            if self.cam.position.z < height {
                self.timer_jump = 1.0;
            }
        }
    }
}
/// `EventHandler` for the `Player`
impl EventHandler for Player {
    fn handle_event(&mut self, e: &Event) -> EventResponse {
        match *e {
            Event::KeyboardInput(ElementState::Pressed, _, Some(VirtualKeyCode::W)) => {
                self.acceleration.x = 500.5;
                EventResponse::Continue
            }
            Event::KeyboardInput(ElementState::Released, _, Some(VirtualKeyCode::W)) => {
                self.acceleration.x = 0.0;
                EventResponse::Continue
            }
            Event::KeyboardInput(ElementState::Pressed, _, Some(VirtualKeyCode::S)) => {
                self.acceleration.x = -400.0;
                EventResponse::Continue
            }
            Event::KeyboardInput(ElementState::Released, _, Some(VirtualKeyCode::S)) => {
                self.acceleration.x = 0.0;
                EventResponse::Continue
            }
            Event::KeyboardInput(ElementState::Pressed, _, Some(VirtualKeyCode::A)) => {
                self.acceleration.y = -400.5;
                EventResponse::Continue
            }
            Event::KeyboardInput(ElementState::Released, _, Some(VirtualKeyCode::A)) => {
                self.acceleration.y = 0.0;
                EventResponse::Continue
            }
            Event::KeyboardInput(ElementState::Pressed, _, Some(VirtualKeyCode::D)) => {
                self.acceleration.y = 400.5;
                EventResponse::Continue
            }
            Event::KeyboardInput(ElementState::Released, _, Some(VirtualKeyCode::D)) => {
                self.acceleration.y = 0.0;
                EventResponse::Continue
            }
            Event::KeyboardInput(ElementState::Pressed, _, Some(VirtualKeyCode::Space)) => {
                self.velocity.z = 6.0;
                EventResponse::Continue
            }
            Event::KeyboardInput(ElementState::Released, _, Some(VirtualKeyCode::Space)) => {
                EventResponse::Continue
            }
            Event::KeyboardInput(ElementState::Pressed, _, Some(VirtualKeyCode::LControl)) => {
                EventResponse::Continue
            }
            Event::KeyboardInput(ElementState::Released, _, Some(VirtualKeyCode::LControl)) => {
                EventResponse::Continue
            }
            Event::KeyboardInput(ElementState::Pressed, _, Some(VirtualKeyCode::LShift)) => {
                self.shift_speed = 2.0;
                EventResponse::Continue
            }
            Event::KeyboardInput(ElementState::Released, _, Some(VirtualKeyCode::LShift)) => {
                self.shift_speed = 1.0;
                EventResponse::Continue
            }
            Event::KeyboardInput(ElementState::Pressed, _, Some(VirtualKeyCode::F)) => {
                EventResponse::Continue
            }
            Event::KeyboardInput(ElementState::Released, _, Some(VirtualKeyCode::F)) => {
                EventResponse::Continue
            }
            Event::MouseInput(ElementState::Pressed, MouseButton::Left) => {
                if !self.mouselock {
                    self.mouselock = true;
                    if let Some(window) = self.context.get_facade().get_window() {
                        window.set_cursor_state(CursorState::Hide)
                            .expect("failed to set cursor state");
                    } else {
                        warn!("Failed to obtain window from facade");
                    }
                } else if self.mouselock {
                    self.mouselock = false;

                    if let Some(window) = self.context.get_facade().get_window() {
                        window.set_cursor_state(CursorState::Normal)
                            .expect("failed to set cursor state");
                    } else {
                        warn!("Failed to obtain window from facade");
                    }
                }

                EventResponse::Continue
            }

            Event::MouseMoved(x, y) => {
                if self.mouselock {
                    if let Some(window) = self.context.get_facade().get_window() {
                        // Possibility of mouse being outside of window without it resetting to the
                        // middle?
                        if let Some(middle) = window.get_inner_size_pixels() {
                            let middle_x = (middle.0 as i32) / 2;
                            let middle_y = (middle.1 as i32) / 2;
                            let x_diff = x - middle_x;
                            let y_diff = y - middle_y;
                            self.cam.change_dir(y_diff as f32 / 300.0, -x_diff as f32 / 300.0);
                            window.set_cursor_position(middle_x as i32, middle_y as i32)
                                .expect("setting cursor position failed");
                        }
                    }
                }
                EventResponse::Continue
            }

            _ => EventResponse::NotHandled,
        }
    }
}
<|endoftext|>


<commit_before>
use mouros_rust_bindings::CVoid;

use i2c;

#[no_mangle]
pub extern "C" fn meteo_comm_loop(_params: *mut CVoid) {

    let mut write1 = [0u8; 10];
    let mut read2 = [0u8; 4];

    let mut steps = [i2c::Step::Write(&mut write1), i2c::Step::Read(&mut read2)];

    i2c::run_transaction(0xaa, &mut steps);
}<commit_msg>Initial do-nothing meteo module<commit_after>
use mouros_rust_bindings::CVoid;

use bsp::i2c;

#[no_mangle]
pub extern "C" fn meteo_comm_loop(_params: *mut CVoid) {

    let mut periph = i2c::I2C::new(i2c::Peripherals::I2C1);

    let mut write1 = [0u8; 10];
    let mut read2 = [0u8; 4];

    let mut steps = [i2c::Step::Write(&mut write1), i2c::Step::Read(&mut read2)];

    loop {
        let _ = periph.run_transaction(0xaa, &mut steps);
    }
}<|endoftext|>


<commit_before>// twobit module containing a native implementation of the twobit query library
#![crate_id = "twobit#0.2"]
#![crate_type = "dylib"]
#![feature(macro_rules)]

extern crate native;
extern crate rustrt;

use std::os::MemoryMap;
use std::collections::hashmap::HashMap;
use std::io::{ IoResult, IoError };

use rustrt::rtio::RtioFileStream;

struct Block { start: u32, length: u32 }

struct Sequence {
	n_dna_bases: u32,
	unk_blocks: Vec<Block>,
	mask_blocks: Vec<Block>,
	dna_start: *mut u8
}

impl Sequence {
	fn string(&self, start: u32, end: u32) -> String {
		let mut rsize = (end - start + 1) as uint;
		let mut end = end;
		let mut result = String::from_char(rsize, 'N');

		if end >= self.n_dna_bases {
			end = self.n_dna_bases - 1;
			rsize = (end - start + 1) as uint;
		}

		unsafe {
			let bvec = result.as_mut_bytes();

			/* fill sequence */
			let mut block = self.dna_start.offset( (start / 4) as int);
			let mut offset = (start % 4) as uint;

			for i in range(0, rsize) {
				bvec[i] = byte_to_base(*block, offset) as u8;

				offset = offset + 1;
				if offset == 4 {
					offset = 0;
					block = block.offset(1);
				}
			}

			/* fill in Ns */
			for item in self.unk_blocks.iter() {
				let mut bstart = item.start;
				let mut bsize = item.length;
				let bend = bstart + bsize - 1;

				if bstart <= end && bend >= start {
					if bstart < start {
						bsize = bsize - (start - bstart);
						bstart = start;
					}

					let mut j = 0;
					let mut k = bstart;
					while j < bsize && k <= end {
						bvec[(k - start) as uint] = 'N' as u8;

						j = j + 1;
						k = k + 1;
					}
				}
			}
		}

		return result;
	}
}

pub struct TwoBit {
	seqs: HashMap<String, Sequence>,

	#[allow(dead_code)]
	data: MemoryMap // this is needed to keep the memory map alive
}

macro_rules! try_rt(
    ($e:expr) => (match $e { Ok(e) => e, Err(rustrt::rtio::IoError{code: code, extra: _, detail: _}) => return Err(IoError::from_errno(code, true)) })
)

fn mmap_read_u32(ptr: * mut u8, offset: uint) -> u32 {
	return unsafe {
		let tmp : *u32 = std::mem::transmute(ptr.offset(offset as int) as *[u8, ..4]);
		*tmp };
}

fn mmap_read_u8(ptr: * mut u8, offset: uint) -> u8 {
	return unsafe {
		*ptr.offset(offset as int)
	};
}

fn read_blocks(data: * mut u8, offset: u32) -> (Vec<Block>, u32) {
	let len = mmap_read_u32(data, offset as uint);
	let mut vec = Vec::<Block>::new();

	if len > 0 {
		let off1 = offset + 4;
		let off2 = offset + 4 + len*4;

		for i in range(0, len) {
			let start = mmap_read_u32(data, (off1 + i*4) as uint);
			let size = mmap_read_u32(data, (off2 + i*4) as uint);

			vec.push(Block{ start: start, length: size });
		}
	}

	return (vec, offset + 4 + 2*len*4);
}

fn mmap_read_index(data: *mut u8, count: u32) -> HashMap<String, Sequence> {
		let mut index = HashMap::with_capacity(count as uint);

		let mut header_start = 16u;

		for _ in range(0, count) {
			let name_size = mmap_read_u8(data, header_start);
			let name = unsafe { String::from_raw_parts(name_size as uint, name_size as uint, data.offset((header_start + 1) as int)) };
			let offset = mmap_read_u32(data, header_start + 1 + name_size as uint);

			// get actual info
			let dna_size = mmap_read_u32(data, offset as uint);

			// unknown blocks
			let (unk_blocks, offset) = read_blocks(data, offset + 4);

			// masked blocks
			let (mask_blocks, offset) = read_blocks(data, offset);

			// actual pointer to DNA data
			let dna_ptr = unsafe { data.offset((offset + 4) as int) }; // + reserved

			index.insert(name, Sequence { n_dna_bases: dna_size, unk_blocks: unk_blocks, mask_blocks: mask_blocks, dna_start: dna_ptr });

			header_start = header_start + 1 + name_size as uint + 4;
		}

		return index;
}

fn byte_to_base(value: u8, offset: uint) -> char {
	let bases = ['T', 'C', 'A', 'G'];
	let rev_offset = 3 - offset;
	let mask = 3 << (rev_offset * 2);
	let idx = (value & mask) >> (rev_offset * 2);

	return bases[idx as uint];
}

impl TwoBit {

	pub fn new(filename: &str) -> IoResult<TwoBit> {
		// open file
		let mut fh = try_rt!(native::io::file::open(&filename.to_c_str(), rustrt::rtio::Open, rustrt::rtio::Read));
		let fs = try_rt!(fh.fstat());

		// build memory map
		let mmap = match MemoryMap::new(fs.size as uint, [ std::os::MapReadable, std::os::MapFd(fh.fd())]) {
			Ok(val) => val,
			Err(_) => return Err(IoError{kind: std::io::OtherIoError, desc: "Memory map failed!", detail: None})
		};

		// TODO: add madvise call

		// validate header
		let val = mmap_read_u32(mmap.data, 0);

		if val != 0x1A412743 {
			return Err(IoError { kind: std::io::OtherIoError, desc: "Invalid signature or wrong architecture.", detail: None });
		}

		let val = mmap_read_u32(mmap.data, 4);
		if val != 0 {
			return Err(IoError { kind: std::io::OtherIoError, desc: "Unknown file version.", detail: None });
		} // TODO: actually report version found

		let n_sequences = mmap_read_u32(mmap.data, 8);
		if n_sequences == 0 {
			return Err(IoError { kind: std::io::OtherIoError, desc: "Zero sequence count.", detail: None });
		}

		let val = mmap_read_u32(mmap.data, 12);
		if val != 0 {
			return Err(IoError { kind: std::io::OtherIoError, desc: "Reserved bytes not zero.", detail: None });
		} // TODO: actually report value found

		// parse index
		let index = mmap_read_index(mmap.data, n_sequences);

		return Ok(TwoBit { seqs: index, data: mmap });
	}

	pub fn sequence(&self, chrom: &str, start: u32, end: u32) -> Option<String> {
		match self.seqs.find(&String::from_str(chrom)) {
			Some(ref seq) => Some(seq.string(start, end)),
			None => None
		}
	}

	pub fn sequence_len(&self, chrom: &str) -> Option<u32> {
		match self.seqs.find(&String::from_str(chrom)) {
			Some(&Sequence{ n_dna_bases: n, ..}) => Some(n),
			None => None
		}
	}

	pub fn sequence_names<'a>(&'a self) -> Vec<&'a String> {
		self.seqs.keys().collect()
	}

	pub fn base_frequencies(&self, chrom: &str) -> Option<[f64, ..4]> {
		match self.seqs.find(&String::from_str(chrom)) {
			Some(ref seq) => {
				let seqstr = seq.string(0, seq.n_dna_bases - 1);
				let mut counts = [0f64, 0.0, 0.0, 0.0];

				for c in seqstr.as_slice().chars() {
					match c {
						'A' => counts[0] = counts[0] + 1.0,
						'C' => counts[1] = counts[1] + 1.0,
						'G' => counts[2] = counts[2] + 1.0,
						'T' => counts[3] = counts[3] + 1.0,
						_ => {}
					}
				}

				let sum = counts[0] + counts[1] + counts[2] + counts[3];
				counts[0] = counts[0] / sum;
				counts[1] = counts[1] / sum;
				counts[2] = counts[2] / sum;
				counts[3] = counts[3] / sum;

				Some(counts)
			}
			None => None
		}
	}
}
<commit_msg>Iterator over sequence range<commit_after>#![crate_id = "twobit#0.2"]
#![crate_type = "dylib"]
#![feature(macro_rules)]

extern crate native;
extern crate rustrt;

use std::os::MemoryMap;
use std::collections::hashmap::HashMap;
use std::io::{ IoResult, IoError };

use rustrt::rtio::RtioFileStream;

#[deriving(Show)]
struct Block { start: u32, length: u32 }

struct Sequence {
	n_dna_bases: u32,
	unk_blocks: Vec<Block>,
	mask_blocks: Vec<Block>,
	dna_start: *mut u8
}

impl Sequence {
	fn range<'a>(&'a self, start: u32, end: u32) -> SeqRange<'a> {
		let mut rsize = (end - start + 1) as uint;
		let mut end = end;

		if end >= self.n_dna_bases {
			let rest = rsize - self.n_dna_bases as uint;
			end = self.n_dna_bases - 1;
			rsize = (end - start + 1) as uint;

			// seq range chained with an iterator that repeats the same value
			SeqRange {
				rsize: rsize,
				ptr: unsafe { self.dna_start.offset( (start / 4) as int) },
				idx: 0u,
				offset: (start % 4) as uint,
				unk_blocks: &self.unk_blocks,
				ub_exhausted: self.unk_blocks.len() > 0,
				ub_idx: 0,
				ub_start: if self.unk_blocks.len() > 0 { self.unk_blocks.get(0).start as uint } else { 0 },
				ub_end: if self.unk_blocks.len() > 0 { (self.unk_blocks.get(0).start + self.unk_blocks.get(0).length - 1) as uint } else { 0 },
				n_more: rest
			}
		} else {
			SeqRange {
				rsize: rsize,
				ptr: unsafe { self.dna_start.offset( (start / 4) as int) },
				idx: 0u,
				offset: (start % 4) as uint,
				unk_blocks: &self.unk_blocks,
				ub_exhausted: self.unk_blocks.len() > 0,
				ub_idx: 0,
				ub_start: if self.unk_blocks.len() > 0 { self.unk_blocks.get(0).start as uint } else { 0 },
				ub_end: if self.unk_blocks.len() > 0 { (self.unk_blocks.get(0).start + self.unk_blocks.get(0).length - 1) as uint } else { 0 },
				n_more: 0
			}
		}
	}

	fn string(&self, start: u32, end: u32) -> String {
		String::from_utf8(self.range(start, end).collect()).unwrap()
	}
}

struct SeqRange<'a> {
	rsize: uint,
	ptr: * mut u8,
	idx: uint,
	offset: uint,
	unk_blocks: &'a Vec<Block>,
	ub_exhausted: bool,
	ub_idx: uint,
	ub_start: uint,
	ub_end: uint,
	n_more: uint
}

impl<'a> Iterator<u8> for SeqRange<'a> {
	fn next(&mut self) -> Option<u8> {
		if self.idx == self.rsize {
			if self.n_more > 0 {
				self.n_more = self.n_more - 1;
				return Some('N' as u8);
			}
			return None;
		} else {
			unsafe {
				// are we within a block?
				if !self.ub_exhausted {
					loop {
						if self.idx > self.ub_end {
							self.ub_idx = self.ub_idx + 1;
							if self.ub_idx == self.unk_blocks.len() {
								self.ub_exhausted = true;
								break;
							} else {
								self.ub_start = self.unk_blocks.get(self.ub_idx).start as uint;
								self.ub_end = self.ub_start + self.unk_blocks.get(self.ub_idx).length as uint - 1;
							}
						} else if self.idx >= self.ub_start {
							return Some('N' as u8);
						}
					}
				}

				// no, so collect data
				let result = Some(byte_to_base(*self.ptr, self.offset) as u8);

				// increment index
				self.idx = self.idx + 1;
				self.offset = self.offset + 1;
				if self.offset == 4 {
					self.offset = 0;
					self.ptr = self.ptr.offset(1);
				}

				return result;
			}
		}
	}
}

pub struct TwoBit {
	seqs: HashMap<String, Sequence>,

	#[allow(dead_code)]
	data: MemoryMap // this is needed to keep the memory map alive
}

macro_rules! try_rt(
    ($e:expr) => (match $e { Ok(e) => e, Err(rustrt::rtio::IoError{code: code, extra: _, detail: _}) => return Err(IoError::from_errno(code, true)) })
)

fn mmap_read_u32(ptr: * mut u8, offset: uint) -> u32 {
	return unsafe {
		let tmp : *u32 = std::mem::transmute(ptr.offset(offset as int) as *[u8, ..4]);
		*tmp };
}

fn mmap_read_u8(ptr: * mut u8, offset: uint) -> u8 {
	return unsafe {
		*ptr.offset(offset as int)
	};
}

fn read_blocks(data: * mut u8, offset: u32) -> (Vec<Block>, u32) {
	let len = mmap_read_u32(data, offset as uint);
	let mut vec = Vec::<Block>::new();

	if len > 0 {
		let off1 = offset + 4;
		let off2 = offset + 4 + len*4;

		for i in range(0, len) {
			let start = mmap_read_u32(data, (off1 + i*4) as uint);
			let size = mmap_read_u32(data, (off2 + i*4) as uint);

			vec.push(Block{ start: start, length: size });
		}
	}

	return (vec, offset + 4 + 2*len*4);
}

fn mmap_read_index(data: *mut u8, count: u32) -> HashMap<String, Sequence> {
		let mut index = HashMap::with_capacity(count as uint);

		let mut header_start = 16u;

		for _ in range(0, count) {
			let name_size = mmap_read_u8(data, header_start);
			let name = unsafe { String::from_raw_parts(name_size as uint, name_size as uint, data.offset((header_start + 1) as int)) };
			let offset = mmap_read_u32(data, header_start + 1 + name_size as uint);

			// get actual info
			let dna_size = mmap_read_u32(data, offset as uint);

			// unknown blocks
			let (unk_blocks, offset) = read_blocks(data, offset + 4);

			// masked blocks
			let (mask_blocks, offset) = read_blocks(data, offset);

			// actual pointer to DNA data
			let dna_ptr = unsafe { data.offset((offset + 4) as int) }; // + reserved

			index.insert(name, Sequence { n_dna_bases: dna_size, unk_blocks: unk_blocks, mask_blocks: mask_blocks, dna_start: dna_ptr });

			header_start = header_start + 1 + name_size as uint + 4;
		}

		return index;
}

fn byte_to_base(value: u8, offset: uint) -> char {
	let bases = ['T', 'C', 'A', 'G'];
	let rev_offset = 3 - offset;
	let mask = 3 << (rev_offset * 2);
	let idx = (value & mask) >> (rev_offset * 2);

	return bases[idx as uint];
}

impl TwoBit {

	pub fn new(filename: &str) -> IoResult<TwoBit> {
		// open file
		let mut fh = try_rt!(native::io::file::open(&filename.to_c_str(), rustrt::rtio::Open, rustrt::rtio::Read));
		let fs = try_rt!(fh.fstat());

		// build memory map
		let mmap = match MemoryMap::new(fs.size as uint, [ std::os::MapReadable, std::os::MapFd(fh.fd())]) {
			Ok(val) => val,
			Err(_) => return Err(IoError{kind: std::io::OtherIoError, desc: "Memory map failed!", detail: None})
		};

		// TODO: add madvise call

		// validate header
		let val = mmap_read_u32(mmap.data, 0);

		if val != 0x1A412743 {
			return Err(IoError { kind: std::io::OtherIoError, desc: "Invalid signature or wrong architecture.", detail: None });
		}

		let val = mmap_read_u32(mmap.data, 4);
		if val != 0 {
			return Err(IoError { kind: std::io::OtherIoError, desc: "Unknown file version.", detail: None });
		} // TODO: actually report version found

		let n_sequences = mmap_read_u32(mmap.data, 8);
		if n_sequences == 0 {
			return Err(IoError { kind: std::io::OtherIoError, desc: "Zero sequence count.", detail: None });
		}

		let val = mmap_read_u32(mmap.data, 12);
		if val != 0 {
			return Err(IoError { kind: std::io::OtherIoError, desc: "Reserved bytes not zero.", detail: None });
		} // TODO: actually report value found

		// parse index
		let index = mmap_read_index(mmap.data, n_sequences);

		return Ok(TwoBit { seqs: index, data: mmap });
	}

	pub fn sequence(&self, chrom: &str, start: u32, end: u32) -> Option<String> {
		match self.seqs.find(&String::from_str(chrom)) {
			Some(ref seq) => Some(seq.string(start, end)),
			None => None
		}
	}

	pub fn sequence_len(&self, chrom: &str) -> Option<u32> {
		match self.seqs.find(&String::from_str(chrom)) {
			Some(&Sequence{ n_dna_bases: n, ..}) => Some(n),
			None => None
		}
	}

	pub fn sequence_names<'a>(&'a self) -> Vec<&'a String> {
		self.seqs.keys().collect()
	}

	pub fn base_frequencies(&self, chrom: &str) -> Option<[f64, ..4]> {
		match self.seqs.find(&String::from_str(chrom)) {
			Some(ref seq) => {
				let mut counts = [0f64, 0.0, 0.0, 0.0];

				for val in seq.range(0, seq.n_dna_bases - 1) {
					let c = val as char;

					match c {
						'A' => counts[0] = counts[0] + 1.0,
						'C' => counts[1] = counts[1] + 1.0,
						'G' => counts[2] = counts[2] + 1.0,
						'T' => counts[3] = counts[3] + 1.0,
						_ => {}
					}
				}

				let sum = counts[0] + counts[1] + counts[2] + counts[3];
				counts[0] = counts[0] / sum;
				counts[1] = counts[1] / sum;
				counts[2] = counts[2] / sum;
				counts[3] = counts[3] / sum;

				Some(counts)
			}
			None => None
		}
	}
}
<|endoftext|>


<commit_before>// Copyright (c) The Libra Core Contributors
// SPDX-License-Identifier: Apache-2.0

use benchmark::{
    bin_utils::{create_ac_clients, measure_throughput},
    ruben_opt::parse_swarm_config_from_dir,
    txn_generator::PairwiseTransferTxnGenerator,
    Benchmarker,
};
use libra_swarm::swarm::LibraSwarm;
use num::traits::Float;
use rusty_fork::{rusty_fork_id, rusty_fork_test, rusty_fork_test_name};
use statistical::{mean, population_standard_deviation};
use std::fmt::Display;

fn calculate_avg_std<T: Float + Display>(sequence: &[T], name: &str) {
    // Output json-formatted result.
    println!(
        "{{\"{}_mean\": {:.2}, \"{}_stdev\": {:.2}}}",
        name,
        mean(sequence),
        name,
        population_standard_deviation(sequence, None),
    );
}

rusty_fork_test! {
    #[test]
    fn test_throughput() {
        // Choose parameters that is able to run on not-too-powerful local machines,
        // but still generates enough TXNs for testing (2K TXNs per epoch).
        // At submit rate 50 TXNs per second per client, submission takes around 10 seconds.
        let (num_nodes, num_accounts, num_clients) = (4, 32, 4);
        let (num_rounds, num_epochs, stagger_ms) = (2, 4, 1);
        let submit_rate = 50;

        let (faucet_account_keypair, faucet_key_file_path, _temp_dir) =
            generate_keypair::load_faucet_key_or_create_default(None);
        let swarm = LibraSwarm::launch_swarm(
            num_nodes,
            true,   /* disable_logging */
            faucet_account_keypair,
            false,  /* tee_logs */
            None,   /* config_dir */
        );
        let swarm_config_dir = String::from(swarm.dir.as_ref().unwrap().as_ref().to_str().unwrap());
        let validator_addresses = parse_swarm_config_from_dir(&swarm_config_dir).unwrap();
        let clients = create_ac_clients(num_clients, &validator_addresses);
        let mut bm = Benchmarker::new(clients, stagger_ms, submit_rate);
        let mut faucet_account = bm.load_faucet_account(&faucet_key_file_path);
        let mut pairwise_generator = PairwiseTransferTxnGenerator::new();
        let results = measure_throughput(&mut bm, &mut pairwise_generator, &mut faucet_account, num_accounts, num_rounds, num_epochs);
        let req_throughput_seq: Vec<_> = results.iter().map(|x| x.0).collect();
        let txn_throughput_seq: Vec<_> = results.iter().map(|x| x.1).collect();
        calculate_avg_std(&req_throughput_seq, &"REQ_throughput");
        calculate_avg_std(&txn_throughput_seq, &"TXN_throughput");
    }
}
<commit_msg>[libratest] Fix launch_swarm in throughput test.<commit_after>// Copyright (c) The Libra Core Contributors
// SPDX-License-Identifier: Apache-2.0

use benchmark::{
    bin_utils::{create_ac_clients, measure_throughput},
    ruben_opt::parse_swarm_config_from_dir,
    txn_generator::PairwiseTransferTxnGenerator,
    Benchmarker,
};
use libra_swarm::swarm::LibraSwarm;
use num::traits::Float;
use rusty_fork::{rusty_fork_id, rusty_fork_test, rusty_fork_test_name};
use statistical::{mean, population_standard_deviation};
use std::fmt::Display;

fn calculate_avg_std<T: Float + Display>(sequence: &[T], name: &str) {
    // Output json-formatted result.
    println!(
        "{{\"{}_mean\": {:.2}, \"{}_stdev\": {:.2}}}",
        name,
        mean(sequence),
        name,
        population_standard_deviation(sequence, None),
    );
}

rusty_fork_test! {
    #[test]
    fn test_throughput() {
        // Choose parameters that is able to run on not-too-powerful local machines,
        // but still generates enough TXNs for testing (2K TXNs per epoch).
        // At submit rate 50 TXNs per second per client, submission takes around 10 seconds.
        let (num_nodes, num_accounts, num_clients) = (4, 32, 4);
        let (num_rounds, num_epochs, stagger_ms) = (2, 4, 1);
        let submit_rate = 50;

        let (faucet_account_keypair, faucet_key_file_path, _temp_dir) =
            generate_keypair::load_faucet_key_or_create_default(None);
        let swarm = LibraSwarm::launch_swarm(
            num_nodes,
            true,   /* disable_logging */
            faucet_account_keypair,
            false,  /* tee_logs */
            None,   /* config_dir */
            None,   /* template_path */
        );
        let swarm_config_dir = String::from(swarm.dir.as_ref().unwrap().as_ref().to_str().unwrap());
        let validator_addresses = parse_swarm_config_from_dir(&swarm_config_dir).unwrap();
        let clients = create_ac_clients(num_clients, &validator_addresses);
        let mut bm = Benchmarker::new(clients, stagger_ms, submit_rate);
        let mut faucet_account = bm.load_faucet_account(&faucet_key_file_path);
        let mut pairwise_generator = PairwiseTransferTxnGenerator::new();
        let results = measure_throughput(&mut bm, &mut pairwise_generator, &mut faucet_account, num_accounts, num_rounds, num_epochs);
        let req_throughput_seq: Vec<_> = results.iter().map(|x| x.0).collect();
        let txn_throughput_seq: Vec<_> = results.iter().map(|x| x.1).collect();
        calculate_avg_std(&req_throughput_seq, &"REQ_throughput");
        calculate_avg_std(&txn_throughput_seq, &"TXN_throughput");
    }
}
<|endoftext|>