<commit_before>// Parse ANSI attr code
use curses::{attr_t, register_ansi, Window};
use regex::Regex;
use std::default::Default;
use std::iter::Enumerate;
use std::iter::Peekable;

pub struct ANSIParser {
    re: &'static Regex,
    last_attr: Option<attr_t>,
}

lazy_static! {
    static ref ANSI_RE: Regex =
        Regex::new(r"\x1B\[(?:([0-9]+;[0-9]+[Hf])|([0-9]+[ABCD])|(s|u|2J|K)|([0-9;]*m)|(=[0-9]+[hI]))").unwrap();
}

impl Default for ANSIParser {
    fn default() -> Self {
        ANSIParser {
            re: &ANSI_RE,
            last_attr: None,
        }
    }
}

#[derive(Clone, Debug)]
// named like to not clash with ANSIString from ansi_term crate
pub struct AnsiString {
    pub stripped: String,
    pub ansi_states: Vec<(usize, attr_t)>,
}

impl AnsiString {

    pub fn new_empty() -> AnsiString {
        AnsiString {
            stripped: "".to_string(),
            ansi_states: Vec::new(),
        }
    }

    pub fn into_inner(self) -> String {
        self.stripped
    }

    pub fn print(&self, curses: &mut Window) {
        for (c, attrs) in self.iter() {
            for (_, a) in attrs {
                curses.attr_on(*a)
            }
            curses.addch(c);
        }
    }

    pub fn iter<'a>(&'a self) -> AnsiStringIterator<'a> {
        AnsiStringIterator {
            ansi_states: &self.ansi_states,
            it_text: Box::new(self.stripped.chars().enumerate()),
            pk_ansi_states: self.ansi_states.iter().enumerate().peekable(),
        }
    }

    pub fn has_attrs(&self) -> bool {
        self.ansi_states.len() != 0
    }
}

pub struct AnsiStringIterator<'a> {
    ansi_states: &'a Vec<(usize, attr_t)>,
    it_text: Box<Enumerate<std::str::Chars<'a>>>,
    pk_ansi_states: Peekable<Enumerate<std::slice::Iter<'a, (usize, attr_t)>>>,
}

impl<'a> Iterator for AnsiStringIterator<'a> {
    type Item = (char, &'a [(usize, attr_t)]);

    fn next(&mut self) -> Option<Self::Item> {
        let mut as_range: Option<(usize, usize)> = None;
        let (ch_idx, ch) = match self.it_text.next() {
            Some((ch_idx, ch)) => (ch_idx, ch),
            None => {
                return None;
            }
        };

        while let Some(&(states_idx, &(ansi_idx, _))) = self.pk_ansi_states.peek() {
            if ch_idx == ansi_idx {
                let _ = self.pk_ansi_states.next();
                as_range = match as_range {
                    Some((start, end)) => Some((start, end + 1)),
                    None => Some((states_idx, states_idx)),
                }
            } else if ch_idx > ansi_idx {
                let _ = self.pk_ansi_states.next();
            } else {
                break;
            }
        }
        if let Some((start, end)) = as_range {
            return Some((ch, &self.ansi_states[start..end + 1]));
        } else {
            return Some((ch, &[]));
        }
    }
}

impl ANSIParser {
    pub fn parse_ansi(&mut self, text: &str) -> AnsiString {
        let mut strip_string = String::new();
        let mut colors = Vec::new();

        // assume parse_ansi is called linewise.
        // Because ANSI color code can affect text of next lines. We will save the last attribute and
        // add it to the newest line if no new color is specified.
        match self.re.find(text) {
            Some(mat) if mat.start() == 0 => {}
            Some(_) | None => {
                self.last_attr.map(|attr| {
                    colors.push((0, attr));
                });
            }
        }

        let mut num_chars = 0;
        let mut last = 0;
        for mat in self.re.find_iter(text) {
            let (start, end) = (mat.start(), mat.end());
            strip_string.push_str(&text[last..start]);
            num_chars += (&text[last..start]).chars().count();

            last = end;

            let attr = self.interpret_code(&text[start..end]);
            attr.map(|attr| {
                colors.push((num_chars, attr));
            });
            self.last_attr = attr;
        }

        strip_string.push_str(&text[last..text.len()]);

        AnsiString {
            stripped: strip_string,
            ansi_states: colors,
        }
    }

    fn interpret_code(&self, code: &str) -> Option<attr_t> {
        if code == "\x1B[K" || code == "\x1B[2J" {
            // clear screen & clear line
            None
        } else {
            let key = register_ansi(code.to_owned());
            Some(key)
        }

        //let mut state256 = 0;
        //let mut attr = 0;
        //let mut fg = -1;
        //let mut bg = -1;
        //let mut use_fg = true;

        //let code = &code[2..code.len()-1]; // ^[[1;30;40m -> 1;30;40
        //if code.is_empty() {
        //return Some(A_NORMAL());
        //}

        //for num in code.split(';').map(|x| x.parse::<i16>()) {
        //match state256 {
        //0 => {
        //match num.unwrap_or(0) {
        //0 => {attr = 0;}
        //1 => {attr |= A_BOLD();}
        //4 => {attr |= A_UNDERLINE();}
        //5 => {attr |= A_BLINK();}
        //7 => {attr |= A_REVERSE();}
        //8 => {attr |= A_INVIS();}
        //38 => {
        //use_fg = true;
        //state256 += 1;
        //}
        //48 => {
        //use_fg = false;
        //state256 += 1;
        //}
        //39 => {
        //fg = -1;
        //}
        //49 => {
        //bg = -1;
        //}
        //num if num >= 30 && num <= 37 => {
        //fg = num - 30;
        //}
        //num if num >= 40 && num <= 47 => {
        //bg = num - 40;
        //}
        //_ => {
        //}
        //}
        //}
        //1 => {
        //match num.unwrap_or(0) {
        //5 => { state256 += 1; }
        //_ => { state256 = 0; }
        //}
        //}
        //2 => {
        //if use_fg {
        //fg = num.unwrap_or(-1);
        //} else {
        //bg = num.unwrap_or(-1);
        //}
        //}
        //_ => {}
        //}
        //}

        //if fg != -1 || bg != -1 {
        //attr |= get_color_pair(fg, bg);
        //}

        //Some(attr)
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_ansi_iterator() {
        let input = "\x1B[48;2;5;10;15m\x1B[38;2;70;130;180mhi\x1B[0m";
        let ansistring = ANSIParser::default().parse_ansi(input);
        let mut it = ansistring.iter();
        let arr: Vec<(usize, u16)> = vec![(0, 11), (0, 12)];
        assert_eq!(Some(('h', &arr[..2])), it.next());
        assert_eq!(Some(('i', &arr[..0])), it.next());
    }
}
<commit_msg>add a from_str for ansistring<commit_after>// Parse ANSI attr code
use curses::{attr_t, register_ansi, Window};
use regex::Regex;
use std::default::Default;
use std::iter::Enumerate;
use std::iter::Peekable;

pub struct ANSIParser {
    re: &'static Regex,
    last_attr: Option<attr_t>,
}

lazy_static! {
    static ref ANSI_RE: Regex =
        Regex::new(r"\x1B\[(?:([0-9]+;[0-9]+[Hf])|([0-9]+[ABCD])|(s|u|2J|K)|([0-9;]*m)|(=[0-9]+[hI]))").unwrap();
}

impl Default for ANSIParser {
    fn default() -> Self {
        ANSIParser {
            re: &ANSI_RE,
            last_attr: None,
        }
    }
}

#[derive(Clone, Debug)]
// named like to not clash with ANSIString from ansi_term crate
pub struct AnsiString {
    pub stripped: String,
    pub ansi_states: Vec<(usize, attr_t)>,
}

impl AnsiString {

    pub fn new_empty() -> AnsiString {
        AnsiString {
            stripped: "".to_string(),
            ansi_states: Vec::new(),
        }
    }

    pub fn into_inner(self) -> String {
        self.stripped
    }

    pub fn print(&self, curses: &mut Window) {
        for (c, attrs) in self.iter() {
            for (_, a) in attrs {
                curses.attr_on(*a)
            }
            curses.addch(c);
        }
    }

    pub fn iter<'a>(&'a self) -> AnsiStringIterator<'a> {
        AnsiStringIterator {
            ansi_states: &self.ansi_states,
            it_text: Box::new(self.stripped.chars().enumerate()),
            pk_ansi_states: self.ansi_states.iter().enumerate().peekable(),
        }
    }

    pub fn has_attrs(&self) -> bool {
        self.ansi_states.len() != 0
    }

    pub fn from_str(raw: &str) -> AnsiString {
        ANSIParser::default().parse_ansi(raw)
    }
}

pub struct AnsiStringIterator<'a> {
    ansi_states: &'a Vec<(usize, attr_t)>,
    it_text: Box<Enumerate<std::str::Chars<'a>>>,
    pk_ansi_states: Peekable<Enumerate<std::slice::Iter<'a, (usize, attr_t)>>>,
}

impl<'a> Iterator for AnsiStringIterator<'a> {
    type Item = (char, &'a [(usize, attr_t)]);

    fn next(&mut self) -> Option<Self::Item> {
        let mut as_range: Option<(usize, usize)> = None;
        let (ch_idx, ch) = match self.it_text.next() {
            Some((ch_idx, ch)) => (ch_idx, ch),
            None => {
                return None;
            }
        };

        while let Some(&(states_idx, &(ansi_idx, _))) = self.pk_ansi_states.peek() {
            if ch_idx == ansi_idx {
                let _ = self.pk_ansi_states.next();
                as_range = match as_range {
                    Some((start, end)) => Some((start, end + 1)),
                    None => Some((states_idx, states_idx)),
                }
            } else if ch_idx > ansi_idx {
                let _ = self.pk_ansi_states.next();
            } else {
                break;
            }
        }
        if let Some((start, end)) = as_range {
            return Some((ch, &self.ansi_states[start..end + 1]));
        } else {
            return Some((ch, &[]));
        }
    }
}

impl ANSIParser {
    pub fn parse_ansi(&mut self, text: &str) -> AnsiString {
        let mut strip_string = String::new();
        let mut colors = Vec::new();

        // assume parse_ansi is called linewise.
        // Because ANSI color code can affect text of next lines. We will save the last attribute and
        // add it to the newest line if no new color is specified.
        match self.re.find(text) {
            Some(mat) if mat.start() == 0 => {}
            Some(_) | None => {
                self.last_attr.map(|attr| {
                    colors.push((0, attr));
                });
            }
        }

        let mut num_chars = 0;
        let mut last = 0;
        for mat in self.re.find_iter(text) {
            let (start, end) = (mat.start(), mat.end());
            strip_string.push_str(&text[last..start]);
            num_chars += (&text[last..start]).chars().count();

            last = end;

            let attr = self.interpret_code(&text[start..end]);
            attr.map(|attr| {
                colors.push((num_chars, attr));
            });
            self.last_attr = attr;
        }

        strip_string.push_str(&text[last..text.len()]);

        AnsiString {
            stripped: strip_string,
            ansi_states: colors,
        }
    }

    fn interpret_code(&self, code: &str) -> Option<attr_t> {
        if code == "\x1B[K" || code == "\x1B[2J" {
            // clear screen & clear line
            None
        } else {
            let key = register_ansi(code.to_owned());
            Some(key)
        }

        //let mut state256 = 0;
        //let mut attr = 0;
        //let mut fg = -1;
        //let mut bg = -1;
        //let mut use_fg = true;

        //let code = &code[2..code.len()-1]; // ^[[1;30;40m -> 1;30;40
        //if code.is_empty() {
        //return Some(A_NORMAL());
        //}

        //for num in code.split(';').map(|x| x.parse::<i16>()) {
        //match state256 {
        //0 => {
        //match num.unwrap_or(0) {
        //0 => {attr = 0;}
        //1 => {attr |= A_BOLD();}
        //4 => {attr |= A_UNDERLINE();}
        //5 => {attr |= A_BLINK();}
        //7 => {attr |= A_REVERSE();}
        //8 => {attr |= A_INVIS();}
        //38 => {
        //use_fg = true;
        //state256 += 1;
        //}
        //48 => {
        //use_fg = false;
        //state256 += 1;
        //}
        //39 => {
        //fg = -1;
        //}
        //49 => {
        //bg = -1;
        //}
        //num if num >= 30 && num <= 37 => {
        //fg = num - 30;
        //}
        //num if num >= 40 && num <= 47 => {
        //bg = num - 40;
        //}
        //_ => {
        //}
        //}
        //}
        //1 => {
        //match num.unwrap_or(0) {
        //5 => { state256 += 1; }
        //_ => { state256 = 0; }
        //}
        //}
        //2 => {
        //if use_fg {
        //fg = num.unwrap_or(-1);
        //} else {
        //bg = num.unwrap_or(-1);
        //}
        //}
        //_ => {}
        //}
        //}

        //if fg != -1 || bg != -1 {
        //attr |= get_color_pair(fg, bg);
        //}

        //Some(attr)
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_ansi_iterator() {
        let input = "\x1B[48;2;5;10;15m\x1B[38;2;70;130;180mhi\x1B[0m";
        let ansistring = ANSIParser::default().parse_ansi(input);
        let mut it = ansistring.iter();
        let arr: Vec<(usize, u16)> = vec![(0, 11), (0, 12)];
        assert_eq!(Some(('h', &arr[..2])), it.next());
        assert_eq!(Some(('i', &arr[..0])), it.next());
    }
}
<|endoftext|>


<commit_before>use std::cmp;
use std::ops;
use std::num;
use std::process;

use clap;
use app;
use num_cpus;
use env_logger;
use log;

use std::path::{Path, PathBuf};
use std::result::Result;
use super::check::InfoLevel;

/// `Args` are transformed/normalized from `ArgMatches`.
#[derive(Debug)]
pub struct Args {
    path: PathBuf,
    endings: Vec<String>,
    clean: bool,
    config_file: Option<PathBuf>,
    line_length: Option<usize>,
    color: bool,
    threads: usize,
    quiet: bool,
    status: bool,
    tabs: bool,
    info_level: InfoLevel,
}

impl Args {
    /// Parse the command line arguments for this process.
    ///
    /// If a CLI usage error occurred, then exit the process and print a usage
    /// or error message. Similarly, if the user requested the version of
    /// enforcer, then print the version and exit.
    ///
    /// Also, initialize a global logger.
    pub fn parse() -> Result<Args, num::ParseIntError> {
        let matches = app::app().get_matches();
        if matches.is_present("help") {
            let _ = ::app::app().print_help();
            println!("");
            process::exit(0);
        }
        if matches.is_present("version") {
            println!("enforcer {}", crate_version!());
            process::exit(0);
        }
        let mut logb = env_logger::LogBuilder::new();
        if matches.is_present("debug") {
            logb.filter(None, log::LogLevelFilter::Debug);
        } else {
            logb.filter(None, log::LogLevelFilter::Warn);
        }
        if let Err(err) = logb.init() {
            println!("failed to initialize logger: {}", err);
        }
        ArgMatches(matches).to_args()
    }

    /// Whether enforcer should be quiet or not.
    pub fn quiet(&self) -> bool {
        self.quiet
    }
    /// Return the path that should be searched.
    pub fn path(&self) -> &PathBuf {
        &self.path
    }
    pub fn clean(&self) -> bool {
        self.clean
    }
    pub fn status(&self) -> bool {
        self.status
    }
    pub fn tabs(&self) -> bool {
        self.tabs
    }
    pub fn config_file(&self) -> &Option<PathBuf> {
        &self.config_file
    }

    /// Returns true if and only if enforcer should color its output.
    pub fn color(&self) -> bool {
        self.color
    }

    /// Return the endings that should be searched.
    pub fn endings(&self) -> &[String] {
        &self.endings
    }

    pub fn threads(&self) -> usize {
        self.threads
    }

    pub fn line_length(&self) -> Option<usize> {
        self.line_length
    }

    pub fn info_level(&self) -> InfoLevel {
        self.info_level.clone()
    }
}

/// `ArgMatches` wraps `clap::ArgMatches` and provides semantic meaning to
/// several options/flags.
struct ArgMatches<'a>(clap::ArgMatches<'a>);

impl<'a> ops::Deref for ArgMatches<'a> {
    type Target = clap::ArgMatches<'a>;
    fn deref(&self) -> &clap::ArgMatches<'a> {
        &self.0
    }
}

impl<'a> ArgMatches<'a> {
    /// Convert the result of parsing CLI arguments into enforcer's
    /// configuration.
    fn to_args(&self) -> Result<Args, num::ParseIntError> {
        let path = self.path();
        let endings = self.endings();
        let config = self.config_path();
        let quiet = self.is_present("quiet");
        let args = Args {
            path: path,
            endings: endings,
            clean: self.is_present("clean"),
            config_file: config,
            line_length: self.usize_of("L")?,
            color: self.is_present("color"),
            quiet: quiet,
            threads: self.threads()?,
            status: self.is_present("status"),
            tabs: self.is_present("tabs"),
            info_level: self.info_level(),
        };
        Ok(args)
    }

    /// Return all file endings that enforcer should search.
    fn endings(&self) -> Vec<String> {
        let endings: Vec<String> = match self.values_of_lossy("endings") {
            None => vec![],
            Some(vals) => vals,
        };
        endings
    }

    /// Return file path that enforcer should search.
    fn path(&self) -> PathBuf {
        match self.value_of_os("path") {
            None => self.default_path(),
            Some(val) => Path::new(val).to_path_buf(),
        }
    }

    /// Return path to config file.
    fn info_level(&self) -> InfoLevel {
        match self.occurrences_of("info_level") {
            0 => { InfoLevel::Quiet },
            1 => { InfoLevel::Normal },
            2 | _ => { InfoLevel::Verbose },
        }
    }

    /// Return path to config file.
    fn config_path(&self) -> Option<PathBuf> {
        match self.value_of_os("config-path") {
            None => None,
            Some(val) => Some(Path::new(val).to_path_buf()),
        }
    }

    /// Return the default path that enforcer should search.
    fn default_path(&self) -> PathBuf {
        Path::new("./").to_path_buf()
    }

    /// Returns the approximate number of threads that enforcer should use.
    fn threads(&self) -> Result<usize, num::ParseIntError> {
        let threads = self.usize_of("N")?.unwrap_or(0);
        Ok(if threads == 0 {
            cmp::min(12, num_cpus::get())
        } else {
            threads
        })
    }

    /// Safely reads an arg value with the given name, and if it's present,
    /// tries to parse it as a usize value.
    fn usize_of(&self, name: &str) -> Result<Option<usize>, num::ParseIntError> {
        match self.0.value_of_lossy(name) {
            None => Ok(None),
            Some(v) => v.parse().map(Some).map_err(From::from),
        }
    }
}
<commit_msg>fix for verbosity level<commit_after>use std::cmp;
use std::ops;
use std::num;
use std::process;

use clap;
use app;
use num_cpus;
use env_logger;
use log;

use std::path::{Path, PathBuf};
use std::result::Result;
use super::check::InfoLevel;

/// `Args` are transformed/normalized from `ArgMatches`.
#[derive(Debug)]
pub struct Args {
    path: PathBuf,
    endings: Vec<String>,
    clean: bool,
    config_file: Option<PathBuf>,
    line_length: Option<usize>,
    color: bool,
    threads: usize,
    quiet: bool,
    status: bool,
    tabs: bool,
    info_level: InfoLevel,
}

impl Args {
    /// Parse the command line arguments for this process.
    ///
    /// If a CLI usage error occurred, then exit the process and print a usage
    /// or error message. Similarly, if the user requested the version of
    /// enforcer, then print the version and exit.
    ///
    /// Also, initialize a global logger.
    pub fn parse() -> Result<Args, num::ParseIntError> {
        let matches = app::app().get_matches();
        if matches.is_present("help") {
            let _ = ::app::app().print_help();
            println!("");
            process::exit(0);
        }
        if matches.is_present("version") {
            println!("enforcer {}", crate_version!());
            process::exit(0);
        }
        let mut logb = env_logger::LogBuilder::new();
        if matches.is_present("debug") {
            logb.filter(None, log::LogLevelFilter::Debug);
        } else {
            logb.filter(None, log::LogLevelFilter::Warn);
        }
        if let Err(err) = logb.init() {
            println!("failed to initialize logger: {}", err);
        }
        ArgMatches(matches).to_args()
    }

    /// Whether enforcer should be quiet or not.
    pub fn quiet(&self) -> bool {
        self.quiet
    }
    /// Return the path that should be searched.
    pub fn path(&self) -> &PathBuf {
        &self.path
    }
    pub fn clean(&self) -> bool {
        self.clean
    }
    pub fn status(&self) -> bool {
        self.status
    }
    pub fn tabs(&self) -> bool {
        self.tabs
    }
    pub fn config_file(&self) -> &Option<PathBuf> {
        &self.config_file
    }

    /// Returns true if and only if enforcer should color its output.
    pub fn color(&self) -> bool {
        self.color
    }

    /// Return the endings that should be searched.
    pub fn endings(&self) -> &[String] {
        &self.endings
    }

    pub fn threads(&self) -> usize {
        self.threads
    }

    pub fn line_length(&self) -> Option<usize> {
        self.line_length
    }

    pub fn info_level(&self) -> InfoLevel {
        self.info_level.clone()
    }
}

/// `ArgMatches` wraps `clap::ArgMatches` and provides semantic meaning to
/// several options/flags.
struct ArgMatches<'a>(clap::ArgMatches<'a>);

impl<'a> ops::Deref for ArgMatches<'a> {
    type Target = clap::ArgMatches<'a>;
    fn deref(&self) -> &clap::ArgMatches<'a> {
        &self.0
    }
}

impl<'a> ArgMatches<'a> {
    /// Convert the result of parsing CLI arguments into enforcer's
    /// configuration.
    fn to_args(&self) -> Result<Args, num::ParseIntError> {
        let path = self.path();
        let endings = self.endings();
        let config = self.config_path();
        let quiet = self.is_present("quiet");
        let args = Args {
            path: path,
            endings: endings,
            clean: self.is_present("clean"),
            config_file: config,
            line_length: self.usize_of("L")?,
            color: self.is_present("color"),
            quiet: quiet,
            threads: self.threads()?,
            status: self.is_present("status"),
            tabs: self.is_present("tabs"),
            info_level: self.info_level(),
        };
        Ok(args)
    }

    /// Return all file endings that enforcer should search.
    fn endings(&self) -> Vec<String> {
        let endings: Vec<String> = match self.values_of_lossy("endings") {
            None => vec![],
            Some(vals) => vals,
        };
        endings
    }

    /// Return file path that enforcer should search.
    fn path(&self) -> PathBuf {
        match self.value_of_os("path") {
            None => self.default_path(),
            Some(val) => Path::new(val).to_path_buf(),
        }
    }

    /// Return path to config file.
    fn info_level(&self) -> InfoLevel {
        match self.occurrences_of("verbose") {
            0 => InfoLevel::Quiet,
            1 => InfoLevel::Normal,
            2 | _ => InfoLevel::Verbose,
        }
    }

    /// Return path to config file.
    fn config_path(&self) -> Option<PathBuf> {
        match self.value_of_os("config-path") {
            None => None,
            Some(val) => Some(Path::new(val).to_path_buf()),
        }
    }

    /// Return the default path that enforcer should search.
    fn default_path(&self) -> PathBuf {
        Path::new("./").to_path_buf()
    }

    /// Returns the approximate number of threads that enforcer should use.
    fn threads(&self) -> Result<usize, num::ParseIntError> {
        let threads = self.usize_of("N")?.unwrap_or(0);
        Ok(if threads == 0 {
            cmp::min(12, num_cpus::get())
        } else {
            threads
        })
    }

    /// Safely reads an arg value with the given name, and if it's present,
    /// tries to parse it as a usize value.
    fn usize_of(&self, name: &str) -> Result<Option<usize>, num::ParseIntError> {
        match self.0.value_of_lossy(name) {
            None => Ok(None),
            Some(v) => v.parse().map(Some).map_err(From::from),
        }
    }
}
<|endoftext|>


<commit_before>use std::iter;
use super::stacks_and_queues::bag::{Bag, Iter};

#[derive(Clone, Debug)]
pub struct Graph {
    v: usize,
    e: usize,
    adj: Vec<Bag<usize>>
}

impl Graph {
    pub fn new(v: usize) -> Graph {
        Graph {
            v: v,
            e: 0,
            adj: iter::repeat(Bag::<usize>::new()).take(v).collect()
        }
    }

    fn validate_vertex(&self, v: usize) {
        assert!(v < self.v, "vertex is not between 0 and {}", self.v - 1)
    }

    pub fn vertices(&self) -> usize {
        self.v
    }

    pub fn edges(&self) -> usize {
        self.e
    }

    pub fn add_edge(&mut self, v: usize, w: usize) {
        self.validate_vertex(v);
        self.validate_vertex(w);

        self.e += 1;
        self.adj[v].add(w);
        self.adj[w].add(v);
    }

    // FIXME: should this be a global function
    pub fn degree(&self, v: usize) -> usize {
        self.validate_vertex(v);
        self.adj[v].len()
    }

    pub fn max_degree(&self) -> usize {
        (0 .. self.vertices()).map(|v| self.degree(v)).max().unwrap_or(0)
    }

    pub fn average_degree(&self) -> f64 {
        // (0 .. self.vertices()) .map(|v| self.degree(v)).sum::<usize>() as f64 / self.vertices() as f64
        2.0 * self.edges() as f64 / self.vertices() as f64
    }

    pub fn number_of_self_loops(&self) -> usize {
        let mut count = 0;
        for v in 0 .. self.vertices() {
            for w in self.adj(v) {
                if v == *w {
                    count += 1;
                }
            }
        }
        count / 2
    }

    pub fn to_dot(&self) -> String {
        let mut dot = String::new();

        dot.push_str("graph G {\n");
        for i in 0 .. self.v {
            dot.push_str(&format!("  {};\n", i));
        }

        for (v, adj) in self.adj.iter().enumerate() {
            for w in adj.iter() {
                dot.push_str(&format!("  {} -- {};\n", v, w));
            }
        }
        dot.push_str("}\n");
        dot
    }

    pub fn adj(&self, v: usize) -> Iter<usize> {
        self.adj[v].iter()
    }

    pub fn dfs<'a>(&'a self, s: usize) -> DepthFirstPaths<'a> {
        DepthFirstPaths {
            graph: self,
            marked: Vec::new(),
            edge_to: Vec::new(),
            s: s
        }
    }
}

pub struct DepthFirstPaths<'a> {
    graph: &'a Graph,
    marked: Vec<bool>,
    edge_to: Vec<usize>,
    s: usize
}

#[test]
fn test_graph_visit() {
    let mut g = Graph::new(13);
    g.add_edge(0, 1);
    g.add_edge(0, 2);
    g.add_edge(0, 6);
    g.add_edge(0, 5);
    g.add_edge(5, 3);
    g.add_edge(5, 4);
    g.add_edge(3, 4);
    g.add_edge(4, 6);

    g.add_edge(7, 8);

    g.add_edge(9, 10);
    g.add_edge(9, 11);
    g.add_edge(9, 12);
    g.add_edge(11, 12);

}

#[test]
fn test_graph() {
    let mut g = Graph::new(10);
    g.add_edge(0, 3);
    g.add_edge(0, 5);
    g.add_edge(4, 5);
    g.add_edge(2, 9);
    g.add_edge(2, 8);
    g.add_edge(3, 7);

    g.add_edge(1, 6);
    g.add_edge(6, 9);
    g.add_edge(5, 8);

    // println!("got => \n{}", g.to_dot());

    assert_eq!(10, g.vertices());
    assert_eq!(9, g.edges());
    assert_eq!(3, g.degree(5));

    for w in g.adj(5) {
        assert!(vec![8, 4, 0].contains(w));
    }

    assert_eq!(g.max_degree(), 3);
    assert!(g.average_degree() < 2.0);
    assert_eq!(g.number_of_self_loops(), 0);
}
<commit_msg>undirected_graphs: impl depth first search for Graph<commit_after>use std::iter;
use super::stacks_and_queues::bag::{Bag, Iter};
use super::stacks_and_queues::Stack;
use super::stacks_and_queues::linked_stack;

#[derive(Clone, Debug)]
pub struct Graph {
    v: usize,
    e: usize,
    adj: Vec<Bag<usize>>
}

impl Graph {
    pub fn new(v: usize) -> Graph {
        Graph {
            v: v,
            e: 0,
            adj: iter::repeat(Bag::<usize>::new()).take(v).collect()
        }
    }

    fn validate_vertex(&self, v: usize) {
        assert!(v < self.v, "vertex is not between 0 and {}", self.v - 1)
    }

    pub fn vertices(&self) -> usize {
        self.v
    }

    pub fn edges(&self) -> usize {
        self.e
    }

    pub fn add_edge(&mut self, v: usize, w: usize) {
        self.validate_vertex(v);
        self.validate_vertex(w);

        self.e += 1;
        self.adj[v].add(w);
        self.adj[w].add(v);
    }

    // FIXME: should this be a global function
    pub fn degree(&self, v: usize) -> usize {
        self.validate_vertex(v);
        self.adj[v].len()
    }

    pub fn max_degree(&self) -> usize {
        (0 .. self.vertices()).map(|v| self.degree(v)).max().unwrap_or(0)
    }

    pub fn average_degree(&self) -> f64 {
        // (0 .. self.vertices()) .map(|v| self.degree(v)).sum::<usize>() as f64 / self.vertices() as f64
        2.0 * self.edges() as f64 / self.vertices() as f64
    }

    pub fn number_of_self_loops(&self) -> usize {
        let mut count = 0;
        for v in 0 .. self.vertices() {
            for w in self.adj(v) {
                if v == *w {
                    count += 1;
                }
            }
        }
        count / 2
    }

    pub fn to_dot(&self) -> String {
        let mut dot = String::new();

        dot.push_str("graph G {\n");
        for i in 0 .. self.v {
            dot.push_str(&format!("  {};\n", i));
        }

        for (v, adj) in self.adj.iter().enumerate() {
            for w in adj.iter() {
                dot.push_str(&format!("  {} -- {};\n", v, w));
            }
        }
        dot.push_str("}\n");
        dot
    }

    pub fn adj(&self, v: usize) -> Iter<usize> {
        self.adj[v].iter()
    }

    pub fn dfs<'a>(&'a self, s: usize) -> DepthFirstPaths<'a> {
        let marked = iter::repeat(false).take(self.vertices()).collect();
        let edge_to = iter::repeat(None).take(self.vertices()).collect();
        let mut path = DepthFirstPaths {
            graph: self,
            marked: marked,
            edge_to: edge_to,
            s: s
        };
        let s = path.s.clone();

        path.dfs(s);
        path
    }
}

pub struct DepthFirstPaths<'a> {
    graph: &'a Graph,
    marked: Vec<bool>,
    edge_to: Vec<Option<usize>>,
    s: usize
}

impl<'a> DepthFirstPaths<'a> {
    pub fn dfs(&mut self, v: usize) {
        self.marked[v] = true;
        for w in self.graph.adj(v) {
            if !self.marked[*w] {
                self.dfs(*w);
                self.edge_to[*w] = Some(v);
            }
        }
    }

    pub fn has_path_to(&self, v: usize) -> bool {
        self.marked[v]
    }

    pub fn path_to(&self, v: usize) -> Option<Vec<usize>> {
        if !self.has_path_to(v) {
            None
        } else {
            let mut path = linked_stack::LinkedStack::new();
            let mut x = v;
            while x != self.s {
                path.push(x);
                x = self.edge_to[x].unwrap();
            }
            path.push(self.s);
            Some(path.into_iter().collect())
        }
    }
}

#[test]
fn test_graph_visit() {
    let mut g = Graph::new(13);
    g.add_edge(0, 1);
    g.add_edge(0, 2);
    g.add_edge(0, 6);
    g.add_edge(0, 5);
    g.add_edge(5, 3);
    g.add_edge(5, 4);
    g.add_edge(3, 4);
    g.add_edge(4, 6);

    g.add_edge(7, 8);

    g.add_edge(9, 10);
    g.add_edge(9, 11);
    g.add_edge(9, 12);
    g.add_edge(11, 12);

    println!("dot => \n {}", g.to_dot());
    let path = g.dfs(0);
    println!("got path=> {:?}", path.edge_to);
    println!("path to 3 => {:?}", path.path_to(3));

}

#[test]
fn test_graph() {
    let mut g = Graph::new(10);
    g.add_edge(0, 3);
    g.add_edge(0, 5);
    g.add_edge(4, 5);
    g.add_edge(2, 9);
    g.add_edge(2, 8);
    g.add_edge(3, 7);

    g.add_edge(1, 6);
    g.add_edge(6, 9);
    g.add_edge(5, 8);

    // println!("got => \n{}", g.to_dot());

    assert_eq!(10, g.vertices());
    assert_eq!(9, g.edges());
    assert_eq!(3, g.degree(5));

    for w in g.adj(5) {
        assert!(vec![8, 4, 0].contains(w));
    }

    assert_eq!(g.max_degree(), 3);
    assert!(g.average_degree() < 2.0);
    assert_eq!(g.number_of_self_loops(), 0);
}
<|endoftext|>


<commit_before>// task/mod.rs
// AltOSRust
//
// Created by Daniel Seitz on 11/30/16

pub mod list;

use volatile::Volatile;
use system_control;
use self::list::{Queue, Queuable};
use alloc::boxed::Box;
use collections::Vec;
use sync::Mutex;

const VALID_TASK: usize = 0xBADB0100;
const INVALID_TASK: usize = 0x0;

#[no_mangle]
pub static mut CURRENT_TASK: Option<Box<TaskControl>> = None;

// TODO: Wrap task_list in a mutex lock to provide safe access
static mut TASK_LIST: Queue<TaskControl> = Queue::new();
static mut SLEEP_LIST: Queue<TaskControl> = Queue::new();

pub struct TaskHandle(*const TaskControl);

impl TaskHandle {
  fn new(task: *const TaskControl) -> Self {
    TaskHandle(task)
  }
}

#[derive(Copy, Clone)]
pub enum Priority {
  Critical,
  Low,
}

#[derive(Copy, Clone, PartialEq)]
enum State {
  Ready,
  Running,
  Blocked,
  Suspended,
  Embryo,
}

/// Create a new task and put it into the task queue for running. The stack depth is how many bytes
/// should be allocated for the stack, if there is not enough space to allocate the stack the
/// kernel will panic with an out of memory (oom) error.
pub fn new_task(code: fn(), stack_depth: usize, priority: Priority, name: &'static str) -> TaskHandle {
  let mut task = Box::new(TaskControl::new(stack_depth, name));
  task.initialize(code, priority);
  let handle = TaskHandle::new(&*task);

  unsafe { TASK_LIST.enqueue(task); }
  handle
}

#[repr(C)]
#[derive(Clone)]
pub struct TaskControl {
  stack: usize, /* stack pointer MUST be first field */
  stack_base: usize,
  stack_depth: usize,
  state: State,
  tid: usize,
  priority: Priority,
  name: &'static str,
  valid: usize,
  wchan: usize,
  next: Option<Box<TaskControl>>,
}

impl TaskControl {
  fn new(depth: usize, name: &'static str) -> Self {
    let stack_mem: Vec<u8> = Vec::with_capacity(depth);
    let stack = stack_mem.as_ptr() as usize;
    // Don't free the heap space
    ::core::mem::forget(stack_mem);
    TaskControl {
      stack: stack + depth,
      stack_base: stack,
      stack_depth: depth,
      state: State::Embryo,
      tid: !0,
      priority: Priority::Critical,
      name: name,
      valid: VALID_TASK,
      wchan: 0,
      next: None,
    }
  }

  const fn uninitialized(name: &'static str) -> Self {
    TaskControl {
      stack: 0,
      stack_base: 0,
      stack_depth: 0,
      state: State::Embryo,
      tid: !0,
      priority: Priority::Low,
      name: name,
      valid: INVALID_TASK,
      wchan: 0,
      next: None,
    }
  }

  /// This initializes the task's stack. This method MUST only be called once, calling it more than
  /// once could at best waste some stack space and at worst corrupt an active stack.
  fn initialize(&mut self, code: fn(), priority: Priority) {
    const INITIAL_XPSR: usize = 0x0100_0000;
    unsafe {
      let mut stack_mut = Volatile::new(self.stack as *const usize);
      // Offset added to account for way MCU uses stack on entry/exit of interrupts
      stack_mut -= 4;
      stack_mut.store(INITIAL_XPSR); /* xPSR */
      stack_mut -= 4;
      stack_mut.store(code as usize); /* PC */
      stack_mut -= 4;
      stack_mut.store(exit_error as usize); /* LR */
      stack_mut -= 20; /* R12, R3, R2, R1 */
      // *stack_mut = params; /* R0 */
      stack_mut -= 32; /* R11..R4 */
      self.stack = stack_mut.as_ptr() as usize;
    }
    self.state = State::Ready;
    self.priority = priority;
    self.tid = tid::fetch_next_tid();
  }

  /// Check if the stack has gone past its bounds
  fn is_stack_overflowed(&self) -> bool {
    // TODO: Add some stack guard bytes to check if we've overflowed during execution?
    //  This would add some extra overhead, maybe have some #[cfg] that determines if we should add
    //  this extra security?
    self.stack <= self.stack_base
  }
}

impl Queuable for TaskControl {
  fn take_next(&mut self) -> Option<Box<Self>> {
    self.next.take()
  }
  fn set_next(&mut self, next: Option<Box<Self>>) {
    self.next = next;
  }
}

/// Select a new task to run and switch its context, this function MUST only be called from the
/// PendSV handler, calling it from elsewhere could lead to undefined behavior. It must be exposed
/// publicly so that the compiler doesn't optimize it away when compiling for release.
#[no_mangle]
pub unsafe fn switch_context() {
  match CURRENT_TASK.take() {
    Some(running) => {
      if running.is_stack_overflowed() {
        ::arm::bkpt();
      }
      loop {
        if let Some(new_task) = TASK_LIST.dequeue() {
          if running.state == State::Blocked {
            SLEEP_LIST.enqueue(running);
          }
          else {
            TASK_LIST.enqueue(running);
          }
          CURRENT_TASK = Some(new_task);
          break;
        }
        else {
          // Go to next priority queue
          // If all queues are empty, reschedule current task
          CURRENT_TASK = Some(running);
          break;
        }
      }
    },
    None => panic!("switch_context - current task doesn't exist!"),
  }
}

/// Start running the first task in the queue
pub fn start_first_task() {
  unsafe {
    CURRENT_TASK = TASK_LIST.dequeue();
    if CURRENT_TASK.is_none() {
      panic!("start_first_task - tried to start running tasks when no tasks have been created!");
    }
    #[cfg(target_arch="arm")]
    asm!(
      concat!(
          "ldr r2, current_task_const_2\n", /* get location of current_task */
          "ldr r3, [r2]\n",
          "ldr r0, [r3]\n",

          "adds r0, #32\n", /* discard everything up to r0 */
          "msr psp, r0\n", /* this is the new top of stack to use for the task */

          "movs r0, #2\n", /* switch to the psp stack */
          "msr CONTROL, r0\n", /* we're using psp instead of msp now */

          "isb\n", /* instruction barrier */

          "pop {r0-r5}\n", /* pop the registers that are saved automatically */
          "mov lr, r5\n", /* lr is now in r5, so put it back where it belongs */
          "pop {r3}\n", /* pop return address (old pc) into r3 */
          "pop {r2}\n", /* pop and discard xPSR */
          "cpsie i\n", /* first task has its context, so interrupts can be enabled */
          "bx r3\n", /* start executing user code */

           ".align 4\n",
          "current_task_const_2: .word CURRENT_TASK\n")
      : /* no outputs */
      : /* no inputs */
      : /* no clobbers */
      : "volatile");
  }
}

fn exit_error() -> ! {
  unsafe {
    ::arm::bkpt();
    loop{}
  }
}

/// Yield the current task to the scheduler so another task can run.
pub fn yield_task() {
  let scb = system_control::scb();
  scb.set_pend_sv();
}

pub fn sleep(wchan: usize) {
  unsafe {
    if let Some(current) = CURRENT_TASK.as_mut() {
      current.wchan = wchan;
      current.state = State::Blocked;
    }
    else {
      panic!("sleep_on - current task doesn't exist!");
    }
  }
  yield_task();
}

pub fn wake(wchan: usize) {
  unsafe {
    let mut to_wake: Queue<TaskControl> = SLEEP_LIST.remove(|task| task.wchan == wchan);
    to_wake.modify_all(|task| { task.wchan = 0; task.state = State::Ready; });
    TASK_LIST.append(to_wake);
  }
}

mod tid {
  use atomic::Atomic;

  static CURRENT_TID: Atomic<usize> = Atomic::new(0);

  /// Atomically increment the task id and return the old value
  pub fn fetch_next_tid() -> usize {
    CURRENT_TID.fetch_add(1)
  }
}
<commit_msg>move task functions into imp module<commit_after>// task/mod.rs
// AltOSRust
//
// Created by Daniel Seitz on 11/30/16

pub mod list;

use volatile::Volatile;
use system_control;
use self::list::{Queue, Queuable};
use alloc::boxed::Box;
use collections::Vec;
use sync::Mutex;
pub use self::imp::*;

const VALID_TASK: usize = 0xBADB0100;
const INVALID_TASK: usize = 0x0;

#[no_mangle]
pub static mut CURRENT_TASK: Option<Box<TaskControl>> = None;

// TODO: Wrap task_list in a mutex lock to provide safe access
static mut TASK_LIST: Queue<TaskControl> = Queue::new();
static mut SLEEP_LIST: Queue<TaskControl> = Queue::new();

pub struct TaskHandle(*const TaskControl);

impl TaskHandle {
  fn new(task: *const TaskControl) -> Self {
    TaskHandle(task)
  }
}

#[derive(Copy, Clone)]
pub enum Priority {
  Critical,
  Low,
}

#[derive(Copy, Clone, PartialEq)]
enum State {
  Ready,
  Running,
  Blocked,
  Suspended,
  Embryo,
}

#[repr(C)]
#[derive(Clone)]
pub struct TaskControl {
  stack: usize, /* stack pointer MUST be first field */
  stack_base: usize,
  stack_depth: usize,
  state: State,
  tid: usize,
  priority: Priority,
  name: &'static str,
  valid: usize,
  wchan: usize,
  next: Option<Box<TaskControl>>,
}

impl TaskControl {
  fn new(depth: usize, name: &'static str) -> Self {
    let stack_mem: Vec<u8> = Vec::with_capacity(depth);
    let stack = stack_mem.as_ptr() as usize;
    // Don't free the heap space
    ::core::mem::forget(stack_mem);
    TaskControl {
      stack: stack + depth,
      stack_base: stack,
      stack_depth: depth,
      state: State::Embryo,
      tid: !0,
      priority: Priority::Critical,
      name: name,
      valid: VALID_TASK,
      wchan: 0,
      next: None,
    }
  }

  const fn uninitialized(name: &'static str) -> Self {
    TaskControl {
      stack: 0,
      stack_base: 0,
      stack_depth: 0,
      state: State::Embryo,
      tid: !0,
      priority: Priority::Low,
      name: name,
      valid: INVALID_TASK,
      wchan: 0,
      next: None,
    }
  }

  /// This initializes the task's stack. This method MUST only be called once, calling it more than
  /// once could at best waste some stack space and at worst corrupt an active stack.
  fn initialize(&mut self, code: fn(), priority: Priority) {
    const INITIAL_XPSR: usize = 0x0100_0000;
    unsafe {
      let mut stack_mut = Volatile::new(self.stack as *const usize);
      // Offset added to account for way MCU uses stack on entry/exit of interrupts
      stack_mut -= 4;
      stack_mut.store(INITIAL_XPSR); /* xPSR */
      stack_mut -= 4;
      stack_mut.store(code as usize); /* PC */
      stack_mut -= 4;
      stack_mut.store(exit_error as usize); /* LR */
      stack_mut -= 20; /* R12, R3, R2, R1 */
      // *stack_mut = params; /* R0 */
      stack_mut -= 32; /* R11..R4 */
      self.stack = stack_mut.as_ptr() as usize;
    }
    self.state = State::Ready;
    self.priority = priority;
    self.tid = tid::fetch_next_tid();
  }

  /// Check if the stack has gone past its bounds
  fn is_stack_overflowed(&self) -> bool {
    // TODO: Add some stack guard bytes to check if we've overflowed during execution?
    //  This would add some extra overhead, maybe have some #[cfg] that determines if we should add
    //  this extra security?
    self.stack <= self.stack_base
  }
}

impl Queuable for TaskControl {
  fn take_next(&mut self) -> Option<Box<Self>> {
    self.next.take()
  }
  fn set_next(&mut self, next: Option<Box<Self>>) {
    self.next = next;
  }
}

/// Select a new task to run and switch its context, this function MUST only be called from the
/// PendSV handler, calling it from elsewhere could lead to undefined behavior. It must be exposed
/// publicly so that the compiler doesn't optimize it away when compiling for release.
#[no_mangle]
pub unsafe fn switch_context() {
  match CURRENT_TASK.take() {
    Some(running) => {
      if running.is_stack_overflowed() {
        ::arm::bkpt();
      }
      loop {
        if let Some(new_task) = TASK_LIST.dequeue() {
          if running.state == State::Blocked {
            SLEEP_LIST.enqueue(running);
          }
          else {
            TASK_LIST.enqueue(running);
          }
          CURRENT_TASK = Some(new_task);
          break;
        }
        else {
          // Go to next priority queue
          // If all queues are empty, reschedule current task
          CURRENT_TASK = Some(running);
          break;
        }
      }
    },
    None => panic!("switch_context - current task doesn't exist!"),
  }
}

fn exit_error() -> ! {
  unsafe {
    ::arm::bkpt();
    loop{}
  }
}

mod tid {
  use atomic::Atomic;

  static CURRENT_TID: Atomic<usize> = Atomic::new(0);

  /// Atomically increment the task id and return the old value
  pub fn fetch_next_tid() -> usize {
    CURRENT_TID.fetch_add(1)
  }
}

mod imp {
  use super::{State, TaskControl, TaskHandle, TASK_LIST, SLEEP_LIST, CURRENT_TASK, Priority};
  use system_control;
  use alloc::boxed::Box;
  use super::list::{Queue, Queuable};

  /// Create a new task and put it into the task queue for running. The stack depth is how many bytes
  /// should be allocated for the stack, if there is not enough space to allocate the stack the
  /// kernel will panic with an out of memory (oom) error.
  pub fn new_task(code: fn(), stack_depth: usize, priority: Priority, name: &'static str) -> TaskHandle {
    let mut task = Box::new(TaskControl::new(stack_depth, name));
    task.initialize(code, priority);
    let handle = TaskHandle::new(&*task);

    unsafe { TASK_LIST.enqueue(task); }
    handle
  }

  /// Yield the current task to the scheduler so another task can run.
  pub fn yield_task() {
    let scb = system_control::scb();
    scb.set_pend_sv();
  }

  pub fn sleep(wchan: usize) {
    unsafe {
      if let Some(current) = CURRENT_TASK.as_mut() {
        current.wchan = wchan;
        current.state = State::Blocked;
      }
      else {
        panic!("sleep_on - current task doesn't exist!");
      }
    }
    yield_task();
  }

  pub fn wake(wchan: usize) {
    unsafe {
      let mut to_wake: Queue<TaskControl> = SLEEP_LIST.remove(|task| task.wchan == wchan);
      to_wake.modify_all(|task| { task.wchan = 0; task.state = State::Ready; });
      TASK_LIST.append(to_wake);
    }
  }

  /// Start running the first task in the queue
  pub fn start_first_task() {
    unsafe {
      CURRENT_TASK = TASK_LIST.dequeue();
      if CURRENT_TASK.is_none() {
        panic!("start_first_task - tried to start running tasks when no tasks have been created!");
      }
      #[cfg(target_arch="arm")]
      asm!(
        concat!(
            "ldr r2, current_task_const_2\n", /* get location of current_task */
            "ldr r3, [r2]\n",
            "ldr r0, [r3]\n",

            "adds r0, #32\n", /* discard everything up to r0 */
            "msr psp, r0\n", /* this is the new top of stack to use for the task */

            "movs r0, #2\n", /* switch to the psp stack */
            "msr CONTROL, r0\n", /* we're using psp instead of msp now */

            "isb\n", /* instruction barrier */

            "pop {r0-r5}\n", /* pop the registers that are saved automatically */
            "mov lr, r5\n", /* lr is now in r5, so put it back where it belongs */
            "pop {r3}\n", /* pop return address (old pc) into r3 */
            "pop {r2}\n", /* pop and discard xPSR */
            "cpsie i\n", /* first task has its context, so interrupts can be enabled */
            "bx r3\n", /* start executing user code */

             ".align 4\n",
            "current_task_const_2: .word CURRENT_TASK\n")
        : /* no outputs */
        : /* no inputs */
        : /* no clobbers */
        : "volatile");
    }
  }

}
<|endoftext|>


<commit_before>// Copyright 2014 Arjan Topolovec
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#[crate_id = "tftp"];
#[license = "MIT/ASL2"];
#[crate_type = "rlib"];
#[crate_type = "dylib"];
#[allow(deprecated_owned_vector)];
//#[deny(warnings)];
#[feature(macro_rules)];

extern crate collections;
extern crate rand;

pub use common::TransferOptions;

pub mod protocol;

mod util;
mod common;
pub mod client;
<commit_msg>Fixes for latest master<commit_after>// Copyright 2014 Arjan Topolovec
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#[crate_id = "tftp"];
#[license = "MIT/ASL2"];
#[crate_type = "rlib"];
#[crate_type = "dylib"];
#[allow(deprecated_owned_vector)];
#[deny(warnings)];
#[feature(macro_rules, phase)];

extern crate collections;
extern crate rand;
#[phase(syntax, link)] extern crate log;

pub use common::TransferOptions;

pub mod protocol;

mod util;
mod common;
pub mod client;
<|endoftext|>


<commit_before>// Zinc, the bare metal stack for rust.
// Copyright 2014 Vladimir "farcaller" Pouzanov <farcaller@gmail.com>
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//! A cell that with volatile setter and getter.

use core::kinds::marker;
use core::intrinsics::{volatile_load, volatile_store};

// TODO(bharrisau) I don't know enough about markers - is it better
// to just use an Unsafe<T> here instead?
pub struct VolatileCell<T> {
  value: T,
  invariant: marker::InvariantType<T>,
}

impl<T> VolatileCell<T> {
  pub fn new(value: T) -> VolatileCell<T> {
    VolatileCell {
      value: value,
      invariant: marker::InvariantType::<T>,
    }
  }

  #[inline]
  pub fn get(&self) -> T {
    unsafe {
      volatile_load(&self.value)
    }
  }

  #[inline]
  pub fn set(&self, value: T) {
    unsafe {
      volatile_store(&self.value as *const T as *mut T, value)
    }
  }
}
<commit_msg>Document VolatileCell<commit_after>// Zinc, the bare metal stack for rust.
// Copyright 2014 Vladimir "farcaller" Pouzanov <farcaller@gmail.com>
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//! A cell that with volatile setter and getter.

use core::kinds::marker;
use core::intrinsics::{volatile_load, volatile_store};

/// This structure is used to represent a hardware register.
/// It is mostly used by `ioreg!` macro.
// TODO(bharrisau) I don't know enough about markers - is it better
// to just use an Unsafe<T> here instead?
pub struct VolatileCell<T> {
  value: T,
  invariant: marker::InvariantType<T>,
}

impl<T> VolatileCell<T> {
  /// Create a cell with initial value.
  pub fn new(value: T) -> VolatileCell<T> {
    VolatileCell {
      value: value,
      invariant: marker::InvariantType::<T>,
    }
  }

  /// Get register value.
  #[inline]
  pub fn get(&self) -> T {
    unsafe {
      volatile_load(&self.value)
    }
  }

  /// Set register value.
  #[inline]
  pub fn set(&self, value: T) {
    unsafe {
      volatile_store(&self.value as *const T as *mut T, value)
    }
  }
}
<|endoftext|>


<commit_before>extern crate ra_analysis;
extern crate ra_editor;
extern crate ra_syntax;
extern crate relative_path;
extern crate rustc_hash;
extern crate test_utils;

use std::sync::Arc;

use ra_syntax::TextRange;
use relative_path::{RelativePath, RelativePathBuf};
use rustc_hash::FxHashMap;
use test_utils::{assert_eq_dbg, extract_offset};

use ra_analysis::{
    Analysis, AnalysisHost, CrateGraph, CrateId, FileId, FileResolver, FnDescriptor,
};

#[derive(Debug)]
struct FileMap(Vec<(FileId, RelativePathBuf)>);

impl FileMap {
    fn iter<'a>(&'a self) -> impl Iterator<Item = (FileId, &'a RelativePath)> + 'a {
        self.0
            .iter()
            .map(|(id, path)| (*id, path.as_relative_path()))
    }

    fn path(&self, id: FileId) -> &RelativePath {
        self.iter().find(|&(it, _)| it == id).unwrap().1
    }
}

impl FileResolver for FileMap {
    fn file_stem(&self, id: FileId) -> String {
        self.path(id).file_stem().unwrap().to_string()
    }
    fn resolve(&self, id: FileId, rel: &RelativePath) -> Option<FileId> {
        let path = self.path(id).join(rel).normalize();
        let id = self.iter().find(|&(_, p)| path == p)?.0;
        Some(id)
    }
}

fn analysis_host(files: &[(&str, &str)]) -> AnalysisHost {
    let mut host = AnalysisHost::new();
    let mut file_map = Vec::new();
    for (id, &(path, contents)) in files.iter().enumerate() {
        let file_id = FileId((id + 1) as u32);
        assert!(path.starts_with('/'));
        let path = RelativePathBuf::from_path(&path[1..]).unwrap();
        host.change_file(file_id, Some(contents.to_string()));
        file_map.push((file_id, path));
    }
    host.set_file_resolver(Arc::new(FileMap(file_map)));
    host
}

fn analysis(files: &[(&str, &str)]) -> Analysis {
    analysis_host(files).analysis()
}

fn get_signature(text: &str) -> (FnDescriptor, Option<usize>) {
    let (offset, code) = extract_offset(text);
    let code = code.as_str();

    let snap = analysis(&[("/lib.rs", code)]);

    snap.resolve_callable(FileId(1), offset).unwrap().unwrap()
}

#[test]
fn test_resolve_module() {
    let snap = analysis(&[("/lib.rs", "mod foo;"), ("/foo.rs", "")]);
    let symbols = snap.approximately_resolve_symbol(FileId(1), 4.into()).unwrap();
    assert_eq_dbg(
        r#"[(FileId(2), FileSymbol { name: "foo", node_range: [0; 0), kind: MODULE })]"#,
        &symbols,
    );

    let snap = analysis(&[("/lib.rs", "mod foo;"), ("/foo/mod.rs", "")]);
    let symbols = snap.approximately_resolve_symbol(FileId(1), 4.into()).unwrap();
    assert_eq_dbg(
        r#"[(FileId(2), FileSymbol { name: "foo", node_range: [0; 0), kind: MODULE })]"#,
        &symbols,
    );
}

#[test]
fn test_unresolved_module_diagnostic() {
    let snap = analysis(&[("/lib.rs", "mod foo;")]);
    let diagnostics = snap.diagnostics(FileId(1)).unwrap();
    assert_eq_dbg(
        r#"[Diagnostic {
            message: "unresolved module",
            range: [4; 7),
            fix: Some(SourceChange {
                label: "create module",
                source_file_edits: [],
                file_system_edits: [CreateFile { anchor: FileId(1), path: "../foo.rs" }],
                cursor_position: None }) }]"#,
        &diagnostics,
    );
}

// #[test]
// fn test_unresolved_module_diagnostic_no_diag_for_inline_mode() {
//     let snap = analysis(&[("/lib.rs", "mod foo {}")]);
//     let diagnostics = snap.diagnostics(FileId(1)).unwrap();
//     assert_eq_dbg(r#"[]"#, &diagnostics);
// }

#[test]
fn test_resolve_parent_module() {
    let snap = analysis(&[("/lib.rs", "mod foo;"), ("/foo.rs", "")]);
    let symbols = snap.parent_module(FileId(2)).unwrap();
    assert_eq_dbg(
        r#"[(FileId(1), FileSymbol { name: "foo", node_range: [0; 8), kind: MODULE })]"#,
        &symbols,
    );
}

#[test]
fn test_resolve_crate_root() {
    let mut host = analysis_host(&[("/lib.rs", "mod foo;"), ("/foo.rs", "")]);
    let snap = host.analysis();
    assert!(snap.crate_for(FileId(2)).unwrap().is_empty());

    let crate_graph = CrateGraph {
        crate_roots: {
            let mut m = FxHashMap::default();
            m.insert(CrateId(1), FileId(1));
            m
        },
    };
    host.set_crate_graph(crate_graph);
    let snap = host.analysis();

    assert_eq!(snap.crate_for(FileId(2)).unwrap(), vec![CrateId(1)],);
}

#[test]
fn test_fn_signature_two_args_first() {
    let (desc, param) = get_signature(
        r#"fn foo(x: u32, y: u32) -> u32 {x + y}
fn bar() { foo(<|>3, ); }"#,
    );

    assert_eq!(desc.name, "foo".to_string());
    assert_eq!(desc.params, vec!("x".to_string(), "y".to_string()));
    assert_eq!(desc.ret_type, Some("-> u32".into()));
    assert_eq!(param, Some(0));
}

#[test]
fn test_fn_signature_two_args_second() {
    let (desc, param) = get_signature(
        r#"fn foo(x: u32, y: u32) -> u32 {x + y}
fn bar() { foo(3, <|>); }"#,
    );

    assert_eq!(desc.name, "foo".to_string());
    assert_eq!(desc.params, vec!("x".to_string(), "y".to_string()));
    assert_eq!(desc.ret_type, Some("-> u32".into()));
    assert_eq!(param, Some(1));
}

#[test]
fn test_fn_signature_for_impl() {
    let (desc, param) = get_signature(
        r#"struct F; impl F { pub fn new() { F{}} }
fn bar() {let _ : F = F::new(<|>);}"#,
    );

    assert_eq!(desc.name, "new".to_string());
    assert_eq!(desc.params, Vec::<String>::new());
    assert_eq!(desc.ret_type, None);
    assert_eq!(param, None);
}

#[test]
fn test_fn_signature_for_method_self() {
    let (desc, param) = get_signature(
        r#"struct F;
impl F {
    pub fn new() -> F{
        F{}
    }

    pub fn do_it(&self) {}
}

fn bar() {
    let f : F = F::new();
    f.do_it(<|>);
}"#,
    );

    assert_eq!(desc.name, "do_it".to_string());
    assert_eq!(desc.params, vec!["&self".to_string()]);
    assert_eq!(desc.ret_type, None);
    assert_eq!(param, None);
}

#[test]
fn test_fn_signature_for_method_with_arg() {
    let (desc, param) = get_signature(
        r#"struct F;
impl F {
    pub fn new() -> F{
        F{}
    }

    pub fn do_it(&self, x: i32) {}
}

fn bar() {
    let f : F = F::new();
    f.do_it(<|>);
}"#,
    );

    assert_eq!(desc.name, "do_it".to_string());
    assert_eq!(desc.params, vec!["&self".to_string(), "x".to_string()]);
    assert_eq!(desc.ret_type, None);
    assert_eq!(param, Some(1));
}

fn get_all_refs(text: &str) -> Vec<(FileId, TextRange)> {
    let (offset, code) = extract_offset(text);
    let code = code.as_str();

    let snap = analysis(&[("/lib.rs", code)]);

    snap.find_all_refs(FileId(1), offset).unwrap()
}

#[test]
fn test_find_all_refs_for_local() {
    let code = r#"
    fn main() {
        let mut i = 1;
        let j = 1;
        i = i<|> + j;

        {
            i = 0;
        }

        i = 5;
    }"#;

    let refs = get_all_refs(code);
    assert_eq!(refs.len(), 5);
}

#[test]
fn test_find_all_refs_for_param_inside() {
    let code = r#"
    fn foo(i : u32) -> u32 {
        i<|>
    }"#;

    let refs = get_all_refs(code);
    assert_eq!(refs.len(), 2);
}
<commit_msg>revive the test<commit_after>extern crate ra_analysis;
extern crate ra_editor;
extern crate ra_syntax;
extern crate relative_path;
extern crate rustc_hash;
extern crate test_utils;

use std::sync::Arc;

use ra_syntax::TextRange;
use relative_path::{RelativePath, RelativePathBuf};
use rustc_hash::FxHashMap;
use test_utils::{assert_eq_dbg, extract_offset};

use ra_analysis::{
    Analysis, AnalysisHost, CrateGraph, CrateId, FileId, FileResolver, FnDescriptor,
};

#[derive(Debug)]
struct FileMap(Vec<(FileId, RelativePathBuf)>);

impl FileMap {
    fn iter<'a>(&'a self) -> impl Iterator<Item = (FileId, &'a RelativePath)> + 'a {
        self.0
            .iter()
            .map(|(id, path)| (*id, path.as_relative_path()))
    }

    fn path(&self, id: FileId) -> &RelativePath {
        self.iter().find(|&(it, _)| it == id).unwrap().1
    }
}

impl FileResolver for FileMap {
    fn file_stem(&self, id: FileId) -> String {
        self.path(id).file_stem().unwrap().to_string()
    }
    fn resolve(&self, id: FileId, rel: &RelativePath) -> Option<FileId> {
        let path = self.path(id).join(rel).normalize();
        let id = self.iter().find(|&(_, p)| path == p)?.0;
        Some(id)
    }
}

fn analysis_host(files: &[(&str, &str)]) -> AnalysisHost {
    let mut host = AnalysisHost::new();
    let mut file_map = Vec::new();
    for (id, &(path, contents)) in files.iter().enumerate() {
        let file_id = FileId((id + 1) as u32);
        assert!(path.starts_with('/'));
        let path = RelativePathBuf::from_path(&path[1..]).unwrap();
        host.change_file(file_id, Some(contents.to_string()));
        file_map.push((file_id, path));
    }
    host.set_file_resolver(Arc::new(FileMap(file_map)));
    host
}

fn analysis(files: &[(&str, &str)]) -> Analysis {
    analysis_host(files).analysis()
}

fn get_signature(text: &str) -> (FnDescriptor, Option<usize>) {
    let (offset, code) = extract_offset(text);
    let code = code.as_str();

    let snap = analysis(&[("/lib.rs", code)]);

    snap.resolve_callable(FileId(1), offset).unwrap().unwrap()
}

#[test]
fn test_resolve_module() {
    let snap = analysis(&[("/lib.rs", "mod foo;"), ("/foo.rs", "")]);
    let symbols = snap.approximately_resolve_symbol(FileId(1), 4.into()).unwrap();
    assert_eq_dbg(
        r#"[(FileId(2), FileSymbol { name: "foo", node_range: [0; 0), kind: MODULE })]"#,
        &symbols,
    );

    let snap = analysis(&[("/lib.rs", "mod foo;"), ("/foo/mod.rs", "")]);
    let symbols = snap.approximately_resolve_symbol(FileId(1), 4.into()).unwrap();
    assert_eq_dbg(
        r#"[(FileId(2), FileSymbol { name: "foo", node_range: [0; 0), kind: MODULE })]"#,
        &symbols,
    );
}

#[test]
fn test_unresolved_module_diagnostic() {
    let snap = analysis(&[("/lib.rs", "mod foo;")]);
    let diagnostics = snap.diagnostics(FileId(1)).unwrap();
    assert_eq_dbg(
        r#"[Diagnostic {
            message: "unresolved module",
            range: [4; 7),
            fix: Some(SourceChange {
                label: "create module",
                source_file_edits: [],
                file_system_edits: [CreateFile { anchor: FileId(1), path: "../foo.rs" }],
                cursor_position: None }) }]"#,
        &diagnostics,
    );
}

#[test]
fn test_unresolved_module_diagnostic_no_diag_for_inline_mode() {
    let snap = analysis(&[("/lib.rs", "mod foo {}")]);
    let diagnostics = snap.diagnostics(FileId(1)).unwrap();
    assert_eq_dbg(r#"[]"#, &diagnostics);
}

#[test]
fn test_resolve_parent_module() {
    let snap = analysis(&[("/lib.rs", "mod foo;"), ("/foo.rs", "")]);
    let symbols = snap.parent_module(FileId(2)).unwrap();
    assert_eq_dbg(
        r#"[(FileId(1), FileSymbol { name: "foo", node_range: [0; 8), kind: MODULE })]"#,
        &symbols,
    );
}

#[test]
fn test_resolve_crate_root() {
    let mut host = analysis_host(&[("/lib.rs", "mod foo;"), ("/foo.rs", "")]);
    let snap = host.analysis();
    assert!(snap.crate_for(FileId(2)).unwrap().is_empty());

    let crate_graph = CrateGraph {
        crate_roots: {
            let mut m = FxHashMap::default();
            m.insert(CrateId(1), FileId(1));
            m
        },
    };
    host.set_crate_graph(crate_graph);
    let snap = host.analysis();

    assert_eq!(snap.crate_for(FileId(2)).unwrap(), vec![CrateId(1)],);
}

#[test]
fn test_fn_signature_two_args_first() {
    let (desc, param) = get_signature(
        r#"fn foo(x: u32, y: u32) -> u32 {x + y}
fn bar() { foo(<|>3, ); }"#,
    );

    assert_eq!(desc.name, "foo".to_string());
    assert_eq!(desc.params, vec!("x".to_string(), "y".to_string()));
    assert_eq!(desc.ret_type, Some("-> u32".into()));
    assert_eq!(param, Some(0));
}

#[test]
fn test_fn_signature_two_args_second() {
    let (desc, param) = get_signature(
        r#"fn foo(x: u32, y: u32) -> u32 {x + y}
fn bar() { foo(3, <|>); }"#,
    );

    assert_eq!(desc.name, "foo".to_string());
    assert_eq!(desc.params, vec!("x".to_string(), "y".to_string()));
    assert_eq!(desc.ret_type, Some("-> u32".into()));
    assert_eq!(param, Some(1));
}

#[test]
fn test_fn_signature_for_impl() {
    let (desc, param) = get_signature(
        r#"struct F; impl F { pub fn new() { F{}} }
fn bar() {let _ : F = F::new(<|>);}"#,
    );

    assert_eq!(desc.name, "new".to_string());
    assert_eq!(desc.params, Vec::<String>::new());
    assert_eq!(desc.ret_type, None);
    assert_eq!(param, None);
}

#[test]
fn test_fn_signature_for_method_self() {
    let (desc, param) = get_signature(
        r#"struct F;
impl F {
    pub fn new() -> F{
        F{}
    }

    pub fn do_it(&self) {}
}

fn bar() {
    let f : F = F::new();
    f.do_it(<|>);
}"#,
    );

    assert_eq!(desc.name, "do_it".to_string());
    assert_eq!(desc.params, vec!["&self".to_string()]);
    assert_eq!(desc.ret_type, None);
    assert_eq!(param, None);
}

#[test]
fn test_fn_signature_for_method_with_arg() {
    let (desc, param) = get_signature(
        r#"struct F;
impl F {
    pub fn new() -> F{
        F{}
    }

    pub fn do_it(&self, x: i32) {}
}

fn bar() {
    let f : F = F::new();
    f.do_it(<|>);
}"#,
    );

    assert_eq!(desc.name, "do_it".to_string());
    assert_eq!(desc.params, vec!["&self".to_string(), "x".to_string()]);
    assert_eq!(desc.ret_type, None);
    assert_eq!(param, Some(1));
}

fn get_all_refs(text: &str) -> Vec<(FileId, TextRange)> {
    let (offset, code) = extract_offset(text);
    let code = code.as_str();

    let snap = analysis(&[("/lib.rs", code)]);

    snap.find_all_refs(FileId(1), offset).unwrap()
}

#[test]
fn test_find_all_refs_for_local() {
    let code = r#"
    fn main() {
        let mut i = 1;
        let j = 1;
        i = i<|> + j;

        {
            i = 0;
        }

        i = 5;
    }"#;

    let refs = get_all_refs(code);
    assert_eq!(refs.len(), 5);
}

#[test]
fn test_find_all_refs_for_param_inside() {
    let code = r#"
    fn foo(i : u32) -> u32 {
        i<|>
    }"#;

    let refs = get_all_refs(code);
    assert_eq!(refs.len(), 2);
}
<|endoftext|>


<commit_before>extern crate hyper;

use std::sync::mpsc::{Receiver, channel, Sender};
use std::thread;
use args::Config;
use run_info::RunInfo;
use misc::split_number;
use tokio_core::reactor::Core;
use chrono::{Duration, Local};
use hyper::{Client, Url};
use std::str::FromStr;
use hyper::client::HttpConnector;

use futures::{Future, stream};
use futures::future::{ok, loop_fn, Loop};
use futures::Stream;
use futures_utils::stopwatch;
use request_result::RequestResult;
use errors::*;

/// Delegates and manages all the work.
pub struct Boss {
    /// Number of requests successfully completed
    pub requests_completed: usize,
    /// Number of active connections
    pub connections: usize,
    num_threads: usize,
}

impl Boss {
    pub fn new(num_threads: usize) -> Self {
        Boss {
            requests_completed: 0,
            connections: 0,
            num_threads: num_threads,
        }
    }

    pub fn start_workforce(&self, config: &Config) -> Result<RunInfo> {
        let (tx, rx) = channel();
        let desired_connections_per_worker_iter = split_number(config.num_connections,
                                                               self.num_threads);
        // start num_threads workers
        for desired_connections_per_worker in desired_connections_per_worker_iter {
            let tx = tx.clone();
            let url = config.url.clone();
            let timeout = config.timeout.to_std()?;
            let hyper_url = Url::from_str(&url)?;
            thread::spawn(move || {
                // TODO: how to use error_chain on tokio-core?
                let mut core = Core::new().expect("Failed to create Tokio core");
                let hyper_client = hyper::Client::configure()
                    .keep_alive_timeout(Some(timeout))
                    .build(&core.handle());

                let iterator = (0..desired_connections_per_worker).map(|_| {
                    let tx = tx.clone();
                    create_looping_worker(hyper_url.clone(), &hyper_client, tx)
                });
                // create stream of requests
                let request_stream = stream::futures_unordered(iterator);
                // TODO: how to use error_chain with tokio?
                let _ = core.run(request_stream.into_future());
            });
        }

        Ok(self.collect_workers(rx, config.duration))
    }

    /// Collects information from all workers
    fn collect_workers(&self, rx: Receiver<RequestResult>, run_duration: Duration) -> RunInfo {
        let start_time = Local::now();
        let wanted_end_time = start_time + run_duration;
        rx.iter()
            .take_while(|_| Local::now() < wanted_end_time)
            .fold(RunInfo::new(run_duration), |mut runinfo_acc, request_result| {
                runinfo_acc.add_request(&request_result);
                runinfo_acc
            })
    }
}

fn create_looping_worker<'a>(url: Url,
                             hyper_client: &'a Client<HttpConnector>,
                             tx: Sender<RequestResult>)
                             -> impl Future<Item = (), Error = ()> + 'a {
    loop_fn((), move |_| {
        let url = url.clone();
        let tx = tx.clone();
        send_request(url, hyper_client)
            .and_then(move |request_result| {
                let _ = tx.send(request_result);
                Ok(())
            })
            .and_then(|_| ok(Loop::Continue(())))
    })
}

fn send_request<C>(url: Url,
                   hyper_client: &Client<C>)
                   -> impl Future<Item = RequestResult, Error = ()>
    where C: hyper::client::Connect
{
    stopwatch(hyper_client.get(url))
        .and_then(|(_, latency)| {
            let request_result = RequestResult::Success { latency: latency };
            Ok(request_result)
        })
        .or_else(|_| ok(RequestResult::Failure))
}
<commit_msg>looping worker as stream<commit_after>extern crate hyper;

use std::sync::mpsc::{Receiver, channel, Sender};
use std::thread;
use args::Config;
use run_info::RunInfo;
use misc::split_number;
use tokio_core::reactor::Core;
use chrono::{Duration, Local};
use hyper::{Client, Url};
use std::str::FromStr;
use hyper::client::HttpConnector;

use futures::{Future, stream};
use futures::future::{ok, loop_fn, Loop};
use futures::Stream;
use futures_utils::stopwatch;
use request_result::RequestResult;
use errors::*;

/// Delegates and manages all the work.
pub struct Boss {
    /// Number of requests successfully completed
    pub requests_completed: usize,
    /// Number of active connections
    pub connections: usize,
    num_threads: usize,
}

impl Boss {
    pub fn new(num_threads: usize) -> Self {
        Boss {
            requests_completed: 0,
            connections: 0,
            num_threads: num_threads,
        }
    }

    pub fn start_workforce(&self, config: &Config) -> Result<RunInfo> {
        let (tx, rx) = channel();
        let desired_connections_per_worker_iter = split_number(config.num_connections,
                                                               self.num_threads);
        // start num_threads workers
        for desired_connections_per_worker in desired_connections_per_worker_iter {
            let tx = tx.clone();
            let url = config.url.clone();
            let timeout = config.timeout.to_std()?;
            let hyper_url = Url::from_str(&url)?;
            thread::spawn(move || {
                // TODO: how to use error_chain on tokio-core?
                let mut core = Core::new().expect("Failed to create Tokio core");
                let hyper_client = hyper::Client::configure()
                    .keep_alive_timeout(Some(timeout))
                    .build(&core.handle());

                let iterator = (0..desired_connections_per_worker).map(|_| {
                    let tx = tx.clone();

                    create_looping_worker(hyper_url.clone(), &hyper_client)
                        .for_each(move |req| {
                            tx.send(req);
                            ok(())
                        })
                });
                // create stream of requests
                let request_stream = stream::futures_unordered(iterator);
                // TODO: how to use error_chain with tokio?
                let _ = core.run(request_stream.into_future());
            });
        }

        Ok(self.collect_workers(rx, config.duration))
    }

    /// Collects information from all workers
    fn collect_workers(&self, rx: Receiver<RequestResult>, run_duration: Duration) -> RunInfo {
        let start_time = Local::now();
        let wanted_end_time = start_time + run_duration;
        rx.iter()
            .take_while(|_| Local::now() < wanted_end_time)
            .fold(RunInfo::new(run_duration), |mut runinfo_acc, request_result| {
                runinfo_acc.add_request(&request_result);
                runinfo_acc
            })
    }
}

fn create_looping_worker<'a>(url: Url,
                             hyper_client: &'a Client<HttpConnector>
                             )
                             -> impl Stream<Item = RequestResult, Error = ()> + 'a {
    stream::unfold(0u32, move |state| {
        let res = send_request(url.clone(), hyper_client);

        let fut = res.and_then(move |req| ok::<_, _>((req, state)));
        Some(fut)
    })
}

fn send_request<C>(url: Url,
                   hyper_client: &Client<C>)
                   -> impl Future<Item = RequestResult, Error = ()>
    where C: hyper::client::Connect
{
    stopwatch(hyper_client.get(url))
        .and_then(|(_, latency)| {
            let request_result = RequestResult::Success { latency: latency };
            Ok(request_result)
        })
        .or_else(|_| ok(RequestResult::Failure))
}
<|endoftext|>


<commit_before>use bls::verify_proof_of_possession;
use types::{BeaconState, ChainSpec, Deposit, Validator};

#[derive(Debug, PartialEq, Clone)]
pub enum ValidatorInductionError {
    InvalidShard,
    InvaidProofOfPossession,
    InvalidWithdrawalCredentials,
}

pub fn process_deposit(
    state: &mut BeaconState,
    deposit: &Deposit,
    spec: &ChainSpec,
) -> Result<(), ValidatorInductionError> {
    let deposit_input = &deposit.deposit_data.deposit_input;
    let deposit_data = &deposit.deposit_data;

    // TODO: Update the signature validation as defined in the spec once issues #91 and #70 are completed
    if !verify_proof_of_possession(&deposit_input.proof_of_possession, &deposit_input.pubkey) {
        return Err(ValidatorInductionError::InvaidProofOfPossession);
    }

    let validator_index = state
        .validator_registry
        .iter()
        .position(|validator| validator.pubkey == deposit_input.pubkey);

    match validator_index {
        Some(i) => {
            if state.validator_registry[i].withdrawal_credentials
                == deposit_input.withdrawal_credentials
            {
                state.validator_balances[i] += deposit_data.amount;
                return Ok(());
            }

            Err(ValidatorInductionError::InvalidWithdrawalCredentials)
        }
        None => {
            let validator = Validator {
                pubkey: deposit_input.pubkey.clone(),
                withdrawal_credentials: deposit_input.withdrawal_credentials,
                proposer_slots: 0,
                activation_slot: spec.far_future_slot,
                exit_slot: spec.far_future_slot,
                withdrawal_slot: spec.far_future_slot,
                penalized_slot: spec.far_future_slot,
                exit_count: 0,
                status_flags: None,
                latest_custody_reseed_slot: 0,
                penultimate_custody_reseed_slot: 0,
            };

            let _index = state.validator_registry.len();
            state.validator_registry.push(validator);
            state.validator_balances.push(deposit_data.amount);
            Ok(())
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use types::test_utils::{SeedableRng, TestRandom, XorShiftRng};

    use bls::{create_proof_of_possession, Keypair};

    /// The size of a validators deposit in GWei.
    pub const DEPOSIT_GWEI: u64 = 32_000_000_000;

    fn get_deposit() -> Deposit {
        let mut rng = XorShiftRng::from_seed([42; 16]);
        let mut deposit = Deposit::random_for_test(&mut rng);

        let kp = Keypair::random();
        deposit.deposit_data.deposit_input.pubkey = kp.pk.clone();
        deposit.deposit_data.deposit_input.proof_of_possession = create_proof_of_possession(&kp);
        deposit
    }

    fn get_validator() -> Validator {
        let mut rng = XorShiftRng::from_seed([42; 16]);
        Validator::random_for_test(&mut rng)
    }

    fn deposit_equals_record(dep: &Deposit, val: &Validator) -> bool {
        (dep.deposit_data.deposit_input.pubkey == val.pubkey)
            & (dep.deposit_data.deposit_input.withdrawal_credentials == val.withdrawal_credentials)
            & (verify_proof_of_possession(
                &dep.deposit_data.deposit_input.proof_of_possession,
                &val.pubkey,
            ))
    }

    #[test]
    fn test_process_deposit_valid_empty_validators() {
        let mut state = BeaconState::default();
        let mut deposit = get_deposit();
        let spec = ChainSpec::foundation();
        deposit.deposit_data.amount = DEPOSIT_GWEI;

        let result = process_deposit(&mut state, &deposit, &spec);

        assert_eq!(result.unwrap(), ());
        assert!(deposit_equals_record(
            &deposit,
            &state.validator_registry[0]
        ));
        assert_eq!(state.validator_registry.len(), 1);
        assert_eq!(state.validator_balances.len(), 1);
    }

    #[test]
    fn test_process_deposits_empty_validators() {
        let mut state = BeaconState::default();
        let spec = ChainSpec::foundation();

        for i in 0..5 {
            let mut deposit = get_deposit();
            let result = process_deposit(&mut state, &deposit, &spec);
            deposit.deposit_data.amount = DEPOSIT_GWEI;
            assert_eq!(result.unwrap(), ());
            assert!(deposit_equals_record(
                &deposit,
                &state.validator_registry[i]
            ));
            assert_eq!(state.validator_registry.len(), i + 1);
            assert_eq!(state.validator_balances.len(), i + 1);
        }
    }

    #[test]
    fn test_process_deposit_top_out() {
        let mut state = BeaconState::default();
        let spec = ChainSpec::foundation();

        let mut deposit = get_deposit();
        let mut validator = get_validator();

        deposit.deposit_data.amount = DEPOSIT_GWEI;
        validator.pubkey = deposit.deposit_data.deposit_input.pubkey.clone();
        validator.withdrawal_credentials =
            deposit.deposit_data.deposit_input.withdrawal_credentials;

        state.validator_registry.push(validator);
        state.validator_balances.push(DEPOSIT_GWEI);

        let result = process_deposit(&mut state, &deposit, &spec);

        assert_eq!(result.unwrap(), ());
        assert!(deposit_equals_record(
            &deposit,
            &state.validator_registry[0]
        ));
        assert_eq!(state.validator_balances[0], DEPOSIT_GWEI * 2);
        assert_eq!(state.validator_registry.len(), 1);
        assert_eq!(state.validator_balances.len(), 1);
    }

    #[test]
    fn test_process_deposit_invalid_proof_of_possession() {
        let mut state = BeaconState::default();
        let mut deposit = get_deposit();
        let spec = ChainSpec::foundation();
        deposit.deposit_data.amount = DEPOSIT_GWEI;
        deposit.deposit_data.deposit_input.proof_of_possession =
            create_proof_of_possession(&Keypair::random());

        let result = process_deposit(&mut state, &deposit, &spec);

        assert_eq!(
            result,
            Err(ValidatorInductionError::InvaidProofOfPossession)
        );
        assert_eq!(state.validator_registry.len(), 0);
        assert_eq!(state.validator_balances.len(), 0);
    }
}
<commit_msg>Update validator_inductor to use Slot newtype<commit_after>use bls::verify_proof_of_possession;
use types::{BeaconState, ChainSpec, Deposit, Slot, Validator};

#[derive(Debug, PartialEq, Clone)]
pub enum ValidatorInductionError {
    InvalidShard,
    InvaidProofOfPossession,
    InvalidWithdrawalCredentials,
}

pub fn process_deposit(
    state: &mut BeaconState,
    deposit: &Deposit,
    spec: &ChainSpec,
) -> Result<(), ValidatorInductionError> {
    let deposit_input = &deposit.deposit_data.deposit_input;
    let deposit_data = &deposit.deposit_data;

    // TODO: Update the signature validation as defined in the spec once issues #91 and #70 are completed
    if !verify_proof_of_possession(&deposit_input.proof_of_possession, &deposit_input.pubkey) {
        return Err(ValidatorInductionError::InvaidProofOfPossession);
    }

    let validator_index = state
        .validator_registry
        .iter()
        .position(|validator| validator.pubkey == deposit_input.pubkey);

    match validator_index {
        Some(i) => {
            if state.validator_registry[i].withdrawal_credentials
                == deposit_input.withdrawal_credentials
            {
                state.validator_balances[i] += deposit_data.amount;
                return Ok(());
            }

            Err(ValidatorInductionError::InvalidWithdrawalCredentials)
        }
        None => {
            let validator = Validator {
                pubkey: deposit_input.pubkey.clone(),
                withdrawal_credentials: deposit_input.withdrawal_credentials,
                proposer_slots: Slot::new(0),
                activation_slot: spec.far_future_slot,
                exit_slot: spec.far_future_slot,
                withdrawal_slot: spec.far_future_slot,
                penalized_slot: spec.far_future_slot,
                exit_count: 0,
                status_flags: None,
                latest_custody_reseed_slot: Slot::new(0),
                penultimate_custody_reseed_slot: Slot::new(0),
            };

            let _index = state.validator_registry.len();
            state.validator_registry.push(validator);
            state.validator_balances.push(deposit_data.amount);
            Ok(())
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use types::test_utils::{SeedableRng, TestRandom, XorShiftRng};

    use bls::{create_proof_of_possession, Keypair};

    /// The size of a validators deposit in GWei.
    pub const DEPOSIT_GWEI: u64 = 32_000_000_000;

    fn get_deposit() -> Deposit {
        let mut rng = XorShiftRng::from_seed([42; 16]);
        let mut deposit = Deposit::random_for_test(&mut rng);

        let kp = Keypair::random();
        deposit.deposit_data.deposit_input.pubkey = kp.pk.clone();
        deposit.deposit_data.deposit_input.proof_of_possession = create_proof_of_possession(&kp);
        deposit
    }

    fn get_validator() -> Validator {
        let mut rng = XorShiftRng::from_seed([42; 16]);
        Validator::random_for_test(&mut rng)
    }

    fn deposit_equals_record(dep: &Deposit, val: &Validator) -> bool {
        (dep.deposit_data.deposit_input.pubkey == val.pubkey)
            & (dep.deposit_data.deposit_input.withdrawal_credentials == val.withdrawal_credentials)
            & (verify_proof_of_possession(
                &dep.deposit_data.deposit_input.proof_of_possession,
                &val.pubkey,
            ))
    }

    #[test]
    fn test_process_deposit_valid_empty_validators() {
        let mut state = BeaconState::default();
        let mut deposit = get_deposit();
        let spec = ChainSpec::foundation();
        deposit.deposit_data.amount = DEPOSIT_GWEI;

        let result = process_deposit(&mut state, &deposit, &spec);

        assert_eq!(result.unwrap(), ());
        assert!(deposit_equals_record(
            &deposit,
            &state.validator_registry[0]
        ));
        assert_eq!(state.validator_registry.len(), 1);
        assert_eq!(state.validator_balances.len(), 1);
    }

    #[test]
    fn test_process_deposits_empty_validators() {
        let mut state = BeaconState::default();
        let spec = ChainSpec::foundation();

        for i in 0..5 {
            let mut deposit = get_deposit();
            let result = process_deposit(&mut state, &deposit, &spec);
            deposit.deposit_data.amount = DEPOSIT_GWEI;
            assert_eq!(result.unwrap(), ());
            assert!(deposit_equals_record(
                &deposit,
                &state.validator_registry[i]
            ));
            assert_eq!(state.validator_registry.len(), i + 1);
            assert_eq!(state.validator_balances.len(), i + 1);
        }
    }

    #[test]
    fn test_process_deposit_top_out() {
        let mut state = BeaconState::default();
        let spec = ChainSpec::foundation();

        let mut deposit = get_deposit();
        let mut validator = get_validator();

        deposit.deposit_data.amount = DEPOSIT_GWEI;
        validator.pubkey = deposit.deposit_data.deposit_input.pubkey.clone();
        validator.withdrawal_credentials =
            deposit.deposit_data.deposit_input.withdrawal_credentials;

        state.validator_registry.push(validator);
        state.validator_balances.push(DEPOSIT_GWEI);

        let result = process_deposit(&mut state, &deposit, &spec);

        assert_eq!(result.unwrap(), ());
        assert!(deposit_equals_record(
            &deposit,
            &state.validator_registry[0]
        ));
        assert_eq!(state.validator_balances[0], DEPOSIT_GWEI * 2);
        assert_eq!(state.validator_registry.len(), 1);
        assert_eq!(state.validator_balances.len(), 1);
    }

    #[test]
    fn test_process_deposit_invalid_proof_of_possession() {
        let mut state = BeaconState::default();
        let mut deposit = get_deposit();
        let spec = ChainSpec::foundation();
        deposit.deposit_data.amount = DEPOSIT_GWEI;
        deposit.deposit_data.deposit_input.proof_of_possession =
            create_proof_of_possession(&Keypair::random());

        let result = process_deposit(&mut state, &deposit, &spec);

        assert_eq!(
            result,
            Err(ValidatorInductionError::InvaidProofOfPossession)
        );
        assert_eq!(state.validator_registry.len(), 0);
        assert_eq!(state.validator_balances.len(), 0);
    }
}
<|endoftext|>


<commit_before>use std::thread;
use std::sync::mpsc::{self, sync_channel};
use std::io::Write;

use mio::*;
use mio::tcp::{TcpStream, Shutdown};

use ladspa::{PluginDescriptor, Plugin, PortConnection, Data};

use super::BASE_PORT;
use super::packet::{BUFFER_SIZE, BYTE_BUFFER_SIZE, Packet};

const CLIENT: Token = Token(1);

pub struct Transmitter {
    sample_rate: u64,
    channel: u16,
    data_tx: Option<mpsc::SyncSender<Packet>>,
    notify_tx: Option<Sender<<PacketTransmitter as Handler>::Message>>,
    lbuffer: Vec<Data>,
    rbuffer: Vec<Data>,
    time: u64,
}

impl Transmitter {
    pub fn new(_: &PluginDescriptor, sample_rate: u64) -> Box<Plugin + Send> {
        Box::new(Transmitter {
            sample_rate: sample_rate,
            channel: 0,
            data_tx: None,
            notify_tx: None,
            lbuffer: Vec::new(),
            rbuffer: Vec::new(),
            time: 0,
        })
    }

    fn init_client(&mut self) {
        let (data_tx, data_rx) = sync_channel(16);
        self.data_tx = Some(data_tx);

        let channel = self.channel;
        let mut event_loop = EventLoop::new().unwrap();
        self.notify_tx = Some(event_loop.channel());
        thread::spawn(move || {
            let addr = format!("127.0.0.1:{}", BASE_PORT + channel).parse().unwrap();
            let client = TcpStream::connect(&addr).unwrap();
            client.set_nodelay(true);
            event_loop.register(&client, CLIENT).unwrap();
            event_loop.run(&mut PacketTransmitter {
                          socket: client,
                          data_rx: data_rx,
                      })
                      .unwrap();
        });
    }

    fn kill_client(&mut self) {
        self.notify_tx.as_ref().unwrap().send(());
    }
}

impl Plugin for Transmitter {
    fn run<'a>(&mut self, sample_count: usize, ports: &[&'a PortConnection<'a>]) {
        let inputl = ports[0].unwrap_audio();
        let inputr = ports[1].unwrap_audio();
        let mut outputl = ports[2].unwrap_audio_mut();
        let mut outputr = ports[3].unwrap_audio_mut();

        let channel = *ports[4].unwrap_control() as u16;

        if channel != self.channel {
            self.channel = channel;
            println!("set channel {}", self.channel);
            self.kill_client();
            self.init_client();
            return;
        }

        let mut need_reboot = false;
        let mut i = 0;
        while i < sample_count {
            while self.lbuffer.len() < BUFFER_SIZE && i < sample_count {
                self.lbuffer.push(inputl[i]);
                self.rbuffer.push(inputr[i]);

                outputl[i] = inputl[i];
                outputr[i] = inputr[i];

                i += 1;
            }

            if self.lbuffer.len() == BUFFER_SIZE {
                let mut packet = Packet::new(&self.lbuffer, &self.rbuffer, self.time);
                self.time += BUFFER_SIZE as u64;

                need_reboot |= self.data_tx.as_ref().unwrap().send(packet).is_err();

                self.lbuffer.clear();
                self.rbuffer.clear();
            }
        }
        if need_reboot {
            self.kill_client();
            self.init_client();
        }
    }

    fn activate(&mut self) {
        println!("activate {}", self.channel);
        self.lbuffer.clear();
        self.rbuffer.clear();
        self.time = 0;
        self.init_client();
    }

    fn deactivate(&mut self) {
        println!("deactivate {}", self.channel);
        self.kill_client();
    }
}

struct PacketTransmitter {
    socket: TcpStream,
    data_rx: mpsc::Receiver<Packet>,
}

impl Handler for PacketTransmitter {
    type Timeout = ();
    type Message = ();

    fn ready(&mut self, event_loop: &mut EventLoop<Self>, token: Token, events: EventSet) {
        match token {
            CLIENT => {
                loop {
                    assert!(events.is_writable());
                    let packet = match self.data_rx.recv() {
                        Ok(p) => p,
                        Err(_) => {
                            println!("err recieving packet from ladspa, channel is dead!");
                            // TODO shutdown here?
                            event_loop.shutdown();
                            break;
                        }
                    };
                    match self.socket.write(&packet.as_bytes()[..]) {
                        Ok(num_written) => {
                            if num_written != BYTE_BUFFER_SIZE {
                                println!("incorrect write size: {}", num_written);
                                event_loop.shutdown();
                                break;
                            }
                        }
                        Err(_) => {
                            println!("err writing packet to network!");
                            event_loop.shutdown();
                            break;
                        }
                    }
                }
            }
            _ => panic!("Received unknown token"),
        }
    }

    fn notify(&mut self, event_loop: &mut EventLoop<Self>, msg: Self::Message) {
        self.socket.shutdown(Shutdown::Both);
        event_loop.shutdown();
    }
}
<commit_msg>I think this is reasonable<commit_after>use std::thread;
use std::sync::mpsc::{self, sync_channel};
use std::io::Write;

use mio::*;
use mio::tcp::{TcpStream, Shutdown};

use ladspa::{PluginDescriptor, Plugin, PortConnection, Data};

use super::BASE_PORT;
use super::packet::{BUFFER_SIZE, BYTE_BUFFER_SIZE, Packet};

const CLIENT: Token = Token(1);

pub struct Transmitter {
    sample_rate: u64,
    channel: u16,
    data_tx: Option<mpsc::SyncSender<Packet>>,
    notify_tx: Option<Sender<<PacketTransmitter as Handler>::Message>>,
    lbuffer: Vec<Data>,
    rbuffer: Vec<Data>,
    time: u64,
}

impl Transmitter {
    pub fn new(_: &PluginDescriptor, sample_rate: u64) -> Box<Plugin + Send> {
        Box::new(Transmitter {
            sample_rate: sample_rate,
            channel: 0,
            data_tx: None,
            notify_tx: None,
            lbuffer: Vec::new(),
            rbuffer: Vec::new(),
            time: 0,
        })
    }

    fn init_client(&mut self) {
        let (data_tx, data_rx) = sync_channel(16);
        self.data_tx = Some(data_tx);

        let channel = self.channel;
        let mut event_loop = EventLoop::new().unwrap();
        self.notify_tx = Some(event_loop.channel());
        thread::spawn(move || {
            let addr = format!("127.0.0.1:{}", BASE_PORT + channel).parse().unwrap();
            let client = TcpStream::connect(&addr).unwrap();
            client.set_nodelay(true);
            event_loop.register(&client, CLIENT).unwrap();
            event_loop.run(&mut PacketTransmitter {
                          socket: client,
                          data_rx: data_rx,
                      })
                      .unwrap();
        });
    }

    fn kill_client(&mut self) {
        self.notify_tx.as_ref().unwrap().send(());
    }
}

impl Plugin for Transmitter {
    fn run<'a>(&mut self, sample_count: usize, ports: &[&'a PortConnection<'a>]) {
        let inputl = ports[0].unwrap_audio();
        let inputr = ports[1].unwrap_audio();
        let mut outputl = ports[2].unwrap_audio_mut();
        let mut outputr = ports[3].unwrap_audio_mut();

        let channel = *ports[4].unwrap_control() as u16;

        if channel != self.channel {
            self.channel = channel;
            println!("set channel {}", self.channel);
            self.kill_client();
            self.init_client();
            return;
        }

        let mut need_reboot = false;
        let mut i = 0;
        while i < sample_count {
            while self.lbuffer.len() < BUFFER_SIZE && i < sample_count {
                self.lbuffer.push(inputl[i]);
                self.rbuffer.push(inputr[i]);

                outputl[i] = inputl[i];
                outputr[i] = inputr[i];

                i += 1;
            }

            if self.lbuffer.len() == BUFFER_SIZE {
                let mut packet = Packet::new(&self.lbuffer, &self.rbuffer, self.time);
                self.time += BUFFER_SIZE as u64;

                need_reboot |= self.data_tx.as_ref().unwrap().send(packet).is_err();

                self.lbuffer.clear();
                self.rbuffer.clear();
            }
        }
        if need_reboot {
            self.kill_client();
            self.init_client();
        }
    }

    fn activate(&mut self) {
        println!("activate {}", self.channel);
        self.lbuffer.clear();
        self.rbuffer.clear();
        self.time = 0;
        self.init_client();
    }

    fn deactivate(&mut self) {
        println!("deactivate {}", self.channel);
        self.kill_client();
    }
}

struct PacketTransmitter {
    socket: TcpStream,
    data_rx: mpsc::Receiver<Packet>,
}

impl Handler for PacketTransmitter {
    type Timeout = ();
    type Message = ();

    fn ready(&mut self, event_loop: &mut EventLoop<Self>, token: Token, events: EventSet) {
        match token {
            CLIENT => {
                loop {
                    assert!(events.is_writable());
                    let packet = match self.data_rx.recv() {
                        Ok(p) => p,
                        Err(_) => {
                            println!("err recieving packet from ladspa, channel is dead!");
                            event_loop.shutdown();
                            break;
                        }
                    };
                    match self.socket.write(&packet.as_bytes()[..]) {
                        Ok(num_written) => {
                            if num_written != BYTE_BUFFER_SIZE {
                                println!("incorrect write size: {}", num_written);
                                event_loop.shutdown();
                                break;
                            }
                        }
                        Err(_) => {
                            println!("err writing packet to network!");
                            event_loop.shutdown();
                            break;
                        }
                    }
                }
            }
            _ => panic!("Received unknown token"),
        }
    }

    fn notify(&mut self, event_loop: &mut EventLoop<Self>, msg: Self::Message) {
        self.socket.shutdown(Shutdown::Both);
        event_loop.shutdown();
    }
}
<|endoftext|>