<commit_before>use std::collections::HashMap;
use std::error::Error;
use std::fs::{self, File};
use std::io::{Read, Write};
use std::os::unix::fs::MetadataExt;
use std::path::{Path, PathBuf};

use chrono::{DateTime, Local, TimeZone};
use pulldown_cmark::{html, Parser, Options, OPTION_ENABLE_TABLES};
use tera::{Tera, Context};

use theme::Theme;
use utils::{create_file, create_error};

pub struct Post {
    pub root: PathBuf,
    pub path: PathBuf,
    pub head: String,
    pub body: String,
    pub publish_datetime: DateTime<Local>,
    pub modify_datetime: DateTime<Local>,
    pub metadata: HashMap<String, String>,
}

impl Post {
    pub fn new<P: AsRef<Path>>(root: P, path: P) -> Post {
        let metadata = fs::metadata(root.as_ref().join(&path.as_ref())).expect("get post metadata error");
        let (ctime, ctime_nsec) = (metadata.ctime(), metadata.ctime_nsec());
        let (mtime, mtime_nsec) = (metadata.mtime(), metadata.mtime_nsec());
        Post {
            root: root.as_ref().to_owned(),
            path: path.as_ref().to_owned(),
            head: String::new(),
            body: String::new(),
            publish_datetime: Local.timestamp(ctime, ctime_nsec as u32),
            modify_datetime: Local.timestamp(mtime, mtime_nsec as u32),
            metadata: HashMap::new(),
        }
    }

    pub fn src(&self) -> PathBuf {
        self.root.join(&self.path)
    }

    pub fn dest(&self) -> PathBuf {
        self.root.join("builds").join(self.path.with_extension("html"))
    }

    pub fn content(&self) -> String {
        let mut opts = Options::empty();
        opts.insert(OPTION_ENABLE_TABLES);
        let mut s = String::with_capacity(self.body.len() * 3 / 2);
        let p = Parser::new_ext(&self.body, opts);
        html::push_html(&mut s, p);
        s
    }

    pub fn tags(&self) -> Vec<&str> {
        if let Some(tag_str) = self.metadata.get("tags") {
            tag_str.split(',').map(|x| x.trim()).filter(|x| x.len() != 0).collect()
        } else {
            Vec::new()
        }
    }

    pub fn load(&mut self) -> ::std::io::Result<()> {
        debug!("loading post: {}", self.path.display());
        debug!("published: {:?}", self.publish_datetime);
        debug!("modified: {:?}", self.modify_datetime);
        let mut pf = File::open(self.src())?;
        let mut content = String::new();
        pf.read_to_string(&mut content)?;
        let v: Vec<&str> = content.splitn(2, "\n\n").collect();
        if v.len() != 2 {
            return create_error(format!("post({path}) must both have `head` and `body` parts",
                                        path=self.path.display()));
        }
        self.head = v[0].to_string();
        self.body = v[1].to_string();
        for line in self.head.lines() {
            let pair: Vec<&str> = line.splitn(2, ':').collect();
            if pair.len() != 2 {
                return create_error(format!("post({path}) `head` part parse error: {line}",
                                            path=self.path.display(),
                                            line=line));
            }
            self.metadata.insert(pair[0].trim().to_owned(), pair[1].trim().to_owned());
        }
        Ok(())
    }

    pub fn render_html(&self, tera: &Tera) -> ::std::io::Result<()> {
        debug!("rendering post: {}", self.path.display());
        let dest = self.dest();
        let mut f = create_file(&dest)?;
        let mut context = Context::new();
        let content = self.content();
        context.add("content", &content);
        match tera.render("post.tpl", context) {
            Ok(s) => {
                f.write(s.as_bytes())?;
                debug!("created html: {:?}", dest.display());
                return Ok(());
            }
            Err(e) => {
                return create_error(format!("post({path}) render error: {descrition}",
                                            path=self.path.display(),
                                            descrition=e.description()));
            }
        }
    }
}
<commit_msg>post title and url<commit_after>use std::collections::HashMap;
use std::error::Error;
use std::fs::{self, File};
use std::io::{Read, Write};
use std::os::unix::fs::MetadataExt;
use std::path::{Path, PathBuf};

use chrono::{DateTime, Local, TimeZone};
use pulldown_cmark::{html, Parser, Options, OPTION_ENABLE_TABLES};
use tera::{Tera, Context};

use theme::Theme;
use utils::{create_file, create_error};

pub struct Post {
    pub root: PathBuf,
    pub path: PathBuf,
    pub head: String,
    pub body: String,
    pub publish_datetime: DateTime<Local>,
    pub modify_datetime: DateTime<Local>,
    pub metadata: HashMap<String, String>,
}

impl Post {
    pub fn new<P: AsRef<Path>>(root: P, path: P) -> Post {
        let metadata = fs::metadata(root.as_ref().join(&path.as_ref())).expect("get post metadata error");
        let (ctime, ctime_nsec) = (metadata.ctime(), metadata.ctime_nsec());
        let (mtime, mtime_nsec) = (metadata.mtime(), metadata.mtime_nsec());
        Post {
            root: root.as_ref().to_owned(),
            path: path.as_ref().to_owned(),
            head: String::new(),
            body: String::new(),
            publish_datetime: Local.timestamp(ctime, ctime_nsec as u32),
            modify_datetime: Local.timestamp(mtime, mtime_nsec as u32),
            metadata: HashMap::new(),
        }
    }

    pub fn src(&self) -> PathBuf {
        self.root.join(&self.path)
    }

    pub fn dest(&self) -> PathBuf {
        self.root.join("builds").join(self.path.with_extension("html"))
    }

    pub fn title(&self) -> &str {
        self.path
            .file_stem()
            .and_then(|x| x.to_str())
            .expect(&format!("post filename format error: {}", self.path.display()))
    }

    pub fn url(&self) -> PathBuf {
        Path::new("/").join(&self.path)
    }

    pub fn content(&self) -> String {
        let mut opts = Options::empty();
        opts.insert(OPTION_ENABLE_TABLES);
        let mut s = String::with_capacity(self.body.len() * 3 / 2);
        let p = Parser::new_ext(&self.body, opts);
        html::push_html(&mut s, p);
        s
    }

    pub fn tags(&self) -> Vec<&str> {
        if let Some(tag_str) = self.metadata.get("tags") {
            tag_str.split(',').map(|x| x.trim()).filter(|x| x.len() != 0).collect()
        } else {
            Vec::new()
        }
    }

    pub fn load(&mut self) -> ::std::io::Result<()> {
        debug!("loading post: {}", self.path.display());
        debug!("published: {:?}", self.publish_datetime);
        debug!("modified: {:?}", self.modify_datetime);
        let mut pf = File::open(self.src())?;
        let mut content = String::new();
        pf.read_to_string(&mut content)?;
        let v: Vec<&str> = content.splitn(2, "\n\n").collect();
        if v.len() != 2 {
            return create_error(format!("post({path}) must both have `head` and `body` parts",
                                        path=self.path.display()));
        }
        self.head = v[0].to_string();
        self.body = v[1].to_string();
        for line in self.head.lines() {
            let pair: Vec<&str> = line.splitn(2, ':').collect();
            if pair.len() != 2 {
                return create_error(format!("post({path}) `head` part parse error: {line}",
                                            path=self.path.display(),
                                            line=line));
            }
            self.metadata.insert(pair[0].trim().to_owned(), pair[1].trim().to_owned());
        }
        Ok(())
    }

    pub fn render_html(&self, tera: &Tera) -> ::std::io::Result<()> {
        debug!("rendering post: {}", self.path.display());
        let dest = self.dest();
        let mut f = create_file(&dest)?;
        let mut context = Context::new();
        let content = self.content();
        context.add("content", &content);
        match tera.render("post.tpl", context) {
            Ok(s) => {
                f.write(s.as_bytes())?;
                debug!("created html: {:?}", dest.display());
                return Ok(());
            }
            Err(e) => {
                return create_error(format!("post({path}) render error: {descrition}",
                                            path=self.path.display(),
                                            descrition=e.description()));
            }
        }
    }
}
<|endoftext|>


<commit_before>use ::{NifDecoder, NifEnv, NifResult};
use ::wrapper::nif_interface::{NIF_TERM};

/// NifTerm is used to represent all erlang terms. Terms are always lifetime limited by a NifEnv.
///
/// NifTerm is cloneable and copyable, but it can not exist outside of the lifetime of the NifEnv
/// that owns it.
#[derive(Clone, Copy)]
pub struct NifTerm<'a> {
    term: NIF_TERM,
    env: NifEnv<'a>,
}

impl<'a> NifTerm<'a> {
    pub fn new(env: NifEnv<'a>, inner: NIF_TERM) -> Self {
        NifTerm {
            term: inner,
            env: env,
        }
    }
    /// This extracts the raw term pointer. It is usually used in order to obtain a type that can
    /// be passed to calls into the erlang vm.
    pub fn as_c_arg(&self) -> NIF_TERM {
        self.term
    }

    pub fn get_env(&self) -> NifEnv<'a> {
        self.env
    }

    /// This will coerce the NifTerm into the given NifEnv without providing any checks
    /// or other operations. This is unsafe as it allows you to make a NifTerm usable
    /// on an env other then the one that owns it.
    ///
    /// The one case where this is acceptable to use is when we already know the NifEnv
    /// is the same, but we need to coerce the lifetime.
    pub unsafe fn env_cast<'b>(&self, env: NifEnv<'b>) -> NifTerm<'b> {
        NifTerm::new(env, self.as_c_arg())
    }

    /// Returns a representation of self in the given NifEnv.
    ///
    /// If the term is already is in the provided env, it will be directly returned. Otherwise
    /// the term will be copied over.
    pub fn in_env<'b>(&self, env: NifEnv<'b>) -> NifTerm<'b> {
        if self.get_env() == env {
            unsafe { self.env_cast(env) }
        } else {
            NifTerm::new(env, unsafe { ::wrapper::copy_term(env.as_c_arg(), self.as_c_arg()) })
        }
    }

    /// Decodes the NifTerm into type T.
    ///
    /// This should be used as the primary method of extracting the value from a NifTerm.
    ///
    /// # Examples
    ///
    /// ```ignore
    /// let term: NifTerm = ...;
    /// let number: i32 = try!(term.decode());
    /// ```
    pub fn decode<T>(self) -> NifResult<T> where T: NifDecoder<'a> {
        NifDecoder::decode(self)
    }
}
<commit_msg>Retract public unsafe API `NifTerm::env_cast()`.<commit_after>use ::{NifDecoder, NifEnv, NifResult};
use ::wrapper::nif_interface::{NIF_TERM};

/// NifTerm is used to represent all erlang terms. Terms are always lifetime limited by a NifEnv.
///
/// NifTerm is cloneable and copyable, but it can not exist outside of the lifetime of the NifEnv
/// that owns it.
#[derive(Clone, Copy)]
pub struct NifTerm<'a> {
    term: NIF_TERM,
    env: NifEnv<'a>,
}

impl<'a> NifTerm<'a> {
    pub fn new(env: NifEnv<'a>, inner: NIF_TERM) -> Self {
        NifTerm {
            term: inner,
            env: env,
        }
    }
    /// This extracts the raw term pointer. It is usually used in order to obtain a type that can
    /// be passed to calls into the erlang vm.
    pub fn as_c_arg(&self) -> NIF_TERM {
        self.term
    }

    pub fn get_env(&self) -> NifEnv<'a> {
        self.env
    }

    /// Returns a representation of self in the given NifEnv.
    ///
    /// If the term is already is in the provided env, it will be directly returned. Otherwise
    /// the term will be copied over.
    pub fn in_env<'b>(&self, env: NifEnv<'b>) -> NifTerm<'b> {
        if self.get_env() == env {
            // It's safe to create a new NifTerm<'b> without copying because we
            // just proved that the same environment is associated with both 'a
            // and 'b.  (They are either exactly the same lifetime, or the
            // lifetimes of two .run() calls on the same OwnedEnv.)
            NifTerm::new(env, self.as_c_arg())
        } else {
            NifTerm::new(env, unsafe { ::wrapper::copy_term(env.as_c_arg(), self.as_c_arg()) })
        }
    }

    /// Decodes the NifTerm into type T.
    ///
    /// This should be used as the primary method of extracting the value from a NifTerm.
    ///
    /// # Examples
    ///
    /// ```ignore
    /// let term: NifTerm = ...;
    /// let number: i32 = try!(term.decode());
    /// ```
    pub fn decode<T>(self) -> NifResult<T> where T: NifDecoder<'a> {
        NifDecoder::decode(self)
    }
}
<|endoftext|>


<commit_before>#![allow(unused_imports)]
extern crate test;
extern crate regex;

use std::fs;
use regex::Regex;
use std::path::PathBuf;
use std::mem::replace;
use test::test::Bencher;
use prelude::*;
use gitignore::*;
use std::fs::File;
use std::io::prelude::*;
use regex::RegexSet;

#[bench]
fn bench_gitignore_parse_file(b: &mut Bencher) {
    b.iter(|| {
        let mut file = File::open("src/testdata/.gitignore").unwrap();
        let mut contents = String::new();
        let _ = file.read_to_string(&mut contents);
        process_to_vector(&contents);
        () } )
}

#[bench]
fn bench_gitignore_parse(b: &mut Bencher) {
    let file_contents = include_str!("testdata/.gitignore");
    b.iter(|| process_to_vector(file_contents))
}

#[test]
fn cabal_gitignore() {
    let file_contents = include_str!("testdata/gitignore-tests/cabal-gitignore");
    let _ = process_to_vector(file_contents);
}

#[test]
fn cabal_regex_ignore() {
    let file_contents = include_str!("testdata/gitignore-tests/cabal-gitignore");
    let path = PathBuf::from("testdata/gitignore-tests/cabal-gitignore");
    let _ = file_contents_to_regex(file_contents, &path);
}

#[test]
fn profunctor_gitignore() {
    let file_contents = include_str!("testdata/gitignore-tests/profunctor-gitignore");
    let _ = process_to_vector(file_contents);
}

#[bench]
fn bench_gitignore_clone(b: &mut Bencher) {
    let file_contents = include_str!("testdata/.gitignore");
    let gitignore_structure = &process_to_vector(file_contents);
    b.iter(|| gitignore_structure.to_owned())
}
#[bench]
fn bench_gitignore(b: &mut Bencher) {
    let file_contents = include_str!("testdata/.gitignore");
    b.iter(|| file_contents_to_regex(file_contents, &PathBuf::from("testdata/.gitignore")))
}

#[bench]
fn bench_traversal(b: &mut Bencher) {
    let p = PathBuf::from("src/testdata");
    b.iter(|| read_all(&p, 4, None, None, None, None, true, &None, false, false))
}

#[bench]
fn bench_traversal_gitignore(b: &mut Bencher) {
    let p = PathBuf::from("src/testdata");
    b.iter(|| read_all(&p, 4, None, None, None, None, true, &None, true, true))
}
#[bench]
fn bench_traversal_sort (b: &mut Bencher) {
    let p = PathBuf::from("src/testdata");
    b.iter(|| { let v = read_all(&p, 4, None, None, None, None, true, &None, false, true); v.sort(None, 2) })
}

#[bench]
fn bench_traversal_artifacts(b: &mut Bencher) {
    let p = PathBuf::from("src/testdata");
    //let p = PathBuf::from("/home/vanessa/programming/haskell/forks/cabal");
    b.iter(|| read_all(&p, 4, None, None, None, None, true, &None, false, true))
}

#[bench]
fn bench_extension_regex(b: &mut Bencher) {
    let metadata = fs::metadata("src/main.rs").unwrap();
    b.iter(|| is_artifact("libdoggo.rlib",
                          "target/release/libdoggo.rlib",
                          None,
                          &metadata,
                          &None) )
}

#[bench]
fn bench_extension_regex_long(b: &mut Bencher) {
    let metadata = fs::metadata("src/main.rs").unwrap();
    b.iter(|| is_artifact("sniff",
                          "target/arm-unknown-linux-musleabi/release/sniff",
                          None,
                          &metadata,
                          &None) )
}

#[test]
fn test_parser() {
    let cli_input = "30M";
    assert_eq!(Some(30*1024*1024), threshold(Some(cli_input)));
}

#[bench]
fn bench_parser(b:&mut Bencher) {
    let cli_input = "1M";
    b.iter(|| threshold(Some(cli_input)))
}
<commit_msg>package<commit_after>#![allow(unused_imports)]
extern crate test;
extern crate regex;

use std::fs;
use regex::Regex;
use std::path::PathBuf;
use std::mem::replace;
use test::test::Bencher;
use prelude::*;
use gitignore::*;
use std::fs::File;
use std::io::prelude::*;
use regex::RegexSet;

#[bench]
fn bench_gitignore_parse_file(b: &mut Bencher) {
    b.iter(|| {
        let mut file = File::open("src/testdata/.gitignore").unwrap();
        let mut contents = String::new();
        let _ = file.read_to_string(&mut contents);
        process_to_vector(&contents);
        () } )
}

#[bench]
fn bench_gitignore_parse(b: &mut Bencher) {
    let file_contents = include_str!("testdata/.gitignore");
    b.iter(|| process_to_vector(file_contents))
}

#[test]
fn cabal_gitignore() {
    let file_contents = include_str!("testdata/gitignore-tests/cabal-gitignore");
    let _ = process_to_vector(file_contents);
}

#[test]
fn cabal_regex_ignore() {
    let file_contents = include_str!("testdata/gitignore-tests/cabal-gitignore");
    let path = PathBuf::from("testdata/gitignore-tests/cabal-gitignore");
    let _ = file_contents_to_regex(file_contents, &path);
}

#[test]
fn profunctor_gitignore() {
    let file_contents = include_str!("testdata/gitignore-tests/profunctor-gitignore");
    let _ = process_to_vector(file_contents);
}

#[bench]
fn bench_gitignore_clone(b: &mut Bencher) {
    let file_contents = include_str!("testdata/.gitignore");
    let gitignore_structure = &process_to_vector(file_contents);
    b.iter(|| gitignore_structure.to_owned())
}
#[bench]
fn bench_gitignore(b: &mut Bencher) {
    let file_contents = include_str!("testdata/.gitignore");
    b.iter(|| file_contents_to_regex(file_contents, &PathBuf::from("testdata/.gitignore")))
}

#[bench]
fn bench_traversal(b: &mut Bencher) {
    let p = PathBuf::from("src/testdata");
    b.iter(|| read_all(&p, 4, None, None, None, None, true, &None, false, false))
}

#[bench]
fn bench_traversal_gitignore(b: &mut Bencher) {
    let p = PathBuf::from("src/testdata");
    b.iter(|| read_all(&p, 4, None, None, None, None, true, &None, true, true))
}
#[bench]
fn bench_traversal_sort (b: &mut Bencher) {
    let p = PathBuf::from("src/testdata");
    b.iter(|| { let v = read_all(&p, 4, None, None, None, None, true, &None, false, true); v.sort(None, 2, false) })
}

#[bench]
fn bench_traversal_artifacts(b: &mut Bencher) {
    let p = PathBuf::from("src/testdata");
    //let p = PathBuf::from("/home/vanessa/programming/haskell/forks/cabal");
    b.iter(|| read_all(&p, 4, None, None, None, None, true, &None, false, true))
}

#[bench]
fn bench_extension_regex(b: &mut Bencher) {
    let metadata = fs::metadata("src/main.rs").unwrap();
    b.iter(|| is_artifact("libdoggo.rlib",
                          "target/release/libdoggo.rlib",
                          None,
                          &metadata,
                          &None) )
}

#[bench]
fn bench_extension_regex_long(b: &mut Bencher) {
    let metadata = fs::metadata("src/main.rs").unwrap();
    b.iter(|| is_artifact("sniff",
                          "target/arm-unknown-linux-musleabi/release/sniff",
                          None,
                          &metadata,
                          &None) )
}

#[test]
fn test_parser() {
    let cli_input = "30M";
    assert_eq!(Some(30*1024*1024), threshold(Some(cli_input)));
}

#[bench]
fn bench_parser(b:&mut Bencher) {
    let cli_input = "1M";
    b.iter(|| threshold(Some(cli_input)))
}
<|endoftext|>


<commit_before>// (c) 2016 Productize SPRL <joost@productize.be>

use super::*;
use ::formatter;

#[allow(dead_code)]
fn check_parse_res(s: &str, o: &str) {
    let e = parser::parse_str(s).unwrap();
    let t = ser::to_string(&e).unwrap();
    assert_eq!(o, t)
}

#[allow(dead_code)]
fn check_parse(s: &str) {
    let e = parser::parse_str(s).unwrap();
    let t = ser::to_string(&e).unwrap();
    assert_eq!(s, t)
}

#[allow(dead_code)]
fn check_parse_kicad(s: &str) {
    let e = parser::parse_str(s).unwrap();
    let t = ser::to_string_with_rules(&e, kicad_test_rules()).unwrap();
    assert_eq!(s, t)
}

#[allow(dead_code)]
fn check_parse_rules(s: &str, rules: formatter::Rules) {
    let e = parser::parse_str(s).unwrap();
    let t = ser::to_string_with_rules(&e, rules).unwrap();
    assert_eq!(s, t)
}

#[allow(dead_code)]
fn parse_fail(s: &str) {
    parser::parse_str(s).unwrap();
}

#[allow(dead_code)]
pub fn kicad_test_rules() -> formatter::Rules {
    let mut rf = formatter::Rules::new();
    rf.insert("layer", 1);
    rf.insert("desc", 1);
    rf.insert("fp_text", 1);
    rf.insert("fp_poly", 1);
    rf.insert("fp_line", 1);
    rf.insert("pad", 1);
    rf.insert("general", 1);
    rf
}

#[test]
fn test_empty() {
    check_parse("")
}

#[test]
fn test_empty_qstring() {
    check_parse("(hello \"\")")
}

#[test]
fn test_minimal() {
    check_parse("()")
}

#[test]
fn test_string() {
    check_parse("hello")
}

#[test]
fn test_qstring_a() {
    check_parse_res("\"hello\"", "hello")
}

#[test]
fn test_qstring_a2() {
    check_parse("\"hello world\"")
}

#[test]
fn test_qstring_a3() {
    check_parse("\"hello(world)\"")
}

#[test]
fn test_number() {
    check_parse("1.3")
}

#[test]
fn test_float_vs_int() {
    check_parse("2.0")
}

#[test]
fn test_double() {
    check_parse("(())")
}

#[test]
fn test_br_string() {
    check_parse("(world)")
}

#[test]
fn test_br_qstring() {
    check_parse_res("(\"world\")", "(world)")
}

#[test]
fn test_br_int() {
    check_parse("(42)")
}

#[test]
fn test_br_float() {
    check_parse("(12.7)")
}

#[test]
fn test_br_qbrstring() {
    check_parse("(\"(()\")")
}

#[test]
fn test_number_string() {
    check_parse("567A_WZ")
}

#[test]
#[should_panic(expected="called `Result::unwrap()` on an\
 `Err` value: Other(\"incomplete: Size(2)\")")]
fn test_invalid1() {
    parse_fail("(")
}

#[test]
#[should_panic(expected="called `Result::unwrap()` on an\
 `Err` value: Other(\"parse error: Alt |)|\")")]
fn test_invalid2() {
    parse_fail(")")
}

#[test]
#[should_panic(expected="incomplete: Size")]
fn test_invalid3() {
    parse_fail("\"hello")
}

#[test]
fn test_complex() {
    check_parse("(module SWITCH_3W_SIDE_MMP221-R (layer F.Cu) (descr \"\") (pad 1 thru_hole rect \
                 (size 1.2 1.2) (at -2.5 -1.6 0) (layers *.Cu *.Mask) (drill 0.8)) (pad 2 \
                 thru_hole rect (size 1.2 1.2) (at 0.0 -1.6 0) (layers *.Cu *.Mask) (drill 0.8)) \
                 (pad 3 thru_hole rect (size 1.2 1.2) (at 2.5 -1.6 0) (layers *.Cu *.Mask) (drill \
                 0.8)) (pad 5 thru_hole rect (size 1.2 1.2) (at 0.0 1.6 0) (layers *.Cu *.Mask) \
                 (drill 0.8)) (pad 6 thru_hole rect (size 1.2 1.2) (at -2.5 1.6 0) (layers *.Cu \
                 *.Mask) (drill 0.8)) (pad 4 thru_hole rect (size 1.2 1.2) (at 2.5 1.6 0) (layers \
                 *.Cu *.Mask) (drill 0.8)) (fp_line (start -4.5 -1.75) (end 4.5 -1.75) (layer \
                 F.SilkS) (width 0.127)) (fp_line (start 4.5 -1.75) (end 4.5 1.75) (layer \
                 F.SilkS) (width 0.127)) (fp_line (start 4.5 1.75) (end -4.5 1.75) (layer \
                 F.SilkS) (width 0.127)) (fp_line (start -4.5 1.75) (end -4.5 -1.75) (layer \
                 F.SilkS) (width 0.127)))")
}

#[test]
fn test_kicad_1() {
    check_parse_kicad("(module SILABS_EFM32_QFM24
  (layer F.Cu))")
}

#[test]
fn test_multiline() {
    let mut rules = formatter::Rules::new();
    rules.insert("foo", 1);
    rules.insert("mars", 1);
    check_parse_rules("\
(hello \"test it\"
  (foo bar)
  (mars venus))",
                      rules)
}

#[test]
fn test_multiline_two_empty() {
    check_parse_res("\
(hello

world)",
                    "(hello world)")
}

#[test]
fn test_fail_pcb() {
    check_parse_kicad("\
(kicad_pcb (version 4) (host pcbnew \"(2015-05-31 BZR 5692)-product\")
  \
                       (general))")
}
<commit_msg>fix build<commit_after>// (c) 2016 Productize SPRL <joost@productize.be>

use super::*;
use ::formatter;

#[allow(dead_code)]
fn check_parse_res(s: &str, o: &str) {
    let e = parser::parse_str(s).unwrap();
    let t = ser::to_string(&e).unwrap();
    assert_eq!(o, t)
}

#[allow(dead_code)]
fn check_parse(s: &str) {
    let e = parser::parse_str(s).unwrap();
    let t = ser::to_string(&e).unwrap();
    assert_eq!(s, t)
}

#[allow(dead_code)]
fn check_parse_kicad(s: &str) {
    let e = parser::parse_str(s).unwrap();
    let t = ser::to_string_with_rules(&e, kicad_test_rules()).unwrap();
    assert_eq!(s, t)
}

#[allow(dead_code)]
fn check_parse_rules(s: &str, rules: formatter::Rules) {
    let e = parser::parse_str(s).unwrap();
    let t = ser::to_string_with_rules(&e, rules).unwrap();
    assert_eq!(s, t)
}

#[allow(dead_code)]
fn parse_fail(s: &str) {
    parser::parse_str(s).unwrap();
}

#[allow(dead_code)]
pub fn kicad_test_rules() -> formatter::Rules {
    let mut rf = formatter::Rules::new();
    rf.insert("layer", 1);
    rf.insert("desc", 1);
    rf.insert("fp_text", 1);
    rf.insert("fp_poly", 1);
    rf.insert("fp_line", 1);
    rf.insert("pad", 1);
    rf.insert("general", 1);
    rf
}

#[test]
fn test_empty() {
    check_parse("")
}

#[test]
fn test_empty_qstring() {
    check_parse("(hello \"\")")
}

#[test]
fn test_minimal() {
    check_parse("()")
}

#[test]
fn test_string() {
    check_parse("hello")
}

#[test]
fn test_qstring_a() {
    check_parse_res("\"hello\"", "hello")
}

#[test]
fn test_qstring_a2() {
    check_parse("\"hello world\"")
}

#[test]
fn test_qstring_a3() {
    check_parse("\"hello(world)\"")
}

#[test]
fn test_number() {
    check_parse("1.3")
}

#[test]
fn test_float_vs_int() {
    check_parse("2.0")
}

#[test]
fn test_double() {
    check_parse("(())")
}

#[test]
fn test_br_string() {
    check_parse("(world)")
}

#[test]
fn test_br_qstring() {
    check_parse_res("(\"world\")", "(world)")
}

#[test]
fn test_br_int() {
    check_parse("(42)")
}

#[test]
fn test_br_float() {
    check_parse("(12.7)")
}

#[test]
fn test_br_qbrstring() {
    check_parse("(\"(()\")")
}

#[test]
fn test_number_string() {
    check_parse("567A_WZ")
}

#[test]
#[should_panic(expected="called `Result::unwrap()` on an `Err` value: Other(\"incomplete: Size(2)\")")]
fn test_invalid1() {
    parse_fail("(")
}

#[test]
#[should_panic(expected="called `Result::unwrap()` on an `Err` value: Other(\"parse error: Alt |)|\")")]
fn test_invalid2() {
    parse_fail(")")
}

#[test]
#[should_panic(expected="incomplete: Size")]
fn test_invalid3() {
    parse_fail("\"hello")
}

#[test]
fn test_complex() {
    check_parse("(module SWITCH_3W_SIDE_MMP221-R (layer F.Cu) (descr \"\") (pad 1 thru_hole rect \
                 (size 1.2 1.2) (at -2.5 -1.6 0) (layers *.Cu *.Mask) (drill 0.8)) (pad 2 \
                 thru_hole rect (size 1.2 1.2) (at 0.0 -1.6 0) (layers *.Cu *.Mask) (drill 0.8)) \
                 (pad 3 thru_hole rect (size 1.2 1.2) (at 2.5 -1.6 0) (layers *.Cu *.Mask) (drill \
                 0.8)) (pad 5 thru_hole rect (size 1.2 1.2) (at 0.0 1.6 0) (layers *.Cu *.Mask) \
                 (drill 0.8)) (pad 6 thru_hole rect (size 1.2 1.2) (at -2.5 1.6 0) (layers *.Cu \
                 *.Mask) (drill 0.8)) (pad 4 thru_hole rect (size 1.2 1.2) (at 2.5 1.6 0) (layers \
                 *.Cu *.Mask) (drill 0.8)) (fp_line (start -4.5 -1.75) (end 4.5 -1.75) (layer \
                 F.SilkS) (width 0.127)) (fp_line (start 4.5 -1.75) (end 4.5 1.75) (layer \
                 F.SilkS) (width 0.127)) (fp_line (start 4.5 1.75) (end -4.5 1.75) (layer \
                 F.SilkS) (width 0.127)) (fp_line (start -4.5 1.75) (end -4.5 -1.75) (layer \
                 F.SilkS) (width 0.127)))")
}

#[test]
fn test_kicad_1() {
    check_parse_kicad("(module SILABS_EFM32_QFM24
  (layer F.Cu))")
}

#[test]
fn test_multiline() {
    let mut rules = formatter::Rules::new();
    rules.insert("foo", 1);
    rules.insert("mars", 1);
    check_parse_rules("\
(hello \"test it\"
  (foo bar)
  (mars venus))",
                      rules)
}

#[test]
fn test_multiline_two_empty() {
    check_parse_res("\
(hello

world)",
                    "(hello world)")
}

#[test]
fn test_fail_pcb() {
    check_parse_kicad("\
(kicad_pcb (version 4) (host pcbnew \"(2015-05-31 BZR 5692)-product\")
  \
                       (general))")
}
<|endoftext|>


<commit_before>//!Constants and structures from time classes
//!
//! This includes include/uapi/linux/time.h, //include/linux/time.h, and /include/linux/time64.h

///A structure that contains the number of seconds and nanoseconds since an epoch.
///
///If in doubt, assume we're talking about the UNIX epoch.
#[repr(C)]
pub struct timespec {
    ///The number of seconds contained in this timespec
    pub tv_sec: ::time_t,

    ///The number of nanoseconds contained in this timespec
    pub tv_nsec: ::c_long
}

///A structure that contains the number of seconds and microseconds since an epoch.
///
///If in doubt, assume we're talking about the UNIX epoch.
#[repr(C)]
pub struct timeval {
    ///The number of seconds contained in this timeval
    pub tv_sec: ::time_t,

    ///The number of microseconds contained in this timeval
    pub tv_usec: ::suseconds_t
}

///A structure containing information on the time-based location of a timezone
///
///Please note that this does not include the name or country code, only the minutes west of Greenwich and the type of DST correction
#[repr(C)]
pub struct timezone {
    ///The number of minutes west of Greenwich
    pub tz_minuteswest: ::c_int,

    ///The type of Daylight Savings Time correction
    pub tz_dsttime: ::c_int
}

//Names of the interval timers

///An interval timer that decrements in real time
///
///On expiration, a SIGALRM is delivered
pub const ITIMER_REAL: ::c_int = 0;

///An interval timer that decrements only when the process is executing.
///
///On expiration, a SIGVTALRM is delivered
pub const ITIMER_VIRTUAL: ::c_int = 1;

///Decrements both while the process is executing and while the system is executing on behalf of the process
///
///This is usually used to profile kernel-space and user-space concurrently.
///
///If coupled with ITIMER_VIRTUAL, you can separate the two values - What is left when ITIMER_VIRTUAL's value is removed is kernel time
pub const ITIMER_PROF: ::c_int = 2;

///An interval timer based on a `timespec`
#[repr(C)]
pub struct itimerspec {
    ///The period of time this timer should run for (Need to verify)
    pub it_interval: timespec,

    ///The amount of time left until expiration (Need to verify)
    pub it_value: timespec
}

///An interval timer based on a `timeval`
#[repr(C)]
pub struct itimerval {
    ///The period of time this timer should run for (Need to verify)
    pub it_interval: timeval,

    ///The amount of time left until expiration (Need to verify)
    pub it_value: timeval
}

///A system-wide clock that measures time from the "real world"
///
///This clock **is** affected by discontinuous jumps in system time, NTP, and user changes
pub const CLOCK_REALTIME: ::clockid_t = 0;

///A clock that measures monotonic time since an unspecified starting point
///
///Unless you manage to break your system, this unspecified point is usually when your computer powers on.
///
///This is not affected by user changes, but is by `adjtime` and NTP.
pub const CLOCK_MONOTONIC: ::clockid_t = 1;

///A high-resolution per-process timer from the processor.
pub const CLOCK_PROCESS_CPUTIME_ID: ::clockid_t = 2;

///A (high-resolution?) thread-specific timer from the processor
pub const CLOCK_THREAD_CPUTIME_ID: ::clockid_t = 3;

///A hardware-based version of `CLOCK_MONOTONIC` that is not subject to changes
pub const CLOCK_MONOTONIC_RAW: ::clockid_t = 4;

///A faster but less precise version of `CLOCK_REALTIME`, measuring time in the "real world"
pub const CLOCK_REALTIME_COARSE: ::clockid_t = 5;

///A faster but less precise version of `CLOCK_MONOTONIC`, measuring time since an unspecified starting point
pub const CLOCK_MONOTONIC_COARSE: ::clockid_t = 6;

///Identical to `CLOCK_MONOTONIC`, but includes any time that the system is suspended.
pub const CLOCK_BOOTIME: ::clockid_t = 7;

///Identical to `CLOCK_REALTIME`, but timers exposed via this will wake the system if suspended
pub const CLOCK_REALTIME_ALARM: ::clockid_t = 8;

///Identical to `CLOCK_BOOTIME`, but timers exposed via this will wake the system if suspended
pub const CLOCK_BOOTTIME_ALARM: ::clockid_t = 9;

///A clock used for SGI systems. Need to investigate
pub const CLOCK_SGI_CYCLE: ::clockid_t = 10;

///A clock that shows International Atomic Time
pub const CLOCK_TAI: ::clockid_t = 11;

///The maximum clock ID that the system is allowed to have
pub const MAX_CLOCKS: ::clockid_t = 16; //Resolves to c_int. Please let me know if this should be c_int on it's own

///A mask for supported clocks
///
///Needs to be investigated
pub const CLOCKS_MASK: ::clockid_t = CLOCK_REALTIME | CLOCK_MONOTONIC;

///A shorthand variant of CLOCK_MONOTONIC.
///
///This isn't used in the kernel. Is it left over from an old change that was reverted?
pub const CLOCKS_MONO: ::clockid_t = CLOCK_MONOTONIC;

///A flag indicating time is absolute
pub const TIMER_ABSTIME: ::c_int = 0x01;

///The type used for 64-bit time
pub type time64_t = i64;

///The number of milliseconds in a second
pub const MSEC_PER_SEC: ::c_long = 1000;

///The number of microseconds in a millisecond
pub const USEC_PER_MSEC: ::c_long = 1000;

///The number of nanoseconds in a microsecond
pub const NSEC_PER_USEC: ::c_long = 1000;

///The number of nanoseconds in a millisecond
pub const NSEC_PER_MSEC: ::c_long = 1000000;

///The number of microseconds in a second
pub const USEC_PER_SEC: ::c_long = 1000000;

///The number of nanoseconds in a second
pub const NSEC_PER_SEC: ::c_long = 1000000000;

///The number of femtoseconds in a second
pub const FSEC_PER_SEC: ::c_longlong = 1000000000000000;

///The maximim value of a time64_t
pub const TIME64_MAX: ::c_longlong = ((1u64 << 63) as i64);

///The maximum value of a ktime_t
pub const KTIME_MAX: ::c_longlong = ((1u64 << 63) as i64);

///The maximum number of seconds in a ktime_t
pub const KTIME_SEC_MAX: ::c_longlong = KTIME_MAX / NSEC_PER_SEC;

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

    #[test]
    fn test_per_sec_accuracy() {
        assert_eq!(NSEC_PER_MSEC, NSEC_PER_USEC * USEC_PER_MSEC);
        assert_eq!(NSEC_PER_SEC, NSEC_PER_MSEC * MSEC_PER_SEC);
    }
}<commit_msg>Proper KTIME bounds<commit_after>//!Constants and structures from time classes
//!
//! This includes include/uapi/linux/time.h, //include/linux/time.h, and /include/linux/time64.h

///A structure that contains the number of seconds and nanoseconds since an epoch.
///
///If in doubt, assume we're talking about the UNIX epoch.
#[repr(C)]
pub struct timespec {
    ///The number of seconds contained in this timespec
    pub tv_sec: ::time_t,

    ///The number of nanoseconds contained in this timespec
    pub tv_nsec: ::c_long
}

///A structure that contains the number of seconds and microseconds since an epoch.
///
///If in doubt, assume we're talking about the UNIX epoch.
#[repr(C)]
pub struct timeval {
    ///The number of seconds contained in this timeval
    pub tv_sec: ::time_t,

    ///The number of microseconds contained in this timeval
    pub tv_usec: ::suseconds_t
}

///A structure containing information on the time-based location of a timezone
///
///Please note that this does not include the name or country code, only the minutes west of Greenwich and the type of DST correction
#[repr(C)]
pub struct timezone {
    ///The number of minutes west of Greenwich
    pub tz_minuteswest: ::c_int,

    ///The type of Daylight Savings Time correction
    pub tz_dsttime: ::c_int
}

//Names of the interval timers

///An interval timer that decrements in real time
///
///On expiration, a SIGALRM is delivered
pub const ITIMER_REAL: ::c_int = 0;

///An interval timer that decrements only when the process is executing.
///
///On expiration, a SIGVTALRM is delivered
pub const ITIMER_VIRTUAL: ::c_int = 1;

///Decrements both while the process is executing and while the system is executing on behalf of the process
///
///This is usually used to profile kernel-space and user-space concurrently.
///
///If coupled with ITIMER_VIRTUAL, you can separate the two values - What is left when ITIMER_VIRTUAL's value is removed is kernel time
pub const ITIMER_PROF: ::c_int = 2;

///An interval timer based on a `timespec`
#[repr(C)]
pub struct itimerspec {
    ///The period of time this timer should run for (Need to verify)
    pub it_interval: timespec,

    ///The amount of time left until expiration (Need to verify)
    pub it_value: timespec
}

///An interval timer based on a `timeval`
#[repr(C)]
pub struct itimerval {
    ///The period of time this timer should run for (Need to verify)
    pub it_interval: timeval,

    ///The amount of time left until expiration (Need to verify)
    pub it_value: timeval
}

///A system-wide clock that measures time from the "real world"
///
///This clock **is** affected by discontinuous jumps in system time, NTP, and user changes
pub const CLOCK_REALTIME: ::clockid_t = 0;

///A clock that measures monotonic time since an unspecified starting point
///
///Unless you manage to break your system, this unspecified point is usually when your computer powers on.
///
///This is not affected by user changes, but is by `adjtime` and NTP.
pub const CLOCK_MONOTONIC: ::clockid_t = 1;

///A high-resolution per-process timer from the processor.
pub const CLOCK_PROCESS_CPUTIME_ID: ::clockid_t = 2;

///A (high-resolution?) thread-specific timer from the processor
pub const CLOCK_THREAD_CPUTIME_ID: ::clockid_t = 3;

///A hardware-based version of `CLOCK_MONOTONIC` that is not subject to changes
pub const CLOCK_MONOTONIC_RAW: ::clockid_t = 4;

///A faster but less precise version of `CLOCK_REALTIME`, measuring time in the "real world"
pub const CLOCK_REALTIME_COARSE: ::clockid_t = 5;

///A faster but less precise version of `CLOCK_MONOTONIC`, measuring time since an unspecified starting point
pub const CLOCK_MONOTONIC_COARSE: ::clockid_t = 6;

///Identical to `CLOCK_MONOTONIC`, but includes any time that the system is suspended.
pub const CLOCK_BOOTIME: ::clockid_t = 7;

///Identical to `CLOCK_REALTIME`, but timers exposed via this will wake the system if suspended
pub const CLOCK_REALTIME_ALARM: ::clockid_t = 8;

///Identical to `CLOCK_BOOTIME`, but timers exposed via this will wake the system if suspended
pub const CLOCK_BOOTTIME_ALARM: ::clockid_t = 9;

///A clock used for SGI systems. Need to investigate
pub const CLOCK_SGI_CYCLE: ::clockid_t = 10;

///A clock that shows International Atomic Time
pub const CLOCK_TAI: ::clockid_t = 11;

///The maximum clock ID that the system is allowed to have
pub const MAX_CLOCKS: ::clockid_t = 16; //Resolves to c_int. Please let me know if this should be c_int on it's own

///A mask for supported clocks
///
///Needs to be investigated
pub const CLOCKS_MASK: ::clockid_t = CLOCK_REALTIME | CLOCK_MONOTONIC;

///A shorthand variant of CLOCK_MONOTONIC.
///
///This isn't used in the kernel. Is it left over from an old change that was reverted?
pub const CLOCKS_MONO: ::clockid_t = CLOCK_MONOTONIC;

///A flag indicating time is absolute
pub const TIMER_ABSTIME: ::c_int = 0x01;

///The type used for 64-bit time
pub type time64_t = i64;

///The number of milliseconds in a second
pub const MSEC_PER_SEC: ::c_long = 1000;

///The number of microseconds in a millisecond
pub const USEC_PER_MSEC: ::c_long = 1000;

///The number of nanoseconds in a microsecond
pub const NSEC_PER_USEC: ::c_long = 1000;

///The number of nanoseconds in a millisecond
pub const NSEC_PER_MSEC: ::c_long = 1000000;

///The number of microseconds in a second
pub const USEC_PER_SEC: ::c_long = 1000000;

///The number of nanoseconds in a second
pub const NSEC_PER_SEC: ::c_long = 1000000000;

///The number of femtoseconds in a second
pub const FSEC_PER_SEC: ::c_longlong = 1000000000000000;

///The maximim value of a time64_t
pub const TIME64_MAX: ::c_longlong = ((1u64 << 63) as i64);

///The maximum value of a ktime_t
pub const KTIME_MAX: ::c_longlong = 9_223_372_036_854_775_807;

///The maximum number of seconds in a ktime_t
pub const KTIME_SEC_MAX: ::c_longlong = 9_223_372_036;

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

    #[test]
    fn test_per_sec_accuracy() {
        assert_eq!(NSEC_PER_MSEC, NSEC_PER_USEC * USEC_PER_MSEC);
        assert_eq!(NSEC_PER_SEC, NSEC_PER_MSEC * MSEC_PER_SEC);
    }
}<|endoftext|>


<commit_before>//! # UART for the LM4F120H5QR

// ****************************************************************************
//
// Imports
//
// ****************************************************************************

use core::fmt;
use core::intrinsics::{volatile_load, volatile_store};

use embedded_serial::{self, BlockingTx, NonBlockingRx};
use cortex_m::asm::nop;

use super::gpio;
use super::pll;
use super::registers as reg;

// ****************************************************************************
//
// Public Types
//
// ****************************************************************************

/// This chip has 8 UARTs
#[derive(PartialEq, Clone, Copy)]
#[allow(missing_docs)]
pub enum UartId {
    Uart0,
    Uart1,
    Uart2,
    Uart3,
    Uart4,
    Uart5,
    Uart6,
    Uart7,
}

/// Controls a single UART
/// Only supports 8/N/1 - who needs anything else?
pub struct Uart {
    id: UartId,
    baud: u32,
    nl_mode: NewlineMode,
    reg: &'static mut reg::UartRegisters,
}

/// writeln!() emits LF chars, so this is useful
/// if you're writing text with your UART
#[derive(PartialEq, Clone, Copy)]
pub enum NewlineMode {
    /// Emit octets as received
    Binary,
    /// Emit an extra CR before every LF
    SwapLFtoCRLF,
}

// ****************************************************************************
//
// Private Types
//
// ****************************************************************************

// None

// ****************************************************************************
//
// Public Data
//
// ****************************************************************************

// None

// ****************************************************************************
//
// Public Functions
//
// ****************************************************************************

/// Represents a single UART on the LM4F120
impl Uart {
    /// Create a new Uart object. The caller is responsible for ensuring
    /// that only one object exists per UartId. The UART is set to
    /// 8 data bits, 1 stop bit, no parity and is not configurable.
    /// Optionally, newline translation can be performed on outbound data
    /// - this will cause writeln!() to emit a CRLF.
    pub fn new(id: UartId, baud: u32, nl_mode: NewlineMode) -> Uart {
        let mut uart = Uart {
            id: id,
            baud: baud,
            nl_mode: nl_mode,
            reg: get_uart_registers(id),
        };
        uart.init();
        uart
    }

    /// Configure the hardware
    fn init(&mut self) -> () {
        // Do GPIO pin muxing
        gpio::enable_uart(self.id);
        // Enable UART module in RCGUART register p306
        unsafe {
            self.enable_clock();

            // Disable UART and all features
            self.reg.ctl.write(0);
            // Calculate the baud rate values
            // baud_div = CLOCK_RATE / (16 * baud_rate);
            // baud_int = round(baud_div * 64)
            let baud_int: u32 = (((pll::get_clock_hz() * 8) / self.baud) + 1) / 2;
            // Store the upper and lower parts of the divider
            self.reg.ibrd.write((baud_int / 64) as usize);
            self.reg.fbrd.write((baud_int % 64) as usize);
            // Set the UART Line Control register value
            // 8N1 + FIFO enabled
            self.reg.lcrh.write(reg::UART_LCRH_WLEN_8 | reg::UART_LCRH_FEN);
            // Clear the flags
            self.reg.rf.write(0);
            // Enable
            self.reg.ctl.write(reg::UART_CTL_RXE | reg::UART_CTL_TXE | reg::UART_CTL_UARTEN);
        }
    }

    /// Select which bits to enable in the clock gating register
    fn get_clock_gating_mask(&self) -> usize {
        match self.id {
            UartId::Uart0 => reg::SYSCTL_RCGCUART_R0,
            UartId::Uart1 => reg::SYSCTL_RCGCUART_R1,
            UartId::Uart2 => reg::SYSCTL_RCGCUART_R2,
            UartId::Uart3 => reg::SYSCTL_RCGCUART_R3,
            UartId::Uart4 => reg::SYSCTL_RCGCUART_R4,
            UartId::Uart5 => reg::SYSCTL_RCGCUART_R5,
            UartId::Uart6 => reg::SYSCTL_RCGCUART_R6,
            UartId::Uart7 => reg::SYSCTL_RCGCUART_R7,
        }
    }

    /// Enable the module in the real-time clock gating registers.
    unsafe fn enable_clock(&mut self) {
        volatile_store(reg::SYSCTL_RCGCUART_R, self.get_clock_gating_mask());
        while volatile_load(reg::SYSCTL_RCGCUART_R) != self.get_clock_gating_mask() {
            nop();
        }
    }

    #[deprecated]
    pub fn read_single(&mut self) -> Option<u8> {
        self.getc_try().ok()
    }
}

impl embedded_serial::BlockingTx for Uart {
    type Error = !;

    /// Emit a single octet, busy-waiting if the FIFO is full.
    /// Never returns `Err`.
    fn putc(&mut self, value: u8) -> Result<(), Self::Error>{
        while (self.reg.rf.read() & reg::UART_FR_TXFF) != 0 {
            nop();
        }
        self.reg.data.write(value as usize);
        Ok(())
    }
}

impl embedded_serial::NonBlockingRx for Uart {
    type Error = ();

    /// Attempts to read from the UART. Returns `Err(())`
    /// if the FIFO is empty, or `Ok(octet)`.
    fn getc_try(&mut self) -> Result<u8, Self::Error> {
        if (self.reg.rf.read() & reg::UART_FR_RXFE) != 0 {
            Err(())
        } else {
            Ok(self.reg.data.read() as u8)
        }
    }
}

/// Allows the Uart to be passed to 'write!()' and friends.
impl fmt::Write for Uart {
    fn write_str(&mut self, s: &str) -> fmt::Result {
        match self.nl_mode {
            NewlineMode::Binary => {
                for byte in s.bytes() {
                    self.putc(byte).unwrap()
                }
            }
            NewlineMode::SwapLFtoCRLF => {
                for byte in s.bytes() {
                    if byte == 0x0A {
                        // Prefix every \n with a \r
                        self.putc(0x0D).unwrap()
                    }
                    self.putc(byte).unwrap()
                }
            }
        }
        Ok(())
    }
}

/// Called when UART 0 interrupt fires
pub unsafe extern "C" fn uart0_isr() {}

// ****************************************************************************
//
// Private Functions
//
// ****************************************************************************

/// Get a reference to the UART control register struct in the chip.
fn get_uart_registers(uart_id: UartId) -> &'static mut reg::UartRegisters {
    unsafe {
        match uart_id {
            UartId::Uart0 => &mut *(reg::UART0_DR_R as *mut reg::UartRegisters),
            UartId::Uart1 => &mut *(reg::UART1_DR_R as *mut reg::UartRegisters),
            UartId::Uart2 => &mut *(reg::UART2_DR_R as *mut reg::UartRegisters),
            UartId::Uart3 => &mut *(reg::UART3_DR_R as *mut reg::UartRegisters),
            UartId::Uart4 => &mut *(reg::UART4_DR_R as *mut reg::UartRegisters),
            UartId::Uart5 => &mut *(reg::UART5_DR_R as *mut reg::UartRegisters),
            UartId::Uart6 => &mut *(reg::UART6_DR_R as *mut reg::UartRegisters),
            UartId::Uart7 => &mut *(reg::UART7_DR_R as *mut reg::UartRegisters),
        }
    }
}

// ****************************************************************************
//
// End Of File
//
// ****************************************************************************
<commit_msg>uart: implement embedded_serial::{NonBlockingTx, BlockingRx} (#1)<commit_after>//! # UART for the LM4F120H5QR

// ****************************************************************************
//
// Imports
//
// ****************************************************************************

use core::fmt;
use core::intrinsics::{volatile_load, volatile_store};

use embedded_serial::{self, BlockingTx, NonBlockingRx};
use cortex_m::asm::nop;

use super::gpio;
use super::pll;
use super::registers as reg;

// ****************************************************************************
//
// Public Types
//
// ****************************************************************************

/// This chip has 8 UARTs
#[derive(PartialEq, Clone, Copy)]
#[allow(missing_docs)]
pub enum UartId {
    Uart0,
    Uart1,
    Uart2,
    Uart3,
    Uart4,
    Uart5,
    Uart6,
    Uart7,
}

/// Controls a single UART
/// Only supports 8/N/1 - who needs anything else?
pub struct Uart {
    id: UartId,
    baud: u32,
    nl_mode: NewlineMode,
    reg: &'static mut reg::UartRegisters,
}

/// writeln!() emits LF chars, so this is useful
/// if you're writing text with your UART
#[derive(PartialEq, Clone, Copy)]
pub enum NewlineMode {
    /// Emit octets as received
    Binary,
    /// Emit an extra CR before every LF
    SwapLFtoCRLF,
}

// ****************************************************************************
//
// Private Types
//
// ****************************************************************************

// None

// ****************************************************************************
//
// Public Data
//
// ****************************************************************************

// None

// ****************************************************************************
//
// Public Functions
//
// ****************************************************************************

/// Represents a single UART on the LM4F120
impl Uart {
    /// Create a new Uart object. The caller is responsible for ensuring
    /// that only one object exists per UartId. The UART is set to
    /// 8 data bits, 1 stop bit, no parity and is not configurable.
    /// Optionally, newline translation can be performed on outbound data
    /// - this will cause writeln!() to emit a CRLF.
    pub fn new(id: UartId, baud: u32, nl_mode: NewlineMode) -> Uart {
        let mut uart = Uart {
            id: id,
            baud: baud,
            nl_mode: nl_mode,
            reg: get_uart_registers(id),
        };
        uart.init();
        uart
    }

    /// Configure the hardware
    fn init(&mut self) -> () {
        // Do GPIO pin muxing
        gpio::enable_uart(self.id);
        // Enable UART module in RCGUART register p306
        unsafe {
            self.enable_clock();

            // Disable UART and all features
            self.reg.ctl.write(0);
            // Calculate the baud rate values
            // baud_div = CLOCK_RATE / (16 * baud_rate);
            // baud_int = round(baud_div * 64)
            let baud_int: u32 = (((pll::get_clock_hz() * 8) / self.baud) + 1) / 2;
            // Store the upper and lower parts of the divider
            self.reg.ibrd.write((baud_int / 64) as usize);
            self.reg.fbrd.write((baud_int % 64) as usize);
            // Set the UART Line Control register value
            // 8N1 + FIFO enabled
            self.reg.lcrh.write(reg::UART_LCRH_WLEN_8 | reg::UART_LCRH_FEN);
            // Clear the flags
            self.reg.rf.write(0);
            // Enable
            self.reg.ctl.write(reg::UART_CTL_RXE | reg::UART_CTL_TXE | reg::UART_CTL_UARTEN);
        }
    }

    /// Select which bits to enable in the clock gating register
    fn get_clock_gating_mask(&self) -> usize {
        match self.id {
            UartId::Uart0 => reg::SYSCTL_RCGCUART_R0,
            UartId::Uart1 => reg::SYSCTL_RCGCUART_R1,
            UartId::Uart2 => reg::SYSCTL_RCGCUART_R2,
            UartId::Uart3 => reg::SYSCTL_RCGCUART_R3,
            UartId::Uart4 => reg::SYSCTL_RCGCUART_R4,
            UartId::Uart5 => reg::SYSCTL_RCGCUART_R5,
            UartId::Uart6 => reg::SYSCTL_RCGCUART_R6,
            UartId::Uart7 => reg::SYSCTL_RCGCUART_R7,
        }
    }

    /// Enable the module in the real-time clock gating registers.
    unsafe fn enable_clock(&mut self) {
        volatile_store(reg::SYSCTL_RCGCUART_R, self.get_clock_gating_mask());
        while volatile_load(reg::SYSCTL_RCGCUART_R) != self.get_clock_gating_mask() {
            nop();
        }
    }

    #[deprecated]
    pub fn read_single(&mut self) -> Option<u8> {
        self.getc_try().ok()
    }
}

impl embedded_serial::BlockingTx for Uart {
    type Error = !;

    /// Emit a single octet, busy-waiting if the FIFO is full.
    /// Never returns `Err`.
    fn putc(&mut self, value: u8) -> Result<(), Self::Error>{
        while (self.reg.rf.read() & reg::UART_FR_TXFF) != 0 {
            nop();
        }
        self.reg.data.write(value as usize);
        Ok(())
    }
}

impl embedded_serial::NonBlockingTx for Uart {
    type Error = ();

    /// Attempts to write to the UART. Returns `Err(())`
    /// if the transmit not ready, or `Ok(())`.
    fn putc_try(&mut self, value: u8) -> Result<(), Self::Error>{
        if (self.reg.rf.read() & reg::UART_FR_TXFF) != 0 {
            Err(())
        } else {
            self.reg.data.write(value as usize);
            Ok(())
        }
    }
}

impl embedded_serial::BlockingRx for Uart {
    type Error = !;

    /// Reads from the UART. Never returns `Err`.
    fn getc(&mut self) -> Result<u8, Self::Error> {
        while (self.reg.rf.read() & reg::UART_FR_RXFE) != 0 {
            nop();
        }
        Ok(self.reg.data.read() as u8)
    }
}

impl embedded_serial::NonBlockingRx for Uart {
    type Error = ();

    /// Attempts to read from the UART. Returns `Err(())`
    /// if the FIFO is empty, or `Ok(octet)`.
    fn getc_try(&mut self) -> Result<u8, Self::Error> {
        if (self.reg.rf.read() & reg::UART_FR_RXFE) != 0 {
            Err(())
        } else {
            Ok(self.reg.data.read() as u8)
        }
    }
}

/// Allows the Uart to be passed to 'write!()' and friends.
impl fmt::Write for Uart {
    fn write_str(&mut self, s: &str) -> fmt::Result {
        match self.nl_mode {
            NewlineMode::Binary => {
                for byte in s.bytes() {
                    self.putc(byte).unwrap()
                }
            }
            NewlineMode::SwapLFtoCRLF => {
                for byte in s.bytes() {
                    if byte == 0x0A {
                        // Prefix every \n with a \r
                        self.putc(0x0D).unwrap()
                    }
                    self.putc(byte).unwrap()
                }
            }
        }
        Ok(())
    }
}

/// Called when UART 0 interrupt fires
pub unsafe extern "C" fn uart0_isr() {}

// ****************************************************************************
//
// Private Functions
//
// ****************************************************************************

/// Get a reference to the UART control register struct in the chip.
fn get_uart_registers(uart_id: UartId) -> &'static mut reg::UartRegisters {
    unsafe {
        match uart_id {
            UartId::Uart0 => &mut *(reg::UART0_DR_R as *mut reg::UartRegisters),
            UartId::Uart1 => &mut *(reg::UART1_DR_R as *mut reg::UartRegisters),
            UartId::Uart2 => &mut *(reg::UART2_DR_R as *mut reg::UartRegisters),
            UartId::Uart3 => &mut *(reg::UART3_DR_R as *mut reg::UartRegisters),
            UartId::Uart4 => &mut *(reg::UART4_DR_R as *mut reg::UartRegisters),
            UartId::Uart5 => &mut *(reg::UART5_DR_R as *mut reg::UartRegisters),
            UartId::Uart6 => &mut *(reg::UART6_DR_R as *mut reg::UartRegisters),
            UartId::Uart7 => &mut *(reg::UART7_DR_R as *mut reg::UartRegisters),
        }
    }
}

// ****************************************************************************
//
// End Of File
//
// ****************************************************************************
<|endoftext|>


<commit_before>extern crate libc;

use std::ffi::CString;
use std::fs;
use std::io;
use std::os::unix::prelude::*;
use std::path::Path;

use self::libc::{c_int, c_char, timeval, time_t, suseconds_t};

use FileTime;

pub fn set_file_times(p: &Path, atime: FileTime, mtime: FileTime) -> io::Result<()> {
    set_file_times_u(p, atime, mtime, libc::utimes)
}

#[cfg(target_os = "android")]
pub fn set_symlink_file_times(_p: &Path, _atime: FileTime, _mtime: FileTime) -> io::Result<()> {
   Err(io::Error::new(io::ErrorKind::Other, "not supported on Android"))
}

#[cfg(not(target_os = "android"))]
pub fn set_symlink_file_times(p: &Path, atime: FileTime, mtime: FileTime) -> io::Result<()> {
   set_file_times_u(p, atime, mtime, libc::lutimes)
}

fn set_file_times_u(p: &Path,
                    atime: FileTime,
                    mtime: FileTime,
                    utimes: unsafe extern fn(*const c_char, *const timeval) -> c_int)
    -> io::Result<()>
{
    let times = [to_timeval(&atime), to_timeval(&mtime)];
    let p = try!(CString::new(p.as_os_str().as_bytes()));
    return if unsafe { utimes(p.as_ptr() as *const _, times.as_ptr()) == 0 } {
        Ok(())
    } else {
        Err(io::Error::last_os_error())
    };

    fn to_timeval(ft: &FileTime) -> timeval {
        timeval {
            tv_sec: ft.seconds() as time_t,
            tv_usec: (ft.nanoseconds() / 1000) as suseconds_t,
        }
    }
}

pub fn from_last_modification_time(meta: &fs::Metadata) -> FileTime {
    FileTime {
        seconds: meta.mtime() as u64,
        nanos: meta.mtime_nsec() as u32,
    }
}

pub fn from_last_access_time(meta: &fs::Metadata) -> FileTime {
    FileTime {
        seconds: meta.atime() as u64,
        nanos: meta.atime_nsec() as u32,
    }
}

pub fn from_creation_time(meta: &fs::Metadata) -> Option<FileTime> {
    macro_rules! birthtim {
        ($(($e:expr, $i:ident)),*) => {
            #[cfg(any($(target_os = $e),*))]
            fn imp(meta: &fs::Metadata) -> Option<FileTime> {
                $(
                    #[cfg(target_os = $e)]
                    use std::os::$i::fs::MetadataExt;
                )*
                let raw = meta.as_raw_stat();
                Some(FileTime {
                    seconds: raw.st_birthtime as u64,
                    nanos: raw.st_birthtime_nsec as u32,
                })
            }

            #[cfg(all($(not(target_os = $e)),*))]
            fn imp(_meta: &fs::Metadata) -> Option<FileTime> {
                None
            }
        }
    }

    birthtim! {
        ("bitrig", bitrig),
        ("freebsd", freebsd),
        ("ios", ios),
        ("macos", macos),
        ("openbsd", openbsd)
    }

    imp(meta)
}
<commit_msg>Avoid using deprecated method<commit_after>extern crate libc;

use std::ffi::CString;
use std::fs;
use std::io;
use std::os::unix::prelude::*;
use std::path::Path;

use self::libc::{c_int, c_char, timeval, time_t, suseconds_t};

use FileTime;

pub fn set_file_times(p: &Path, atime: FileTime, mtime: FileTime) -> io::Result<()> {
    set_file_times_u(p, atime, mtime, libc::utimes)
}

#[cfg(target_os = "android")]
pub fn set_symlink_file_times(_p: &Path, _atime: FileTime, _mtime: FileTime) -> io::Result<()> {
   Err(io::Error::new(io::ErrorKind::Other, "not supported on Android"))
}

#[cfg(not(target_os = "android"))]
pub fn set_symlink_file_times(p: &Path, atime: FileTime, mtime: FileTime) -> io::Result<()> {
   set_file_times_u(p, atime, mtime, libc::lutimes)
}

fn set_file_times_u(p: &Path,
                    atime: FileTime,
                    mtime: FileTime,
                    utimes: unsafe extern fn(*const c_char, *const timeval) -> c_int)
    -> io::Result<()>
{
    let times = [to_timeval(&atime), to_timeval(&mtime)];
    let p = try!(CString::new(p.as_os_str().as_bytes()));
    return if unsafe { utimes(p.as_ptr() as *const _, times.as_ptr()) == 0 } {
        Ok(())
    } else {
        Err(io::Error::last_os_error())
    };

    fn to_timeval(ft: &FileTime) -> timeval {
        timeval {
            tv_sec: ft.seconds() as time_t,
            tv_usec: (ft.nanoseconds() / 1000) as suseconds_t,
        }
    }
}

pub fn from_last_modification_time(meta: &fs::Metadata) -> FileTime {
    FileTime {
        seconds: meta.mtime() as u64,
        nanos: meta.mtime_nsec() as u32,
    }
}

pub fn from_last_access_time(meta: &fs::Metadata) -> FileTime {
    FileTime {
        seconds: meta.atime() as u64,
        nanos: meta.atime_nsec() as u32,
    }
}

pub fn from_creation_time(meta: &fs::Metadata) -> Option<FileTime> {
    macro_rules! birthtim {
        ($(($e:expr, $i:ident)),*) => {
            #[cfg(any($(target_os = $e),*))]
            fn imp(meta: &fs::Metadata) -> Option<FileTime> {
                $(
                    #[cfg(target_os = $e)]
                    use std::os::$i::fs::MetadataExt;
                )*
                Some(FileTime {
                    seconds: meta.st_birthtime() as u64,
                    nanos: meta.st_birthtime_nsec() as u32,
                })
            }

            #[cfg(all($(not(target_os = $e)),*))]
            fn imp(_meta: &fs::Metadata) -> Option<FileTime> {
                None
            }
        }
    }

    birthtim! {
        ("bitrig", bitrig),
        ("freebsd", freebsd),
        ("ios", ios),
        ("macos", macos),
        ("openbsd", openbsd)
    }

    imp(meta)
}
<|endoftext|>


<commit_before>#![feature(asm)]
#![feature(slice_concat_ext)]

use std::rand;
use std::ptr;
use std::slice::SliceConcatExt;
use std::string::*;
use std::syscall::sys_exit;
use std::thread;

macro_rules! readln {
    () => ({
        let mut buffer = String::new();
        match std::io::stdin().read_line(&mut buffer) {
            Ok(_) => Some(buffer),
            Err(_) => None
        }
    });
}

fn main() {
    println!("Type help for a command list");
    loop {
        print!("# ");
        if let Some(line) = readln!() {
            let args: Vec<String> = line.trim().split(' ').map(|arg| arg.to_string()).collect();

            if let Some(a_command) = args.get(0) {
                let console_commands = ["exit",
                                        "panic",
                                        "ptr_write",
                                        "box_write",
                                        "reboot",
                                        "shutdown",
                                        "clone",
                                        "leak_test",
                                        "test_hm",
                                        "int3"];

                match &a_command[..] {
                    command if command == console_commands[0] => unsafe {
                        sys_exit(0);
                    },
                    command if command == console_commands[1] => panic!("Test panic"),
                    command if command == console_commands[2] => {
                        let a_ptr = rand() as *mut u8;
                        unsafe {
                            ptr::write(a_ptr, rand() as u8);
                        }
                    }
                    command if command == console_commands[3] => {
                        let a_box = Box::new(rand() as u8);
                        unsafe {
                            ptr::write(Box::into_raw(a_box), rand() as u8);
                        }
                    }
                    command if command == console_commands[4] => unsafe {
                        let mut good: u8 = 2;
                        while good & 2 == 2 {
                            asm!("in al, dx" : "={al}"(good) : "{dx}"(0x64) : : "intel", "volatile");
                        }
                        asm!("out dx, al" : : "{dx}"(0x64), "{al}"(0xFE) : : "intel", "volatile");
                        loop {
                            asm!("cli" : : : : "intel", "volatile");
                            asm!("hlt" : : : : "intel", "volatile");
                        }
                    },
                    command if command == console_commands[5] => unsafe {
                        loop {
                            asm!("cli" : : : : "intel", "volatile");
                            asm!("hlt" : : : : "intel", "volatile");
                        }
                    },
                    command if command == console_commands[6] => {
                        let parent_message = "Parent Message";
                        let handle = thread::spawn(move || {
                            println!("Child after spawn: {}", parent_message);
                            return "Child message";
                        });
                        println!("Parent after spawn: {}", parent_message);
                        match handle.join() {
                            Some(child_message) => println!("Parent after join: {}", child_message),
                            None => println!("Failed to join"),
                        }
                    }
                    command if command == console_commands[7] => {
                        let mut stack_it: Vec<Box<u8>> = Vec::new();
                        loop {
                            stack_it.push(Box::new(rand() as u8))
                        }
                    }
                    command if command == console_commands[8] => {
                        ::std::hashmap::test();
                    }
                    command if command == console_commands[9] => unsafe {
                        asm!("int 3" : : : : "intel", "volatile");
                    },
                    _ => println!("Commands: {}", console_commands.join(" ")),
                }
            }
        } else {
            println!("Failed to read line from stdin");
        }
    }
}
<commit_msg>Fix build<commit_after>#![feature(asm)]
#![feature(slice_concat_ext)]

use std::rand;
use std::ptr;
use std::slice::SliceConcatExt;
use std::string::*;
use std::syscall::sys_exit;
use std::thread;

macro_rules! readln {
    () => ({
        let mut buffer = String::new();
        match std::io::stdin().read_line(&mut buffer) {
            Ok(_) => Some(buffer),
            Err(_) => None
        }
    });
}

fn main() {
    println!("Type help for a command list");
    loop {
        print!("# ");
        if let Some(line) = readln!() {
            let args: Vec<String> = line.trim().split(' ').map(|arg| arg.to_string()).collect();

            if let Some(a_command) = args.get(0) {
                let console_commands = ["exit",
                                        "panic",
                                        "ptr_write",
                                        "box_write",
                                        "reboot",
                                        "shutdown",
                                        "clone",
                                        "leak_test",
                                        "test_hm",
                                        "int3"];

                match &a_command[..] {
                    command if command == console_commands[0] => unsafe {
                        sys_exit(0);
                    },
                    command if command == console_commands[1] => panic!("Test panic"),
                    command if command == console_commands[2] => {
                        let a_ptr = rand() as *mut u8;
                        unsafe {
                            ptr::write(a_ptr, rand() as u8);
                        }
                    }
                    command if command == console_commands[3] => {
                        let a_box = Box::new(rand() as u8);
                        unsafe {
                            ptr::write(Box::into_raw(a_box), rand() as u8);
                        }
                    }
                    command if command == console_commands[4] => unsafe {
                        let mut good: u8 = 2;
                        while good & 2 == 2 {
                            asm!("in al, dx" : "={al}"(good) : "{dx}"(0x64) : : "intel", "volatile");
                        }
                        asm!("out dx, al" : : "{dx}"(0x64), "{al}"(0xFE) : : "intel", "volatile");
                        loop {
                            asm!("cli" : : : : "intel", "volatile");
                            asm!("hlt" : : : : "intel", "volatile");
                        }
                    },
                    command if command == console_commands[5] => unsafe {
                        loop {
                            asm!("cli" : : : : "intel", "volatile");
                            asm!("hlt" : : : : "intel", "volatile");
                        }
                    },
                    command if command == console_commands[6] => {
                        let parent_message = "Parent Message";
                        let handle = thread::spawn(move || {
                            println!("Child after spawn: {}", parent_message);
                            return "Child message";
                        });
                        println!("Parent after spawn: {}", parent_message);
                        match handle.join() {
                            Some(child_message) => println!("Parent after join: {}", child_message),
                            None => println!("Failed to join"),
                        }
                    },
                    command if command == console_commands[7] => {
                        let mut stack_it: Vec<Box<u8>> = Vec::new();
                        loop {
                            stack_it.push(Box::new(rand() as u8))
                        }
                    },
                    command if command == console_commands[9] => unsafe {
                        asm!("int 3" : : : : "intel", "volatile");
                    },
                    _ => println!("Commands: {}", console_commands.join(" ")),
                }
            }
        } else {
            println!("Failed to read line from stdin");
        }
    }
}
<|endoftext|>


<commit_before>//! ZLIB Compression and Decompression. Requires `zlib` feature, enabled by default
//!
//! This module contains an implementation of the ZLIB compression scheme. This
//! compression format is based on an underlying DEFLATE-encoded stream.
//!
//! # Example
//!
//! ```rust
//! use compress::zlib;
//! use std::io::File;
//!
//! let stream = File::open(&Path::new("path/to/file.flate"));
//! let decompressed = zlib::Decoder::new(stream).read_to_end();
//! ```
//!
//! # Related links
//!
//! * http://tools.ietf.org/html/rfc1950 - RFC that this implementation is based
//!   on

use std::io;

use Adler32;
use flate;

/// Structure used to decode a ZLIB-encoded stream. The wrapped stream can be
/// re-acquired through the unwrap() method.
pub struct Decoder<R> {
    hash: Adler32,
    inner: flate::Decoder<R>,
    read_header: bool,
}

impl<R: Reader> Decoder<R> {
    /// Creates a new ZLIB-stream decoder which will wrap the specified reader.
    /// This decoder also implements the `Reader` trait, and the underlying
    /// reader can be re-acquired through the `unwrap` method.
    pub fn new(r: R) -> Decoder<R> {
        Decoder {
            hash: Adler32::new(),
            inner: flate::Decoder::new(r),
            read_header: false,
        }
    }

    /// Destroys this decoder, returning the underlying reader.
    pub fn unwrap(self) -> R {
        self.inner.r
    }

    fn validate_header(&mut self) -> io::IoResult<()> {
        let cmf = try!(self.inner.r.read_byte());
        let flg = try!(self.inner.r.read_byte());
        if cmf & 0xf != 0x8 {
            return Err(io::IoError {
                kind: io::InvalidInput,
                desc: "unsupport zlib stream format",
                detail: None,
            })
        }
        if cmf & 0xf0 != 0x70 {
            return Err(io::IoError {
                kind: io::InvalidInput,
                desc: "unsupport zlib window size",
                detail: None,
            })
        }

        if flg & 0x20 != 0 {
            return Err(io::IoError {
                kind: io::InvalidInput,
                desc: "unsupported initial dictionary in the output stream",
                detail: None,
            })
        }

        if ((cmf as u16) * 256 + (flg as u16)) % 31 != 0 {
            return Err(io::IoError {
                kind: io::InvalidInput,
                desc: "invalid zlib header checksum",
                detail: None,
            })
        }
        Ok(())
    }

    /// Tests if this stream has reached the EOF point yet.
    pub fn eof(&self) -> bool { self.inner.eof() }

    #[allow(dead_code)]
    fn reset(&mut self) {
        self.inner.reset();
        self.hash.reset();
        self.read_header = false;
    }
}

impl<R: Reader> Reader for Decoder<R> {
    fn read(&mut self, buf: &mut [u8]) -> io::IoResult<uint> {
        if !self.read_header {
            try!(self.validate_header());
            self.read_header = true;
        } else if self.inner.eof() {
            return Err(io::standard_error(io::EndOfFile));
        }
        match self.inner.read(buf) {
            Ok(n) => {
                self.hash.feed(buf.slice_to(n));
                Ok(n)
            }
            Err(ref e) if e.kind == io::EndOfFile => {
                let cksum = try!(self.inner.r.read_be_u32());
                if cksum != self.hash.result() {
                    return Err(io::IoError {
                        kind: io::InvalidInput,
                        desc: "invalid checksum on zlib stream",
                        detail: None,
                    })
                }
                return Err(e.clone())
            }
            Err(e) => Err(e)
        }
    }
}

#[cfg(test)]
#[allow(warnings)]
mod test {
    use std::io::{BufReader, MemWriter};
    use std::rand;
    use std::str;
    use super::{Decoder};
    use test;

    fn test_decode(input: &[u8], output: &[u8]) {
        let mut d = Decoder::new(BufReader::new(input));
        let got = match d.read_to_end() {
            Ok(b) => b,
            Err(e) => fail!("error reading: {}", e),
        };
        assert!(got.as_slice() == output);
    }

    #[test]
    fn decode() {
        let reference = include_bin!("data/test.txt");
        test_decode(include_bin!("data/test.z.0"), reference);
        test_decode(include_bin!("data/test.z.1"), reference);
        test_decode(include_bin!("data/test.z.2"), reference);
        test_decode(include_bin!("data/test.z.3"), reference);
        test_decode(include_bin!("data/test.z.4"), reference);
        test_decode(include_bin!("data/test.z.5"), reference);
        test_decode(include_bin!("data/test.z.6"), reference);
        test_decode(include_bin!("data/test.z.7"), reference);
        test_decode(include_bin!("data/test.z.8"), reference);
        test_decode(include_bin!("data/test.z.9"), reference);
    }

    #[test]
    fn large() {
        let reference = include_bin!("data/test.large");
        test_decode(include_bin!("data/test.large.z.5"), reference);
    }

    #[test]
    fn one_byte_at_a_time() {
        let input = include_bin!("data/test.z.1");
        let mut d = Decoder::new(BufReader::new(input));
        assert!(!d.eof());
        let mut out = Vec::new();
        loop {
            match d.read_byte() {
                Ok(b) => out.push(b),
                Err(..) => break
            }
        }
        assert!(d.eof());
        assert!(out.as_slice() == include_bin!("data/test.txt"));
    }

    #[test]
    fn random_byte_lengths() {
        let input = include_bin!("data/test.z.1");
        let mut d = Decoder::new(BufReader::new(input));
        let mut out = Vec::new();
        let mut buf = [0u8, ..40];
        loop {
            match d.read(buf.mut_slice_to(1 + rand::random::<uint>() % 40)) {
                Ok(n) => {
                    out.push_all(buf.slice_to(n));
                }
                Err(..) => break
            }
        }
        assert!(out.as_slice() == include_bin!("data/test.txt"));
    }

    //fn roundtrip(bytes: &[u8]) {
    //    let mut e = Encoder::new(MemWriter::new());
    //    e.write(bytes);
    //    let encoded = e.finish().unwrap();
    //
    //    let mut d = Decoder::new(BufReader::new(encoded));
    //    let decoded = d.read_to_end();
    //    assert_eq!(decoded.as_slice(), bytes);
    //}
    //
    //#[test]
    //fn some_roundtrips() {
    //    roundtrip(bytes!("test"));
    //    roundtrip(bytes!(""));
    //    roundtrip(include_bin!("data/test.txt"));
    //}

    #[bench]
    fn decompress_speed(bh: &mut test::Bencher) {
        let input = include_bin!("data/test.z.9");
        let mut d = Decoder::new(BufReader::new(input));
        let mut output = [0u8, ..65536];
        let mut output_size = 0;
        bh.iter(|| {
            d.inner.r = BufReader::new(input);
            d.reset();
            output_size = d.read(output).unwrap();
        });
        bh.bytes = output_size as u64;
    }
}
<commit_msg>Update to rust master<commit_after>//! ZLIB Compression and Decompression. Requires `zlib` feature, enabled by default
//!
//! This module contains an implementation of the ZLIB compression scheme. This
//! compression format is based on an underlying DEFLATE-encoded stream.
//!
//! # Example
//!
//! ```rust
//! use compress::zlib;
//! use std::io::File;
//!
//! let stream = File::open(&Path::new("path/to/file.flate"));
//! let decompressed = zlib::Decoder::new(stream).read_to_end();
//! ```
//!
//! # Related links
//!
//! * http://tools.ietf.org/html/rfc1950 - RFC that this implementation is based
//!   on

use std::io;

use Adler32;
use flate;

/// Structure used to decode a ZLIB-encoded stream. The wrapped stream can be
/// re-acquired through the unwrap() method.
pub struct Decoder<R> {
    hash: Adler32,
    inner: flate::Decoder<R>,
    read_header: bool,
}

impl<R: Reader> Decoder<R> {
    /// Creates a new ZLIB-stream decoder which will wrap the specified reader.
    /// This decoder also implements the `Reader` trait, and the underlying
    /// reader can be re-acquired through the `unwrap` method.
    pub fn new(r: R) -> Decoder<R> {
        Decoder {
            hash: Adler32::new(),
            inner: flate::Decoder::new(r),
            read_header: false,
        }
    }

    /// Destroys this decoder, returning the underlying reader.
    pub fn unwrap(self) -> R {
        self.inner.r
    }

    fn validate_header(&mut self) -> io::IoResult<()> {
        let cmf = try!(self.inner.r.read_byte());
        let flg = try!(self.inner.r.read_byte());
        if cmf & 0xf != 0x8 {
            return Err(io::IoError {
                kind: io::InvalidInput,
                desc: "unsupport zlib stream format",
                detail: None,
            })
        }
        if cmf & 0xf0 != 0x70 {
            return Err(io::IoError {
                kind: io::InvalidInput,
                desc: "unsupport zlib window size",
                detail: None,
            })
        }

        if flg & 0x20 != 0 {
            return Err(io::IoError {
                kind: io::InvalidInput,
                desc: "unsupported initial dictionary in the output stream",
                detail: None,
            })
        }

        if ((cmf as u16) * 256 + (flg as u16)) % 31 != 0 {
            return Err(io::IoError {
                kind: io::InvalidInput,
                desc: "invalid zlib header checksum",
                detail: None,
            })
        }
        Ok(())
    }

    /// Tests if this stream has reached the EOF point yet.
    pub fn eof(&self) -> bool { self.inner.eof() }

    #[allow(dead_code)]
    fn reset(&mut self) {
        self.inner.reset();
        self.hash.reset();
        self.read_header = false;
    }
}

impl<R: Reader> Reader for Decoder<R> {
    fn read(&mut self, buf: &mut [u8]) -> io::IoResult<uint> {
        if !self.read_header {
            try!(self.validate_header());
            self.read_header = true;
        } else if self.inner.eof() {
            return Err(io::standard_error(io::EndOfFile));
        }
        match self.inner.read(buf) {
            Ok(n) => {
                self.hash.feed(buf.slice_to(n));
                Ok(n)
            }
            Err(ref e) if e.kind == io::EndOfFile => {
                let cksum = try!(self.inner.r.read_be_u32());
                if cksum != self.hash.result() {
                    return Err(io::IoError {
                        kind: io::InvalidInput,
                        desc: "invalid checksum on zlib stream",
                        detail: None,
                    })
                }
                return Err(e.clone())
            }
            Err(e) => Err(e)
        }
    }
}

#[cfg(test)]
#[allow(warnings)]
mod test {
    use std::io::{BufReader, MemWriter};
    use std::rand;
    use std::str;
    use super::{Decoder};
    use test;

    fn test_decode(input: &[u8], output: &[u8]) {
        let mut d = Decoder::new(BufReader::new(input));
        let got = match d.read_to_end() {
            Ok(b) => b,
            Err(e) => fail!("error reading: {}", e),
        };
        assert!(got.as_slice() == output);
    }

    #[test]
    fn decode() {
        let reference = include_bin!("data/test.txt");
        test_decode(include_bin!("data/test.z.0"), reference);
        test_decode(include_bin!("data/test.z.1"), reference);
        test_decode(include_bin!("data/test.z.2"), reference);
        test_decode(include_bin!("data/test.z.3"), reference);
        test_decode(include_bin!("data/test.z.4"), reference);
        test_decode(include_bin!("data/test.z.5"), reference);
        test_decode(include_bin!("data/test.z.6"), reference);
        test_decode(include_bin!("data/test.z.7"), reference);
        test_decode(include_bin!("data/test.z.8"), reference);
        test_decode(include_bin!("data/test.z.9"), reference);
    }

    #[test]
    fn large() {
        let reference = include_bin!("data/test.large");
        test_decode(include_bin!("data/test.large.z.5"), reference);
    }

    #[test]
    fn one_byte_at_a_time() {
        let input = include_bin!("data/test.z.1");
        let mut d = Decoder::new(BufReader::new(input));
        assert!(!d.eof());
        let mut out = Vec::new();
        loop {
            match d.read_byte() {
                Ok(b) => out.push(b),
                Err(..) => break
            }
        }
        assert!(d.eof());
        assert!(out.as_slice() == include_bin!("data/test.txt"));
    }

    #[test]
    fn random_byte_lengths() {
        let input = include_bin!("data/test.z.1");
        let mut d = Decoder::new(BufReader::new(input));
        let mut out = Vec::new();
        let mut buf = [0u8, ..40];
        loop {
            match d.read(buf.slice_to_mut(1 + rand::random::<uint>() % 40)) {
                Ok(n) => {
                    out.push_all(buf.slice_to(n));
                }
                Err(..) => break
            }
        }
        assert!(out.as_slice() == include_bin!("data/test.txt"));
    }

    //fn roundtrip(bytes: &[u8]) {
    //    let mut e = Encoder::new(MemWriter::new());
    //    e.write(bytes);
    //    let encoded = e.finish().unwrap();
    //
    //    let mut d = Decoder::new(BufReader::new(encoded));
    //    let decoded = d.read_to_end();
    //    assert_eq!(decoded.as_slice(), bytes);
    //}
    //
    //#[test]
    //fn some_roundtrips() {
    //    roundtrip(bytes!("test"));
    //    roundtrip(bytes!(""));
    //    roundtrip(include_bin!("data/test.txt"));
    //}

    #[bench]
    fn decompress_speed(bh: &mut test::Bencher) {
        let input = include_bin!("data/test.z.9");
        let mut d = Decoder::new(BufReader::new(input));
        let mut output = [0u8, ..65536];
        let mut output_size = 0;
        bh.iter(|| {
            d.inner.r = BufReader::new(input);
            d.reset();
            output_size = d.read(output).unwrap();
        });
        bh.bytes = output_size as u64;
    }
}
<|endoftext|>


<commit_before>//! Utility module to generate a GraphiQL interface

/// Generate the HTML source to show a GraphiQL interface
pub fn graphiql_source(graphql_endpoint_url: &str) -> String {
    let stylesheet_source = r#"

    "#;
    let fetcher_source = r#"

    "#;

    format!(r#"
<!DOCTYPE html>

    <title>GraphQL</title>
    {stylesheet_source}
    <link rel="stylesheet" type="text/css" href="//cdnjs.cloudflare.com/ajax/libs/graphiql/0.10.2/graphiql.css">

    {fetcher_source}

"#,
        graphql_url = graphql_endpoint_url,
        stylesheet_source = stylesheet_source,
        fetcher_source = fetcher_source)
}
<commit_msg>Use latest graphiql (v0.17.2) (#477)<commit_after>//! Utility module to generate a GraphiQL interface

/// Generate the HTML source to show a GraphiQL interface
pub fn graphiql_source(graphql_endpoint_url: &str) -> String {
    let stylesheet_source = r#"

    "#;
    let fetcher_source = r#"

    "#;

    format!(r#"
<!DOCTYPE html>

    <title>GraphQL</title>
    {stylesheet_source}
    <link rel="stylesheet" type="text/css" href="//cdn.jsdelivr.net/npm/graphiql@0.17.2/graphiql.min.css">

    {fetcher_source}

"#,
        graphql_url = graphql_endpoint_url,
        stylesheet_source = stylesheet_source,
        fetcher_source = fetcher_source)
}
<|endoftext|>


<commit_before>use {
    BackEnd,
    Borrowed,
    Color,
    Field,
    Fill,
    Matrix2d,
    Value,
    View,
};
use vecmath::{
    identity
};
use triangulation::{
    with_lerp_polygons_tri_list_xy_f32_rgba_f32
};
use internal::{
    CanColor,
    CanTransform,
    HasColor,
    HasTransform,
};

/// An animation inbetweening context with color.
pub struct TweenPolygonsColorContext<'a> {
    /// Base/origin transform.
    pub base: Field<'a, Matrix2d>,
    /// Current transform.
    pub transform: Field<'a, Matrix2d>,
    /// Current color.
    pub color: Field<'a, Color>,
    /// Animation inbetweening factor.
    pub tween_factor: Field<'a, f64>,
    /// The animated polygons.
    pub polygons: Field<'a, &'a [&'a [f64]]>,
}

impl<'a> HasColor<'a, Color> for TweenPolygonsColorContext<'a> {
    #[inline(always)]
    fn get_color(&'a self) -> &'a Color {
        self.color.get()
    }
}

impl<'a> CanColor<'a, TweenPolygonsColorContext<'a>, Color> for TweenPolygonsColorContext<'a> {
    #[inline(always)]
    fn color(&'a self, value: Color) -> TweenPolygonsColorContext<'a> {
        TweenPolygonsColorContext {
            base: Borrowed(self.base.get()),
            transform: Borrowed(self.transform.get()),
            color: Value(value),
            tween_factor: Borrowed(self.tween_factor.get()),
            polygons: Borrowed(self.polygons.get()),
        }
    }
}

impl<'a> HasTransform<'a, Matrix2d> for TweenPolygonsColorContext<'a> {
    #[inline(alwyas)]
    fn get_transform(&'a self) -> &'a Matrix2d {
        self.transform.get()
    }
}

impl<'a> CanTransform<'a, TweenPolygonsColorContext<'a>, Matrix2d> for TweenPolygonsColorContext<'a> {
    #[inline(always)]
    fn transform(&'a self, value: Matrix2d) -> TweenPolygonsColorContext<'a> {
        TweenPolygonsColorContext {
            base: Borrowed(self.base.get()),
            transform: Value(value),
            color: Borrowed(self.color.get()),
            tween_factor: Borrowed(self.tween_factor.get()),
            polygons: Borrowed(self.polygons.get()),
        }
    }
}

impl<'a> Fill<'a> for TweenPolygonsColorContext<'a> {
    fn fill<B: BackEnd>(&'a self, back_end: &mut B) {
        if back_end.supports_tri_list_xy_f32_rgba_f32() {
            let polygons = self.polygons.get();
            let color = self.color.get();
            let color: [f32, ..4] = [color[0], color[1], color[2], color[3]];
            // Complete transparency does not need to be rendered.
            if color[3] == 0.0 { return; }
            // Turn on alpha blending if not completely opaque.
            let needs_alpha = color[3] != 1.0;
            if needs_alpha { back_end.enable_alpha_blend(); }
            with_lerp_polygons_tri_list_xy_f32_rgba_f32(
                self.transform.get(),
                *polygons,
                *self.tween_factor.get(),
                color,
                |vertices, colors| {
                    back_end.tri_list_xy_f32_rgba_f32(vertices, colors)
                }
            );
            if needs_alpha { back_end.disable_alpha_blend(); }
        } else {
            unimplemented!();
        }
    }
}

impl<'a> View<'a> for TweenPolygonsColorContext<'a> {
    #[inline(always)]
    fn view(&'a self) -> TweenPolygonsColorContext<'a> {
        TweenPolygonsColorContext {
            base: Borrowed(self.base.get()),
            transform: Borrowed(self.base.get()),
            polygons: Borrowed(self.polygons.get()),
            color: Borrowed(self.color.get()),
            tween_factor: Borrowed(self.tween_factor.get()),
        }
    }

    #[inline(always)]
    fn reset(&'a self) -> TweenPolygonsColorContext<'a> {
        TweenPolygonsColorContext {
            base: Borrowed(self.base.get()),
            transform: Value(identity()),
            polygons: Borrowed(self.polygons.get()),
            color: Borrowed(self.color.get()),
            tween_factor: Borrowed(self.tween_factor.get()),
        }
    }

    #[inline(always)]
    fn store_view(&'a self) -> TweenPolygonsColorContext<'a> {
        TweenPolygonsColorContext {
            base: Borrowed(self.transform.get()),
            transform: Borrowed(self.transform.get()),
            polygons: Borrowed(self.polygons.get()),
            color: Borrowed(self.color.get()),
            tween_factor: Borrowed(self.tween_factor.get()),
        }
    }
}

<commit_msg>Implemented `Clear` for `TweenPolygonsColorContext`<commit_after>use {
    BackEnd,
    Borrowed,
    Clear,
    Color,
    Field,
    Fill,
    Matrix2d,
    Value,
    View,
};
use vecmath::{
    identity
};
use triangulation::{
    with_lerp_polygons_tri_list_xy_f32_rgba_f32
};
use internal::{
    CanColor,
    CanTransform,
    HasColor,
    HasTransform,
};

/// An animation inbetweening context with color.
pub struct TweenPolygonsColorContext<'a> {
    /// Base/origin transform.
    pub base: Field<'a, Matrix2d>,
    /// Current transform.
    pub transform: Field<'a, Matrix2d>,
    /// Current color.
    pub color: Field<'a, Color>,
    /// Animation inbetweening factor.
    pub tween_factor: Field<'a, f64>,
    /// The animated polygons.
    pub polygons: Field<'a, &'a [&'a [f64]]>,
}

impl<'a> HasColor<'a, Color> for TweenPolygonsColorContext<'a> {
    #[inline(always)]
    fn get_color(&'a self) -> &'a Color {
        self.color.get()
    }
}

impl<'a> CanColor<'a, TweenPolygonsColorContext<'a>, Color> for TweenPolygonsColorContext<'a> {
    #[inline(always)]
    fn color(&'a self, value: Color) -> TweenPolygonsColorContext<'a> {
        TweenPolygonsColorContext {
            base: Borrowed(self.base.get()),
            transform: Borrowed(self.transform.get()),
            color: Value(value),
            tween_factor: Borrowed(self.tween_factor.get()),
            polygons: Borrowed(self.polygons.get()),
        }
    }
}

impl<'a> HasTransform<'a, Matrix2d> for TweenPolygonsColorContext<'a> {
    #[inline(alwyas)]
    fn get_transform(&'a self) -> &'a Matrix2d {
        self.transform.get()
    }
}

impl<'a> CanTransform<'a, TweenPolygonsColorContext<'a>, Matrix2d> for TweenPolygonsColorContext<'a> {
    #[inline(always)]
    fn transform(&'a self, value: Matrix2d) -> TweenPolygonsColorContext<'a> {
        TweenPolygonsColorContext {
            base: Borrowed(self.base.get()),
            transform: Value(value),
            color: Borrowed(self.color.get()),
            tween_factor: Borrowed(self.tween_factor.get()),
            polygons: Borrowed(self.polygons.get()),
        }
    }
}

impl<'a> Fill<'a> for TweenPolygonsColorContext<'a> {
    fn fill<B: BackEnd>(&'a self, back_end: &mut B) {
        if back_end.supports_tri_list_xy_f32_rgba_f32() {
            let polygons = self.polygons.get();
            let color = self.color.get();
            let color: [f32, ..4] = [color[0], color[1], color[2], color[3]];
            // Complete transparency does not need to be rendered.
            if color[3] == 0.0 { return; }
            // Turn on alpha blending if not completely opaque.
            let needs_alpha = color[3] != 1.0;
            if needs_alpha { back_end.enable_alpha_blend(); }
            with_lerp_polygons_tri_list_xy_f32_rgba_f32(
                self.transform.get(),
                *polygons,
                *self.tween_factor.get(),
                color,
                |vertices, colors| {
                    back_end.tri_list_xy_f32_rgba_f32(vertices, colors)
                }
            );
            if needs_alpha { back_end.disable_alpha_blend(); }
        } else {
            unimplemented!();
        }
    }
}

impl<'a> View<'a> for TweenPolygonsColorContext<'a> {
    #[inline(always)]
    fn view(&'a self) -> TweenPolygonsColorContext<'a> {
        TweenPolygonsColorContext {
            base: Borrowed(self.base.get()),
            transform: Borrowed(self.base.get()),
            polygons: Borrowed(self.polygons.get()),
            color: Borrowed(self.color.get()),
            tween_factor: Borrowed(self.tween_factor.get()),
        }
    }

    #[inline(always)]
    fn reset(&'a self) -> TweenPolygonsColorContext<'a> {
        TweenPolygonsColorContext {
            base: Borrowed(self.base.get()),
            transform: Value(identity()),
            polygons: Borrowed(self.polygons.get()),
            color: Borrowed(self.color.get()),
            tween_factor: Borrowed(self.tween_factor.get()),
        }
    }

    #[inline(always)]
    fn store_view(&'a self) -> TweenPolygonsColorContext<'a> {
        TweenPolygonsColorContext {
            base: Borrowed(self.transform.get()),
            transform: Borrowed(self.transform.get()),
            polygons: Borrowed(self.polygons.get()),
            color: Borrowed(self.color.get()),
            tween_factor: Borrowed(self.tween_factor.get()),
        }
    }
}

impl<'a> Clear for TweenPolygonsColorContext<'a> {
    fn clear<B: BackEnd>(&self, back_end: &mut B) {
        if back_end.supports_clear_rgba() {
            let color = self.color.get();
            back_end.clear_rgba(color[0], color[1], color[2], color[3]);
        }
    }
}

<|endoftext|>