<commit_before>use std::fmt;
use std::vec::Vec;
use collections::treemap::TreeMap;
#[deriving(Clone, Eq)]
/// A Javascript Constant
pub enum Const {
	/// A UTF-8 string
	CString(~str),
	/// A regular expression
	CRegExp(~str, bool, bool),
	/// A 64-bit floating-point number
	CNum(f64),
	/// A 32-bit integer
	CInt(i32),
	/// A boolean
	CBool(bool),
	/// Null
	CNull,
	/// The infamous value returned when you access a non-existent field
	CUndefined
}
impl fmt::Show for Const {
	fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
		return match *self {
			CString(ref st) => write!(f.buf, "\"{}\"", st),
			CRegExp(ref reg, _, _) => write!(f.buf, "~/{}/", reg),
			CNum(num) => write!(f.buf, "{}", num),
			CInt(num) => write!(f.buf, "{}", num),
			CBool(v) => write!(f.buf, "{}", v),
			CNull => write!(f.buf, "null"),
			CUndefined => write!(f.buf, "undefined")
		}
	}
}
#[deriving(Clone, Eq)]
/// An operation between 2 values
pub enum NumOp {
	/// Add them togther
	OpAdd,
	/// Subtract the second from the first
	OpSub,
	/// Divide the first by the second
	OpDiv,
	/// Multiply them together
	OpMul,
	/// Bitwise and
	OpAnd,
	/// Bitwise or
	OpOr
}
impl fmt::Show for NumOp {
	fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
		return f.buf.write_str(match *self {
			OpAdd => "+",
			OpSub => "-",
			OpDiv => "/",
			OpMul => "*",
			OpAnd => "&",
			OpOr => "|"
		});
	}
}
#[deriving(Clone, Eq)]
/// A Javscript Expression
pub enum Expr {
	/// Run a numeric operation on two numeric expressions
	NumOpExpr(NumOp, ~Expr, ~Expr),
	/// Make a simple value
	ConstExpr(Const),
	/// Run several expressions
	BlockExpr(Vec<~Expr>),
	/// Load a reference to a value
	LocalExpr(~str),
	/// Gets the cosntant field of the expression
	GetConstFieldExpr(~Expr, ~str),
	/// Gets the field of an expression
	GetFieldExpr(~Expr, ~Expr),
	/// Call a function with some arguments
	CallExpr(~Expr, Vec<~Expr>),
	/// Repeatedly run an expression while the conditional expression resolves to true
	WhileLoopExpr(~Expr, ~Expr),
	/// Check if a conditional expression is true and run an expression if it is and another expression if it isn't
	IfExpr(~Expr, ~Expr, Option<~Expr>),
	/// Run blocks whose cases match the expression
	SwitchExpr(~Expr, Vec<(~Expr, Vec<~Expr>)>, Option<~Expr>),
	/// Create an object
	ObjectDeclExpr(~TreeMap<~str, ~Expr>),
	/// Create an array with items inside
	ArrayDeclExpr(Vec<~Expr>),
	/// Create a function with the given name, arguments, and expression
	FunctionDeclExpr(Option<~str>, Vec<~str>, ~Expr),
	/// Construct an object from the function and arguments given
	ConstructExpr(~Expr, Vec<~Expr>),
	/// Return the expression from a function
	ReturnExpr(Option<~Expr>),
	/// Throw an expression
	ThrowExpr(~Expr),
	/// Assign an expression to another expression
	AssignExpr(~Expr, ~Expr)
}
impl fmt::Show for Expr {
	fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
		return match *self {
			ConstExpr(ref c) => write!(f.buf, "{}", c),
			BlockExpr(ref block) => write!(f.buf, "{} {} {}", '{', block, '}'),
			LocalExpr(ref s) => write!(f.buf, "{}", s),
			GetConstFieldExpr(ref ex, ref field) => write!(f.buf, "{}.{}", ex, field),
			GetFieldExpr(ref ex, ref field) => write!(f.buf, "{}[{}]", ex, field),
			CallExpr(ref ex, ref args) => write!(f.buf, "{}({})", ex, args),
			ConstructExpr(ref func, ref args) => write!(f.buf, "new {}({})", func, args),
			WhileLoopExpr(ref cond, ref expr) => write!(f.buf, "while({}) {}", cond, expr),
			IfExpr(ref cond, ref expr, None) => write!(f.buf, "if({}) {}", cond, expr),
			IfExpr(ref cond, ref expr, Some(ref else_e)) => write!(f.buf, "if({}) {} else {}", cond, expr, else_e),
			SwitchExpr(ref val, ref vals, None) => write!(f.buf, "switch({}){}", val, vals),
			SwitchExpr(ref val, ref vals, Some(ref def)) => write!(f.buf, "switch({}){}default:{}", val, vals, def),
			ObjectDeclExpr(ref map) => write!(f.buf, "{}", map),
			ArrayDeclExpr(ref arr) => write!(f.buf, "{}", arr),
			FunctionDeclExpr(ref name, ref args, ref expr) => write!(f.buf, "function {}({}){}", name, args, expr),
			NumOpExpr(ref op, ref a, ref b) => write!(f.buf, "{} {} {}", a, op, b),
			ReturnExpr(Some(ref ex)) => write!(f.buf, "return {}", ex),
			ReturnExpr(None) => f.buf.write_str("return"),
			ThrowExpr(ref ex) => write!(f.buf, "throw {}", ex),
			AssignExpr(ref ref_e, ref val) => write!(f.buf, "{} = {}", ref_e, val)
		}
	}
}

impl fmt::Show for TreeMap<~str, ~Expr> {
	fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
		try!(f.buf.write_str("{ "));
		for (k, v) in self.iter() {
			try!(write!(f.buf, "{} = {}\n", k, v));
		}
		f.buf.write_str("}")
	}
}
#[deriving(Clone)]
#[deriving(Eq)]
/// A single token of Javacript code - a single word, symbol or constant
pub enum Token {
	/// A string literal
	TString(~str),
	/// A semicolon (;)
	TSemicolon,
	/// A colon
	TColon,
	/// A dot / full stop
	TDot,
	/// An equal sign
	TEqual,
	/// A comma
	TComma,
	/// An identity literal
	TIdent(~str),
	/// An opening bracket
	TOpenParen,
	/// A closing bracket
	TCloseParen,
	/// An opening curly bracket
	TOpenBlock,
	/// An closing curly bracket
	TCloseBlock,
	/// An opening square bracket
	TOpenArray,
	/// A closing square bracket
	TCloseArray,
	/// A 64-bit floating-point number
	TNumber(f64),
	/// A question
	TQuestion,
	/// A numeric operation
	TNumOp(NumOp)
}
impl fmt::Show for Token {
	fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
		return match *self {
			TString(ref s) => write!(f.buf, "\"{}\"", s),
			TSemicolon => f.buf.write_str(";"),
			TColon => f.buf.write_str(":"),
			TDot => f.buf.write_str("."),
			TEqual => f.buf.write_str("="),
			TComma => f.buf.write_str(","),
			TIdent(ref ident) => f.buf.write_str(*ident),
			TOpenParen => f.buf.write_str("("),
			TCloseParen => f.buf.write_str(")"),
			TOpenBlock => f.buf.write_str("{"),
			TCloseBlock => f.buf.write_str("}"),
			TOpenArray => f.buf.write_str("["),
			TCloseArray => f.buf.write_str("]"),
			TNumber(num) => write!(f.buf, "{}", num),
			TQuestion => f.buf.write_str("?"),
			TNumOp(op) => write!(f.buf, "{}", op)
		}
	}
}<commit_msg>Improve string conversion of object declaration expressions<commit_after>use std::fmt;
use std::vec::Vec;
use collections::treemap::TreeMap;
#[deriving(Clone, Eq)]
/// A Javascript Constant
pub enum Const {
	/// A UTF-8 string
	CString(~str),
	/// A regular expression
	CRegExp(~str, bool, bool),
	/// A 64-bit floating-point number
	CNum(f64),
	/// A 32-bit integer
	CInt(i32),
	/// A boolean
	CBool(bool),
	/// Null
	CNull,
	/// The infamous value returned when you access a non-existent field
	CUndefined
}
impl fmt::Show for Const {
	fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
		return match *self {
			CString(ref st) => write!(f.buf, "\"{}\"", st),
			CRegExp(ref reg, _, _) => write!(f.buf, "~/{}/", reg),
			CNum(num) => write!(f.buf, "{}", num),
			CInt(num) => write!(f.buf, "{}", num),
			CBool(v) => write!(f.buf, "{}", v),
			CNull => write!(f.buf, "null"),
			CUndefined => write!(f.buf, "undefined")
		}
	}
}
#[deriving(Clone, Eq)]
/// An operation between 2 values
pub enum NumOp {
	/// Add them togther
	OpAdd,
	/// Subtract the second from the first
	OpSub,
	/// Divide the first by the second
	OpDiv,
	/// Multiply them together
	OpMul,
	/// Bitwise and
	OpAnd,
	/// Bitwise or
	OpOr
}
impl fmt::Show for NumOp {
	fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
		return f.buf.write_str(match *self {
			OpAdd => "+",
			OpSub => "-",
			OpDiv => "/",
			OpMul => "*",
			OpAnd => "&",
			OpOr => "|"
		});
	}
}
#[deriving(Clone, Eq)]
/// A Javscript Expression
pub enum Expr {
	/// Run a numeric operation on two numeric expressions
	NumOpExpr(NumOp, ~Expr, ~Expr),
	/// Make a simple value
	ConstExpr(Const),
	/// Run several expressions
	BlockExpr(Vec<~Expr>),
	/// Load a reference to a value
	LocalExpr(~str),
	/// Gets the cosntant field of the expression
	GetConstFieldExpr(~Expr, ~str),
	/// Gets the field of an expression
	GetFieldExpr(~Expr, ~Expr),
	/// Call a function with some arguments
	CallExpr(~Expr, Vec<~Expr>),
	/// Repeatedly run an expression while the conditional expression resolves to true
	WhileLoopExpr(~Expr, ~Expr),
	/// Check if a conditional expression is true and run an expression if it is and another expression if it isn't
	IfExpr(~Expr, ~Expr, Option<~Expr>),
	/// Run blocks whose cases match the expression
	SwitchExpr(~Expr, Vec<(~Expr, Vec<~Expr>)>, Option<~Expr>),
	/// Create an object
	ObjectDeclExpr(~TreeMap<~str, ~Expr>),
	/// Create an array with items inside
	ArrayDeclExpr(Vec<~Expr>),
	/// Create a function with the given name, arguments, and expression
	FunctionDeclExpr(Option<~str>, Vec<~str>, ~Expr),
	/// Construct an object from the function and arguments given
	ConstructExpr(~Expr, Vec<~Expr>),
	/// Return the expression from a function
	ReturnExpr(Option<~Expr>),
	/// Throw an expression
	ThrowExpr(~Expr),
	/// Assign an expression to another expression
	AssignExpr(~Expr, ~Expr)
}
impl fmt::Show for Expr {
	fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
		return match *self {
			ConstExpr(ref c) => write!(f.buf, "{}", c),
			BlockExpr(ref block) => {
				try!(f.buf.write_str("{"));
				for expr in block.iter() {
					try!(write!(f.buf, "{};", expr));
				}
				f.buf.write_str("}")
			},
			LocalExpr(ref s) => write!(f.buf, "{}", s),
			GetConstFieldExpr(ref ex, ref field) => write!(f.buf, "{}.{}", ex, field),
			GetFieldExpr(ref ex, ref field) => write!(f.buf, "{}[{}]", ex, field),
			CallExpr(ref ex, ref args) => write!(f.buf, "{}({})", ex, args),
			ConstructExpr(ref func, ref args) => write!(f.buf, "new {}({})", func, args),
			WhileLoopExpr(ref cond, ref expr) => write!(f.buf, "while({}) {}", cond, expr),
			IfExpr(ref cond, ref expr, None) => write!(f.buf, "if({}) {}", cond, expr),
			IfExpr(ref cond, ref expr, Some(ref else_e)) => write!(f.buf, "if({}) {} else {}", cond, expr, else_e),
			SwitchExpr(ref val, ref vals, None) => write!(f.buf, "switch({}){}", val, vals),
			SwitchExpr(ref val, ref vals, Some(ref def)) => write!(f.buf, "switch({}){}default:{}", val, vals, def),
			ObjectDeclExpr(ref map) => write!(f.buf, "{}", map),
			ArrayDeclExpr(ref arr) => write!(f.buf, "{}", arr),
			FunctionDeclExpr(ref name, ref args, ref expr) => write!(f.buf, "function {}({}){}", name, args, expr),
			NumOpExpr(ref op, ref a, ref b) => write!(f.buf, "{} {} {}", a, op, b),
			ReturnExpr(Some(ref ex)) => write!(f.buf, "return {}", ex),
			ReturnExpr(None) => f.buf.write_str("return"),
			ThrowExpr(ref ex) => write!(f.buf, "throw {}", ex),
			AssignExpr(ref ref_e, ref val) => write!(f.buf, "{} = {}", ref_e, val)
		}
	}
}

impl fmt::Show for TreeMap<~str, ~Expr> {
	fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
		try!(f.buf.write_str("{ "));
		match self.iter().last() {
			Some((last_key, _)) => {
				for (k, v) in self.iter() {
					try!(write!(f.buf, "{}: {}", k, v));
					if k == last_key {
						try!(f.buf.write_str(","));
					}
					try!(f.buf.write_str("\n"));
				}
			},
			None => ()
		}
		f.buf.write_str("}")
	}
}
#[deriving(Clone)]
#[deriving(Eq)]
/// A single token of Javacript code - a single word, symbol or constant
pub enum Token {
	/// A string literal
	TString(~str),
	/// A semicolon (;)
	TSemicolon,
	/// A colon
	TColon,
	/// A dot / full stop
	TDot,
	/// An equal sign
	TEqual,
	/// A comma
	TComma,
	/// An identity literal
	TIdent(~str),
	/// An opening bracket
	TOpenParen,
	/// A closing bracket
	TCloseParen,
	/// An opening curly bracket
	TOpenBlock,
	/// An closing curly bracket
	TCloseBlock,
	/// An opening square bracket
	TOpenArray,
	/// A closing square bracket
	TCloseArray,
	/// A 64-bit floating-point number
	TNumber(f64),
	/// A question
	TQuestion,
	/// A numeric operation
	TNumOp(NumOp)
}
impl fmt::Show for Token {
	fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
		return match *self {
			TString(ref s) => write!(f.buf, "\"{}\"", s),
			TSemicolon => f.buf.write_str(";"),
			TColon => f.buf.write_str(":"),
			TDot => f.buf.write_str("."),
			TEqual => f.buf.write_str("="),
			TComma => f.buf.write_str(","),
			TIdent(ref ident) => f.buf.write_str(*ident),
			TOpenParen => f.buf.write_str("("),
			TCloseParen => f.buf.write_str(")"),
			TOpenBlock => f.buf.write_str("{"),
			TCloseBlock => f.buf.write_str("}"),
			TOpenArray => f.buf.write_str("["),
			TCloseArray => f.buf.write_str("]"),
			TNumber(num) => write!(f.buf, "{}", num),
			TQuestion => f.buf.write_str("?"),
			TNumOp(op) => write!(f.buf, "{}", op)
		}
	}
}<|endoftext|>


<commit_before>use std::slice::from_raw_parts;
use std::ffi::CStr;
use std::mem::copy_lifetime;

use htslib;

#[derive(Debug)]
pub enum Aux<'a> {
    Integer(i32),
    String(&'a [u8]),
    Float(f64),
    Char(u8),
}

impl<'a> Aux<'a> {
    pub fn string(&self) -> &'a [u8] {
        match *self {
            Aux::String(x) => x,
            _ => panic!("not a string"),
        }
    }

    pub fn float(&self) -> f64 {
        match *self {
            Aux::Float(x) => x,
            _ => panic!("not a float"),
        }
    }

    pub fn integer(&self) -> i32 {
        match *self {
            Aux::Integer(x) => x,
            _ => panic!("not an integer"),
        }
    }

    pub fn char(&self) -> u8 {
        match *self {
            Aux::Char(x) => x,
            _ => panic!("not a character"),
        }
    }
}

pub struct Record {
    b: htslib::bam1_t,
}

impl Record {
    pub fn new() -> Self {
        let b = unsafe { *htslib::bam_init1() };
        Record { b: b }
    }
    // TODO ensure that owning b really destroys b.data when object goes out of scope

    fn data(&self) -> &[u8] {
        unsafe { from_raw_parts(self.b.data, self.b.l_data as usize) }
    }

    pub fn tid(&self) -> i32 {
        self.b.core.tid
    }

    pub fn pos(&self) -> i32 {
        self.b.core.pos
    }

    pub fn bin(&self) -> u16 {
        self.b.core.bin
    }

    pub fn map_qual(&self) -> u8 {
        self.b.core.qual
    }

    pub fn flag(&self) -> u16 {
        self.b.core.flag
    }

    pub fn mtid(&self) -> i32 {
        self.b.core.mtid
    }

    pub fn mpos(&self) -> i32 {
        self.b.core.mpos
    }

    pub fn isize(&self) -> i32 {
        self.b.core.isize
    }

    fn qname_len(&self) -> usize {
        self.b.core.l_qname as usize
    }

    pub fn qname(&self) -> &[u8] {
        self.data()[..self.qname_len()-1].as_slice() // -1 ignores the termination symbol

    }

    fn cigar_len(&self) -> usize {
        self.b.core.n_cigar as usize
    }

    pub fn bam_get_cigar(&self) -> &[u32] {
        unsafe { from_raw_parts(self.data()[self.qname_len()..].as_ptr() as *const u32, self.cigar_len()) }
    }

    fn seq_len(&self) -> usize {
        self.b.core.l_qseq as usize
    }

    pub fn seq(&self) -> Seq {
        Seq {
            encoded: self.data()
                        [self.qname_len() + self.cigar_len()*4..]
                        [..(self.seq_len() + 1) / 2].as_slice()
        }
    }

    pub fn qual(&self) -> &[u8] {
        self.data()[self.qname_len() + self.cigar_len()*4 + (self.seq_len()+1)/2..][..self.seq_len()].as_slice()
    }

    pub fn aux(&self, name: &[u8]) -> Option<Aux> {
        let aux = unsafe { htslib::bam_aux_get(&self.b, name.as_ptr() as *mut i8 ) };
        unsafe { println!("{}", *aux); }

        unsafe {
            match *aux {
                b'c'|b'C'|b's'|b'S'|b'i'|b'I' => Some(Aux::Integer(htslib::bam_aux2i(aux))),
                b'f'|b'd' => Some(Aux::Float(htslib::bam_aux2f(aux))),
                b'A' => Some(Aux::Char(htslib::bam_aux2A(aux) as u8)),
                b'Z'|b'H' => {
                    let f = aux.offset(1) as *const i8;
                    let x = CStr::from_ptr(f).to_bytes();
                    Some(Aux::String(copy_lifetime(self, x)))
                },
                _ => None,
            }
        }
    }

    pub fn is_paired(&self) -> bool{
        (self.flag() & 1u16) > 0
    }

    pub fn is_proper_pair(&self) -> bool{
        (self.flag() & 2u16) > 0
    }

    pub fn is_unmapped(&self) -> bool{
        (self.flag() & 4u16) > 0
    }

    pub fn mate_is_unmapped(&self) -> bool{
        (self.flag() & 8u16) > 0
    }

    pub fn is_reverse(&self) -> bool{
        (self.flag() & 16u16) > 0
    }

    pub fn mate_is_reverse(&self) -> bool{
        (self.flag() & 32u16) > 0
    }

    pub fn is_first_in_pair(&self) -> bool{
        (self.flag() & 64u16) > 0
    }

    pub fn is_second_in_pair(&self) -> bool{
        (self.flag() & 128u16) > 0
    }

    pub fn is_secondary(&self) -> bool{
        (self.flag() & 256u16) > 0
    }

    pub fn is_quality_check_failed(&self) -> bool{
        (self.flag() & 512u16) > 0
    }

    pub fn is_duplicate(&self) -> bool{
        (self.flag() & 1024u16) > 0
    }

    pub fn is_supplementary(&self) -> bool{
        (self.flag() & 2048u16) > 0
    }
}

pub struct Bamfile {
    f: *mut htslib::Struct_BGZF,
    header: htslib::bam_hdr_t,
}

impl Bamfile{
     pub fn new(filename: &[u8]) -> Self {
        let f = unsafe { htslib::bgzf_open(filename.as_ptr() as *const i8, b"r\0".as_ptr() as *const i8) };
        let header = unsafe { *htslib::bam_hdr_read(f) };
        Bamfile { f : f, header : header }
    }

    pub fn read(&self, record: &mut Record) -> Result<(), Error> {
        match unsafe { htslib::bam_read1(self.f, &mut record.b as *mut htslib::bam1_t) } {
            -1 => Err(Error::EOF),
            -2 => Err(Error::Truncated),
            -4 => Err(Error::Invalid),
            _  => Ok(())
        }
    }

    pub fn records(self) -> Records {
        Records { bam: self }
    }
}

pub struct Records {
    bam: Bamfile
}

impl Iterator for Records {
    type Item = Result<Record, Error>;

    fn next(&mut self) -> Option<Result<Record, Error>> {
        let mut record = Record::new();
        match self.bam.read(&mut record) {
            Err(Error::EOF) => None,
            Ok(())   => Some(Ok(record)),
            Err(err) => Some(Err(err))
        }
    }
}

static TRANSLATE_BASE: &'static [u8] = b"=ACMGRSVTWYHKDBN";

pub struct Seq<'a> {
    pub encoded: &'a [u8]
}

impl<'a> Seq<'a> {

    #[inline]
    pub fn encoded_base(&self, i: usize) -> u8 {
        (self.encoded[i / 2] >> ((! i & 1) << 2)) & 0b1111
    }

    #[inline]
    pub fn base(&self, i: usize) -> u8 {
        TRANSLATE_BASE[self.encoded_base(i) as usize]
    }

    pub fn as_bytes(&self) -> Vec<u8> {
        (0..self.len()).map(|i| self.base(i)).collect()
    }

    pub fn len(&self) -> usize {
        self.encoded.len() * 2
    }
}

pub enum Error {
    Truncated,
    Invalid,
    EOF,
}

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

    #[test]
    fn test_record() {
        let names = [b"I", b"II.14978392", b"III", b"IV", b"V", b"VI"];
        let flags = [16u16, 16u16, 16u16, 16u16, 16u16, 2048u16];
        let seqs = [
            b"CCTAGCCCTAACCCTAACCCTAACCCTAGCCTAAGCCTAAGCCTAAGCCTAAGCCTAAGCCTAAGCCTAAGCCTAAGCCTAAGCCTAAGCCTAAGCCTAA",
            b"CCTAGCCCTAACCCTAACCCTAACCCTAGCCTAAGCCTAAGCCTAAGCCTAAGCCTAAGCCTAAGCCTAAGCCTAAGCCTAAGCCTAAGCCTAAGCCTAA",
            b"CCTAGCCCTAACCCTAACCCTAACCCTAGCCTAAGCCTAAGCCTAAGCCTAAGCCTAAGCCTAAGCCTAAGCCTAAGCCTAAGCCTAAGCCTAAGCCTAA",
            b"CCTAGCCCTAACCCTAACCCTAACCCTAGCCTAAGCCTAAGCCTAAGCCTAAGCCTAAGCCTAAGCCTAAGCCTAAGCCTAAGCCTAAGCCTAAGCCTAA",
            b"CCTAGCCCTAACCCTAACCCTAACCCTAGCCTAAGCCTAAGCCTAAGCCTAAGCCTAAGCCTAAGCCTAAGCCTAAGCCTAAGCCTAAGCCTAAGCCTAA",
            b"ACTAAGCCTAAGCCTAAGCCTAAGCCAATTATCGATTTCTGAAAAAATTATCGAATTTTCTAGAAATTTTGCAAATTTTTTCATAAAATTATCGATTTTA",
        ];

        let bam = Bamfile::new(b"test.bam");

        for (i, record) in bam.records().enumerate() {
            let rec = record.ok().expect("Expected valid record");
            println!("{}", str::from_utf8(rec.qname()).ok().unwrap());
            assert_eq!(rec.qname(), names[i]);
            assert_eq!(rec.flag(), flags[i]);
            assert_eq!(rec.seq().as_bytes(), seqs[i]);
        }

    }
}
<commit_msg>Added cigar enum.<commit_after>use std::slice::from_raw_parts;
use std::ffi::CStr;
use std::mem::copy_lifetime;

use htslib;

#[derive(Debug)]
pub enum Aux<'a> {
    Integer(i32),
    String(&'a [u8]),
    Float(f64),
    Char(u8),
}

impl<'a> Aux<'a> {
    pub fn string(&self) -> &'a [u8] {
        match *self {
            Aux::String(x) => x,
            _ => panic!("not a string"),
        }
    }

    pub fn float(&self) -> f64 {
        match *self {
            Aux::Float(x) => x,
            _ => panic!("not a float"),
        }
    }

    pub fn integer(&self) -> i32 {
        match *self {
            Aux::Integer(x) => x,
            _ => panic!("not an integer"),
        }
    }

    pub fn char(&self) -> u8 {
        match *self {
            Aux::Char(x) => x,
            _ => panic!("not a character"),
        }
    }
}

pub struct Record {
    b: htslib::bam1_t,
}

impl Record {
    pub fn new() -> Self {
        let b = unsafe { *htslib::bam_init1() };
        Record { b: b }
    }
    // TODO ensure that owning b really destroys b.data when object goes out of scope

    fn data(&self) -> &[u8] {
        unsafe { from_raw_parts(self.b.data, self.b.l_data as usize) }
    }

    pub fn tid(&self) -> i32 {
        self.b.core.tid
    }

    pub fn pos(&self) -> i32 {
        self.b.core.pos
    }

    pub fn bin(&self) -> u16 {
        self.b.core.bin
    }

    pub fn map_qual(&self) -> u8 {
        self.b.core.qual
    }

    pub fn flag(&self) -> u16 {
        self.b.core.flag
    }

    pub fn mtid(&self) -> i32 {
        self.b.core.mtid
    }

    pub fn mpos(&self) -> i32 {
        self.b.core.mpos
    }

    pub fn isize(&self) -> i32 {
        self.b.core.isize
    }

    fn qname_len(&self) -> usize {
        self.b.core.l_qname as usize
    }

    pub fn qname(&self) -> &[u8] {
        self.data()[..self.qname_len()-1].as_slice() // -1 ignores the termination symbol

    }

    fn cigar_len(&self) -> usize {
        self.b.core.n_cigar as usize
    }

    pub fn bam_get_cigar(&self) -> &[u32] {
        unsafe { from_raw_parts(self.data()[self.qname_len()..].as_ptr() as *const u32, self.cigar_len()) }
    }

    fn seq_len(&self) -> usize {
        self.b.core.l_qseq as usize
    }

    pub fn seq(&self) -> Seq {
        Seq {
            encoded: self.data()
                        [self.qname_len() + self.cigar_len()*4..]
                        [..(self.seq_len() + 1) / 2].as_slice()
        }
    }

    pub fn qual(&self) -> &[u8] {
        self.data()[self.qname_len() + self.cigar_len()*4 + (self.seq_len()+1)/2..][..self.seq_len()].as_slice()
    }

    pub fn aux(&self, name: &[u8]) -> Option<Aux> {
        let aux = unsafe { htslib::bam_aux_get(&self.b, name.as_ptr() as *mut i8 ) };
        unsafe { println!("{}", *aux); }

        unsafe {
            match *aux {
                b'c'|b'C'|b's'|b'S'|b'i'|b'I' => Some(Aux::Integer(htslib::bam_aux2i(aux))),
                b'f'|b'd' => Some(Aux::Float(htslib::bam_aux2f(aux))),
                b'A' => Some(Aux::Char(htslib::bam_aux2A(aux) as u8)),
                b'Z'|b'H' => {
                    let f = aux.offset(1) as *const i8;
                    let x = CStr::from_ptr(f).to_bytes();
                    Some(Aux::String(copy_lifetime(self, x)))
                },
                _ => None,
            }
        }
    }

    pub fn is_paired(&self) -> bool{
        (self.flag() & 1u16) > 0
    }

    pub fn is_proper_pair(&self) -> bool{
        (self.flag() & 2u16) > 0
    }

    pub fn is_unmapped(&self) -> bool{
        (self.flag() & 4u16) > 0
    }

    pub fn mate_is_unmapped(&self) -> bool{
        (self.flag() & 8u16) > 0
    }

    pub fn is_reverse(&self) -> bool{
        (self.flag() & 16u16) > 0
    }

    pub fn mate_is_reverse(&self) -> bool{
        (self.flag() & 32u16) > 0
    }

    pub fn is_first_in_pair(&self) -> bool{
        (self.flag() & 64u16) > 0
    }

    pub fn is_second_in_pair(&self) -> bool{
        (self.flag() & 128u16) > 0
    }

    pub fn is_secondary(&self) -> bool{
        (self.flag() & 256u16) > 0
    }

    pub fn is_quality_check_failed(&self) -> bool{
        (self.flag() & 512u16) > 0
    }

    pub fn is_duplicate(&self) -> bool{
        (self.flag() & 1024u16) > 0
    }

    pub fn is_supplementary(&self) -> bool{
        (self.flag() & 2048u16) > 0
    }
}

pub struct Bamfile {
    f: *mut htslib::Struct_BGZF,
    header: htslib::bam_hdr_t,
}

impl Bamfile{
     pub fn new(filename: &[u8]) -> Self {
        let f = unsafe { htslib::bgzf_open(filename.as_ptr() as *const i8, b"r\0".as_ptr() as *const i8) };
        let header = unsafe { *htslib::bam_hdr_read(f) };
        Bamfile { f : f, header : header }
    }

    pub fn read(&self, record: &mut Record) -> Result<(), Error> {
        match unsafe { htslib::bam_read1(self.f, &mut record.b as *mut htslib::bam1_t) } {
            -1 => Err(Error::EOF),
            -2 => Err(Error::Truncated),
            -4 => Err(Error::Invalid),
            _  => Ok(())
        }
    }

    pub fn records(self) -> Records {
        Records { bam: self }
    }
}

pub struct Records {
    bam: Bamfile
}

impl Iterator for Records {
    type Item = Result<Record, Error>;

    fn next(&mut self) -> Option<Result<Record, Error>> {
        let mut record = Record::new();
        match self.bam.read(&mut record) {
            Err(Error::EOF) => None,
            Ok(())   => Some(Ok(record)),
            Err(err) => Some(Err(err))
        }
    }
}

static TRANSLATE_BASE: &'static [u8] = b"=ACMGRSVTWYHKDBN";

pub struct Seq<'a> {
    pub encoded: &'a [u8]
}

impl<'a> Seq<'a> {

    #[inline]
    pub fn encoded_base(&self, i: usize) -> u8 {
        (self.encoded[i / 2] >> ((! i & 1) << 2)) & 0b1111
    }

    #[inline]
    pub fn base(&self, i: usize) -> u8 {
        TRANSLATE_BASE[self.encoded_base(i) as usize]
    }

    pub fn as_bytes(&self) -> Vec<u8> {
        (0..self.len()).map(|i| self.base(i)).collect()
    }

    pub fn len(&self) -> usize {
        self.encoded.len() * 2
    }
}

pub enum Cigar {
    Match(u32),  // M
    Ins(u32),  // I
    Del(u32),  // D
    RefSkip(u32),  // N
    SoftClip(u32),  // S
    HardClip(u32),  // H
    Pad(u32),  // P
    Equal(u32),  // =
    Diff(u32),  // X
    Back(u32)  // B
}

pub enum Error {
    Truncated,
    Invalid,
    EOF,
}

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

    #[test]
    fn test_record() {
        let names = [b"I", b"II.14978392", b"III", b"IV", b"V", b"VI"];
        let flags = [16u16, 16u16, 16u16, 16u16, 16u16, 2048u16];
        let seqs = [
            b"CCTAGCCCTAACCCTAACCCTAACCCTAGCCTAAGCCTAAGCCTAAGCCTAAGCCTAAGCCTAAGCCTAAGCCTAAGCCTAAGCCTAAGCCTAAGCCTAA",
            b"CCTAGCCCTAACCCTAACCCTAACCCTAGCCTAAGCCTAAGCCTAAGCCTAAGCCTAAGCCTAAGCCTAAGCCTAAGCCTAAGCCTAAGCCTAAGCCTAA",
            b"CCTAGCCCTAACCCTAACCCTAACCCTAGCCTAAGCCTAAGCCTAAGCCTAAGCCTAAGCCTAAGCCTAAGCCTAAGCCTAAGCCTAAGCCTAAGCCTAA",
            b"CCTAGCCCTAACCCTAACCCTAACCCTAGCCTAAGCCTAAGCCTAAGCCTAAGCCTAAGCCTAAGCCTAAGCCTAAGCCTAAGCCTAAGCCTAAGCCTAA",
            b"CCTAGCCCTAACCCTAACCCTAACCCTAGCCTAAGCCTAAGCCTAAGCCTAAGCCTAAGCCTAAGCCTAAGCCTAAGCCTAAGCCTAAGCCTAAGCCTAA",
            b"ACTAAGCCTAAGCCTAAGCCTAAGCCAATTATCGATTTCTGAAAAAATTATCGAATTTTCTAGAAATTTTGCAAATTTTTTCATAAAATTATCGATTTTA",
        ];

        let bam = Bamfile::new(b"test.bam");

        for (i, record) in bam.records().enumerate() {
            let rec = record.ok().expect("Expected valid record");
            println!("{}", str::from_utf8(rec.qname()).ok().unwrap());
            assert_eq!(rec.qname(), names[i]);
            assert_eq!(rec.flag(), flags[i]);
            assert_eq!(rec.seq().as_bytes(), seqs[i]);
        }

    }
}
<|endoftext|>


<commit_before>extern crate clap;
extern crate dent;

use clap::{App, Arg};
use dent::plot;
use dent::summary::Summary;
use dent::t_test::{SigLevel, TTest, welch_t_test};

use std::fs::File;
use std::path::Path;
use std::io::{self, BufRead, BufReader};

fn print_summary(s: &Summary) {
    println!("N\tMin\tMax\tMedian\tMean\tStdDev\tStdErr");
    println!(
        "{}\t{:0.2}\t{:0.2}\t{:0.2}\t{:0.2}\t{:0.2}\t{:0.2}",
        s.size(),
        s.min(),
        s.max(),
        s.median(),
        s.mean(),
        s.standard_deviation(),
        s.standard_error(),
    );
}

fn print_t_test(t_test: &TTest) {
    println!("T\tDF\tAlpha\tCrit\tRejectNull");
    println!(
        "{:0.3}\t{}\t{:0.3}\t{:0.3}\t{}",
        t_test.t,
        t_test.df,
        t_test.alpha,
        t_test.crit,
        t_test.reject,
    );
}

fn read_file(path: &str) -> Summary {
    let p = Path::new(path);
    let f = File::open(p).unwrap();
    let r = BufReader::new(f);

    let data: Vec<f64> = r
        .lines()
        .map(|l| l.unwrap().parse().unwrap())
        .collect();

    Summary::new(&data).unwrap()
}

fn parse_alpha(arg: &str) -> SigLevel {
    match arg {
        ".001" => SigLevel::Alpha001,
        ".005" => SigLevel::Alpha005,
        ".01"  => SigLevel::Alpha010,
        ".025" => SigLevel::Alpha025,
        ".05"  => SigLevel::Alpha050,
        ".1"   => SigLevel::Alpha100,
        _ => panic!(),
    }
}

fn summarize_stdin(draw_plot: bool, ascii: bool) {
    let stdin = io::stdin();

    let data: Vec<f64> = stdin
        .lock()
        .lines()
        .map(|l| l.unwrap().parse().unwrap())
        .collect();

    let s = Summary::new(&data).unwrap();

    if draw_plot {
        println!("{}\n", plot::summary_plot(&s, 80, ascii));
    }

    print_summary(&s);
}

fn t_test_files(
    file1: &str,
    file2: &str,
    alpha: SigLevel,
    draw_plot: bool,
    ascii: bool,
) {
    let s1 = read_file(file1);
    let s2 = read_file(file2);

    let t_test = welch_t_test(&s1, &s2, alpha);

    if draw_plot {
        println!("{}\n", plot::comparison_plot(&s1, &s2, 84, ascii, true));
    }

    print_summary(&s1);
    println!();
    print_summary(&s2);
    println!();
    print_t_test(&t_test);
}

fn main() {
    let matches = App::new("dent")
        .version("0.1.0")
        .author("Joe Ranweiler <joe@lemma.co>")
        .about("A tiny tool for t-tests &c.")
        .arg(Arg::with_name("stdin")
             .short("s")
             .long("stdin")
             .help("Read and summarize data from stdin."))
        .arg(Arg::with_name("file1")
             .index(1)
             .value_name("FILE1")
             .takes_value(true)
             .required_unless("stdin")
             .help("1st file of sample data."))
        .arg(Arg::with_name("file2")
             .index(2)
             .value_name("FILE2")
             .takes_value(true)
             .required_unless("stdin")
             .help("2nd file of sample data."))
        .arg(Arg::with_name("alpha")
             .short("a")
             .long("alpha")
             .value_name("ALPHA")
             .help("Significance level α")
             .takes_value(true)
             .default_value(".05"))
        .arg(Arg::with_name("plot")
             .short("p")
             .long("plot")
             .help("Draw a box-and-whisker plot."))
        .arg(Arg::with_name("ascii")
             .long("ascii")
             .help("Use only ASCII characters in plots."))
        .get_matches();

    let ascii = matches.is_present("ascii");
    let draw_plot = matches.is_present("plot");
    let use_stdin = matches.is_present("stdin");

    if use_stdin {
        summarize_stdin(draw_plot, ascii);
    } else {
        let alpha = parse_alpha(matches.value_of("alpha").unwrap());
        let file1 = matches.value_of("file1").unwrap();
        let file2 = matches.value_of("file2").unwrap();

        t_test_files(file1, file2, alpha, draw_plot, ascii);
    }
}
<commit_msg>Add command-line arg for plot width<commit_after>extern crate clap;
extern crate dent;

use clap::{App, Arg};
use dent::plot;
use dent::summary::Summary;
use dent::t_test::{SigLevel, TTest, welch_t_test};

use std::fs::File;
use std::path::Path;
use std::io::{self, BufRead, BufReader};

fn print_summary(s: &Summary) {
    println!("N\tMin\tMax\tMedian\tMean\tStdDev\tStdErr");
    println!(
        "{}\t{:0.2}\t{:0.2}\t{:0.2}\t{:0.2}\t{:0.2}\t{:0.2}",
        s.size(),
        s.min(),
        s.max(),
        s.median(),
        s.mean(),
        s.standard_deviation(),
        s.standard_error(),
    );
}

fn print_t_test(t_test: &TTest) {
    println!("T\tDF\tAlpha\tCrit\tRejectNull");
    println!(
        "{:0.3}\t{}\t{:0.3}\t{:0.3}\t{}",
        t_test.t,
        t_test.df,
        t_test.alpha,
        t_test.crit,
        t_test.reject,
    );
}

fn read_file(path: &str) -> Summary {
    let p = Path::new(path);
    let f = File::open(p).unwrap();
    let r = BufReader::new(f);

    let data: Vec<f64> = r
        .lines()
        .map(|l| l.unwrap().parse().unwrap())
        .collect();

    Summary::new(&data).unwrap()
}

fn parse_alpha(arg: &str) -> SigLevel {
    match arg {
        ".001" => SigLevel::Alpha001,
        ".005" => SigLevel::Alpha005,
        ".01"  => SigLevel::Alpha010,
        ".025" => SigLevel::Alpha025,
        ".05"  => SigLevel::Alpha050,
        ".1"   => SigLevel::Alpha100,
        _ => panic!(),
    }
}

fn summarize_stdin(draw_plot: bool, width: usize, ascii: bool) {
    let stdin = io::stdin();

    let data: Vec<f64> = stdin
        .lock()
        .lines()
        .map(|l| l.unwrap().parse().unwrap())
        .collect();

    let s = Summary::new(&data).unwrap();

    if draw_plot {
        println!("{}\n", plot::summary_plot(&s, width, ascii));
    }

    print_summary(&s);
}

fn t_test_files(
    file1: &str,
    file2: &str,
    alpha: SigLevel,
    draw_plot: bool,
    width: usize,
    ascii: bool,
) {
    let s1 = read_file(file1);
    let s2 = read_file(file2);

    let t_test = welch_t_test(&s1, &s2, alpha);

    if draw_plot {
        println!("{}\n", plot::comparison_plot(&s1, &s2, width, ascii, true));
    }

    print_summary(&s1);
    println!();
    print_summary(&s2);
    println!();
    print_t_test(&t_test);
}

fn main() {
    let matches = App::new("dent")
        .version("0.1.0")
        .author("Joe Ranweiler <joe@lemma.co>")
        .about("A tiny tool for t-tests &c.")
        .arg(Arg::with_name("stdin")
             .short("s")
             .long("stdin")
             .help("Read and summarize data from stdin."))
        .arg(Arg::with_name("file1")
             .index(1)
             .value_name("FILE1")
             .takes_value(true)
             .required_unless("stdin")
             .help("1st file of sample data."))
        .arg(Arg::with_name("file2")
             .index(2)
             .value_name("FILE2")
             .takes_value(true)
             .required_unless("stdin")
             .help("2nd file of sample data."))
        .arg(Arg::with_name("alpha")
             .short("a")
             .long("alpha")
             .value_name("ALPHA")
             .help("Significance level α")
             .takes_value(true)
             .default_value(".05"))
        .arg(Arg::with_name("plot")
             .short("p")
             .long("plot")
             .help("Draw a box-and-whisker plot."))
        .arg(Arg::with_name("ascii")
             .long("ascii")
             .help("Use only ASCII characters in plots."))
        .arg(Arg::with_name("width")
             .short("w")
             .long("width")
             .value_name("WIDTH")
             .takes_value(true)
             .help("Width of boxplot"))
        .get_matches();

    let ascii = matches.is_present("ascii");
    let draw_plot = matches.is_present("plot");
    let use_stdin = matches.is_present("stdin");

    let width = matches
        .value_of("width")
        .and_then(|w| w.parse::<usize>().ok())
        .unwrap_or(80);

    if use_stdin {
        summarize_stdin(draw_plot, width, ascii);
    } else {
        let alpha = parse_alpha(matches.value_of("alpha").unwrap());
        let file1 = matches.value_of("file1").unwrap();
        let file2 = matches.value_of("file2").unwrap();

        t_test_files(file1, file2, alpha, draw_plot, width, ascii);
    }
}
<|endoftext|>


<commit_before>extern crate byteorder;
pub mod rom_loader;
pub mod memory;
pub mod cpu;
pub mod logger;

use cpu::CpuState;
use memory::Memory;

fn main() {
    let rom = rom_loader::load_ines("roms/nestest.nes").unwrap();
    let mut cpu: CpuState = Default::default();
    let mut mem:Memory = Memory::new();

    // TODO: handle this properly instead of just unwrapping
    let opcode_info = cpu::opcode::load_from_file("resources/opcodes.csv").unwrap();
    let executor = cpu::CpuExecutor::new(opcode_info.0);
    let mut logger = logger::NesTest::new("resources/nestest.out",opcode_info.1);

    executor.power_on(&mut cpu, &mut mem);
    cpu.pc = 0xC000;
    mem.write(0,&rom);

    for i in 0..10 {
        executor.fetch_and_decode(&mut cpu,&mut mem);
        logger.log_after_fetch(&cpu,&mem);
        executor.execute(&mut cpu,&mut mem);
    }
}

<commit_msg>added unwrap statements to force panic on error<commit_after>extern crate byteorder;
pub mod rom_loader;
pub mod memory;
pub mod cpu;
pub mod logger;

use cpu::CpuState;
use memory::Memory;

fn main() {
    let rom = rom_loader::load_ines("roms/nestest.nes").unwrap();
    let mut cpu: CpuState = Default::default();
    let mut mem:Memory = Memory::new();

    // TODO: handle this properly instead of just unwrapping
    let opcode_info = cpu::opcode::load_from_file("resources/opcodes.csv").unwrap();
    let executor = cpu::CpuExecutor::new(opcode_info.0);
    let mut logger = logger::NesTest::new("resources/nestest.out",opcode_info.1);

    executor.power_on(&mut cpu, &mut mem);
    cpu.pc = 0xC000;
    mem.write(0,&rom);

    for i in 0..10 {
        executor.fetch_and_decode(&mut cpu,&mut mem).unwrap();
        logger.log_after_fetch(&cpu,&mem);
        executor.execute(&mut cpu,&mut mem).unwrap();
    }
}

<|endoftext|>


<commit_before>use std::path::MAIN_SEPARATOR;
use std::process::Command;

use clap::{App, Arg, Error};

#[derive(Debug)]
pub struct Args {
    pub cmd: String,
    pub paths: Vec<String>,
    pub filters: Vec<String>,
    pub ignores: Vec<String>,
    pub clear_screen: bool,
    pub signal: Option<String>,
    pub restart: bool,
    pub debug: bool,
    pub run_initially: bool,
    pub no_shell: bool,
    pub no_vcs_ignore: bool,
    pub once: bool,
    pub poll: bool,
    pub poll_interval: u32,
}

#[cfg(target_family = "windows")]
pub fn clear_screen() {
    let _ = Command::new("cls").status();
}

#[cfg(target_family = "unix")]
pub fn clear_screen() {
    let _ = Command::new("clear").status();
}

#[allow(unknown_lints)]
#[allow(or_fun_call)]
pub fn get_args() -> Args {
    let args = App::new("watchexec")
        .version(crate_version!())
        .about("Execute commands when watched files change")
        .arg(Arg::with_name("command")
                 .help("Command to execute")
                 .multiple(true)
                 .required(true))
        .arg(Arg::with_name("extensions")
                 .help("Comma-separated list of file extensions to watch (js,css,html)")
                 .short("e")
                 .long("exts")
                 .takes_value(true))
        .arg(Arg::with_name("path")
                 .help("Watch a specific directory")
                 .short("w")
                 .long("watch")
                 .number_of_values(1)
                 .multiple(true)
                 .takes_value(true))
        .arg(Arg::with_name("clear")
                 .help("Clear screen before executing command")
                 .short("c")
                 .long("clear"))
        .arg(Arg::with_name("restart")
                 .help("Restart the process if it's still running")
                 .short("r")
                 .long("restart"))
        .arg(Arg::with_name("signal")
                 .help("Send signal to process upon changes, e.g. SIGHUP")
                 .short("s")
                 .long("signal")
                 .takes_value(true)
                 .number_of_values(1)
                 .value_name("signal"))
        .arg(Arg::with_name("kill")
                 .help("Send SIGKILL to child processes (deprecated, use -s SIGKILL instead)")
                 .short("k")
                 .long("kill"))
        .arg(Arg::with_name("debug")
                 .help("Print debugging messages to stderr")
                 .short("d")
                 .long("debug"))
        .arg(Arg::with_name("filter")
                 .help("Ignore all modifications except those matching the pattern")
                 .short("f")
                 .long("filter")
                 .number_of_values(1)
                 .multiple(true)
                 .takes_value(true)
                 .value_name("pattern"))
        .arg(Arg::with_name("ignore")
                 .help("Ignore modifications to paths matching the pattern")
                 .short("i")
                 .long("ignore")
                 .number_of_values(1)
                 .multiple(true)
                 .takes_value(true)
                 .value_name("pattern"))
        .arg(Arg::with_name("no-vcs-ignore")
                 .help("Skip auto-loading of .gitignore files for filtering")
                 .long("no-vcs-ignore"))
        .arg(Arg::with_name("postpone")
                 .help("Wait until first change to execute command")
                 .short("p")
                 .long("postpone"))
        .arg(Arg::with_name("poll")
                 .help("Forces polling mode")
                 .long("force-poll")
                 .value_name("interval"))
        .arg(Arg::with_name("no-shell")
                 .help("Do not wrap command in 'sh -c' resp. 'cmd.exe /C'")
                 .short("n")
                 .long("no-shell"))
        .arg(Arg::with_name("once").short("1").hidden(true))
        .get_matches();

    let cmd = values_t!(args.values_of("command"), String)
        .unwrap()
        .join(" ");
    let paths = values_t!(args.values_of("path"), String).unwrap_or(vec![String::from(".")]);

    // Treat --kill as --signal SIGKILL (for compatibility with older syntax)
    let signal = if args.is_present("kill") {
        Some("SIGKILL".to_string())
    } else {
        // Convert Option<&str> to Option<String>
        args.value_of("signal").map(str::to_string)
    };

    let mut filters = values_t!(args.values_of("filter"), String).unwrap_or(vec![]);

    if let Some(extensions) = args.values_of("extensions") {
        for exts in extensions {
            filters.extend(exts.split(',')
                               .filter(|ext| !ext.is_empty())
                               .map(|ext| format!("*.{}", ext.replace(".", ""))));

        }
    }

    let mut ignores = vec![];
    let default_ignores = vec![format!("*{}.*{}*", MAIN_SEPARATOR, MAIN_SEPARATOR),
                               format!("*{}.DS_Store", MAIN_SEPARATOR),
                               String::from("*.pyc"),
                               String::from("*.swp")];

    ignores.extend(default_ignores);
    ignores.extend(values_t!(args.values_of("ignore"), String).unwrap_or(vec![]));

    let poll_interval = if args.occurrences_of("poll") > 0 {
        value_t!(args.value_of("poll"), u32).unwrap_or_else(|e| e.exit())
    } else {
        1000
    };

    if signal.is_some() && args.is_present("postpone") {
        // TODO: Error::argument_conflict() might be the better fit, usage was unclear, though
        Error::value_validation_auto("--postpone and --signal are mutually exclusive".to_string())
            .exit();
    }

    if signal.is_some() && args.is_present("kill") {
        // TODO: Error::argument_conflict() might be the better fit, usage was unclear, though
        Error::value_validation_auto("--kill and --signal is ambiguous.\n       Hint: Use only '--signal SIGKILL' without --kill".to_string())
            .exit();
    }

    Args {
        cmd: cmd,
        paths: paths,
        filters: filters,
        ignores: ignores,
        signal: signal,
        clear_screen: args.is_present("clear"),
        restart: args.is_present("restart"),
        debug: args.is_present("debug"),
        run_initially: !args.is_present("postpone"),
        no_shell: args.is_present("no-shell"),
        no_vcs_ignore: args.is_present("no-vcs-ignore"),
        once: args.is_present("once"),
        poll: args.occurrences_of("poll") > 0,
        poll_interval: poll_interval,
    }
}
<commit_msg>Remove /.* ignore pattern (see #45)<commit_after>use std::path::MAIN_SEPARATOR;
use std::process::Command;

use clap::{App, Arg, Error};

#[derive(Debug)]
pub struct Args {
    pub cmd: String,
    pub paths: Vec<String>,
    pub filters: Vec<String>,
    pub ignores: Vec<String>,
    pub clear_screen: bool,
    pub signal: Option<String>,
    pub restart: bool,
    pub debug: bool,
    pub run_initially: bool,
    pub no_shell: bool,
    pub no_vcs_ignore: bool,
    pub once: bool,
    pub poll: bool,
    pub poll_interval: u32,
}

#[cfg(target_family = "windows")]
pub fn clear_screen() {
    let _ = Command::new("cls").status();
}

#[cfg(target_family = "unix")]
pub fn clear_screen() {
    let _ = Command::new("clear").status();
}

#[allow(unknown_lints)]
#[allow(or_fun_call)]
pub fn get_args() -> Args {
    let args = App::new("watchexec")
        .version(crate_version!())
        .about("Execute commands when watched files change")
        .arg(Arg::with_name("command")
                 .help("Command to execute")
                 .multiple(true)
                 .required(true))
        .arg(Arg::with_name("extensions")
                 .help("Comma-separated list of file extensions to watch (js,css,html)")
                 .short("e")
                 .long("exts")
                 .takes_value(true))
        .arg(Arg::with_name("path")
                 .help("Watch a specific directory")
                 .short("w")
                 .long("watch")
                 .number_of_values(1)
                 .multiple(true)
                 .takes_value(true))
        .arg(Arg::with_name("clear")
                 .help("Clear screen before executing command")
                 .short("c")
                 .long("clear"))
        .arg(Arg::with_name("restart")
                 .help("Restart the process if it's still running")
                 .short("r")
                 .long("restart"))
        .arg(Arg::with_name("signal")
                 .help("Send signal to process upon changes, e.g. SIGHUP")
                 .short("s")
                 .long("signal")
                 .takes_value(true)
                 .number_of_values(1)
                 .value_name("signal"))
        .arg(Arg::with_name("kill")
                 .help("Send SIGKILL to child processes (deprecated, use -s SIGKILL instead)")
                 .short("k")
                 .long("kill"))
        .arg(Arg::with_name("debug")
                 .help("Print debugging messages to stderr")
                 .short("d")
                 .long("debug"))
        .arg(Arg::with_name("filter")
                 .help("Ignore all modifications except those matching the pattern")
                 .short("f")
                 .long("filter")
                 .number_of_values(1)
                 .multiple(true)
                 .takes_value(true)
                 .value_name("pattern"))
        .arg(Arg::with_name("ignore")
                 .help("Ignore modifications to paths matching the pattern")
                 .short("i")
                 .long("ignore")
                 .number_of_values(1)
                 .multiple(true)
                 .takes_value(true)
                 .value_name("pattern"))
        .arg(Arg::with_name("no-vcs-ignore")
                 .help("Skip auto-loading of .gitignore files for filtering")
                 .long("no-vcs-ignore"))
        .arg(Arg::with_name("postpone")
                 .help("Wait until first change to execute command")
                 .short("p")
                 .long("postpone"))
        .arg(Arg::with_name("poll")
                 .help("Forces polling mode")
                 .long("force-poll")
                 .value_name("interval"))
        .arg(Arg::with_name("no-shell")
                 .help("Do not wrap command in 'sh -c' resp. 'cmd.exe /C'")
                 .short("n")
                 .long("no-shell"))
        .arg(Arg::with_name("once").short("1").hidden(true))
        .get_matches();

    let cmd = values_t!(args.values_of("command"), String)
        .unwrap()
        .join(" ");
    let paths = values_t!(args.values_of("path"), String).unwrap_or(vec![String::from(".")]);

    // Treat --kill as --signal SIGKILL (for compatibility with older syntax)
    let signal = if args.is_present("kill") {
        Some("SIGKILL".to_string())
    } else {
        // Convert Option<&str> to Option<String>
        args.value_of("signal").map(str::to_string)
    };

    let mut filters = values_t!(args.values_of("filter"), String).unwrap_or(vec![]);

    if let Some(extensions) = args.values_of("extensions") {
        for exts in extensions {
            filters.extend(exts.split(',')
                               .filter(|ext| !ext.is_empty())
                               .map(|ext| format!("*.{}", ext.replace(".", ""))));

        }
    }

    let mut ignores = vec![];
    let default_ignores = vec![format!("*{}.DS_Store", MAIN_SEPARATOR),
                               String::from("*.pyc"),
                               String::from("*.swp")];

    ignores.extend(default_ignores);
    ignores.extend(values_t!(args.values_of("ignore"), String).unwrap_or(vec![]));

    let poll_interval = if args.occurrences_of("poll") > 0 {
        value_t!(args.value_of("poll"), u32).unwrap_or_else(|e| e.exit())
    } else {
        1000
    };

    if signal.is_some() && args.is_present("postpone") {
        // TODO: Error::argument_conflict() might be the better fit, usage was unclear, though
        Error::value_validation_auto("--postpone and --signal are mutually exclusive".to_string())
            .exit();
    }

    if signal.is_some() && args.is_present("kill") {
        // TODO: Error::argument_conflict() might be the better fit, usage was unclear, though
        Error::value_validation_auto("--kill and --signal is ambiguous.\n       Hint: Use only '--signal SIGKILL' without --kill".to_string())
            .exit();
    }

    Args {
        cmd: cmd,
        paths: paths,
        filters: filters,
        ignores: ignores,
        signal: signal,
        clear_screen: args.is_present("clear"),
        restart: args.is_present("restart"),
        debug: args.is_present("debug"),
        run_initially: !args.is_present("postpone"),
        no_shell: args.is_present("no-shell"),
        no_vcs_ignore: args.is_present("no-vcs-ignore"),
        once: args.is_present("once"),
        poll: args.occurrences_of("poll") > 0,
        poll_interval: poll_interval,
    }
}
<|endoftext|>


<commit_before>#![allow(unused,
         unused_attributes,
         raw_pointer_derive,
         non_camel_case_types,
         non_snake_case)]

/// All of the extensions defined for OpenCL 1.1, from
/// [`cl_ext.h`](https://www.khronos.org/registry/cl/api/1.1/cl_ext.h).

// Macro to define a struct-style extension pointer loader.
// Defines a (`Copy`, `Sync`) `struct Functions` that has extension function pointers as members (and methods,
// for convenience).
// Call `$ext::load()` to get an Option<$ext::Functions, String>.  (It's safe to call extension function pointers in other threads, right?)
macro_rules! cl_extension_loader {
    (
        $ext_name:expr;
        $(extern fn $function:ident ($($arg:ident : $arg_type:ty),*) -> $ret:ty),*
    ) => (
        // Define struct Functions
        ext_struct_def!{ $($function, ($($arg, $arg_type),*) $ret)* }
        impl Functions {
            // Make function pointers available as methods so they don't have to be called as (struct.member)(arg)
            $( #[inline(always)] unsafe fn $function (&self, $($arg:$arg_type),*) -> $ret { (self.$function)($($arg),*) } )*
        }

        pub fn load(platform: cl_platform_id) -> Result<Functions, String> {
            use hl;
            use std::mem;
            use std::ptr;
            use std::ffi::CString;
            use cl::ll::clGetExtensionFunctionAddress;

            // Read in the available extensions
            // We have to do this, since loading function pointers for an
            // unavailable extension can return non-NULL.
            // TODO read in extensions lazily and store them in a global HashSet?
            let available = unsafe {
                let hl_platform = hl::Platform::from_platform_id(platform);
                let available = hl_platform.extensions().contains($ext_name);
                mem::forget(hl_platform);
                available
            };
            if !available {
                let platform_name;
                unsafe {
                    let hl_platform = hl::Platform::from_platform_id(platform);
                    platform_name = hl_platform.name();
                    mem::forget(hl_platform);
                }
                return Err(format!("extension {} unavailable for platform {}", $ext_name, platform_name));
            }
            // Return a struct with all functions loaded
            Ok(ext_struct_literal!($ext_name, platform, $($function),*))
        }
    )
}
// We only need these helper macros so we can special-case for unit structs
// (Since writing `struct name {}` is a failing error for some reason)
// Whatever functions we're calling aren't necessarily thread-safe, but since this is a low-level
// interface we'll let the callers worry about that
macro_rules! ext_struct_def {
    () => (#[deriving(Copy, Sync)] pub struct Functions;);
    ($($function:ident, ($($arg:ident, $arg_type:ty),+) $ret:ty)+) =>
    (
        #[deriving(Copy, Sync)]
        pub struct Functions {
            $(pub $function: (extern fn ($($arg : $arg_type),+) -> $ret)),+
        }
    );
}
// (So is writing `name {}` as a literal)
macro_rules! ext_struct_literal {
    ($ext_name:expr, $plat:ident,) => (Functions);
    ($ext_name:expr, $plat:ident, $($function:ident),+) =>
    (
        Functions {
            $($function: {
                let mut fn_name = CString::from_slice(stringify!($function).as_bytes());
                // TODO use clGetExtensionFunctionAddressForPlatform() when it's available; more
                // reliable.
                let fn_ptr = unsafe { clGetExtensionFunctionAddress(fn_name.as_ptr()) };
                if fn_ptr == ptr::null_mut() {
                    let platform_name;

                    unsafe {
                        let hl_platform = hl::Platform::from_platform_id($plat);
                        platform_name = hl_platform.name();
                        mem::forget(hl_platform);
                    }

                    return Err(format!("extension {} apparently available for platform with id {}, but couldn't load function {}",
                                       $ext_name,
                                       platform_name,
                                       stringify!($function)));
                }
                unsafe {
                    // Cast from *mut libc::void to the function pointer type we want
                    mem::transmute(fn_ptr)
                }
            }),+
        }
    );
}

pub mod cl_khr_fp64 {
    use cl::*;
    static CL_DEVICE_DOUBLE_FP_CONFIG: cl_uint = 0x1032;
    cl_extension_loader! {
        "cl_khr_fp64";
    }
}

pub mod cl_khr_fp16 {
    use cl::*;
    pub static CL_DEVICE_HALF_FP_CONFIG: cl_uint = 0x1033;
    cl_extension_loader! {
        "cl_khr_pf16";
    }
}

pub mod cl_APPLE_SetMemObjectDestructor {
    use libc;
    use cl::*;
    cl_extension_loader! {
        "cl_APPLE_SetMemObjectDestructor";
        extern fn clSetMemObjectDestructorAPPLE(memobj: cl_mem,
                                                pfn_notify: (extern fn(memobj: cl_mem,
                                                                       user_data: *mut libc::c_void)),
                                                user_data: *mut libc::c_void) -> () // Note: returning () is necessary to satisfy macros
    }
}

pub mod cl_APPLE_ContextLoggingFunctions {
    use libc;
    use cl::*;
    cl_extension_loader! {
        "cl_APPLE_ContextLoggingFunctions";
        extern fn clLogMessagesToSystemLogAPPLE(errstr: *const libc::c_char,
                                                private_info: *const libc::c_void,
                                                cb: libc::size_t,
                                                user_data: *mut libc::c_void) -> (),
        extern fn clLogMessagesToStdoutAPPLE(errstr: *const libc::c_char,
                                             private_info: *const libc::c_void,
                                             cb: libc::size_t,
                                             user_data: *mut libc::c_void) -> (),
        extern fn clLogMessagesToStderrAPPLE(errstr: *const libc::c_char,
                                             private_info: *const libc::c_void,
                                             cb: libc::size_t,
                                             user_data: *mut libc::c_void) -> ()
    }
}

pub mod cl_khr_icd {
    use libc;
    use cl::*;
    pub static CL_PLATFORM_ICD_SUFFIX:      cl_uint = 0x0920;
    // Note: this is an error code, but we can't extend CLStatus with it... hmm.
    pub static CL_PLATFORM_NOT_FOUND_KHR:   cl_int  = -1001;
    cl_extension_loader! {
        "cl_khr_icd";
        extern fn clIcdGetPlatformIDsKHR(num_entries: cl_uint,
                                         platform: *mut cl_platform_id,
                                         num_platforms: *mut cl_uint) -> cl_int
    }
}

pub mod cl_nv_device_attribute_query {
    use cl::*;
    pub static CL_DEVICE_COMPUTE_CAPABILITY_MAJOR_NV:   cl_uint = 0x4000;
    pub static CL_DEVICE_COMPUTE_CAPABILITY_MINOR_NV:   cl_uint = 0x4001;
    pub static CL_DEVICE_REGISTERS_PER_BLOCK_NV:        cl_uint = 0x4002;
    pub static CL_DEVICE_WARP_SIZE_NV:                  cl_uint = 0x4003;
    pub static CL_DEVICE_GPU_OVERLAP_NV:                cl_uint = 0x4004;
    pub static CL_DEVICE_KERNEL_EXEC_TIMEOUT_NV:        cl_uint = 0x4005;
    pub static CL_DEVICE_INTEGRATED_MEMORY_NV:          cl_uint = 0x4006;
    cl_extension_loader! {
        "cl_nv_device_attribute_query";
    }
}

pub mod cl_amd_device_attribute_query {
    use cl::*;
    pub static CL_DEVICE_PROFILING_TIMER_OFFSET_AMD:    cl_uint = 0x4036;
    cl_extension_loader! {
        "cl_amd_device_attribute_query";
    }
}

pub mod cl_arm_printf {
    use cl::*;
    pub static CL_PRINTF_CALLBACK_ARM:      cl_uint = 0x40B0;
    pub static CL_PRINTF_BUFFERSIZE_ARM:    cl_uint = 0x40B1;
    cl_extension_loader! {
        "cl_arm_printf";
    }
}

pub mod cl_ext_device_fission {
    use std;
    use cl::*;
    pub type cl_device_partition_property_ext = cl_ulong;
    pub static CL_DEVICE_PARTITION_EQUALLY_EXT: cl_device_partition_property_ext            = 0x4050;
    pub static CL_DEVICE_PARTITION_BY_COUNTS_EXT: cl_device_partition_property_ext          = 0x4051;
    pub static CL_DEVICE_PARTITION_BY_NAMES_EXT: cl_device_partition_property_ext           = 0x4052;
    pub static CL_DEVICE_PARTITION_BY_AFFINITY_DOMAIN_EXT: cl_device_partition_property_ext = 0x4053;
    pub static CL_DEVICE_PARENT_DEVICE_EXT: cl_device_info                                  = 0x4054;
    pub static CL_DEVICE_PARTITION_TYPES_EXT: cl_device_info                                = 0x4055;
    pub static CL_DEVICE_AFFINITY_DOMAINS_EXT: cl_device_info                               = 0x4056;
    pub static CL_DEVICE_REFERENCE_COUNT_EXT: cl_device_info                                = 0x4057;
    pub static CL_DEVICE_PARTITION_STYLE_EXT: cl_device_info                                = 0x4058;
    pub static CL_DEVICE_PARTITION_FAILED_EXT: cl_int                                       = -1057;
    pub static CL_INVALID_PARTITION_COUNT_EXT: cl_int                                       = -1058;
    pub static CL_INVALID_PARTITION_NAME_EXT: cl_int                                        = -1059;
    pub static CL_AFFINITY_DOMAIN_L1_CACHE_EXT: cl_uint                                     = 0x1;
    pub static CL_AFFINITY_DOMAIN_L2_CACHE_EXT: cl_uint                                     = 0x2;
    pub static CL_AFFINITY_DOMAIN_L3_CACHE_EXT: cl_uint                                     = 0x3;
    pub static CL_AFFINITY_DOMAIN_L4_CACHE_EXT: cl_uint                                     = 0x4;
    pub static CL_AFFINITY_DOMAIN_NUMA_EXT: cl_uint                                         = 0x10;
    pub static CL_AFFINITY_DOMAIN_NEXT_FISSIONABLE_EXT: cl_uint                             = 0x100;
    pub static CL_PROPERTIES_LIST_END_EXT: cl_device_partition_property_ext                 = 0;
    pub static CL_PARTITION_BY_COUNTS_LIST_END_EXT: cl_device_partition_property_ext        = 0;
    pub static CL_PARTITION_BY_NAMES_LIST_END_EXT: cl_device_partition_property_ext         = std::u64::MAX;
    cl_extension_loader! {
        "cl_ext_device_fission";
        extern fn clReleaseDeviceEXT(device: cl_device_id) -> cl_int,
        extern fn clRetainDeviceEXT(device: cl_device_id) -> cl_int,
        extern fn clCreateSubDevicesExt(in_device: cl_device_id,
                                        properties: *const cl_device_partition_property_ext,
                                        num_entries: cl_uint,
                                        out_devices: *mut cl_device_id,
                                        num_devices: *mut cl_uint) -> cl_int
    }
}

pub mod cl_qcom_ext_host_ptr {
    use libc;
    use cl::*;
    pub type cl_image_pitch_info_qcom = cl_uint;
    pub struct cl_mem_ext_host_ptr {
        pub allocation_type: cl_uint,
        pub host_cache_policy: cl_uint
    }
    pub static CL_MEM_EXT_HOST_PTR_QCOM:                cl_uint = (1 << 29);
    pub static CL_DEVICE_EXT_MEM_PADDING_IN_BYTES_QCOM: cl_uint = 0x40A0;
    pub static CL_DEVICE_PAGE_SIZE_QCOM:                cl_uint = 0x40A1;
    pub static CL_IMAGE_ROW_ALIGNMENT_QCOM:             cl_uint = 0x40A2;
    pub static CL_IMAGE_SLICE_ALIGNMENT_QCOM:           cl_uint = 0x40A3;
    pub static CL_MEM_HOST_UNCACHED_QCOM:               cl_uint = 0x40A4;
    pub static CL_MEM_HOST_WRITEBACK_QCOM:              cl_uint = 0x40A5;
    pub static CL_MEM_HOST_WRITETHROUGH_QCOM:           cl_uint = 0x40A6;
    pub static CL_MEM_HOST_WRITE_COMBINING_QCOM:        cl_uint = 0x40A7;
    cl_extension_loader! {
        "cl_qcom_ext_host_ptr";
        extern fn clGetDeviceImageInfoQCOM(device: cl_device_id,
                                           image_width: libc::size_t,
                                           image_height: libc::size_t,
                                           image_format: *const cl_image_format,
                                           param_name: cl_image_pitch_info_qcom,
                                           param_value_size: libc::size_t,
                                           param_value: *mut libc::c_void,
                                           param_value_size_ret: *mut libc::size_t) -> ()
    }
}

// This extension depends on the previous one. Should we try to express that?
pub mod cl_qcom_ion_host_ptr {
    use libc;
    use cl::*;
    use super::cl_qcom_ext_host_ptr;
    struct cl_mem_ion_host_ptr {
        pub ext_host_ptr: cl_qcom_ext_host_ptr::cl_mem_ext_host_ptr,
        pub ion_filedesc: libc::c_int,
        pub ion_hostptr: *mut libc::c_void
    }
    pub static CL_MEM_ION_HOST_PTR_QCOM: cl_uint = 0x40A8;

    cl_extension_loader! {
        "cl_qcom_ion_host_ptr";
    }
}
<commit_msg>s/deriving/derive and remove #[deriving(Sync)].<commit_after>#![allow(unused,
         unused_attributes,
         raw_pointer_derive,
         non_camel_case_types,
         non_snake_case)]

/// All of the extensions defined for OpenCL 1.1, from
/// [`cl_ext.h`](https://www.khronos.org/registry/cl/api/1.1/cl_ext.h).

// Macro to define a struct-style extension pointer loader.
// Defines a (`Copy`, `Sync`) `struct Functions` that has extension function pointers as members (and methods,
// for convenience).
// Call `$ext::load()` to get an Option<$ext::Functions, String>.  (It's safe to call extension function pointers in other threads, right?)
macro_rules! cl_extension_loader {
    (
        $ext_name:expr;
        $(extern fn $function:ident ($($arg:ident : $arg_type:ty),*) -> $ret:ty),*
    ) => (
        // Define struct Functions
        ext_struct_def!{ $($function, ($($arg, $arg_type),*) $ret)* }
        impl Functions {
            // Make function pointers available as methods so they don't have to be called as (struct.member)(arg)
            $( #[inline(always)] unsafe fn $function (&self, $($arg:$arg_type),*) -> $ret { (self.$function)($($arg),*) } )*
        }

        pub fn load(platform: cl_platform_id) -> Result<Functions, String> {
            use hl;
            use std::mem;
            use std::ptr;
            use std::ffi::CString;
            use cl::ll::clGetExtensionFunctionAddress;

            // Read in the available extensions
            // We have to do this, since loading function pointers for an
            // unavailable extension can return non-NULL.
            // TODO read in extensions lazily and store them in a global HashSet?
            let available = unsafe {
                let hl_platform = hl::Platform::from_platform_id(platform);
                let available = hl_platform.extensions().contains($ext_name);
                mem::forget(hl_platform);
                available
            };
            if !available {
                let platform_name;
                unsafe {
                    let hl_platform = hl::Platform::from_platform_id(platform);
                    platform_name = hl_platform.name();
                    mem::forget(hl_platform);
                }
                return Err(format!("extension {} unavailable for platform {}", $ext_name, platform_name));
            }
            // Return a struct with all functions loaded
            Ok(ext_struct_literal!($ext_name, platform, $($function),*))
        }
    )
}
// We only need these helper macros so we can special-case for unit structs
// (Since writing `struct name {}` is a failing error for some reason)
// Whatever functions we're calling aren't necessarily thread-safe, but since this is a low-level
// interface we'll let the callers worry about that
macro_rules! ext_struct_def {
    () => (#[derive(Copy)] pub struct Functions;);
    ($($function:ident, ($($arg:ident, $arg_type:ty),+) $ret:ty)+) =>
    (
        #[derive(Copy)]
        pub struct Functions {
            $(pub $function: (extern fn ($($arg : $arg_type),+) -> $ret)),+
        }
    );
}
// (So is writing `name {}` as a literal)
macro_rules! ext_struct_literal {
    ($ext_name:expr, $plat:ident,) => (Functions);
    ($ext_name:expr, $plat:ident, $($function:ident),+) =>
    (
        Functions {
            $($function: {
                let mut fn_name = CString::from_slice(stringify!($function).as_bytes());
                // TODO use clGetExtensionFunctionAddressForPlatform() when it's available; more
                // reliable.
                let fn_ptr = unsafe { clGetExtensionFunctionAddress(fn_name.as_ptr()) };
                if fn_ptr == ptr::null_mut() {
                    let platform_name;

                    unsafe {
                        let hl_platform = hl::Platform::from_platform_id($plat);
                        platform_name = hl_platform.name();
                        mem::forget(hl_platform);
                    }

                    return Err(format!("extension {} apparently available for platform with id {}, but couldn't load function {}",
                                       $ext_name,
                                       platform_name,
                                       stringify!($function)));
                }
                unsafe {
                    // Cast from *mut libc::void to the function pointer type we want
                    mem::transmute(fn_ptr)
                }
            }),+
        }
    );
}

pub mod cl_khr_fp64 {
    use cl::*;
    static CL_DEVICE_DOUBLE_FP_CONFIG: cl_uint = 0x1032;
    cl_extension_loader! {
        "cl_khr_fp64";
    }
}

pub mod cl_khr_fp16 {
    use cl::*;
    pub static CL_DEVICE_HALF_FP_CONFIG: cl_uint = 0x1033;
    cl_extension_loader! {
        "cl_khr_pf16";
    }
}

pub mod cl_APPLE_SetMemObjectDestructor {
    use libc;
    use cl::*;
    cl_extension_loader! {
        "cl_APPLE_SetMemObjectDestructor";
        extern fn clSetMemObjectDestructorAPPLE(memobj: cl_mem,
                                                pfn_notify: (extern fn(memobj: cl_mem,
                                                                       user_data: *mut libc::c_void)),
                                                user_data: *mut libc::c_void) -> () // Note: returning () is necessary to satisfy macros
    }
}

pub mod cl_APPLE_ContextLoggingFunctions {
    use libc;
    use cl::*;
    cl_extension_loader! {
        "cl_APPLE_ContextLoggingFunctions";
        extern fn clLogMessagesToSystemLogAPPLE(errstr: *const libc::c_char,
                                                private_info: *const libc::c_void,
                                                cb: libc::size_t,
                                                user_data: *mut libc::c_void) -> (),
        extern fn clLogMessagesToStdoutAPPLE(errstr: *const libc::c_char,
                                             private_info: *const libc::c_void,
                                             cb: libc::size_t,
                                             user_data: *mut libc::c_void) -> (),
        extern fn clLogMessagesToStderrAPPLE(errstr: *const libc::c_char,
                                             private_info: *const libc::c_void,
                                             cb: libc::size_t,
                                             user_data: *mut libc::c_void) -> ()
    }
}

pub mod cl_khr_icd {
    use libc;
    use cl::*;
    pub static CL_PLATFORM_ICD_SUFFIX:      cl_uint = 0x0920;
    // Note: this is an error code, but we can't extend CLStatus with it... hmm.
    pub static CL_PLATFORM_NOT_FOUND_KHR:   cl_int  = -1001;
    cl_extension_loader! {
        "cl_khr_icd";
        extern fn clIcdGetPlatformIDsKHR(num_entries: cl_uint,
                                         platform: *mut cl_platform_id,
                                         num_platforms: *mut cl_uint) -> cl_int
    }
}

pub mod cl_nv_device_attribute_query {
    use cl::*;
    pub static CL_DEVICE_COMPUTE_CAPABILITY_MAJOR_NV:   cl_uint = 0x4000;
    pub static CL_DEVICE_COMPUTE_CAPABILITY_MINOR_NV:   cl_uint = 0x4001;
    pub static CL_DEVICE_REGISTERS_PER_BLOCK_NV:        cl_uint = 0x4002;
    pub static CL_DEVICE_WARP_SIZE_NV:                  cl_uint = 0x4003;
    pub static CL_DEVICE_GPU_OVERLAP_NV:                cl_uint = 0x4004;
    pub static CL_DEVICE_KERNEL_EXEC_TIMEOUT_NV:        cl_uint = 0x4005;
    pub static CL_DEVICE_INTEGRATED_MEMORY_NV:          cl_uint = 0x4006;
    cl_extension_loader! {
        "cl_nv_device_attribute_query";
    }
}

pub mod cl_amd_device_attribute_query {
    use cl::*;
    pub static CL_DEVICE_PROFILING_TIMER_OFFSET_AMD:    cl_uint = 0x4036;
    cl_extension_loader! {
        "cl_amd_device_attribute_query";
    }
}

pub mod cl_arm_printf {
    use cl::*;
    pub static CL_PRINTF_CALLBACK_ARM:      cl_uint = 0x40B0;
    pub static CL_PRINTF_BUFFERSIZE_ARM:    cl_uint = 0x40B1;
    cl_extension_loader! {
        "cl_arm_printf";
    }
}

pub mod cl_ext_device_fission {
    use std;
    use cl::*;
    pub type cl_device_partition_property_ext = cl_ulong;
    pub static CL_DEVICE_PARTITION_EQUALLY_EXT: cl_device_partition_property_ext            = 0x4050;
    pub static CL_DEVICE_PARTITION_BY_COUNTS_EXT: cl_device_partition_property_ext          = 0x4051;
    pub static CL_DEVICE_PARTITION_BY_NAMES_EXT: cl_device_partition_property_ext           = 0x4052;
    pub static CL_DEVICE_PARTITION_BY_AFFINITY_DOMAIN_EXT: cl_device_partition_property_ext = 0x4053;
    pub static CL_DEVICE_PARENT_DEVICE_EXT: cl_device_info                                  = 0x4054;
    pub static CL_DEVICE_PARTITION_TYPES_EXT: cl_device_info                                = 0x4055;
    pub static CL_DEVICE_AFFINITY_DOMAINS_EXT: cl_device_info                               = 0x4056;
    pub static CL_DEVICE_REFERENCE_COUNT_EXT: cl_device_info                                = 0x4057;
    pub static CL_DEVICE_PARTITION_STYLE_EXT: cl_device_info                                = 0x4058;
    pub static CL_DEVICE_PARTITION_FAILED_EXT: cl_int                                       = -1057;
    pub static CL_INVALID_PARTITION_COUNT_EXT: cl_int                                       = -1058;
    pub static CL_INVALID_PARTITION_NAME_EXT: cl_int                                        = -1059;
    pub static CL_AFFINITY_DOMAIN_L1_CACHE_EXT: cl_uint                                     = 0x1;
    pub static CL_AFFINITY_DOMAIN_L2_CACHE_EXT: cl_uint                                     = 0x2;
    pub static CL_AFFINITY_DOMAIN_L3_CACHE_EXT: cl_uint                                     = 0x3;
    pub static CL_AFFINITY_DOMAIN_L4_CACHE_EXT: cl_uint                                     = 0x4;
    pub static CL_AFFINITY_DOMAIN_NUMA_EXT: cl_uint                                         = 0x10;
    pub static CL_AFFINITY_DOMAIN_NEXT_FISSIONABLE_EXT: cl_uint                             = 0x100;
    pub static CL_PROPERTIES_LIST_END_EXT: cl_device_partition_property_ext                 = 0;
    pub static CL_PARTITION_BY_COUNTS_LIST_END_EXT: cl_device_partition_property_ext        = 0;
    pub static CL_PARTITION_BY_NAMES_LIST_END_EXT: cl_device_partition_property_ext         = std::u64::MAX;
    cl_extension_loader! {
        "cl_ext_device_fission";
        extern fn clReleaseDeviceEXT(device: cl_device_id) -> cl_int,
        extern fn clRetainDeviceEXT(device: cl_device_id) -> cl_int,
        extern fn clCreateSubDevicesExt(in_device: cl_device_id,
                                        properties: *const cl_device_partition_property_ext,
                                        num_entries: cl_uint,
                                        out_devices: *mut cl_device_id,
                                        num_devices: *mut cl_uint) -> cl_int
    }
}

pub mod cl_qcom_ext_host_ptr {
    use libc;
    use cl::*;
    pub type cl_image_pitch_info_qcom = cl_uint;
    pub struct cl_mem_ext_host_ptr {
        pub allocation_type: cl_uint,
        pub host_cache_policy: cl_uint
    }
    pub static CL_MEM_EXT_HOST_PTR_QCOM:                cl_uint = (1 << 29);
    pub static CL_DEVICE_EXT_MEM_PADDING_IN_BYTES_QCOM: cl_uint = 0x40A0;
    pub static CL_DEVICE_PAGE_SIZE_QCOM:                cl_uint = 0x40A1;
    pub static CL_IMAGE_ROW_ALIGNMENT_QCOM:             cl_uint = 0x40A2;
    pub static CL_IMAGE_SLICE_ALIGNMENT_QCOM:           cl_uint = 0x40A3;
    pub static CL_MEM_HOST_UNCACHED_QCOM:               cl_uint = 0x40A4;
    pub static CL_MEM_HOST_WRITEBACK_QCOM:              cl_uint = 0x40A5;
    pub static CL_MEM_HOST_WRITETHROUGH_QCOM:           cl_uint = 0x40A6;
    pub static CL_MEM_HOST_WRITE_COMBINING_QCOM:        cl_uint = 0x40A7;
    cl_extension_loader! {
        "cl_qcom_ext_host_ptr";
        extern fn clGetDeviceImageInfoQCOM(device: cl_device_id,
                                           image_width: libc::size_t,
                                           image_height: libc::size_t,
                                           image_format: *const cl_image_format,
                                           param_name: cl_image_pitch_info_qcom,
                                           param_value_size: libc::size_t,
                                           param_value: *mut libc::c_void,
                                           param_value_size_ret: *mut libc::size_t) -> ()
    }
}

// This extension depends on the previous one. Should we try to express that?
pub mod cl_qcom_ion_host_ptr {
    use libc;
    use cl::*;
    use super::cl_qcom_ext_host_ptr;
    struct cl_mem_ion_host_ptr {
        pub ext_host_ptr: cl_qcom_ext_host_ptr::cl_mem_ext_host_ptr,
        pub ion_filedesc: libc::c_int,
        pub ion_hostptr: *mut libc::c_void
    }
    pub static CL_MEM_ION_HOST_PTR_QCOM: cl_uint = 0x40A8;

    cl_extension_loader! {
        "cl_qcom_ion_host_ptr";
    }
}
<|endoftext|>


<commit_before>#[cfg(all(feature = "color", not(target_os = "windows")))]
use ansi_term::ANSIString;

#[cfg(all(feature = "color", not(target_os = "windows")))]
use ansi_term::Colour::{Green, Red, Yellow};

#[cfg(feature = "color")]
use atty;
use std::fmt;

#[doc(hidden)]
#[derive(Debug, Copy, Clone, PartialEq)]
pub enum ColorWhen {
    Auto,
    Always,
    Never,
}

#[cfg(feature = "color")]
pub fn is_a_tty(stderr: bool) -> bool {
    debugln!("is_a_tty: stderr={:?}", stderr);
    let stream = if stderr {
        atty::Stream::Stderr
    } else {
        atty::Stream::Stdout
    };
    atty::is(stream)
}

#[cfg(not(feature = "color"))]
pub fn is_a_tty(_: bool) -> bool {
    debugln!("is_a_tty;");
    false
}

#[doc(hidden)]
pub struct Colorizer {
    pub use_stderr: bool,
    pub when: ColorWhen,
}

macro_rules! color {
    ($_self:ident, $c:ident, $m:expr) => {
        match $_self.when {
            ColorWhen::Auto => if is_a_tty($_self.use_stderr) {
                Format::$c($m)
            } else {
                Format::None($m)
            },
            ColorWhen::Always => Format::$c($m),
            ColorWhen::Never => Format::None($m),
        }
    };
}

impl Colorizer {
    pub fn good<T>(&self, msg: T) -> Format<T>
        where T: fmt::Display + AsRef<str>
    {
        debugln!("Colorizer::good;");
        color!(self, Good, msg)
    }

    pub fn warning<T>(&self, msg: T) -> Format<T>
        where T: fmt::Display + AsRef<str>
    {
        debugln!("Colorizer::warning;");
        color!(self, Warning, msg)
    }

    pub fn error<T>(&self, msg: T) -> Format<T>
        where T: fmt::Display + AsRef<str>
    {
        debugln!("Colorizer::error;");
        color!(self, Error, msg)
    }

    pub fn none<T>(&self, msg: T) -> Format<T>
        where T: fmt::Display + AsRef<str>
    {
        debugln!("Colorizer::none;");
        Format::None(msg)
    }
}

impl Default for Colorizer {
    fn default() -> Self {
        Colorizer {
            use_stderr: true,
            when: ColorWhen::Auto,
        }
    }
}

/// Defines styles for different types of error messages. Defaults to Error=Red, Warning=Yellow,
/// and Good=Green
#[derive(Debug)]
#[doc(hidden)]
pub enum Format<T> {
    /// Defines the style used for errors, defaults to Red
    Error(T),
    /// Defines the style used for warnings, defaults to Yellow
    Warning(T),
    /// Defines the style used for good values, defaults to Green
    Good(T),
    /// Defines no formatting style
    None(T),
}

#[cfg(all(feature = "color", not(target_os = "windows")))]
impl<T: AsRef<str>> Format<T> {
    fn format(&self) -> ANSIString {
        match *self {
            Format::Error(ref e) => Red.bold().paint(e.as_ref()),
            Format::Warning(ref e) => Yellow.paint(e.as_ref()),
            Format::Good(ref e) => Green.paint(e.as_ref()),
            Format::None(ref e) => ANSIString::from(e.as_ref()),
        }
    }
}

#[cfg(any(not(feature = "color"), target_os = "windows"))]
#[cfg_attr(feature="lints", allow(match_same_arms))]
impl<T: fmt::Display> Format<T> {
    fn format(&self) -> &T {
        match *self {
            Format::Error(ref e) => e,
            Format::Warning(ref e) => e,
            Format::Good(ref e) => e,
            Format::None(ref e) => e,
        }
    }
}

#[cfg(all(feature = "color", not(target_os = "windows")))]
impl<T: AsRef<str>> fmt::Display for Format<T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "{}", &self.format()) }
}

#[cfg(any(not(feature = "color"), target_os = "windows"))]
impl<T: fmt::Display> fmt::Display for Format<T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "{}", &self.format()) }
}

#[cfg(all(test, feature = "color", not(target_os = "windows")))]
mod test {
    use ansi_term::ANSIString;
    use ansi_term::Colour::{Green, Red, Yellow};
    use super::Format;

    #[test]
    fn colored_output() {
        let err = Format::Error("error");
        assert_eq!(&*format!("{}", err),
                   &*format!("{}", Red.bold().paint("error")));
        let good = Format::Good("good");
        assert_eq!(&*format!("{}", good), &*format!("{}", Green.paint("good")));
        let warn = Format::Warning("warn");
        assert_eq!(&*format!("{}", warn), &*format!("{}", Yellow.paint("warn")));
        let none = Format::None("none");
        assert_eq!(&*format!("{}", none),
                   &*format!("{}", ANSIString::from("none")));
    }
}
<commit_msg>when `TERM=dumb`, the output is colorless #847<commit_after>#[cfg(all(feature = "color", not(target_os = "windows")))]
use ansi_term::ANSIString;

#[cfg(all(feature = "color", not(target_os = "windows")))]
use ansi_term::Colour::{Green, Red, Yellow};

#[cfg(feature = "color")]
use atty;
use std::fmt;
use std::env;

#[doc(hidden)]
#[derive(Debug, Copy, Clone, PartialEq)]
pub enum ColorWhen {
    Auto,
    Always,
    Never,
}

#[cfg(feature = "color")]
pub fn is_a_tty(stderr: bool) -> bool {
    debugln!("is_a_tty: stderr={:?}", stderr);
    let stream = if stderr {
        atty::Stream::Stderr
    } else {
        atty::Stream::Stdout
    };
    atty::is(stream)
}

#[cfg(not(feature = "color"))]
pub fn is_a_tty(_: bool) -> bool {
    debugln!("is_a_tty;");
    false
}

#[doc(hidden)]
pub struct Colorizer {
    pub use_stderr: bool,
    pub when: ColorWhen,
}

macro_rules! color {
    ($_self:ident, $c:ident, $m:expr) => {
        if env::var("TERM").ok() == Some(String::from("dumb")) {
            Format::None($m)
        } else {
            match $_self.when {
                ColorWhen::Auto => if is_a_tty($_self.use_stderr) {
                    Format::$c($m)
                } else {
                    Format::None($m)
                },
                ColorWhen::Always => Format::$c($m),
                ColorWhen::Never => Format::None($m),
            }
        }
    };
}

impl Colorizer {
    pub fn good<T>(&self, msg: T) -> Format<T>
        where T: fmt::Display + AsRef<str>
    {
        debugln!("Colorizer::good;");
        color!(self, Good, msg)
    }

    pub fn warning<T>(&self, msg: T) -> Format<T>
        where T: fmt::Display + AsRef<str>
    {
        debugln!("Colorizer::warning;");
        color!(self, Warning, msg)
    }

    pub fn error<T>(&self, msg: T) -> Format<T>
        where T: fmt::Display + AsRef<str>
    {
        debugln!("Colorizer::error;");
        color!(self, Error, msg)
    }

    pub fn none<T>(&self, msg: T) -> Format<T>
        where T: fmt::Display + AsRef<str>
    {
        debugln!("Colorizer::none;");
        Format::None(msg)
    }
}

impl Default for Colorizer {
    fn default() -> Self {
        Colorizer {
            use_stderr: true,
            when: ColorWhen::Auto,
        }
    }
}

/// Defines styles for different types of error messages. Defaults to Error=Red, Warning=Yellow,
/// and Good=Green
#[derive(Debug)]
#[doc(hidden)]
pub enum Format<T> {
    /// Defines the style used for errors, defaults to Red
    Error(T),
    /// Defines the style used for warnings, defaults to Yellow
    Warning(T),
    /// Defines the style used for good values, defaults to Green
    Good(T),
    /// Defines no formatting style
    None(T),
}

#[cfg(all(feature = "color", not(target_os = "windows")))]
impl<T: AsRef<str>> Format<T> {
    fn format(&self) -> ANSIString {
        match *self {
            Format::Error(ref e) => Red.bold().paint(e.as_ref()),
            Format::Warning(ref e) => Yellow.paint(e.as_ref()),
            Format::Good(ref e) => Green.paint(e.as_ref()),
            Format::None(ref e) => ANSIString::from(e.as_ref()),
        }
    }
}

#[cfg(any(not(feature = "color"), target_os = "windows"))]
#[cfg_attr(feature="lints", allow(match_same_arms))]
impl<T: fmt::Display> Format<T> {
    fn format(&self) -> &T {
        match *self {
            Format::Error(ref e) => e,
            Format::Warning(ref e) => e,
            Format::Good(ref e) => e,
            Format::None(ref e) => e,
        }
    }
}

#[cfg(all(feature = "color", not(target_os = "windows")))]
impl<T: AsRef<str>> fmt::Display for Format<T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "{}", &self.format()) }
}

#[cfg(any(not(feature = "color"), target_os = "windows"))]
impl<T: fmt::Display> fmt::Display for Format<T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "{}", &self.format()) }
}

#[cfg(all(test, feature = "color", not(target_os = "windows")))]
mod test {
    use ansi_term::ANSIString;
    use ansi_term::Colour::{Green, Red, Yellow};
    use super::Format;

    #[test]
    fn colored_output() {
        let err = Format::Error("error");
        assert_eq!(&*format!("{}", err),
                   &*format!("{}", Red.bold().paint("error")));
        let good = Format::Good("good");
        assert_eq!(&*format!("{}", good), &*format!("{}", Green.paint("good")));
        let warn = Format::Warning("warn");
        assert_eq!(&*format!("{}", warn), &*format!("{}", Yellow.paint("warn")));
        let none = Format::None("none");
        assert_eq!(&*format!("{}", none),
                   &*format!("{}", ANSIString::from("none")));
    }
}
<|endoftext|>


<commit_before>#[test]
fn run() {
    let path = env!("CARGO_BIN_EXE_hello-world");
    let output = std::process::Command::new(path)
        .output()
        .expect("Failed to run process");
    assert_eq!(&b"Hello world\n"[..], output.stdout.as_slice());

    // Test the `env` attribute of `rust_test` at run time
    assert_eq!(
        std::env::var("FERRIS_SAYS").unwrap(),
        "Hello fellow Rustaceans!"
    );

    // Test the behavior of `rootpath` and that a binary can be found relative to current_dir
    let hello_world_bin = std::path::PathBuf::from(std::env::var_os("HELLO_WORLD_BIN").unwrap());

    assert_eq!(
        hello_world_bin.as_path(),
        std::path::Path::new(if std::env::consts::OS == "windows" {
            "test/test_env_launcher/hello-world.exe"
        } else {
            "test/test_env_launcher/hello-world"
        })
    );
    assert!(!hello_world_bin.is_absolute());
    assert!(hello_world_bin.exists());

    // Ensure `execpath` expanded variables map to real files and have absolute paths
    let hello_world_src = std::path::PathBuf::from(std::env::var("HELLO_WORLD_SRC").unwrap());
    assert!(!hello_world_bin.is_absolute());
    assert!(hello_world_src.exists());
}
<commit_msg>Fix incorrect assertion in test_env_launcher test (#1368)<commit_after>#[test]
fn run() {
    let path = env!("CARGO_BIN_EXE_hello-world");
    let output = std::process::Command::new(path)
        .output()
        .expect("Failed to run process");
    assert_eq!(&b"Hello world\n"[..], output.stdout.as_slice());

    // Test the `env` attribute of `rust_test` at run time
    assert_eq!(
        std::env::var("FERRIS_SAYS").unwrap(),
        "Hello fellow Rustaceans!"
    );

    // Test the behavior of `rootpath` and that a binary can be found relative to current_dir
    let hello_world_bin = std::path::PathBuf::from(std::env::var_os("HELLO_WORLD_BIN").unwrap());

    assert_eq!(
        hello_world_bin.as_path(),
        std::path::Path::new(if std::env::consts::OS == "windows" {
            "test/test_env_launcher/hello-world.exe"
        } else {
            "test/test_env_launcher/hello-world"
        })
    );
    assert!(!hello_world_bin.is_absolute());
    assert!(hello_world_bin.exists());

    // Ensure `execpath` expanded variables map to real files and have absolute paths
    let hello_world_src = std::path::PathBuf::from(std::env::var("HELLO_WORLD_SRC").unwrap());
    assert!(!hello_world_src.is_absolute());
    assert!(hello_world_src.exists());
}
<|endoftext|>