<commit_before>extern crate clap;

fn main() {

}
<commit_msg>Added main cli application<commit_after>extern crate rustylnk;
extern crate clap;
extern crate seek_bufread;
use clap::{App, Arg, ArgMatches};
use seek_bufread::BufReader;
use rustylnk::lnkpkg::lnk::{Lnk};
use std::fs;

fn process_directory(directory: &str, options: &ArgMatches) {
    for entry in fs::read_dir(directory).unwrap() {
        let entry = entry.unwrap();
        let path = entry.path();
        if path.is_file() {
            let path_string = path.into_os_string().into_string().unwrap();
            if path_string.ends_with(".lnk"){
                process_file(&path_string, &options);
            }
        }
    }
}

fn process_file(filename: &str, options: &ArgMatches) -> bool {
    let mut file = match fs::File::open(filename) {
        Ok(file) => file,
        Err(error) => {
            println!("Could not open file: {} [error: {}]", filename, error);
            return false;
        }
    };

    let mut reader = BufReader::new(file);

    let lnk = match Lnk::new(reader) {
        Ok(lnk) => lnk,
        Err(error) => {
            println!("Could not parse file: {} [error: {}]", filename, error);
            return false;
        }
    };

    println!("{:#?}",lnk);

    return true;
}

fn is_directory(source: &str)->bool{
    let metadata = fs::metadata(source).unwrap();

    let file_type = metadata.file_type();

    file_type.is_dir()
}

fn main() {
    let source_arg = Arg::with_name("source")
        .short("s")
        .long("source")
        .value_name("PATH")
        .help("The LNK file or folder with LNK files to parse.")
        .takes_value(true);

    let options = App::new("RusyLnk")
        .version("0.0.0")
        .author("Matthew Seyer <https://github.com/forensicmatt/RustyUsn>")
        .about("LNK Parser written in Rust.")
        .arg(source_arg)   // add the journal parameter
        .get_matches();

    let source = options.value_of("source").unwrap();

    if is_directory(source) {
        process_directory(source,&options);
    } else {
        process_file(source,&options);
    }
}
<|endoftext|>


<commit_before>#![feature(io)]
#![feature(rand)]
#![allow(deprecated)]

use game::{Game};

use std::old_io;

mod game;

fn main() {
    println!("Guess the word game");
    let mut game = Game::new(get_words());
    game_loop(&mut game);
    println!("'{}' - You won!", game.intended_word());
}

fn game_loop(game : &mut Game) {
    loop {
        print!(" {}, {} letters left, ", game.current_progress(), game.letters_left());
        let input = old_io::stdin().read_line().ok().expect("Failed to read line");
        let input_trimed = &input[].trim();
        game.guess(input_trimed);
        if game.letters_left() == 0 {
            break;
        }
    }
}

fn get_words() -> Vec<String> {
    let words = vec![
        "rust",
        "is",
        "the",
        "best",
        "programming",
        "language",
    ];
    words.iter().map(|x| x.to_string()).collect()
}
<commit_msg>Сообщение о победе через одну пустую строку<commit_after>#![feature(io)]
#![feature(rand)]
#![allow(deprecated)]

use game::{Game};

use std::old_io;

mod game;

fn main() {
    println!("Guess the word game");
    let mut game = Game::new(get_words());
    game_loop(&mut game);
    println!("\n'{}' - You won!", game.intended_word());
}

fn game_loop(game : &mut Game) {
    loop {
        print!(" {}, {} letters left, ", game.current_progress(), game.letters_left());
        let input = old_io::stdin().read_line().ok().expect("Failed to read line");
        let input_trimed = &input[].trim();
        game.guess(input_trimed);
        if game.letters_left() == 0 {
            break;
        }
    }
}

fn get_words() -> Vec<String> {
    let words = vec![
        "rust",
        "is",
        "the",
        "best",
        "programming",
        "language",
    ];
    words.iter().map(|x| x.to_string()).collect()
}
<|endoftext|>


<commit_before><commit_msg>convert `_mm256_mask_cmp_epu16_mask` to const generics<commit_after><|endoftext|>


<commit_before>// Implements http://rosettacode.org/wiki/Concurrent_computing
extern crate rand;

use std::io::timer::sleep;
use rand::random;

fn main() {
    let strings = ~[~"Enjoy", ~"Rosetta", ~"Code"];

    for s in strings.move_iter(){
        spawn(proc() {
            // We use a random u8 (so an integer from 0 to 255)
            sleep(random::<u8>() as u64);
            println!("{}", s);
        });
    }
}
<commit_msg>fix concurrent_computing<commit_after>// Implements http://rosettacode.org/wiki/Concurrent_computing
extern crate rand;

use std::io::timer::sleep;
use rand::random;

fn main() {
    let strings = vec!["Enjoy", "Rosetta", "Code"];

    for s in strings.move_iter(){
        spawn(proc() {
            // We use a random u8 (so an integer from 0 to 255)
            sleep(random::<u8>() as u64);
            println!("{}", s);
        });
    }
}
<|endoftext|>


<commit_before>//! Logic for state machine.

use state::State;
use state::UpdateDelta;

pub type UpdateFunction<T, D> = fn (obj: &mut T, delta: &D);

/// A unique identifier for object.
pub struct ObjectId(uint);

/// A unique identifier for state.
pub struct StateId(uint);

/// Keeps track of the current state of objects.
/// Also keeps an update function per state.
/// This is because otherwise all states require same logic.
pub struct StateMachine<Object, Delta> {
    current: State<StateId>,
    states: State<State<Object>>,
    update_functions: State<UpdateFunction<Object, Delta>>
}

impl<T, D> StateMachine<T, D> {
    /// Adds a new state.
    pub fn add_state(
            &mut self,
            StateId(state_id): StateId,
            state: State<T>,
            update: Option<UpdateFunction<T, D>>
    ) {
        self.states.objects.insert(state_id, state);
        match update {
            None => {},
            Some(fun) => { self.update_functions.objects.insert(state_id, fun); }
        }
    }

    /// Adds a new object.
    pub fn add_object(
            &mut self,
            StateId(state_id): StateId,
            ObjectId(obj_id): ObjectId,
            obj: T) {
        self.current.objects.insert(obj_id, StateId(state_id));
        self.states.objects.get_mut(&state_id).objects.insert(obj_id, obj);
    }

    /// Returns the current value of object by looking up in correct state.
    #[inline(always)]
    pub fn val<'a>(&'a self, ObjectId(obj): ObjectId) -> &'a T {
        let &StateId(state) = self.current.objects.get(&obj);
        self.states.objects.get(&state).objects.get(&obj)
    }

    /// Returns the current `state_id` of an object.
    pub fn state_id(&self, ObjectId(obj): ObjectId) -> StateId {
        *self.current.objects.get(&obj)
    }

    /// Returns the current state of an object.
    pub fn state<'a>(&'a self, ObjectId(obj): ObjectId) -> &'a State<T> {
        let &StateId(state) = self.current.objects.get(&obj);
        self.states.objects.get(&state)
    }

    /// Moves an object to a new state.
    pub fn move_to(&mut self, StateId(to): StateId, ObjectId(obj): ObjectId) {
        let &StateId(state) = self.current.objects.get(&obj);
        let pop = self.states.objects.get_mut(&state).objects.pop(&obj);
        match pop {
            None => {},
            Some(val) => { self.states.objects.get_mut(&to).objects.insert(obj, val); }
        }
    }

    /// Removes an object from state machine.
    pub fn pop(&mut self, ObjectId(obj): ObjectId) -> Option<T> {
        let &StateId(state) = self.current.objects.get(&obj);
        self.states.objects.get_mut(&state).objects.pop(&obj)
    }
}

impl<T: UpdateDelta<D>, D>
UpdateDelta<D> for StateMachine<T, D> {
    fn update(&mut self, delta: &D) {
        for (id_state, state) in self.states.objects.mut_iter() {
            match self.update_functions.objects.find(id_state) {
                    None => {},
                    Some(fun) => {
                        for (_, obj) in state.objects.mut_iter() {
                            (*fun)(obj, delta);
                        }
                    }
            }
        }
    }
}

<commit_msg>Added get and get_mut<commit_after>//! Logic for state machine.

use state::State;
use state::UpdateDelta;

pub type UpdateFunction<T, D> = fn (obj: &mut T, delta: &D);

/// A unique identifier for object.
pub struct ObjectId(uint);

/// A unique identifier for state.
pub struct StateId(uint);

/// Keeps track of the current state of objects.
/// Also keeps an update function per state.
/// This is because otherwise all states require same logic.
pub struct StateMachine<Object, Delta> {
    current: State<StateId>,
    states: State<State<Object>>,
    update_functions: State<UpdateFunction<Object, Delta>>
}

impl<T, D> StateMachine<T, D> {
    /// Adds a new state.
    pub fn add_state(
            &mut self,
            StateId(state_id): StateId,
            state: State<T>,
            update: Option<UpdateFunction<T, D>>
    ) {
        self.states.objects.insert(state_id, state);
        match update {
            None => {},
            Some(fun) => { self.update_functions.objects.insert(state_id, fun); }
        }
    }

    /// Adds a new object.
    pub fn add_object(
            &mut self,
            StateId(state_id): StateId,
            ObjectId(obj_id): ObjectId,
            obj: T) {
        self.current.objects.insert(obj_id, StateId(state_id));
        self.states.objects.get_mut(&state_id).objects.insert(obj_id, obj);
    }

    /// Returns a readonly pointer to object.
    #[inline(always)]
    pub fn get<'a>(&'a self, ObjectId(obj): ObjectId) -> &'a T {
        let &StateId(state) = self.current.objects.get(&obj);
        self.states.objects.get(&state).objects.get(&obj)
    }

    /// Returns a mutable pointer to object.
    #[inline(always)]
    pub fn get_mut<'a>(&'a mut self, ObjectId(obj): ObjectId) -> &'a mut T {
        let &StateId(state) = self.current.objects.get(&obj);
        self.states.objects.get_mut(&state).objects.get_mut(&obj)
    }

    /// Returns the current `state_id` of an object.
    pub fn state_id(&self, ObjectId(obj): ObjectId) -> StateId {
        *self.current.objects.get(&obj)
    }

    /// Returns the current state of an object.
    pub fn state<'a>(&'a self, ObjectId(obj): ObjectId) -> &'a State<T> {
        let &StateId(state) = self.current.objects.get(&obj);
        self.states.objects.get(&state)
    }

    /// Moves an object to a new state.
    pub fn move_to(&mut self, StateId(to): StateId, ObjectId(obj): ObjectId) {
        let &StateId(state) = self.current.objects.get(&obj);
        let pop = self.states.objects.get_mut(&state).objects.pop(&obj);
        match pop {
            None => {},
            Some(val) => { self.states.objects.get_mut(&to).objects.insert(obj, val); }
        }
    }

    /// Removes an object from state machine.
    pub fn pop(&mut self, ObjectId(obj): ObjectId) -> Option<T> {
        let &StateId(state) = self.current.objects.get(&obj);
        self.states.objects.get_mut(&state).objects.pop(&obj)
    }
}

impl<T: UpdateDelta<D>, D>
UpdateDelta<D> for StateMachine<T, D> {
    fn update(&mut self, delta: &D) {
        for (id_state, state) in self.states.objects.mut_iter() {
            match self.update_functions.objects.find(id_state) {
                    None => {},
                    Some(fun) => {
                        for (_, obj) in state.objects.mut_iter() {
                            (*fun)(obj, delta);
                        }
                    }
            }
        }
    }
}

<|endoftext|>


<commit_before>//! An operator which captures the streams of records and notifications to play back later.
//!
//! Not yet tested; please be careful using!

use std::rc::Rc;
use std::cell::RefCell;

use ::Data;
use dataflow::{Scope, Stream};
use dataflow::channels::pact::{ParallelizationContract, Pipeline};
use dataflow::channels::pullers::Counter as PullCounter;
use dataflow::channels::pushers::Counter as PushCounter;
use dataflow::channels::pushers::buffer::Buffer as PushBuffer;
use dataflow::channels::pushers::Tee;
use dataflow::channels::message::Content;

use progress::count_map::CountMap;
use progress::nested::subgraph::Source::ChildOutput;
use progress::nested::subgraph::Target::ChildInput;
use progress::{Timestamp, Operate, Antichain};

pub trait Capture<T: Timestamp, D: Data> {
    ///
    ///
    /// #Examples
    /// ```
    /// use timely::dataflow::Scope;
    /// use timely::dataflow::operators::{Capture, ToStream, Inspect};

    /// timely::execute(timely::Configuration::Thread, |computation| {
    ///     let handle = computation.scoped::<u64,_,_>(|builder|
    ///         (0..10).to_stream(builder)
    ///                .capture()
    ///     );
    ///
    ///     computation.scoped(|builder| {
    ///         handle.replay(builder)
    ///               .inspect(|x| println!("replayed: {:?}", x));
    ///     })
    /// });
    /// ```
    fn capture(&self) -> Handle<T, D>;
}

impl<S: Scope, D: Data> Capture<S::Timestamp, D> for Stream<S, D> {
    fn capture(&self) -> Handle<S::Timestamp, D> {

        let events = Rc::new(RefCell::new(EventLink { event: Event::Start, next: None }));
        let handle = Handle { events: events.clone() };

        let mut scope = self.scope();   // clones the scope
        let channel_id = scope.new_identifier();

        let (sender, receiver) = Pipeline.connect(&mut scope, channel_id);
        let operator = CaptureOperator {
            input: PullCounter::new(receiver),
            events: events,
        };

        let index = scope.add_operator(operator);
        self.connect_to(ChildInput(index, 0), sender, channel_id);
        handle
    }
}

/// Possible events that the captured stream may provide.
pub enum Event<T, D> {
    Start,
    /// Progress received via `push_external_progress`.
    Progress(Vec<(T, i64)>),
    /// Messages received via the data stream.
    Messages(T, Content<D>),
}

pub struct EventLink<T, D> {
    event: Event<T, D>,
    next: Option<Rc<RefCell<EventLink<T, D>>>>,
}

// TODO : No notion of streaming garbage collection, which is probably a bug.
// TODO : The whole list will be collected when everyone is done, but perhaps a linked list would
// TODO : be better / have better properties?

/// A handle to the captured data, shared with the capture operator itself.
pub struct Handle<T: Timestamp, D: Data> {
    events: Rc<RefCell<EventLink<T, D>>>,
}

impl<T: Timestamp, D: Data> Handle<T, D> {
    pub fn replay<S: Scope<Timestamp=T>>(&self, scope: &mut S) -> Stream<S, D> {

        let (targets, registrar) = Tee::<S::Timestamp, D>::new();
        let operator = ReplayOperator {
            output: PushBuffer::new(PushCounter::new(targets, Rc::new(RefCell::new(CountMap::new())))),
            events: self.events.clone(),
        };

        let index = scope.add_operator(operator);
        Stream::new(ChildOutput(index, 0), registrar, scope.clone())
    }
}

struct CaptureOperator<T: Timestamp, D: Data> {
    input: PullCounter<T, D>,
    events: Rc<RefCell<EventLink<T, D>>>,
}

impl<T:Timestamp, D: Data> Operate<T> for CaptureOperator<T, D> {
    fn name(&self) -> &str { "Capture" }
    fn inputs(&self) -> usize { 1 }
    fn outputs(&self) -> usize { 0 }

    // we need to set the initial value of the frontier
    fn set_external_summary(&mut self, _: Vec<Vec<Antichain<T::Summary>>>, counts: &mut [CountMap<T>]) {
        self.events.borrow_mut().next = Some(Rc::new(RefCell::new(EventLink { event: Event::Progress(counts[0].updates.clone()), next: None })));
        let next = self.events.borrow().next.as_ref().unwrap().clone();
        self.events = next;
        counts[0].updates.clear();
    }

    // each change to the frontier should be shared
    fn push_external_progress(&mut self, counts: &mut [CountMap<T>]) {
        self.events.borrow_mut().next = Some(Rc::new(RefCell::new(EventLink { event: Event::Progress(counts[0].updates.clone()), next: None })));
        let next = self.events.borrow().next.as_ref().unwrap().clone();
        self.events = next;
        counts[0].updates.clear();
    }

    fn pull_internal_progress(&mut self, _: &mut [CountMap<T>], consumed: &mut [CountMap<T>], _: &mut [CountMap<T>]) -> bool {
        let events = &mut self.events;
        self.input.for_each(|&time, data| {
            events.borrow_mut().next = Some(Rc::new(RefCell::new(EventLink { event: Event::Messages(time, data.clone()), next: None })));
            let next = events.borrow().next.as_ref().unwrap().clone();
            *events = next;
        });
        self.input.pull_progress(&mut consumed[0]);
        false
    }
}

struct ReplayOperator<T:Timestamp, D: Data> {
    events: Rc<RefCell<EventLink<T, D>>>,
    output: PushBuffer<T, D, PushCounter<T, D, Tee<T, D>>>,
}

impl<T:Timestamp, D: Data> Operate<T> for ReplayOperator<T, D> {
    fn name(&self) -> &str { "Replay" }
    fn inputs(&self) -> usize { 0 }
    fn outputs(&self) -> usize { 1 }

    fn get_internal_summary(&mut self) -> (Vec<Vec<Antichain<T::Summary>>>, Vec<CountMap<T>>) {

        // panics if the event link has not been initialized; should only happen if no one has
        // called set_external_summary on the `CaptureOperator`. So, please don't use this in the
        // same graph as the `CaptureOperator`.

        // TODO : use Default::default() as the initial time, and in the first Event we dequeue,
        // TODO : announce that we've moved beyond Default::default().
        let mut result = CountMap::new();
        let next = self.events.borrow().next.as_ref().unwrap().clone();
        self.events = next;
        if let Event::Progress(ref vec) = self.events.borrow().event {
            for &(ref time, delta) in vec {
                result.update(time, delta);
            }
        }
        (vec![], vec![result])
    }

    fn pull_internal_progress(&mut self, internal: &mut [CountMap<T>], _: &mut [CountMap<T>], produced: &mut [CountMap<T>]) -> bool {

        while self.events.borrow().next.is_some() {
            let next = self.events.borrow().next.as_ref().unwrap().clone();
            self.events = next;
            match self.events.borrow().event {
                Event::Start => { },
                Event::Progress(ref vec) => {
                    for &(ref time, delta) in vec {
                        internal[0].update(time, delta);
                    }
                },
                Event::Messages(ref time, ref data) => {
                    let mut data = data.clone();
                    self.output.session(time).give_content(&mut data);
                }
            }
        }

        self.output.cease();
        self.output.inner().pull_progress(&mut produced[0]);

        false
    }
}

#[cfg(test)]
mod tests {

    use ::Configuration;
    use dataflow::*;
    use dataflow::operators::{Capture, ToStream, Inspect};

    #[test]
    fn probe() {

        // initializes and runs a timely dataflow computation
        ::execute(Configuration::Thread, |computation| {
            let handle = computation.scoped::<u64,_,_>(|builder|
                (0..10).to_stream(builder)
                       .capture()
            );

            // computation.step();
            // computation.step();
            // computation.step();

            computation.scoped(|builder| {
                handle.replay(builder)
                      .inspect(|x| println!("replayed: {:?}", x));
            })
        });
    }

}
<commit_msg>documentation/test update for capture<commit_after>//! An operator which captures the streams of records and notifications to play back later.
//!
//! Not yet tested; please be careful using!

use std::rc::Rc;
use std::cell::RefCell;

use ::Data;
use dataflow::{Scope, Stream};
use dataflow::channels::pact::{ParallelizationContract, Pipeline};
use dataflow::channels::pullers::Counter as PullCounter;
use dataflow::channels::pushers::Counter as PushCounter;
use dataflow::channels::pushers::buffer::Buffer as PushBuffer;
use dataflow::channels::pushers::Tee;
use dataflow::channels::message::Content;

use progress::count_map::CountMap;
use progress::nested::subgraph::Source::ChildOutput;
use progress::nested::subgraph::Target::ChildInput;
use progress::{Timestamp, Operate, Antichain};

pub trait Capture<T: Timestamp, D: Data> {
    ///
    ///
    /// #Examples
    /// ```
    /// use timely::dataflow::Scope;
    /// use timely::dataflow::operators::{Capture, ToStream, Inspect};
    ///
    /// timely::execute(timely::Configuration::Thread, |computation| {
    ///     let handle = computation.scoped::<u64,_,_>(|builder|
    ///         (0..10).to_stream(builder)
    ///                .capture()
    ///     );
    ///
    ///     computation.scoped(|builder| {
    ///         handle.replay(builder)
    ///               .inspect(|x| println!("replayed: {:?}", x));
    ///     })
    /// });
    /// ```
    fn capture(&self) -> Handle<T, D>;
}

impl<S: Scope, D: Data> Capture<S::Timestamp, D> for Stream<S, D> {
    fn capture(&self) -> Handle<S::Timestamp, D> {

        let events = Rc::new(RefCell::new(EventLink { event: Event::Start, next: None }));
        let handle = Handle { events: events.clone() };

        let mut scope = self.scope();   // clones the scope
        let channel_id = scope.new_identifier();

        let (sender, receiver) = Pipeline.connect(&mut scope, channel_id);
        let operator = CaptureOperator {
            input: PullCounter::new(receiver),
            events: events,
        };

        let index = scope.add_operator(operator);
        self.connect_to(ChildInput(index, 0), sender, channel_id);
        handle
    }
}

/// Possible events that the captured stream may provide.
pub enum Event<T, D> {
    Start,
    /// Progress received via `push_external_progress`.
    Progress(Vec<(T, i64)>),
    /// Messages received via the data stream.
    Messages(T, Content<D>),
}

pub struct EventLink<T, D> {
    event: Event<T, D>,
    next: Option<Rc<RefCell<EventLink<T, D>>>>,
}

// TODO : No notion of streaming garbage collection, which is probably a bug.
// TODO : The whole list will be collected when everyone is done, but perhaps a linked list would
// TODO : be better / have better properties?

/// A handle to the captured data, shared with the capture operator itself.
pub struct Handle<T: Timestamp, D: Data> {
    pub events: Rc<RefCell<EventLink<T, D>>>,
}

impl<T: Timestamp, D: Data> Handle<T, D> {
    pub fn replay<S: Scope<Timestamp=T>>(&self, scope: &mut S) -> Stream<S, D> {

        let (targets, registrar) = Tee::<S::Timestamp, D>::new();
        let operator = ReplayOperator {
            output: PushBuffer::new(PushCounter::new(targets, Rc::new(RefCell::new(CountMap::new())))),
            events: self.events.clone(),
        };

        let index = scope.add_operator(operator);
        Stream::new(ChildOutput(index, 0), registrar, scope.clone())
    }
}

struct CaptureOperator<T: Timestamp, D: Data> {
    input: PullCounter<T, D>,
    events: Rc<RefCell<EventLink<T, D>>>,
}

impl<T:Timestamp, D: Data> Operate<T> for CaptureOperator<T, D> {
    fn name(&self) -> &str { "Capture" }
    fn inputs(&self) -> usize { 1 }
    fn outputs(&self) -> usize { 0 }

    // we need to set the initial value of the frontier
    fn set_external_summary(&mut self, _: Vec<Vec<Antichain<T::Summary>>>, counts: &mut [CountMap<T>]) {
        self.events.borrow_mut().next = Some(Rc::new(RefCell::new(EventLink { event: Event::Progress(counts[0].updates.clone()), next: None })));
        let next = self.events.borrow().next.as_ref().unwrap().clone();
        self.events = next;
        counts[0].updates.clear();
    }

    // each change to the frontier should be shared
    fn push_external_progress(&mut self, counts: &mut [CountMap<T>]) {
        self.events.borrow_mut().next = Some(Rc::new(RefCell::new(EventLink { event: Event::Progress(counts[0].updates.clone()), next: None })));
        let next = self.events.borrow().next.as_ref().unwrap().clone();
        self.events = next;
        counts[0].updates.clear();
    }

    fn pull_internal_progress(&mut self, _: &mut [CountMap<T>], consumed: &mut [CountMap<T>], _: &mut [CountMap<T>]) -> bool {
        let events = &mut self.events;
        self.input.for_each(|&time, data| {
            events.borrow_mut().next = Some(Rc::new(RefCell::new(EventLink { event: Event::Messages(time, data.clone()), next: None })));
            let next = events.borrow().next.as_ref().unwrap().clone();
            *events = next;
        });
        self.input.pull_progress(&mut consumed[0]);
        false
    }
}

struct ReplayOperator<T:Timestamp, D: Data> {
    events: Rc<RefCell<EventLink<T, D>>>,
    output: PushBuffer<T, D, PushCounter<T, D, Tee<T, D>>>,
}

impl<T:Timestamp, D: Data> Operate<T> for ReplayOperator<T, D> {
    fn name(&self) -> &str { "Replay" }
    fn inputs(&self) -> usize { 0 }
    fn outputs(&self) -> usize { 1 }

    fn get_internal_summary(&mut self) -> (Vec<Vec<Antichain<T::Summary>>>, Vec<CountMap<T>>) {

        // panics if the event link has not been initialized; should only happen if no one has
        // called set_external_summary on the `CaptureOperator`. So, please don't use this in the
        // same graph as the `CaptureOperator`.

        // TODO : use Default::default() as the initial time, and in the first Event we dequeue,
        // TODO : announce that we've moved beyond Default::default().
        let mut result = CountMap::new();
        let next = self.events.borrow().next.as_ref().unwrap().clone();
        self.events = next;
        if let Event::Progress(ref vec) = self.events.borrow().event {
            for &(ref time, delta) in vec {
                result.update(time, delta);
            }
        }
        (vec![], vec![result])
    }

    fn pull_internal_progress(&mut self, internal: &mut [CountMap<T>], _: &mut [CountMap<T>], produced: &mut [CountMap<T>]) -> bool {

        while self.events.borrow().next.is_some() {
            let next = self.events.borrow().next.as_ref().unwrap().clone();
            self.events = next;
            match self.events.borrow().event {
                Event::Start => { },
                Event::Progress(ref vec) => {
                    for &(ref time, delta) in vec {
                        internal[0].update(time, delta);
                    }
                },
                Event::Messages(ref time, ref data) => {
                    let mut data = data.clone();
                    self.output.session(time).give_content(&mut data);
                }
            }
        }

        self.output.cease();
        self.output.inner().pull_progress(&mut produced[0]);

        false
    }
}

#[cfg(test)]
mod tests {

    use ::Configuration;
    use dataflow::*;
    use dataflow::operators::{Capture, ToStream, Inspect};

    #[test]
    fn probe() {

        // initializes and runs a timely dataflow computation
        ::execute(Configuration::Thread, |computation| {
            let handle = computation.scoped::<u64,_,_>(|builder|
                (0..10).to_stream(builder)
                       .capture()
            );

            // computation.step();
            // computation.step();
            // computation.step();

            computation.scoped(|builder| {
                handle.replay(builder)
                      .inspect(|x| println!("replayed: {:?}", x));
            })
        });
    }

}
<|endoftext|>


<commit_before>// Copyright 2018 Syn Developers
//
// 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.

extern crate proc_macro2;
extern crate syn;
extern crate syntax;
extern crate syntax_pos;

use self::syntax::ast;
use self::syntax::codemap::FilePathMapping;
use self::syntax::parse::{self, ParseSess};
use self::syntax::ptr::P;
use self::syntax_pos::FileName;

use std::panic;

use self::syn::buffer::TokenBuffer;
use self::syn::synom::Synom;

pub fn libsyntax_expr(input: &str) -> Option<P<ast::Expr>> {
    match panic::catch_unwind(|| {
        let sess = ParseSess::new(FilePathMapping::empty());
        sess.span_diagnostic.set_continue_after_error(false);
        let e = parse::parse_expr_from_source_str(
            FileName::Custom("test_precedence".to_string()),
            input.to_string(),
            &sess,
        );
        Some(match e {
            Ok(expr) => expr,
            Err(mut diagnostic) => {
                diagnostic.emit();;
                return None;
            }
        })
    }) {
        Ok(Some(e)) => Some(e),
        Ok(None) => None,
        Err(_) => {
            errorf!("libsyntax panicked\n");
            None
        }
    }
}

pub fn syn_expr(input: &str) -> Option<syn::Expr> {
    match syn::parse_str(input) {
        Ok(e) => Some(e),
        Err(msg) => {
            errorf!("syn failed to parse\n{:?}\n", msg);
            None
        }
    }
}

pub fn syn<T: Synom>(tokens: proc_macro2::TokenStream) -> T {
    let buf = TokenBuffer::new2(tokens);
    let result = T::parse(buf.begin());
    match result {
        Ok((t, rest)) => {
            if rest.eof() {
                t
            } else if rest == buf.begin() {
                panic!("failed to parse anything")
            } else {
                panic!("failed to parse all tokens")
            }
        }
        Err(err) => panic!("failed to parse: {}", err),
    }
}
<commit_msg>Update nightly libsyntax api for parsing an expr<commit_after>// Copyright 2018 Syn Developers
//
// 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.

extern crate proc_macro2;
extern crate syn;
extern crate syntax;
extern crate syntax_pos;

use self::syntax::ast;
use self::syntax::codemap::FilePathMapping;
use self::syntax::parse::{self, ParseSess};
use self::syntax::ptr::P;
use self::syntax_pos::FileName;

use std::panic;

use self::syn::buffer::TokenBuffer;
use self::syn::synom::Synom;

pub fn libsyntax_expr(input: &str) -> Option<P<ast::Expr>> {
    match panic::catch_unwind(|| {
        let sess = ParseSess::new(FilePathMapping::empty());
        sess.span_diagnostic.set_continue_after_error(false);
        let e = parse::new_parser_from_source_str(
            &sess,
            FileName::Custom("test_precedence".to_string()),
            input.to_string(),
        ).parse_expr();
        Some(match e {
            Ok(expr) => expr,
            Err(mut diagnostic) => {
                diagnostic.emit();;
                return None;
            }
        })
    }) {
        Ok(Some(e)) => Some(e),
        Ok(None) => None,
        Err(_) => {
            errorf!("libsyntax panicked\n");
            None
        }
    }
}

pub fn syn_expr(input: &str) -> Option<syn::Expr> {
    match syn::parse_str(input) {
        Ok(e) => Some(e),
        Err(msg) => {
            errorf!("syn failed to parse\n{:?}\n", msg);
            None
        }
    }
}

pub fn syn<T: Synom>(tokens: proc_macro2::TokenStream) -> T {
    let buf = TokenBuffer::new2(tokens);
    let result = T::parse(buf.begin());
    match result {
        Ok((t, rest)) => {
            if rest.eof() {
                t
            } else if rest == buf.begin() {
                panic!("failed to parse anything")
            } else {
                panic!("failed to parse all tokens")
            }
        }
        Err(err) => panic!("failed to parse: {}", err),
    }
}
<|endoftext|>


<commit_before>use core::{ascii, mem};
use alloc::string::String;
use alloc::vec::Vec;

use super::data::{Map, Stat, TimeSpec};
use super::flag::*;
use super::number::*;
use super::validate::*;

struct ByteStr<'a>(&'a[u8]);

impl<'a> ::core::fmt::Debug for ByteStr<'a> {
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        write!(f, "\"")?;
        for i in self.0 {
            for ch in ascii::escape_default(*i) {
                write!(f, "{}", ch as char)?;
            }
        }
        write!(f, "\"")?;
        Ok(())
    }
}

pub fn format_call(a: usize, b: usize, c: usize, d: usize, e: usize, f: usize) -> String {
    match a {
        SYS_OPEN => format!(
            "open({:?}, {:#X})",
            validate_slice(b as *const u8, c).map(ByteStr),
            d
        ),
        SYS_CHMOD => format!(
            "chmod({:?}, {:#o})",
            validate_slice(b as *const u8, c).map(ByteStr),
            d
        ),
        SYS_RMDIR => format!(
            "rmdir({:?})",
            validate_slice(b as *const u8, c).map(ByteStr)
        ),
        SYS_UNLINK => format!(
            "unlink({:?})",
            validate_slice(b as *const u8, c).map(ByteStr)
        ),
        SYS_CLOSE => format!(
            "close({})", b
        ),
        SYS_DUP => format!(
            "dup({}, {:?})",
            b,
            validate_slice(c as *const u8, d).map(ByteStr)
        ),
        SYS_DUP2 => format!(
            "dup2({}, {}, {:?})",
            b,
            c,
            validate_slice(d as *const u8, e).map(ByteStr)
        ),
        SYS_READ => format!(
            "read({}, {:#X}, {})",
            b,
            c,
            d
        ),
        SYS_WRITE => format!(
            "write({}, {:#X}, {})",
            b,
            c,
            d
        ),
        SYS_LSEEK => format!(
            "lseek({}, {}, {} ({}))",
            b,
            c as isize,
            match d {
                SEEK_SET => "SEEK_SET",
                SEEK_CUR => "SEEK_CUR",
                SEEK_END => "SEEK_END",
                _ => "UNKNOWN"
            },
            d
        ),
        SYS_FCNTL => format!(
            "fcntl({}, {} ({}), {:#X})",
            b,
            match c {
                F_DUPFD => "F_DUPFD",
                F_GETFD => "F_GETFD",
                F_SETFD => "F_SETFD",
                F_SETFL => "F_SETFL",
                F_GETFL => "F_GETFL",
                _ => "UNKNOWN"
            },
            c,
            d
        ),
        SYS_FMAP => format!(
            "fmap({}, {:?})",
            b,
            validate_slice(
                c as *const Map,
                d/mem::size_of::<Map>()
            ),
        ),
        SYS_FUNMAP => format!(
            "funmap({:#X})",
            b
        ),
        SYS_FPATH => format!(
            "fpath({}, {:#X}, {})",
            b,
            c,
            d
        ),
        SYS_FSTAT => format!(
            "fstat({}, {:?})",
            b,
            validate_slice(
                c as *const Stat,
                d/mem::size_of::<Stat>()
            ),
        ),
        SYS_FSTATVFS => format!(
            "fstatvfs({}, {:#X}, {})",
            b,
            c,
            d
        ),
        SYS_FSYNC => format!(
            "fsync({})",
            b
        ),
        SYS_FTRUNCATE => format!(
            "ftruncate({}, {})",
            b,
            c
        ),

        SYS_BRK => format!(
            "brk({:#X})",
            b
        ),
        SYS_CHDIR => format!(
            "chdir({:?})",
            validate_slice(b as *const u8, c).map(ByteStr)
        ),
        SYS_CLOCK_GETTIME => format!(
            "clock_gettime({}, {:?})",
            b,
            validate_slice_mut(c as *mut TimeSpec, 1)
        ),
        SYS_CLONE => format!(
            "clone({})",
            b
        ),
        SYS_EXIT => format!(
            "exit({})",
            b
        ),
        //TODO: Cleanup, do not allocate
        SYS_FEXEC => format!(
            "fexec({}, {:?}, {:?})",
            b,
            validate_slice(
                c as *const [usize; 2],
                d
            ).map(|slice| {
                slice.iter().map(|a|
                    validate_slice(a[0] as *const u8, a[1]).ok()
                    .and_then(|s| ::core::str::from_utf8(s).ok())
                ).collect::<Vec<Option<&str>>>()
            }),
            validate_slice(
                e as *const [usize; 2],
                f
            ).map(|slice| {
                slice.iter().map(|a|
                    validate_slice(a[0] as *const u8, a[1]).ok()
                    .and_then(|s| ::core::str::from_utf8(s).ok())
                ).collect::<Vec<Option<&str>>>()
            })
        ),
        SYS_FUTEX => format!(
            "futex({:#X} [{:?}], {}, {}, {}, {})",
            b,
            validate_slice_mut(b as *mut i32, 1).map(|uaddr| &mut uaddr[0]),
            c,
            d,
            e,
            f
        ),
        SYS_GETCWD => format!(
            "getcwd({:#X}, {})",
            b,
            c
        ),
        SYS_GETEGID => format!("getegid()"),
        SYS_GETENS => format!("getens()"),
        SYS_GETEUID => format!("geteuid()"),
        SYS_GETGID => format!("getgid()"),
        SYS_GETNS => format!("getns()"),
        SYS_GETPID => format!("getpid()"),
        SYS_GETUID => format!("getuid()"),
        SYS_IOPL => format!(
            "iopl({})",
            b
        ),
        SYS_KILL => format!(
            "kill({}, {})",
            b,
            c
        ),
        SYS_SIGRETURN => format!("sigreturn()"),
        SYS_SIGACTION => format!(
            "sigaction({}, {:#X}, {:#X}, {:#X})",
            b,
            c,
            d,
            e
        ),
        SYS_SIGPROCMASK => format!(
            "sigprocmask({}, {:?}, {:?})",
            b,
            validate_slice(c as *const [u64; 2], 1),
            validate_slice(d as *const [u64; 2], 1)
        ),
        SYS_MKNS => format!(
            "mkns({:?})",
            validate_slice(b as *const [usize; 2], c)
        ),
        SYS_MPROTECT => format!(
            "mprotect({:#X}, {}, {:#X})",
            b,
            c,
            d
        ),
        SYS_NANOSLEEP => format!(
            "nanosleep({:?}, ({}, {}))",
            validate_slice(b as *const TimeSpec, 1),
            c,
            d
        ),
        SYS_PHYSALLOC => format!(
            "physalloc({})",
            b
        ),
        SYS_PHYSFREE => format!(
            "physfree({:#X}, {})",
            b,
            c
        ),
        SYS_PHYSMAP => format!(
            "physmap({:#X}, {}, {:#X})",
            b,
            c,
            d
        ),
        SYS_PHYSUNMAP => format!(
            "physunmap({:#X})",
            b
        ),
        SYS_VIRTTOPHYS => format!(
            "virttophys({:#X})",
            b
        ),
        SYS_PIPE2 => format!(
            "pipe2({:?}, {})",
            validate_slice_mut(b as *mut usize, 2),
            c
        ),
        SYS_SETREGID => format!(
            "setregid({}, {})",
            b,
            c
        ),
        SYS_SETRENS => format!(
            "setrens({}, {})",
            b,
            c
        ),
        SYS_SETREUID => format!(
            "setreuid({}, {})",
            b,
            c
        ),
        SYS_UMASK => format!(
            "umask({:#o}",
            b
        ),
        SYS_WAITPID => format!(
            "waitpid({}, {:#X}, {})",
            b,
            c,
            d
        ),
        SYS_YIELD => format!("yield()"),
        _ => format!(
            "UNKNOWN{} {:#X}({:#X}, {:#X}, {:#X}, {:#X}, {:#X})",
            a, a,
            b,
            c,
            d,
            e,
            f
        )
    }
}
<commit_msg>Add missing debug definitions<commit_after>use core::{ascii, mem};
use alloc::string::String;
use alloc::vec::Vec;

use super::data::{Map, Stat, TimeSpec};
use super::flag::*;
use super::number::*;
use super::validate::*;

struct ByteStr<'a>(&'a[u8]);

impl<'a> ::core::fmt::Debug for ByteStr<'a> {
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        write!(f, "\"")?;
        for i in self.0 {
            for ch in ascii::escape_default(*i) {
                write!(f, "{}", ch as char)?;
            }
        }
        write!(f, "\"")?;
        Ok(())
    }
}

pub fn format_call(a: usize, b: usize, c: usize, d: usize, e: usize, f: usize) -> String {
    match a {
        SYS_OPEN => format!(
            "open({:?}, {:#X})",
            validate_slice(b as *const u8, c).map(ByteStr),
            d
        ),
        SYS_CHMOD => format!(
            "chmod({:?}, {:#o})",
            validate_slice(b as *const u8, c).map(ByteStr),
            d
        ),
        SYS_RMDIR => format!(
            "rmdir({:?})",
            validate_slice(b as *const u8, c).map(ByteStr)
        ),
        SYS_UNLINK => format!(
            "unlink({:?})",
            validate_slice(b as *const u8, c).map(ByteStr)
        ),
        SYS_CLOSE => format!(
            "close({})", b
        ),
        SYS_DUP => format!(
            "dup({}, {:?})",
            b,
            validate_slice(c as *const u8, d).map(ByteStr)
        ),
        SYS_DUP2 => format!(
            "dup2({}, {}, {:?})",
            b,
            c,
            validate_slice(d as *const u8, e).map(ByteStr)
        ),
        SYS_READ => format!(
            "read({}, {:#X}, {})",
            b,
            c,
            d
        ),
        SYS_WRITE => format!(
            "write({}, {:#X}, {})",
            b,
            c,
            d
        ),
        SYS_LSEEK => format!(
            "lseek({}, {}, {} ({}))",
            b,
            c as isize,
            match d {
                SEEK_SET => "SEEK_SET",
                SEEK_CUR => "SEEK_CUR",
                SEEK_END => "SEEK_END",
                _ => "UNKNOWN"
            },
            d
        ),
        SYS_FCHMOD => format!(
            "fchmod({}, {:#o})",
            b,
            c
        ),
        SYS_FCHOWN => format!(
            "fchown({}, {}, {})",
            b,
            c,
            d
        ),
        SYS_FCNTL => format!(
            "fcntl({}, {} ({}), {:#X})",
            b,
            match c {
                F_DUPFD => "F_DUPFD",
                F_GETFD => "F_GETFD",
                F_SETFD => "F_SETFD",
                F_SETFL => "F_SETFL",
                F_GETFL => "F_GETFL",
                _ => "UNKNOWN"
            },
            c,
            d
        ),
        SYS_FMAP => format!(
            "fmap({}, {:?})",
            b,
            validate_slice(
                c as *const Map,
                d/mem::size_of::<Map>()
            ),
        ),
        SYS_FUNMAP => format!(
            "funmap({:#X})",
            b
        ),
        SYS_FPATH => format!(
            "fpath({}, {:#X}, {})",
            b,
            c,
            d
        ),
        SYS_FRENAME => format!(
            "frename({}, {:?})",
            b,
            validate_slice(c as *const u8, d).map(ByteStr),
        ),
        SYS_FSTAT => format!(
            "fstat({}, {:?})",
            b,
            validate_slice(
                c as *const Stat,
                d/mem::size_of::<Stat>()
            ),
        ),
        SYS_FSTATVFS => format!(
            "fstatvfs({}, {:#X}, {})",
            b,
            c,
            d
        ),
        SYS_FSYNC => format!(
            "fsync({})",
            b
        ),
        SYS_FTRUNCATE => format!(
            "ftruncate({}, {})",
            b,
            c
        ),
        SYS_FUTIMENS => format!(
            "futimens({}, {:?})",
            b,
            validate_slice(
                c as *const TimeSpec,
                d/mem::size_of::<TimeSpec>()
            ),
        ),

        SYS_BRK => format!(
            "brk({:#X})",
            b
        ),
        SYS_CHDIR => format!(
            "chdir({:?})",
            validate_slice(b as *const u8, c).map(ByteStr)
        ),
        SYS_CLOCK_GETTIME => format!(
            "clock_gettime({}, {:?})",
            b,
            validate_slice_mut(c as *mut TimeSpec, 1)
        ),
        SYS_CLONE => format!(
            "clone({})",
            b
        ),
        SYS_EXIT => format!(
            "exit({})",
            b
        ),
        //TODO: Cleanup, do not allocate
        SYS_FEXEC => format!(
            "fexec({}, {:?}, {:?})",
            b,
            validate_slice(
                c as *const [usize; 2],
                d
            ).map(|slice| {
                slice.iter().map(|a|
                    validate_slice(a[0] as *const u8, a[1]).ok()
                    .and_then(|s| ::core::str::from_utf8(s).ok())
                ).collect::<Vec<Option<&str>>>()
            }),
            validate_slice(
                e as *const [usize; 2],
                f
            ).map(|slice| {
                slice.iter().map(|a|
                    validate_slice(a[0] as *const u8, a[1]).ok()
                    .and_then(|s| ::core::str::from_utf8(s).ok())
                ).collect::<Vec<Option<&str>>>()
            })
        ),
        SYS_FUTEX => format!(
            "futex({:#X} [{:?}], {}, {}, {}, {})",
            b,
            validate_slice_mut(b as *mut i32, 1).map(|uaddr| &mut uaddr[0]),
            c,
            d,
            e,
            f
        ),
        SYS_GETCWD => format!(
            "getcwd({:#X}, {})",
            b,
            c
        ),
        SYS_GETEGID => format!("getegid()"),
        SYS_GETENS => format!("getens()"),
        SYS_GETEUID => format!("geteuid()"),
        SYS_GETGID => format!("getgid()"),
        SYS_GETNS => format!("getns()"),
        SYS_GETPGID => format!("getpgid()"),
        SYS_GETPID => format!("getpid()"),
        SYS_GETPPID => format!("getppid()"),
        SYS_GETUID => format!("getuid()"),
        SYS_IOPL => format!(
            "iopl({})",
            b
        ),
        SYS_KILL => format!(
            "kill({}, {})",
            b,
            c
        ),
        SYS_SIGRETURN => format!("sigreturn()"),
        SYS_SIGACTION => format!(
            "sigaction({}, {:#X}, {:#X}, {:#X})",
            b,
            c,
            d,
            e
        ),
        SYS_SIGPROCMASK => format!(
            "sigprocmask({}, {:?}, {:?})",
            b,
            validate_slice(c as *const [u64; 2], 1),
            validate_slice(d as *const [u64; 2], 1)
        ),
        SYS_MKNS => format!(
            "mkns({:?})",
            validate_slice(b as *const [usize; 2], c)
        ),
        SYS_MPROTECT => format!(
            "mprotect({:#X}, {}, {:#X})",
            b,
            c,
            d
        ),
        SYS_NANOSLEEP => format!(
            "nanosleep({:?}, ({}, {}))",
            validate_slice(b as *const TimeSpec, 1),
            c,
            d
        ),
        SYS_PHYSALLOC => format!(
            "physalloc({})",
            b
        ),
        SYS_PHYSFREE => format!(
            "physfree({:#X}, {})",
            b,
            c
        ),
        SYS_PHYSMAP => format!(
            "physmap({:#X}, {}, {:#X})",
            b,
            c,
            d
        ),
        SYS_PHYSUNMAP => format!(
            "physunmap({:#X})",
            b
        ),
        SYS_VIRTTOPHYS => format!(
            "virttophys({:#X})",
            b
        ),
        SYS_PIPE2 => format!(
            "pipe2({:?}, {})",
            validate_slice_mut(b as *mut usize, 2),
            c
        ),
        SYS_SETREGID => format!(
            "setregid({}, {})",
            b,
            c
        ),
        SYS_SETRENS => format!(
            "setrens({}, {})",
            b,
            c
        ),
        SYS_SETREUID => format!(
            "setreuid({}, {})",
            b,
            c
        ),
        SYS_UMASK => format!(
            "umask({:#o}",
            b
        ),
        SYS_WAITPID => format!(
            "waitpid({}, {:#X}, {})",
            b,
            c,
            d
        ),
        SYS_YIELD => format!("yield()"),
        _ => format!(
            "UNKNOWN{} {:#X}({:#X}, {:#X}, {:#X}, {:#X}, {:#X})",
            a, a,
            b,
            c,
            d,
            e,
            f
        )
    }
}
<|endoftext|>


<commit_before>use libc;
use std::str::FromStr;
use std::cmp::{self,Ord};
use std::sync::{Mutex, Once, ONCE_INIT};
use std::cell::RefCell;
use std::fmt::{Arguments,format,write};
use std::io::{stdout,Stdout,Write};
use std::ascii::AsciiExt;
use std::net::{SocketAddr,UdpSocket};
use std::net::TcpStream;
use mio_uds::UnixDatagram;

lazy_static! {
  pub static ref LOGGER: Mutex<Logger> = Mutex::new(Logger::new());
  pub static ref PID:    i32 = unsafe { libc::getpid() };
}

pub struct Logger {
  directives: Vec<LogDirective>,
  backend:    LoggerBackend,
}

impl Logger {
  pub fn new() -> Logger {
    Logger {
      directives: vec!(LogDirective {
        name:  None,
        level: LogLevelFilter::Error,
      }),
      backend: LoggerBackend::Stdout(stdout())
    }
  }

  pub fn init(spec: &str, backend: LoggerBackend) {
    let directives = parse_logging_spec(spec);
    if let Ok(ref mut logger) = LOGGER.lock() {
      logger.set_directives(directives);
      logger.backend = backend;
    }
  }

  pub fn log<'a>(&mut self, meta: &LogMetadata, args: Arguments) {
    if self.enabled(meta) {
      match self.backend {
        LoggerBackend::Stdout(ref mut stdout) => {
          stdout.write_fmt(args);
        },
        //FIXME: should have a buffer to write to instead of allocating a string
        LoggerBackend::Unix(ref mut socket) => {
          socket.send(format(args).as_bytes());
        },
        //FIXME: should have a buffer to write to instead of allocating a string
        LoggerBackend::Udp(ref mut socket, ref address) => {
          socket.send_to(format(args).as_bytes(), address);
        }
        LoggerBackend::Tcp(ref mut socket) => {
          socket.write_fmt(args);
        },
      }
    }
  }

  pub fn set_directives(&mut self, directives: Vec<LogDirective>) {
    self.directives = directives;
  }

  fn enabled(&self, meta: &LogMetadata) -> bool {
    // Search for the longest match, the vector is assumed to be pre-sorted.
    for directive in self.directives.iter().rev() {
      match directive.name {
        Some(ref name) if !meta.target.starts_with(&**name) => {},
        Some(..) | None => {
          return meta.level <= directive.level
        }
      }
    }
    false
  }
}

#[derive(Debug)]
pub enum LoggerBackend {
  Stdout(Stdout),
  Unix(UnixDatagram),
  Udp(UdpSocket, SocketAddr),
  Tcp(TcpStream)
}

#[repr(usize)]
#[derive(Copy, Eq, Debug)]
pub enum LogLevel {
    /// The "error" level.
    ///
    /// Designates very serious errors.
    Error = 1, // This way these line up with the discriminants for LogLevelFilter below
    /// The "warn" level.
    ///
    /// Designates hazardous situations.
    Warn,
    /// The "info" level.
    ///
    /// Designates useful information.
    Info,
    /// The "debug" level.
    ///
    /// Designates lower priority information.
    Debug,
    /// The "trace" level.
    ///
    /// Designates very low priority, often extremely verbose, information.
    Trace,
}

static LOG_LEVEL_NAMES: [&'static str; 6] = ["OFF", "ERROR", "WARN", "INFO",
                                             "DEBUG", "TRACE"];

impl Clone for LogLevel {
    #[inline]
    fn clone(&self) -> LogLevel {
        *self
    }
}

impl PartialEq for LogLevel {
    #[inline]
    fn eq(&self, other: &LogLevel) -> bool {
        *self as usize == *other as usize
    }
}

impl PartialEq<LogLevelFilter> for LogLevel {
    #[inline]
    fn eq(&self, other: &LogLevelFilter) -> bool {
        *self as usize == *other as usize
    }
}

impl PartialOrd for LogLevel {
    #[inline]
    fn partial_cmp(&self, other: &LogLevel) -> Option<cmp::Ordering> {
        Some(self.cmp(other))
    }
}

impl PartialOrd<LogLevelFilter> for LogLevel {
    #[inline]
    fn partial_cmp(&self, other: &LogLevelFilter) -> Option<cmp::Ordering> {
        Some((*self as usize).cmp(&(*other as usize)))
    }
}

impl Ord for LogLevel {
    #[inline]
    fn cmp(&self, other: &LogLevel) -> cmp::Ordering {
        (*self as usize).cmp(&(*other as usize))
    }
}

impl LogLevel {
    fn from_usize(u: usize) -> Option<LogLevel> {
        match u {
            1 => Some(LogLevel::Error),
            2 => Some(LogLevel::Warn),
            3 => Some(LogLevel::Info),
            4 => Some(LogLevel::Debug),
            5 => Some(LogLevel::Trace),
            _ => None
        }
    }

    /// Returns the most verbose logging level.
    #[inline]
    pub fn max() -> LogLevel {
        LogLevel::Trace
    }

    /// Converts the `LogLevel` to the equivalent `LogLevelFilter`.
    #[inline]
    pub fn to_log_level_filter(&self) -> LogLevelFilter {
        LogLevelFilter::from_usize(*self as usize).unwrap()
    }
}

#[repr(usize)]
#[derive(Copy, Eq, Debug)]
pub enum LogLevelFilter {
    Off,
    Error,
    Warn,
    Info,
    Debug,
    Trace,
}

impl Clone for LogLevelFilter {
    #[inline]
    fn clone(&self) -> LogLevelFilter {
        *self
    }
}

impl PartialEq for LogLevelFilter {
    #[inline]
    fn eq(&self, other: &LogLevelFilter) -> bool {
        *self as usize == *other as usize
    }
}

impl PartialEq<LogLevel> for LogLevelFilter {
    #[inline]
    fn eq(&self, other: &LogLevel) -> bool {
        other.eq(self)
    }
}

impl PartialOrd for LogLevelFilter {
    #[inline]
    fn partial_cmp(&self, other: &LogLevelFilter) -> Option<cmp::Ordering> {
        Some(self.cmp(other))
    }
}

impl PartialOrd<LogLevel> for LogLevelFilter {
    #[inline]
    fn partial_cmp(&self, other: &LogLevel) -> Option<cmp::Ordering> {
        other.partial_cmp(self).map(|x| x.reverse())
    }
}

impl Ord for LogLevelFilter {
    #[inline]
    fn cmp(&self, other: &LogLevelFilter) -> cmp::Ordering {
        (*self as usize).cmp(&(*other as usize))
    }
}

impl FromStr for LogLevelFilter {
    type Err = ();
    fn from_str(level: &str) -> Result<LogLevelFilter, ()> {
        ok_or(LOG_LEVEL_NAMES.iter()
                    .position(|&name| name.eq_ignore_ascii_case(level))
                    .map(|p| LogLevelFilter::from_usize(p).unwrap()), ())
    }
}

impl LogLevelFilter {
    fn from_usize(u: usize) -> Option<LogLevelFilter> {
        match u {
            0 => Some(LogLevelFilter::Off),
            1 => Some(LogLevelFilter::Error),
            2 => Some(LogLevelFilter::Warn),
            3 => Some(LogLevelFilter::Info),
            4 => Some(LogLevelFilter::Debug),
            5 => Some(LogLevelFilter::Trace),
            _ => None
        }
    }
    /// Returns the most verbose logging level filter.
    #[inline]
    pub fn max() -> LogLevelFilter {
        LogLevelFilter::Trace
    }

    /// Converts `self` to the equivalent `LogLevel`.
    ///
    /// Returns `None` if `self` is `LogLevelFilter::Off`.
    #[inline]
    pub fn to_log_level(&self) -> Option<LogLevel> {
        LogLevel::from_usize(*self as usize)
    }
}

/// Metadata about a log message.
pub struct LogMetadata {
  pub level:  LogLevel,
  pub target: &'static str,
}

pub struct LogDirective {
    name:  Option<String>,
    level: LogLevelFilter,
}

fn ok_or<T, E>(t: Option<T>, e: E) -> Result<T, E> {
    match t {
        Some(t) => Ok(t),
        None => Err(e),
    }
}

pub fn parse_logging_spec(spec: &str) -> Vec<LogDirective> {
    let mut dirs = Vec::new();

    let mut parts = spec.split('/');
    let mods = parts.next();
    let filter = parts.next();
    if parts.next().is_some() {
        println!("warning: invalid logging spec '{}', \
                 ignoring it (too many '/'s)", spec);
        return dirs;
    }
    mods.map(|m| { for s in m.split(',') {
        if s.len() == 0 { continue }
        let mut parts = s.split('=');
        let (log_level, name) = match (parts.next(), parts.next().map(|s| s.trim()), parts.next()) {
            (Some(part0), None, None) => {
                // if the single argument is a log-level string or number,
                // treat that as a global fallback
                match part0.parse() {
                    Ok(num) => (num, None),
                    Err(_) => (LogLevelFilter::max(), Some(part0)),
                }
            }
            (Some(part0), Some(""), None) => (LogLevelFilter::max(), Some(part0)),
            (Some(part0), Some(part1), None) => {
                match part1.parse() {
                    Ok(num) => (num, Some(part0)),
                    _ => {
                        println!("warning: invalid logging spec '{}', \
                                 ignoring it", part1);
                        continue
                    }
                }
            },
            _ => {
                println!("warning: invalid logging spec '{}', \
                         ignoring it", s);
                continue
            }
        };
        dirs.push(LogDirective {
            name: name.map(|s| s.to_string()),
            level: log_level,
        });
    }});

    return dirs;
}

#[macro_export]
macro_rules! log {
    (target: $target:expr, $lvl:expr, $($arg:tt)+) => ({
      use $crate::logging::LOGGER;
      static _META: $crate::logging::LogMetadata = $crate::logging::LogMetadata {
          level:  $lvl,
          target: module_path!(),
      };
      LOGGER.lock().unwrap().log(&_META, format_args!($($arg)+));
    });
    ($lvl:expr, $($arg:tt)+) => (log!(target: module_path!(), $lvl, $($arg)+));
}

#[macro_export]
macro_rules! error {
    ($format:expr, $($arg:tt)*) => {
        log!($crate::logging::LogLevel::Error, concat!("{}\t{}\t{}\t{}\t", $format, '\n'),
          ::time::now_utc().rfc3339(), ::time::precise_time_ns(), *$crate::logging::PID,
          "ERROR", $($arg)*);
    };
    ($format:expr) => {
        log!($crate::logging::LogLevel::Error, concat!("{}\t{}\t{}\t{}\t", $format, '\n'),
          ::time::now_utc().rfc3339(), ::time::precise_time_ns(), *$crate::logging::PID,
          "ERROR");
    };
}

#[macro_export]
macro_rules! warn {
    ($format:expr, $($arg:tt)*) => {
        use time;
        use logging::PID;
        log!($crate::logging::LogLevel::Warn, concat!("{}\t{}\t{}\t{}\t", $format, '\n'),
          ::time::now_utc().rfc3339(), ::time::precise_time_ns(), *$crate::logging::PID,
          "WARN", $($arg)*);
    };
    ($format:expr) => {
        log!($crate::logging::LogLevel::Warn, concat!("{}\t{}\t{}\t{}\t", $format, '\n'),
          ::time::now_utc().rfc3339(), ::time::precise_time_ns(), *$crate::logging::PID,
          "WARN");
    }
}

#[macro_export]
macro_rules! info {
    ($format:expr, $($arg:tt)*) => {
        log!($crate::logging::LogLevel::Info, concat!("{}\t{}\t{}\t{}\t", $format, '\n'),
          ::time::now_utc().rfc3339(), ::time::precise_time_ns(), *$crate::logging::PID,
          "INFO", $($arg)*);
    };
    ($format:expr) => {
        log!($crate::logging::LogLevel::Info, concat!("{}\t{}\t{}\t{}\t", $format, '\n'),
          ::time::now_utc().rfc3339(), ::time::precise_time_ns(), *$crate::logging::PID,
          "INFO");
    }
}

#[macro_export]
macro_rules! debug {
    ($format:expr, $($arg:tt)*) => {
        log!($crate::logging::LogLevel::Debug, concat!("{}\t{}\t{}\t{}\t{}\t", $format, '\n'),
          ::time::now_utc().rfc3339(), ::time::precise_time_ns(), *$crate::logging::PID,
          "DEBUG", module_path!(), $($arg)*);
    };
    ($format:expr) => {
        log!($crate::logging::LogLevel::Debug, concat!("{}\t{}\t{}\t{}\t{}\t", $format, '\n'),
          ::time::now_utc().rfc3339(), ::time::precise_time_ns(), *$crate::logging::PID,
          "DEBUG", module_path!());
    }
}

#[macro_export]
macro_rules! trace {
    ($format:expr, $($arg:tt)*) => (
        log!($crate::logging::LogLevel::Trace, concat!("{}\t{}\t{}\t{}\t{}\t", $format, '\n'),
          ::time::now_utc().rfc3339(), ::time::precise_time_ns(), *$crate::logging::PID,
          "TRACE", module_path!(), $($arg)*);
    );
    ($format:expr) => (
        log!($crate::logging::LogLevel::Trace, concat!("{}\t{}\t{}\t{}\t{}\t", $format, '\n'),
          ::time::now_utc().rfc3339(), ::time::precise_time_ns(), *$crate::logging::PID,
          "TRACE", module_path!());
    )
}

<commit_msg>remove Debug from LoggerBackend<commit_after>use libc;
use std::str::FromStr;
use std::cmp::{self,Ord};
use std::sync::{Mutex, Once, ONCE_INIT};
use std::cell::RefCell;
use std::fmt::{Arguments,format,write};
use std::io::{stdout,Stdout,Write};
use std::ascii::AsciiExt;
use std::net::{SocketAddr,UdpSocket};
use std::net::TcpStream;
use mio_uds::UnixDatagram;

lazy_static! {
  pub static ref LOGGER: Mutex<Logger> = Mutex::new(Logger::new());
  pub static ref PID:    i32 = unsafe { libc::getpid() };
}

pub struct Logger {
  directives: Vec<LogDirective>,
  backend:    LoggerBackend,
}

impl Logger {
  pub fn new() -> Logger {
    Logger {
      directives: vec!(LogDirective {
        name:  None,
        level: LogLevelFilter::Error,
      }),
      backend: LoggerBackend::Stdout(stdout())
    }
  }

  pub fn init(spec: &str, backend: LoggerBackend) {
    let directives = parse_logging_spec(spec);
    if let Ok(ref mut logger) = LOGGER.lock() {
      logger.set_directives(directives);
      logger.backend = backend;
    }
  }

  pub fn log<'a>(&mut self, meta: &LogMetadata, args: Arguments) {
    if self.enabled(meta) {
      match self.backend {
        LoggerBackend::Stdout(ref mut stdout) => {
          stdout.write_fmt(args);
        },
        //FIXME: should have a buffer to write to instead of allocating a string
        LoggerBackend::Unix(ref mut socket) => {
          socket.send(format(args).as_bytes());
        },
        //FIXME: should have a buffer to write to instead of allocating a string
        LoggerBackend::Udp(ref mut socket, ref address) => {
          socket.send_to(format(args).as_bytes(), address);
        }
        LoggerBackend::Tcp(ref mut socket) => {
          socket.write_fmt(args);
        },
      }
    }
  }

  pub fn set_directives(&mut self, directives: Vec<LogDirective>) {
    self.directives = directives;
  }

  fn enabled(&self, meta: &LogMetadata) -> bool {
    // Search for the longest match, the vector is assumed to be pre-sorted.
    for directive in self.directives.iter().rev() {
      match directive.name {
        Some(ref name) if !meta.target.starts_with(&**name) => {},
        Some(..) | None => {
          return meta.level <= directive.level
        }
      }
    }
    false
  }
}

pub enum LoggerBackend {
  Stdout(Stdout),
  Unix(UnixDatagram),
  Udp(UdpSocket, SocketAddr),
  Tcp(TcpStream)
}

#[repr(usize)]
#[derive(Copy, Eq, Debug)]
pub enum LogLevel {
    /// The "error" level.
    ///
    /// Designates very serious errors.
    Error = 1, // This way these line up with the discriminants for LogLevelFilter below
    /// The "warn" level.
    ///
    /// Designates hazardous situations.
    Warn,
    /// The "info" level.
    ///
    /// Designates useful information.
    Info,
    /// The "debug" level.
    ///
    /// Designates lower priority information.
    Debug,
    /// The "trace" level.
    ///
    /// Designates very low priority, often extremely verbose, information.
    Trace,
}

static LOG_LEVEL_NAMES: [&'static str; 6] = ["OFF", "ERROR", "WARN", "INFO",
                                             "DEBUG", "TRACE"];

impl Clone for LogLevel {
    #[inline]
    fn clone(&self) -> LogLevel {
        *self
    }
}

impl PartialEq for LogLevel {
    #[inline]
    fn eq(&self, other: &LogLevel) -> bool {
        *self as usize == *other as usize
    }
}

impl PartialEq<LogLevelFilter> for LogLevel {
    #[inline]
    fn eq(&self, other: &LogLevelFilter) -> bool {
        *self as usize == *other as usize
    }
}

impl PartialOrd for LogLevel {
    #[inline]
    fn partial_cmp(&self, other: &LogLevel) -> Option<cmp::Ordering> {
        Some(self.cmp(other))
    }
}

impl PartialOrd<LogLevelFilter> for LogLevel {
    #[inline]
    fn partial_cmp(&self, other: &LogLevelFilter) -> Option<cmp::Ordering> {
        Some((*self as usize).cmp(&(*other as usize)))
    }
}

impl Ord for LogLevel {
    #[inline]
    fn cmp(&self, other: &LogLevel) -> cmp::Ordering {
        (*self as usize).cmp(&(*other as usize))
    }
}

impl LogLevel {
    fn from_usize(u: usize) -> Option<LogLevel> {
        match u {
            1 => Some(LogLevel::Error),
            2 => Some(LogLevel::Warn),
            3 => Some(LogLevel::Info),
            4 => Some(LogLevel::Debug),
            5 => Some(LogLevel::Trace),
            _ => None
        }
    }

    /// Returns the most verbose logging level.
    #[inline]
    pub fn max() -> LogLevel {
        LogLevel::Trace
    }

    /// Converts the `LogLevel` to the equivalent `LogLevelFilter`.
    #[inline]
    pub fn to_log_level_filter(&self) -> LogLevelFilter {
        LogLevelFilter::from_usize(*self as usize).unwrap()
    }
}

#[repr(usize)]
#[derive(Copy, Eq, Debug)]
pub enum LogLevelFilter {
    Off,
    Error,
    Warn,
    Info,
    Debug,
    Trace,
}

impl Clone for LogLevelFilter {
    #[inline]
    fn clone(&self) -> LogLevelFilter {
        *self
    }
}

impl PartialEq for LogLevelFilter {
    #[inline]
    fn eq(&self, other: &LogLevelFilter) -> bool {
        *self as usize == *other as usize
    }
}

impl PartialEq<LogLevel> for LogLevelFilter {
    #[inline]
    fn eq(&self, other: &LogLevel) -> bool {
        other.eq(self)
    }
}

impl PartialOrd for LogLevelFilter {
    #[inline]
    fn partial_cmp(&self, other: &LogLevelFilter) -> Option<cmp::Ordering> {
        Some(self.cmp(other))
    }
}

impl PartialOrd<LogLevel> for LogLevelFilter {
    #[inline]
    fn partial_cmp(&self, other: &LogLevel) -> Option<cmp::Ordering> {
        other.partial_cmp(self).map(|x| x.reverse())
    }
}

impl Ord for LogLevelFilter {
    #[inline]
    fn cmp(&self, other: &LogLevelFilter) -> cmp::Ordering {
        (*self as usize).cmp(&(*other as usize))
    }
}

impl FromStr for LogLevelFilter {
    type Err = ();
    fn from_str(level: &str) -> Result<LogLevelFilter, ()> {
        ok_or(LOG_LEVEL_NAMES.iter()
                    .position(|&name| name.eq_ignore_ascii_case(level))
                    .map(|p| LogLevelFilter::from_usize(p).unwrap()), ())
    }
}

impl LogLevelFilter {
    fn from_usize(u: usize) -> Option<LogLevelFilter> {
        match u {
            0 => Some(LogLevelFilter::Off),
            1 => Some(LogLevelFilter::Error),
            2 => Some(LogLevelFilter::Warn),
            3 => Some(LogLevelFilter::Info),
            4 => Some(LogLevelFilter::Debug),
            5 => Some(LogLevelFilter::Trace),
            _ => None
        }
    }
    /// Returns the most verbose logging level filter.
    #[inline]
    pub fn max() -> LogLevelFilter {
        LogLevelFilter::Trace
    }

    /// Converts `self` to the equivalent `LogLevel`.
    ///
    /// Returns `None` if `self` is `LogLevelFilter::Off`.
    #[inline]
    pub fn to_log_level(&self) -> Option<LogLevel> {
        LogLevel::from_usize(*self as usize)
    }
}

/// Metadata about a log message.
pub struct LogMetadata {
  pub level:  LogLevel,
  pub target: &'static str,
}

pub struct LogDirective {
    name:  Option<String>,
    level: LogLevelFilter,
}

fn ok_or<T, E>(t: Option<T>, e: E) -> Result<T, E> {
    match t {
        Some(t) => Ok(t),
        None => Err(e),
    }
}

pub fn parse_logging_spec(spec: &str) -> Vec<LogDirective> {
    let mut dirs = Vec::new();

    let mut parts = spec.split('/');
    let mods = parts.next();
    let filter = parts.next();
    if parts.next().is_some() {
        println!("warning: invalid logging spec '{}', \
                 ignoring it (too many '/'s)", spec);
        return dirs;
    }
    mods.map(|m| { for s in m.split(',') {
        if s.len() == 0 { continue }
        let mut parts = s.split('=');
        let (log_level, name) = match (parts.next(), parts.next().map(|s| s.trim()), parts.next()) {
            (Some(part0), None, None) => {
                // if the single argument is a log-level string or number,
                // treat that as a global fallback
                match part0.parse() {
                    Ok(num) => (num, None),
                    Err(_) => (LogLevelFilter::max(), Some(part0)),
                }
            }
            (Some(part0), Some(""), None) => (LogLevelFilter::max(), Some(part0)),
            (Some(part0), Some(part1), None) => {
                match part1.parse() {
                    Ok(num) => (num, Some(part0)),
                    _ => {
                        println!("warning: invalid logging spec '{}', \
                                 ignoring it", part1);
                        continue
                    }
                }
            },
            _ => {
                println!("warning: invalid logging spec '{}', \
                         ignoring it", s);
                continue
            }
        };
        dirs.push(LogDirective {
            name: name.map(|s| s.to_string()),
            level: log_level,
        });
    }});

    return dirs;
}

#[macro_export]
macro_rules! log {
    (target: $target:expr, $lvl:expr, $($arg:tt)+) => ({
      use $crate::logging::LOGGER;
      static _META: $crate::logging::LogMetadata = $crate::logging::LogMetadata {
          level:  $lvl,
          target: module_path!(),
      };
      LOGGER.lock().unwrap().log(&_META, format_args!($($arg)+));
    });
    ($lvl:expr, $($arg:tt)+) => (log!(target: module_path!(), $lvl, $($arg)+));
}

#[macro_export]
macro_rules! error {
    ($format:expr, $($arg:tt)*) => {
        log!($crate::logging::LogLevel::Error, concat!("{}\t{}\t{}\t{}\t", $format, '\n'),
          ::time::now_utc().rfc3339(), ::time::precise_time_ns(), *$crate::logging::PID,
          "ERROR", $($arg)*);
    };
    ($format:expr) => {
        log!($crate::logging::LogLevel::Error, concat!("{}\t{}\t{}\t{}\t", $format, '\n'),
          ::time::now_utc().rfc3339(), ::time::precise_time_ns(), *$crate::logging::PID,
          "ERROR");
    };
}

#[macro_export]
macro_rules! warn {
    ($format:expr, $($arg:tt)*) => {
        use time;
        use logging::PID;
        log!($crate::logging::LogLevel::Warn, concat!("{}\t{}\t{}\t{}\t", $format, '\n'),
          ::time::now_utc().rfc3339(), ::time::precise_time_ns(), *$crate::logging::PID,
          "WARN", $($arg)*);
    };
    ($format:expr) => {
        log!($crate::logging::LogLevel::Warn, concat!("{}\t{}\t{}\t{}\t", $format, '\n'),
          ::time::now_utc().rfc3339(), ::time::precise_time_ns(), *$crate::logging::PID,
          "WARN");
    }
}

#[macro_export]
macro_rules! info {
    ($format:expr, $($arg:tt)*) => {
        log!($crate::logging::LogLevel::Info, concat!("{}\t{}\t{}\t{}\t", $format, '\n'),
          ::time::now_utc().rfc3339(), ::time::precise_time_ns(), *$crate::logging::PID,
          "INFO", $($arg)*);
    };
    ($format:expr) => {
        log!($crate::logging::LogLevel::Info, concat!("{}\t{}\t{}\t{}\t", $format, '\n'),
          ::time::now_utc().rfc3339(), ::time::precise_time_ns(), *$crate::logging::PID,
          "INFO");
    }
}

#[macro_export]
macro_rules! debug {
    ($format:expr, $($arg:tt)*) => {
        log!($crate::logging::LogLevel::Debug, concat!("{}\t{}\t{}\t{}\t{}\t", $format, '\n'),
          ::time::now_utc().rfc3339(), ::time::precise_time_ns(), *$crate::logging::PID,
          "DEBUG", module_path!(), $($arg)*);
    };
    ($format:expr) => {
        log!($crate::logging::LogLevel::Debug, concat!("{}\t{}\t{}\t{}\t{}\t", $format, '\n'),
          ::time::now_utc().rfc3339(), ::time::precise_time_ns(), *$crate::logging::PID,
          "DEBUG", module_path!());
    }
}

#[macro_export]
macro_rules! trace {
    ($format:expr, $($arg:tt)*) => (
        log!($crate::logging::LogLevel::Trace, concat!("{}\t{}\t{}\t{}\t{}\t", $format, '\n'),
          ::time::now_utc().rfc3339(), ::time::precise_time_ns(), *$crate::logging::PID,
          "TRACE", module_path!(), $($arg)*);
    );
    ($format:expr) => (
        log!($crate::logging::LogLevel::Trace, concat!("{}\t{}\t{}\t{}\t{}\t", $format, '\n'),
          ::time::now_utc().rfc3339(), ::time::precise_time_ns(), *$crate::logging::PID,
          "TRACE", module_path!());
    )
}

<|endoftext|>


<commit_before>use std::io::stdio::{stdout, stderr};
use std::io::fs::{readdir, rmdir_recursive};

use argparse::{ArgumentParser, PushConst, StoreTrue};

use super::setup;
use super::Wrapper;

#[derive(Copy)]
enum Action {
    Temporary,
    Old,
    Everything,
    Orphans,
}

pub fn clean_cmd(wrapper: &Wrapper, cmdline: Vec<String>)
    -> Result<isize, String>
{
    let mut global = false;
    let mut dry_run = false;
    let mut actions = vec!();
    {
        let mut ap = ArgumentParser::new();
        ap.set_description("
            Performs various cleanup tasks
            ");
        ap.refer(&mut actions)
          .add_option(&["--tmp", "--tmp-folders"],
                Box::new(PushConst(Action::Temporary)),
                "Clean temporary containers (failed builds)")
          .add_option(&["--old", "--old-containers"],
                Box::new(PushConst(Action::Old)),
                "Clean old versions of containers (configurable)")
          .add_option(&["--everything"],
                Box::new(PushConst(Action::Everything)),
                "Clean whole `.vagga` folder. Useful when deleting a project.
                 With ``--global`` cleans whole storage-dir and cache-dir")
          .add_option(&["--orphans"],
                Box::new(PushConst(Action::Orphans)),
                "Without `--global` removes containers which are not in
                 vagga.yaml any more. With `--global` removes all folders
                 which have `.lnk` pointing to nowhere (i.e. project dir
                 already deleted while vagga folder is not)")
          .required();
        ap.refer(&mut global)
          .add_option(&["--global"], Box::new(StoreTrue),
                "Apply cleanup command to all containers. Works only \
                if `storage-dir` is configured in settings");
        ap.refer(&mut dry_run)
          .add_option(&["-n", "--dry-run"], Box::new(StoreTrue),
                "Dry run. Don't delete everything, just print");
        match ap.parse(cmdline, &mut stdout(), &mut stderr()) {
            Ok(()) => {}
            Err(0) => return Ok(0),
            Err(_) => {
                return Ok(1);
            }
        }
    }
    if global && wrapper.ext_settings.storage_dir.is_none() {
        error!("The --global flag is only meaningful if you configure \
            storage-dir in settings");
        return Ok(2);
    }
    for action in actions.iter() {
        let res = match *action {
            Action::Temporary => clean_temporary(wrapper, global, dry_run),
            _ => unimplemented!(),
        };
        match res {
            Ok(()) => {}
            Err(err) => {
                error!("Error cleaning up: {}", err);
                return Ok(3);
            }
        }
    }
    return Ok(0);
}

fn clean_temporary(wrapper: &Wrapper, global: bool, dry_run: bool)
    -> Result<(), String>
{
    if global {
        panic!("Global cleanup is not implemented yet");
    }
    let base = match try!(setup::get_vagga_base(
        wrapper.project_root, wrapper.ext_settings))
    {
        Some(base) => base,
        None => {
            warn!("No vagga directory exists");
            return Ok(());
        }
    };
    let roots = base.join(".roots");
    for path in try!(readdir(&roots)
            .map_err(|e| format!("Can't read dir {:?}: {}", roots, e)))
            .iter()
    {
        if path.filename_str().map(|n| n.starts_with(".tmp")).unwrap_or(false)
        {
            if dry_run {
                println!("Would remove {:?}", path);
            } else {
                try!(rmdir_recursive(path)
                     .map_err(|x| format!("Error removing directory: {}", x)));
            }
        }
    }

    return Ok(());
}
<commit_msg>Implement `_clean --old`<commit_after>use std::io::fs::{readdir, rmdir_recursive, readlink};
use std::io::stdio::{stdout, stderr};
use std::collections::HashSet;

use argparse::{ArgumentParser, PushConst, StoreTrue};

use super::setup;
use super::Wrapper;

#[derive(Copy)]
enum Action {
    Temporary,
    Old,
    Everything,
    Orphans,
}

pub fn clean_cmd(wrapper: &Wrapper, cmdline: Vec<String>)
    -> Result<isize, String>
{
    let mut global = false;
    let mut dry_run = false;
    let mut actions = vec!();
    {
        let mut ap = ArgumentParser::new();
        ap.set_description("
            Performs various cleanup tasks
            ");
        ap.refer(&mut actions)
          .add_option(&["--tmp", "--tmp-folders"],
                Box::new(PushConst(Action::Temporary)),
                "Clean temporary containers (failed builds)")
          .add_option(&["--old", "--old-containers"],
                Box::new(PushConst(Action::Old)),
                "Clean old versions of containers (configurable)")
          .add_option(&["--everything"],
                Box::new(PushConst(Action::Everything)),
                "Clean whole `.vagga` folder. Useful when deleting a project.
                 With ``--global`` cleans whole storage-dir and cache-dir")
          .add_option(&["--orphans"],
                Box::new(PushConst(Action::Orphans)),
                "Without `--global` removes containers which are not in
                 vagga.yaml any more. With `--global` removes all folders
                 which have `.lnk` pointing to nowhere (i.e. project dir
                 already deleted while vagga folder is not)")
          .required();
        ap.refer(&mut global)
          .add_option(&["--global"], Box::new(StoreTrue),
                "Apply cleanup command to all containers. Works only \
                if `storage-dir` is configured in settings");
        ap.refer(&mut dry_run)
          .add_option(&["-n", "--dry-run"], Box::new(StoreTrue),
                "Dry run. Don't delete everything, just print");
        match ap.parse(cmdline, &mut stdout(), &mut stderr()) {
            Ok(()) => {}
            Err(0) => return Ok(0),
            Err(_) => {
                return Ok(1);
            }
        }
    }
    if global && wrapper.ext_settings.storage_dir.is_none() {
        error!("The --global flag is only meaningful if you configure \
            storage-dir in settings");
        return Ok(2);
    }
    for action in actions.iter() {
        let res = match *action {
            Action::Temporary => clean_temporary(wrapper, global, dry_run),
            Action::Old => clean_old(wrapper, global, dry_run),
            _ => unimplemented!(),
        };
        match res {
            Ok(()) => {}
            Err(err) => {
                error!("Error cleaning up: {}", err);
                return Ok(3);
            }
        }
    }
    return Ok(0);
}

fn clean_temporary(wrapper: &Wrapper, global: bool, dry_run: bool)
    -> Result<(), String>
{
    if global {
        panic!("Global cleanup is not implemented yet");
    }
    let base = match try!(setup::get_vagga_base(
        wrapper.project_root, wrapper.ext_settings))
    {
        Some(base) => base,
        None => {
            warn!("No vagga directory exists");
            return Ok(());
        }
    };
    let roots = base.join(".roots");
    for path in try!(readdir(&roots)
            .map_err(|e| format!("Can't read dir {:?}: {}", roots, e)))
            .iter()
    {
        if path.filename_str().map(|n| n.starts_with(".tmp")).unwrap_or(false)
        {
            if dry_run {
                println!("Would remove {:?}", path);
            } else {
                try!(rmdir_recursive(path)
                     .map_err(|x| format!("Error removing directory: {}", x)));
            }
        }
    }

    return Ok(());
}

fn clean_old(wrapper: &Wrapper, global: bool, dry_run: bool)
    -> Result<(), String>
{
    if global {
        panic!("Global cleanup is not implemented yet");
    }
    let base = match try!(setup::get_vagga_base(
        wrapper.project_root, wrapper.ext_settings))
    {
        Some(base) => base,
        None => {
            warn!("No vagga directory exists");
            return Ok(());
        }
    };
    let useful: HashSet<String> = try!(
        readdir(&wrapper.project_root.join(".vagga"))
            .map_err(|e| format!("Can't read vagga directory: {}", e)))
        .into_iter()
        .filter(|path| !path.filename_str()
                           .map(|f| f.starts_with("."))
                           .unwrap_or(true))
        .map(|path| readlink(&path)
                    .map_err(|e| warn!("Can't readlink {:?}: {}", path, e))
                    .ok()
                    .and_then(|f| {
                        let mut cmp = f.str_components().rev();
                        cmp.next();
                        // The container name is next to the last component
                        cmp.next().and_then(|x| x).map(ToString::to_string)
                    }))
        .filter(|x| x.is_some()).map(|x| x.unwrap())
        .collect();
    debug!("Useful images {:?}", useful);

    let roots = base.join(".roots");
    for path in try!(readdir(&roots)
            .map_err(|e| format!("Can't read dir {:?}: {}", roots, e)))
            .iter()
    {
        if path.filename_str()
            .map(|n| !useful.contains(&n.to_string()))
            .unwrap_or(false)
        {
            if dry_run {
                println!("Would remove {:?}", path);
            } else {
                try!(rmdir_recursive(path)
                     .map_err(|x| format!("Error removing directory: {}", x)));
            }
        }
    }

    return Ok(());
}
<|endoftext|>


<commit_before>use std::os::unix::process::ExitStatusExt;
use std::process::{Command, Stdio};

use super::Wrapper;
use super::setup::setup_base_filesystem;

pub fn run_interactive_build_shell(wrapper: &Wrapper) -> i32 {
    if let Err(text) = setup_base_filesystem(
        wrapper.project_root, wrapper.ext_settings)
    {
        error!("Error setting base file system: {}", &text);
        return 122;
    }
    match Command::new("/vagga/bin/busybox")
            .stdin(Stdio::inherit(0))
            .stdout(Stdio::inherit()).stderr(Stdio::inherit())
            .arg("sh")
            .env("PATH", "/vagga/bin")
        .output()
        .map_err(|e| format!("Can't run tar: {}", e))
        .map(|o| o.status)
    {
        Ok(x) if x.signal().is_some() => 128+(x.signal().unwrap() as i32),
        Ok(x) => x.code().unwrap() as i32,
        Err(x) => {
            error!("Error running build_shell: {}", x);
            return 127;
        }
    }
}
<commit_msg>Fix wrapper/debug.rs<commit_after>use std::os::unix::process::ExitStatusExt;
use std::process::{Command, Stdio};

use super::Wrapper;
use super::setup::setup_base_filesystem;

pub fn run_interactive_build_shell(wrapper: &Wrapper) -> i32 {
    if let Err(text) = setup_base_filesystem(
        wrapper.project_root, wrapper.ext_settings)
    {
        error!("Error setting base file system: {}", &text);
        return 122;
    }
    match Command::new("/vagga/bin/busybox")
            .stdin(Stdio::inherit())
            .stdout(Stdio::inherit()).stderr(Stdio::inherit())
            .arg("sh")
            .env("PATH", "/vagga/bin")
        .output()
        .map_err(|e| format!("Can't run tar: {}", e))
        .map(|o| o.status)
    {
        Ok(x) if x.signal().is_some() => 128+(x.signal().unwrap() as i32),
        Ok(x) => x.code().unwrap() as i32,
        Err(x) => {
            error!("Error running build_shell: {}", x);
            return 127;
        }
    }
}
<|endoftext|>


<commit_before>#![feature(question_mark)]

extern crate cloudfm;
extern crate chill;
extern crate dotenv;

use std::{error};
use cloudfm::{views, User, Error};
use chill::{UnreducedView, ViewRow, DocumentId, AllDocumentsViewValue};
use std::env;
use dotenv::dotenv;

pub fn main() {
    dotenv().ok();

    let db_url = env::var("DATABASE_URL").expect("DATABASE_URL must be set");
    let db = chill::Client::new(&db_url).expect("DATABASE_URL must be a valid URL");

    let errors = index_all(db);
    println!("index_all done. error count: {}", errors.len());
    for error in errors {
        println!("error: {}", error);
    }
}

pub fn index_all(db: chill::Client) -> Vec<Error> {
    let mut errors: Vec<Error> = Vec::new();

    let action = match db.read_all_documents("/_users") {
        Ok(action) => action,
        Err(error) => return vec![Error::from(error)]
    };

    let res = match action.run() {
        Ok(res) => res,
        Err(error) => return vec![Error::from(error)]
    };

    let view = match res.as_unreduced() {
        Some(view) => view,
        None => unimplemented!()
    };

    for row in view.rows() {
        if let Err(e) = index_user(&db, row) {
            errors.push(e);
        }
    }

    errors
}

pub fn index_user(db: &chill::Client, row: &ViewRow<DocumentId, AllDocumentsViewValue>) -> Result<(), Error> {
    let doc = db.read_document(("/_users", row.key()))?.run()?; // TODO use include_docs
    let user: User = doc.get_content()?;
    views::apply(db, &user.db_name())?;
    Ok(())
}
<commit_msg>fix(indexd): skip design docs, print success count<commit_after>#![feature(question_mark)]

extern crate cloudfm;
extern crate chill;
extern crate dotenv;

use std::{error};
use cloudfm::{views, User, Error};
use chill::{UnreducedView, ViewRow, DocumentId, AllDocumentsViewValue};
use std::env;
use dotenv::dotenv;

pub fn main() {
    dotenv().ok();

    let db_url = env::var("DATABASE_URL").expect("DATABASE_URL must be set");
    let db = chill::Client::new(&db_url).expect("DATABASE_URL must be a valid URL");

    let (count, errors) = index_all(db);
    println!("index_all done. success: {}, failed: {}", count - errors.len(), errors.len());
    for error in errors {
        println!("error: {}", error);
    }
}

pub fn index_all(db: chill::Client) -> (usize, Vec<Error>) {
    let mut errors: Vec<Error> = Vec::new();

    // skips design docs
    let start_key = &DocumentId::from("org.couchdb.user:");

    let action = match db.read_all_documents("/_users") {
        Ok(action) => action.with_start_key(start_key),
        Err(error) => return (0, vec![Error::from(error)])
    };

    let res = match action.run() {
        Ok(res) => res,
        Err(error) => return (0, vec![Error::from(error)])
    };

    let view = match res.as_unreduced() {
        Some(view) => view,
        None => unimplemented!()
    };

    for row in view.rows() {
        if let Err(e) = index_user(&db, row) {
            errors.push(e);
        }
    }

    (view.rows().len(), errors)
}

pub fn index_user(db: &chill::Client, row: &ViewRow<DocumentId, AllDocumentsViewValue>) -> Result<(), Error> {
    let doc = db.read_document(("/_users", row.key()))?.run()?; // TODO use include_docs
    let user: User = doc.get_content()?;
    views::apply(db, &user.db_name())?;
    Ok(())
}
<|endoftext|>