<commit_before>extern crate ocl;
#[allow(non_camel_case_types)]
#[allow(non_upper_case_globals)]
#[allow(non_snake_case)]
pub mod ffi;
use std::mem;
pub use ffi::clfftSetupData;

macro_rules! clfft_try {
    ( $result_expr: expr) => {
        let result = $result_expr;
        if result != ffi::clfftStatus::CLFFT_SUCCESS {
            let error_code: i32 = unsafe { mem::transmute(result) };
            return ocl::Error::err(format!("FOREIGN_CLFFT_ERROR {}\nSee http://clmathlibraries.github.io/clFFT/clFFT_8h.html#a74e303bed132064cfa22c1cce96d2bce for further information", error_code));
        }
    }
}

macro_rules! clfft_panic {
    ( $result_expr: expr) => {
        let result = $result_expr;
        if result != ffi::clfftStatus::CLFFT_SUCCESS {
            panic!("Unexpeced error in foreign library: {:?}", result);
        }
    }
}

fn translate_to_fft_dim(dims: ocl::SpatialDims) -> ffi::clfftDim {
    match dims.dim_count() {
        1 => ffi::clfftDim::CLFFT_1D,
        2 => ffi::clfftDim::CLFFT_2D,
        3 => ffi::clfftDim::CLFFT_3D,
        n => panic!("Number of dimensions must be 1, 2 or 3, but it is {}", n)
    }
}

pub struct FftPlan {
    handle: ffi::clfftPlanHandle
}

impl FftPlan {
    /// Create a plan object initialized entirely with default values.
    ///
    /// A plan is a repository of state for calculating FFT's.  Allows the runtime to pre-calculate kernels, programs
    /// and buffers and associate them with buffers of specified dimensions.
    pub fn default<D: Into<ocl::SpatialDims>>(pro_que: &ocl::ProQue, dims: D)
        -> ocl::Result<FftPlan> {
        let context = unsafe { pro_que.context().core_as_ref().as_ptr() };
        let dims = dims.into();
        let dim = translate_to_fft_dim(dims);
        let lengths = try!(dims.to_lens());
        let mut plan: ffi::clfftPlanHandle = 0;
        clfft_try!( unsafe { ffi::clfftCreateDefaultPlan(&mut plan, context, dim, &lengths as *const usize) } );
        Ok(FftPlan {  handle: plan })
    }

    /// Returns the native clFFT plan handle.
    pub fn plan_handle(&self) -> ffi::clfftPlanHandle {
        self.handle
    }
}

/// Initialize the internal FFT resources such as FFT implementation caches kernels, programs, and buffers.
pub fn init_lib() -> ffi::clfftSetupData {
    let mut major: ocl::ffi::cl_uint = 0;
    let mut minor: ocl::ffi::cl_uint = 0;
    let mut patch: ocl::ffi::cl_uint = 0;
    clfft_panic!( unsafe { ffi::clfftGetVersion(&mut major, &mut minor, &mut patch) } );
    let data = ffi::clfftSetupData {
        major: major,
        minor: minor,
        patch: patch,
        debugFlags: 0,
    };

    clfft_panic!(unsafe { ffi::clfftSetup(&data) });
    data
}

/// Release all internal resources acquired during `init_lib`.
pub fn drop_lib() {
    unsafe { ffi::clfftTeardown() };
}

#[cfg(test)]
mod tests {
    use super::*;
    use ocl::{ProQue};
    use ocl::builders::ProgramBuilder;

    #[test]
    pub fn fft_test() {
        init_lib();
        let prog_bldr = ProgramBuilder::new();
        let ocl_pq = ProQue::builder()
            .prog_bldr(prog_bldr)
            .build()
            .expect("Building ProQue");
        FftPlan::default(&ocl_pq, [1000]);
        drop_lib();
    }
}<commit_msg>Reordered method definitions<commit_after>extern crate ocl;
#[allow(non_camel_case_types)]
#[allow(non_upper_case_globals)]
#[allow(non_snake_case)]
pub mod ffi;
use std::mem;
pub use ffi::clfftSetupData;

macro_rules! clfft_try {
    ( $result_expr: expr) => {
        let result = $result_expr;
        if result != ffi::clfftStatus::CLFFT_SUCCESS {
            let error_code: i32 = unsafe { mem::transmute(result) };
            return ocl::Error::err(format!("FOREIGN_CLFFT_ERROR {}\nSee http://clmathlibraries.github.io/clFFT/clFFT_8h.html#a74e303bed132064cfa22c1cce96d2bce for further information", error_code));
        }
    }
}

macro_rules! clfft_panic {
    ( $result_expr: expr) => {
        let result = $result_expr;
        if result != ffi::clfftStatus::CLFFT_SUCCESS {
            panic!("Unexpeced error in foreign library: {:?}", result);
        }
    }
}

/// Initialize the internal FFT resources such as FFT implementation caches kernels, programs, and buffers.
pub fn init_lib() -> ffi::clfftSetupData {
    let mut major: ocl::ffi::cl_uint = 0;
    let mut minor: ocl::ffi::cl_uint = 0;
    let mut patch: ocl::ffi::cl_uint = 0;
    clfft_panic!( unsafe { ffi::clfftGetVersion(&mut major, &mut minor, &mut patch) } );
    let data = ffi::clfftSetupData {
        major: major,
        minor: minor,
        patch: patch,
        debugFlags: 0,
    };

    clfft_panic!(unsafe { ffi::clfftSetup(&data) });
    data
}

/// Release all internal resources acquired during `init_lib`.
pub fn drop_lib() {
    unsafe { ffi::clfftTeardown() };
}

fn translate_to_fft_dim(dims: ocl::SpatialDims) -> ffi::clfftDim {
    match dims.dim_count() {
        1 => ffi::clfftDim::CLFFT_1D,
        2 => ffi::clfftDim::CLFFT_2D,
        3 => ffi::clfftDim::CLFFT_3D,
        n => panic!("Number of dimensions must be 1, 2 or 3, but it is {}", n)
    }
}

pub struct FftPlan {
    handle: ffi::clfftPlanHandle
}

impl FftPlan {
    /// Create a plan object initialized entirely with default values.
    ///
    /// A plan is a repository of state for calculating FFT's.  Allows the runtime to pre-calculate kernels, programs
    /// and buffers and associate them with buffers of specified dimensions.
    pub fn default<D: Into<ocl::SpatialDims>>(pro_que: &ocl::ProQue, dims: D)
        -> ocl::Result<FftPlan> {
        let context = unsafe { pro_que.context().core_as_ref().as_ptr() };
        let dims = dims.into();
        let dim = translate_to_fft_dim(dims);
        let lengths = try!(dims.to_lens());
        let mut plan: ffi::clfftPlanHandle = 0;
        clfft_try!( unsafe { ffi::clfftCreateDefaultPlan(&mut plan, context, dim, &lengths as *const usize) } );
        Ok(FftPlan {  handle: plan })
    }

    /// Returns the native clFFT plan handle.
    pub fn plan_handle(&self) -> ffi::clfftPlanHandle {
        self.handle
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use ocl::{ProQue};
    use ocl::builders::ProgramBuilder;

    #[test]
    pub fn fft_test() {
        init_lib();
        let prog_bldr = ProgramBuilder::new();
        let ocl_pq = ProQue::builder()
            .prog_bldr(prog_bldr)
            .build()
            .expect("Building ProQue");
        FftPlan::default(&ocl_pq, [1000]);
        drop_lib();
    }
}<|endoftext|>


<commit_before><commit_msg>always construct shortslice using debug checked new constructor (#1741)<commit_after><|endoftext|>


<commit_before>// Claxon -- A FLAC decoding library in Rust
// Copyright 2018 Ruud van Asseldonk
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// A copy of the License has been included in the root of the repository.

#![no_main]

extern crate libfuzzer_sys;
extern crate claxon;

use std::io::Seek;
use std::io;
use std::iter;

#[export_name="rust_fuzzer_test_input"]
pub extern fn go(data: &[u8]) {
    // We want two distinct marker bytes.
    if data.len() < 2 || data[0] == data[1] {
        return
    }

    let mut cursor = io::Cursor::new(&data[2..]);

    // Allocate two large buffers filled with a marker byte. We will decode one
    // block twice, once into each buffer. If both decodes are successful, then
    // the two outputs should be identical. If we don't overwrite parts of the
    // buffer, then we would see a difference in the marker byte. The buffer
    // allocated up front should be large enough that Claxon does not need to
    // allocate a new one, but small enough to keep the fuzzer fast.
    let buffer0: Vec<i32> = iter::repeat(data[0] as i32).take(1024 * 8).collect();
    let buffer1: Vec<i32> = iter::repeat(data[1] as i32).take(1024 * 8).collect();

    // NOTE: Somewhat surprisingly, the bove runs at about 4x the execs per
    // second of this version below. I should file a performance bug against Rust.
    // let mut buffer0: Vec<i32> = Vec::with_capacity(1024 * 8);
    // let mut buffer1: Vec<i32> = Vec::with_capacity(1024 * 8);
    // buffer0.resize(1024 * 16, data[0] as i32);
    // buffer1.resize(1024 * 16, data[1] as i32);

    let result0 = {
        let mut reader = match claxon::FlacReader::new(&mut cursor) {
            Ok(r) => r,
            Err(..) => return,
        };

        match reader.blocks().read_next_or_eof(buffer0) {
            Ok(Some(block)) => Some(block.into_buffer()),
            _ => None,
        }
    };

    cursor.seek(io::SeekFrom::Start(0)).unwrap();

    let result1 = {
        let mut reader = match claxon::FlacReader::new(&mut cursor) {
            Ok(r) => r,
            Err(..) => panic!("First time decoded fine, second time should too."),
        };

        match reader.blocks().read_next_or_eof(buffer1) {
            Ok(Some(block)) => Some(block.into_buffer()),
            _ => None,
        }
    };

    assert_eq!(result0, result1);
}
<commit_msg>Speed up the differential decoder a bit<commit_after>// Claxon -- A FLAC decoding library in Rust
// Copyright 2018 Ruud van Asseldonk
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// A copy of the License has been included in the root of the repository.

#![no_main]

extern crate libfuzzer_sys;
extern crate claxon;

use std::io::Seek;
use std::io;
use std::iter;

#[export_name="rust_fuzzer_test_input"]
pub extern fn go(data: &[u8]) {
    // We want two distinct marker bytes.
    if data.len() < 2 || data[0] == data[1] {
        return
    }

    let mut cursor = io::Cursor::new(&data[2..]);

    // Allocate two large buffers filled with a marker byte. We will decode one
    // block twice, once into each buffer. If both decodes are successful, then
    // the two outputs should be identical. If we don't overwrite parts of the
    // buffer, then we would see a difference in the marker byte. The buffer
    // allocated up front should be large enough that Claxon does not need to
    // allocate a new one, but small enough to keep the fuzzer fast.
    let buffer0: Vec<i32> = iter::repeat(data[0] as i32).take(1024 * 8).collect();
    let buffer1: Vec<i32> = iter::repeat(data[1] as i32).take(1024 * 8).collect();

    // NOTE: Somewhat surprisingly, the bove runs at about 4x the execs per
    // second of this version below. I should file a performance bug against Rust.
    // let mut buffer0: Vec<i32> = Vec::with_capacity(1024 * 8);
    // let mut buffer1: Vec<i32> = Vec::with_capacity(1024 * 8);
    // buffer0.resize(1024 * 16, data[0] as i32);
    // buffer1.resize(1024 * 16, data[1] as i32);

    let result0 = {
        let mut reader = match claxon::FlacReader::new(&mut cursor) {
            Ok(r) => r,
            Err(..) => return,
        };

        match reader.blocks().read_next_or_eof(buffer0) {
            Ok(Some(block)) => Some(block.into_buffer()),
            _ => None,
        }
    };

    if let Some(ref res) = result0 {
        if res.capacity() != 1024 * 8 {
            // If a resize was needed, there is no point in attempting the
            // second decode, because Claxon allocated a new buffer that was not
            // filled with the marker byte.
            return
        }
    }

    cursor.seek(io::SeekFrom::Start(0)).unwrap();

    let result1 = {
        let mut reader = match claxon::FlacReader::new(&mut cursor) {
            Ok(r) => r,
            Err(..) => panic!("First time decoded fine, second time should too."),
        };

        match reader.blocks().read_next_or_eof(buffer1) {
            Ok(Some(block)) => Some(block.into_buffer()),
            _ => None,
        }
    };

    assert_eq!(result0, result1);
}
<|endoftext|>


<commit_before>use std;
use std::collections::VecDeque;
use std::io::{Read, Write};
use std::process::{Command, Child, ChildStdin, ChildStdout, ExitStatus};
use std::sync::{mpsc, Arc, Mutex, Semaphore};
use std::thread;

use byteorder::{ReadBytesExt, WriteBytesExt, NativeEndian};

#[derive(Clone)]
pub struct Evaluator {
    queue: Arc<Mutex<VecDeque<Request>>>,
    has_work: Arc<Semaphore>
}

enum Request {
    Terminate,
    Restart,
    Work {
        code: String,
        timeout: usize,
        reporter: mpsc::Sender<Output>
    }
}

struct Output {
    success: bool,
    output: String
}

impl Evaluator {
    fn new() -> Self {
        Evaluator {
            queue: Arc::new(Mutex::new(VecDeque::new())),
            has_work: Arc::new(Semaphore::new(0))
        }
    }

    fn send_request(&self, req: Request) {
        self.queue.lock().unwrap().push_back(req);
        self.has_work.release();
    }

    #[cfg(not(unix))]
    pub fn eval(&self, _: &str, _: usize) -> Result<String, String> {
        Err("not implemented".to_owned())
    }

    #[cfg(unix)]
    pub fn eval(&self, code: &str, timeout: usize) -> Result<String, String> {
        let (tx, rx) = mpsc::channel();
        self.send_request(Request::Work {
            code: code.to_owned(),
            timeout: timeout,
            reporter: tx
        });

        let result = match rx.recv() {
            Ok(x) => x,
            Err(x) => {
                println!("couldn't receive result: {:?}", x);
                Output {
                    success: false,
                    output: "something bad happened".to_owned()
                }
            }
        };

        // this basically controls whether the output is prefixed if it's in a channel
        if result.success { Ok(result.output) } else { Err(result.output) }
    }

    pub fn restart(&self) {
        self.send_request(Request::Restart);
    }

    pub fn terminate(&self) {
        self.send_request(Request::Terminate);
    }
}

fn worker_evaluate(stdin: &mut ChildStdin,
                   stdout: Arc<Mutex<ChildStdout>>,
                   work: &Request)
                   -> Result<(), ()> {
    macro_rules! try_io {
        ($x:expr, $repr:expr) => {
            match $x {
                Err(x) => {
                    println!("couldn't communicate with child (1): {:?}", x);
                    match $repr.send(Output { success: false, output: "couldn't communicate with child (1)".to_owned() }) {
                        Ok(_) => (),
                        Err(x) => println!("couldn't report error (1): {:?}", x)
                    };
                    return Err(());
                },
                Ok(x) => x
            }
        }
    };

    macro_rules! try_io2 {
        ($x:expr, $repr:expr) => {
            match $x {
                Err(x) => {
                    println!("couldn't communicate with child (2): {:?}", x);
                    match $repr.send(Err(Output { success: false, output: "couldn't communicate with child (2)".to_owned() })) {
                        Ok(_) => (),
                        Err(x) => println!("couldn't report error (2): {:?}", x)
                    };
                    return;
                },
                Ok(x) => x
            }
        }
    };

    if let &Request::Work { ref code, timeout, ref reporter } = work {
        try_io!(stdin.write_i32::<NativeEndian>((timeout * 1000) as i32),
                reporter);
        let bytes = code.as_bytes();
        try_io!(stdin.write_i32::<NativeEndian>(bytes.len() as i32),
                reporter);
        try_io!(stdin.write_all(bytes), reporter);
        try_io!(stdin.flush(), reporter);

        let (tx, rx) = mpsc::channel();

        {
            // wait for response
            let tx = tx.clone();
            thread::spawn(move || {
                let mut stdout = stdout.lock().unwrap();
                let success = try_io2!(stdout.read_u8(), tx) == 1;
                let result_len = try_io2!(stdout.read_i32::<NativeEndian>(), tx);
                let mut result_bytes = vec![0u8; result_len as usize];
                try_io2!(stdout.read_exact(&mut result_bytes), tx);
                match tx.send(Ok(Output {
                    success: success,
                    output: String::from_utf8_lossy(&result_bytes).into_owned()
                })) {
                    _ => (),
                };
            });
        }

        {
            // timeout
            let timeout = (timeout as f64 * 1.5) as u64;
            thread::spawn(move || {
                thread::sleep(::std::time::Duration::new(timeout, 0));
                match tx.send(Err(Output {
                    success: false,
                    output: "timed out waiting for evaluator response".to_owned()
                })) {
                    _ => (),
                };
            });
        }
        let mut err = false;

        // this one receives from the two threads spawned above
        // Ok means we got a message through the channel
        // Err means both threads above died
        let result = match rx.recv() {
            Ok(x) => x,
            Err(_) => {
                err = true;
                Ok(Output {
                    success: false,
                    output: "couldn't receive result from communicator thread".to_owned()
                })
            }
        };

        // this one is the result from the threads
        // Ok means we got the response from the sandboxed evaluator
        // Err means we timed out on Rust end (if the evaluator timed out, it'll be
        // Ok(Output { success: false, output: "timed out" }) or something like that
        let result = match result {
            Ok(x) => x,
            Err(x) => {
                err = true;
                x
            }
        };

        // we'll just ignore this error, not going to restart child
        match reporter.send(result) {
            Ok(_) => (),
            Err(x) => println!("couldn't return result: {:?}", x),
        };

        // returning Err here will make the loop in worker(..) break
        // restarting the child
        if err { Err(()) } else { Ok(()) }
    } else {
        println!("worker_evaluate got something other than Request::Work");
        Ok(())
    }
}

fn worker<'a, F>(childfn: F, queue: Arc<Mutex<VecDeque<Request>>>, has_work: Arc<Semaphore>)
    where F: Fn() -> Child + Send + 'static {
    use std::mem;
    let mut terminate;
    loop {
        let mut evaluator = childfn();
        println!("started persistent child pid {}", evaluator.id());
        let mut stdin = evaluator.stdin.take().unwrap();
        let stdout = Arc::new(Mutex::new(evaluator.stdout.take().unwrap()));
        loop {
            has_work.acquire();
            let mut rvec = queue.lock().unwrap();
            let work = rvec.pop_front();
            std::mem::drop(rvec);

            if let Some(work) = work {
                match work {
                    Request::Terminate => {
                        println!("requested to terminate persistent child pid {}",
                                 evaluator.id());
                        terminate = true;
                        break;
                    }
                    Request::Restart => {
                        println!("requested to restart persistent child pid {}",
                                 evaluator.id());
                        terminate = false;
                        break;
                    }
                    Request::Work { .. } => {
                        let res = worker_evaluate(&mut stdin, stdout.clone(), &work);
                        match res {
                            Ok(_) => (),
                            Err(_) => {
                                terminate = false;
                                break;
                            }
                        };
                    }
                }
            }
        }
        let pid = evaluator.id();
        println!("killing persistent child pid {}", pid);
        match evaluator.kill() {
            _ => (),
        };
        mem::drop(evaluator);
        match sudo_kill(pid) {
            Err(x) => println!("failed to kill {}: {}", pid, x),
            Ok(x) => println!("kill result: {:?}", x),
        };
        if terminate {
            break;
        }
    }
}

fn sudo_kill(pid: u32) -> Result<ExitStatus, String> {
    try!(Command::new("sudo")
             .args(&["kill", "-KILL"])
             .arg(format!("{}", pid))
             .spawn()
             .map_err(|x| format!("couldn't spawn sudo kill: {:?}", x)))
        .wait()
        .map_err(|x| format!("couldn't SIGKILL: {:?}", x))
}

pub fn new<F>(childfn: F) -> Evaluator
    where F: Fn() -> Child + Send + 'static {
    let ret = Evaluator::new();
    let (queue, has_work) = (ret.queue.clone(), ret.has_work.clone());
    thread::spawn(move || {
        worker(childfn, queue, has_work);
    });
    ret
}
<commit_msg>Make Rust waitpid our killed children<commit_after>use std;
use std::collections::VecDeque;
use std::io::{Read, Write};
use std::process::{Command, Child, ChildStdin, ChildStdout, ExitStatus};
use std::sync::{mpsc, Arc, Mutex, Semaphore};
use std::thread;

use byteorder::{ReadBytesExt, WriteBytesExt, NativeEndian};

#[derive(Clone)]
pub struct Evaluator {
    queue: Arc<Mutex<VecDeque<Request>>>,
    has_work: Arc<Semaphore>
}

enum Request {
    Terminate,
    Restart,
    Work {
        code: String,
        timeout: usize,
        reporter: mpsc::Sender<Output>
    }
}

struct Output {
    success: bool,
    output: String
}

impl Evaluator {
    fn new() -> Self {
        Evaluator {
            queue: Arc::new(Mutex::new(VecDeque::new())),
            has_work: Arc::new(Semaphore::new(0))
        }
    }

    fn send_request(&self, req: Request) {
        self.queue.lock().unwrap().push_back(req);
        self.has_work.release();
    }

    #[cfg(not(unix))]
    pub fn eval(&self, _: &str, _: usize) -> Result<String, String> {
        Err("not implemented".to_owned())
    }

    #[cfg(unix)]
    pub fn eval(&self, code: &str, timeout: usize) -> Result<String, String> {
        let (tx, rx) = mpsc::channel();
        self.send_request(Request::Work {
            code: code.to_owned(),
            timeout: timeout,
            reporter: tx
        });

        let result = match rx.recv() {
            Ok(x) => x,
            Err(x) => {
                println!("couldn't receive result: {:?}", x);
                Output {
                    success: false,
                    output: "something bad happened".to_owned()
                }
            }
        };

        // this basically controls whether the output is prefixed if it's in a channel
        if result.success { Ok(result.output) } else { Err(result.output) }
    }

    pub fn restart(&self) {
        self.send_request(Request::Restart);
    }

    pub fn terminate(&self) {
        self.send_request(Request::Terminate);
    }
}

fn worker_evaluate(stdin: &mut ChildStdin,
                   stdout: Arc<Mutex<ChildStdout>>,
                   work: &Request)
                   -> Result<(), ()> {
    macro_rules! try_io {
        ($x:expr, $repr:expr) => {
            match $x {
                Err(x) => {
                    println!("couldn't communicate with child (1): {:?}", x);
                    match $repr.send(Output { success: false, output: "couldn't communicate with child (1)".to_owned() }) {
                        Ok(_) => (),
                        Err(x) => println!("couldn't report error (1): {:?}", x)
                    };
                    return Err(());
                },
                Ok(x) => x
            }
        }
    };

    macro_rules! try_io2 {
        ($x:expr, $repr:expr) => {
            match $x {
                Err(x) => {
                    println!("couldn't communicate with child (2): {:?}", x);
                    match $repr.send(Err(Output { success: false, output: "couldn't communicate with child (2)".to_owned() })) {
                        Ok(_) => (),
                        Err(x) => println!("couldn't report error (2): {:?}", x)
                    };
                    return;
                },
                Ok(x) => x
            }
        }
    };

    if let &Request::Work { ref code, timeout, ref reporter } = work {
        try_io!(stdin.write_i32::<NativeEndian>((timeout * 1000) as i32),
                reporter);
        let bytes = code.as_bytes();
        try_io!(stdin.write_i32::<NativeEndian>(bytes.len() as i32),
                reporter);
        try_io!(stdin.write_all(bytes), reporter);
        try_io!(stdin.flush(), reporter);

        let (tx, rx) = mpsc::channel();

        {
            // wait for response
            let tx = tx.clone();
            thread::spawn(move || {
                let mut stdout = stdout.lock().unwrap();
                let success = try_io2!(stdout.read_u8(), tx) == 1;
                let result_len = try_io2!(stdout.read_i32::<NativeEndian>(), tx);
                let mut result_bytes = vec![0u8; result_len as usize];
                try_io2!(stdout.read_exact(&mut result_bytes), tx);
                match tx.send(Ok(Output {
                    success: success,
                    output: String::from_utf8_lossy(&result_bytes).into_owned()
                })) {
                    _ => (),
                };
            });
        }

        {
            // timeout
            let timeout = (timeout as f64 * 1.5) as u64;
            thread::spawn(move || {
                thread::sleep(::std::time::Duration::new(timeout, 0));
                match tx.send(Err(Output {
                    success: false,
                    output: "timed out waiting for evaluator response".to_owned()
                })) {
                    _ => (),
                };
            });
        }
        let mut err = false;

        // this one receives from the two threads spawned above
        // Ok means we got a message through the channel
        // Err means both threads above died
        let result = match rx.recv() {
            Ok(x) => x,
            Err(_) => {
                err = true;
                Ok(Output {
                    success: false,
                    output: "couldn't receive result from communicator thread".to_owned()
                })
            }
        };

        // this one is the result from the threads
        // Ok means we got the response from the sandboxed evaluator
        // Err means we timed out on Rust end (if the evaluator timed out, it'll be
        // Ok(Output { success: false, output: "timed out" }) or something like that
        let result = match result {
            Ok(x) => x,
            Err(x) => {
                err = true;
                x
            }
        };

        // we'll just ignore this error, not going to restart child
        match reporter.send(result) {
            Ok(_) => (),
            Err(x) => println!("couldn't return result: {:?}", x),
        };

        // returning Err here will make the loop in worker(..) break
        // restarting the child
        if err { Err(()) } else { Ok(()) }
    } else {
        println!("worker_evaluate got something other than Request::Work");
        Ok(())
    }
}

fn worker<'a, F>(childfn: F, queue: Arc<Mutex<VecDeque<Request>>>, has_work: Arc<Semaphore>)
    where F: Fn() -> Child + Send + 'static {
    let mut terminate;
    loop {
        let mut evaluator = childfn();
        println!("started persistent child pid {}", evaluator.id());
        let mut stdin = evaluator.stdin.take().unwrap();
        let stdout = Arc::new(Mutex::new(evaluator.stdout.take().unwrap()));
        loop {
            has_work.acquire();
            let mut rvec = queue.lock().unwrap();
            let work = rvec.pop_front();
            std::mem::drop(rvec);

            if let Some(work) = work {
                match work {
                    Request::Terminate => {
                        println!("requested to terminate persistent child pid {}",
                                 evaluator.id());
                        terminate = true;
                        break;
                    }
                    Request::Restart => {
                        println!("requested to restart persistent child pid {}",
                                 evaluator.id());
                        terminate = false;
                        break;
                    }
                    Request::Work { .. } => {
                        let res = worker_evaluate(&mut stdin, stdout.clone(), &work);
                        match res {
                            Ok(_) => (),
                            Err(_) => {
                                terminate = false;
                                break;
                            }
                        };
                    }
                }
            }
        }
        let pid = evaluator.id();
        println!("killing persistent child pid {}", pid);
        match sudo_kill(pid) {
            Err(x) => println!("failed to kill {}: {}", pid, x),
            Ok(x) => println!("kill result: {:?}", x),
        };
        // we only do this here because Child::kill does waitpid, to reap the process
        match evaluator.kill() {
            _ => (),
        };
        if terminate {
            break;
        }
    }
}

fn sudo_kill(pid: u32) -> Result<ExitStatus, String> {
    try!(Command::new("sudo")
             .args(&["kill", "-KILL"])
             .arg(format!("{}", pid))
             .spawn()
             .map_err(|x| format!("couldn't spawn sudo kill: {:?}", x)))
        .wait()
        .map_err(|x| format!("couldn't SIGKILL: {:?}", x))
}

pub fn new<F>(childfn: F) -> Evaluator
    where F: Fn() -> Child + Send + 'static {
    let ret = Evaluator::new();
    let (queue, has_work) = (ret.queue.clone(), ret.has_work.clone());
    thread::spawn(move || {
        worker(childfn, queue, has_work);
    });
    ret
}
<|endoftext|>


<commit_before>#![allow(dead_code)]

use rational::Rational32;
use data::frame::MediaKind;

#[derive(Clone,Debug,PartialEq)]
enum CodecID {
    VP9,
    Opus
}

#[derive(Clone,Debug,PartialEq)]
pub struct CodecParams {
    kind: MediaKind,
    codec_id: CodecID,
    extradata: Vec<u8>,
    tag: u32,
    bit_rate: usize,
    bits_per_coded_sample: usize,
    profile: usize,
    level: usize,
}

#[derive(Clone,Debug,PartialEq)]
pub struct Stream {
    id: usize,
    index: usize,
    params : CodecParams,
    start: Option<u64>,
    duration: Option<u64>,
    timebase : Rational32,
//  seek_index : SeekIndex
}

pub struct StreamGroup<'a> {
    id: usize,
    start: u64,
    end: u64,
    streams: &'a [Stream],
}
<commit_msg>stream struct members should be public<commit_after>#![allow(dead_code)]

use rational::Rational32;
use data::frame::MediaKind;

#[derive(Clone,Debug,PartialEq)]
pub enum CodecID {
    VP9,
    Opus
}

#[derive(Clone,Debug,PartialEq)]
pub struct CodecParams {
    pub kind: MediaKind,
    pub codec_id: CodecID,
    pub extradata: Vec<u8>,
    pub tag: u32,
    pub bit_rate: usize,
    pub bits_per_coded_sample: usize,
    pub profile: usize,
    pub level: usize,
}

#[derive(Clone,Debug,PartialEq)]
pub struct Stream {
    pub id: usize,
    pub index: usize,
    pub params : CodecParams,
    pub start: Option<u64>,
    pub duration: Option<u64>,
    pub timebase : Rational32,
//  seek_index : SeekIndex
}

pub struct StreamGroup<'a> {
    pub id: usize,
    pub start: u64,
    pub end: u64,
    pub streams: &'a [Stream],
}
<|endoftext|>


<commit_before>use redox::{Vec, String, ToString};
use redox::collections::{BTreeMap, VecDeque};

use super::dvaddr::DVAddr;
use super::zio;

// Our implementation of the Adaptive Replacement Cache (ARC) is set up to allocate
// its buffer on the heap rather than in a private pool thing. This makes it much
// simpler to implement, but defers the fragmentation problem to the heap allocator.
// We named the type `ArCache` to avoid confusion with Rust's `Arc` reference type.
pub struct ArCache {
    // MRU
    // TODO: keep track of use counts. So mru_map becomes (use_count: u64, Vec<u8>)
    mru_map: BTreeMap<DVAddr, Vec<u8>>, // Most recently used cache
    mru_queue: VecDeque<DVAddr>, // Oldest DVAddrs are at the end
    mru_size: usize, // Max mru cache size in blocks
    mru_used: usize, // Number of used blocks in mru cache

    // MFU
    // TODO: Keep track of use counts. So mfu_map becomes (use_count: u64, Vec<u8>). Reset the use
    // count every once in a while. For instance, every 1000 reads. This will probably end up being
    // a knob for the user.
    // TODO: Keep track of minimum frequency and corresponding DVA
    mfu_map: BTreeMap<DVAddr, Vec<u8>>, // Most frequently used cache
    mfu_size: usize, // Max mfu cache size in blocks
    mfu_used: usize, // Number of used bytes in mfu cache
}

impl ArCache {
    pub fn new() -> Self {
        ArCache {
            mru_map: BTreeMap::new(),
            mru_queue: VecDeque::new(),
            mru_size: 1000,
            mru_used: 0,

            mfu_map: BTreeMap::new(),
            mfu_size: 1000,
            mfu_used: 0,
        }
    }

    pub fn read(&mut self, reader: &mut zio::Reader, dva: &DVAddr) -> Result<Vec<u8>, String> {
        if let Some(block) = self.mru_map.get(dva) {
            // TODO: Keep track of MRU DVA use count. If it gets used a second time, move the block into
            // the MFU cache.

            // Block is cached
            return Ok(block.clone());
        }
        if let Some(block) = self.mfu_map.get(dva) {
            // TODO: keep track of DVA use count
            // Block is cached
            return Ok(block.clone());
        }

        // Block isn't cached, have to read it from disk
        let block = reader.read(dva.sector() as usize, dva.asize() as usize);

        // Blocks start in MRU cache
        self.mru_cache_block(dva, block)
    }

    fn mru_cache_block(&mut self, dva: &DVAddr, block: Vec<u8>) -> Result<Vec<u8>, String>{
        // If necessary, make room for the block in the cache
        while self.mru_used + (dva.asize() as usize) > self.mru_size {
            let last_dva =
                match self.mru_queue.pop_back()
                {
                    Some(dva) => dva,
                    None => return Err("No more ARC MRU items to free".to_string()),
                };
            self.mru_map.remove(&last_dva);
            self.mru_used -= last_dva.asize() as usize;
        }

        // Add the block to the cache
        self.mru_used += dva.asize() as usize;
        self.mru_map.insert(*dva, block);
        self.mru_queue.push_front(*dva);
        Ok(self.mru_map.get(dva).unwrap().clone())
    }

    // TODO: mfu_cache_block. Remove the DVA with the lowest frequency
}
<commit_msg>Introduce `Mru` and `Mfu` types<commit_after>use redox::{Vec, String, ToString};
use redox::collections::{BTreeMap, VecDeque};

use super::dvaddr::DVAddr;
use super::zio;

/// MRU - Most Recently Used cache
struct Mru {
    // TODO: keep track of use counts. So mru_map becomes (use_count: u64, Vec<u8>)
    map: BTreeMap<DVAddr, (u64, Vec<u8>)>,
    queue: VecDeque<DVAddr>, // Oldest DVAddrs are at the end
    size: usize, // Max mru cache size in bytes
    used: usize, // Used bytes in mru cache
}

impl Mru {
    pub fn new() -> Self {
        Mru {
            map: BTreeMap::new(),
            queue: VecDeque::new(),
            size: 10,
            used: 0,
        }
    }
}

/// MFU - Most Frequently Used cache
struct Mfu {
    // TODO: Keep track of use counts. So mfu_map becomes (use_count: u64, Vec<u8>). Reset the use
    // count every once in a while. For instance, every 1000 reads. This will probably end up being
    // a knob for the user.
    // TODO: Keep track of minimum frequency and corresponding DVA
    map: BTreeMap<DVAddr, (u64, Vec<u8>)>,
    size: usize, // Max mfu cache size in bytes
    used: usize, // Used bytes in mfu cache
}

impl Mfu {
    pub fn new() -> Self {
        Mfu {
            map: BTreeMap::new(),
            size: 10,
            used: 0,
        }
    }
}

// Our implementation of the Adaptive Replacement Cache (ARC) is set up to allocate
// its buffer on the heap rather than in a private pool thing. This makes it much
// simpler to implement, but defers the fragmentation problem to the heap allocator.
// We named the type `ArCache` to avoid confusion with Rust's `Arc` reference type.
pub struct ArCache {
    // MRU
    // TODO: keep track of use counts. So mru_map becomes (use_count: u64, Vec<u8>)
    mru_map: BTreeMap<DVAddr, Vec<u8>>, // Most recently used cache
    mru_queue: VecDeque<DVAddr>, // Oldest DVAddrs are at the end
    mru_size: usize, // Max mru cache size in blocks
    mru_used: usize, // Number of used blocks in mru cache

    // MFU
    // TODO: Keep track of use counts. So mfu_map becomes (use_count: u64, Vec<u8>). Reset the use
    // count every once in a while. For instance, every 1000 reads. This will probably end up being
    // a knob for the user.
    // TODO: Keep track of minimum frequency and corresponding DVA
    mfu_map: BTreeMap<DVAddr, Vec<u8>>, // Most frequently used cache
    mfu_size: usize, // Max mfu cache size in blocks
    mfu_used: usize, // Number of used bytes in mfu cache
}

impl ArCache {
    pub fn new() -> Self {
        ArCache {
            mru_map: BTreeMap::new(),
            mru_queue: VecDeque::new(),
            mru_size: 1000,
            mru_used: 0,

            mfu_map: BTreeMap::new(),
            mfu_size: 1000,
            mfu_used: 0,
        }
    }

    pub fn read(&mut self, reader: &mut zio::Reader, dva: &DVAddr) -> Result<Vec<u8>, String> {
        if let Some(block) = self.mru_map.get(dva) {
            // TODO: Keep track of MRU DVA use count. If it gets used a second time, move the block into
            // the MFU cache.

            // Block is cached
            return Ok(block.clone());
        }
        if let Some(block) = self.mfu_map.get(dva) {
            // TODO: keep track of DVA use count
            // Block is cached
            return Ok(block.clone());
        }

        // Block isn't cached, have to read it from disk
        let block = reader.read(dva.sector() as usize, dva.asize() as usize);

        // Blocks start in MRU cache
        self.mru_cache_block(dva, block)
    }

    fn mru_cache_block(&mut self, dva: &DVAddr, block: Vec<u8>) -> Result<Vec<u8>, String>{
        // If necessary, make room for the block in the cache
        while self.mru_used + (dva.asize() as usize) > self.mru_size {
            let last_dva =
                match self.mru_queue.pop_back()
                {
                    Some(dva) => dva,
                    None => return Err("No more ARC MRU items to free".to_string()),
                };
            self.mru_map.remove(&last_dva);
            self.mru_used -= last_dva.asize() as usize;
        }

        // Add the block to the cache
        self.mru_used += dva.asize() as usize;
        self.mru_map.insert(*dva, block);
        self.mru_queue.push_front(*dva);
        Ok(self.mru_map.get(dva).unwrap().clone())
    }

    // TODO: mfu_cache_block. Remove the DVA with the lowest frequency
}
<|endoftext|>


<commit_before>//! All routes related to managing owners of a crate

use crate::controllers::prelude::*;
use crate::models::{Crate, Owner, Rights, Team, User};
use crate::views::EncodableOwner;

/// Handles the `GET /crates/:crate_id/owners` route.
pub fn owners(req: &mut dyn RequestExt) -> EndpointResult {
    let crate_name = &req.params()["crate_id"];
    let conn = req.db_read_only()?;
    let krate: Crate = Crate::by_name(crate_name).first(&*conn)?;
    let owners = krate
        .owners(&conn)?
        .into_iter()
        .map(Owner::into)
        .collect::<Vec<EncodableOwner>>();

    Ok(req.json(&json!({ "users": owners })))
}

/// Handles the `GET /crates/:crate_id/owner_team` route.
pub fn owner_team(req: &mut dyn RequestExt) -> EndpointResult {
    let crate_name = &req.params()["crate_id"];
    let conn = req.db_read_only()?;
    let krate: Crate = Crate::by_name(crate_name).first(&*conn)?;
    let owners = Team::owning(&krate, &conn)?
        .into_iter()
        .map(Owner::into)
        .collect::<Vec<EncodableOwner>>();

    Ok(req.json(&json!({ "teams": owners })))
}

/// Handles the `GET /crates/:crate_id/owner_user` route.
pub fn owner_user(req: &mut dyn RequestExt) -> EndpointResult {
    let crate_name = &req.params()["crate_id"];
    let conn = req.db_read_only()?;
    let krate: Crate = Crate::by_name(crate_name).first(&*conn)?;
    let owners = User::owning(&krate, &conn)?
        .into_iter()
        .map(Owner::into)
        .collect::<Vec<EncodableOwner>>();

    Ok(req.json(&json!({ "users": owners })))
}

/// Handles the `PUT /crates/:crate_id/owners` route.
pub fn add_owners(req: &mut dyn RequestExt) -> EndpointResult {
    modify_owners(req, true)
}

/// Handles the `DELETE /crates/:crate_id/owners` route.
pub fn remove_owners(req: &mut dyn RequestExt) -> EndpointResult {
    modify_owners(req, false)
}

/// Parse the JSON request body of requests to modify the owners of a crate.
/// The format is
///
///     {"owners": ["username", "github:org:team", ...]}
fn parse_owners_request(req: &mut dyn RequestExt) -> AppResult<Vec<String>> {
    let mut body = String::new();
    req.body().read_to_string(&mut body)?;
    #[derive(Deserialize)]
    struct Request {
        // identical, for back-compat (owners preferred)
        users: Option<Vec<String>>,
        owners: Option<Vec<String>>,
    }
    let request: Request =
        serde_json::from_str(&body).map_err(|_| cargo_err("invalid json request"))?;
    request
        .owners
        .or(request.users)
        .ok_or_else(|| cargo_err("invalid json request"))
}

fn modify_owners(req: &mut dyn RequestExt, add: bool) -> EndpointResult {
    let authenticated_user = req.authenticate()?;
    let logins = parse_owners_request(req)?;
    let app = req.app();
    let crate_name = &req.params()["crate_id"];

    let conn = req.db_conn()?;
    let user = authenticated_user.user();

    conn.transaction(|| {
        let krate: Crate = Crate::by_name(crate_name).first(&*conn)?;
        let owners = krate.owners(&conn)?;

        match user.rights(app, &owners)? {
            Rights::Full => {}
            // Yes!
            Rights::Publish => {
                return Err(cargo_err(
                    "team members don't have permission to modify owners",
                ));
            }
            Rights::None => {
                return Err(cargo_err("only owners have permission to modify owners"));
            }
        }

        let comma_sep_msg = if add {
            let mut msgs = Vec::with_capacity(logins.len());
            for login in &logins {
                let login_test =
                    |owner: &Owner| owner.login().to_lowercase() == *login.to_lowercase();
                if owners.iter().any(login_test) {
                    return Err(cargo_err(&format_args!("`{}` is already an owner", login)));
                }
                let msg = krate.owner_add(app, &conn, &user, login)?;
                msgs.push(msg);
            }
            msgs.join(",")
        } else {
            for login in &logins {
                krate.owner_remove(app, &conn, &user, login)?;
            }
            if User::owning(&krate, &conn)?.is_empty() {
                return Err(cargo_err(
                    "cannot remove all individual owners of a crate. \
                     Team member don't have permission to modify owners, so \
                     at least one individual owner is required.",
                ));
            }
            "owners successfully removed".to_owned()
        };

        Ok(req.json(&json!({ "ok": true, "msg": comma_sep_msg })))
    })
}
<commit_msg>krate::owners: Fix doc comment format<commit_after>//! All routes related to managing owners of a crate

use crate::controllers::prelude::*;
use crate::models::{Crate, Owner, Rights, Team, User};
use crate::views::EncodableOwner;

/// Handles the `GET /crates/:crate_id/owners` route.
pub fn owners(req: &mut dyn RequestExt) -> EndpointResult {
    let crate_name = &req.params()["crate_id"];
    let conn = req.db_read_only()?;
    let krate: Crate = Crate::by_name(crate_name).first(&*conn)?;
    let owners = krate
        .owners(&conn)?
        .into_iter()
        .map(Owner::into)
        .collect::<Vec<EncodableOwner>>();

    Ok(req.json(&json!({ "users": owners })))
}

/// Handles the `GET /crates/:crate_id/owner_team` route.
pub fn owner_team(req: &mut dyn RequestExt) -> EndpointResult {
    let crate_name = &req.params()["crate_id"];
    let conn = req.db_read_only()?;
    let krate: Crate = Crate::by_name(crate_name).first(&*conn)?;
    let owners = Team::owning(&krate, &conn)?
        .into_iter()
        .map(Owner::into)
        .collect::<Vec<EncodableOwner>>();

    Ok(req.json(&json!({ "teams": owners })))
}

/// Handles the `GET /crates/:crate_id/owner_user` route.
pub fn owner_user(req: &mut dyn RequestExt) -> EndpointResult {
    let crate_name = &req.params()["crate_id"];
    let conn = req.db_read_only()?;
    let krate: Crate = Crate::by_name(crate_name).first(&*conn)?;
    let owners = User::owning(&krate, &conn)?
        .into_iter()
        .map(Owner::into)
        .collect::<Vec<EncodableOwner>>();

    Ok(req.json(&json!({ "users": owners })))
}

/// Handles the `PUT /crates/:crate_id/owners` route.
pub fn add_owners(req: &mut dyn RequestExt) -> EndpointResult {
    modify_owners(req, true)
}

/// Handles the `DELETE /crates/:crate_id/owners` route.
pub fn remove_owners(req: &mut dyn RequestExt) -> EndpointResult {
    modify_owners(req, false)
}

/// Parse the JSON request body of requests to modify the owners of a crate.
///
/// The format is:
///
/// ```json
/// {"owners": ["username", "github:org:team", ...]}
/// ```
fn parse_owners_request(req: &mut dyn RequestExt) -> AppResult<Vec<String>> {
    let mut body = String::new();
    req.body().read_to_string(&mut body)?;
    #[derive(Deserialize)]
    struct Request {
        // identical, for back-compat (owners preferred)
        users: Option<Vec<String>>,
        owners: Option<Vec<String>>,
    }
    let request: Request =
        serde_json::from_str(&body).map_err(|_| cargo_err("invalid json request"))?;
    request
        .owners
        .or(request.users)
        .ok_or_else(|| cargo_err("invalid json request"))
}

fn modify_owners(req: &mut dyn RequestExt, add: bool) -> EndpointResult {
    let authenticated_user = req.authenticate()?;
    let logins = parse_owners_request(req)?;
    let app = req.app();
    let crate_name = &req.params()["crate_id"];

    let conn = req.db_conn()?;
    let user = authenticated_user.user();

    conn.transaction(|| {
        let krate: Crate = Crate::by_name(crate_name).first(&*conn)?;
        let owners = krate.owners(&conn)?;

        match user.rights(app, &owners)? {
            Rights::Full => {}
            // Yes!
            Rights::Publish => {
                return Err(cargo_err(
                    "team members don't have permission to modify owners",
                ));
            }
            Rights::None => {
                return Err(cargo_err("only owners have permission to modify owners"));
            }
        }

        let comma_sep_msg = if add {
            let mut msgs = Vec::with_capacity(logins.len());
            for login in &logins {
                let login_test =
                    |owner: &Owner| owner.login().to_lowercase() == *login.to_lowercase();
                if owners.iter().any(login_test) {
                    return Err(cargo_err(&format_args!("`{}` is already an owner", login)));
                }
                let msg = krate.owner_add(app, &conn, &user, login)?;
                msgs.push(msg);
            }
            msgs.join(",")
        } else {
            for login in &logins {
                krate.owner_remove(app, &conn, &user, login)?;
            }
            if User::owning(&krate, &conn)?.is_empty() {
                return Err(cargo_err(
                    "cannot remove all individual owners of a crate. \
                     Team member don't have permission to modify owners, so \
                     at least one individual owner is required.",
                ));
            }
            "owners successfully removed".to_owned()
        };

        Ok(req.json(&json!({ "ok": true, "msg": comma_sep_msg })))
    })
}
<|endoftext|>


<commit_before>//! C API extensions to experiment with eager execution of kernels.
//!
//! WARNING: The underlying C-API for the eager execution is not guaranteed to be
//! stable and can be changed without notice, which could result in breaking.

mod context;
pub use context::*;

mod readonly_tensor;
pub use readonly_tensor::*;

mod tensor_handle;
pub use tensor_handle::*;

mod op;

pub use op::raw_ops;

use crate::{Result, Tensor, TensorType};

impl<T: TensorType> Tensor<T> {
    /// Convert a Tensor to a readonly Tensor for use in eager execution.
    pub fn freeze(self) -> ReadonlyTensor<T> {
        ReadonlyTensor {
            inner: self.inner,
            dims: self.dims,
        }
    }

    /// Convert a Tensor to a TensorHandle for use in eager execution.
    pub fn into_handle<'a>(self, ctx: &'a Context) -> Result<TensorHandle<'a>> {
        self.freeze().to_handle(ctx)
    }
}

/// A helper trait to convert a Tensor or some other types into a TensorHandle
/// for use in eager execution.
pub trait ToTensorHandle<'a> {
    /// Convert a Tensor or values into a new TensorHandle.
    fn to_handle(&self, ctx: &'a Context) -> Result<TensorHandle<'a>>;
}

impl<'a, T> ToTensorHandle<'a> for ReadonlyTensor<T>
where
    T: TensorType,
{
    fn to_handle(&self, ctx: &'a Context) -> Result<TensorHandle<'a>> {
        TensorHandle::new(ctx, self)
    }
}

impl<'a> ToTensorHandle<'a> for TensorHandle<'a> {
    fn to_handle(&self, _: &'a Context) -> Result<TensorHandle<'a>> {
        self.copy_sharing_tensor()
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use crate::eager::{Context, ContextOptions};
    use crate::Tensor;

    #[test]
    fn tensor_to_handle() {
        let ctx = Context::new(ContextOptions::new()).unwrap();

        // Create a read-only tensor.
        let tensor = Tensor::<i32>::new(&[1, 2, 3, 4]).freeze();
        let handle = tensor.to_handle(&ctx).unwrap();
        assert_eq!(handle.num_dims().unwrap(), 4);
        assert_eq!(handle.dim(0).unwrap(), 1);
        assert_eq!(handle.dim(1).unwrap(), 2);
        assert_eq!(handle.dim(2).unwrap(), 3);
        assert_eq!(handle.dim(3).unwrap(), 4);

        // Create a TensorHandle directly from a Tensor.
        // It takes ownership of the Tensor.
        let tensor = Tensor::<i32>::new(&[1, 2, 3, 4]);
        let handle = tensor.into_handle(&ctx).unwrap();
        assert_eq!(handle.num_dims().unwrap(), 4);
        assert_eq!(handle.dim(0).unwrap(), 1);
        assert_eq!(handle.dim(1).unwrap(), 2);
        assert_eq!(handle.dim(2).unwrap(), 3);
        assert_eq!(handle.dim(3).unwrap(), 4);
    }

    #[test]
    fn handle_to_handle() {
        let ctx = Context::new(ContextOptions::new()).unwrap();
        let tensor = Tensor::<i32>::new(&[1, 2, 3, 4]).freeze();
        let handle = tensor.to_handle(&ctx).unwrap();
        let handle2 = handle.to_handle(&ctx).unwrap();
        let tensor2 = handle2.resolve::<i32>().unwrap();
        assert_eq!(tensor, tensor2);
    }

    #[test]
    fn handle_to_tensor_unsafe() {
        let ctx = Context::new(ContextOptions::new()).unwrap();
        let tensor = Tensor::from(0i32).freeze();
        let h = tensor.to_handle(&ctx).unwrap();

        // Getting multiple times should return the same Tensor.
        let t0 = h.resolve::<i32>().unwrap();
        assert_eq!(t0[0], 0i32);

        // Manipulating the Tensor will affect the Tensor that shares underlying buffer.
        {
            let t1 = h.resolve::<i32>().unwrap();

            // Convert back from a TensorHandle to a Tensor.
            let mut t1 = unsafe { t1.into_tensor() };
            t1[0] = 5;
        }

        // Check that t0 shares the same underlying buffer with t1.
        // This is why we need to use unsafe.
        assert_eq!(t0[0], 5);
    }
}
<commit_msg>add ToTensorHandle trait implementations<commit_after>//! C API extensions to experiment with eager execution of kernels.
//!
//! WARNING: The underlying C-API for the eager execution is not guaranteed to be
//! stable and can be changed without notice, which could result in breaking.

mod context;
pub use context::*;

mod readonly_tensor;
pub use readonly_tensor::*;

mod tensor_handle;
pub use tensor_handle::*;

mod op;

pub use op::raw_ops;

use crate::{Result, Tensor, TensorType};
#[cfg(feature = "ndarray")]
use ndarray::{ArrayBase, Data, Dimension};

impl<T: TensorType> Tensor<T> {
    /// Convert a Tensor to a readonly Tensor for use in eager execution.
    pub fn freeze(self) -> ReadonlyTensor<T> {
        ReadonlyTensor {
            inner: self.inner,
            dims: self.dims,
        }
    }

    /// Convert a Tensor to a TensorHandle for use in eager execution.
    pub fn into_handle<'a>(self, ctx: &'a Context) -> Result<TensorHandle<'a>> {
        self.freeze().to_handle(ctx)
    }
}

/// A helper trait to convert a Tensor or some other types into a TensorHandle
/// for use in eager execution.
pub trait ToTensorHandle<'a> {
    /// Convert a Tensor or values into a new TensorHandle.
    fn to_handle(&self, ctx: &'a Context) -> Result<TensorHandle<'a>>;
}

impl<'a, T> ToTensorHandle<'a> for ReadonlyTensor<T>
where
    T: TensorType,
{
    fn to_handle(&self, ctx: &'a Context) -> Result<TensorHandle<'a>> {
        TensorHandle::new(ctx, self)
    }
}

impl<'a> ToTensorHandle<'a> for TensorHandle<'a> {
    fn to_handle(&self, _: &'a Context) -> Result<TensorHandle<'a>> {
        self.copy_sharing_tensor()
    }
}

impl<'a, T: TensorType> ToTensorHandle<'a> for T {
    fn to_handle(&self, ctx: &'a Context) -> Result<TensorHandle<'a>> {
        Tensor::from(self.clone()).into_handle(ctx)
    }
}

impl<'a> ToTensorHandle<'a> for str {
    fn to_handle(&self, ctx: &'a Context) -> Result<TensorHandle<'a>> {
        Tensor::from(self.to_string()).into_handle(ctx)
    }
}

impl<'a, T: TensorType> ToTensorHandle<'a> for [T] {
    fn to_handle(&self, ctx: &'a Context) -> Result<TensorHandle<'a>> {
        Tensor::from(self).into_handle(ctx)
    }
}

impl<'a, T: TensorType, const N: usize> ToTensorHandle<'a> for [T; N] {
    fn to_handle(&self, ctx: &'a Context) -> Result<TensorHandle<'a>> {
        Tensor::from(self).into_handle(ctx)
    }
}

#[cfg(feature = "ndarray")]
/// Convert any ndarray::ArrayBase type into a tensorflow::Tensor
impl<'a, T, S, D> ToTensorHandle<'a> for ArrayBase<S, D>
where
    T: TensorType,
    S: Data<Elem = T>,
    D: Dimension,
{
    fn to_handle(&self, ctx: &'a Context) -> Result<TensorHandle<'a>> {
        let dims: Vec<u64> = self.shape().iter().map(|x| *x as u64).collect();
        let mut tensor: Tensor<T> = Tensor::new(&dims);
        for (e, v) in tensor.iter_mut().zip(self.iter()) {
            e.clone_from(v);
        }
        tensor.into_handle(ctx)
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use crate::eager::{Context, ContextOptions};
    use crate::Tensor;

    #[test]
    fn tensor_to_handle() {
        let ctx = Context::new(ContextOptions::new()).unwrap();

        // Create a read-only tensor.
        let tensor = Tensor::<i32>::new(&[1, 2, 3, 4]).freeze();
        let handle = tensor.to_handle(&ctx).unwrap();
        assert_eq!(handle.num_dims().unwrap(), 4);
        assert_eq!(handle.dim(0).unwrap(), 1);
        assert_eq!(handle.dim(1).unwrap(), 2);
        assert_eq!(handle.dim(2).unwrap(), 3);
        assert_eq!(handle.dim(3).unwrap(), 4);

        // Create a TensorHandle directly from a Tensor.
        // It takes ownership of the Tensor.
        let tensor = Tensor::<i32>::new(&[1, 2, 3, 4]);
        let handle = tensor.into_handle(&ctx).unwrap();
        assert_eq!(handle.num_dims().unwrap(), 4);
        assert_eq!(handle.dim(0).unwrap(), 1);
        assert_eq!(handle.dim(1).unwrap(), 2);
        assert_eq!(handle.dim(2).unwrap(), 3);
        assert_eq!(handle.dim(3).unwrap(), 4);
    }

    #[test]
    fn handle_to_handle() {
        let ctx = Context::new(ContextOptions::new()).unwrap();
        let tensor = Tensor::<i32>::new(&[1, 2, 3, 4]).freeze();
        let handle = tensor.to_handle(&ctx).unwrap();
        let handle2 = handle.to_handle(&ctx).unwrap();
        let tensor2 = handle2.resolve::<i32>().unwrap();
        assert_eq!(tensor, tensor2);
    }

    #[test]
    fn handle_to_tensor_unsafe() {
        let ctx = Context::new(ContextOptions::new()).unwrap();
        let tensor = Tensor::from(0i32).freeze();
        let h = tensor.to_handle(&ctx).unwrap();

        // Getting multiple times should return the same Tensor.
        let t0 = h.resolve::<i32>().unwrap();
        assert_eq!(t0[0], 0i32);

        // Manipulating the Tensor will affect the Tensor that shares underlying buffer.
        {
            let t1 = h.resolve::<i32>().unwrap();

            // Convert back from a TensorHandle to a Tensor.
            let mut t1 = unsafe { t1.into_tensor() };
            t1[0] = 5;
        }

        // Check that t0 shares the same underlying buffer with t1.
        // This is why we need to use unsafe.
        assert_eq!(t0[0], 5);
    }
}
<|endoftext|>


<commit_before>#[macro_use]
mod common;

use common::util::*;

static UTIL_NAME: &'static str = "basename";

#[test]
fn test_directory() {
    let (_, mut ucmd) = testing(UTIL_NAME);
    let dir = "/root/alpha/beta/gamma/delta/epsilon/omega/";
    ucmd.arg(dir);

    assert_eq!(ucmd.run().stdout.trim_right(), "omega");
}

#[test]
fn test_file() {
    let (_, mut ucmd) = testing(UTIL_NAME);
    let file = "/etc/passwd";
    ucmd.arg(file);

    assert_eq!(ucmd.run().stdout.trim_right(), "passwd");
}

#[test]
fn test_remove_suffix() {
    let (_, mut ucmd) = testing(UTIL_NAME);
    let path = "/usr/local/bin/reallylongexecutable.exe";
    ucmd.arg(path)
        .arg(".exe");

    assert_eq!(ucmd.run().stdout.trim_right(), "reallylongexecutable");
}

#[test]
fn test_dont_remove_suffix() {
    let (_, mut ucmd) = testing(UTIL_NAME);
    let path = "/foo/bar/baz";
    ucmd.arg(path)
        .arg("baz");

    assert_eq!(ucmd.run().stdout.trim_right(), "baz");
}
<commit_msg>basename: in tests, assert error-free in usage<commit_after>#[macro_use]
mod common;

use common::util::*;

static UTIL_NAME: &'static str = "basename";

fn expect_successful_stdout(input: Vec<&str>, expected: &str) {
    let (_, mut ucmd) = testing(UTIL_NAME);
    let results = ucmd.args(&input).run();
    assert_empty_stderr!(results);
    assert!(results.success);
    assert_eq!(expected, results.stdout.trim_right());
}

#[test]
fn test_directory() {
    let dir = "/root/alpha/beta/gamma/delta/epsilon/omega/";
    expect_successful_stdout(vec![dir], "omega");
}

#[test]
fn test_file() {
    let file = "/etc/passwd";
    expect_successful_stdout(vec![file], "passwd");
}

#[test]
fn test_remove_suffix() {
    let path = "/usr/local/bin/reallylongexecutable.exe";
    expect_successful_stdout(vec![path, ".exe"], "reallylongexecutable");
}

#[test]
fn test_dont_remove_suffix() {
    let path = "/foo/bar/baz";
    expect_successful_stdout(vec![path, "baz"], "baz");
}
<|endoftext|>


<commit_before>//! Operations on ASCII strings and characters.
//!
//! Most string operations in Rust act on UTF-8 strings. However, at times it
//! makes more sense to only consider the ASCII character set for a specific
//! operation.
//!
//! The [`escape_default`] function provides an iterator over the bytes of an
//! escaped version of the character given.

#![stable(feature = "core_ascii", since = "1.26.0")]

use crate::fmt;
use crate::iter::FusedIterator;
use crate::ops::Range;
use crate::str::from_utf8_unchecked;

/// An iterator over the escaped version of a byte.
///
/// This `struct` is created by the [`escape_default`] function. See its
/// documentation for more.
#[stable(feature = "rust1", since = "1.0.0")]
#[derive(Clone)]
pub struct EscapeDefault {
    range: Range<usize>,
    data: [u8; 4],
}

/// Returns an iterator that produces an escaped version of a `u8`.
///
/// The default is chosen with a bias toward producing literals that are
/// legal in a variety of languages, including C++11 and similar C-family
/// languages. The exact rules are:
///
/// * Tab is escaped as `\t`.
/// * Carriage return is escaped as `\r`.
/// * Line feed is escaped as `\n`.
/// * Single quote is escaped as `\'`.
/// * Double quote is escaped as `\"`.
/// * Backslash is escaped as `\\`.
/// * Any character in the 'printable ASCII' range `0x20` .. `0x7e`
///   inclusive is not escaped.
/// * Any other chars are given hex escapes of the form '\xNN'.
/// * Unicode escapes are never generated by this function.
///
/// # Examples
///
/// ```
/// use std::ascii;
///
/// let escaped = ascii::escape_default(b'0').next().unwrap();
/// assert_eq!(b'0', escaped);
///
/// let mut escaped = ascii::escape_default(b'\t');
///
/// assert_eq!(b'\\', escaped.next().unwrap());
/// assert_eq!(b't', escaped.next().unwrap());
///
/// let mut escaped = ascii::escape_default(b'\r');
///
/// assert_eq!(b'\\', escaped.next().unwrap());
/// assert_eq!(b'r', escaped.next().unwrap());
///
/// let mut escaped = ascii::escape_default(b'\n');
///
/// assert_eq!(b'\\', escaped.next().unwrap());
/// assert_eq!(b'n', escaped.next().unwrap());
///
/// let mut escaped = ascii::escape_default(b'\'');
///
/// assert_eq!(b'\\', escaped.next().unwrap());
/// assert_eq!(b'\'', escaped.next().unwrap());
///
/// let mut escaped = ascii::escape_default(b'"');
///
/// assert_eq!(b'\\', escaped.next().unwrap());
/// assert_eq!(b'"', escaped.next().unwrap());
///
/// let mut escaped = ascii::escape_default(b'\\');
///
/// assert_eq!(b'\\', escaped.next().unwrap());
/// assert_eq!(b'\\', escaped.next().unwrap());
///
/// let mut escaped = ascii::escape_default(b'\x9d');
///
/// assert_eq!(b'\\', escaped.next().unwrap());
/// assert_eq!(b'x', escaped.next().unwrap());
/// assert_eq!(b'9', escaped.next().unwrap());
/// assert_eq!(b'd', escaped.next().unwrap());
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn escape_default(c: u8) -> EscapeDefault {
    let (data, len) = match c {
        b'\t' => ([b'\\', b't', 0, 0], 2),
        b'\r' => ([b'\\', b'r', 0, 0], 2),
        b'\n' => ([b'\\', b'n', 0, 0], 2),
        b'\\' => ([b'\\', b'\\', 0, 0], 2),
        b'\'' => ([b'\\', b'\'', 0, 0], 2),
        b'"' => ([b'\\', b'"', 0, 0], 2),
        b'\x20'..=b'\x7e' => ([c, 0, 0, 0], 1),
        _ => ([b'\\', b'x', hexify(c >> 4), hexify(c & 0xf)], 4),
    };

    return EscapeDefault { range: 0..len, data };

    fn hexify(b: u8) -> u8 {
        match b {
            0..=9 => b'0' + b,
            _ => b'a' + b - 10,
        }
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl Iterator for EscapeDefault {
    type Item = u8;
    fn next(&mut self) -> Option<u8> {
        self.range.next().map(|i| self.data[i])
    }
    fn size_hint(&self) -> (usize, Option<usize>) {
        self.range.size_hint()
    }
    fn last(mut self) -> Option<u8> {
        self.next_back()
    }
}
#[stable(feature = "rust1", since = "1.0.0")]
impl DoubleEndedIterator for EscapeDefault {
    fn next_back(&mut self) -> Option<u8> {
        self.range.next_back().map(|i| self.data[i])
    }
}
#[stable(feature = "rust1", since = "1.0.0")]
impl ExactSizeIterator for EscapeDefault {}
#[stable(feature = "fused", since = "1.26.0")]
impl FusedIterator for EscapeDefault {}

#[stable(feature = "ascii_escape_display", since = "1.39.0")]
impl fmt::Display for EscapeDefault {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        // SAFETY: ok because `escape_default` created only valid utf-8 data
        f.write_str(unsafe { from_utf8_unchecked(&self.data[self.range.clone()]) })
    }
}

#[stable(feature = "std_debug", since = "1.16.0")]
impl fmt::Debug for EscapeDefault {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.debug_struct("EscapeDefault").finish_non_exhaustive()
    }
}
<commit_msg>Rollup merge of #89015 - klensy:escape-def, r=Mark-Simulacrum<commit_after>//! Operations on ASCII strings and characters.
//!
//! Most string operations in Rust act on UTF-8 strings. However, at times it
//! makes more sense to only consider the ASCII character set for a specific
//! operation.
//!
//! The [`escape_default`] function provides an iterator over the bytes of an
//! escaped version of the character given.

#![stable(feature = "core_ascii", since = "1.26.0")]

use crate::fmt;
use crate::iter::FusedIterator;
use crate::ops::Range;
use crate::str::from_utf8_unchecked;

/// An iterator over the escaped version of a byte.
///
/// This `struct` is created by the [`escape_default`] function. See its
/// documentation for more.
#[stable(feature = "rust1", since = "1.0.0")]
#[derive(Clone)]
pub struct EscapeDefault {
    range: Range<u8>,
    data: [u8; 4],
}

/// Returns an iterator that produces an escaped version of a `u8`.
///
/// The default is chosen with a bias toward producing literals that are
/// legal in a variety of languages, including C++11 and similar C-family
/// languages. The exact rules are:
///
/// * Tab is escaped as `\t`.
/// * Carriage return is escaped as `\r`.
/// * Line feed is escaped as `\n`.
/// * Single quote is escaped as `\'`.
/// * Double quote is escaped as `\"`.
/// * Backslash is escaped as `\\`.
/// * Any character in the 'printable ASCII' range `0x20` .. `0x7e`
///   inclusive is not escaped.
/// * Any other chars are given hex escapes of the form '\xNN'.
/// * Unicode escapes are never generated by this function.
///
/// # Examples
///
/// ```
/// use std::ascii;
///
/// let escaped = ascii::escape_default(b'0').next().unwrap();
/// assert_eq!(b'0', escaped);
///
/// let mut escaped = ascii::escape_default(b'\t');
///
/// assert_eq!(b'\\', escaped.next().unwrap());
/// assert_eq!(b't', escaped.next().unwrap());
///
/// let mut escaped = ascii::escape_default(b'\r');
///
/// assert_eq!(b'\\', escaped.next().unwrap());
/// assert_eq!(b'r', escaped.next().unwrap());
///
/// let mut escaped = ascii::escape_default(b'\n');
///
/// assert_eq!(b'\\', escaped.next().unwrap());
/// assert_eq!(b'n', escaped.next().unwrap());
///
/// let mut escaped = ascii::escape_default(b'\'');
///
/// assert_eq!(b'\\', escaped.next().unwrap());
/// assert_eq!(b'\'', escaped.next().unwrap());
///
/// let mut escaped = ascii::escape_default(b'"');
///
/// assert_eq!(b'\\', escaped.next().unwrap());
/// assert_eq!(b'"', escaped.next().unwrap());
///
/// let mut escaped = ascii::escape_default(b'\\');
///
/// assert_eq!(b'\\', escaped.next().unwrap());
/// assert_eq!(b'\\', escaped.next().unwrap());
///
/// let mut escaped = ascii::escape_default(b'\x9d');
///
/// assert_eq!(b'\\', escaped.next().unwrap());
/// assert_eq!(b'x', escaped.next().unwrap());
/// assert_eq!(b'9', escaped.next().unwrap());
/// assert_eq!(b'd', escaped.next().unwrap());
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn escape_default(c: u8) -> EscapeDefault {
    let (data, len) = match c {
        b'\t' => ([b'\\', b't', 0, 0], 2),
        b'\r' => ([b'\\', b'r', 0, 0], 2),
        b'\n' => ([b'\\', b'n', 0, 0], 2),
        b'\\' => ([b'\\', b'\\', 0, 0], 2),
        b'\'' => ([b'\\', b'\'', 0, 0], 2),
        b'"' => ([b'\\', b'"', 0, 0], 2),
        b'\x20'..=b'\x7e' => ([c, 0, 0, 0], 1),
        _ => ([b'\\', b'x', hexify(c >> 4), hexify(c & 0xf)], 4),
    };

    return EscapeDefault { range: 0..len, data };

    fn hexify(b: u8) -> u8 {
        match b {
            0..=9 => b'0' + b,
            _ => b'a' + b - 10,
        }
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl Iterator for EscapeDefault {
    type Item = u8;
    fn next(&mut self) -> Option<u8> {
        self.range.next().map(|i| self.data[i as usize])
    }
    fn size_hint(&self) -> (usize, Option<usize>) {
        self.range.size_hint()
    }
    fn last(mut self) -> Option<u8> {
        self.next_back()
    }
}
#[stable(feature = "rust1", since = "1.0.0")]
impl DoubleEndedIterator for EscapeDefault {
    fn next_back(&mut self) -> Option<u8> {
        self.range.next_back().map(|i| self.data[i as usize])
    }
}
#[stable(feature = "rust1", since = "1.0.0")]
impl ExactSizeIterator for EscapeDefault {}
#[stable(feature = "fused", since = "1.26.0")]
impl FusedIterator for EscapeDefault {}

#[stable(feature = "ascii_escape_display", since = "1.39.0")]
impl fmt::Display for EscapeDefault {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        // SAFETY: ok because `escape_default` created only valid utf-8 data
        f.write_str(unsafe {
            from_utf8_unchecked(&self.data[(self.range.start as usize)..(self.range.end as usize)])
        })
    }
}

#[stable(feature = "std_debug", since = "1.16.0")]
impl fmt::Debug for EscapeDefault {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.debug_struct("EscapeDefault").finish_non_exhaustive()
    }
}
<|endoftext|>


<commit_before>/// Implement ncurses-compatible database discovery

use core::os;
use core::os::getenv;
use core::str;
use core::io::{file_reader, Reader};
use path = core::path::PosixPath;

/// Return path to database entry for `term`
pub fn get_dbpath_for_term(term: &str) -> Option<~path> {
    if term.len() == 0 {
        return None;
    }

    let homedir = os::homedir();

    let mut dirs_to_search = ~[];
    let first_char = term.substr(0, 1);

    // Find search directory
    match getenv(~"TERMINFO") {
        Some(dir) => dirs_to_search.push(path(dir)),
        None => {
            if homedir.is_some() {
                dirs_to_search.push(homedir.unwrap().push(".terminfo")); // ncurses compatability
            }
            match getenv(~"TERMINFO_DIRS") {
                Some(dirs) => for str::each_split_char(dirs, ':') |i| {
                    if i == ~"" {
                        dirs_to_search.push(path(~"/usr/share/terminfo"));
                    } else {
                        dirs_to_search.push(path(i.to_owned()));
                    }
                },
                // Found nothing, use the default path
                None => dirs_to_search.push(path(~"/usr/share/terminfo"))
            }
        }
    };

    // Look for the terminal in all of the search directories
    for dirs_to_search.each |p| {
        let newp = ~p.push_many(&[first_char.to_owned(), term.to_owned()]);
        if os::path_exists(p) && os::path_exists(newp) {
            return Some(newp);
        }
    }
    None
}

/// Return open file for `term`
fn open(term: &str) -> Result<@Reader, ~str> {
    match get_dbpath_for_term(term) {
        Some(x) => file_reader(x),
        None => Err(fmt!("could not find terminfo entry for %s", term))
    }
}

#[test]
fn test_get_dbpath_for_term() {
    // woefully inadequate test coverage
    use core::os::{setenv, unsetenv};
    fn x(t: &str) -> ~str { get_dbpath_for_term(t).expect("no terminfo entry found").to_str() };
    assert!(x("screen") == ~"/usr/share/terminfo/s/screen");
    assert!(get_dbpath_for_term("") == None);
    setenv("TERMINFO_DIRS", ":");
    assert!(x("screen") == ~"/usr/share/terminfo/s/screen");
    unsetenv("TERMINFO_DIRS");
}

#[test]
fn test_open() {
    open("screen");
    let t = open("nonexistent terminal that hopefully does not exist");
    assert!(t.is_err());
}
<commit_msg>add note about bdb<commit_after>/// Implement ncurses-compatible database discovery
/// Does not support hashed database, only filesystem!

use core::os;
use core::os::getenv;
use core::str;
use core::io::{file_reader, Reader};
use path = core::path::PosixPath;

/// Return path to database entry for `term`
pub fn get_dbpath_for_term(term: &str) -> Option<~path> {
    if term.len() == 0 {
        return None;
    }

    let homedir = os::homedir();

    let mut dirs_to_search = ~[];
    let first_char = term.substr(0, 1);

    // Find search directory
    match getenv(~"TERMINFO") {
        Some(dir) => dirs_to_search.push(path(dir)),
        None => {
            if homedir.is_some() {
                dirs_to_search.push(homedir.unwrap().push(".terminfo")); // ncurses compatability
            }
            match getenv(~"TERMINFO_DIRS") {
                Some(dirs) => for str::each_split_char(dirs, ':') |i| {
                    if i == ~"" {
                        dirs_to_search.push(path(~"/usr/share/terminfo"));
                    } else {
                        dirs_to_search.push(path(i.to_owned()));
                    }
                },
                // Found nothing, use the default path
                None => dirs_to_search.push(path(~"/usr/share/terminfo"))
            }
        }
    };

    // Look for the terminal in all of the search directories
    for dirs_to_search.each |p| {
        let newp = ~p.push_many(&[first_char.to_owned(), term.to_owned()]);
        if os::path_exists(p) && os::path_exists(newp) {
            return Some(newp);
        }
    }
    None
}

/// Return open file for `term`
fn open(term: &str) -> Result<@Reader, ~str> {
    match get_dbpath_for_term(term) {
        Some(x) => file_reader(x),
        None => Err(fmt!("could not find terminfo entry for %s", term))
    }
}

#[test]
fn test_get_dbpath_for_term() {
    // woefully inadequate test coverage
    use core::os::{setenv, unsetenv};
    fn x(t: &str) -> ~str { get_dbpath_for_term(t).expect("no terminfo entry found").to_str() };
    assert!(x("screen") == ~"/usr/share/terminfo/s/screen");
    assert!(get_dbpath_for_term("") == None);
    setenv("TERMINFO_DIRS", ":");
    assert!(x("screen") == ~"/usr/share/terminfo/s/screen");
    unsetenv("TERMINFO_DIRS");
}

#[test]
fn test_open() {
    open("screen");
    let t = open("nonexistent terminal that hopefully does not exist");
    assert!(t.is_err());
}
<|endoftext|>


<commit_before>extern crate num_cpus;
use clap::Arg;
use chrono::*;

pub struct Config {
    pub url: String,
    pub num_threads: usize,
    pub num_connections: usize,
    pub duration: Duration,
    pub timeout: Duration,
}

fn integer_validator<E>(input: String, error_message: E) -> Result<(), String>
    where E: Into<String>
{
    input.parse::<usize>()
        .map(|_| ())
        .map_err(|_| error_message.into())
}

pub fn parse_args() -> Config {
    let app = app_from_crate!();
    let num_cpus_str = num_cpus::get().to_string();
    let matches = app.arg(Arg::with_name("url")
            .required(true)
            .help("target url"))
        .arg(Arg::with_name("threads")
            .short("t")
            .default_value(&num_cpus_str)
            .validator(|i| integer_validator(i, "Number of threads must be an integer"))
            .help("Number of threads to use. Default is the number of CPUs"))
        .arg(Arg::with_name("connections")
            .short("c")
            .default_value("10")
            .validator(|i| integer_validator(i, "Number of connections must be an integer"))
            .help("Number of connections to spawn"))
        .arg(Arg::with_name("duration")
            .short("d")
            .default_value("10")
            .validator(|i| integer_validator(i, "Duration must be an integer"))
            .help("Duration in seconds to run"))
        .arg(Arg::with_name("timeout")
            .long("timeout")
            .default_value("10")
            .validator(|i| integer_validator(i, "Timeout must be an integer"))
            .help("Timeout in seconds to run"))
        .get_matches();

    // this can be unwrapped, as the validator should guarantee the argument is an integer
    let num_threads = matches.value_of("threads").map(|x| x.parse()).unwrap().unwrap();
    // this can be unwrapped, as the validator should guarantee the argument is an integer
    let num_connections = matches.value_of("connections").map(|x| x.parse()).unwrap().unwrap();
    let duration_seconds = matches.value_of("duration").map(|x| x.parse()).unwrap().unwrap();
    let timeout_seconds = matches.value_of("timeout").map(|x| x.parse()).unwrap().unwrap();

    Config {
        url: matches.value_of("url").unwrap().into(),
        num_threads: num_threads,
        num_connections: num_connections,
        duration: Duration::seconds(duration_seconds),
        timeout: Duration::seconds(timeout_seconds),
    }
}
<commit_msg>args cleaner unwrap<commit_after>extern crate num_cpus;
use clap::Arg;
use chrono::*;

pub struct Config {
    pub url: String,
    pub num_threads: usize,
    pub num_connections: usize,
    pub duration: Duration,
    pub timeout: Duration,
}

fn integer_validator<E>(input: String, error_message: E) -> Result<(), String>
    where E: Into<String>
{
    input.parse::<usize>()
        .map(|_| ())
        .map_err(|_| error_message.into())
}

pub fn parse_args() -> Config {
    let app = app_from_crate!();
    let num_cpus_str = num_cpus::get().to_string();
    let matches = app.arg(Arg::with_name("url")
            .required(true)
            .help("target url"))
        .arg(Arg::with_name("threads")
            .short("t")
            .default_value(&num_cpus_str)
            .validator(|i| integer_validator(i, "Number of threads must be an integer"))
            .help("Number of threads to use. Default is the number of CPUs"))
        .arg(Arg::with_name("connections")
            .short("c")
            .default_value("10")
            .validator(|i| integer_validator(i, "Number of connections must be an integer"))
            .help("Number of connections to spawn"))
        .arg(Arg::with_name("duration")
            .short("d")
            .default_value("10")
            .validator(|i| integer_validator(i, "Duration must be an integer"))
            .help("Duration in seconds to run"))
        .arg(Arg::with_name("timeout")
            .long("timeout")
            .default_value("10")
            .validator(|i| integer_validator(i, "Timeout must be an integer"))
            .help("Timeout in seconds to run"))
        .get_matches();

    // these can be unwrapped, as the validator should guarantee the argument is an integer
    let num_threads = matches.value_of("threads").and_then(|x| x.parse().ok()).unwrap();
    let num_connections = matches.value_of("connections").and_then(|x| x.parse().ok()).unwrap();
    let duration_seconds = matches.value_of("duration").and_then(|x| x.parse().ok()).unwrap();
    let timeout_seconds = matches.value_of("timeout").and_then(|x| x.parse().ok()).unwrap();

    Config {
        url: matches.value_of("url").unwrap().into(),
        num_threads: num_threads,
        num_connections: num_connections,
        duration: Duration::seconds(duration_seconds),
        timeout: Duration::seconds(timeout_seconds),
    }
}
<|endoftext|>


<commit_before>// Copyright 2016, The Gtk-rs Project Developers.
// See the COPYRIGHT file at the top-level directory of this distribution.
// Licensed under the MIT license, see the LICENSE file or <http://opensource.org/licenses/MIT>

//! `Error` binding and helper trait.

use std::ffi::CStr;
use std::error;
use std::fmt;
use std::str;
use std::ptr;
use std::mem;
use translate::*;
use ffi as glib_ffi;
use gobject_ffi;

glib_wrapper! {
    /// A generic error capable of representing various error domains (types).
    pub struct Error(Boxed<glib_ffi::GError>);

    match fn {
        copy => |ptr| glib_ffi::g_error_copy(ptr),
        free => |ptr| glib_ffi::g_error_free(ptr),
        get_type => || glib_ffi::g_error_get_type(),
    }
}

impl Error {
    /// Creates an error with supplied error enum variant and message.
    pub fn new<T: ErrorDomain>(error: T, message: &str) -> Error {
        unsafe {
            from_glib_full(
                glib_ffi::g_error_new_literal(T::domain(), error.code(), message.to_glib_none().0))
        }
    }

    /// Checks if the error domain matches `T`.
    pub fn is<T: ErrorDomain>(&self) -> bool {
        self.0.domain == T::domain()
    }

    /// Tries to convert to a specific error enum.
    ///
    /// Returns `Some` if the error belongs to the enum's error domain and
    /// `None` otherwise.
    ///
    /// # Examples
    ///
    /// ```ignore
    /// if let Some(file_error) = error.kind::<FileError>() {
    ///     match file_error {
    ///         FileError::Exist => ...
    ///         FileError::Isdir => ...
    ///         ...
    ///     }
    /// }
    /// ```
    ///
    /// ```ignore
    /// match error {
    ///     Some(FileError::Exist) => ...
    ///     Some(FileError::Isdir) => ...
    ///     ...
    /// }
    /// ```
    pub fn kind<T: ErrorDomain>(&self) -> Option<T> {
        if self.0.domain == T::domain() {
            T::from(self.0.code)
        }
        else {
            None
        }
    }

    fn message(&self) -> &str {
        unsafe {
            let bytes = CStr::from_ptr(self.0.message).to_bytes();
            str::from_utf8(bytes).unwrap_or_else(|err| {
                str::from_utf8(&bytes[..err.valid_up_to()]).unwrap()
            })
        }
    }

    // backcompat shim
    pub fn wrap(ptr: *mut glib_ffi::GError) -> Error {
        unsafe { from_glib_full(ptr) }
    }
}

impl fmt::Display for Error {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}", self.message())
    }
}

impl error::Error for Error {
    fn description(&self) -> &str {
        self.message()
    }
}

/// `GLib` error domain.
///
/// This trait is implemented by error enums that represent error domains (types).
pub trait ErrorDomain: Copy {
    /// Returns the quark identifying the error domain.
    ///
    /// As returned from `g_some_error_quark`.
    fn domain() -> glib_ffi::GQuark;

    /// Gets the integer representation of the variant.
    fn code(self) -> i32;

    /// Tries to convert an integer code to an enum variant.
    ///
    /// By convention, the `Failed` variant, if present, is a catch-all,
    /// i.e. any unrecognized codes map to it.
    fn from(code: i32) -> Option<Self> where Self: Sized;
}

/// Generic error used for functions that fail without any further information
#[derive(Debug)]
pub struct BoolError(pub &'static str);

impl BoolError {
    pub fn from_glib(b: glib_ffi::gboolean, s: &'static str) -> Result<(), Self> {
        match b {
            glib_ffi::GFALSE => Err(BoolError(s)),
            _ => Ok(()),
        }
    }
}

impl fmt::Display for BoolError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}", self.0)
    }
}

impl error::Error for BoolError {
    fn description(&self) -> &str {
        self.0
    }
}
<commit_msg>Make glib::Error Send/Sync<commit_after>// Copyright 2016, The Gtk-rs Project Developers.
// See the COPYRIGHT file at the top-level directory of this distribution.
// Licensed under the MIT license, see the LICENSE file or <http://opensource.org/licenses/MIT>

//! `Error` binding and helper trait.

use std::ffi::CStr;
use std::error;
use std::fmt;
use std::str;
use std::ptr;
use std::mem;
use translate::*;
use ffi as glib_ffi;
use gobject_ffi;

glib_wrapper! {
    /// A generic error capable of representing various error domains (types).
    pub struct Error(Boxed<glib_ffi::GError>);

    match fn {
        copy => |ptr| glib_ffi::g_error_copy(ptr),
        free => |ptr| glib_ffi::g_error_free(ptr),
        get_type => || glib_ffi::g_error_get_type(),
    }
}

unsafe impl Send for Error {}
unsafe impl Sync for Error {}

impl Error {
    /// Creates an error with supplied error enum variant and message.
    pub fn new<T: ErrorDomain>(error: T, message: &str) -> Error {
        unsafe {
            from_glib_full(
                glib_ffi::g_error_new_literal(T::domain(), error.code(), message.to_glib_none().0))
        }
    }

    /// Checks if the error domain matches `T`.
    pub fn is<T: ErrorDomain>(&self) -> bool {
        self.0.domain == T::domain()
    }

    /// Tries to convert to a specific error enum.
    ///
    /// Returns `Some` if the error belongs to the enum's error domain and
    /// `None` otherwise.
    ///
    /// # Examples
    ///
    /// ```ignore
    /// if let Some(file_error) = error.kind::<FileError>() {
    ///     match file_error {
    ///         FileError::Exist => ...
    ///         FileError::Isdir => ...
    ///         ...
    ///     }
    /// }
    /// ```
    ///
    /// ```ignore
    /// match error {
    ///     Some(FileError::Exist) => ...
    ///     Some(FileError::Isdir) => ...
    ///     ...
    /// }
    /// ```
    pub fn kind<T: ErrorDomain>(&self) -> Option<T> {
        if self.0.domain == T::domain() {
            T::from(self.0.code)
        }
        else {
            None
        }
    }

    fn message(&self) -> &str {
        unsafe {
            let bytes = CStr::from_ptr(self.0.message).to_bytes();
            str::from_utf8(bytes).unwrap_or_else(|err| {
                str::from_utf8(&bytes[..err.valid_up_to()]).unwrap()
            })
        }
    }

    // backcompat shim
    pub fn wrap(ptr: *mut glib_ffi::GError) -> Error {
        unsafe { from_glib_full(ptr) }
    }
}

impl fmt::Display for Error {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}", self.message())
    }
}

impl error::Error for Error {
    fn description(&self) -> &str {
        self.message()
    }
}

/// `GLib` error domain.
///
/// This trait is implemented by error enums that represent error domains (types).
pub trait ErrorDomain: Copy {
    /// Returns the quark identifying the error domain.
    ///
    /// As returned from `g_some_error_quark`.
    fn domain() -> glib_ffi::GQuark;

    /// Gets the integer representation of the variant.
    fn code(self) -> i32;

    /// Tries to convert an integer code to an enum variant.
    ///
    /// By convention, the `Failed` variant, if present, is a catch-all,
    /// i.e. any unrecognized codes map to it.
    fn from(code: i32) -> Option<Self> where Self: Sized;
}

/// Generic error used for functions that fail without any further information
#[derive(Debug)]
pub struct BoolError(pub &'static str);

impl BoolError {
    pub fn from_glib(b: glib_ffi::gboolean, s: &'static str) -> Result<(), Self> {
        match b {
            glib_ffi::GFALSE => Err(BoolError(s)),
            _ => Ok(()),
        }
    }
}

impl fmt::Display for BoolError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}", self.0)
    }
}

impl error::Error for BoolError {
    fn description(&self) -> &str {
        self.0
    }
}
<|endoftext|>


<commit_before>//! Custom Error Types for errors that may occur when handling todos (or lists).

/// Custom Result Type for tdo.
///
/// This abbreviation is introduced since many functions throughout the crate return
/// this type of result, which bundles all possible errors of the `tdo_core` crate.
pub type TdoResult<T> = Result<T>;

/// Errors that can arise when working with todo lists.
pub mod todo_error {
    error_chain! {
        errors {
            /// The requested item is not in the list.
            NotInList {
                description("Todo is not in this list")
            }
            /// The requested todo list does not exist.
            NoSuchList {
                description("No such list")
            }
            /// The default list is tried to be removed.
            CanNotRemoveDefault {
                description("The default list can no be removed")
            }
            /// A list with the same name already exists.
            NameAlreadyExists {
                description("There already exists a list with this name")
            }
            /// A todo with the same ID already exists.
            IDAlreadyExists {
                description("There already exists a todo with this ID")
            }
        }
    }
}

/// Errors that can arise when interacting with github.
pub mod github_error {
    error_chain! {
        errors {
            /// Repository does not exist
            DoesNotExist {
                description("Repository does not exist")
            }
            /// Bad credentials
            BadCredentials {
                description("Bad credentials")
            }
            /// Not allowed to move error
            NotAllowedToMove {
                description("A github issue is not allowed to be moved out ouf the default list")
            }
            /// Unknown error
            UnknownError {
                description("An unknown error occured")
            }
        }
    }
}

/// The Errors that may occur while interacting with the file system.
pub mod storage_error {
    error_chain! {
        errors {
            /// The accessed file is corrupted. This is most likely
            /// because someone edited the JSON file manually.
            FileCorrupted {
                description("File is corrupted")
            }
            /// The data could not be written to the file.
            SaveFailure {
                description("File could not be saved")
            }
            /// The requested file could not be found.
            FileNotFound {
                description("File was not found")
            }
            /// The conversion of an older format failed.
            UnableToConvert {
                description("File could not be converted automatically")
            }
        }
    }
}

error_chain! {
    links {
        TodoError(todo_error::Error, todo_error::ErrorKind) #[doc = "An error within the tdo data structures occured."];
        StorageError(storage_error::Error, storage_error::ErrorKind) #[doc = "A storage-related error occured while interacting with the file system."];
        GithubError(github_error::Error, github_error::ErrorKind) #[doc = "A github communication-related error occured."];
    }
}
<commit_msg>Add another errorkind in GitHubError<commit_after>//! Custom Error Types for errors that may occur when handling todos (or lists).

/// Custom Result Type for tdo.
///
/// This abbreviation is introduced since many functions throughout the crate return
/// this type of result, which bundles all possible errors of the `tdo_core` crate.
pub type TdoResult<T> = Result<T>;

/// Errors that can arise when working with todo lists.
pub mod todo_error {
    error_chain! {
        errors {
            /// The requested item is not in the list.
            NotInList {
                description("Todo is not in this list")
            }
            /// The requested todo list does not exist.
            NoSuchList {
                description("No such list")
            }
            /// The default list is tried to be removed.
            CanNotRemoveDefault {
                description("The default list can no be removed")
            }
            /// A list with the same name already exists.
            NameAlreadyExists {
                description("There already exists a list with this name")
            }
            /// A todo with the same ID already exists.
            IDAlreadyExists {
                description("There already exists a todo with this ID")
            }
        }
    }
}

/// Errors that can arise when interacting with github.
pub mod github_error {
    error_chain! {
        errors {
            /// Repository does not exist
            DoesNotExist {
                description("Repository does not exist")
            }
            /// Bad credentials
            BadCredentials {
                description("Bad credentials")
            }
            /// Not allowed to move error
            NotAllowedToMove {
                description("A github issue is not allowed to be moved out ouf the default list")
            }
            /// Not a guthub issue eroor
            NoIssueAsigned {
                description("There is no github issue asigned to this todo")
            }
            /// Unknown error
            UnknownError {
                description("An unknown error occured")
            }
        }
    }
}

/// The Errors that may occur while interacting with the file system.
pub mod storage_error {
    error_chain! {
        errors {
            /// The accessed file is corrupted. This is most likely
            /// because someone edited the JSON file manually.
            FileCorrupted {
                description("File is corrupted")
            }
            /// The data could not be written to the file.
            SaveFailure {
                description("File could not be saved")
            }
            /// The requested file could not be found.
            FileNotFound {
                description("File was not found")
            }
            /// The conversion of an older format failed.
            UnableToConvert {
                description("File could not be converted automatically")
            }
        }
    }
}

error_chain! {
    links {
        TodoError(todo_error::Error, todo_error::ErrorKind) #[doc = "An error within the tdo data structures occured."];
        StorageError(storage_error::Error, storage_error::ErrorKind) #[doc = "A storage-related error occured while interacting with the file system."];
        GithubError(github_error::Error, github_error::ErrorKind) #[doc = "A github communication-related error occured."];
    }
}
<|endoftext|>


<commit_before>use turtle::{Distance, Drawing, Point, Size, Turtle};

const LEVELS: u8 = 6;
const SPEED: f64 = 25.0;
const BORDER_MARGIN: Distance = 15.0;

fn turn_and_go_to(turtle: &mut Turtle, dest: Point) {
    turtle.turn_towards(dest);
    turtle.go_to(dest);
}

fn sierpinski_triangle(turtle: &mut Turtle, level: u8, size: Distance) {
    if level == 0 {
        turtle.pen_down();

        for _ in 0..3 {
            turtle.forward(size);
            turtle.left(120.0);
        }

        turtle.pen_up();
    } else {
        let next_level = level - 1;
        let next_size = size / 2.0;

        sierpinski_triangle(turtle, next_level, next_size);

        turtle.forward(next_size);

        sierpinski_triangle(turtle, next_level, next_size);

        turtle.left(120.0);
        turtle.forward(next_size);
        turtle.right(120.0);

        sierpinski_triangle(turtle, next_level, next_size);

        turtle.right(120.0);
        turtle.forward(next_size);
        turtle.left(120.0);
    }
}

fn sierpinski_triangle_auto(turtle: &mut Turtle, level: u8, canvas_size: Size) {
    let auto_size = canvas_size.width.min(canvas_size.height) as f64 - 2.0 * BORDER_MARGIN;
    let start_point_coord = -auto_size / 2.0;

    turtle.pen_up();
    turn_and_go_to(turtle, [start_point_coord, start_point_coord].into());
    turtle.set_heading(0.0);

    sierpinski_triangle(turtle, level, auto_size);
}

fn main() {
    let mut drawing = Drawing::new();
    let mut turtle = drawing.add_turtle();

    turtle.use_degrees();
    turtle.set_speed(SPEED);

    sierpinski_triangle_auto(&mut turtle, LEVELS, drawing.size());

    turtle.hide();
}
<commit_msg>Better auto-sizing for Sierpinski Triangle example<commit_after>use turtle::{Distance, Drawing, Point, Size, Turtle};

const LEVELS: u8 = 6;
const SPEED: f64 = 25.0;
const BORDER_MARGIN: Distance = 15.0;

fn turn_and_go_to(turtle: &mut Turtle, dest: Point) {
    turtle.turn_towards(dest);
    turtle.go_to(dest);
}

fn sierpinski_triangle(turtle: &mut Turtle, level: u8, size: Distance) {
    if level == 0 {
        turtle.pen_down();

        for _ in 0..3 {
            turtle.forward(size);
            turtle.left(120.0);
        }

        turtle.pen_up();
    } else {
        let next_level = level - 1;
        let next_size = size / 2.0;

        sierpinski_triangle(turtle, next_level, next_size);

        turtle.forward(next_size);

        sierpinski_triangle(turtle, next_level, next_size);

        turtle.left(120.0);
        turtle.forward(next_size);
        turtle.right(120.0);

        sierpinski_triangle(turtle, next_level, next_size);

        turtle.right(120.0);
        turtle.forward(next_size);
        turtle.left(120.0);
    }
}

fn sierpinski_triangle_auto(turtle: &mut Turtle, level: u8, canvas_size: Size) {
    let auto_size = (canvas_size.width as f64).min(canvas_size.height as f64 * 2.0 / 3f64.sqrt())
        - 2.0 * BORDER_MARGIN;

    turtle.pen_up();
    turn_and_go_to(
        turtle,
        [-auto_size / 2.0, -auto_size / 4.0 * 3f64.sqrt()].into(),
    );
    turtle.set_heading(0.0);

    sierpinski_triangle(turtle, level, auto_size);
}

fn main() {
    let mut drawing = Drawing::new();
    let mut turtle = drawing.add_turtle();

    turtle.use_degrees();
    turtle.set_speed(SPEED);

    sierpinski_triangle_auto(&mut turtle, LEVELS, drawing.size());

    turtle.hide();
}
<|endoftext|>