<commit_before>// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#[allow(deprecated_mode)];

use json;
use sha1;
use serialize::{Encoder, Encodable, Decoder, Decodable};
use sort;

use core::cell::Cell;
use core::cmp;
use core::either::{Either, Left, Right};
use core::io;
use core::comm::{oneshot, PortOne, send_one};
use core::pipes::recv;
use core::prelude::*;
use core::result;
use core::run;
use core::hashmap::linear::LinearMap;
use core::task;
use core::to_bytes;
use core::mutable::Mut;

/**
*
* This is a loose clone of the fbuild build system, made a touch more
* generic (not wired to special cases on files) and much less metaprogram-y
* due to rust's comparative weakness there, relative to python.
*
* It's based around _imperative bulids_ that happen to have some function
* calls cached. That is, it's _just_ a mechanism for describing cached
* functions. This makes it much simpler and smaller than a "build system"
* that produces an IR and evaluates it. The evaluation order is normal
* function calls. Some of them just return really quickly.
*
* A cached function consumes and produces a set of _works_. A work has a
* name, a kind (that determines how the value is to be checked for
* freshness) and a value. Works must also be (de)serializable. Some
* examples of works:
*
*    kind   name    value
*   ------------------------
*    cfg    os      linux
*    file   foo.c   <sha1>
*    url    foo.com <etag>
*
* Works are conceptually single units, but we store them most of the time
* in maps of the form (type,name) => value. These are WorkMaps.
*
* A cached function divides the works it's interested up into inputs and
* outputs, and subdivides those into declared (input) works and
* discovered (input and output) works.
*
* A _declared_ input or is one that is given to the workcache before
* any work actually happens, in the "prep" phase. Even when a function's
* work-doing part (the "exec" phase) never gets called, it has declared
* inputs, which can be checked for freshness (and potentially
* used to determine that the function can be skipped).
*
* The workcache checks _all_ works for freshness, but uses the set of
* discovered outputs from the _previous_ exec (which it will re-discover
* and re-record each time the exec phase runs).
*
* Therefore the discovered works cached in the db might be a
* mis-approximation of the current discoverable works, but this is ok for
* the following reason: we assume that if an artifact A changed from
* depending on B,C,D to depending on B,C,D,E, then A itself changed (as
* part of the change-in-dependencies), so we will be ok.
*
* Each function has a single discriminated output work called its _result_.
* This is only different from other works in that it is returned, by value,
* from a call to the cacheable function; the other output works are used in
* passing to invalidate dependencies elsewhere in the cache, but do not
* otherwise escape from a function invocation. Most functions only have one
* output work anyways.
*
* A database (the central store of a workcache) stores a mappings:
*
* (fn_name,{declared_input}) => ({discovered_input},
*                                {discovered_output},result)
*
* (Note: fbuild, which workcache is based on, has the concept of a declared
* output as separate from a discovered output. This distinction exists only
* as an artifact of how fbuild works: via annotations on function types
* and metaprogramming, with explicit dependency declaration as a fallback.
* Workcache is more explicit about dependencies, and as such treats all
* outputs the same, as discovered-during-the-last-run.)
*
*/

#[deriving_eq]
#[auto_encode]
#[auto_decode]
struct WorkKey {
    kind: ~str,
    name: ~str
}

impl to_bytes::IterBytes for WorkKey {
    #[inline(always)]
    pure fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) {
        let mut flag = true;
        self.kind.iter_bytes(lsb0, |bytes| {flag = f(bytes); flag});
        if !flag { return; }
        self.name.iter_bytes(lsb0, f);
    }
}

impl cmp::Ord for WorkKey {
    pure fn lt(&self, other: &WorkKey) -> bool {
        self.kind < other.kind ||
            (self.kind == other.kind &&
             self.name < other.name)
    }
    pure fn le(&self, other: &WorkKey) -> bool {
        self.lt(other) || self.eq(other)
    }
    pure fn ge(&self, other: &WorkKey) -> bool {
        self.gt(other) || self.eq(other)
    }
    pure fn gt(&self, other: &WorkKey) -> bool {
        ! self.le(other)
    }
}

pub impl WorkKey {
    static fn new(kind: &str, name: &str) -> WorkKey {
    WorkKey { kind: kind.to_owned(), name: name.to_owned() }
    }
}

type WorkMap = LinearMap<WorkKey, ~str>;

impl<S:Encoder> Encodable<S> for WorkMap {
    fn encode(&self, s: &S) {
        let mut d = ~[];
        for self.each |&(k, v)| {
            d.push((copy *k, copy *v))
        }
        sort::tim_sort(d);
        d.encode(s)
    }
}

impl<D:Decoder> Decodable<D> for WorkMap {
    static fn decode(&self, d: &D) -> WorkMap {
        let v : ~[(WorkKey,~str)] = Decodable::decode(d);
        let mut w = LinearMap::new();
        for v.each |&(k, v)| {
            w.insert(copy k, copy v);
        }
        w
    }
}

struct Database {
    db_filename: Path,
    db_cache: LinearMap<~str, ~str>,
    mut db_dirty: bool
}

pub impl Database {
    fn prepare(&mut self, fn_name: &str,
               declared_inputs: &WorkMap) -> Option<(WorkMap, WorkMap, ~str)>
    {
        let k = json_encode(&(fn_name, declared_inputs));
        match self.db_cache.find(&k) {
            None => None,
            Some(&v) => Some(json_decode(copy v))
        }
    }

    fn cache(&mut self,
             fn_name: &str,
             declared_inputs: &WorkMap,
             discovered_inputs: &WorkMap,
             discovered_outputs: &WorkMap,
             result: &str) {
        let k = json_encode(&(fn_name, declared_inputs));
        let v = json_encode(&(discovered_inputs,
                              discovered_outputs,
                              result));
        self.db_cache.insert(k,v);
        self.db_dirty = true
    }
}

struct Logger {
    // FIXME #4432: Fill in
    a: ()
}

pub impl Logger {
    fn info(i: &str) {
        io::println(~"workcache: " + i.to_owned());
    }
}

struct Context {
    db: @Mut<Database>,
    logger: @Mut<Logger>,
    cfg: @json::Object,
    freshness: LinearMap<~str,@fn(&str,&str)->bool>
}

struct Prep {
    ctxt: @Context,
    fn_name: ~str,
    declared_inputs: WorkMap,
}

struct Exec {
    discovered_inputs: WorkMap,
    discovered_outputs: WorkMap
}

struct Work<T> {
    prep: @Mut<Prep>,
    res: Option<Either<T,PortOne<(Exec,T)>>>
}

fn json_encode<T:Encodable<json::Encoder>>(t: &T) -> ~str {
    do io::with_str_writer |wr| {
        t.encode(&json::Encoder(wr));
    }
}

fn json_decode<T:Decodable<json::Decoder>>(s: &str) -> T {
    do io::with_str_reader(s) |rdr| {
        let j = result::unwrap(json::from_reader(rdr));
        Decodable::decode(&json::Decoder(j))
    }
}

fn digest<T:Encodable<json::Encoder>>(t: &T) -> ~str {
    let mut sha = sha1::sha1();
    sha.input_str(json_encode(t));
    sha.result_str()
}

fn digest_file(path: &Path) -> ~str {
    let mut sha = sha1::sha1();
    let s = io::read_whole_file_str(path);
    sha.input_str(*s.get_ref());
    sha.result_str()
}

pub impl Context {

    static fn new(db: @Mut<Database>,
                  lg: @Mut<Logger>,
                  cfg: @json::Object) -> Context {
        Context{db: db, logger: lg, cfg: cfg, freshness: LinearMap::new()}
    }

    fn prep<T:Owned + Encodable<json::Encoder> + Decodable<json::Decoder>>(
                  @self,
                  fn_name:&str,
                  blk: fn(@Mut<Prep>)->Work<T>) -> Work<T> {
        let p = @Mut(Prep {ctxt: self,
                           fn_name: fn_name.to_owned(),
                           declared_inputs: LinearMap::new()});
        blk(p)
    }
}

trait TPrep {
    fn declare_input(&self, kind:&str, name:&str, val:&str);
    fn is_fresh(&self, cat:&str, kind:&str, name:&str, val:&str) -> bool;
    fn all_fresh(&self, cat:&str, map:&WorkMap) -> bool;
    fn exec<T:Owned + Encodable<json::Encoder> + Decodable<json::Decoder>>(
        &self, blk: ~fn(&Exec) -> T) -> Work<T>;
}

impl TPrep for @Mut<Prep> {
    fn declare_input(&self, kind:&str, name:&str, val:&str) {
        do self.borrow_mut |p| {
            p.declared_inputs.insert(WorkKey::new(kind, name),
                                     val.to_owned());
        }
    }

    fn is_fresh(&self, cat: &str, kind: &str,
                name: &str, val: &str) -> bool {
        do self.borrow_imm |p| {
            let k = kind.to_owned();
            let f = (*p.ctxt.freshness.get(&k))(name, val);
            do p.ctxt.logger.borrow_imm |lg| {
                if f {
                    lg.info(fmt!("%s %s:%s is fresh",
                                 cat, kind, name));
                } else {
                    lg.info(fmt!("%s %s:%s is not fresh",
                                 cat, kind, name))
                }
            }
            f
        }
    }

    fn all_fresh(&self, cat: &str, map: &WorkMap) -> bool {
        for map.each |&(k, v)| {
            if ! self.is_fresh(cat, k.kind, k.name, *v) {
                return false;
            }
        }
        return true;
    }

    fn exec<T:Owned + Encodable<json::Encoder> + Decodable<json::Decoder>>(
            &self, blk: ~fn(&Exec) -> T) -> Work<T> {
        let mut bo = Some(blk);

        do self.borrow_imm |p| {
            let cached = do p.ctxt.db.borrow_mut |db| {
                db.prepare(p.fn_name, &p.declared_inputs)
            };

            match cached {
                Some((ref disc_in, ref disc_out, ref res))
                if self.all_fresh("declared input",
                                  &p.declared_inputs) &&
                self.all_fresh("discovered input", disc_in) &&
                self.all_fresh("discovered output", disc_out) => {
                    Work::new(*self, Left(json_decode(*res)))
                }

                _ => {
                    let (chan, port) = oneshot::init();
                    let mut blk = None;
                    blk <-> bo;
                    let blk = blk.unwrap();
                    let chan = Cell(chan);
                    do task::spawn || {
                        let exe = Exec{discovered_inputs: LinearMap::new(),
                                       discovered_outputs: LinearMap::new()};
                        let chan = chan.take();
                        let v = blk(&exe);
                        send_one(chan, (exe, v));
                    }

                    Work::new(*self, Right(port))
                }
            }
        }
    }
}

pub impl<T:Owned+Encodable<json::Encoder>+Decodable<json::Decoder>> Work<T> {
    static fn new(p: @Mut<Prep>, e: Either<T,PortOne<(Exec,T)>>) -> Work<T> {
        Work { prep: p, res: Some(e) }
    }
}

// FIXME (#3724): movable self. This should be in impl Work.
fn unwrap<T:Owned + Encodable<json::Encoder> + Decodable<json::Decoder>>(
        w: Work<T>) -> T {
    let mut ww = w;
    let mut s = None;

    ww.res <-> s;

    match s {
        None => fail!(),
        Some(Left(v)) => v,
        Some(Right(port)) => {
            let (exe, v) = match recv(port) {
                oneshot::send(data) => data
            };

            let s = json_encode(&v);

            do ww.prep.borrow_imm |p| {
                do p.ctxt.db.borrow_mut |db| {
                    db.cache(p.fn_name,
                             &p.declared_inputs,
                             &exe.discovered_inputs,
                             &exe.discovered_outputs,
                             s);
                }
            }
            v
        }
    }
}

//#[test]
fn test() {
    use core::io::WriterUtil;

    let db = @Mut(Database { db_filename: Path("db.json"),
                             db_cache: LinearMap::new(),
                             db_dirty: false });
    let lg = @Mut(Logger { a: () });
    let cfg = @LinearMap::new();
    let cx = @Context::new(db, lg, cfg);
    let w:Work<~str> = do cx.prep("test1") |prep| {
        let pth = Path("foo.c");
        {
            let file = io::file_writer(&pth, [io::Create]).get();
            file.write_str("int main() { return 0; }");
        }

        prep.declare_input("file", pth.to_str(), digest_file(&pth));
        do prep.exec |_exe| {
            let out = Path("foo.o");
            run::run_program("gcc", [~"foo.c", ~"-o", out.to_str()]);
            out.to_str()
        }
    };
    let s = unwrap(w);
    io::println(s);
}
<commit_msg>std: remove an unnecessary copy from workcache<commit_after>// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#[allow(deprecated_mode)];

use json;
use sha1;
use serialize::{Encoder, Encodable, Decoder, Decodable};
use sort;

use core::cell::Cell;
use core::cmp;
use core::either::{Either, Left, Right};
use core::io;
use core::comm::{oneshot, PortOne, send_one};
use core::pipes::recv;
use core::prelude::*;
use core::result;
use core::run;
use core::hashmap::linear::LinearMap;
use core::task;
use core::to_bytes;
use core::mutable::Mut;

/**
*
* This is a loose clone of the fbuild build system, made a touch more
* generic (not wired to special cases on files) and much less metaprogram-y
* due to rust's comparative weakness there, relative to python.
*
* It's based around _imperative bulids_ that happen to have some function
* calls cached. That is, it's _just_ a mechanism for describing cached
* functions. This makes it much simpler and smaller than a "build system"
* that produces an IR and evaluates it. The evaluation order is normal
* function calls. Some of them just return really quickly.
*
* A cached function consumes and produces a set of _works_. A work has a
* name, a kind (that determines how the value is to be checked for
* freshness) and a value. Works must also be (de)serializable. Some
* examples of works:
*
*    kind   name    value
*   ------------------------
*    cfg    os      linux
*    file   foo.c   <sha1>
*    url    foo.com <etag>
*
* Works are conceptually single units, but we store them most of the time
* in maps of the form (type,name) => value. These are WorkMaps.
*
* A cached function divides the works it's interested up into inputs and
* outputs, and subdivides those into declared (input) works and
* discovered (input and output) works.
*
* A _declared_ input or is one that is given to the workcache before
* any work actually happens, in the "prep" phase. Even when a function's
* work-doing part (the "exec" phase) never gets called, it has declared
* inputs, which can be checked for freshness (and potentially
* used to determine that the function can be skipped).
*
* The workcache checks _all_ works for freshness, but uses the set of
* discovered outputs from the _previous_ exec (which it will re-discover
* and re-record each time the exec phase runs).
*
* Therefore the discovered works cached in the db might be a
* mis-approximation of the current discoverable works, but this is ok for
* the following reason: we assume that if an artifact A changed from
* depending on B,C,D to depending on B,C,D,E, then A itself changed (as
* part of the change-in-dependencies), so we will be ok.
*
* Each function has a single discriminated output work called its _result_.
* This is only different from other works in that it is returned, by value,
* from a call to the cacheable function; the other output works are used in
* passing to invalidate dependencies elsewhere in the cache, but do not
* otherwise escape from a function invocation. Most functions only have one
* output work anyways.
*
* A database (the central store of a workcache) stores a mappings:
*
* (fn_name,{declared_input}) => ({discovered_input},
*                                {discovered_output},result)
*
* (Note: fbuild, which workcache is based on, has the concept of a declared
* output as separate from a discovered output. This distinction exists only
* as an artifact of how fbuild works: via annotations on function types
* and metaprogramming, with explicit dependency declaration as a fallback.
* Workcache is more explicit about dependencies, and as such treats all
* outputs the same, as discovered-during-the-last-run.)
*
*/

#[deriving_eq]
#[auto_encode]
#[auto_decode]
struct WorkKey {
    kind: ~str,
    name: ~str
}

impl to_bytes::IterBytes for WorkKey {
    #[inline(always)]
    pure fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) {
        let mut flag = true;
        self.kind.iter_bytes(lsb0, |bytes| {flag = f(bytes); flag});
        if !flag { return; }
        self.name.iter_bytes(lsb0, f);
    }
}

impl cmp::Ord for WorkKey {
    pure fn lt(&self, other: &WorkKey) -> bool {
        self.kind < other.kind ||
            (self.kind == other.kind &&
             self.name < other.name)
    }
    pure fn le(&self, other: &WorkKey) -> bool {
        self.lt(other) || self.eq(other)
    }
    pure fn ge(&self, other: &WorkKey) -> bool {
        self.gt(other) || self.eq(other)
    }
    pure fn gt(&self, other: &WorkKey) -> bool {
        ! self.le(other)
    }
}

pub impl WorkKey {
    static fn new(kind: &str, name: &str) -> WorkKey {
    WorkKey { kind: kind.to_owned(), name: name.to_owned() }
    }
}

type WorkMap = LinearMap<WorkKey, ~str>;

impl<S:Encoder> Encodable<S> for WorkMap {
    fn encode(&self, s: &S) {
        let mut d = ~[];
        for self.each |&(k, v)| {
            d.push((copy *k, copy *v))
        }
        sort::tim_sort(d);
        d.encode(s)
    }
}

impl<D:Decoder> Decodable<D> for WorkMap {
    static fn decode(&self, d: &D) -> WorkMap {
        let v : ~[(WorkKey,~str)] = Decodable::decode(d);
        let mut w = LinearMap::new();
        for v.each |&(k, v)| {
            w.insert(copy k, copy v);
        }
        w
    }
}

struct Database {
    db_filename: Path,
    db_cache: LinearMap<~str, ~str>,
    mut db_dirty: bool
}

pub impl Database {
    fn prepare(&mut self, fn_name: &str,
               declared_inputs: &WorkMap) -> Option<(WorkMap, WorkMap, ~str)>
    {
        let k = json_encode(&(fn_name, declared_inputs));
        match self.db_cache.find(&k) {
            None => None,
            Some(v) => Some(json_decode(*v))
        }
    }

    fn cache(&mut self,
             fn_name: &str,
             declared_inputs: &WorkMap,
             discovered_inputs: &WorkMap,
             discovered_outputs: &WorkMap,
             result: &str) {
        let k = json_encode(&(fn_name, declared_inputs));
        let v = json_encode(&(discovered_inputs,
                              discovered_outputs,
                              result));
        self.db_cache.insert(k,v);
        self.db_dirty = true
    }
}

struct Logger {
    // FIXME #4432: Fill in
    a: ()
}

pub impl Logger {
    fn info(i: &str) {
        io::println(~"workcache: " + i.to_owned());
    }
}

struct Context {
    db: @Mut<Database>,
    logger: @Mut<Logger>,
    cfg: @json::Object,
    freshness: LinearMap<~str,@fn(&str,&str)->bool>
}

struct Prep {
    ctxt: @Context,
    fn_name: ~str,
    declared_inputs: WorkMap,
}

struct Exec {
    discovered_inputs: WorkMap,
    discovered_outputs: WorkMap
}

struct Work<T> {
    prep: @Mut<Prep>,
    res: Option<Either<T,PortOne<(Exec,T)>>>
}

fn json_encode<T:Encodable<json::Encoder>>(t: &T) -> ~str {
    do io::with_str_writer |wr| {
        t.encode(&json::Encoder(wr));
    }
}

fn json_decode<T:Decodable<json::Decoder>>(s: &str) -> T {
    do io::with_str_reader(s) |rdr| {
        let j = result::unwrap(json::from_reader(rdr));
        Decodable::decode(&json::Decoder(j))
    }
}

fn digest<T:Encodable<json::Encoder>>(t: &T) -> ~str {
    let mut sha = sha1::sha1();
    sha.input_str(json_encode(t));
    sha.result_str()
}

fn digest_file(path: &Path) -> ~str {
    let mut sha = sha1::sha1();
    let s = io::read_whole_file_str(path);
    sha.input_str(*s.get_ref());
    sha.result_str()
}

pub impl Context {

    static fn new(db: @Mut<Database>,
                  lg: @Mut<Logger>,
                  cfg: @json::Object) -> Context {
        Context{db: db, logger: lg, cfg: cfg, freshness: LinearMap::new()}
    }

    fn prep<T:Owned + Encodable<json::Encoder> + Decodable<json::Decoder>>(
                  @self,
                  fn_name:&str,
                  blk: fn(@Mut<Prep>)->Work<T>) -> Work<T> {
        let p = @Mut(Prep {ctxt: self,
                           fn_name: fn_name.to_owned(),
                           declared_inputs: LinearMap::new()});
        blk(p)
    }
}

trait TPrep {
    fn declare_input(&self, kind:&str, name:&str, val:&str);
    fn is_fresh(&self, cat:&str, kind:&str, name:&str, val:&str) -> bool;
    fn all_fresh(&self, cat:&str, map:&WorkMap) -> bool;
    fn exec<T:Owned + Encodable<json::Encoder> + Decodable<json::Decoder>>(
        &self, blk: ~fn(&Exec) -> T) -> Work<T>;
}

impl TPrep for @Mut<Prep> {
    fn declare_input(&self, kind:&str, name:&str, val:&str) {
        do self.borrow_mut |p| {
            p.declared_inputs.insert(WorkKey::new(kind, name),
                                     val.to_owned());
        }
    }

    fn is_fresh(&self, cat: &str, kind: &str,
                name: &str, val: &str) -> bool {
        do self.borrow_imm |p| {
            let k = kind.to_owned();
            let f = (*p.ctxt.freshness.get(&k))(name, val);
            do p.ctxt.logger.borrow_imm |lg| {
                if f {
                    lg.info(fmt!("%s %s:%s is fresh",
                                 cat, kind, name));
                } else {
                    lg.info(fmt!("%s %s:%s is not fresh",
                                 cat, kind, name))
                }
            }
            f
        }
    }

    fn all_fresh(&self, cat: &str, map: &WorkMap) -> bool {
        for map.each |&(k, v)| {
            if ! self.is_fresh(cat, k.kind, k.name, *v) {
                return false;
            }
        }
        return true;
    }

    fn exec<T:Owned + Encodable<json::Encoder> + Decodable<json::Decoder>>(
            &self, blk: ~fn(&Exec) -> T) -> Work<T> {
        let mut bo = Some(blk);

        do self.borrow_imm |p| {
            let cached = do p.ctxt.db.borrow_mut |db| {
                db.prepare(p.fn_name, &p.declared_inputs)
            };

            match cached {
                Some((ref disc_in, ref disc_out, ref res))
                if self.all_fresh("declared input",
                                  &p.declared_inputs) &&
                self.all_fresh("discovered input", disc_in) &&
                self.all_fresh("discovered output", disc_out) => {
                    Work::new(*self, Left(json_decode(*res)))
                }

                _ => {
                    let (chan, port) = oneshot::init();
                    let mut blk = None;
                    blk <-> bo;
                    let blk = blk.unwrap();
                    let chan = Cell(chan);
                    do task::spawn || {
                        let exe = Exec{discovered_inputs: LinearMap::new(),
                                       discovered_outputs: LinearMap::new()};
                        let chan = chan.take();
                        let v = blk(&exe);
                        send_one(chan, (exe, v));
                    }

                    Work::new(*self, Right(port))
                }
            }
        }
    }
}

pub impl<T:Owned+Encodable<json::Encoder>+Decodable<json::Decoder>> Work<T> {
    static fn new(p: @Mut<Prep>, e: Either<T,PortOne<(Exec,T)>>) -> Work<T> {
        Work { prep: p, res: Some(e) }
    }
}

// FIXME (#3724): movable self. This should be in impl Work.
fn unwrap<T:Owned + Encodable<json::Encoder> + Decodable<json::Decoder>>(
        w: Work<T>) -> T {
    let mut ww = w;
    let mut s = None;

    ww.res <-> s;

    match s {
        None => fail!(),
        Some(Left(v)) => v,
        Some(Right(port)) => {
            let (exe, v) = match recv(port) {
                oneshot::send(data) => data
            };

            let s = json_encode(&v);

            do ww.prep.borrow_imm |p| {
                do p.ctxt.db.borrow_mut |db| {
                    db.cache(p.fn_name,
                             &p.declared_inputs,
                             &exe.discovered_inputs,
                             &exe.discovered_outputs,
                             s);
                }
            }
            v
        }
    }
}

//#[test]
fn test() {
    use core::io::WriterUtil;

    let db = @Mut(Database { db_filename: Path("db.json"),
                             db_cache: LinearMap::new(),
                             db_dirty: false });
    let lg = @Mut(Logger { a: () });
    let cfg = @LinearMap::new();
    let cx = @Context::new(db, lg, cfg);
    let w:Work<~str> = do cx.prep("test1") |prep| {
        let pth = Path("foo.c");
        {
            let file = io::file_writer(&pth, [io::Create]).get();
            file.write_str("int main() { return 0; }");
        }

        prep.declare_input("file", pth.to_str(), digest_file(&pth));
        do prep.exec |_exe| {
            let out = Path("foo.o");
            run::run_program("gcc", [~"foo.c", ~"-o", out.to_str()]);
            out.to_str()
        }
    };
    let s = unwrap(w);
    io::println(s);
}
<|endoftext|>


<commit_before>iface to_str {
    fn to_str() -> str;
}
impl of to_str for int {
    fn to_str() -> str { int::str(self) }
}
impl of to_str for str {
    fn to_str() -> str { self }
}

iface map<T> {
    fn map<U>(f: block(T) -> U) -> [U];
}
impl <T> of map<T> for [T] {
    fn map<U>(f: block(T) -> U) -> [U] {
        let r = [];
        for x in self { r += [f(x)]; }
        r
    }
}

fn foo<U, T: map<U>>(x: T) -> [str] {
    x.map({|_e| "hi" })
}
fn bar<U: to_str, T: map<U>>(x: T) -> [str] {
    x.map({|_e| _e.to_str() })
}

fn main() {
    assert foo([1]) == ["hi"];
    assert bar::<int, [int]>([4, 5]) == ["4", "5"];
    assert bar::<str, [str]>(["x", "y"]) == ["x", "y"];
}
<commit_msg>xfail-pretty iface-generic.rs until i have time to debug<commit_after>// xfail-pretty

iface to_str {
    fn to_str() -> str;
}
impl of to_str for int {
    fn to_str() -> str { int::str(self) }
}
impl of to_str for str {
    fn to_str() -> str { self }
}

iface map<T> {
    fn map<U>(f: block(T) -> U) -> [U];
}
impl <T> of map<T> for [T] {
    fn map<U>(f: block(T) -> U) -> [U] {
        let r = [];
        for x in self { r += [f(x)]; }
        r
    }
}

fn foo<U, T: map<U>>(x: T) -> [str] {
    x.map({|_e| "hi" })
}
fn bar<U: to_str, T: map<U>>(x: T) -> [str] {
    x.map({|_e| _e.to_str() })
}

fn main() {
    assert foo([1]) == ["hi"];
    assert bar::<int, [int]>([4, 5]) == ["4", "5"];
    assert bar::<str, [str]>(["x", "y"]) == ["x", "y"];
}
<|endoftext|>


<commit_before>// Passing enums by value

enum void { }

#[nolink]
native mod bindgen {
    fn printf(++v: void);
}

fn main() { }
<commit_msg>test: xfail-win32 run-pass/native-struct<commit_after>// xfail-win32
// Passing enums by value

enum void { }

#[nolink]
native mod bindgen {
    fn printf(++v: void);
}

fn main() { }
<|endoftext|>


<commit_before><commit_msg>Add hello world server example<commit_after>extern crate clap;
extern crate fibers;
extern crate futures;
extern crate miasht;

use fibers::{Executor, ThreadPoolExecutor};
use futures::{Future, BoxFuture};
use miasht::{Server, Status};
use miasht::builtin::servers::{SimpleHttpServer, RawConnection};
use miasht::builtin::headers::ContentLength;
use miasht::builtin::FutureExt;

fn main() {
    let mut executor = ThreadPoolExecutor::new().unwrap();
    let addr = "0.0.0.0:3000".parse().unwrap();
    let server = SimpleHttpServer::new((), echo);
    let server = server.start(addr, executor.handle());
    let monitor = executor.spawn_monitor(server.join());
    let result = executor.run_fiber(monitor).unwrap();
    println!("HTTP Server shutdown: {:?}", result);
}

fn echo(_: (), connection: RawConnection) -> BoxFuture<(), ()> {
    connection.read_request()
        .and_then(|request| {
            let bytes = b"Hello, World";
            let connection = request.finish();
            let mut response = connection.build_response(Status::Ok);
            response.add_header(&ContentLength(bytes.len() as u64));
            response.finish().write_all_bytes(bytes).then(|_| Ok(()))
        })
        .map_err(|e| {
            println!("Error: {:?}", e);
            ()
        })
        .boxed()
}
<|endoftext|>


<commit_before><commit_msg>Implement hashing for trie metadata.<commit_after>use std::fmt::Debug;
use std::hash::{Hash, Hasher, SipHasher};

#[derive(Debug,PartialEq,Eq,Clone)]
pub enum IFreq {
    Never,
    Depth(u64, u64),
    First(u64),
    Const(u64),
}

impl Hash for IFreq {
    fn hash<H: Hasher>(&self, state: &mut H) {
        match *self {
            IFreq::Never => {
                "Adapton.Trie.Meta.Freq#Never".hash(state);
            },
            IFreq::Depth(i, j) => {
                "Adapton.Trie.Meta.Freq#Depth".hash(state);
                i.hash(state);
                j.hash(state);
            },
            IFreq::First(n) => {
                "Adapton.Trie.Meta.Freq#First".hash(state);
                n.hash(state);
            },
            IFreq::Const(i) => {
                "Adapton.Trie.Meta.Freq#Const".hash(state);
                i.hash(state);
            },
        }
    }
}

#[derive(Debug,PartialEq,Eq,Hash,Clone)]
pub struct Meta {
    min_depth: u64,
    ifreq: IFreq,
}

pub trait MetaT {
    fn hash_seeded(&self, u64);
}

impl MetaT for Meta {
    fn hash_seeded(&self, seed:u64) {
        let mut hasher = SipHasher::new_with_keys(0, seed);
        "Adapton.Trie.Meta".hash(&mut hasher);
        self.min_depth.hash(&mut hasher);
        self.ifreq.hash(&mut hasher);
    }
}
<|endoftext|>


<commit_before><commit_msg>Implement some tests for zipper::Nth<commit_after><|endoftext|>


<commit_before>type fields<T> = @{
    mut parent: option<T>,
    mut first_child: option<T>,
    mut last_child: option<T>,
    mut prev_sibling: option<T>,
    mut next_sibling: option<T>
};

iface tree {
    fn tree_fields() -> fields<self>;
}

fn each_child<T:copy tree>(
    node: T, f: fn(T) -> bool) {

    let mut p = node.tree_fields().first_child;
    loop {
        alt p {
          none { ret; }
          some(c) {
            if !f(c) { ret; }
            p = c.tree_fields().next_sibling;
          }
        }
    }
}

fn empty<T>() -> fields<T> {
    @{mut parent: none,
      mut first_child: none,
      mut last_child: none,
      mut prev_sibling: none,
      mut next_sibling: none}
}

fn add_child<T:copy tree>(
    node: T, child: T) {

    let child_tf = child.tree_fields();
    alt child_tf.parent {
      some(_) { fail "Already has a parent"; }
      none { child_tf.parent = some(node); }
    }

    assert child_tf.prev_sibling == none;
    assert child_tf.next_sibling == none;

    let node_tf = node.tree_fields();
    alt node_tf.last_child {
      none {
        node_tf.first_child = some(child);
      }

      some(lc) {
        let lc_tf = lc.tree_fields();
        assert lc_tf.next_sibling == none;
        lc_tf.next_sibling = some(child);
        child_tf.prev_sibling = some(lc);
      }
    }

    node_tf.last_child = some(child);
}

#[cfg(test)]
mod test {
    enum dummy = @{
        fields: fields<dummy>,
        value: uint
    };

    impl of tree for dummy {
        fn tree_fields() -> fields<dummy> { self.fields }
    }

    fn new_dummy(v: uint) -> dummy {
        dummy(@{fields: empty(), value: v})
    }

    #[test]
    fn add_child_0() {
        let children = [new_dummy(0u),
                        new_dummy(1u),
                        new_dummy(2u)];
        let p = new_dummy(3u);

        for vec::each(children) {|c|
            add_child(p, c);
        }

        let mut i = 0u;
        for each_child(p) {|c|
            assert c.value == i;
            i += 1u;
        }
        assert i == children.len();
    }
}<commit_msg>add a rather silly second test<commit_after>type fields<T> = @{
    mut parent: option<T>,
    mut first_child: option<T>,
    mut last_child: option<T>,
    mut prev_sibling: option<T>,
    mut next_sibling: option<T>
};

iface tree {
    fn tree_fields() -> fields<self>;
}

fn each_child<T:copy tree>(
    node: T, f: fn(T) -> bool) {

    let mut p = node.tree_fields().first_child;
    loop {
        alt p {
          none { ret; }
          some(c) {
            if !f(c) { ret; }
            p = c.tree_fields().next_sibling;
          }
        }
    }
}

fn empty<T>() -> fields<T> {
    @{mut parent: none,
      mut first_child: none,
      mut last_child: none,
      mut prev_sibling: none,
      mut next_sibling: none}
}

fn add_child<T:copy tree>(
    node: T, child: T) {

    let child_tf = child.tree_fields();
    alt child_tf.parent {
      some(_) { fail "Already has a parent"; }
      none { child_tf.parent = some(node); }
    }

    assert child_tf.prev_sibling == none;
    assert child_tf.next_sibling == none;

    let node_tf = node.tree_fields();
    alt node_tf.last_child {
      none {
        node_tf.first_child = some(child);
      }

      some(lc) {
        let lc_tf = lc.tree_fields();
        assert lc_tf.next_sibling == none;
        lc_tf.next_sibling = some(child);
        child_tf.prev_sibling = some(lc);
      }
    }

    node_tf.last_child = some(child);
}

#[cfg(test)]
mod test {
    enum dummy = @{
        fields: fields<dummy>,
        value: uint
    };

    impl of tree for dummy {
        fn tree_fields() -> fields<dummy> { self.fields }
    }

    fn new_dummy(v: uint) -> dummy {
        dummy(@{fields: empty(), value: v})
    }

    fn parent_with_3_children() -> {p: dummy, children: [dummy]} {
        let children = [new_dummy(0u),
                        new_dummy(1u),
                        new_dummy(2u)];
        let p = new_dummy(3u);

        for vec::each(children) {|c|
            add_child(p, c);
        }

        ret {p: p, children: children};
    }

    #[test]
    fn add_child_0() {
        let {p, children} = parent_with_3_children();
        let mut i = 0u;
        for each_child(p) {|c|
            assert c.value == i;
            i += 1u;
        }
        assert i == children.len();
    }

    #[test]
    fn add_child_break() {
        let {p, _} = parent_with_3_children();
        let mut i = 0u;
        for each_child(p) {|_c|
            i += 1u;
            break;
        }
        assert i == 1u;
    }
}<|endoftext|>


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

#![feature(thread_local, link_args, plugin, box_syntax, int_uint)]

#![allow(experimental, non_camel_case_types, unstable)]
#![deny(unused_imports, unused_variables, unused_mut)]

#[macro_use]
extern crate log;
#[plugin]
extern crate "plugins" as servo_plugins;

extern crate servo;
extern crate compositing;

extern crate azure;
extern crate geom;
extern crate gfx;
extern crate gleam;
extern crate glutin_app;
extern crate js;
extern crate layers;
extern crate png;
extern crate script;

extern crate "net" as servo_net;
extern crate "msg" as servo_msg;
extern crate util;
extern crate style;
extern crate stb_image;

extern crate libc;
extern crate "url" as std_url;

#[cfg(target_os="macos")]
extern crate cgl;
#[cfg(target_os="macos")]
extern crate cocoa;
#[cfg(target_os="macos")]
extern crate core_graphics;
#[cfg(target_os="macos")]
extern crate core_text;

// Must come first.
pub mod macros;

pub mod browser;
pub mod browser_host;
pub mod command_line;
pub mod cookie;
pub mod core;
pub mod drag_data;
pub mod eutil;
pub mod frame;
pub mod interfaces;
pub mod print_settings;
pub mod process_message;
pub mod render_handler;
pub mod request;
pub mod request_context;
pub mod response;
pub mod stream;
pub mod string;
pub mod string_list;
pub mod string_map;
pub mod string_multimap;
pub mod stubs;
pub mod switches;
pub mod task;
pub mod types;
pub mod urlrequest;
pub mod v8;
pub mod values;
pub mod window;
pub mod wrappers;
pub mod xml_reader;
pub mod zip_reader;
<commit_msg>auto merge of #4826 : mbrubeck/servo/cef_plugins, r=jdm<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#![feature(thread_local, link_args, plugin, box_syntax, int_uint)]

#![allow(experimental, non_camel_case_types, unstable)]
#![deny(unused_imports, unused_variables, unused_mut)]

#[macro_use]
extern crate log;
#[plugin] #[no_link]
extern crate "plugins" as servo_plugins;

extern crate servo;
extern crate compositing;

extern crate azure;
extern crate geom;
extern crate gfx;
extern crate gleam;
extern crate glutin_app;
extern crate js;
extern crate layers;
extern crate png;
extern crate script;

extern crate "net" as servo_net;
extern crate "msg" as servo_msg;
extern crate util;
extern crate style;
extern crate stb_image;

extern crate libc;
extern crate "url" as std_url;

#[cfg(target_os="macos")]
extern crate cgl;
#[cfg(target_os="macos")]
extern crate cocoa;
#[cfg(target_os="macos")]
extern crate core_graphics;
#[cfg(target_os="macos")]
extern crate core_text;

// Must come first.
pub mod macros;

pub mod browser;
pub mod browser_host;
pub mod command_line;
pub mod cookie;
pub mod core;
pub mod drag_data;
pub mod eutil;
pub mod frame;
pub mod interfaces;
pub mod print_settings;
pub mod process_message;
pub mod render_handler;
pub mod request;
pub mod request_context;
pub mod response;
pub mod stream;
pub mod string;
pub mod string_list;
pub mod string_map;
pub mod string_multimap;
pub mod stubs;
pub mod switches;
pub mod task;
pub mod types;
pub mod urlrequest;
pub mod v8;
pub mod values;
pub mod window;
pub mod wrappers;
pub mod xml_reader;
pub mod zip_reader;
<|endoftext|>


<commit_before>// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! Logging

use option::*;
use os;
use either::*;
use rt;
use rt::OldTaskContext;
use rt::logging::{Logger, StdErrLogger};

/// Turns on logging to stdout globally
pub fn console_on() {
    if rt::context() == OldTaskContext {
        unsafe {
            rustrt::rust_log_console_on();
        }
    } else {
        rt::logging::console_on();
    }
}

/**
 * Turns off logging to stdout globally
 *
 * Turns off the console unless the user has overridden the
 * runtime environment's logging spec, e.g. by setting
 * the RUST_LOG environment variable
 */
pub fn console_off() {
    // If RUST_LOG is set then the console can't be turned off
    if os::getenv("RUST_LOG").is_some() {
        return;
    }

    if rt::context() == OldTaskContext {
        unsafe {
            rustrt::rust_log_console_off();
        }
    } else {
        rt::logging::console_off();
    }
}

#[cfg(not(test))]
#[lang="log_type"]
#[allow(missing_doc)]
pub fn log_type<T>(level: u32, object: &T) {
    use cast;
    use container::Container;
    use io;
    use libc;
    use repr;
    use rt;
    use str;
    use vec;

    let bytes = do io::with_bytes_writer |writer| {
        repr::write_repr(writer, object);
    };

    match rt::context() {
        rt::OldTaskContext => {
            unsafe {
                let len = bytes.len() as libc::size_t;
                rustrt::rust_log_str(level, cast::transmute(vec::raw::to_ptr(bytes)), len);
            }
        }
        _ => {
            // XXX: Bad allocation
            let msg = str::from_bytes(bytes);
            newsched_log_str(msg);
        }
    }
}

fn newsched_log_str(msg: ~str) {
    use rt::task::Task;
    use rt::local::Local;
    use str::StrSlice;
    use container::Container;

    // Truncate the string
    let buf_bytes = 2048;
    let msg = if msg.len() > buf_bytes {
        msg.slice(0, buf_bytes) + "[...]"
    } else {
        msg
    };

    unsafe {
        match Local::try_unsafe_borrow::<Task>() {
            Some(local) => {
                // Use the available logger
                (*local).logger.log(Left(msg));
            }
            None => {
                // There is no logger anywhere, just write to stderr
                let mut logger = StdErrLogger;
                logger.log(Left(msg));
            }
        }
    }
}

pub mod rustrt {
    use libc;

    extern {
        pub fn rust_log_console_on();
        pub fn rust_log_console_off();
        pub fn rust_log_str(level: u32,
                            string: *libc::c_char,
                            size: libc::size_t);
    }
}
<commit_msg>fixed the buffer to make it a more reasonable size<commit_after>// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! Logging

use option::*;
use os;
use either::*;
use rt;
use rt::OldTaskContext;
use rt::logging::{Logger, StdErrLogger};

/// Turns on logging to stdout globally
pub fn console_on() {
    if rt::context() == OldTaskContext {
        unsafe {
            rustrt::rust_log_console_on();
        }
    } else {
        rt::logging::console_on();
    }
}

/**
 * Turns off logging to stdout globally
 *
 * Turns off the console unless the user has overridden the
 * runtime environment's logging spec, e.g. by setting
 * the RUST_LOG environment variable
 */
pub fn console_off() {
    // If RUST_LOG is set then the console can't be turned off
    if os::getenv("RUST_LOG").is_some() {
        return;
    }

    if rt::context() == OldTaskContext {
        unsafe {
            rustrt::rust_log_console_off();
        }
    } else {
        rt::logging::console_off();
    }
}

#[cfg(not(test))]
#[lang="log_type"]
#[allow(missing_doc)]
pub fn log_type<T>(level: u32, object: &T) {
    use cast;
    use container::Container;
    use io;
    use libc;
    use repr;
    use rt;
    use str;
    use vec;

    let bytes = do io::with_bytes_writer |writer| {
        repr::write_repr(writer, object);
    };

    match rt::context() {
        rt::OldTaskContext => {
            unsafe {
                let len = bytes.len() as libc::size_t;
                rustrt::rust_log_str(level, cast::transmute(vec::raw::to_ptr(bytes)), len);
            }
        }
        _ => {
            // XXX: Bad allocation
            let msg = str::from_bytes(bytes);
            newsched_log_str(msg);
        }
    }
}

fn newsched_log_str(msg: ~str) {
    use rt::task::Task;
    use rt::local::Local;
    use str::StrSlice;
    use container::Container;

    // Truncate the string
    let buf_bytes = 256;
    let msg = if msg.len() > buf_bytes {
        msg.slice(0, buf_bytes) + "[...]"
    } else {
        msg
    };

    unsafe {
        match Local::try_unsafe_borrow::<Task>() {
            Some(local) => {
                // Use the available logger
                (*local).logger.log(Left(msg));
            }
            None => {
                // There is no logger anywhere, just write to stderr
                let mut logger = StdErrLogger;
                logger.log(Left(msg));
            }
        }
    }
}

pub mod rustrt {
    use libc;

    extern {
        pub fn rust_log_console_on();
        pub fn rust_log_console_off();
        pub fn rust_log_str(level: u32,
                            string: *libc::c_char,
                            size: libc::size_t);
    }
}
<|endoftext|>


<commit_before>// Copyright 2013 The Servo Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#[macro_use] extern crate bitflags;
extern crate png;
extern crate test;
extern crate url;

use std::ascii::AsciiExt;
use std::old_io as io;
use std::old_io::{File, Reader, Command, IoResult};
use std::old_io::process::ExitStatus;
use std::old_io::fs::PathExtensions;
use std::old_path::Path;
use std::os;
use std::thunk::Thunk;
use test::{AutoColor, DynTestName, DynTestFn, TestDesc, TestOpts, TestDescAndFn, ShouldFail};
use test::run_tests_console;
use url::Url;

bitflags!(
    flags RenderMode: u32 {
        const CPU_RENDERING  = 0x00000001,
        const GPU_RENDERING  = 0x00000010,
        const LINUX_TARGET   = 0x00000100,
        const MACOS_TARGET   = 0x00001000,
        const ANDROID_TARGET = 0x00010000
    }
);

fn main() {
    let args = os::args();
    let mut parts = args.tail().split(|e| "--" == e.as_slice());

    let harness_args = parts.next().unwrap();  // .split() is never empty
    let servo_args = parts.next().unwrap_or(&[]);

    let (render_mode_string, base_path, testname) = match harness_args {
        [] | [_] => panic!("USAGE: cpu|gpu base_path [testname regex]"),
        [ref render_mode_string, ref base_path] => (render_mode_string, base_path, None),
        [ref render_mode_string, ref base_path, ref testname, ..] => (render_mode_string, base_path, Some(testname.clone())),
    };

    let mut render_mode = match render_mode_string.as_slice() {
        "cpu" => CPU_RENDERING,
        "gpu" => GPU_RENDERING,
        _ => panic!("First argument must specify cpu or gpu as rendering mode")
    };
    if cfg!(target_os = "linux") {
        render_mode.insert(LINUX_TARGET);
    }
    if cfg!(target_os = "macos") {
        render_mode.insert(MACOS_TARGET);
    }
    if cfg!(target_os = "android") {
        render_mode.insert(ANDROID_TARGET);
    }

    let mut all_tests = vec!();
    println!("Scanning {} for manifests\n", base_path);

    for file in io::fs::walk_dir(&Path::new(base_path.as_slice())).unwrap() {
        let maybe_extension = file.extension_str();
        match maybe_extension {
            Some(extension) => {
                if extension.to_ascii_lowercase().as_slice() == "list" && file.is_file() {
                    let tests = parse_lists(&file, servo_args, render_mode, all_tests.len());
                    println!("\t{} [{} tests]", file.display(), tests.len());
                    all_tests.extend(tests.into_iter());
                }
            }
            _ => {}
        }
    }

    let test_opts = TestOpts {
        filter: testname,
        run_ignored: false,
        logfile: None,
        run_tests: true,
        run_benchmarks: false,
        nocapture: false,
        color: AutoColor,
    };

    match run(test_opts,
              all_tests,
              servo_args.iter().map(|x| x.clone()).collect()) {
        Ok(false) => os::set_exit_status(1), // tests failed
        Err(_) => os::set_exit_status(2),    // I/O-related failure
        _ => (),
    }
}

fn run(test_opts: TestOpts, all_tests: Vec<TestDescAndFn>,
       servo_args: Vec<String>) -> IoResult<bool> {
    // Verify that we're passing in valid servo arguments. Otherwise, servo
    // will exit before we've run any tests, and it will appear to us as if
    // all the tests are failing.
    let mut command = match Command::new(os::self_exe_path().unwrap().join("servo"))
                            .args(servo_args.as_slice()).spawn() {
        Ok(p) => p,
        Err(e) => panic!("failed to execute process: {}", e),
    };
    let stderr = command.stderr.as_mut().unwrap().read_to_string().unwrap();

    if stderr.as_slice().contains("Unrecognized") {
        println!("Servo: {}", stderr.as_slice());
        return Ok(false);
    }

    run_tests_console(&test_opts, all_tests)
}

#[derive(PartialEq)]
enum ReftestKind {
    Same,
    Different,
}

struct Reftest {
    name: String,
    kind: ReftestKind,
    files: [Path; 2],
    id: uint,
    servo_args: Vec<String>,
    render_mode: RenderMode,
    is_flaky: bool,
    experimental: bool,
    fragment_identifier: Option<String>,
}

struct TestLine<'a> {
    conditions: &'a str,
    kind: &'a str,
    file_left: &'a str,
    file_right: &'a str,
}

fn parse_lists(file: &Path, servo_args: &[String], render_mode: RenderMode, id_offset: uint) -> Vec<TestDescAndFn> {
    let mut tests = Vec::new();
    let contents = File::open_mode(file, io::Open, io::Read)
                       .and_then(|mut f| f.read_to_string())
                       .ok().expect("Could not read file");

    for line in contents.as_slice().lines() {
        // ignore comments or empty lines
        if line.starts_with("#") || line.is_empty() {
            continue;
        }

        let parts: Vec<&str> = line.split(' ').filter(|p| !p.is_empty()).collect();

        let test_line = match parts.len() {
            3 => TestLine {
                conditions: "",
                kind: parts[0],
                file_left: parts[1],
                file_right: parts[2],
            },
            4 => TestLine {
                conditions: parts[0],
                kind: parts[1],
                file_left: parts[2],
                file_right: parts[3],
            },
            _ => panic!("reftest line: '{}' doesn't match '[CONDITIONS] KIND LEFT RIGHT'", line),
        };

        let kind = match test_line.kind {
            "==" => ReftestKind::Same,
            "!=" => ReftestKind::Different,
            part => panic!("reftest line: '{}' has invalid kind '{}'", line, part)
        };

        // If we're running this directly, file.dir_path() might be relative.
        // (see issue #3521)
        let base = match file.dir_path().is_relative() {
            true  => os::getcwd().unwrap().join(file.dir_path()),
            false => file.dir_path()
        };

        let file_left =  base.join(test_line.file_left);
        let file_right = base.join(test_line.file_right);

        let mut conditions_list = test_line.conditions.split(',');
        let mut flakiness = RenderMode::empty();
        let mut experimental = false;
        let mut fragment_identifier = None;
        for condition in conditions_list {
            match condition {
                "flaky_cpu" => flakiness.insert(CPU_RENDERING),
                "flaky_gpu" => flakiness.insert(GPU_RENDERING),
                "flaky_linux" => flakiness.insert(LINUX_TARGET),
                "flaky_macos" => flakiness.insert(MACOS_TARGET),
                "experimental" => experimental = true,
                _ => (),
            }
            if condition.starts_with("fragment=") {
                fragment_identifier = Some(condition.slice_from("fragment=".len()).to_string());
            }
        }

        let reftest = Reftest {
            name: format!("{} {} {}", test_line.file_left, test_line.kind, test_line.file_right),
            kind: kind,
            files: [file_left, file_right],
            id: id_offset + tests.len(),
            render_mode: render_mode,
            servo_args: servo_args.iter().map(|x| x.clone()).collect(),
            is_flaky: render_mode.intersects(flakiness),
            experimental: experimental,
            fragment_identifier: fragment_identifier,
        };

        tests.push(make_test(reftest));
    }
    tests
}

fn make_test(reftest: Reftest) -> TestDescAndFn {
    let name = reftest.name.clone();
    TestDescAndFn {
        desc: TestDesc {
            name: DynTestName(name),
            ignore: false,
            should_fail: ShouldFail::No,
        },
        testfn: DynTestFn(Thunk::new(move || {
            check_reftest(reftest);
        })),
    }
}

fn capture(reftest: &Reftest, side: uint) -> (u32, u32, Vec<u8>) {
    let png_filename = format!("/tmp/servo-reftest-{:06}-{}.png", reftest.id, side);
    let mut command = Command::new(os::self_exe_path().unwrap().join("servo"));
    command
        .args(reftest.servo_args.as_slice())
        // Allows pixel perfect rendering of Ahem font for reftests.
        .arg("-Z")
        .arg("disable-text-aa")
        .args(["-f", "-o"].as_slice())
        .arg(png_filename.as_slice())
        .arg({
            let mut url = Url::from_file_path(&reftest.files[side]).unwrap();
            url.fragment = reftest.fragment_identifier.clone();
            url.to_string()
        });
    // CPU rendering is the default
    if reftest.render_mode.contains(CPU_RENDERING) {
        command.arg("-c");
    }
    if reftest.render_mode.contains(GPU_RENDERING) {
        command.arg("-g");
    }
    if reftest.experimental {
        command.arg("--experimental");
    }
    let retval = match command.status() {
        Ok(status) => status,
        Err(e) => panic!("failed to execute process: {}", e),
    };
    assert_eq!(retval, ExitStatus(0));

    let path = png_filename.parse::<Path>().unwrap();
    let image = png::load_png(&path).unwrap();
    let rgba8_bytes = match image.pixels {
        png::PixelsByColorType::RGBA8(pixels) => pixels,
        _ => panic!(),
    };
    (image.width, image.height, rgba8_bytes)
}

fn check_reftest(reftest: Reftest) {
    let (left_width, left_height, left_bytes) = capture(&reftest, 0);
    let (right_width, right_height, right_bytes) = capture(&reftest, 1);

    assert_eq!(left_width, right_width);
    assert_eq!(left_height, right_height);

    let left_all_white = left_bytes.iter().all(|&p| p == 255);
    let right_all_white = right_bytes.iter().all(|&p| p == 255);

    if left_all_white && right_all_white {
        panic!("Both renderings are empty")
    }

    let pixels = left_bytes.iter().zip(right_bytes.iter()).map(|(&a, &b)| {
        if a as i8 - b as i8 == 0 {
            // White for correct
            0xFF
        } else {
            // "1100" in the RGBA channel with an error for an incorrect value
            // This results in some number of C0 and FFs, which is much more
            // readable (and distinguishable) than the previous difference-wise
            // scaling but does not require reconstructing the actual RGBA pixel.
            0xC0
        }
    }).collect::<Vec<u8>>();

    if pixels.iter().any(|&a| a < 255) {
        let output_str = format!("/tmp/servo-reftest-{:06}-diff.png", reftest.id);
        let output = output_str.parse::<Path>().unwrap();

        let mut img = png::Image {
            width: left_width,
            height: left_height,
            pixels: png::PixelsByColorType::RGBA8(pixels),
        };
        let res = png::store_png(&mut img, &output);
        assert!(res.is_ok());

        match (reftest.kind, reftest.is_flaky) {
            (ReftestKind::Same, true) => println!("flaky test - rendering difference: {}", output_str),
            (ReftestKind::Same, false) => panic!("rendering difference: {}", output_str),
            (ReftestKind::Different, _) => {}   // Result was different and that's what was expected
        }
    } else {
        assert!(reftest.is_flaky || reftest.kind == ReftestKind::Same);
    }
}
<commit_msg>auto merge of #5136 : iamdanfox/servo/replace-uint-with-usize, r=metajack<commit_after>// Copyright 2013 The Servo Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#[macro_use] extern crate bitflags;
extern crate png;
extern crate test;
extern crate url;

use std::ascii::AsciiExt;
use std::old_io as io;
use std::old_io::{File, Reader, Command, IoResult};
use std::old_io::process::ExitStatus;
use std::old_io::fs::PathExtensions;
use std::old_path::Path;
use std::os;
use std::thunk::Thunk;
use test::{AutoColor, DynTestName, DynTestFn, TestDesc, TestOpts, TestDescAndFn, ShouldFail};
use test::run_tests_console;
use url::Url;

bitflags!(
    flags RenderMode: u32 {
        const CPU_RENDERING  = 0x00000001,
        const GPU_RENDERING  = 0x00000010,
        const LINUX_TARGET   = 0x00000100,
        const MACOS_TARGET   = 0x00001000,
        const ANDROID_TARGET = 0x00010000
    }
);

fn main() {
    let args = os::args();
    let mut parts = args.tail().split(|e| "--" == e.as_slice());

    let harness_args = parts.next().unwrap();  // .split() is never empty
    let servo_args = parts.next().unwrap_or(&[]);

    let (render_mode_string, base_path, testname) = match harness_args {
        [] | [_] => panic!("USAGE: cpu|gpu base_path [testname regex]"),
        [ref render_mode_string, ref base_path] => (render_mode_string, base_path, None),
        [ref render_mode_string, ref base_path, ref testname, ..] => (render_mode_string, base_path, Some(testname.clone())),
    };

    let mut render_mode = match render_mode_string.as_slice() {
        "cpu" => CPU_RENDERING,
        "gpu" => GPU_RENDERING,
        _ => panic!("First argument must specify cpu or gpu as rendering mode")
    };
    if cfg!(target_os = "linux") {
        render_mode.insert(LINUX_TARGET);
    }
    if cfg!(target_os = "macos") {
        render_mode.insert(MACOS_TARGET);
    }
    if cfg!(target_os = "android") {
        render_mode.insert(ANDROID_TARGET);
    }

    let mut all_tests = vec!();
    println!("Scanning {} for manifests\n", base_path);

    for file in io::fs::walk_dir(&Path::new(base_path.as_slice())).unwrap() {
        let maybe_extension = file.extension_str();
        match maybe_extension {
            Some(extension) => {
                if extension.to_ascii_lowercase().as_slice() == "list" && file.is_file() {
                    let tests = parse_lists(&file, servo_args, render_mode, all_tests.len());
                    println!("\t{} [{} tests]", file.display(), tests.len());
                    all_tests.extend(tests.into_iter());
                }
            }
            _ => {}
        }
    }

    let test_opts = TestOpts {
        filter: testname,
        run_ignored: false,
        logfile: None,
        run_tests: true,
        run_benchmarks: false,
        nocapture: false,
        color: AutoColor,
    };

    match run(test_opts,
              all_tests,
              servo_args.iter().map(|x| x.clone()).collect()) {
        Ok(false) => os::set_exit_status(1), // tests failed
        Err(_) => os::set_exit_status(2),    // I/O-related failure
        _ => (),
    }
}

fn run(test_opts: TestOpts, all_tests: Vec<TestDescAndFn>,
       servo_args: Vec<String>) -> IoResult<bool> {
    // Verify that we're passing in valid servo arguments. Otherwise, servo
    // will exit before we've run any tests, and it will appear to us as if
    // all the tests are failing.
    let mut command = match Command::new(os::self_exe_path().unwrap().join("servo"))
                            .args(servo_args.as_slice()).spawn() {
        Ok(p) => p,
        Err(e) => panic!("failed to execute process: {}", e),
    };
    let stderr = command.stderr.as_mut().unwrap().read_to_string().unwrap();

    if stderr.as_slice().contains("Unrecognized") {
        println!("Servo: {}", stderr.as_slice());
        return Ok(false);
    }

    run_tests_console(&test_opts, all_tests)
}

#[derive(PartialEq)]
enum ReftestKind {
    Same,
    Different,
}

struct Reftest {
    name: String,
    kind: ReftestKind,
    files: [Path; 2],
    id: usize,
    servo_args: Vec<String>,
    render_mode: RenderMode,
    is_flaky: bool,
    experimental: bool,
    fragment_identifier: Option<String>,
}

struct TestLine<'a> {
    conditions: &'a str,
    kind: &'a str,
    file_left: &'a str,
    file_right: &'a str,
}

fn parse_lists(file: &Path, servo_args: &[String], render_mode: RenderMode, id_offset: usize) -> Vec<TestDescAndFn> {
    let mut tests = Vec::new();
    let contents = File::open_mode(file, io::Open, io::Read)
                       .and_then(|mut f| f.read_to_string())
                       .ok().expect("Could not read file");

    for line in contents.as_slice().lines() {
        // ignore comments or empty lines
        if line.starts_with("#") || line.is_empty() {
            continue;
        }

        let parts: Vec<&str> = line.split(' ').filter(|p| !p.is_empty()).collect();

        let test_line = match parts.len() {
            3 => TestLine {
                conditions: "",
                kind: parts[0],
                file_left: parts[1],
                file_right: parts[2],
            },
            4 => TestLine {
                conditions: parts[0],
                kind: parts[1],
                file_left: parts[2],
                file_right: parts[3],
            },
            _ => panic!("reftest line: '{}' doesn't match '[CONDITIONS] KIND LEFT RIGHT'", line),
        };

        let kind = match test_line.kind {
            "==" => ReftestKind::Same,
            "!=" => ReftestKind::Different,
            part => panic!("reftest line: '{}' has invalid kind '{}'", line, part)
        };

        // If we're running this directly, file.dir_path() might be relative.
        // (see issue #3521)
        let base = match file.dir_path().is_relative() {
            true  => os::getcwd().unwrap().join(file.dir_path()),
            false => file.dir_path()
        };

        let file_left =  base.join(test_line.file_left);
        let file_right = base.join(test_line.file_right);

        let mut conditions_list = test_line.conditions.split(',');
        let mut flakiness = RenderMode::empty();
        let mut experimental = false;
        let mut fragment_identifier = None;
        for condition in conditions_list {
            match condition {
                "flaky_cpu" => flakiness.insert(CPU_RENDERING),
                "flaky_gpu" => flakiness.insert(GPU_RENDERING),
                "flaky_linux" => flakiness.insert(LINUX_TARGET),
                "flaky_macos" => flakiness.insert(MACOS_TARGET),
                "experimental" => experimental = true,
                _ => (),
            }
            if condition.starts_with("fragment=") {
                fragment_identifier = Some(condition.slice_from("fragment=".len()).to_string());
            }
        }

        let reftest = Reftest {
            name: format!("{} {} {}", test_line.file_left, test_line.kind, test_line.file_right),
            kind: kind,
            files: [file_left, file_right],
            id: id_offset + tests.len(),
            render_mode: render_mode,
            servo_args: servo_args.iter().map(|x| x.clone()).collect(),
            is_flaky: render_mode.intersects(flakiness),
            experimental: experimental,
            fragment_identifier: fragment_identifier,
        };

        tests.push(make_test(reftest));
    }
    tests
}

fn make_test(reftest: Reftest) -> TestDescAndFn {
    let name = reftest.name.clone();
    TestDescAndFn {
        desc: TestDesc {
            name: DynTestName(name),
            ignore: false,
            should_fail: ShouldFail::No,
        },
        testfn: DynTestFn(Thunk::new(move || {
            check_reftest(reftest);
        })),
    }
}

fn capture(reftest: &Reftest, side: usize) -> (u32, u32, Vec<u8>) {
    let png_filename = format!("/tmp/servo-reftest-{:06}-{}.png", reftest.id, side);
    let mut command = Command::new(os::self_exe_path().unwrap().join("servo"));
    command
        .args(reftest.servo_args.as_slice())
        // Allows pixel perfect rendering of Ahem font for reftests.
        .arg("-Z")
        .arg("disable-text-aa")
        .args(["-f", "-o"].as_slice())
        .arg(png_filename.as_slice())
        .arg({
            let mut url = Url::from_file_path(&reftest.files[side]).unwrap();
            url.fragment = reftest.fragment_identifier.clone();
            url.to_string()
        });
    // CPU rendering is the default
    if reftest.render_mode.contains(CPU_RENDERING) {
        command.arg("-c");
    }
    if reftest.render_mode.contains(GPU_RENDERING) {
        command.arg("-g");
    }
    if reftest.experimental {
        command.arg("--experimental");
    }
    let retval = match command.status() {
        Ok(status) => status,
        Err(e) => panic!("failed to execute process: {}", e),
    };
    assert_eq!(retval, ExitStatus(0));

    let path = png_filename.parse::<Path>().unwrap();
    let image = png::load_png(&path).unwrap();
    let rgba8_bytes = match image.pixels {
        png::PixelsByColorType::RGBA8(pixels) => pixels,
        _ => panic!(),
    };
    (image.width, image.height, rgba8_bytes)
}

fn check_reftest(reftest: Reftest) {
    let (left_width, left_height, left_bytes) = capture(&reftest, 0);
    let (right_width, right_height, right_bytes) = capture(&reftest, 1);

    assert_eq!(left_width, right_width);
    assert_eq!(left_height, right_height);

    let left_all_white = left_bytes.iter().all(|&p| p == 255);
    let right_all_white = right_bytes.iter().all(|&p| p == 255);

    if left_all_white && right_all_white {
        panic!("Both renderings are empty")
    }

    let pixels = left_bytes.iter().zip(right_bytes.iter()).map(|(&a, &b)| {
        if a as i8 - b as i8 == 0 {
            // White for correct
            0xFF
        } else {
            // "1100" in the RGBA channel with an error for an incorrect value
            // This results in some number of C0 and FFs, which is much more
            // readable (and distinguishable) than the previous difference-wise
            // scaling but does not require reconstructing the actual RGBA pixel.
            0xC0
        }
    }).collect::<Vec<u8>>();

    if pixels.iter().any(|&a| a < 255) {
        let output_str = format!("/tmp/servo-reftest-{:06}-diff.png", reftest.id);
        let output = output_str.parse::<Path>().unwrap();

        let mut img = png::Image {
            width: left_width,
            height: left_height,
            pixels: png::PixelsByColorType::RGBA8(pixels),
        };
        let res = png::store_png(&mut img, &output);
        assert!(res.is_ok());

        match (reftest.kind, reftest.is_flaky) {
            (ReftestKind::Same, true) => println!("flaky test - rendering difference: {}", output_str),
            (ReftestKind::Same, false) => panic!("rendering difference: {}", output_str),
            (ReftestKind::Different, _) => {}   // Result was different and that's what was expected
        }
    } else {
        assert!(reftest.is_flaky || reftest.kind == ReftestKind::Same);
    }
}
<|endoftext|>


<commit_before><commit_msg>Moved audio_unit::Type and the various subtypes into their own module.<commit_after>//! Core Audio's various const audio unit types identifiers represented as typesafe enums.
//!
//! Oirginal documentation [here](https://developer.apple.com/library/prerelease/mac/documentation/AudioUnit/Reference/AUComponentServicesReference/index.html#//apple_ref/doc/constant_group/Audio_Unit_Types).

/// Represents the different kinds of Audio Units that are available.
///
/// Original documentation [here](https://developer.apple.com/library/prerelease/mac/documentation/AudioUnit/Reference/AUComponentServicesReference/index.html#//apple_ref/doc/constant_group/Audio_Unit_Types).
#[derive(Copy, Clone, Debug)]
pub enum Type {
    /// Provides input, output, or both input and output simultaneously.
    ///
    /// It can be used as the head of an audio unit processing graph.
    ///
    /// **Available** in OS X v10.2 and later.
    IO(IOType),
    /// An instrument unit can be used as a software musical instrument, such as a sampler or
    /// synthesizer.
    ///
    /// It responds to MIDI (Musical Instrument Digital Interface) control signals and can create
    /// notes.
    ///
    /// **Available** in OS X v10.2 and later.
    MusicDevice(MusicDeviceType),
    /// An effect unit that can respond to MIDI control messages, typically through a mapping of
    /// MIDI messages to parameters of the audio unit's DSP algorithm.
    ///
    /// **Available** in OS X v10.2 and later.
    MusicEffect,
    /// A format converter unit can transform audio formats, such as performing sample rate
    /// conversion.
    ///
    /// A format converter is also appropriate for dferred rendering and for effects such as
    /// varispeed.
    ///
    /// A format converter unit can ask for as much or as little audio input as it needs to produce
    /// a given output, while still completing its rendering within the time represented by the
    /// output buffer.
    ///
    /// For effect-like format converters, such as pitch shifters, it is common to provide both a
    /// real-time and an offline version. OS X, for example, includes Time-Pitch and Varispeed
    /// audio units in both real-time and offline versions.
    ///
    /// **Available** in OS X v10.2 and later.
    FormatConverter(FormatConverterType),
    /// An effect unit repeatedly processes a number of audio input samples to produce the same
    /// number of audio output samples.
    ///
    /// Most commonly, an effect unit has a single input and a single output.
    ///
    /// Some effects take side-chain inputs as well.
    ///
    /// Effect units can be run offline, such as to process a file without playing it, but are
    /// expected to run in real-time.
    ///
    /// **Available** in OS X v10.2 and later.
    Effect(EffectType),
    /// A mixer unit takes a number of input channels and mixes them to provide one or more output
    /// channels.
    ///
    /// For example, the **StereoMixer** **SubType** in OS X takes multiple mono or stereo inputs
    /// and produces a single stereo output.
    ///
    /// **Available** in OS X v10.2 and later.
    Mixer(MixerType),
    /// A panner unit is a specialised effect unit that distributes one or more channels in a
    /// single input to one or more channels in a single output.
    ///
    /// Panner units must support a set of standard audio unit parameters that specify panning
    /// coordinates.
    ///
    /// **Available** in OS X v10.3 and later.
    Panner,
    /// A generator unit provides audio output that has no audio input.
    ///
    /// This audio unit type is appropriate for a tone generator.
    ///
    /// Unlike an instrument unit, a generator unit does not have a control input.
    ///
    /// **Available** in OS X v10.3 and later.
    Generator(GeneratorType),
    /// An offline effect unit provides digital signal processing of a sort that cannot proceed in
    /// real-time.
    ///
    /// For example, level normalisation requires examination of an entire sound, beginning to end,
    /// before the normalisation factor can be calculated.
    ///
    /// As such, offline effect units also have a notion of a priming stage that can be performed
    /// before the actual rendering/processing phase is executed.
    ///
    /// **Available** in OS X v10.3 and later.
    OfflineEffect,
    /// FIXME: Could not find any documenation for this type - it seems it was added very recently
    /// (around 2013) and Apple's documentation doesn't seem to have updated to include it.
    MidiProcessor,
}

impl Type {

    /// Convert the `Type` to its associated `u32` for compatibility with original API.
    pub fn to_u32(&self) -> u32 {
        match *self {
            Type::IO(_)              => 1635086197,
            Type::MusicDevice(_)     => 1635085685,
            Type::MusicEffect        => 1635085670,
            Type::FormatConverter(_) => 1635083875,
            Type::Effect(_)          => 1635083896,
            Type::Mixer(_)           => 1635085688,
            Type::Panner             => 1635086446,
            Type::Generator(_)       => 1635084142,
            Type::OfflineEffect      => 1635086188,
            Type::MidiProcessor      => 1635085673,
        }
    }

    /// Convert the `Type` to the const `u32` that is associated with its subtype.
    pub fn to_subtype_u32(&self) -> Option<u32> {
        match *self {
            Type::IO(ty)              => Some(ty as u32),
            Type::MusicDevice(ty)     => Some(ty as u32),
            Type::FormatConverter(ty) => Some(ty as u32),
            Type::Effect(ty)          => Some(ty as u32),
            Type::Mixer(ty)           => Some(ty as u32),
            Type::Generator(ty)       => Some(ty as u32),
            _ => None,
        }
    }

}

impl From<EffectType> for Type {
    fn from(ty: EffectType) -> Self {
        Type::Effect(ty)
    }
}

impl From<FormatConverterType> for Type {
    fn from(ty: FormatConverterType) -> Self {
        Type::FormatConverter(ty)
    }
}

impl From<MixerType> for Type {
    fn from(ty: MixerType) -> Self {
        Type::Mixer(ty)
    }
}

impl From<GeneratorType> for Type {
    fn from(ty: GeneratorType) -> Self {
        Type::Generator(ty)
    }
}

impl From<MusicDeviceType> for Type {
    fn from(ty: MusicDeviceType) -> Self {
        Type::MusicDevice(ty)
    }
}

impl From<IOType> for Type {
    fn from(ty: IOType) -> Self {
        Type::IO(ty)
    }
}

/// Effect (digital signal processing) audio unit subtypes for audio units provided by Apple.
#[derive(Copy, Clone, Debug, PartialEq)]
pub enum EffectType {
    /// An audio unit that enforces an upper dynamic limit on an audio signal.
    ///
    /// **Available** in OS X v10.2 and later.
    PeakLimiter = 1819112562,
    /// An audio unit that provides dynamic compression or expansion.
    ///
    /// **Available** in OS X v10.3 and later.
    DynamicsProcessor = 1684237680,
    /// An audio unit that passes frequencies below a specified cutoff frequency and blocks
    /// frequencies above that cutoff frequency.
    ///
    /// **Available** in OS X v10.2 and later.
    LowPassFilter = 1819304307,
    /// An audio unit that passes frequencies above a specified cutoff frequency and blocks
    /// frequencies below that cutoff frequency.
    ///
    /// **Available** in OS X v10.2 and later.
    HighPassFilter = 1752195443,
    /// An audio unit that passes frequencies between specified upper and lower cutoff frequencies,
    /// and blocks frequencies outside that band.
    ///
    /// **Available** in OS X v10.2 and later.
    BandPassFilter = 1651532147,
    /// An audio unit suitable for implementing a treble control in an audio playback or recording
    /// system.
    ///
    /// **Available** in OS X v10.2 and later.
    HighShelfFilter = 1752393830,
    /// An audio unit suitable for implementing a bass control in an audio playback or recording
    /// system.
    ///
    /// **Available** in OS X v10.2 and later.
    LowShelfFilter = 1819502694,
    /// An audio unit that provides a filter whose center frequency, boost/cut level, and Q can be
    /// adjusted.
    ///
    /// **Available** in OS X v10.2 and later.
    ParametricEQ = 1886217585,
    /// An audio unit that provides a distortion effect.
    ///
    /// **Available** in OS X v10.5 and later.
    Distortion = 1684632436,
    /// An audio unit that introduces a time delay to a signal.
    ///
    /// **Available** in OS X v10.2 and later.
    Delay = 1684368505,
    /// An audio unit that provides a time delay for a specified number of samples.
    ///
    /// **Available** in OS X v10.4 and later.
    SampleDelay = 1935961209,
    /// An audio unit that provides a 10- or 31-band graphic equalizer.
    ///
    /// Available in OS X v10.2 and later.
    GraphicEQ = 1735550321,
    /// An audio unit that provides four-bands of dynamic compression or expansion.
    ///
    /// **Available** in OS X v10.3 and later.
    MultiBandCompressor = 1835232624,
    /// An audio unit that provides a reverberation effect that can be used to simulate a variety
    /// of acoustic spaces.
    ///
    /// **Available** in OS X v10.2 and later.
    MatrixReverb = 1836213622,
    /// An audio unit for modifying the pitch of a signal.
    ///
    /// **Available** in OS X v10.4 and later.
    Pitch = 1953329268,
    /// An audio unit that provides a combination of five filters: low-frequency, three
    /// mid-frequencies, and high-frequency.
    ///
    /// **Available** in OS X v10.4 and later.
    AUFilter = 1718185076,
    /// An audio unit for use in conjunction with a kAudioUnitSubType_NetReceive audio unit for
    /// sending audio across a network or from one application to another.
    ///
    /// **Available** in OS X v10.4 and later.
    NetSend = 1853058660,
    /// An audio unit that detects gaps between segments of speech and fills the gaps with a short
    /// tone, simulating the sound of a walkie-talkie communication device.
    ///
    /// **Available** in OS X v10.5 and later.
    RogerBeep = 1919903602,
    /// A multi-band equalizer with specifiable filter type for each band.
    ///
    /// **Available** in OS X v10.9 and later.
    NBandEQ = 1851942257,
}

/// Audio data format converter audio unit subtypes for **AudioUnit**s provided by Apple.
#[derive(Copy, Clone, Debug, PartialEq)]
pub enum FormatConverterType {
    /// An audio unit that uses an audio converter to do linear PCM conversions, such as changes to
    /// sample rate, bit depth, or interleaving.
    ///
    /// **Available** in OS X v10.2 and later.
    AUConverter = 1668247158,
    /// An audio unit that can be used to have independent control of both playback rate and pitch.
    ///
    /// In OS X it provides a generic view, so it can be used in both a UI and programmatic
    /// context.
    ///
    /// It also comes in an offline version for processing audio files.
    ///
    /// **Available** in OS X v10.7 and later.
    NewTimePitch = 1853191280,
    /// An audio unit that can provide independent control of playback rate and pitch. This subtype
    /// provides a generic view, making it suitable for UI and programmatic context. OS X provides
    /// realtime and offline audio units of this subtype.
    ///
    /// **Available** in OS X v10.3 and later.
    TimePitch = 1953329268,
    /// An audio unit that acquires audio input from a separate thread than the thread on which its
    /// render method is called.
    ///
    /// You can use this subtype to introduce multiple threads into an audio unit processing graph.
    ///
    /// There is a delay, equal to the buffer size, introduced between the audio input and output.
    ///
    /// **Available** in OS X v10.4 and later.
    DeferredRenderer = 1684366962,
    /// An audio unit with one input bus and two output buses. The audio unit duplicates the input
    /// signal to each of its two output buses.
    ///
    /// **Available** in OS X v10.4 and later.
    Splitter = 1936747636,
    /// An audio unit with two input buses and one output bus. The audio unit merges the two input
    /// signals to the single output.
    ///
    /// **Available** in OS X v10.4 and later.
    Merger = 1835364967,
    /// An audio unit that can control playback rate. As the playback rate increases, so does
    /// pitch.
    ///
    /// This subtype provides a generic view, making it suitable for UI and programmatic context.
    ///
    /// OS X provides realtime and offline audio units of this subtype.
    ///
    /// **Available** in OS X v10.3 and later.
    Varispeed = 1986097769,
    /// **Available** in OS X v10.9 and later.
    AUiPodTimeOther = 1768977519,
}

/// Audio mixing **AudioUnit** subtypes for **AudioUnit**s provided by Apple.
#[derive(Copy, Clone, Debug, PartialEq)]
pub enum MixerType {
    /// An audio unit that can have any number of input buses, with any number of channels on each
    /// input bus, and one output bus.
    ///
    /// In OS X, the output bus can have any number of channels.
    ///
    /// In iPhone OS, the output bus always has two channels.
    ///
    /// **Available** in OS X v10.5 and later.
    MultiChannelMixer = 1835232632,
    /// An audio unit that can have any number of input buses, each of which is mono or stereo, and
    /// one stereo output bus.
    ///
    /// **Available** in OS X v10.2 and later.
    StereoMixer = 1936554098,
    /// An audio unit that can have any number of input buses and one output bus.
    ///
    /// Each input bus can be mono, in which case it can be panned using 3D coordinates and
    /// parameters.
    ///
    /// Stereo input buses pass directly through to the output.
    ///
    /// Four-channel ambisonic inputs are rendered to the output configuration.
    ///
    /// The single output bus can be configured with 2, 4, 5, 6, 7 or 8 channels.
    ///
    /// **Available** in OS X v10.3 and later.
    ///
    /// **Deprecated** in OS X v10.10.
    Mixer3D = 862219640,
    /// An audio unit that can have any number of input and output buses with any number of
    /// channels on each bus.
    ///
    /// You configure the mix using a matrix of channels with a separate input level control for
    /// each channel.
    ///
    /// The audio unit also provides individual level control for each
    /// input-channel-to-output-channel combination, as well as level control for each output
    /// channel.
    ///
    /// Finally, the audio unit provides a global level control for the matrix as a whole.
    ///
    /// **Available** in OS X v10.3 and later.
    MatrixMixer = 1836608888,
}

/// Audio units that serve as sound sources.
#[derive(Copy, Clone, Debug, PartialEq)]
pub enum GeneratorType {
    /// A generator unit that can be used to schedule slices of audio to be played at specified
    /// times.
    ///
    /// The audio is scheduled using the time stamps for the render operation and can be scheduled
    /// from any thread.
    ///
    /// **Available** in OS X v10.4 and later.
    ScheduledSoundPlayer = 1936945260,
    /// A generator unit that is used to play a file. In OS X it presents a custom UI so can be
    /// used in a UI context as well as in a programmatic context.
    ///
    /// **Available** in OS X v10.4 and later.
    AudioFilePlayer = 1634103404,
}

/// Audio units that can be played as musical instruments via MIDI control.
#[derive(Copy, Clone, Debug, PartialEq)]
pub enum MusicDeviceType {
    /// A multitimbral instrument unit that can use sample banks in either DLS or SoundFont
    /// formats.
    ///
    /// It fully supports GM-MIDI and the basic extensions of GS-MIDI
    ///
    /// **Available** in OS X v10.2 and later.
    DLSSynth = 1684828960,
    /// A monotimbral instrument unit that functions a a sampler-synthesizer and supports full
    /// interactive editing of its state.
    ///
    /// **Available** in OS X v10.7 and later.
    Sampler = 1935764848,
}

/// Input/output **AudioUnit** subtypes for **AudioUnit**s provided by Apple.
#[derive(Copy, Clone, Debug, PartialEq)]
pub enum IOType {
    /// An audio unit that responds to start/stop calls and provides basic services for converting
    /// to and from linear PCM formats.
    ///
    /// **Available** in OS X v10.2 and later.
    GenericOutput = 1734700658,
    /// An audio unit that can provides input/output connection to an a specified audio device.
    ///
    /// Bus 0 provides output to the audio device and bus 1 accepts input from the audio device.
    ///
    /// **Available** in OS X v10.2 and later.
    HalOutput = 1634230636,
    /// A specialized **HalOutput** audio unit that connects to the user’s selected default device
    /// in Sound Preferences.
    ///
    /// **Available** in OS X v10.2 and later.
    DefaultOutput = 1684366880,
    /// A specialized **HalOutput** audio unit that connects to the user’s selected device for
    /// sound effects, alerts, and other user-interface sounds.
    ///
    /// **Available** in OS X v10.2 and later.
    SystemOutput = 1937339168,
    /// An audio unit that interfaces to the audio inputs and outputs of iPhone OS devices and
    /// provides voice processing features.
    ///
    /// Bus 0 provides output to hardware and bus 1 accepts input from hardware.
    ///
    /// See the [Voice-Processing I/O Audio Unit
    /// Properties](https://developer.apple.com/library/prerelease/mac/documentation/AudioUnit/Reference/AudioUnitPropertiesReference/index.html#//apple_ref/doc/constant_group/Voice_Processing_I_O_Audio_Unit_Properties)
    /// enumeration for the identifiers for this audio unit’s properties.
    ///
    /// **Available** in OS X v10.7 and later.
    VoiceProcessingIO = 1987078511,
}

<|endoftext|>


<commit_before><commit_msg>(feat) Added convenience impl of Middleware for controller functions.<commit_after><|endoftext|>


<commit_before><commit_msg>Rollup merge of #68842 - Centril:issue-68785, r=estebank<commit_after>// check-pass

#![feature(or_patterns)]

enum MyEnum {
    FirstCase(u8),
    OtherCase(u16),
}

fn my_fn(x @ (MyEnum::FirstCase(_) | MyEnum::OtherCase(_)): MyEnum) {}

fn main() {
    my_fn(MyEnum::FirstCase(0));
}
<|endoftext|>


<commit_before><commit_msg>Template the Effect class<commit_after>// TODO: rust-crypto lib for SHA256 verification.

extern crate serde;
extern crate serde_json;
use self::serde_json::map::Map;
use self::serde_json::value::Value;

#[derive(Serialize, Deserialize)]
struct Effect {
    /// Canonical name of the effect
    name: String,
    /// Hash of the effect's definition file, or None if the effect is primitive
    sha1: Option<[u8; 32]>,
    /// List of URLs where the Effect can be obtained
    urls: Vec<String>,
    /// Arguments specific to the given effect (relevant for e.g. Constant).
    effect_args: Map<String, Value>,
}

///// Data structure needed for deserializing Effects
//struct EffectVisitor {
//}
//impl EffectVisitor {
//    fn new() -> Self {
//        EffectVisitor {}
//    }
//}
//impl de::Visitor for EffectVisitor {
//    // This Visitor deserializes to an Effect.
//    type Value = Effect;
//    // Diagnostic info
//    fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
//        formatter.write_str("Effect")
//    }
//    fn visit_map<M>(self, mut visitor: M) -> Result<Self::Value, M::Error>
//        where M: de::MapVisitor
//    {
//        // First, deserialize into a generic Map<String, Value>
//        let mut collected = Map::new();
//
//        // While there are entries remaining in the input, add them
//        // into our map.
//        while let Some((key, value)) = visitor.visit()? {
//            collected.insert(key, value);
//        }
//
//        // typecheck all keys that we understand.
//        let name = match collected.entry("name") {
//            Vacant(_) => M::Error::missing_field("name"),
//            Occupied(entry) =>
//        }
//
//        Ok(values)
//    }
//}
<|endoftext|>


<commit_before><commit_msg>Add regression test for issue #17361<commit_after>// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// Test that astconv doesn't forget about mutability of &mut str

fn main() {
    fn foo<Sized? T>(_: &mut T) {}
    let _f: fn(&mut str) = foo;
}
<|endoftext|>


<commit_before><commit_msg>Add some tests<commit_after>// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// Various scenarios in which `pub` is required in blocks

struct S;

mod m {
    fn f() {
        impl ::S {
            pub fn s(&self) {}
        }
    }
}

// ------------------------------------------------------

pub trait Tr {
    type A;
}
pub struct S1;

fn f() {
    pub struct Z;

    impl ::Tr for ::S1 {
        type A = Z; // Private-in-public error unless `struct Z` is pub
    }
}

// ------------------------------------------------------

trait Tr1 {
    type A;
    fn pull(&self) -> Self::A;
}
struct S2;

mod m1 {
    fn f() {
        struct Z {
            pub field: u8
        }

        impl ::Tr1 for ::S2 {
            type A = Z;
            fn pull(&self) -> Self::A { Z{field: 10} }
        }
    }
}

// ------------------------------------------------------

fn main() {
    S.s(); // Privacy error, unless `fn s` is pub
    let a = S2.pull().field; // Privacy error unless `field: u8` is pub
}
<|endoftext|>


<commit_before><commit_msg>add missing test<commit_after>// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// Regression test for #35546. Check that we are able to codegen
// this. Before we had problems because of the drop glue signature
// around dropping a trait object (specifically, when dropping the
// `value` field of `Node<Send>`).

struct Node<T: ?Sized + Send> {
    next: Option<Box<Node<Send>>>,
    value: T,
}

fn clear(head: &mut Option<Box<Node<Send>>>) {
    match head.take() {
        Some(node) => *head = node.next,
        None => (),
    }
}

fn main() {}
<|endoftext|>


<commit_before>// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// xfail-test
// -*- rust -*-
extern mod std;

type cell = {c: @list};

enum list { link(@mut cell), nil, }

pub fn main() {
    let first: @cell = @mut {c: @nil()};
    let second: @cell = @mut {c: @link(first)};
    first._0 = @link(second);
    sys.rustrt.gc();
    let third: @cell = @mut {c: @nil()};
}
<commit_msg>this test still doesn't pass, but at least it parses...<commit_after>// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// xfail-test
// -*- rust -*-
extern mod core;
use core::gc;
use core::gc::rustrt;

struct cell {c: @list}

enum list { link(@mut cell), nil, }

pub fn main() {
    let first: @cell = @mut cell{c: @nil()};
    let second: @cell = @mut cell{c: @link(first)};
    first._0 = @link(second);
    rustrt::gc();
    let third: @cell = @mut cell{c: @nil()};
}
<|endoftext|>


<commit_before><commit_msg>Added test<commit_after>use librespot_core::*;

#[cfg(test)]
mod tests {
    use super::*;
    // Test AP Resolve
    use apresolve::apresolve_or_fallback;
    #[tokio::test]
    async fn test_ap_resolve() {
        let ap = apresolve_or_fallback(&None, &None).await;
        println!("AP: {:?}", ap);
    }

    // Test connect
    use authentication::Credentials;
    use config::SessionConfig;
    #[tokio::test]
    async fn test_connection() -> Result<(), Box<dyn std::error::Error>> {
        println!("Running connection test");
        let ap = apresolve_or_fallback(&None, &None).await;
        let credentials = Credentials::with_password(String::from("test"), String::from("test"));
        let session_config = SessionConfig::default();
        let proxy = None;

        println!("Connecting to AP \"{}\"", ap);
        let mut connection = connection::connect(ap, &proxy).await?;
        let rc = connection::authenticate(&mut connection, credentials, &session_config.device_id)
            .await?;
        println!("Authenticated as \"{}\"", rc.username);
        Ok(())
    }
}
<|endoftext|>


<commit_before>use core::mem;

use redox::*;

use super::{XdrOps, XdrError, XdrResult};

pub struct MemOps {
    pos: usize,
    buffer: Vec<u8>,
}

impl XdrOps for MemOps {
    fn get_long(&mut self) -> XdrResult<usize> {
        if self.buffer.len()-self.pos < 4 {
            Err(XdrError)
        } else {
            let d: &usize = unsafe { mem::transmute(&self.buffer[self.pos]) };
            self.pos += 4;
            Ok(*d)
        }
    }

    fn put_long(&mut self, l: usize) -> XdrResult<()> {
        Ok(())
    }

    fn get_i32(&mut self) -> XdrResult<i32> {
        Ok(0)
    }

    fn put_i32(&mut self, i: i32) -> XdrResult<()> {
        Ok(())
    }

    fn get_bytes(&mut self, bytes: &mut [u8]) -> XdrResult<()> {
        Ok(())
    }

    fn put_bytes(&mut self, bytes: &[u8]) -> XdrResult<()> {
        Ok(())
    }

    fn get_pos(&self) -> usize {
        self.pos
    }

    fn set_pos(&mut self, offset: usize) -> XdrResult<()> {
        Ok(())
    }

    fn destroy(&mut self) {
    }
}
<commit_msg>Whoops.. forgot big endian<commit_after>use core::mem;

use redox::*;

use super::{XdrOps, XdrError, XdrResult};

pub struct MemOps {
    pos: usize,
    buffer: Vec<u8>,
}

impl XdrOps for MemOps {
    fn get_long(&mut self) -> XdrResult<usize> {
        if self.buffer.len()-self.pos < 4 {
            Err(XdrError)
        } else {
            let d: &usize = unsafe { mem::transmute(&self.buffer[self.pos]) };
            self.pos += 4;
            Ok(usize::from_be(*d))
        }
    }

    fn put_long(&mut self, l: usize) -> XdrResult<()> {
        Ok(())
    }

    fn get_i32(&mut self) -> XdrResult<i32> {
        Ok(0)
    }

    fn put_i32(&mut self, i: i32) -> XdrResult<()> {
        Ok(())
    }

    fn get_bytes(&mut self, bytes: &mut [u8]) -> XdrResult<()> {
        Ok(())
    }

    fn put_bytes(&mut self, bytes: &[u8]) -> XdrResult<()> {
        Ok(())
    }

    fn get_pos(&self) -> usize {
        self.pos
    }

    fn set_pos(&mut self, offset: usize) -> XdrResult<()> {
        Ok(())
    }

    fn destroy(&mut self) {
    }
}
<|endoftext|>


<commit_before><commit_msg>[Rust] temporary value in if condition is dropped after if-else statements finished<commit_after>struct S {
    i: i32,
}

impl ::std::ops::Drop for S {
    fn drop(&mut self) {
        println!("DROP {}", self.i);
    }
}

impl S {
    fn new(i: i32) -> Self {
        Self {
            i,
        }
    }
    fn get(&self) -> Option<&i32> {
        Some(&self.i)
    }
    fn get2(&self) -> Option<&i32> {
        None
    }
}

fn main() {
    println!("1");
    if let Some(_i) = S::new(1).get() {
        println!("if");
    } else {
        println!("else");
    }
    println!("2");
    if let Some(_i) = S::new(2).get2() {
        println!("if");
    } else {
        println!("else");
    }
    println!("3");
    if let Some(_) = S::new(3).get() {
        println!("if");
    } else {
        println!("else");
    }
    println!("4");
    if let Some(_) = S::new(4).get2() {
        println!("if");
    } else {
        println!("else");
    }
    println!("5");
}
<|endoftext|>


<commit_before><commit_msg>Added a benchmark for insert_or_update_document<commit_after>#![feature(test)]

#[macro_use]
extern crate maplit;
extern crate test;
extern crate abra;

use test::Bencher;

use abra::term::Term;
use abra::token::Token;
use abra::schema::{SchemaRead, FieldType};
use abra::document::Document;
use abra::store::{IndexStore, IndexReader};
use abra::store::memory::{MemoryIndexStore, MemoryIndexStoreReader};
use abra::query_set::QuerySetIterator;

fn make_test_store() -> MemoryIndexStore {
    let mut store = MemoryIndexStore::new();
    let body_field = store.add_field("body".to_string(), FieldType::Text).unwrap();

    store
}

#[bench]
fn bench_insert_document(b: &mut Bencher) {
    let mut store = MemoryIndexStore::new();
    let body_field = store.add_field("body".to_string(), FieldType::Text).unwrap();

    let mut tokens = Vec::new();
    for t in 0..5000 {
        tokens.push(Token {
            term: Term::String(t.to_string()),
            position: t
        });
    }

    let mut i = 0;
    b.iter(|| {
        i += 1;

        store.insert_or_update_document(Document {
            key: i.to_string(),
            fields: hashmap! {
                body_field => tokens.clone()
            }
        });
    });
}
<|endoftext|>


<commit_before><commit_msg>added ownerships<commit_after>fn print_block(c: Box<i32>) {
    println!("value of c is: {}",c);
}

fn main() {
    let x = 10i32;
    let y = x;

    //Stack vars
    println!("Value of x is: {}" ,x);
    println!("Value of y is: {}", y);

    // Heap vars
    let a = Box::new(5i32);
    println!("Value of a is: {}",a);

    let b = a;
    // println!("Value of a is: {}",a); // value a used here after move

    print_block(b); // b is moved to print_block

    // println!("Value of a is: {}",b); // value b used here after move

}<|endoftext|>


<commit_before><commit_msg>Add support for XChaCha20.<commit_after><|endoftext|>