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

#![allow(unused_imports)]  // for quotes

use std::old_io as io;
use std::path;
use std::str::FromStr;
use std::collections::HashMap;

use rustc_serialize::json;
use rustc_serialize::json::Json;
use rustc_serialize::Decodable;
use syntax::codemap::Span;
use syntax::ast::{Path, ExprLit, Lit_, TokenTree, TtToken};
use syntax::parse::token;
use syntax::ext::base::{ExtCtxt, MacResult, MacExpr};
use syntax::ext::source_util::expand_file;

// A struct matching the entries in entities.json.
// Simplifies JSON parsing because we can use Decodable.
#[derive(RustcDecodable)]
struct CharRef {
    codepoints: Vec<u32>,
    //characters: String,  // Present in the file but we don't need it
}

// Build the map from entity names (and their prefixes) to characters.
fn build_map(js: Json) -> Option<HashMap<String, [u32; 2]>> {
    let mut map = HashMap::new();
    let json_map = match js {
        Json::Object(m) => m,
        _ => return None,
    };

    // Add every named entity to the map.
    for (k,v) in json_map.into_iter() {
        let mut decoder = json::Decoder::new(v);
        let CharRef { codepoints }: CharRef
            = Decodable::decode(&mut decoder).ok().expect("bad CharRef");

        assert!((codepoints.len() >= 1) && (codepoints.len() <= 2));
        let mut codepoint_pair = [0, 0];
        for (i,n) in codepoints.into_iter().enumerate() {
            codepoint_pair[i] = n;
        }

        // Slice off the initial '&'
        assert!(k.as_slice().char_at(0) == '&');
        map.insert(k[1..].to_string(), codepoint_pair);
    }

    // Add every missing prefix of those keys, mapping to NULL characters.
    map.insert("".to_string(), [0, 0]);
    let keys: Vec<String> = map.keys().map(|k| k.to_string()).collect();
    for k in keys.into_iter() {
        for n in range(1, k.len()) {
            let pfx = k[..n].to_string();
            if !map.contains_key(&pfx) {
                map.insert(pfx, [0, 0]);
            }
        }
    }

    Some(map)
}

// Expand named_entities!("path/to/entities.json") into an invocation of phf_map!().
pub fn expand(cx: &mut ExtCtxt, sp: Span, tt: &[TokenTree]) -> Box<MacResult+'static> {
    let usage = "Usage: named_entities!(\"path/to/entities.json\")";

    // Argument to the macro should be a single literal string: a path to
    // entities.json, relative to the file containing the macro invocation.
    let json_filename = match tt {
        [TtToken(_, token::Literal(token::Lit::Str_(s), _))] => s.as_str().to_string(),
        _ => bail!(cx, sp, usage),
    };

    // Get the result of calling file!() in the same place as our macro.
    // This would be a lot nicer if @-patterns were still supported.
    let mod_filename = expect!(cx, sp, match expand_file(cx, sp, &[]).make_expr() {
        Some(e) => match e.node {
            ExprLit(ref s) => match s.node {
                Lit_::LitStr(ref s, _) => Some(s.get().to_string()),
                _ => None,
            },
            _ => None,
        },
        _ => None,
    }, "unexpected result from file!()");

    // Combine those to get an absolute path to entities.json.
    let mod_path: path::Path = expect!(cx, sp, FromStr::from_str(mod_filename.as_slice()).ok(),
        "can't parse module filename");
    let json_path = mod_path.dir_path().join(json_filename);

    // Open the JSON file, parse it, and build the map from names to characters.
    let mut json_file = expect!(cx, sp, io::File::open(&json_path).ok(),
        "can't open JSON file");
    let js = expect!(cx, sp, json::from_reader(&mut json_file as &mut Reader).ok(),
        "can't parse JSON file");
    let map = expect!(cx, sp, build_map(js),
        "JSON file does not match entities.json format");

    // Emit a macro invocation of the form
    //
    //     phf_map!(k => v, k => v, ...)
    let toks: Vec<_> = map.into_iter().flat_map(|(k, [c0, c1])| {
        let k = k.as_slice();
        (quote_tokens!(&mut *cx, $k => [$c0, $c1],)).into_iter()
    }).collect();
    MacExpr::new(quote_expr!(&mut *cx, phf_map!($toks)))
}
<commit_msg>Rustup path -> old_path<commit_after>// Copyright 2014 The html5ever Project Developers. See the
// COPYRIGHT file at the top-level directory of this distribution.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![allow(unused_imports)]  // for quotes

use std::old_io as io;
use std::old_path as path;
use std::str::FromStr;
use std::collections::HashMap;

use rustc_serialize::json;
use rustc_serialize::json::Json;
use rustc_serialize::Decodable;
use syntax::codemap::Span;
use syntax::ast::{Path, ExprLit, Lit_, TokenTree, TtToken};
use syntax::parse::token;
use syntax::ext::base::{ExtCtxt, MacResult, MacExpr};
use syntax::ext::source_util::expand_file;

// A struct matching the entries in entities.json.
// Simplifies JSON parsing because we can use Decodable.
#[derive(RustcDecodable)]
struct CharRef {
    codepoints: Vec<u32>,
    //characters: String,  // Present in the file but we don't need it
}

// Build the map from entity names (and their prefixes) to characters.
fn build_map(js: Json) -> Option<HashMap<String, [u32; 2]>> {
    let mut map = HashMap::new();
    let json_map = match js {
        Json::Object(m) => m,
        _ => return None,
    };

    // Add every named entity to the map.
    for (k,v) in json_map.into_iter() {
        let mut decoder = json::Decoder::new(v);
        let CharRef { codepoints }: CharRef
            = Decodable::decode(&mut decoder).ok().expect("bad CharRef");

        assert!((codepoints.len() >= 1) && (codepoints.len() <= 2));
        let mut codepoint_pair = [0, 0];
        for (i,n) in codepoints.into_iter().enumerate() {
            codepoint_pair[i] = n;
        }

        // Slice off the initial '&'
        assert!(k.as_slice().char_at(0) == '&');
        map.insert(k[1..].to_string(), codepoint_pair);
    }

    // Add every missing prefix of those keys, mapping to NULL characters.
    map.insert("".to_string(), [0, 0]);
    let keys: Vec<String> = map.keys().map(|k| k.to_string()).collect();
    for k in keys.into_iter() {
        for n in range(1, k.len()) {
            let pfx = k[..n].to_string();
            if !map.contains_key(&pfx) {
                map.insert(pfx, [0, 0]);
            }
        }
    }

    Some(map)
}

// Expand named_entities!("path/to/entities.json") into an invocation of phf_map!().
pub fn expand(cx: &mut ExtCtxt, sp: Span, tt: &[TokenTree]) -> Box<MacResult+'static> {
    let usage = "Usage: named_entities!(\"path/to/entities.json\")";

    // Argument to the macro should be a single literal string: a path to
    // entities.json, relative to the file containing the macro invocation.
    let json_filename = match tt {
        [TtToken(_, token::Literal(token::Lit::Str_(s), _))] => s.as_str().to_string(),
        _ => bail!(cx, sp, usage),
    };

    // Get the result of calling file!() in the same place as our macro.
    // This would be a lot nicer if @-patterns were still supported.
    let mod_filename = expect!(cx, sp, match expand_file(cx, sp, &[]).make_expr() {
        Some(e) => match e.node {
            ExprLit(ref s) => match s.node {
                Lit_::LitStr(ref s, _) => Some(s.get().to_string()),
                _ => None,
            },
            _ => None,
        },
        _ => None,
    }, "unexpected result from file!()");

    // Combine those to get an absolute path to entities.json.
    let mod_path: path::Path = expect!(cx, sp, FromStr::from_str(mod_filename.as_slice()).ok(),
        "can't parse module filename");
    let json_path = mod_path.dir_path().join(json_filename);

    // Open the JSON file, parse it, and build the map from names to characters.
    let mut json_file = expect!(cx, sp, io::File::open(&json_path).ok(),
        "can't open JSON file");
    let js = expect!(cx, sp, json::from_reader(&mut json_file as &mut Reader).ok(),
        "can't parse JSON file");
    let map = expect!(cx, sp, build_map(js),
        "JSON file does not match entities.json format");

    // Emit a macro invocation of the form
    //
    //     phf_map!(k => v, k => v, ...)
    let toks: Vec<_> = map.into_iter().flat_map(|(k, [c0, c1])| {
        let k = k.as_slice();
        (quote_tokens!(&mut *cx, $k => [$c0, $c1],)).into_iter()
    }).collect();
    MacExpr::new(quote_expr!(&mut *cx, phf_map!($toks)))
}
<|endoftext|>


<commit_before>//! The Ref object is a helper over the link functionality, so one is able to create references to
//! files outside of the imag store.

use std::path::PathBuf;
use std::ops::Deref;
use std::ops::DerefMut;
use std::collections::BTreeMap;
use std::fs::File;
use std::io::Read;

use libimagstore::store::FileLockEntry;
use libimagstore::storeid::StoreId;
use libimagstore::storeid::IntoStoreId;
use libimagstore::store::Store;
use libimagerror::into::IntoError;

use toml::Value;
use crypto::sha1::Sha1;
use crypto::digest::Digest;

use error::RefErrorKind as REK;
use flags::RefFlags;
use result::Result;
use module_path::ModuleEntryPath;

pub struct Ref<'a>(FileLockEntry<'a>);

impl<'a> Ref<'a> {

    /// Try to get `si` as Ref object from the store
    pub fn get(store: &'a Store, si: StoreId) -> Result<Ref<'a>> {
        match store.get(si) {
            Err(e) => return Err(REK::StoreReadError.into_error_with_cause(Box::new(e))),
            Ok(None) => return Err(REK::RefNotInStore.into_error()),
            Ok(Some(fle)) => Ref::read_reference(&fle).map(|_| Ref(fle)),
        }
    }

    fn read_reference(fle: &FileLockEntry<'a>) -> Result<PathBuf> {
        match fle.get_header().read("ref.reference") {
            Ok(Some(Value::String(s))) => Ok(PathBuf::from(s)),
            Ok(Some(_)) => Err(REK::HeaderTypeError.into_error()),
            Ok(None)    => Err(REK::HeaderFieldMissingError.into_error()),
            Err(e)      => Err(REK::StoreReadError.into_error_with_cause(Box::new(e))),
        }
    }

    /// Create a Ref object which refers to `pb`
    pub fn create(store: &'a Store, pb: PathBuf, flags: RefFlags) -> Result<Ref<'a>> {
        if !pb.exists() {
            return Err(REK::RefTargetDoesNotExist.into_error());
        }
        if flags.get_content_hashing() && pb.is_dir() {
            return Err(REK::RefTargetCannotBeHashed.into_error());
        }

        let (mut fle, content_hash, permissions, canonical_path) = { // scope to be able to fold
            try!(File::open(pb.clone())
                .map_err(Box::new)
                .map_err(|e| REK::RefTargetFileCannotBeOpened.into_error_with_cause(e))

                // If we were able to open this file,
                // we hash the contents of the file and return (file, hash)
                .and_then(|mut file| {
                    let opt_contenthash = if flags.get_content_hashing() {
                        Some(hash_file_contents(&mut file))
                    } else {
                        None
                    };

                    Ok((file, opt_contenthash))
                })

                // and then we get the permissions if we have to
                // and return (file, content hash, permissions)
                .and_then(|(file, opt_contenthash)| {
                    let opt_permissions = if flags.get_permission_tracking() {
                        Some(try!(file
                                  .metadata()
                                  .map(|md| md.permissions())
                                  .map_err(Box::new)
                                  .map_err(|e| REK::RefTargetCannotReadPermissions.into_error_with_cause(e))
                        ))
                    } else {
                        None
                    };

                    Ok((file, opt_contenthash, opt_permissions))
                })

                // and then we try to canonicalize the PathBuf, because we want to store a
                // canonicalized path
                // and return (file, content hash, permissions, canonicalized path)
                .and_then(|(file, opt_contenthash, opt_permissions)| {
                    pb.canonicalize()
                        .map(|can| (file, opt_contenthash, opt_permissions, can))
                        // if PathBuf::canonicalize() failed, build an error from the return value
                        .map_err(|e| REK::PathCanonicalizationError.into_error_with_cause(Box::new(e)))
                })

                // and then we hash the canonicalized path
                // and return (file, content hash, permissions, canonicalized path, path hash)
                .and_then(|(file, opt_contenthash, opt_permissions, can)| {
                    let path_hash = try!(Ref::hash_path(&can)
                        .map_err(Box::new)
                        .map_err(|e| REK::PathHashingError.into_error_with_cause(e))
                    );

                    Ok((file, opt_contenthash, opt_permissions, can, path_hash))
                })

                // and then we convert the PathBuf of the canonicalized path to a String to be able
                // to save it in the Ref FileLockEntry obj
                // and return
                // (file, content hash, permissions, canonicalized path as String, path hash)
                .and_then(|(file, opt_conhash, opt_perm, can, path_hash)| {
                    match can.to_str().map(String::from) {
                        // UTF convert error in PathBuf::to_str(),
                        None      => Err(REK::PathUTF8Error.into_error()),
                        Some(can) => Ok((file, opt_conhash, opt_perm, can, path_hash))
                    }
                })

                // and then we create the FileLockEntry in the Store
                // and return (filelockentry, content hash, permissions, canonicalized path)
                .and_then(|(file, opt_conhash, opt_perm, can, path_hash)| {
                    let fle = try!(store
                                   .create(ModuleEntryPath::new(path_hash))
                                   .map_err(Box::new)
                                   .map_err(|e| REK::StoreWriteError.into_error_with_cause(e))
                    );

                    Ok((fle, opt_conhash, opt_perm, can))
                })
            )
        };

        for tpl in [
                Some(("ref",             Value::Table(BTreeMap::new()))),
                Some(("ref.permissions", Value::Table(BTreeMap::new()))),

                Some(("ref.path", Value::String(canonical_path))),

                content_hash.map(|h| ("ref.content_hash", Value::String(h))),
                permissions.map(|p| ("ref.permissions.ro", Value::Boolean(p.readonly()))),
            ].into_iter()
        {
            match tpl {
                &Some((ref s, ref v)) => {
                    match fle.get_header_mut().insert(s, v.clone()) {
                        Ok(false) => {
                            let e = REK::HeaderFieldAlreadyExistsError.into_error();
                            let e = Box::new(e);
                            let e = REK::HeaderFieldWriteError.into_error_with_cause(e);
                            return Err(e);
                        },
                        Err(e) => {
                            let e = Box::new(e);
                            let e = REK::HeaderFieldWriteError.into_error_with_cause(e);
                            return Err(e);
                        },
                        _ => (),
                    }
                }
                &None => {
                    debug!("Not going to insert.");
                }
            }
        }

        Ok(Ref(fle))
    }

    /// Creates a Hash from a PathBuf by making the PathBuf absolute and then running a hash
    /// algorithm on it
    fn hash_path(pb: &PathBuf) -> Result<String> {
        use std::io::Read;
        use crypto::sha1::Sha1;
        use crypto::digest::Digest;

        match pb.to_str() {
            Some(s) => {
                let mut hasher = Sha1::new();
                hasher.input_str(s);
                Ok(hasher.result_str())
            },
            None => return Err(REK::PathUTF8Error.into_error()),
        }
    }

    /// check whether the pointer the Ref represents still points to a file which exists
    pub fn fs_link_exists(&self) -> Result<bool> {
        self.fs_file().map(|pathbuf| pathbuf.exists())
    }

    /// Alias for `r.fs_link_exists() && r.deref().is_file()`
    pub fn is_ref_to_file(&self) -> Result<bool> {
        self.fs_file().map(|pathbuf| pathbuf.is_file())
    }

    /// Alias for `r.fs_link_exists() && r.deref().is_dir()`
    pub fn is_ref_to_dir(&self) -> Result<bool> {
        self.fs_file().map(|pathbuf| pathbuf.is_dir())
    }

    /// Alias for `!Ref::fs_link_exists()`
    pub fn is_dangling(&self) -> Result<bool> {
        self.fs_link_exists().map(|b| !b)
    }

    /// check whether the pointer the Ref represents is valid
    /// This includes:
    ///     - Hashsum of the file is still the same as stored in the Ref
    ///     - file permissions are still valid
    pub fn fs_link_valid(&self) -> bool {
        unimplemented!()
    }

    /// Check whether the file permissions of the referenced file are equal to the stored
    /// permissions
    pub fn fs_link_valid_permissions(&self) -> bool {
        unimplemented!()
    }

    /// Check whether the Hashsum of the referenced file is equal to the stored hashsum
    pub fn fs_link_valid_hash(&self) -> Result<bool> {
        let stored_hash = try!(match self.0.get_header().read("ref.content_hash") {
            // content hash stored...
            Ok(Some(Value::String(s))) => Ok(s),

            // content hash header field has wrong type
            Ok(Some(_)) => Err(REK::HeaderTypeError.into_error()),

            // content hash not stored
            Ok(None) => Err(REK::HeaderFieldMissingError.into_error()),

            // Error
            Err(e) => Err(REK::StoreReadError.into_error_with_cause(Box::new(e))),
        });

        let current_hash = try!(self.fs_file()
            .and_then(|pb| {
                File::open(pb)
                    .map_err(Box::new)
                    .map_err(|e| REK::IOError.into_error_with_cause(e))
            })
            .map(|mut file| hash_file_contents(&mut file))
        );

        Ok(stored_hash == current_hash)
    }

    /// Update the Ref by re-checking the file from FS
    /// This errors if the file is not present or cannot be read()
    pub fn update_ref(&mut self) -> Result<()> {
        unimplemented!()
    }

    /// Get the path of the file which is reffered to by this Ref
    pub fn fs_file(&self) -> Result<PathBuf> {
        match self.0.get_header().read("ref.path") {
            Ok(Some(Value::String(ref s))) => Ok(PathBuf::from(s)),
            Ok(Some(_)) => Err(REK::HeaderTypeError.into_error()),
            Ok(None)    => Err(REK::HeaderFieldMissingError.into_error()),
            Err(e)      => Err(REK::StoreReadError.into_error_with_cause(Box::new(e))),
        }
    }

    /// Check whether there is a reference to the file at `pb`
    pub fn exists(store: &Store, pb: PathBuf) -> Result<bool> {
        pb.canonicalize()
            .map_err(Box::new)
            .map_err(|e| REK::PathCanonicalizationError.into_error_with_cause(e))
            .and_then(|can| {
                Ref::hash_path(&can)
                    .map_err(Box::new)
                    .map_err(|e| REK::PathHashingError.into_error_with_cause(e))
            })
            .and_then(|hash| {
                store.retrieve_for_module("ref").map(|iter| (hash, iter))
                    .map_err(Box::new)
                    .map_err(|e| REK::StoreReadError.into_error_with_cause(e))
            })
            .and_then(|(hash, possible_refs)| {
                // This is kind of a manual Iterator::filter() call what we do here, but with the
                // actual ::filter method we cannot return the error in a nice way, so we do it
                // manually here. If you can come up with a better version of this, feel free to
                // take this note as a todo.
                for r in possible_refs {
                    let contains_hash = match r.to_str() {
                        None => { // couldn't parse StoreId -> PathBuf -> &str
                            // TODO: How to report this?
                            return Err(REK::TypeConversionError.into_error());
                        },
                        Some(s) => s.contains(&hash[..]),
                    };

                    if !contains_hash {
                        continue;
                    }

                    match store.get(r) {
                        Ok(Some(fle)) => {
                            if Ref::read_reference(&fle).map(|path| path == pb).unwrap_or(false) {
                                return Ok(true)
                            }
                        },

                        Ok(None) => { // Something weird just happened
                            return Err(REK::StoreReadError.into_error());
                        },

                        Err(e) => {
                            return Err(REK::StoreReadError.into_error_with_cause(Box::new(e)));
                        },
                    }
                }

                Ok(false)
            })
    }

    /// Re-find a referenced file
    ///
    /// This function tries to re-find a ref by searching all directories in `search_roots` recursively
    /// for a file which matches the hash of the Ref `ref`.
    ///
    /// If `search_roots` is `None`, it starts at the filesystem root `/`.
    ///
    /// # Warning
    ///
    /// This option causes heavy I/O as it recursively searches the Filesystem.
    pub fn refind(&self, search_roots: Option<Vec<PathBuf>>) -> Option<PathBuf> {
        unimplemented!()
    }

}

impl<'a> Deref for Ref<'a> {
    type Target = FileLockEntry<'a>;

    fn deref(&self) -> &FileLockEntry<'a> {
        &self.0
    }

}

impl<'a> DerefMut for Ref<'a> {

    fn deref_mut(&mut self) -> &mut FileLockEntry<'a> {
        &mut self.0
    }

}

fn hash_file_contents(f: &mut File) -> String {
    let mut hasher = Sha1::new();
    let mut s = String::new();
    f.read_to_string(&mut s);
    hasher.input_str(&s[..]);
    hasher.result_str()
}

<commit_msg>Impl Ref::fs_link_valid_permissions()<commit_after>//! The Ref object is a helper over the link functionality, so one is able to create references to
//! files outside of the imag store.

use std::path::PathBuf;
use std::ops::Deref;
use std::ops::DerefMut;
use std::collections::BTreeMap;
use std::fs::File;
use std::io::Read;

use libimagstore::store::FileLockEntry;
use libimagstore::storeid::StoreId;
use libimagstore::storeid::IntoStoreId;
use libimagstore::store::Store;
use libimagerror::into::IntoError;

use toml::Value;
use crypto::sha1::Sha1;
use crypto::digest::Digest;

use error::RefErrorKind as REK;
use flags::RefFlags;
use result::Result;
use module_path::ModuleEntryPath;

pub struct Ref<'a>(FileLockEntry<'a>);

impl<'a> Ref<'a> {

    /// Try to get `si` as Ref object from the store
    pub fn get(store: &'a Store, si: StoreId) -> Result<Ref<'a>> {
        match store.get(si) {
            Err(e) => return Err(REK::StoreReadError.into_error_with_cause(Box::new(e))),
            Ok(None) => return Err(REK::RefNotInStore.into_error()),
            Ok(Some(fle)) => Ref::read_reference(&fle).map(|_| Ref(fle)),
        }
    }

    fn read_reference(fle: &FileLockEntry<'a>) -> Result<PathBuf> {
        match fle.get_header().read("ref.reference") {
            Ok(Some(Value::String(s))) => Ok(PathBuf::from(s)),
            Ok(Some(_)) => Err(REK::HeaderTypeError.into_error()),
            Ok(None)    => Err(REK::HeaderFieldMissingError.into_error()),
            Err(e)      => Err(REK::StoreReadError.into_error_with_cause(Box::new(e))),
        }
    }

    /// Create a Ref object which refers to `pb`
    pub fn create(store: &'a Store, pb: PathBuf, flags: RefFlags) -> Result<Ref<'a>> {
        if !pb.exists() {
            return Err(REK::RefTargetDoesNotExist.into_error());
        }
        if flags.get_content_hashing() && pb.is_dir() {
            return Err(REK::RefTargetCannotBeHashed.into_error());
        }

        let (mut fle, content_hash, permissions, canonical_path) = { // scope to be able to fold
            try!(File::open(pb.clone())
                .map_err(Box::new)
                .map_err(|e| REK::RefTargetFileCannotBeOpened.into_error_with_cause(e))

                // If we were able to open this file,
                // we hash the contents of the file and return (file, hash)
                .and_then(|mut file| {
                    let opt_contenthash = if flags.get_content_hashing() {
                        Some(hash_file_contents(&mut file))
                    } else {
                        None
                    };

                    Ok((file, opt_contenthash))
                })

                // and then we get the permissions if we have to
                // and return (file, content hash, permissions)
                .and_then(|(file, opt_contenthash)| {
                    let opt_permissions = if flags.get_permission_tracking() {
                        Some(try!(file
                                  .metadata()
                                  .map(|md| md.permissions())
                                  .map_err(Box::new)
                                  .map_err(|e| REK::RefTargetCannotReadPermissions.into_error_with_cause(e))
                        ))
                    } else {
                        None
                    };

                    Ok((file, opt_contenthash, opt_permissions))
                })

                // and then we try to canonicalize the PathBuf, because we want to store a
                // canonicalized path
                // and return (file, content hash, permissions, canonicalized path)
                .and_then(|(file, opt_contenthash, opt_permissions)| {
                    pb.canonicalize()
                        .map(|can| (file, opt_contenthash, opt_permissions, can))
                        // if PathBuf::canonicalize() failed, build an error from the return value
                        .map_err(|e| REK::PathCanonicalizationError.into_error_with_cause(Box::new(e)))
                })

                // and then we hash the canonicalized path
                // and return (file, content hash, permissions, canonicalized path, path hash)
                .and_then(|(file, opt_contenthash, opt_permissions, can)| {
                    let path_hash = try!(Ref::hash_path(&can)
                        .map_err(Box::new)
                        .map_err(|e| REK::PathHashingError.into_error_with_cause(e))
                    );

                    Ok((file, opt_contenthash, opt_permissions, can, path_hash))
                })

                // and then we convert the PathBuf of the canonicalized path to a String to be able
                // to save it in the Ref FileLockEntry obj
                // and return
                // (file, content hash, permissions, canonicalized path as String, path hash)
                .and_then(|(file, opt_conhash, opt_perm, can, path_hash)| {
                    match can.to_str().map(String::from) {
                        // UTF convert error in PathBuf::to_str(),
                        None      => Err(REK::PathUTF8Error.into_error()),
                        Some(can) => Ok((file, opt_conhash, opt_perm, can, path_hash))
                    }
                })

                // and then we create the FileLockEntry in the Store
                // and return (filelockentry, content hash, permissions, canonicalized path)
                .and_then(|(file, opt_conhash, opt_perm, can, path_hash)| {
                    let fle = try!(store
                                   .create(ModuleEntryPath::new(path_hash))
                                   .map_err(Box::new)
                                   .map_err(|e| REK::StoreWriteError.into_error_with_cause(e))
                    );

                    Ok((fle, opt_conhash, opt_perm, can))
                })
            )
        };

        for tpl in [
                Some(("ref",             Value::Table(BTreeMap::new()))),
                Some(("ref.permissions", Value::Table(BTreeMap::new()))),

                Some(("ref.path", Value::String(canonical_path))),

                content_hash.map(|h| ("ref.content_hash", Value::String(h))),
                permissions.map(|p| ("ref.permissions.ro", Value::Boolean(p.readonly()))),
            ].into_iter()
        {
            match tpl {
                &Some((ref s, ref v)) => {
                    match fle.get_header_mut().insert(s, v.clone()) {
                        Ok(false) => {
                            let e = REK::HeaderFieldAlreadyExistsError.into_error();
                            let e = Box::new(e);
                            let e = REK::HeaderFieldWriteError.into_error_with_cause(e);
                            return Err(e);
                        },
                        Err(e) => {
                            let e = Box::new(e);
                            let e = REK::HeaderFieldWriteError.into_error_with_cause(e);
                            return Err(e);
                        },
                        _ => (),
                    }
                }
                &None => {
                    debug!("Not going to insert.");
                }
            }
        }

        Ok(Ref(fle))
    }

    /// Creates a Hash from a PathBuf by making the PathBuf absolute and then running a hash
    /// algorithm on it
    fn hash_path(pb: &PathBuf) -> Result<String> {
        use std::io::Read;
        use crypto::sha1::Sha1;
        use crypto::digest::Digest;

        match pb.to_str() {
            Some(s) => {
                let mut hasher = Sha1::new();
                hasher.input_str(s);
                Ok(hasher.result_str())
            },
            None => return Err(REK::PathUTF8Error.into_error()),
        }
    }

    /// check whether the pointer the Ref represents still points to a file which exists
    pub fn fs_link_exists(&self) -> Result<bool> {
        self.fs_file().map(|pathbuf| pathbuf.exists())
    }

    /// Alias for `r.fs_link_exists() && r.deref().is_file()`
    pub fn is_ref_to_file(&self) -> Result<bool> {
        self.fs_file().map(|pathbuf| pathbuf.is_file())
    }

    /// Alias for `r.fs_link_exists() && r.deref().is_dir()`
    pub fn is_ref_to_dir(&self) -> Result<bool> {
        self.fs_file().map(|pathbuf| pathbuf.is_dir())
    }

    /// Alias for `!Ref::fs_link_exists()`
    pub fn is_dangling(&self) -> Result<bool> {
        self.fs_link_exists().map(|b| !b)
    }

    /// check whether the pointer the Ref represents is valid
    /// This includes:
    ///     - Hashsum of the file is still the same as stored in the Ref
    ///     - file permissions are still valid
    pub fn fs_link_valid(&self) -> bool {
        unimplemented!()
    }

    /// Check whether the file permissions of the referenced file are equal to the stored
    /// permissions
    pub fn fs_link_valid_permissions(&self) -> Result<bool> {
        self.0
            .get_header()
            .read("ref.permissions.ro")
            .map_err(Box::new)
            .map_err(|e| REK::HeaderFieldReadError.into_error_with_cause(e))
            .and_then(|ro| {
                match ro {
                    Some(Value::Boolean(b)) => Ok(b),
                    Some(_)                 => Err(REK::HeaderTypeError.into_error()),
                    None                    => Err(REK::HeaderFieldMissingError.into_error()),
                }
            })
            .and_then(|ro| self.fs_file().map(|pb| (ro, pb)))
            .and_then(|(ro, pb)| {
                File::open(pb)
                    .map(|file| (ro, file))
                    .map_err(Box::new)
                    .map_err(|e| REK::HeaderFieldReadError.into_error_with_cause(e))
            })
            .and_then(|(ro, file)| {
                file
                    .metadata()
                    .map(|md| md.permissions())
                    .map(|perm| perm.readonly() == ro)
                    .map_err(Box::new)
                    .map_err(|e| REK::RefTargetCannotReadPermissions.into_error_with_cause(e))
            })
            .map_err(Box::new)
            .map_err(|e| REK::RefTargetCannotReadPermissions.into_error_with_cause(e))
    }

    /// Check whether the Hashsum of the referenced file is equal to the stored hashsum
    pub fn fs_link_valid_hash(&self) -> Result<bool> {
        let stored_hash = try!(match self.0.get_header().read("ref.content_hash") {
            // content hash stored...
            Ok(Some(Value::String(s))) => Ok(s),

            // content hash header field has wrong type
            Ok(Some(_)) => Err(REK::HeaderTypeError.into_error()),

            // content hash not stored
            Ok(None) => Err(REK::HeaderFieldMissingError.into_error()),

            // Error
            Err(e) => Err(REK::StoreReadError.into_error_with_cause(Box::new(e))),
        });

        let current_hash = try!(self.fs_file()
            .and_then(|pb| {
                File::open(pb)
                    .map_err(Box::new)
                    .map_err(|e| REK::IOError.into_error_with_cause(e))
            })
            .map(|mut file| hash_file_contents(&mut file))
        );

        Ok(stored_hash == current_hash)
    }

    /// Update the Ref by re-checking the file from FS
    /// This errors if the file is not present or cannot be read()
    pub fn update_ref(&mut self) -> Result<()> {
        unimplemented!()
    }

    /// Get the path of the file which is reffered to by this Ref
    pub fn fs_file(&self) -> Result<PathBuf> {
        match self.0.get_header().read("ref.path") {
            Ok(Some(Value::String(ref s))) => Ok(PathBuf::from(s)),
            Ok(Some(_)) => Err(REK::HeaderTypeError.into_error()),
            Ok(None)    => Err(REK::HeaderFieldMissingError.into_error()),
            Err(e)      => Err(REK::StoreReadError.into_error_with_cause(Box::new(e))),
        }
    }

    /// Check whether there is a reference to the file at `pb`
    pub fn exists(store: &Store, pb: PathBuf) -> Result<bool> {
        pb.canonicalize()
            .map_err(Box::new)
            .map_err(|e| REK::PathCanonicalizationError.into_error_with_cause(e))
            .and_then(|can| {
                Ref::hash_path(&can)
                    .map_err(Box::new)
                    .map_err(|e| REK::PathHashingError.into_error_with_cause(e))
            })
            .and_then(|hash| {
                store.retrieve_for_module("ref").map(|iter| (hash, iter))
                    .map_err(Box::new)
                    .map_err(|e| REK::StoreReadError.into_error_with_cause(e))
            })
            .and_then(|(hash, possible_refs)| {
                // This is kind of a manual Iterator::filter() call what we do here, but with the
                // actual ::filter method we cannot return the error in a nice way, so we do it
                // manually here. If you can come up with a better version of this, feel free to
                // take this note as a todo.
                for r in possible_refs {
                    let contains_hash = match r.to_str() {
                        None => { // couldn't parse StoreId -> PathBuf -> &str
                            // TODO: How to report this?
                            return Err(REK::TypeConversionError.into_error());
                        },
                        Some(s) => s.contains(&hash[..]),
                    };

                    if !contains_hash {
                        continue;
                    }

                    match store.get(r) {
                        Ok(Some(fle)) => {
                            if Ref::read_reference(&fle).map(|path| path == pb).unwrap_or(false) {
                                return Ok(true)
                            }
                        },

                        Ok(None) => { // Something weird just happened
                            return Err(REK::StoreReadError.into_error());
                        },

                        Err(e) => {
                            return Err(REK::StoreReadError.into_error_with_cause(Box::new(e)));
                        },
                    }
                }

                Ok(false)
            })
    }

    /// Re-find a referenced file
    ///
    /// This function tries to re-find a ref by searching all directories in `search_roots` recursively
    /// for a file which matches the hash of the Ref `ref`.
    ///
    /// If `search_roots` is `None`, it starts at the filesystem root `/`.
    ///
    /// # Warning
    ///
    /// This option causes heavy I/O as it recursively searches the Filesystem.
    pub fn refind(&self, search_roots: Option<Vec<PathBuf>>) -> Option<PathBuf> {
        unimplemented!()
    }

}

impl<'a> Deref for Ref<'a> {
    type Target = FileLockEntry<'a>;

    fn deref(&self) -> &FileLockEntry<'a> {
        &self.0
    }

}

impl<'a> DerefMut for Ref<'a> {

    fn deref_mut(&mut self) -> &mut FileLockEntry<'a> {
        &mut self.0
    }

}

fn hash_file_contents(f: &mut File) -> String {
    let mut hasher = Sha1::new();
    let mut s = String::new();
    f.read_to_string(&mut s);
    hasher.input_str(&s[..]);
    hasher.result_str()
}

<|endoftext|>


<commit_before>use std::io::prelude::*;
use std::fs::File;
use std::error::Error;
use std::io::BufWriter;

pub struct BitInputStream {
	buffer : u16,
	pos : usize,
	bits_in_buffer : i16,
	eof: bool,
	bytes : Vec<u8>,
	len : usize,
}

pub struct BitOutputStream {
	out : BufWriter<File>,
	buffer : u16,
	bits_in_buffer : i16,
}

impl BitInputStream {

	pub fn new(file: &str) -> BitInputStream {
		let mut bis = BitInputStream {
			buffer : 0,
			pos : 0,
			bits_in_buffer : 0,
			eof: false,
			bytes : match File::open(file) {
						Err(e) => panic!("No pudo abrir archivo {}, causa: {}", file, e.description()),
						Ok(mut f) => {
							let mut buffer = Vec::new();
							f.read_to_end(&mut buffer).unwrap();
							buffer
						}
					},
			len : 0
		};
		bis.len = bis.bytes.len();
		bis.fill_buffer();
		bis
	}

	pub fn get_bytes(&mut self) -> &Vec<u8> { &self.bytes }

	pub fn read_char(&mut self) -> u8 {
		if self.eof { panic!("reading from empty input stream"); }

		let mut x = self.buffer;
		if self.bits_in_buffer == 8 {
			self.fill_buffer();
		} else {
			x <<= 8 - self.bits_in_buffer;
			let temp = self.bits_in_buffer;
			self.fill_buffer();
			self.bits_in_buffer = temp;
			x |= self.buffer >> self.bits_in_buffer;
		}
		(x & 0xFF) as u8
	}

	pub fn read_bool(&mut self) -> bool {
		if self.eof { panic!("reading from empty input stream"); }

		self.bits_in_buffer -= 1;
		let bit = ((self.buffer >> self.bits_in_buffer) & 1) == 1;
		if self.bits_in_buffer == 0 {
			self.fill_buffer();
		}
		bit
	}

	pub fn read_int(&mut self) -> u32 {
		let mut x : u32 = u32::from(self.read_char());
		x = (x << 8) | u32::from(self.read_char());
		x = (x << 8) | u32::from(self.read_char());
		x = (x << 8) | u32::from(self.read_char());
		x
	}

	fn fill_buffer(&mut self) {
		if self.pos == self.len {
			self.eof = true;
		} else {
			self.buffer = u16::from(self.bytes[self.pos]);
			self.bits_in_buffer = 8;
			self.pos += 1;
		}
	}
}

impl BitOutputStream {

	pub fn new(output: &str) -> BitOutputStream {
		BitOutputStream {
			out: BufWriter::new(File::create(output).unwrap()),
			buffer : 0 ,
			bits_in_buffer : 0
		}
	}

	pub fn write_bit(&mut self, bit: u8) {
		if bit != 0 && bit != 1 { panic!("argument must be 0 or 1., received {}", bit); }
		self.buffer = (self.buffer << 1) | (u16::from(bit));
		self.bits_in_buffer += 1;
		if self.bits_in_buffer == 8 {
			self.clear_buffer();
		}
	}

	pub fn write_int(&mut self, i: u32) {
		self.write_byte(((i >> 24) & 0xFF) as u16);
    	self.write_byte(((i >> 16) & 0xFF) as u16);
    	self.write_byte(((i >>  8) & 0xFF) as u16);
    	self.write_byte((i & 0xFF) as u16);
	}

	pub fn write_byte(&mut self, byte: u16) {
		for i in 0..8 {
			let bit  = (byte >> (8 - i -1)) & 1;
			self.write_bit(bit as u8);
		}
	}

	fn clear_buffer(&mut self) {
		if self.bits_in_buffer == 0 {
			return
		}
		if self.bits_in_buffer > 0 {
			self.buffer <<= 8 - self.bits_in_buffer;
		}
		self.out.write(&[self.buffer as u8]).unwrap();
		self.buffer = 0;
		self.bits_in_buffer = 0;
	}

	pub fn close(&mut self) {
    	self.clear_buffer();
    	self.out.flush().unwrap();
    }
}<commit_msg>cambia write por write_all en BitOutputStream en la solución Rust<commit_after>use std::io::prelude::*;
use std::fs::File;
use std::error::Error;
use std::io::BufWriter;

pub struct BitInputStream {
	buffer : u16,
	pos : usize,
	bits_in_buffer : i16,
	eof: bool,
	bytes : Vec<u8>,
	len : usize,
}

pub struct BitOutputStream {
	out : BufWriter<File>,
	buffer : u16,
	bits_in_buffer : i16,
}

impl BitInputStream {

	pub fn new(file: &str) -> BitInputStream {
		let mut bis = BitInputStream {
			buffer : 0,
			pos : 0,
			bits_in_buffer : 0,
			eof: false,
			bytes : match File::open(file) {
						Err(e) => panic!("No pudo abrir archivo {}, causa: {}", file, e.description()),
						Ok(mut f) => {
							let mut buffer = Vec::new();
							f.read_to_end(&mut buffer).unwrap();
							buffer
						}
					},
			len : 0
		};
		bis.len = bis.bytes.len();
		bis.fill_buffer();
		bis
	}

	pub fn get_bytes(&mut self) -> &Vec<u8> { &self.bytes }

	pub fn read_char(&mut self) -> u8 {
		if self.eof { panic!("reading from empty input stream"); }

		let mut x = self.buffer;
		if self.bits_in_buffer == 8 {
			self.fill_buffer();
		} else {
			x <<= 8 - self.bits_in_buffer;
			let temp = self.bits_in_buffer;
			self.fill_buffer();
			self.bits_in_buffer = temp;
			x |= self.buffer >> self.bits_in_buffer;
		}
		(x & 0xFF) as u8
	}

	pub fn read_bool(&mut self) -> bool {
		if self.eof { panic!("reading from empty input stream"); }

		self.bits_in_buffer -= 1;
		let bit = ((self.buffer >> self.bits_in_buffer) & 1) == 1;
		if self.bits_in_buffer == 0 {
			self.fill_buffer();
		}
		bit
	}

	pub fn read_int(&mut self) -> u32 {
		let mut x : u32 = u32::from(self.read_char());
		x = (x << 8) | u32::from(self.read_char());
		x = (x << 8) | u32::from(self.read_char());
		x = (x << 8) | u32::from(self.read_char());
		x
	}

	fn fill_buffer(&mut self) {
		if self.pos == self.len {
			self.eof = true;
		} else {
			self.buffer = u16::from(self.bytes[self.pos]);
			self.bits_in_buffer = 8;
			self.pos += 1;
		}
	}
}

impl BitOutputStream {

	pub fn new(output: &str) -> BitOutputStream {
		BitOutputStream {
			out: BufWriter::new(File::create(output).unwrap()),
			buffer : 0 ,
			bits_in_buffer : 0
		}
	}

	pub fn write_bit(&mut self, bit: u8) {
		if bit != 0 && bit != 1 { panic!("argument must be 0 or 1., received {}", bit); }
		self.buffer = (self.buffer << 1) | (u16::from(bit));
		self.bits_in_buffer += 1;
		if self.bits_in_buffer == 8 {
			self.clear_buffer();
		}
	}

	pub fn write_int(&mut self, i: u32) {
		self.write_byte(((i >> 24) & 0xFF) as u16);
    	self.write_byte(((i >> 16) & 0xFF) as u16);
    	self.write_byte(((i >>  8) & 0xFF) as u16);
    	self.write_byte((i & 0xFF) as u16);
	}

	pub fn write_byte(&mut self, byte: u16) {
		for i in 0..8 {
			let bit  = (byte >> (8 - i -1)) & 1;
			self.write_bit(bit as u8);
		}
	}

	fn clear_buffer(&mut self) {
		if self.bits_in_buffer == 0 {
			return
		}
		if self.bits_in_buffer > 0 {
			self.buffer <<= 8 - self.bits_in_buffer;
		}
		self.out.write_all(&[self.buffer as u8]).unwrap();
		self.buffer = 0;
		self.bits_in_buffer = 0;
	}

	pub fn close(&mut self) {
    	self.clear_buffer();
    	self.out.flush().unwrap();
    }
}<|endoftext|>


<commit_before>//! A macro for writing HTML templates.
//!
//! This crate, along with its sister `maud_macros`, lets you generate
//! HTML markup from within Rust. It exposes a single macro, `html!`,
//! which compiles your markup to specialized Rust code.
//!
//! # Dependencies
//!
//! To get started, add `maud` and `maud_macros` to your `Cargo.toml`:
//!
//! ```toml
//! [dependencies]
//! # ...
//! maud = "*"
//! maud_macros = "*"
//! ```
//!
//! # Example
//!
//! ```rust
//! #![feature(plugin)]
//! #![allow(unstable)]
//!
//! extern crate maud;
//! #[plugin] #[no_link] extern crate maud_macros;
//!
//! fn main() {
//!     let name = "Lyra";
//!     let markup = html! {
//!         p { "Hi, " $name "!" }
//!     };
//!     assert_eq!(markup.render(), "<p>Hi, Lyra!</p>");
//! }
//! ```
//!
//! # Syntax
//!
//! Maud uses its own syntax, loosely inspired by HTML and Rust.
//!
//! ## Literals
//!
//! ```
//! html! {
//!     "Oatmeal, are you crazy?\n"
//!     "<script>alert(\"XSS\")</script>\n"
//!     $$"<script>alert(\"XSS\")</script>\n"
//! }
//! ```
//!
//! ```html
//! Oatmeal, are you crazy?
//! <script>alert("XSS")</script>
//! <script>alert("XSS")</script>
//! ```
//!
//! Literal strings use the same syntax as Rust.
//!
//! By default, HTML special characters are escaped automatically. Add a
//! `$$` prefix to disable this escaping.
//!
//! ## Elements
//!
//! ```
//! html! {
//!     h1 "Pinkie's Brew"
//!     p {
//!         "Watch as I work my gypsy magic"
//!         br /
//!         "Eye of a newt and cinnamon"
//!     }
//!     p small em "squee"
//! }
//! ```
//!
//! ```html
//! <h1>Pinkie's Brew</h1>
//! <p>
//!   Watch as I work my gypsy magic
//!   <br>
//!   Eye of a newt and cinnamon
//! </p>
//! <p><small><em>squee</em></small></p>
//! ```
//!
//! Write an element using curly braces (`p {}`).
//!
//! Terminate a void element using a slash (`br /`).
//!
//! If the element has only a single child, you can omit the brackets
//! (`h1 "Pinkie's Brew"`). This shorthand works with nested elements
//! too.
//!
//! ## Attributes
//!
//! ```
//! html! {
//!     form method="POST" {
//!         label for="waffles" "Do you like waffles?"
//!         input name="waffles" type="checkbox" checked=! /
//!     }
//! }
//! ```
//!
//! ```html
//! <form method="POST">
//!   <label for="waffles">Do you like waffles?</label>
//!   <input name="waffles" type="checkbox" checked>
//! </form>
//! ```
//!
//! Add attributes using the syntax `attr="value"`. Attributes must be
//! quoted: they are parsed as string literals.
//!
//! To declare an empty attribute, use `!` for the value: `checked=!`.
//!
//! ## Splices
//!
//! ```
//! let best_pony = "Pinkie Pie";
//! let numbers = [1, 2, 3, 4];
//! let secret_message = "Surprise!";
//! let pre_escaped = "<p>Pre-escaped</p>";
//! html! {
//!     h1 { $best_pony " says:" }
//!     p {
//!         "I have " $numbers.len() " numbers, "
//!         "and the first one is " $numbers[0]
//!     }
//!     p title=$secret_message {
//!         "1 + 1 = " $(1 + 1)
//!     }
//!     $$pre_escaped
//! }
//! ```
//!
//! ```html
//! <h1>Pinkie Pie says:</h1>
//! <p>I have 4 numbers, and the first one is 1</p>
//! <p title="Surprise!">1 + 1 = 2</p>
//! <p>Pre-escaped</p>
//! ```
//!
//! Use `$(expr)` syntax to splice a Rust expression into the output.
//! You can omit the brackets if it's just a variable (`$var`), indexing
//! operation (`$var[0]`), method call (`$var.method()`), or property
//! lookup (`$var.property`).
//!
//! As with literals, expression values are escaped by default. Use a
//! `$$` prefix to disable this behavior.

#![allow(unstable)]

use std::fmt;
use std::io::{IoError, IoErrorKind, IoResult};

/// Escape an HTML value.
pub fn escape(s: &str) -> String {
    use std::fmt::Writer;
    let mut buf = String::new();
    rt::Escaper { inner: &mut buf }.write_str(s).unwrap();
    buf
}

/// A block of HTML markup, as returned by the `html!` macro.
///
/// Use `.render()` to convert it to a `String`, or `.render_to()` to
/// write it directly to a handle.
pub struct Markup<'a> {
    callback: &'a (Fn(&mut fmt::Writer) -> fmt::Result + 'a),
}

impl<'a> Markup<'a> {
    /// Render the markup to a `String`.
    pub fn render(&self) -> String {
        let mut buf = String::new();
        self.render_fmt(&mut buf).unwrap();
        buf
    }

    /// Render the markup to a `std::io::Writer`.
    ///
    /// If you're writing to, say, a file or a socket, this may be more
    /// efficient than calling `.render()`.
    pub fn render_to(&self, w: &mut Writer) -> IoResult<()> {
        struct WriterWrapper<'a, 'b: 'a> {
            inner: &'a mut (Writer + 'b),
        }
        impl<'a, 'b> fmt::Writer for WriterWrapper<'a, 'b> {
            fn write_str(&mut self, s: &str) -> fmt::Result {
                self.inner.write_str(s).map_err(|_| fmt::Error)
            }
        }
        self.render_fmt(&mut WriterWrapper { inner: w })
            .map_err(|_| IoError {
                kind: IoErrorKind::OtherIoError,
                desc: "formatting error",
                detail: None,
            })
    }

    /// Render the markup to a `std::fmt::Writer`.
    pub fn render_fmt(&self, w: &mut fmt::Writer) -> fmt::Result {
        (self.callback)(w)
    }
}

/// Internal functions used by the `maud_macros` package. You should
/// never need to call these directly.
#[doc(hidden)]
pub mod rt {
    use std::fmt;
    use super::Markup;

    #[inline]
    pub fn make_markup<'a>(f: &'a (Fn(&mut fmt::Writer) -> fmt::Result + 'a)) -> Markup<'a> {
        Markup { callback: f }
    }

    /// rustc is a butt and doesn't let us quote macro invocations
    /// directly. So we factor the `write!` call into a separate
    /// function and use that instead.
    ///
    /// See <https://github.com/rust-lang/rust/issues/16617>
    #[inline]
    pub fn write_fmt<T: fmt::String>(w: &mut fmt::Writer, value: T) -> fmt::Result {
        write!(w, "{}", value)
    }

    pub struct Escaper<'a, 'b: 'a> {
        pub inner: &'a mut (fmt::Writer + 'b),
    }

    impl<'a, 'b> fmt::Writer for Escaper<'a, 'b> {
        fn write_str(&mut self, s: &str) -> fmt::Result {
            for c in s.chars() {
                try!(match c {
                    '&' => self.inner.write_str("&"),
                    '<' => self.inner.write_str("<"),
                    '>' => self.inner.write_str(">"),
                    '"' => self.inner.write_str("""),
                    '\'' => self.inner.write_str("'"),
                    _ => write!(self.inner, "{}", c),
                });
            }
            Ok(())
        }
    }
}
<commit_msg>Update Rust<commit_after>//! A macro for writing HTML templates.
//!
//! This crate, along with its sister `maud_macros`, lets you generate
//! HTML markup from within Rust. It exposes a single macro, `html!`,
//! which compiles your markup to specialized Rust code.
//!
//! # Dependencies
//!
//! To get started, add `maud` and `maud_macros` to your `Cargo.toml`:
//!
//! ```toml
//! [dependencies]
//! # ...
//! maud = "*"
//! maud_macros = "*"
//! ```
//!
//! # Example
//!
//! ```rust
//! #![feature(plugin)]
//! #![allow(unstable)]
//!
//! extern crate maud;
//! #[plugin] #[no_link] extern crate maud_macros;
//!
//! fn main() {
//!     let name = "Lyra";
//!     let markup = html! {
//!         p { "Hi, " $name "!" }
//!     };
//!     assert_eq!(markup.render(), "<p>Hi, Lyra!</p>");
//! }
//! ```
//!
//! # Syntax
//!
//! Maud uses its own syntax, loosely inspired by HTML and Rust.
//!
//! ## Literals
//!
//! ```
//! html! {
//!     "Oatmeal, are you crazy?\n"
//!     "<script>alert(\"XSS\")</script>\n"
//!     $$"<script>alert(\"XSS\")</script>\n"
//! }
//! ```
//!
//! ```html
//! Oatmeal, are you crazy?
//! <script>alert("XSS")</script>
//! <script>alert("XSS")</script>
//! ```
//!
//! Literal strings use the same syntax as Rust.
//!
//! By default, HTML special characters are escaped automatically. Add a
//! `$$` prefix to disable this escaping.
//!
//! ## Elements
//!
//! ```
//! html! {
//!     h1 "Pinkie's Brew"
//!     p {
//!         "Watch as I work my gypsy magic"
//!         br /
//!         "Eye of a newt and cinnamon"
//!     }
//!     p small em "squee"
//! }
//! ```
//!
//! ```html
//! <h1>Pinkie's Brew</h1>
//! <p>
//!   Watch as I work my gypsy magic
//!   <br>
//!   Eye of a newt and cinnamon
//! </p>
//! <p><small><em>squee</em></small></p>
//! ```
//!
//! Write an element using curly braces (`p {}`).
//!
//! Terminate a void element using a slash (`br /`).
//!
//! If the element has only a single child, you can omit the brackets
//! (`h1 "Pinkie's Brew"`). This shorthand works with nested elements
//! too.
//!
//! ## Attributes
//!
//! ```
//! html! {
//!     form method="POST" {
//!         label for="waffles" "Do you like waffles?"
//!         input name="waffles" type="checkbox" checked=! /
//!     }
//! }
//! ```
//!
//! ```html
//! <form method="POST">
//!   <label for="waffles">Do you like waffles?</label>
//!   <input name="waffles" type="checkbox" checked>
//! </form>
//! ```
//!
//! Add attributes using the syntax `attr="value"`. Attributes must be
//! quoted: they are parsed as string literals.
//!
//! To declare an empty attribute, use `!` for the value: `checked=!`.
//!
//! ## Splices
//!
//! ```
//! let best_pony = "Pinkie Pie";
//! let numbers = [1, 2, 3, 4];
//! let secret_message = "Surprise!";
//! let pre_escaped = "<p>Pre-escaped</p>";
//! html! {
//!     h1 { $best_pony " says:" }
//!     p {
//!         "I have " $numbers.len() " numbers, "
//!         "and the first one is " $numbers[0]
//!     }
//!     p title=$secret_message {
//!         "1 + 1 = " $(1 + 1)
//!     }
//!     $$pre_escaped
//! }
//! ```
//!
//! ```html
//! <h1>Pinkie Pie says:</h1>
//! <p>I have 4 numbers, and the first one is 1</p>
//! <p title="Surprise!">1 + 1 = 2</p>
//! <p>Pre-escaped</p>
//! ```
//!
//! Use `$(expr)` syntax to splice a Rust expression into the output.
//! You can omit the brackets if it's just a variable (`$var`), indexing
//! operation (`$var[0]`), method call (`$var.method()`), or property
//! lookup (`$var.property`).
//!
//! As with literals, expression values are escaped by default. Use a
//! `$$` prefix to disable this behavior.

#![allow(unstable)]

use std::fmt;
use std::io::{IoError, IoErrorKind, IoResult};

/// Escape an HTML value.
pub fn escape(s: &str) -> String {
    use std::fmt::Writer;
    let mut buf = String::new();
    rt::Escaper { inner: &mut buf }.write_str(s).unwrap();
    buf
}

/// A block of HTML markup, as returned by the `html!` macro.
///
/// Use `.render()` to convert it to a `String`, or `.render_to()` to
/// write it directly to a handle.
pub struct Markup<'a> {
    callback: &'a (Fn(&mut fmt::Writer) -> fmt::Result + 'a),
}

impl<'a> Markup<'a> {
    /// Render the markup to a `String`.
    pub fn render(&self) -> String {
        let mut buf = String::new();
        self.render_fmt(&mut buf).unwrap();
        buf
    }

    /// Render the markup to a `std::io::Writer`.
    ///
    /// If you're writing to, say, a file or a socket, this may be more
    /// efficient than calling `.render()`.
    pub fn render_to(&self, w: &mut Writer) -> IoResult<()> {
        struct WriterWrapper<'a, 'b: 'a> {
            inner: &'a mut (Writer + 'b),
        }
        impl<'a, 'b> fmt::Writer for WriterWrapper<'a, 'b> {
            fn write_str(&mut self, s: &str) -> fmt::Result {
                self.inner.write_str(s).map_err(|_| fmt::Error)
            }
        }
        self.render_fmt(&mut WriterWrapper { inner: w })
            .map_err(|_| IoError {
                kind: IoErrorKind::OtherIoError,
                desc: "formatting error",
                detail: None,
            })
    }

    /// Render the markup to a `std::fmt::Writer`.
    pub fn render_fmt(&self, w: &mut fmt::Writer) -> fmt::Result {
        (self.callback)(w)
    }
}

/// Internal functions used by the `maud_macros` package. You should
/// never need to call these directly.
#[doc(hidden)]
pub mod rt {
    use std::fmt;
    use super::Markup;

    #[inline]
    pub fn make_markup<'a>(f: &'a (Fn(&mut fmt::Writer) -> fmt::Result + 'a)) -> Markup<'a> {
        Markup { callback: f }
    }

    /// rustc is a butt and doesn't let us quote macro invocations
    /// directly. So we factor the `write!` call into a separate
    /// function and use that instead.
    ///
    /// See <https://github.com/rust-lang/rust/issues/16617>
    #[inline]
    pub fn write_fmt<T: fmt::Display>(w: &mut fmt::Writer, value: T) -> fmt::Result {
        write!(w, "{}", value)
    }

    pub struct Escaper<'a, 'b: 'a> {
        pub inner: &'a mut (fmt::Writer + 'b),
    }

    impl<'a, 'b> fmt::Writer for Escaper<'a, 'b> {
        fn write_str(&mut self, s: &str) -> fmt::Result {
            for c in s.chars() {
                try!(match c {
                    '&' => self.inner.write_str("&"),
                    '<' => self.inner.write_str("<"),
                    '>' => self.inner.write_str(">"),
                    '"' => self.inner.write_str("""),
                    '\'' => self.inner.write_str("'"),
                    _ => write!(self.inner, "{}", c),
                });
            }
            Ok(())
        }
    }
}
<|endoftext|>


<commit_before>// pest. The Elegant Parser
// Copyright (c) 2018 Dragoș Tiselice
//
// Licensed under the Apache License, Version 2.0
// <LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0> or the MIT
// license <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. All files in the project carrying such notice may not be copied,
// modified, or distributed except according to those terms.

#[derive(Clone, Debug, Eq, PartialEq)]
pub struct Rule {
    pub name: String,
    pub ty: RuleType,
    pub expr: Expr
}

#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum RuleType {
    Normal,
    Silent,
    Atomic,
    CompoundAtomic,
    NonAtomic
}

#[derive(Clone, Debug, Eq, PartialEq)]
pub enum Expr {
    Str(String),
    Insens(String),
    Range(String, String),
    Ident(String),
    PosPred(Box<Expr>),
    NegPred(Box<Expr>),
    Seq(Box<Expr>, Box<Expr>),
    Choice(Box<Expr>, Box<Expr>),
    Opt(Box<Expr>),
    Rep(Box<Expr>),
    RepOnce(Box<Expr>),
    RepExact(Box<Expr>, u32),
    RepMin(Box<Expr>, u32),
    RepMax(Box<Expr>, u32),
    RepMinMax(Box<Expr>, u32, u32),
    Skip(Vec<String>),
    Push(Box<Expr>)
}

impl Expr {
    pub fn map_top_down<F>(self, mut f: F) -> Expr
    where
        F: FnMut(Expr) -> Expr
    {
        pub fn map_internal<F>(expr: Expr, f: &mut F) -> Expr
        where
            F: FnMut(Expr) -> Expr
        {
            let expr = f(expr);

            match expr {
                // TODO: Use box syntax when it gets stabilized.
                Expr::PosPred(expr) => {
                    let mapped = Box::new(map_internal(*expr, f));
                    Expr::PosPred(mapped)
                }
                Expr::NegPred(expr) => {
                    let mapped = Box::new(map_internal(*expr, f));
                    Expr::NegPred(mapped)
                }
                Expr::Seq(lhs, rhs) => {
                    let mapped_lhs = Box::new(map_internal(*lhs, f));
                    let mapped_rhs = Box::new(map_internal(*rhs, f));
                    Expr::Seq(mapped_lhs, mapped_rhs)
                }
                Expr::Choice(lhs, rhs) => {
                    let mapped_lhs = Box::new(map_internal(*lhs, f));
                    let mapped_rhs = Box::new(map_internal(*rhs, f));
                    Expr::Choice(mapped_lhs, mapped_rhs)
                }
                Expr::Rep(expr) => {
                    let mapped = Box::new(map_internal(*expr, f));
                    Expr::Rep(mapped)
                }
                Expr::RepOnce(expr) => {
                    let mapped = Box::new(map_internal(*expr, f));
                    Expr::RepOnce(mapped)
                }
                Expr::RepExact(expr, max) => {
                    let mapped = Box::new(map_internal(*expr, f));
                    Expr::RepExact(mapped, max)
                }
                Expr::RepMin(expr, num) => {
                    let mapped = Box::new(map_internal(*expr, f));
                    Expr::RepMin(mapped, num)
                }
                Expr::RepMax(expr, num) => {
                    let mapped = Box::new(map_internal(*expr, f));
                    Expr::RepMax(mapped, num)
                }
                Expr::RepMinMax(expr, min, max) => {
                    let mapped = Box::new(map_internal(*expr, f));
                    Expr::RepMinMax(mapped, min, max)
                }
                Expr::Opt(expr) => {
                    let mapped = Box::new(map_internal(*expr, f));
                    Expr::Opt(mapped)
                }
                Expr::Push(expr) => {
                    let mapped = Box::new(map_internal(*expr, f));
                    Expr::Push(mapped)
                }
                expr => expr
            }
        }

        map_internal(self, &mut f)
    }

    pub fn map_bottom_up<F>(self, mut f: F) -> Expr
    where
        F: FnMut(Expr) -> Expr
    {
        pub fn map_internal<F>(expr: Expr, f: &mut F) -> Expr
        where
            F: FnMut(Expr) -> Expr
        {
            let mapped = match expr {
                Expr::PosPred(expr) => {
                    // TODO: Use box syntax when it gets stabilized.
                    let mapped = Box::new(map_internal(*expr, f));
                    Expr::PosPred(mapped)
                }
                Expr::NegPred(expr) => {
                    let mapped = Box::new(map_internal(*expr, f));
                    Expr::NegPred(mapped)
                }
                Expr::Seq(lhs, rhs) => {
                    let mapped_lhs = Box::new(map_internal(*lhs, f));
                    let mapped_rhs = Box::new(map_internal(*rhs, f));
                    Expr::Seq(mapped_lhs, mapped_rhs)
                }
                Expr::Choice(lhs, rhs) => {
                    let mapped_lhs = Box::new(map_internal(*lhs, f));
                    let mapped_rhs = Box::new(map_internal(*rhs, f));
                    Expr::Choice(mapped_lhs, mapped_rhs)
                }
                Expr::Rep(expr) => {
                    let mapped = Box::new(map_internal(*expr, f));
                    Expr::Rep(mapped)
                }
                Expr::RepOnce(expr) => {
                    let mapped = Box::new(map_internal(*expr, f));
                    Expr::RepOnce(mapped)
                }
                Expr::RepExact(expr, num) => {
                    let mapped = Box::new(map_internal(*expr, f));
                    Expr::RepExact(mapped, num)
                }
                Expr::RepMin(expr, max) => {
                    let mapped = Box::new(map_internal(*expr, f));
                    Expr::RepMin(mapped, max)
                }
                Expr::RepMax(expr, max) => {
                    let mapped = Box::new(map_internal(*expr, f));
                    Expr::RepMax(mapped, max)
                }
                Expr::RepMinMax(expr, min, max) => {
                    let mapped = Box::new(map_internal(*expr, f));
                    Expr::RepMinMax(mapped, min, max)
                }
                Expr::Opt(expr) => {
                    let mapped = Box::new(map_internal(*expr, f));
                    Expr::Opt(mapped)
                }
                Expr::Push(expr) => {
                    let mapped = Box::new(map_internal(*expr, f));
                    Expr::Push(mapped)
                }
                expr => expr
            };

            f(mapped)
        }

        map_internal(self, &mut f)
    }
}

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

    #[test]
    fn identity() {
        let expr = Expr::Choice(
            Box::new(Expr::Seq(
                Box::new(Expr::Ident("a".to_owned())),
                Box::new(Expr::Str("b".to_owned()))
            )),
            Box::new(Expr::PosPred(Box::new(Expr::NegPred(Box::new(
                Expr::Rep(Box::new(Expr::RepOnce(Box::new(Expr::Opt(Box::new(
                    Expr::Choice(
                        Box::new(Expr::Insens("c".to_owned())),
                        Box::new(Expr::Push(Box::new(Expr::Range(
                            "'d'".to_owned(),
                            "'e'".to_owned()
                        ))))
                    )
                ))))))
            )))))
        );

        assert_eq!(
            expr.clone()
                .map_bottom_up(|expr| expr)
                .map_top_down(|expr| expr),
            expr
        );
    }
}
<commit_msg>add comments to the Expr enum<commit_after>// pest. The Elegant Parser
// Copyright (c) 2018 Dragoș Tiselice
//
// Licensed under the Apache License, Version 2.0
// <LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0> or the MIT
// license <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. All files in the project carrying such notice may not be copied,
// modified, or distributed except according to those terms.

#[derive(Clone, Debug, Eq, PartialEq)]
pub struct Rule {
    pub name: String,
    pub ty: RuleType,
    pub expr: Expr
}

#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum RuleType {
    Normal,
    Silent,
    Atomic,
    CompoundAtomic,
    NonAtomic
}

#[derive(Clone, Debug, Eq, PartialEq)]
pub enum Expr {
    /// Matches an exact string, e.g. `"a"`
    Str(String),
    /// Matches an exact string, case insensitively (ASCII only), e.g. `^"a"`
    Insens(String),
    /// Matches one character in the range, e.g. `'a'..'z'`
    Range(String, String),
    /// Matches the rule with the given name, e.g. `a`
    Ident(Ident),
    /// Positive lookahead; matches expression without making progress, e.g. `&e`
    PosPred(Box<Expr>),
    /// Negative lookahead; matches if expression doesn't match, without making progress, e.g. `!e`
    NegPred(Box<Expr>),
    /// Matches a sequence of two expressions, e.g. `e1 ~ e2`
    Seq(Box<Expr>, Box<Expr>),
    /// Matches either of two expressions, e.g. `e1 | e2`
    Choice(Box<Expr>, Box<Expr>),
    /// Optionally matches an expression, e.g. `e?`
    Opt(Box<Expr>),
    /// Matches an expression zero or more times, e.g. `e*`
    Rep(Box<Expr>),
    /// Matches an expression one or more times, e.g. `e+`
    RepOnce(Box<Expr>),
    /// Matches an expression an exact number of times, e.g. `e{n}`
    RepExact(Box<Expr>, u32),
    /// Matches an expression at least a number of times, e.g. `e{n,}`
    RepMin(Box<Expr>, u32),
    /// Matches an expression at most a number of times, e.g. `e{,n}`
    RepMax(Box<Expr>, u32),
    /// Matches an expression at range of times, e.g. `e{m, n}`
    RepMinMax(Box<Expr>, u32, u32),
    /// Matches any expression that does not contain the strings in the Vec.
    Skip(Vec<String>),
    /// Matches an expression and pushes it to the stack, e.g. `push(e)`
    Push(Box<Expr>)
}

impl Expr {
    pub fn map_top_down<F>(self, mut f: F) -> Expr
    where
        F: FnMut(Expr) -> Expr
    {
        pub fn map_internal<F>(expr: Expr, f: &mut F) -> Expr
        where
            F: FnMut(Expr) -> Expr
        {
            let expr = f(expr);

            match expr {
                // TODO: Use box syntax when it gets stabilized.
                Expr::PosPred(expr) => {
                    let mapped = Box::new(map_internal(*expr, f));
                    Expr::PosPred(mapped)
                }
                Expr::NegPred(expr) => {
                    let mapped = Box::new(map_internal(*expr, f));
                    Expr::NegPred(mapped)
                }
                Expr::Seq(lhs, rhs) => {
                    let mapped_lhs = Box::new(map_internal(*lhs, f));
                    let mapped_rhs = Box::new(map_internal(*rhs, f));
                    Expr::Seq(mapped_lhs, mapped_rhs)
                }
                Expr::Choice(lhs, rhs) => {
                    let mapped_lhs = Box::new(map_internal(*lhs, f));
                    let mapped_rhs = Box::new(map_internal(*rhs, f));
                    Expr::Choice(mapped_lhs, mapped_rhs)
                }
                Expr::Rep(expr) => {
                    let mapped = Box::new(map_internal(*expr, f));
                    Expr::Rep(mapped)
                }
                Expr::RepOnce(expr) => {
                    let mapped = Box::new(map_internal(*expr, f));
                    Expr::RepOnce(mapped)
                }
                Expr::RepExact(expr, max) => {
                    let mapped = Box::new(map_internal(*expr, f));
                    Expr::RepExact(mapped, max)
                }
                Expr::RepMin(expr, num) => {
                    let mapped = Box::new(map_internal(*expr, f));
                    Expr::RepMin(mapped, num)
                }
                Expr::RepMax(expr, num) => {
                    let mapped = Box::new(map_internal(*expr, f));
                    Expr::RepMax(mapped, num)
                }
                Expr::RepMinMax(expr, min, max) => {
                    let mapped = Box::new(map_internal(*expr, f));
                    Expr::RepMinMax(mapped, min, max)
                }
                Expr::Opt(expr) => {
                    let mapped = Box::new(map_internal(*expr, f));
                    Expr::Opt(mapped)
                }
                Expr::Push(expr) => {
                    let mapped = Box::new(map_internal(*expr, f));
                    Expr::Push(mapped)
                }
                expr => expr
            }
        }

        map_internal(self, &mut f)
    }

    pub fn map_bottom_up<F>(self, mut f: F) -> Expr
    where
        F: FnMut(Expr) -> Expr
    {
        pub fn map_internal<F>(expr: Expr, f: &mut F) -> Expr
        where
            F: FnMut(Expr) -> Expr
        {
            let mapped = match expr {
                Expr::PosPred(expr) => {
                    // TODO: Use box syntax when it gets stabilized.
                    let mapped = Box::new(map_internal(*expr, f));
                    Expr::PosPred(mapped)
                }
                Expr::NegPred(expr) => {
                    let mapped = Box::new(map_internal(*expr, f));
                    Expr::NegPred(mapped)
                }
                Expr::Seq(lhs, rhs) => {
                    let mapped_lhs = Box::new(map_internal(*lhs, f));
                    let mapped_rhs = Box::new(map_internal(*rhs, f));
                    Expr::Seq(mapped_lhs, mapped_rhs)
                }
                Expr::Choice(lhs, rhs) => {
                    let mapped_lhs = Box::new(map_internal(*lhs, f));
                    let mapped_rhs = Box::new(map_internal(*rhs, f));
                    Expr::Choice(mapped_lhs, mapped_rhs)
                }
                Expr::Rep(expr) => {
                    let mapped = Box::new(map_internal(*expr, f));
                    Expr::Rep(mapped)
                }
                Expr::RepOnce(expr) => {
                    let mapped = Box::new(map_internal(*expr, f));
                    Expr::RepOnce(mapped)
                }
                Expr::RepExact(expr, num) => {
                    let mapped = Box::new(map_internal(*expr, f));
                    Expr::RepExact(mapped, num)
                }
                Expr::RepMin(expr, max) => {
                    let mapped = Box::new(map_internal(*expr, f));
                    Expr::RepMin(mapped, max)
                }
                Expr::RepMax(expr, max) => {
                    let mapped = Box::new(map_internal(*expr, f));
                    Expr::RepMax(mapped, max)
                }
                Expr::RepMinMax(expr, min, max) => {
                    let mapped = Box::new(map_internal(*expr, f));
                    Expr::RepMinMax(mapped, min, max)
                }
                Expr::Opt(expr) => {
                    let mapped = Box::new(map_internal(*expr, f));
                    Expr::Opt(mapped)
                }
                Expr::Push(expr) => {
                    let mapped = Box::new(map_internal(*expr, f));
                    Expr::Push(mapped)
                }
                expr => expr
            };

            f(mapped)
        }

        map_internal(self, &mut f)
    }
}

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

    #[test]
    fn identity() {
        let expr = Expr::Choice(
            Box::new(Expr::Seq(
                Box::new(Expr::Ident("a".to_owned())),
                Box::new(Expr::Str("b".to_owned()))
            )),
            Box::new(Expr::PosPred(Box::new(Expr::NegPred(Box::new(
                Expr::Rep(Box::new(Expr::RepOnce(Box::new(Expr::Opt(Box::new(
                    Expr::Choice(
                        Box::new(Expr::Insens("c".to_owned())),
                        Box::new(Expr::Push(Box::new(Expr::Range(
                            "'d'".to_owned(),
                            "'e'".to_owned()
                        ))))
                    )
                ))))))
            )))))
        );

        assert_eq!(
            expr.clone()
                .map_bottom_up(|expr| expr)
                .map_top_down(|expr| expr),
            expr
        );
    }
}
<|endoftext|>


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

#![allow(non_snake_case)]

register_long_diagnostics! {
E0454: r##"
A link name was given with an empty name. Erroneous code example:

```
#[link(name = "")] extern {} // error: #[link(name = "")] given with empty name
```

The rust compiler cannot link to an external library if you don't give it its
name. Example:

```
#[link(name = "some_lib")] extern {} // ok!
```
"##,

E0458: r##"
An unknown "kind" was specified for a link attribute. Erroneous code example:

```
#[link(kind = "wonderful_unicorn")] extern {}
// error: unknown kind: `wonderful_unicorn`
```

Please specify a valid "kind" value, from one of the following:
 * static
 * dylib
 * framework
"##,

E0459: r##"
A link was used without a name parameter. Erroneous code example:

```
#[link(kind = "dylib")] extern {}
// error: #[link(...)] specified without `name = "foo"`
```

Please add the name parameter to allow the rust compiler to find the library
you want. Example:

```
#[link(kind = "dylib", name = "some_lib")] extern {} // ok!
```
"##,

}

register_diagnostics! {
    E0455, // native frameworks are only available on OSX targets
    E0456, // plugin `..` is not available for triple `..`
    E0457, // plugin `..` only found in rlib format, but must be available...
    E0514, // metadata version mismatch
    E0460, // found possibly newer version of crate `..`
    E0461, // couldn't find crate `..` with expected target triple ..
    E0462, // found staticlib `..` instead of rlib or dylib
    E0463, // can't find crate for `..`
    E0464, // multiple matching crates for `..`
    E0465, // multiple .. candidates for `..` found
    E0466, // bad macro import
    E0467, // bad macro reexport
    E0468, // an `extern crate` loading macros must be at the crate root
    E0469, // imported macro not found
    E0470, // reexported macro not found
}
<commit_msg>Add E0463 error explanation<commit_after>// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![allow(non_snake_case)]

register_long_diagnostics! {
E0454: r##"
A link name was given with an empty name. Erroneous code example:

```
#[link(name = "")] extern {} // error: #[link(name = "")] given with empty name
```

The rust compiler cannot link to an external library if you don't give it its
name. Example:

```
#[link(name = "some_lib")] extern {} // ok!
```
"##,

E0458: r##"
An unknown "kind" was specified for a link attribute. Erroneous code example:

```
#[link(kind = "wonderful_unicorn")] extern {}
// error: unknown kind: `wonderful_unicorn`
```

Please specify a valid "kind" value, from one of the following:
 * static
 * dylib
 * framework
"##,

E0459: r##"
A link was used without a name parameter. Erroneous code example:

```
#[link(kind = "dylib")] extern {}
// error: #[link(...)] specified without `name = "foo"`
```

Please add the name parameter to allow the rust compiler to find the library
you want. Example:

```
#[link(kind = "dylib", name = "some_lib")] extern {} // ok!
```
"##,

E0463: r##"
A plugin/crate was declared but cannot be found. Erroneous code example:

```
#![feature(plugin)]
#![plugin(cookie_monster)] // error: can't find crate for `cookie_monster`
extern crate cake_is_a_lie; // error: can't find crate for `cake_is_a_lie`
```

You need to link your code to the relevant crate in order to be able to use it
(through Cargo or the `-L` option of rustc example). Plugins are crates as
well, and you link to them the same way.
"##,

}

register_diagnostics! {
    E0455, // native frameworks are only available on OSX targets
    E0456, // plugin `..` is not available for triple `..`
    E0457, // plugin `..` only found in rlib format, but must be available...
    E0514, // metadata version mismatch
    E0460, // found possibly newer version of crate `..`
    E0461, // couldn't find crate `..` with expected target triple ..
    E0462, // found staticlib `..` instead of rlib or dylib
    E0464, // multiple matching crates for `..`
    E0465, // multiple .. candidates for `..` found
    E0466, // bad macro import
    E0467, // bad macro reexport
    E0468, // an `extern crate` loading macros must be at the crate root
    E0469, // imported macro not found
    E0470, // reexported macro not found
}
<|endoftext|>


<commit_before>#![feature(std_misc)]
#![feature(core)]

extern crate para_bm;

use std::time::Duration;
use std::thread::Thread;
use std::num::Float;

use para_bm::{sleep_ns};

fn fast () {
    sleep_ns(1000);
}

fn slow () {
    sleep_ns(10000000);
}

fn my_bench<F> (f: F) -> f64 where F: Fn() {

    // first "throw away" run
    let mut d = Duration::span(|| {
        f();
    });
    let ns = d.num_nanoseconds().unwrap();
    //println!("num nano seconds first run {}", ns);

    let mut sum = 0;
    // iterate to get more cache hits, etc...
    let iters = 100.0;
    for _ in 0 .. iters as usize {
        d = Duration::span(|| {
            f();
        });
        let ns = d.num_nanoseconds().unwrap();
        sum = sum + ns;
    }

    let avg = (sum as f64) / iters;
    //println!("average after first run {}", avg);

    return avg;
}

fn main () {

    let mut max_ns = 10000000.0;
    let mut min_ns = 1.0;

    let num_steps = 500;
    let step_size = (max_ns - min_ns) / num_steps as f64;
    let mut num_ns = min_ns;

    for power in 0 .. num_steps {
        println!("Size.....: {}", num_ns as i64);
        num_ns += step_size;

        let t_avg = my_bench(||{
            let threads_holder = (0 .. 3).map(|_| {
                Thread::scoped(move || {
                    sleep_ns(num_ns as i64);
                })
            }).collect::<Vec<_>>();
        });
        println!("Runtime thread....: {}", t_avg);

        let s_avg = my_bench(||{
            sleep_ns(num_ns as i64);
            sleep_ns(num_ns as i64);
            sleep_ns(num_ns as i64);
        });
        println!("Runtime serial....: {}", s_avg);

        if t_avg < s_avg {
            println!("Cutoff size {}", num_ns);
            break;
        }
    }
}
<commit_msg>cleanup, more steps, cutoff<commit_after>#![feature(std_misc)]
#![feature(core)]

extern crate para_bm;

use std::time::Duration;
use std::thread::Thread;
use std::num::Float;

use para_bm::{sleep_ns};

fn fast () {
    sleep_ns(1000);
}

fn slow () {
    sleep_ns(10000000);
}

fn my_bench<F> (f: F) -> f64 where F: Fn() {

    // first "throw away" run
    let mut d = Duration::span(|| {
        f();
    });
    let ns = d.num_nanoseconds().unwrap();

    let mut sum = 0;
    // iterate to get more cache hits, etc...
    let iters = 100.0;
    for _ in 0 .. iters as usize {
        d = Duration::span(|| {
            f();
        });
        let ns = d.num_nanoseconds().unwrap();
        sum = sum + ns;
    }

    let avg = (sum as f64) / iters;

    return avg;
}

fn main () {

    let mut max_ns = 10000000.0;
    let mut min_ns = 1000.0;

    let num_steps = 5000;
    let step_size = (max_ns - min_ns) / num_steps as f64;
    let mut num_ns = min_ns;

    for power in 0 .. num_steps {
        println!("Size.....: {}", num_ns as i64);
        num_ns += step_size;

        let t_avg = my_bench(||{
            let threads_holder = (0 .. 3).map(|_| {
                Thread::scoped(move || {
                    sleep_ns(num_ns as i64);
                })
            }).collect::<Vec<_>>();
        });
        println!("Runtime thread....: {}", t_avg);

        let s_avg = my_bench(||{
            sleep_ns(num_ns as i64);
            sleep_ns(num_ns as i64);
            sleep_ns(num_ns as i64);
        });
        println!("Runtime serial....: {}", s_avg);

        if t_avg < s_avg {
            println!("Cutoff size {}", num_ns);
            break;
        }
    }
}
<|endoftext|>


<commit_before>use super::parse_module;

use core::semantic::ast::Node;

macro_rules! expr_test {
    ($name:ident, $code:expr) => {
        #[test]
        fn $name() {
            assert_eq!( parse_module($code)
                            .unwrap()[0]
                            .to_sexpr(0)
                      , $code)
        }
    }
}

expr_test!(test_basic_add, "(+ 1 2)");
expr_test!(test_basic_sub, "(- 3 4)");
expr_test!(test_basic_div, "(/ 5 6)");
expr_test!(test_basic_mul, "(* 1 2)");
expr_test!(test_nested_arith_1, "(+ 1 (- 2 3))");
expr_test!(test_nested_arith_2, "(* (+ 1 2) 3 4)");
expr_test!(test_nested_arith_3, "(+ (/ 1 2) (* 3 4))");

expr_test!(test_call_1, "(my_fn 1 2)");
expr_test!(test_call_2, "(my_fn (my_other_fn a_var a_different_var))");
expr_test!(test_call_3
  , "(my_fn (my_other_fn a_var a_different_var) VarWithUppercase Othervar)");
expr_test!(test_call_4
  , "(my_fn (my_other_fn a_var a_different_var) (another_fn a_var))");

expr_test!(test_call_ptr_1, "(my_fn a *b)");
expr_test!(test_call_ptr_2, "(my_fn *a *b)");
expr_test!(test_call_ptr_3, "(my_fn &a)");
expr_test!(test_call_ptr_4, "(my_fn a &b)");
expr_test!(test_call_ptr_5, "(my_fn &a &b)");
expr_test!(test_call_ptr_6, "(my_fn @a)");
expr_test!(test_call_ptr_7, "(my_fn a @b)");
expr_test!(test_call_ptr_8, "(my_fn @a @b)");

expr_test!(test_defsyntax_1,
r#"(def fac (fn (-> I64 I64)
    ((0) 1)
    ((n) (fac (- n 1)))))"#);
<commit_msg>Commented out NYI parser test temporarily<commit_after>use super::parse_module;

use core::semantic::ast::Node;

macro_rules! expr_test {
    ($name:ident, $code:expr) => {
        #[test]
        fn $name() {
            assert_eq!( parse_module($code)
                            .unwrap()[0]
                            .to_sexpr(0)
                      , $code)
        }
    }
}

expr_test!(test_basic_add, "(+ 1 2)");
expr_test!(test_basic_sub, "(- 3 4)");
expr_test!(test_basic_div, "(/ 5 6)");
expr_test!(test_basic_mul, "(* 1 2)");
expr_test!(test_nested_arith_1, "(+ 1 (- 2 3))");
expr_test!(test_nested_arith_2, "(* (+ 1 2) 3 4)");
expr_test!(test_nested_arith_3, "(+ (/ 1 2) (* 3 4))");

expr_test!(test_call_1, "(my_fn 1 2)");
expr_test!(test_call_2, "(my_fn (my_other_fn a_var a_different_var))");
expr_test!(test_call_3
  , "(my_fn (my_other_fn a_var a_different_var) VarWithUppercase Othervar)");
expr_test!(test_call_4
  , "(my_fn (my_other_fn a_var a_different_var) (another_fn a_var))");

expr_test!(test_call_ptr_1, "(my_fn a *b)");
expr_test!(test_call_ptr_2, "(my_fn *a *b)");
expr_test!(test_call_ptr_3, "(my_fn &a)");
expr_test!(test_call_ptr_4, "(my_fn a &b)");
expr_test!(test_call_ptr_5, "(my_fn &a &b)");
expr_test!(test_call_ptr_6, "(my_fn @a)");
expr_test!(test_call_ptr_7, "(my_fn a @b)");
expr_test!(test_call_ptr_8, "(my_fn @a @b)");

// expr_test!(test_defsyntax_1,
// r#"
// (defn fac (-> I64 I64)
//     ((0) 1)
//     ((n) (fac (- n 1))))"#);
<|endoftext|>


<commit_before>#![allow(dead_code)]
use tag::{TagType, VerifyTag};

#[repr(C)]
pub struct MemoryMapTag {
    tag_type: u32,
    size: u32,
    entry_size: u32,
    /// This is currently set to `0`.
    entry_version: u32,
    first_entry: MemoryMapEntry
}

impl MemoryMapTag {
    pub fn memory_regions(&self) -> MemoryMapIter {
        let ptr = self as *const MemoryMapTag;
        let first_entry = (&self.first_entry) as *const MemoryMapEntry;
        let final_entry = ((ptr as u64) + (self.size as u64)) as *const MemoryMapEntry;

        MemoryMapIter::new(first_entry, final_entry, self.entry_size)
    }

    fn all_memory_regions(&self) -> VerifyMemoryMapIter {
        let ptr = self as *const MemoryMapTag;
        let first_entry = (&self.first_entry) as *const MemoryMapEntry;
        let final_entry = ((ptr as u64) + (self.size as u64)) as *const MemoryMapEntry;

        VerifyMemoryMapIter::new(first_entry, final_entry, self.entry_size)
    }
}

impl VerifyTag for MemoryMapTag {
    fn is_valid(&self) -> bool {
        let mut entries = self.all_memory_regions();

        (self.tag_type == TagType::MemoryMap as u32) &&
        (self.entry_size % 8 == 0) &&
        (self.entry_version == 0) &&
        entries.all(|entry| entry.is_valid())
    }
}

#[derive(Debug)]
#[repr(C, packed)]
pub struct MemoryMapEntry {
    /// The starting physical address
    base_addr: u64,
    /// The size of the memory region, in bytes.
    length: u64,
    /// The type of memory region contained.
    entry_type: u32,
    /// This should be set to `0` and ignored by the bootloader.
    reserved: u32
}

#[derive(Debug, PartialEq, Eq)]
pub enum MemoryType {
    Usable         = 1,
    UsableWithACPI = 3,
    Unusable       = 4,
}

impl MemoryMapEntry {
    pub fn base_address(&self) -> usize {
        self.base_addr as usize
    }

    pub fn length(&self) -> usize {
        self.length as usize
    }

    fn memory_type(&self) -> MemoryType {
        match self.entry_type {
            1 => MemoryType::Usable,
            3 => MemoryType::UsableWithACPI,
            _ => MemoryType::Unusable
        }
    }

    fn is_usable_region(&self) -> bool {
        self.memory_type() == MemoryType::Usable
    }

    fn is_valid(&self) -> bool {
        self.reserved == 0
    }
}

pub struct MemoryMapIter {
    current_entry: *const MemoryMapEntry,
    final_entry: *const MemoryMapEntry,
    // We need to know the entry size so we can calculate the
    // address of the next memory map entry.
    entry_size: u32,
}

impl MemoryMapIter {
    fn new(current_entry: *const MemoryMapEntry,
           final_entry: *const MemoryMapEntry,
           entry_size: u32) -> MemoryMapIter
    {
        MemoryMapIter {
            current_entry: current_entry,
            final_entry: final_entry,
            entry_size: entry_size,
        }
    }
}

impl Iterator for MemoryMapIter {
    type Item = &'static MemoryMapEntry;

    fn next(&mut self) -> Option<Self::Item> {
        // Loop until the next usable memory region. We ignore the unusable regions
        // per the Multiboot2 standard requirements.
        loop {
            if self.current_entry <= self.final_entry {
                let current_entry = unsafe { &*self.current_entry };
                let next_entry = (self.current_entry as u64) + (self.entry_size as u64);

                self.current_entry = next_entry as *const MemoryMapEntry;

                if current_entry.is_usable_region() {
                    return Some(current_entry);
                }

            } else {
                // We have fallen off the end of the memory map.
                return None;
            }
        }
    }
}

// This iterator is for supporting verification of the memory map. This iterator
// also iterates over the unusable memory regions.
struct VerifyMemoryMapIter {
    current_entry: *const MemoryMapEntry,
    final_entry: *const MemoryMapEntry,
    // We need to know the entry size so we can calculate the
    // address of the next memory map entry.
    entry_size: u32,
}

impl VerifyMemoryMapIter {
    fn new(current_entry: *const MemoryMapEntry,
           final_entry: *const MemoryMapEntry,
           entry_size: u32) -> VerifyMemoryMapIter
    {
        VerifyMemoryMapIter {
            current_entry: current_entry,
            final_entry: final_entry,
            entry_size: entry_size,
        }
    }
}

impl Iterator for VerifyMemoryMapIter {
    type Item = &'static MemoryMapEntry;

    fn next(&mut self) -> Option<Self::Item> {
        if self.current_entry <= self.final_entry {
            let current_entry = unsafe { &*self.current_entry };
            let next_entry = (self.current_entry as u64) + (self.entry_size as u64);

            self.current_entry = next_entry as *const MemoryMapEntry;

            return Some(current_entry);

        } else {
            // We have fallen off the end of the memory map.
            return None;
        }
    }
}
<commit_msg>Minor refactoring of verification code.<commit_after>#![allow(dead_code)]
use tag::{TagType, VerifyTag};

#[repr(C)]
pub struct MemoryMapTag {
    tag_type: u32,
    size: u32,
    entry_size: u32,
    /// This is currently set to `0`.
    entry_version: u32,
    first_entry: MemoryMapEntry
}

impl MemoryMapTag {
    pub fn memory_regions(&self) -> MemoryMapIter {
        let ptr = self as *const MemoryMapTag;
        let first_entry = (&self.first_entry) as *const MemoryMapEntry;
        let final_entry = ((ptr as u64) + (self.size as u64)) as *const MemoryMapEntry;

        MemoryMapIter::new(first_entry, final_entry, self.entry_size)
    }

    fn all_memory_regions(&self) -> VerifyMemoryMapIter {
        let ptr = self as *const MemoryMapTag;
        let first_entry = (&self.first_entry) as *const MemoryMapEntry;
        let final_entry = ((ptr as u64) + (self.size as u64)) as *const MemoryMapEntry;

        VerifyMemoryMapIter::new(first_entry, final_entry, self.entry_size)
    }
}

impl VerifyTag for MemoryMapTag {
    fn is_valid(&self) -> bool {
        let mut entries = self.all_memory_regions();

        (self.tag_type == TagType::MemoryMap as u32)
            && (self.entry_size % 8 == 0)
            && (self.entry_version == 0)
            && entries.all(|entry| entry.is_valid())
    }
}

#[derive(Debug)]
#[repr(C, packed)]
pub struct MemoryMapEntry {
    /// The starting physical address
    base_addr: u64,
    /// The size of the memory region, in bytes.
    length: u64,
    /// The type of memory region contained.
    entry_type: u32,
    /// This should be set to `0` and ignored by the bootloader.
    reserved: u32
}

#[derive(Debug, PartialEq, Eq)]
pub enum MemoryType {
    Usable         = 1,
    UsableWithACPI = 3,
    Unusable       = 4,
}

impl MemoryMapEntry {
    pub fn base_address(&self) -> usize {
        self.base_addr as usize
    }

    pub fn length(&self) -> usize {
        self.length as usize
    }

    fn memory_type(&self) -> MemoryType {
        match self.entry_type {
            1 => MemoryType::Usable,
            3 => MemoryType::UsableWithACPI,
            _ => MemoryType::Unusable
        }
    }

    fn is_usable_region(&self) -> bool {
        self.memory_type() == MemoryType::Usable
    }

    fn is_valid(&self) -> bool {
        self.reserved == 0
    }
}

pub struct MemoryMapIter {
    current_entry: *const MemoryMapEntry,
    final_entry: *const MemoryMapEntry,
    // We need to know the entry size so we can calculate the
    // address of the next memory map entry.
    entry_size: u32,
}

impl MemoryMapIter {
    fn new(current_entry: *const MemoryMapEntry,
           final_entry: *const MemoryMapEntry,
           entry_size: u32) -> MemoryMapIter
    {
        MemoryMapIter {
            current_entry: current_entry,
            final_entry: final_entry,
            entry_size: entry_size,
        }
    }
}

impl Iterator for MemoryMapIter {
    type Item = &'static MemoryMapEntry;

    fn next(&mut self) -> Option<Self::Item> {
        // Loop until the next usable memory region. We ignore the unusable regions
        // per the Multiboot2 standard requirements.
        loop {
            if self.current_entry <= self.final_entry {
                let current_entry = unsafe { &*self.current_entry };
                let next_entry = (self.current_entry as u64) + (self.entry_size as u64);

                self.current_entry = next_entry as *const MemoryMapEntry;

                if current_entry.is_usable_region() {
                    return Some(current_entry);
                }

            } else {
                // We have fallen off the end of the memory map.
                return None;
            }
        }
    }
}

// This iterator is for supporting verification of the memory map. This iterator
// also iterates over the unusable memory regions.
struct VerifyMemoryMapIter {
    current_entry: *const MemoryMapEntry,
    final_entry: *const MemoryMapEntry,
    // We need to know the entry size so we can calculate the
    // address of the next memory map entry.
    entry_size: u32,
}

impl VerifyMemoryMapIter {
    fn new(current_entry: *const MemoryMapEntry,
           final_entry: *const MemoryMapEntry,
           entry_size: u32) -> VerifyMemoryMapIter
    {
        VerifyMemoryMapIter {
            current_entry: current_entry,
            final_entry: final_entry,
            entry_size: entry_size,
        }
    }
}

impl Iterator for VerifyMemoryMapIter {
    type Item = &'static MemoryMapEntry;

    fn next(&mut self) -> Option<Self::Item> {
        if self.current_entry <= self.final_entry {
            let current_entry = unsafe { &*self.current_entry };
            let next_entry = (self.current_entry as u64) + (self.entry_size as u64);

            self.current_entry = next_entry as *const MemoryMapEntry;

            return Some(current_entry);

        } else {
            // We have fallen off the end of the memory map.
            return None;
        }
    }
}
<|endoftext|>