<commit_before>//! This module contains utilities for turning SyntaxNodes and HIR types
//! into types that may be used to render in a UI.

mod function_signature;
mod navigation_target;
mod structure;
mod short_label;

use std::fmt::Display;

use ra_syntax::{
    ast::{self, AstNode, AttrsOwner, NameOwner, TypeParamsOwner},
    SyntaxKind::{ATTR, COMMENT},
};
use stdx::format_to;

pub use function_signature::FunctionSignature;
pub use navigation_target::NavigationTarget;
pub use structure::{file_structure, StructureNode};

pub(crate) use navigation_target::{ToNav, TryToNav};
pub(crate) use short_label::ShortLabel;

pub(crate) fn function_label(node: &ast::FnDef) -> String {
    FunctionSignature::from(node).to_string()
}

pub(crate) fn const_label(node: &ast::ConstDef) -> String {
    let label: String = node
        .syntax()
        .children_with_tokens()
        .filter(|child| !(child.kind() == COMMENT || child.kind() == ATTR))
        .map(|node| node.to_string())
        .collect();

    label.trim().to_owned()
}

pub(crate) fn type_label(node: &ast::TypeAliasDef) -> String {
    let label: String = node
        .syntax()
        .children_with_tokens()
        .filter(|child| !(child.kind() == COMMENT || child.kind() == ATTR))
        .map(|node| node.to_string())
        .collect();

    label.trim().to_owned()
}

pub(crate) fn generic_parameters<N: TypeParamsOwner>(node: &N) -> Vec<String> {
    let mut res = vec![];
    if let Some(type_params) = node.type_param_list() {
        res.extend(type_params.lifetime_params().map(|p| p.syntax().text().to_string()));
        res.extend(type_params.type_params().map(|p| p.syntax().text().to_string()));
    }
    res
}

pub(crate) fn where_predicates<N: TypeParamsOwner>(node: &N) -> Vec<String> {
    let mut res = vec![];
    if let Some(clause) = node.where_clause() {
        res.extend(clause.predicates().map(|p| p.syntax().text().to_string()));
    }
    res
}

pub(crate) fn macro_label(node: &ast::MacroCall) -> String {
    let name = node.name().map(|name| name.syntax().text().to_string()).unwrap_or_default();
    let vis = if node.has_atom_attr("macro_export") { "#[macro_export]\n" } else { "" };
    format!("{}macro_rules! {}", vis, name)
}

pub(crate) fn rust_code_markup(code: &impl Display) -> String {
    rust_code_markup_with_doc(code, None, None)
}

pub(crate) fn rust_code_markup_with_doc(
    code: &impl Display,
    doc: Option<&str>,
    mod_path: Option<&str>,
) -> String {
    let mut buf = "".to_owned();

    if let Some(mod_path) = mod_path {
        if !mod_path.is_empty() {
            format_to!(buf, "{}\n___\n", mod_path);
        }
    }
    format_to!(buf, "```rust\n\n{}\n```", code);

    if let Some(doc) = doc {
        format_to!(buf, "\n\n{}", doc);
    }

    buf
}
<commit_msg>Fix formatting error when no modpath is present<commit_after>//! This module contains utilities for turning SyntaxNodes and HIR types
//! into types that may be used to render in a UI.

mod function_signature;
mod navigation_target;
mod structure;
mod short_label;

use std::fmt::Display;

use ra_syntax::{
    ast::{self, AstNode, AttrsOwner, NameOwner, TypeParamsOwner},
    SyntaxKind::{ATTR, COMMENT},
};
use stdx::format_to;

pub use function_signature::FunctionSignature;
pub use navigation_target::NavigationTarget;
pub use structure::{file_structure, StructureNode};

pub(crate) use navigation_target::{ToNav, TryToNav};
pub(crate) use short_label::ShortLabel;

pub(crate) fn function_label(node: &ast::FnDef) -> String {
    FunctionSignature::from(node).to_string()
}

pub(crate) fn const_label(node: &ast::ConstDef) -> String {
    let label: String = node
        .syntax()
        .children_with_tokens()
        .filter(|child| !(child.kind() == COMMENT || child.kind() == ATTR))
        .map(|node| node.to_string())
        .collect();

    label.trim().to_owned()
}

pub(crate) fn type_label(node: &ast::TypeAliasDef) -> String {
    let label: String = node
        .syntax()
        .children_with_tokens()
        .filter(|child| !(child.kind() == COMMENT || child.kind() == ATTR))
        .map(|node| node.to_string())
        .collect();

    label.trim().to_owned()
}

pub(crate) fn generic_parameters<N: TypeParamsOwner>(node: &N) -> Vec<String> {
    let mut res = vec![];
    if let Some(type_params) = node.type_param_list() {
        res.extend(type_params.lifetime_params().map(|p| p.syntax().text().to_string()));
        res.extend(type_params.type_params().map(|p| p.syntax().text().to_string()));
    }
    res
}

pub(crate) fn where_predicates<N: TypeParamsOwner>(node: &N) -> Vec<String> {
    let mut res = vec![];
    if let Some(clause) = node.where_clause() {
        res.extend(clause.predicates().map(|p| p.syntax().text().to_string()));
    }
    res
}

pub(crate) fn macro_label(node: &ast::MacroCall) -> String {
    let name = node.name().map(|name| name.syntax().text().to_string()).unwrap_or_default();
    let vis = if node.has_atom_attr("macro_export") { "#[macro_export]\n" } else { "" };
    format!("{}macro_rules! {}", vis, name)
}

pub(crate) fn rust_code_markup(code: &impl Display) -> String {
    rust_code_markup_with_doc(code, None, None)
}

pub(crate) fn rust_code_markup_with_doc(
    code: &impl Display,
    doc: Option<&str>,
    mod_path: Option<&str>,
) -> String {
    let mut buf = String::new();

    if let Some(mod_path) = mod_path {
        if !mod_path.is_empty() {
            format_to!(buf, "{}\n___\n\n", mod_path);
        }
    }
    format_to!(buf, "```rust\n{}\n```", code);

    if let Some(doc) = doc {
        format_to!(buf, "\n\n{}", doc);
    }

    buf
}
<|endoftext|>


<commit_before>use rustc_serialize::json::Json;
use chrono::{DateTime, UTC, Timelike};
use byteorder::{WriteBytesExt, BigEndian};

#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
pub struct TermRef(u32);

impl TermRef {
    pub fn new(ord: u32) -> TermRef {
        TermRef(ord)
    }

    pub fn ord(&self) -> u32 {
        self.0
    }
}

#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Hash)]
pub enum Term {
    String(String),
    Boolean(bool),
    I64(i64),
    U64(u64),
    DateTime(DateTime<UTC>),
    //F64(f64),
}

impl Term {
    pub fn from_json(json: &Json) -> Option<Term> {
        // TODO: Should be aware of mappings
        match *json {
            Json::String(ref string) => Some(Term::String(string.clone())),
            Json::Boolean(value) => Some(Term::Boolean(value)),
            Json::F64(_) => None, //Term::F64(value),
            Json::I64(value) => Some(Term::I64(value)),
            Json::U64(value) => Some(Term::U64(value)),
            Json::Null => None,
            Json::Array(_) => None,
            Json::Object(_) => None,
        }
    }

    pub fn as_json(&self) -> Json {
        match *self {
            Term::String(ref string) => Json::String(string.clone()),
            Term::Boolean(value) => Json::Boolean(value),
            //Term::F64(value) => Json::F64(value),
            Term::I64(value) => Json::I64(value),
            Term::U64(value) => Json::U64(value),
            Term::DateTime(value) => Json::String(value.to_rfc3339()),
        }
    }

    pub fn to_bytes(&self) -> Vec<u8> {
        match *self {
            Term::String(ref string) => {
                let mut bytes = Vec::with_capacity(string.len());

                for byte in string.as_bytes() {
                    bytes.push(*byte);
                }

                bytes
            },
            Term::Boolean(value) => {
                if value {
                    vec![b't']
                } else {
                    vec![b'f']
                }
            }
            Term::I64(value) => {
                let mut bytes = Vec::with_capacity(8);
                bytes.write_i64::<BigEndian>(value).unwrap();
                bytes
            }
            Term::U64(value) => {
                let mut bytes = Vec::with_capacity(8);
                bytes.write_u64::<BigEndian>(value).unwrap();
                bytes
            }
            Term::DateTime(value) => {
                let mut bytes = Vec::with_capacity(0);
                let timestamp = value.timestamp();
                let micros = value.nanosecond() / 1000;
                let timestamp_with_micros = timestamp * 1000000 + micros as i64;
                bytes.write_i64::<BigEndian>(timestamp_with_micros).unwrap();
                bytes
            }
        }
    }
}

#[cfg(test)]
mod tests {
    use chrono::{DateTime, UTC, Timelike};
    use super::Term;

    #[test]
    fn test_string_to_bytes() {
        let term = Term::String("foo".to_string());

        assert_eq!(term.to_bytes(), vec![102, 111, 111])
    }

    #[test]
    fn test_hiragana_string_to_bytes() {
        let term = Term::String("こんにちは".to_string());

        assert_eq!(term.to_bytes(), vec![227, 129, 147, 227, 130, 147, 227, 129, 171, 227, 129, 161, 227, 129, 175])
    }

    #[test]
    fn test_blank_string_to_bytes() {
        let term = Term::String("".to_string());

        assert_eq!(term.to_bytes(), vec![])
    }

    #[test]
    fn test_boolean_true_to_bytes() {
        let term = Term::Boolean(true);

        // 116 = 't' in ASCII
        assert_eq!(term.to_bytes(), vec![116])
    }

    #[test]
    fn test_boolean_false_to_bytes() {
        let term = Term::Boolean(false);

        // 102 = 'f' in ASCII
        assert_eq!(term.to_bytes(), vec![102])
    }

    #[test]
    fn test_i64_to_bytes() {
        let term = Term::I64(123);

        assert_eq!(term.to_bytes(), vec![0, 0, 0, 0, 0, 0, 0, 123])
    }

    #[test]
    fn test_negative_i64_to_bytes() {
        let term = Term::I64(-123);

        assert_eq!(term.to_bytes(), vec![255, 255, 255, 255, 255, 255, 255, 133])
    }

    #[test]
    fn test_u64_to_bytes() {
        let term = Term::U64(123);

        assert_eq!(term.to_bytes(), vec![0, 0, 0, 0, 0, 0, 0, 123])
    }

    #[test]
    fn test_datetime_to_bytes() {
        let date = "2016-07-23T16:15:00+01:00".parse::<DateTime<UTC>>().unwrap();
        let term = Term::DateTime(date);

        assert_eq!(term.to_bytes(), vec![0, 5, 56, 79, 3, 191, 101, 0])
    }

    #[test]
    fn test_datetime_with_microseconds_to_bytes() {
        let mut date = "2016-07-23T16:15:00+01:00".parse::<DateTime<UTC>>().unwrap();
        date = date.with_nanosecond(123123123).unwrap();
        let term = Term::DateTime(date);

        // This is exactly 123123 higher than the result of "test_datetime_to_bytes"
        assert_eq!(term.to_bytes(), vec![0, 5, 56, 79, 3, 193, 69, 243])
    }

    #[test]
    fn test_datetime_with_different_timezone_to_bytes() {
        let date = "2016-07-23T16:15:00+02:00".parse::<DateTime<UTC>>().unwrap();
        let term = Term::DateTime(date);

        // This is exactly 3_600_000_000 lower than the result of "test_datetime_to_bytes"
        assert_eq!(term.to_bytes(), vec![0, 5, 56, 78, 45, 43, 193, 0])
    }
}
<commit_msg>Completely remove F64 term type<commit_after>use rustc_serialize::json::Json;
use chrono::{DateTime, UTC, Timelike};
use byteorder::{WriteBytesExt, BigEndian};

#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
pub struct TermRef(u32);

impl TermRef {
    pub fn new(ord: u32) -> TermRef {
        TermRef(ord)
    }

    pub fn ord(&self) -> u32 {
        self.0
    }
}

#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Hash)]
pub enum Term {
    String(String),
    Boolean(bool),
    I64(i64),
    U64(u64),
    DateTime(DateTime<UTC>),
}

impl Term {
    pub fn from_json(json: &Json) -> Option<Term> {
        // TODO: Should be aware of mappings
        match *json {
            Json::String(ref string) => Some(Term::String(string.clone())),
            Json::Boolean(value) => Some(Term::Boolean(value)),
            Json::F64(_) => None,
            Json::I64(value) => Some(Term::I64(value)),
            Json::U64(value) => Some(Term::U64(value)),
            Json::Null => None,
            Json::Array(_) => None,
            Json::Object(_) => None,
        }
    }

    pub fn as_json(&self) -> Json {
        match *self {
            Term::String(ref string) => Json::String(string.clone()),
            Term::Boolean(value) => Json::Boolean(value),
            Term::I64(value) => Json::I64(value),
            Term::U64(value) => Json::U64(value),
            Term::DateTime(value) => Json::String(value.to_rfc3339()),
        }
    }

    pub fn to_bytes(&self) -> Vec<u8> {
        match *self {
            Term::String(ref string) => {
                let mut bytes = Vec::with_capacity(string.len());

                for byte in string.as_bytes() {
                    bytes.push(*byte);
                }

                bytes
            },
            Term::Boolean(value) => {
                if value {
                    vec![b't']
                } else {
                    vec![b'f']
                }
            }
            Term::I64(value) => {
                let mut bytes = Vec::with_capacity(8);
                bytes.write_i64::<BigEndian>(value).unwrap();
                bytes
            }
            Term::U64(value) => {
                let mut bytes = Vec::with_capacity(8);
                bytes.write_u64::<BigEndian>(value).unwrap();
                bytes
            }
            Term::DateTime(value) => {
                let mut bytes = Vec::with_capacity(0);
                let timestamp = value.timestamp();
                let micros = value.nanosecond() / 1000;
                let timestamp_with_micros = timestamp * 1000000 + micros as i64;
                bytes.write_i64::<BigEndian>(timestamp_with_micros).unwrap();
                bytes
            }
        }
    }
}

#[cfg(test)]
mod tests {
    use chrono::{DateTime, UTC, Timelike};
    use super::Term;

    #[test]
    fn test_string_to_bytes() {
        let term = Term::String("foo".to_string());

        assert_eq!(term.to_bytes(), vec![102, 111, 111])
    }

    #[test]
    fn test_hiragana_string_to_bytes() {
        let term = Term::String("こんにちは".to_string());

        assert_eq!(term.to_bytes(), vec![227, 129, 147, 227, 130, 147, 227, 129, 171, 227, 129, 161, 227, 129, 175])
    }

    #[test]
    fn test_blank_string_to_bytes() {
        let term = Term::String("".to_string());

        assert_eq!(term.to_bytes(), vec![])
    }

    #[test]
    fn test_boolean_true_to_bytes() {
        let term = Term::Boolean(true);

        // 116 = 't' in ASCII
        assert_eq!(term.to_bytes(), vec![116])
    }

    #[test]
    fn test_boolean_false_to_bytes() {
        let term = Term::Boolean(false);

        // 102 = 'f' in ASCII
        assert_eq!(term.to_bytes(), vec![102])
    }

    #[test]
    fn test_i64_to_bytes() {
        let term = Term::I64(123);

        assert_eq!(term.to_bytes(), vec![0, 0, 0, 0, 0, 0, 0, 123])
    }

    #[test]
    fn test_negative_i64_to_bytes() {
        let term = Term::I64(-123);

        assert_eq!(term.to_bytes(), vec![255, 255, 255, 255, 255, 255, 255, 133])
    }

    #[test]
    fn test_u64_to_bytes() {
        let term = Term::U64(123);

        assert_eq!(term.to_bytes(), vec![0, 0, 0, 0, 0, 0, 0, 123])
    }

    #[test]
    fn test_datetime_to_bytes() {
        let date = "2016-07-23T16:15:00+01:00".parse::<DateTime<UTC>>().unwrap();
        let term = Term::DateTime(date);

        assert_eq!(term.to_bytes(), vec![0, 5, 56, 79, 3, 191, 101, 0])
    }

    #[test]
    fn test_datetime_with_microseconds_to_bytes() {
        let mut date = "2016-07-23T16:15:00+01:00".parse::<DateTime<UTC>>().unwrap();
        date = date.with_nanosecond(123123123).unwrap();
        let term = Term::DateTime(date);

        // This is exactly 123123 higher than the result of "test_datetime_to_bytes"
        assert_eq!(term.to_bytes(), vec![0, 5, 56, 79, 3, 193, 69, 243])
    }

    #[test]
    fn test_datetime_with_different_timezone_to_bytes() {
        let date = "2016-07-23T16:15:00+02:00".parse::<DateTime<UTC>>().unwrap();
        let term = Term::DateTime(date);

        // This is exactly 3_600_000_000 lower than the result of "test_datetime_to_bytes"
        assert_eq!(term.to_bytes(), vec![0, 5, 56, 78, 45, 43, 193, 0])
    }
}
<|endoftext|>


<commit_before>extern crate gimli;
extern crate getopts;
extern crate memmap;
extern crate object;

use object::Object;
use std::env;
use std::fs;

fn main() {
    let args: Vec<String> = env::args().collect();
    let mut opts = getopts::Options::new();
    opts.optopt("e",
                "exe",
                "Set the input file name (default is a.out)",
                "<executable>");

    let matches = opts.parse(&args[1..]).unwrap();

    let file_path = matches.opt_str("e").unwrap_or("a.out".to_string());
    let file = fs::File::open(&file_path).expect("Should open file");
    let file = memmap::Mmap::open(&file, memmap::Protection::Read)
        .expect("Should create a mmap for file");
    let file = object::File::parse(unsafe { file.as_slice() });

    if file.is_little_endian() {
        symbolicate::<gimli::LittleEndian>(&file, &matches);
    } else {
        symbolicate::<gimli::BigEndian>(&file, &matches);
    }
}

fn parse_uint_from_hex_string(string: &str) -> u64 {
    if string.len() > 2 && string.starts_with("0x") {
        u64::from_str_radix(&string[2..], 16).expect("Failed to parse address")
    } else {
        u64::from_str_radix(string, 16).expect("Failed to parse address")
    }
}

fn entry_offsets_for_addresses<Endian>(file: &object::File,
                                       addrs: &Vec<u64>)
                                       -> Vec<Option<gimli::DebugInfoOffset>>
    where Endian: gimli::Endianity
{
    let aranges = file.get_section(".debug_aranges")
        .expect("Can't addr2line with no aranges");
    let aranges = gimli::DebugAranges::<Endian>::new(aranges);
    let mut aranges = aranges.items();

    let mut dies: Vec<Option<gimli::DebugInfoOffset>> = (0..addrs.len()).map(|_| None).collect();
    while let Some(arange) = aranges.next().expect("Should parse arange OK") {
        let start = arange.address();
        let end = start + arange.length();

        for (i, addr) in addrs.iter().enumerate() {
            if *addr >= start && *addr < end {
                dies[i] = Some(arange.debug_info_offset());
            }
        }
    }

    dies
}

fn line_offset_for_entry<Endian>(abbrevs: &gimli::DebugAbbrev<Endian>,
                                 header: &gimli::UnitHeader<Endian>)
                                 -> Option<gimli::DebugLineOffset>
    where Endian: gimli::Endianity
{
    let abbrev = abbrevs.abbreviations(header.debug_abbrev_offset()).expect("Fail");
    let mut entries = header.entries(&abbrev);
    let (_, entry) = entries.next_dfs()
        .expect("Should parse first entry OK")
        .expect("And first entry should exist!");
    match entry.attr_value(gimli::DW_AT_stmt_list) {
        Some(gimli::AttributeValue::DebugLineRef(offset)) => Some(offset),
        _ => None,
    }
}

fn display_file<Endian>(row: gimli::LineNumberRow<Endian>)
    where Endian: gimli::Endianity
{
    let file = row.file().unwrap();
    if let Some(directory) = file.directory(row.header()) {
        println!("{}/{}:{}",
                 directory.to_string_lossy(),
                 file.path_name().to_string_lossy(),
                 row.line().unwrap());
    } else {
        println!("{}:{}",
                 file.path_name().to_string_lossy(),
                 row.line().unwrap());
    }
}

fn symbolicate<Endian>(file: &object::File, matches: &getopts::Matches)
    where Endian: gimli::Endianity
{
    let addrs: Vec<u64> = matches.free.iter().map(|x| parse_uint_from_hex_string(x)).collect();

    let offsets = entry_offsets_for_addresses::<Endian>(&file, &addrs);
    let debug_info = file.get_section(".debug_info")
        .expect("Can't addr2line without .debug_info");
    let debug_info = gimli::DebugInfo::<Endian>::new(debug_info);
    let debug_abbrev = file.get_section(".debug_abbrev")
        .expect("Can't addr2line without .debug_abbrev");
    let debug_abbrev = gimli::DebugAbbrev::<Endian>::new(debug_abbrev);
    let debug_line = file.get_section(".debug_line")
        .expect("Can't addr2line without .debug_line");
    let debug_line = gimli::DebugLine::<Endian>::new(&debug_line);

    for (info_offset, addr) in offsets.iter().zip(addrs.iter()) {
        match *info_offset {
            None => println!("Found nothing"),
            Some(d) => {
                match debug_info.header_from_offset(d) {
                    Err(_) => println!("Couldn't get DIE header"),
                    Ok(h) => {
                        let line_offset = line_offset_for_entry(&debug_abbrev, &h)
                            .expect("No offset into .debug_lines!?");
                        let header = gimli::LineNumberProgramHeader::new(debug_line,
                                                                         line_offset,
                                                                         h.address_size());
                        if let Ok(header) = header {
                            let mut state_machine = gimli::StateMachine::new(header);
                            match state_machine.run_to_address(addr) {
                                Err(_) => println!("Failed to run line number program!"),
                                Ok(None) => println!("Failed to find matching line for {}", *addr),
                                Ok(Some(row)) => display_file(row),
                            };
                        }
                    }
                }
            }
        }
    }
}
<commit_msg>addr2line: use DW_AT_low_pc/DW_AT_high_pc instead of .debug_aranges<commit_after>extern crate gimli;
extern crate getopts;
extern crate memmap;
extern crate object;

use object::Object;
use std::env;
use std::fs;

fn main() {
    let args: Vec<String> = env::args().collect();
    let mut opts = getopts::Options::new();
    opts.optopt("e",
                "exe",
                "Set the input file name (default is a.out)",
                "<executable>");

    let matches = opts.parse(&args[1..]).unwrap();

    let file_path = matches.opt_str("e").unwrap_or("a.out".to_string());
    let file = fs::File::open(&file_path).expect("Should open file");
    let file = memmap::Mmap::open(&file, memmap::Protection::Read)
        .expect("Should create a mmap for file");
    let file = object::File::parse(unsafe { file.as_slice() });

    let addrs = matches.free.iter().map(|x| parse_uint_from_hex_string(x)).collect();

    if file.is_little_endian() {
        symbolicate::<gimli::LittleEndian>(&file, addrs);
    } else {
        symbolicate::<gimli::BigEndian>(&file, addrs);
    }
}

fn parse_uint_from_hex_string(string: &str) -> u64 {
    if string.len() > 2 && string.starts_with("0x") {
        u64::from_str_radix(&string[2..], 16).expect("Failed to parse address")
    } else {
        u64::from_str_radix(string, 16).expect("Failed to parse address")
    }
}

fn display_file<Endian>(row: gimli::LineNumberRow<Endian>)
    where Endian: gimli::Endianity
{
    let file = row.file().unwrap();
    if let Some(directory) = file.directory(row.header()) {
        println!("{}/{}:{}",
                 directory.to_string_lossy(),
                 file.path_name().to_string_lossy(),
                 row.line().unwrap());
    } else {
        println!("{}:{}",
                 file.path_name().to_string_lossy(),
                 row.line().unwrap());
    }
}

fn symbolicate<Endian>(file: &object::File, addrs: Vec<u64>)
    where Endian: gimli::Endianity
{
    let debug_info = file.get_section(".debug_info")
        .expect("Can't addr2line without .debug_info");
    let debug_info = gimli::DebugInfo::<Endian>::new(debug_info);
    let debug_abbrev = file.get_section(".debug_abbrev")
        .expect("Can't addr2line without .debug_abbrev");
    let debug_abbrev = gimli::DebugAbbrev::<Endian>::new(debug_abbrev);
    let debug_line = file.get_section(".debug_line")
        .expect("Can't addr2line without .debug_line");
    let debug_line = gimli::DebugLine::<Endian>::new(&debug_line);

    let mut units = Vec::new();
    let mut headers = debug_info.units();
    while let Some(header) = headers.next().expect("Couldn't get DIE header") {
        if let Some(unit) = Unit::parse(&debug_abbrev, &header) {
            units.push(unit);
        }
    }

    for addr in addrs {
        find_address(debug_line, &units, addr);
    }
}

fn find_address<Endian>(debug_line: gimli::DebugLine<Endian>, units: &[Unit], addr: u64)
    where Endian: gimli::Endianity
{
    for unit in units {
        if unit.contains_address(addr) {
            if let Ok(mut lines) = unit.lines(debug_line) {
                if let Ok(Some(row)) = lines.run_to_address(&addr) {
                    display_file(row);
                    return;
                };
            }
        }
    }
    println!("Failed to find matching line for {}", addr);
}

struct Unit {
    address_size: u8,
    low_pc: u64,
    high_pc: u64,
    line_offset: gimli::DebugLineOffset,
}

impl Unit {
    fn parse<Endian>(abbrevs: &gimli::DebugAbbrev<Endian>,
                     header: &gimli::UnitHeader<Endian>)
                     -> Option<Unit>
        where Endian: gimli::Endianity
    {
        let abbrev = abbrevs.abbreviations(header.debug_abbrev_offset()).expect("Fail");
        let mut entries = header.entries(&abbrev);
        let (_, entry) = entries.next_dfs()
            .expect("Should parse first entry OK")
            .expect("And first entry should exist!");

        let low_pc = match entry.attr_value(gimli::DW_AT_low_pc) {
            Some(gimli::AttributeValue::Addr(addr)) => addr,
            _ => 0,
        };
        let high_pc = match entry.attr_value(gimli::DW_AT_high_pc) {
            Some(gimli::AttributeValue::Addr(addr)) => addr,
            _ => 0,
        };
        // TODO: handle DW_AT_ranges
        let line_offset = match entry.attr_value(gimli::DW_AT_stmt_list) {
            Some(gimli::AttributeValue::DebugLineRef(offset)) => offset,
            _ => return None,
        };
        Some(Unit {
            address_size: header.address_size(),
            low_pc: low_pc,
            high_pc: high_pc,
            line_offset: line_offset,
        })
    }

    fn contains_address(&self, address: u64) -> bool {
        self.high_pc == 0 || address >= self.low_pc && address <= self.high_pc
    }

    fn lines<'a, Endian>(&self,
                         debug_line: gimli::DebugLine<'a, Endian>)
                         -> gimli::ParseResult<gimli::StateMachine<'a, Endian>>
        where Endian: gimli::Endianity
    {
        let header = try!(gimli::LineNumberProgramHeader::new(debug_line,
                                                              self.line_offset,
                                                              self.address_size));
        Ok(gimli::StateMachine::new(header))
    }
}
<|endoftext|>


<commit_before>use std::io::{stdout, stderr, Write};

use argparse::{ArgumentParser, StoreTrue};

use config::Config;

pub fn print_list(config: &Config, mut args: Vec<String>)
    -> Result<i32, String>
{
    let mut all = false;
    let mut builtin = false;
    let mut hidden = false;
    {
        args.insert(0, String::from("vagga _list"));
        let mut ap = ArgumentParser::new();
        ap.refer(&mut all)
            .add_option(&["-A", "--all"], StoreTrue,
                "Show all commands");
        ap.refer(&mut builtin)
            .add_option(&["--builtin"], StoreTrue,
                "Show built-in commands (starting with underscore)");
        ap.refer(&mut hidden)
            .add_option(&["--hidden"], StoreTrue,
                "Show hidden commands");
        match ap.parse(args, &mut stdout(), &mut stderr()) {
            Ok(()) => {}
            Err(x) => return Ok(x),
        }
    }
    let mut out = stdout();
    for (k, cmd) in config.commands.iter() {
        out.write_all(k.as_bytes()).ok();
        match cmd.description() {
            Some(ref val) => {
                if k.len() > 19 {
                    out.write_all(b"\n                    ").ok();
                } else {
                    for _ in k.len()..19 {
                        out.write_all(b" ").ok();
                    }
                    out.write_all(b" ").ok();
                }
                out.write_all(val.as_bytes()).ok();
            }
            None => {}
        }
        out.write_all(b"\n").ok();
    }

    if all || builtin {
        write!(&mut out, "\
            _build              Build a container\n\
            _run                Run arbitrary command, \
                                optionally building container\n\
            _clean              Clean containers and build artifacts\n\
            _list               List of built-in commands\n\
        ").ok();
    }
    return Ok(0);
}
<commit_msg>Implement a container list (closes #233)<commit_after>use std::io::{stdout, stderr, Write};

use argparse::{ArgumentParser, StoreTrue};

use config::Config;

pub fn print_list(config: &Config, mut args: Vec<String>)
    -> Result<i32, String>
{
    let mut all = false;
    let mut builtin = false;
    let mut hidden = false;
    let mut containers = false;
    {
        args.insert(0, String::from("vagga _list"));
        let mut ap = ArgumentParser::new();
        ap.refer(&mut containers)
            .add_option(&["--containers"], StoreTrue,
                "Show containers instead of commands");
        ap.refer(&mut all)
            .add_option(&["-A", "--all"], StoreTrue,
                "Show all commands");
        ap.refer(&mut builtin)
            .add_option(&["--builtin"], StoreTrue,
                "Show built-in commands (starting with underscore)");
        ap.refer(&mut hidden)
            .add_option(&["--hidden"], StoreTrue,
                "Show hidden commands");
        match ap.parse(args, &mut stdout(), &mut stderr()) {
            Ok(()) => {}
            Err(x) => return Ok(x),
        }
    }
    if containers {
        for (cname, _) in config.containers.iter() {
            println!("{}", cname);
        }
    } else {
        let mut out = stdout();
        for (k, cmd) in config.commands.iter() {
            out.write_all(k.as_bytes()).ok();
            match cmd.description() {
                Some(ref val) => {
                    if k.len() > 19 {
                        out.write_all(b"\n                    ").ok();
                    } else {
                        for _ in k.len()..19 {
                            out.write_all(b" ").ok();
                        }
                        out.write_all(b" ").ok();
                    }
                    out.write_all(val.as_bytes()).ok();
                }
                None => {}
            }
            out.write_all(b"\n").ok();
        }

        if all || builtin {
            // TODO(tailhook) fetch builtins from completion code
            write!(&mut out, "\
                _build              Build a container\n\
                _run                Run arbitrary command, \
                                    optionally building container\n\
                _clean              Clean containers and build artifacts\n\
                _list               List of built-in commands\n\
            ").ok();
        }
    }
    return Ok(0);
}
<|endoftext|>


<commit_before>// Simple API example, ported from http://lua-users.org/wiki/SimpleLuaApiExample

// This is a simple introductory example of how to interface to Lua from Rust.
// The Rust program loads a Lua script file, sets some Lua variables, runs the
// Lua script, and reads back the return value.

#![allow(non_snake_case)]
#![feature(core,exit_status)]

extern crate lua;

use std::env;
use std::io::{self, Write};
use std::path::Path;
use std::iter::range_inclusive;

fn main() {
    let mut L = lua::State::new();
    L.openlibs(); // Load Lua libraries

    // Load the file containing the script we are going to run
    let path = Path::new("simpleapi.lua");
    match L.loadfile(Some(&path)) {
        Ok(_) => (),
        Err(_) => {
            // If something went wrong, error message is at the top of the stack
            let _ = writeln!(&mut io::stderr(),
                             "Couldn't load file: {}", L.describe(-1));
            env::set_exit_status(1);
            return;
        }
    }

    /*
     * Ok, now here we go: We pass data to the lua script on the stack.
     * That is, we first have to prepare Lua's virtual stack the way we
     * want the script to receive it, then ask Lua to run it.
     */
    L.newtable(); // We will pass a table

    /*
     * To put values into the table, we first push the index, then the
     * value, and then call rawset() with the index of the table in the
     * stack. Let's see why it's -3: In Lua, the value -1 always refers to
     * the top of the stack. When you create the table with newtable(),
     * the table gets pushed into the top of the stack. When you push the
     * index and then the cell value, the stack looks like:
     *
     * - [stack bottom] -- table, index, value [top]
     *
     * So the -1 will refer to the cell value, thus -3 is used to refer to
     * the table itself. Note that rawset() pops the last two elements
     * of the stack, so that after it has been called, the table is at the
     * top of the stack.
     */
    for i in range_inclusive(1, 5) {
        L.pushinteger(i);   // Push the table index
        L.pushinteger(i*2); // Push the cell value
        L.rawset(-3);       // Stores the pair in the table
    }

    // By what name is the script going to reference our table?
    L.setglobal("foo");

    // Ask Lua to run our little script
    match L.pcall(0, lua::MULTRET, 0) {
        Ok(()) => (),
        Err(_) => {
            let _ = writeln!(&mut io::stderr(),
                             "Failed to run script: {}", L.describe(-1));
            env::set_exit_status(1);
            return;
        }
    }

    // Get the returned value at the to of the stack (index -1)
    let sum = L.tonumber(-1);

    println!("Script returned: {}", sum);

    L.pop(1); // Take the returned value out of the stack

    // L's destructor will close the state for us
}
<commit_msg>Stop using range_inclusive in examples/simpleapi.rs<commit_after>// Simple API example, ported from http://lua-users.org/wiki/SimpleLuaApiExample

// This is a simple introductory example of how to interface to Lua from Rust.
// The Rust program loads a Lua script file, sets some Lua variables, runs the
// Lua script, and reads back the return value.

#![allow(non_snake_case)]
#![feature(core,exit_status)]

extern crate lua;

use std::env;
use std::io::{self, Write};
use std::path::Path;

fn main() {
    let mut L = lua::State::new();
    L.openlibs(); // Load Lua libraries

    // Load the file containing the script we are going to run
    let path = Path::new("simpleapi.lua");
    match L.loadfile(Some(&path)) {
        Ok(_) => (),
        Err(_) => {
            // If something went wrong, error message is at the top of the stack
            let _ = writeln!(&mut io::stderr(),
                             "Couldn't load file: {}", L.describe(-1));
            env::set_exit_status(1);
            return;
        }
    }

    /*
     * Ok, now here we go: We pass data to the lua script on the stack.
     * That is, we first have to prepare Lua's virtual stack the way we
     * want the script to receive it, then ask Lua to run it.
     */
    L.newtable(); // We will pass a table

    /*
     * To put values into the table, we first push the index, then the
     * value, and then call rawset() with the index of the table in the
     * stack. Let's see why it's -3: In Lua, the value -1 always refers to
     * the top of the stack. When you create the table with newtable(),
     * the table gets pushed into the top of the stack. When you push the
     * index and then the cell value, the stack looks like:
     *
     * - [stack bottom] -- table, index, value [top]
     *
     * So the -1 will refer to the cell value, thus -3 is used to refer to
     * the table itself. Note that rawset() pops the last two elements
     * of the stack, so that after it has been called, the table is at the
     * top of the stack.
     */
    for i in 1..6 {
        L.pushinteger(i);   // Push the table index
        L.pushinteger(i*2); // Push the cell value
        L.rawset(-3);       // Stores the pair in the table
    }

    // By what name is the script going to reference our table?
    L.setglobal("foo");

    // Ask Lua to run our little script
    match L.pcall(0, lua::MULTRET, 0) {
        Ok(()) => (),
        Err(_) => {
            let _ = writeln!(&mut io::stderr(),
                             "Failed to run script: {}", L.describe(-1));
            env::set_exit_status(1);
            return;
        }
    }

    // Get the returned value at the to of the stack (index -1)
    let sum = L.tonumber(-1);

    println!("Script returned: {}", sum);

    L.pop(1); // Take the returned value out of the stack

    // L's destructor will close the state for us
}
<|endoftext|>


<commit_before>extern crate graph_layout;
extern crate graph_generators;
extern crate rand;

use rand::{random, Closed01};
use graph_layout::P2d;
use std::io::Write;

struct SvgCanvas {
    width: f32,
    height: f32,
    border: f32,
    radius: f32,
    scalex: f32,
    scaley: f32,
    offsetx: f32,
    offsety: f32,
}

struct SvgWriter {
    canvas: SvgCanvas,
    wr: Box<Write>,
}

impl SvgWriter {
    fn new(canvas: SvgCanvas, wr: Box<Write>) -> SvgWriter {
        SvgWriter{canvas: canvas, wr: wr}
    }

    fn header(&mut self) {
        writeln!(&mut self.wr, r#"<?xml version="1.0" encoding="UTF-8"?>
                <svg xmlns="http://www.w3.org/2000/svg"
                version="1.1" baseProfile="full"
                width="100%" height="100%"
                viewBox="{} {} {} {}">"#, 0, 0, self.canvas.width+2.0*self.canvas.border, self.canvas.height+2.0*self.canvas.border).unwrap();
    }

    fn footer(&mut self) {
        writeln!(&mut self.wr, "</svg>").unwrap();
    }

    fn node(&mut self, pos: &P2d) {
        let x = self.canvas.border + (pos.0*self.canvas.scalex) + self.canvas.offsetx;
        let y = self.canvas.border + (pos.1*self.canvas.scaley) + self.canvas.offsety;
        writeln!(&mut self.wr, r#"<circle cx="{}" cy="{}" r="{}" stroke="black" stroke-width="1px" fill="red" />"#,
                 x, y, self.canvas.radius).unwrap();
    }

    fn edge(&mut self, pos1: &P2d, pos2: &P2d) {
        let x1 = self.canvas.border + (pos1.0*self.canvas.scalex) + self.canvas.offsetx;
        let y1 = self.canvas.border + (pos1.1*self.canvas.scaley) + self.canvas.offsety;
        let x2 = self.canvas.border + (pos2.0*self.canvas.scalex) + self.canvas.offsetx;
        let y2 = self.canvas.border + (pos2.1*self.canvas.scaley) + self.canvas.offsety;

         writeln!(&mut self.wr, r#"<line x1="{}" y1="{}" x2="{}" y2="{}" stroke="black" stroke-width="1px" />"#,
                  x1, y1, x2, y2).unwrap();
    }
}

fn draw_graph(g: graph_generators::Graph, filename: &str, l: Option<f32>) {
    use std::fs::File;
    let mut node_positions: Vec<P2d> = g.nodes.iter().map(|_| P2d(random::<Closed01<f32>>().0, random::<Closed01<f32>>().0)).collect();
    let mut node_neighbors: Vec<Vec<usize>> = g.nodes.iter().map(|_| Vec::new()).collect();
    for &(src, dst) in g.edges.iter() {
        node_neighbors[src].push(dst);
    }

    graph_layout::typical_fruchterman_reingold_2d(l,
                                            &mut node_positions[..],
                                            &node_neighbors);

    let canvas = SvgCanvas{
        width:1000.0,
        height:1000.0,
        border:40.0,
        radius:10.0,
        scalex: 1000.0,
        scaley: 1000.0,
        offsetx: 0.0,
        offsety: 0.0};
    let mut svg_wr = SvgWriter::new(canvas, Box::new(File::create(filename).unwrap()));

    svg_wr.header();

    for (i, pos1) in node_positions.iter().enumerate() {
        for &n in node_neighbors[i].iter() {
            let pos2 = &node_positions[n];

             svg_wr.edge(&pos1, &pos2);
        }
    }

    for pos1 in node_positions.iter() {
        svg_wr.node(&pos1);
    }

    svg_wr.footer();
}

fn main() {
    let mut rng = rand::thread_rng();
    let g = graph_generators::barabasi_albert_graph(&mut rng, 20, 3);
    draw_graph(g, "barabasi_albert_20_3.svg", None);

    let mut g = graph_generators::Graph::new();
    let n1 = g.add_node();
    let n2 = g.add_node();
    let n3 = g.add_node();
    let n4 = g.add_node();
    g.add_edge((n1, n2));
    g.add_edge((n2, n3));
    g.add_edge((n3, n4));
    draw_graph(g, "line.svg", None);

    let mut g = graph_generators::Graph::new();
    let n1 = g.add_node();
    let n2 = g.add_node();
    let n3 = g.add_node();
    g.add_edge((n1, n2));
    g.add_edge((n2, n3));
    g.add_edge((n3, n1));
    draw_graph(g, "triad.svg", None);

    let mut g = graph_generators::Graph::new();
    let n1 = g.add_node();
    let n2 = g.add_node();
    let n3 = g.add_node();
    let n4 = g.add_node();
    g.add_edge((n1, n2));
    g.add_edge((n2, n3));
    g.add_edge((n3, n4));
    g.add_edge((n4, n1));
    draw_graph(g, "square.svg", None);

    let mut g = graph_generators::Graph::new();
    let n1 = g.add_node();
    let n2 = g.add_node();
    let n3 = g.add_node();
    let n4 = g.add_node();
    g.add_edge((n1, n2));
    g.add_edge((n2, n3));
    g.add_edge((n3, n4));
    g.add_edge((n4, n1));
    g.add_edge((n1, n3));
    g.add_edge((n2, n4));
    draw_graph(g, "connected_square.svg", None);

    let mut g = graph_generators::Graph::new();
    let n = 100;
    for _ in 0..n {
        let _ = g.add_node();
    }
    for i in 0..n {
        g.add_edge((i, (i+1)%n));
    }
    draw_graph(g, "circle_50.svg", Some(0.01));
}
<commit_msg>Add another example graph<commit_after>extern crate graph_layout;
extern crate graph_generators;
extern crate rand;

use rand::{random, Closed01};
use graph_layout::P2d;
use std::io::Write;

struct SvgCanvas {
    width: f32,
    height: f32,
    border: f32,
    radius: f32,
    scalex: f32,
    scaley: f32,
    offsetx: f32,
    offsety: f32,
}

struct SvgWriter {
    canvas: SvgCanvas,
    wr: Box<Write>,
}

impl SvgWriter {
    fn new(canvas: SvgCanvas, wr: Box<Write>) -> SvgWriter {
        SvgWriter{canvas: canvas, wr: wr}
    }

    fn header(&mut self) {
        writeln!(&mut self.wr, r#"<?xml version="1.0" encoding="UTF-8"?>
                <svg xmlns="http://www.w3.org/2000/svg"
                version="1.1" baseProfile="full"
                width="100%" height="100%"
                viewBox="{} {} {} {}">"#, 0, 0, self.canvas.width+2.0*self.canvas.border, self.canvas.height+2.0*self.canvas.border).unwrap();
    }

    fn footer(&mut self) {
        writeln!(&mut self.wr, "</svg>").unwrap();
    }

    fn node(&mut self, pos: &P2d) {
        let x = self.canvas.border + (pos.0*self.canvas.scalex) + self.canvas.offsetx;
        let y = self.canvas.border + (pos.1*self.canvas.scaley) + self.canvas.offsety;
        writeln!(&mut self.wr, r#"<circle cx="{}" cy="{}" r="{}" stroke="black" stroke-width="1px" fill="red" />"#,
                 x, y, self.canvas.radius).unwrap();
    }

    fn edge(&mut self, pos1: &P2d, pos2: &P2d) {
        let x1 = self.canvas.border + (pos1.0*self.canvas.scalex) + self.canvas.offsetx;
        let y1 = self.canvas.border + (pos1.1*self.canvas.scaley) + self.canvas.offsety;
        let x2 = self.canvas.border + (pos2.0*self.canvas.scalex) + self.canvas.offsetx;
        let y2 = self.canvas.border + (pos2.1*self.canvas.scaley) + self.canvas.offsety;

         writeln!(&mut self.wr, r#"<line x1="{}" y1="{}" x2="{}" y2="{}" stroke="black" stroke-width="1px" />"#,
                  x1, y1, x2, y2).unwrap();
    }
}

fn draw_graph(g: graph_generators::Graph, filename: &str, l: Option<f32>) {
    use std::fs::File;
    let mut node_positions: Vec<P2d> = g.nodes.iter().map(|_| P2d(random::<Closed01<f32>>().0, random::<Closed01<f32>>().0)).collect();
    let mut node_neighbors: Vec<Vec<usize>> = g.nodes.iter().map(|_| Vec::new()).collect();
    for &(src, dst) in g.edges.iter() {
        node_neighbors[src].push(dst);
    }

    graph_layout::typical_fruchterman_reingold_2d(l,
                                            &mut node_positions[..],
                                            &node_neighbors);

    let canvas = SvgCanvas{
        width:1000.0,
        height:1000.0,
        border:40.0,
        radius:10.0,
        scalex: 1000.0,
        scaley: 1000.0,
        offsetx: 0.0,
        offsety: 0.0};
    let mut svg_wr = SvgWriter::new(canvas, Box::new(File::create(filename).unwrap()));

    svg_wr.header();

    for (i, pos1) in node_positions.iter().enumerate() {
        for &n in node_neighbors[i].iter() {
            let pos2 = &node_positions[n];

             svg_wr.edge(&pos1, &pos2);
        }
    }

    for pos1 in node_positions.iter() {
        svg_wr.node(&pos1);
    }

    svg_wr.footer();
}

fn main() {
    let mut rng = rand::thread_rng();

    let g = graph_generators::barabasi_albert_graph(&mut rng, 50, 1);
    draw_graph(g, "barabasi_albert_50_1.svg", Some(0.03));

    let g = graph_generators::barabasi_albert_graph(&mut rng, 20, 3);
    draw_graph(g, "barabasi_albert_20_3.svg", None);

    let mut g = graph_generators::Graph::new();
    let n1 = g.add_node();
    let n2 = g.add_node();
    let n3 = g.add_node();
    let n4 = g.add_node();
    g.add_edge((n1, n2));
    g.add_edge((n2, n3));
    g.add_edge((n3, n4));
    draw_graph(g, "line.svg", None);

    let mut g = graph_generators::Graph::new();
    let n1 = g.add_node();
    let n2 = g.add_node();
    let n3 = g.add_node();
    g.add_edge((n1, n2));
    g.add_edge((n2, n3));
    g.add_edge((n3, n1));
    draw_graph(g, "triad.svg", None);

    let mut g = graph_generators::Graph::new();
    let n1 = g.add_node();
    let n2 = g.add_node();
    let n3 = g.add_node();
    let n4 = g.add_node();
    g.add_edge((n1, n2));
    g.add_edge((n2, n3));
    g.add_edge((n3, n4));
    g.add_edge((n4, n1));
    draw_graph(g, "square.svg", None);

    let mut g = graph_generators::Graph::new();
    let n1 = g.add_node();
    let n2 = g.add_node();
    let n3 = g.add_node();
    let n4 = g.add_node();
    g.add_edge((n1, n2));
    g.add_edge((n2, n3));
    g.add_edge((n3, n4));
    g.add_edge((n4, n1));
    g.add_edge((n1, n3));
    g.add_edge((n2, n4));
    draw_graph(g, "connected_square.svg", None);

    let mut g = graph_generators::Graph::new();
    let n = 100;
    for _ in 0..n {
        let _ = g.add_node();
    }
    for i in 0..n {
        g.add_edge((i, (i+1)%n));
    }
    draw_graph(g, "circle_50.svg", Some(0.01));
}
<|endoftext|>


<commit_before>use cocoa::appkit::{NSPasteboard, NSPasteboardTypeString};
use cocoa::base::{id, nil};
use cocoa::foundation::{NSArray, NSData, NSString, NSUInteger};
use std::borrow::Cow;
use std::ffi::CStr;
use {Clipboard, Item, Result};

pub trait ClipboardExt: Clipboard {
    fn clipboard_with_name(&self, name: &str) -> Self;

    fn get_clipboard_text_as_nsstring(&self) -> id;
    fn get_raw_clipboard(&self) -> id;
}

#[derive(Debug)]
pub struct CocoaClipboard(id);

impl Clipboard for CocoaClipboard {
    fn get() -> Result<Self> where Self: Sized {
        let pboard = unsafe { NSPasteboard::generalPasteboard(nil) };
        if pboard.is_null() {
            Err(From::from("could not get pasteboard"))
        } else {
            Ok(CocoaClipboard(pboard))
        }
    }

    fn copy(&mut self, item: &Item) -> Result<()> {
        self.copy_items(&[*item])
    }

    fn copy_items(&mut self, items: &[Item]) -> Result<()> {
        let items = items.iter().map(|i| i.native_representation()).collect::<Cow<[_]>>();
        let array = unsafe { NSArray::arrayWithObjects(nil, &items) };
        unsafe {
            self.0.clearContents();
            self.0.writeObjects(array);
        }
        Ok(())
    }

    fn get_paste_text(&self)  -> Result<&str> {
        unsafe {
            let text = NSPasteboard::stringForType(self.0, NSPasteboardTypeString);
            Ok(CStr::from_ptr(text.UTF8String()).to_str().unwrap_or(""))
        }
    }

    fn get_items(&self) -> &[Item] {
        unimplemented!();
    }
}

impl ClipboardExt for CocoaClipboard {
    fn clipboard_with_name(&self, name: &str) -> Self {
        unimplemented!();
    }

    fn get_clipboard_text_as_nsstring(&self) -> id {
        unimplemented!();
    }

    fn get_raw_clipboard(&self) -> id {
        unimplemented!();
    }
}

impl<'a> Item<'a> {
    fn native_representation(&self) -> id {
        match *self {
            Item::Text(text) => unsafe { NSString::alloc(nil).init_str(text) },
            Item::Image(image) => unsafe {
                let slice = image.bytes();
                let _data = NSData::dataWithBytes_length_(nil,
                                                          slice.as_ptr() as *const _,
                                                          slice.len() as NSUInteger);
                unimplemented!();
            },
            Item::Sound(sound) => {
                unimplemented!();
            }
            _ => nil
        }
    }
}
<commit_msg>Begin implementing more methods<commit_after>use cocoa::appkit::{NSPasteboard, NSPasteboardTypeString};
use cocoa::base::{id, nil};
use cocoa::foundation::{NSArray, NSData, NSString, NSUInteger};
use std::borrow::Cow;
use std::ffi::CStr;
use {Clipboard, Item, Result};

pub trait ClipboardExt: Clipboard {
    fn clipboard_with_name(&self, name: &str) -> Self;
    fn get_items_nsarray(&self) -> id;
    fn get_raw_clipboard(&self) -> id;
}

#[derive(Debug)]
pub struct CocoaClipboard(id);

impl Clipboard for CocoaClipboard {
    fn get() -> Result<Self> where Self: Sized {
        let pboard = unsafe { NSPasteboard::generalPasteboard(nil) };
        if pboard.is_null() {
            Err(From::from("could not get pasteboard"))
        } else {
            Ok(CocoaClipboard(pboard))
        }
    }

    fn copy(&mut self, item: &Item) -> Result<()> {
        self.copy_items(&[*item])
    }

    fn copy_items(&mut self, items: &[Item]) -> Result<()> {
        let items = items.iter().map(|i| i.native_representation()).collect::<Cow<[_]>>();
        let array = unsafe { NSArray::arrayWithObjects(nil, &items) };
        unsafe {
            self.0.clearContents();
            self.0.writeObjects(array);
        }
        Ok(())
    }

    fn get_paste_text(&self)  -> Result<&str> {
        unsafe {
            let text = NSPasteboard::stringForType(self.0, NSPasteboardTypeString);
            Ok(CStr::from_ptr(text.UTF8String()).to_str().unwrap_or(""))
        }
    }

    fn get_items(&self) -> &[Item] {
        unsafe {
            let items = self.0.pasteboardItems();
            unimplemented!();
        }
    }
}

impl ClipboardExt for CocoaClipboard {
    fn clipboard_with_name(&self, name: &str) -> Self {
        unimplemented!();
    }

    fn get_items_nsarray(&self) -> id {
        unimplemented!();
    }

    fn get_raw_clipboard(&self) -> id {
        unimplemented!();
    }
}

impl<'a> Item<'a> {
    fn native_representation(&self) -> id {
        match *self {
            Item::Text(text) => unsafe { NSString::alloc(nil).init_str(text) },
            Item::Image(image) => unsafe {
                let slice = image.bytes();
                let _data = NSData::dataWithBytes_length_(nil,
                                                          slice.as_ptr() as *const _,
                                                          slice.len() as NSUInteger);
                unimplemented!();
            },
            Item::Sound(sound) => {
                unimplemented!();
            }
            _ => nil
        }
    }
}
<|endoftext|>


<commit_before>use std::collections::HashMap;

#[derive(Clone)]
pub enum Lang {
    en_US,
    de_DE,
    es_ES,
    es_MX,
    fr_FR,
    it_IT,
    ja_JP,
    pl_PL,
    pt_BR,
    ru_RU,
}

impl Lang {
    pub fn as_str(&self) -> &str {
        match self {
            &Lang::en_US => "en-US",
            &Lang::de_DE => "de-DE",
            &Lang::es_ES => "es-ES",
            &Lang::es_MX => "es-MX",
            &Lang::fr_FR => "fr-FR",
            &Lang::it_IT => "it-IT",
            &Lang::ja_JP => "ja-JP",
            &Lang::pl_PL => "pl-PL",
            &Lang::pt_BR => "pt-BR",
            &Lang::ru_RU => "ru-RU",
        }
    }
}

pub struct CardPageRequest {
    pub lang: Lang,
    pub limit: u64,
    pub name: Option<String>,
    pub offset: u64,
    pub if_modified_since: Option<String>,
}

impl CardPageRequest {
    pub fn default() -> CardPageRequest {
        CardPageRequest {
            lang: Lang::en_US,
            limit: 20,
            name: None,
            offset: 0,
            if_modified_since: None
        }
    }

    pub fn card_search_query(name: &str, lang: Option<Lang>) -> CardPageRequest {
        CardPageRequest {
            lang: lang.unwrap_or(Lang::en_US),
            limit: 1,
            name: Some(String::from(name)),
            offset: 0,
            if_modified_since: None
        }
    }

    pub fn to_hash(&self) -> HashMap<String, String> {
        let mut hash = HashMap::new();
        hash.insert(String::from("lang"), String::from(self.lang.as_str()));
        hash.insert(String::from("limit"), self.limit.to_string());
        if self.name.is_some() {
            let name = self.name.clone().unwrap();
            if name.len() >= 3 {
                hash.insert(String::from("name"), name);
            }
        }
        hash.insert(String::from("offset"), self.offset.to_string());
        hash
    }

    pub fn query(&self) -> String {
        let mut query = String::from("https://api.gwentapi.com/v0/cards");
        query.push_str("?");
        let args = self.to_hash();
        for (key, val) in &args {
            query.push_str(key);
            query.push_str("=");
            query.push_str(val);
            query.push_str("&");
        }
        query
    }
}

pub struct CardRequest {
    card_id: String,
    lang: Option<Lang>,
}

impl CardRequest {
    pub fn default(card_id: &str) -> CardRequest {
        CardRequest {
            card_id: String::from(card_id),
            lang: Some(Lang::en_US),
        }
    }

    pub fn query(&self) -> String {
        let mut query = String::from("https://api.gwentapi.com/v0/cards/");
        query.push_str("?card_id=");
        query.push_str(self.card_id.as_str());
        // FIXME lang attribute is not appended properly
        // query.push_str(self.lang.clone().unwrap_or(Lang::en_US).as_str());
        query
    }
}
<commit_msg>Gets rid of the camelcase warning.<commit_after>use std::collections::HashMap;

#[derive(Clone)]
pub enum Lang {
    US,
    DE,
    ES,
    MX,
    FR,
    IT,
    JP,
    PL,
    BR,
    RU,
}

impl Lang {
    pub fn as_str(&self) -> &str {
        match self {
            &Lang::US => "en-US",
            &Lang::DE => "de-DE",
            &Lang::ES => "es-ES",
            &Lang::MX => "es-MX",
            &Lang::FR => "fr-FR",
            &Lang::IT => "it-IT",
            &Lang::JP => "ja-JP",
            &Lang::PL => "pl-PL",
            &Lang::BR => "pt-BR",
            &Lang::RU => "ru-RU",
        }
    }
}

pub struct CardPageRequest {
    pub lang: Lang,
    pub limit: u64,
    pub name: Option<String>,
    pub offset: u64,
    pub if_modified_since: Option<String>,
}

impl CardPageRequest {
    pub fn default() -> CardPageRequest {
        CardPageRequest {
            lang: Lang::US,
            limit: 20,
            name: None,
            offset: 0,
            if_modified_since: None
        }
    }

    pub fn card_search_query(name: &str, lang: Option<Lang>) -> CardPageRequest {
        CardPageRequest {
            lang: lang.unwrap_or(Lang::US),
            limit: 1,
            name: Some(String::from(name)),
            offset: 0,
            if_modified_since: None
        }
    }

    pub fn to_hash(&self) -> HashMap<String, String> {
        let mut hash = HashMap::new();
        hash.insert(String::from("lang"), String::from(self.lang.as_str()));
        hash.insert(String::from("limit"), self.limit.to_string());
        if self.name.is_some() {
            let name = self.name.clone().unwrap();
            if name.len() >= 3 {
                hash.insert(String::from("name"), name);
            }
        }
        hash.insert(String::from("offset"), self.offset.to_string());
        hash
    }

    pub fn query(&self) -> String {
        let mut query = String::from("https://api.gwentapi.com/v0/cards");
        query.push_str("?");
        let args = self.to_hash();
        for (key, val) in &args {
            query.push_str(key);
            query.push_str("=");
            query.push_str(val);
            query.push_str("&");
        }
        query
    }
}

pub struct CardRequest {
    card_id: String,
    lang: Option<Lang>,
}

impl CardRequest {
    pub fn default(card_id: &str) -> CardRequest {
        CardRequest {
            card_id: String::from(card_id),
            lang: Some(Lang::US),
        }
    }

    pub fn query(&self) -> String {
        let mut query = String::from("https://api.gwentapi.com/v0/cards/");
        query.push_str("?card_id=");
        query.push_str(self.card_id.as_str());
        // FIXME lang attribute is not appended properly
        // query.push_str(self.lang.clone().unwrap_or(Lang::en_US).as_str());
        query
    }
}
<|endoftext|>


<commit_before>//
//  SOS: the Stupid Operating System
//  by Hawk Weisman (hi@hawkweisman.me)
//
//  Copyright (c) 2015 Hawk Weisman
//  Released under the terms of the MIT license. See `LICENSE` in the root
//  directory of this repository for more information.
//
const END_TAG_LEN: u32 = 8;

use core::mem::transmute;

#[macro_use]
macro_rules! ptr {
    ($it:expr) => { &$it as *const _ }
}

pub mod elf;
pub mod elf64;

#[repr(C)]
pub struct Info { pub length: u32
                , _pad: u32
                , tag_start: Tag
                }

impl Info {

    pub unsafe fn from(addr: usize) -> &'static Self {
        let info = &*(addr as *const Info);
        assert!(info.has_end());
        info
    }

    /// Finds the tag with the given tag type.
    ///
    /// This is actually safe since the tag types are constrained by The
    /// `TagType` enum
    pub fn get_tag(&self, tag_type: TagType) -> Option<&'static Tag> {
        self.tags()
            .find(|t| t.ty == tag_type)
    }

    #[inline]
    pub fn mem_map(&self) -> Option<&'static MemMapTag> {
        self.get_tag(TagType::MemoryMap)
            .map(|tag| unsafe { &*(ptr!(tag) as *const MemMapTag) })
    }

    #[inline]
    pub fn elf64_sections(&self) -> Option<&'static elf64::SectionsTag> {
        self.get_tag(TagType::ELFSections)
            .map(|tag| unsafe { &*(ptr!(tag) as *const elf64::SectionsTag) })
    }

    #[inline]
    fn tags(&self) -> Tags { Tags(ptr!(self.tag_start)) }

    fn has_end(&self) -> bool {
        let end_tag_addr
            = (self as *const _) as usize +
              (self.length - END_TAG_LEN) as usize;
        let end_tag = unsafe {&*(end_tag_addr as *const Tag)};
        end_tag.ty == TagType::End && end_tag.length == 8
    }
}

/// A Multiboot tag.
///
/// From the specification:
///
/// Boot information consists of a fixed part and a series of tags.
/// Its start is 8-bytes aligned. Fixed part is as following:
///
///<rawtext>
///
///             +-------------------+
///     u32     | total_size        |
///     u32     | reserved          |
///             +-------------------+
///</rawtext>
///
/// `total_size` contains the total size of boot information including this
/// field and terminating tag in bytes.
/// `reserved` is always set to zero and must be ignored by OS image.
///
///  Every tag begins with following fields:
///<rawtext>
///
///             +-------------------+
///     u32     | type              |
///     u32     | size              |
///             +-------------------+
///</rawtext>
/// `type` contains an identifier of contents of the rest of the tag. `size`
/// contains the size of tag including header fields but not including padding.
/// Tags follow one another padded when necessary in order for each tag to
/// start at 8-bytes aligned address. Tags are terminated by a tag of type `0`
/// and size `8`.
#[repr(C, packed)]
#[derive(Debug)]
pub struct Tag { ty: TagType
               , length: u32
               }

/// Types of Multiboot tags
///
/// Refer to Chapter 3 of the Multiboot 2 spec
#[repr(u32)]
#[derive(Debug, Eq, PartialEq)]
pub enum TagType { /// Tag that indicates the end of multiboot tags
                   End              = 0
                 , /// Command line passed to the bootloader
                   CommandLine      = 1
                 , BootloaderName   = 2
                 , Modules          = 3
                 , BasicMemInfo     = 4
                 , BIOSBootDev      = 5
                 , MemoryMap        = 6
                 , VBEInfo          = 7
                 , FramebufferInfo  = 8
                 , ELFSections      = 9
                 , APMTable         = 10
                 }

struct Tags(*const Tag);

impl Tags {
    #[inline] fn advance(&mut self, size: u32) {
        let next_addr = self.0 as usize + size as usize;
        self.0 = (((next_addr-1) & !0x7) + 0x8) as *const _;
    }
}

impl Iterator for Tags {
    type Item = &'static Tag;

    fn next(&mut self) -> Option<Self::Item> {
        match unsafe { &*self.0 } {
            &Tag{ ty: TagType::End, length: END_TAG_LEN } => None
          , tag => { self.advance(tag.length); Some(tag) }
        }
    }
}

#[repr(C,packed)]
pub struct MemMapTag { tag: Tag
                     , entry_size: u32
                     , entry_version: u32
                     , first_entry: MemArea
                     }
impl MemMapTag {
    pub fn entries(&self) -> Entries {
        Entries { curr: (&self.first_entry) as *const MemArea
                , last: ((self as *const MemMapTag as u32) +
                        (self.tag.length - self.entry_size))
                        as *const MemArea
                , size: self.entry_size
                }
    }
}

#[repr(u32)]
#[derive(Debug, Eq, PartialEq, Ord, PartialOrd)]
pub enum MemAreaType { Available = 1
                     , ACPI      = 3
                     , Preserve  = 4
                     }

#[repr(C)]
pub struct MemArea { pub base: u64
                   , pub length: u64
                   , ty: MemAreaType
                   , _pad: u32
                   }

pub struct Entries { curr: *const MemArea
                   , last: *const MemArea
                   , size: u32
                   }

impl Iterator for Entries {
    type Item = &'static MemArea;
    fn next(&mut self) -> Option<&'static MemArea> {
        if self.curr > self.last {
            None
        } else {
            let current = unsafe { &*self.curr };
            self.curr = (self.curr as u32 + self.size) as *const MemArea;
            if current.ty == MemAreaType::Available {
                Some(current)
            } else {
                self.next()
            }
        }
    }
}
<commit_msg>Remove `repr(packed)` attrs<commit_after>//
//  SOS: the Stupid Operating System
//  by Hawk Weisman (hi@hawkweisman.me)
//
//  Copyright (c) 2015 Hawk Weisman
//  Released under the terms of the MIT license. See `LICENSE` in the root
//  directory of this repository for more information.
//
const END_TAG_LEN: u32 = 8;

use core::mem::transmute;

#[macro_use]
macro_rules! ptr {
    ($it:expr) => { &$it as *const _ }
}

pub mod elf;
pub mod elf64;

#[repr(C)]
pub struct Info { pub length: u32
                , _pad: u32
                , tag_start: Tag
                }

impl Info {

    pub unsafe fn from(addr: usize) -> &'static Self {
        let info = &*(addr as *const Info);
        assert!(info.has_end());
        info
    }

    /// Finds the tag with the given tag type.
    ///
    /// This is actually safe since the tag types are constrained by The
    /// `TagType` enum
    pub fn get_tag(&self, tag_type: TagType) -> Option<&'static Tag> {
        self.tags()
            .find(|t| t.ty == tag_type)
    }

    #[inline]
    pub fn mem_map(&self) -> Option<&'static MemMapTag> {
        self.get_tag(TagType::MemoryMap)
            .map(|tag| unsafe { &*(ptr!(tag) as *const MemMapTag) })
    }

    #[inline]
    pub fn elf64_sections(&self) -> Option<&'static elf64::SectionsTag> {
        self.get_tag(TagType::ELFSections)
            .map(|tag| unsafe { &*(ptr!(tag) as *const elf64::SectionsTag) })
    }

    #[inline]
    fn tags(&self) -> Tags { Tags(ptr!(self.tag_start)) }

    fn has_end(&self) -> bool {
        let end_tag_addr
            = (self as *const _) as usize +
              (self.length - END_TAG_LEN) as usize;
        let end_tag = unsafe {&*(end_tag_addr as *const Tag)};
        end_tag.ty == TagType::End && end_tag.length == 8
    }
}

/// A Multiboot tag.
///
/// From the specification:
///
/// Boot information consists of a fixed part and a series of tags.
/// Its start is 8-bytes aligned. Fixed part is as following:
///
///<rawtext>
///
///             +-------------------+
///     u32     | total_size        |
///     u32     | reserved          |
///             +-------------------+
///</rawtext>
///
/// `total_size` contains the total size of boot information including this
/// field and terminating tag in bytes.
/// `reserved` is always set to zero and must be ignored by OS image.
///
///  Every tag begins with following fields:
///<rawtext>
///
///             +-------------------+
///     u32     | type              |
///     u32     | size              |
///             +-------------------+
///</rawtext>
/// `type` contains an identifier of contents of the rest of the tag. `size`
/// contains the size of tag including header fields but not including padding.
/// Tags follow one another padded when necessary in order for each tag to
/// start at 8-bytes aligned address. Tags are terminated by a tag of type `0`
/// and size `8`.
#[repr(C)]
#[derive(Debug)]
pub struct Tag { ty: TagType
               , length: u32
               }

/// Types of Multiboot tags
///
/// Refer to Chapter 3 of the Multiboot 2 spec
#[repr(u32)]
#[derive(Debug, Eq, PartialEq)]
pub enum TagType { /// Tag that indicates the end of multiboot tags
                   End              = 0
                 , /// Command line passed to the bootloader
                   CommandLine      = 1
                 , BootloaderName   = 2
                 , Modules          = 3
                 , BasicMemInfo     = 4
                 , BIOSBootDev      = 5
                 , MemoryMap        = 6
                 , VBEInfo          = 7
                 , FramebufferInfo  = 8
                 , ELFSections      = 9
                 , APMTable         = 10
                 }

struct Tags(*const Tag);

impl Tags {
    #[inline] fn advance(&mut self, size: u32) {
        let next_addr = self.0 as usize + size as usize;
        self.0 = (((next_addr-1) & !0x7) + 0x8) as *const _;
    }
}

impl Iterator for Tags {
    type Item = &'static Tag;

    fn next(&mut self) -> Option<Self::Item> {
        match unsafe { &*self.0 } {
            &Tag{ ty: TagType::End, length: END_TAG_LEN } => None
          , tag => { self.advance(tag.length); Some(tag) }
        }
    }
}

#[repr(C)]
pub struct MemMapTag { tag: Tag
                     , entry_size: u32
                     , entry_version: u32
                     , first_entry: MemArea
                     }
impl MemMapTag {
    pub fn entries(&self) -> Entries {
        Entries { curr: (&self.first_entry) as *const MemArea
                , last: ((self as *const MemMapTag as u32) +
                        (self.tag.length - self.entry_size))
                        as *const MemArea
                , size: self.entry_size
                }
    }
}

#[repr(u32)]
#[derive(Debug, Eq, PartialEq, Ord, PartialOrd)]
pub enum MemAreaType { Available = 1
                     , ACPI      = 3
                     , Preserve  = 4
                     }

#[repr(C)]
pub struct MemArea { pub base: u64
                   , pub length: u64
                   , ty: MemAreaType
                   , _pad: u32
                   }

pub struct Entries { curr: *const MemArea
                   , last: *const MemArea
                   , size: u32
                   }

impl Iterator for Entries {
    type Item = &'static MemArea;
    fn next(&mut self) -> Option<&'static MemArea> {
        if self.curr > self.last {
            None
        } else {
            let current = unsafe { &*self.curr };
            self.curr = (self.curr as u32 + self.size) as *const MemArea;
            if current.ty == MemAreaType::Available {
                Some(current)
            } else {
                self.next()
            }
        }
    }
}
<|endoftext|>


<commit_before>//use torchrs::nn::functional::{max_pool2d, relu, conv2d, dropout, dropout2d, linear, log_softmax};

use autograd::variable::Variable;
use autograd::{Conv2dFArgs, ConvNdArgs, ConvNd, FuncIntf, FuncIntfX, MaxPool2d, Dropout1d,
               Dropout2d, Threshold, LogSoftmax, NLLLoss};

pub use autograd::{MaxPool2dArgs, DropoutArgs, NLLLossArgs};

pub fn max_pool2d<T>(input: &Variable<T>,
                     kernel_size: (u32, u32),
                     args: &MaxPool2dArgs)
                     -> Variable<T> {
    let mut pool_args = args.v.clone();
    pool_args.kernel_size = vec![kernel_size.0, kernel_size.1];
    MaxPool2d::new(&pool_args).f(&mut vec![input.clone()])[0].clone()
}

pub fn dropout<T>(input: &Variable<T>, args: &DropoutArgs) -> Variable<T> {
    if args.training == false {
        return input.clone();
    }
    Dropout1d::new(args).f(&mut vec![input.clone()])[0].clone()
}

pub fn dropout_<T>(input: &mut Variable<T>, args: &DropoutArgs) -> Variable<T> {
    if args.training == false {
        return input.clone();
    }
    Dropout1d::new(args).f(&mut vec![input.clone()])[0].clone()
}

pub fn dropout2d<T>(input: &Variable<T>, args: &DropoutArgs) -> Variable<T> {
    if args.training == false {
        return input.clone();
    }
    Dropout2d::new(args).f(&mut vec![input.clone()])[0].clone()
}

pub fn dropout2d_<T>(input: &mut Variable<T>, args: &DropoutArgs) -> Variable<T> {
    if args.training == false {
        return input.clone();
    }
    Dropout2d::new(args).f(&mut vec![input.clone()])[0].clone()
}

pub fn conv2d<T: Default>(input: &mut Variable<T>,
                          weight: &mut Variable<T>,
                          args: &mut Conv2dFArgs<T>)
                          -> Variable<T> {
    let mut v = match args.bias {
        Some(ref mut bias) => vec![input.clone(), weight.clone(), bias.clone()],
        None => vec![input.clone(), weight.clone()],
    };
    ConvNd::new(&ConvNdArgs::from(args)).f(&mut v)[0].clone()
}

pub fn relu<T>(input: &Variable<T>) -> Variable<T> {
    Threshold::new(0., 0., false).f(&mut vec![input.clone()])[0].clone()
}

pub fn relu_<T>(input: &mut Variable<T>) -> Variable<T> {
    Threshold::new(0., 0., true).f(&mut vec![input.clone()])[0].clone()
}

pub fn log_softmax<T>(input: &Variable<T>) -> Variable<T> {
    LogSoftmax::new().f(&mut vec![input.clone()])[0].clone()
}

pub fn nll_loss<T: Default + Copy>(input: &Variable<T>,
                                   target: &Variable<i64>,
                                   args: &NLLLossArgs<T>)
                                   -> Variable<T> {
    NLLLoss::new(args).fx(&vec![input.clone()], &vec![target.clone()])[0].clone()
}
<commit_msg>implement functional linear<commit_after>//use torchrs::nn::functional::{max_pool2d, relu, conv2d, dropout, dropout2d, linear, log_softmax};

use autograd::variable::Variable;
use autograd::{Conv2dFArgs, ConvNdArgs, ConvNd, FuncIntf, FuncIntfX, MaxPool2d, Dropout1d,
               Dropout2d, Threshold, LogSoftmax, NLLLoss, LinearF};

pub use autograd::{MaxPool2dArgs, DropoutArgs, NLLLossArgs};

pub fn max_pool2d<T>(input: &Variable<T>,
                     kernel_size: (u32, u32),
                     args: &MaxPool2dArgs)
                     -> Variable<T> {
    let mut pool_args = args.v.clone();
    pool_args.kernel_size = vec![kernel_size.0, kernel_size.1];
    MaxPool2d::new(&pool_args).f(&mut vec![input.clone()])[0].clone()
}

pub fn dropout<T>(input: &Variable<T>, args: &DropoutArgs) -> Variable<T> {
    if args.training == false {
        return input.clone();
    }
    Dropout1d::new(args).f(&mut vec![input.clone()])[0].clone()
}

pub fn dropout_<T>(input: &mut Variable<T>, args: &DropoutArgs) -> Variable<T> {
    if args.training == false {
        return input.clone();
    }
    Dropout1d::new(args).f(&mut vec![input.clone()])[0].clone()
}

pub fn dropout2d<T>(input: &Variable<T>, args: &DropoutArgs) -> Variable<T> {
    if args.training == false {
        return input.clone();
    }
    Dropout2d::new(args).f(&mut vec![input.clone()])[0].clone()
}

pub fn dropout2d_<T>(input: &mut Variable<T>, args: &DropoutArgs) -> Variable<T> {
    if args.training == false {
        return input.clone();
    }
    Dropout2d::new(args).f(&mut vec![input.clone()])[0].clone()
}

pub fn conv2d<T: Default>(input: &mut Variable<T>,
                          weight: &mut Variable<T>,
                          args: &mut Conv2dFArgs<T>)
                          -> Variable<T> {
    let mut v = match args.bias {
        Some(ref mut bias) => vec![input.clone(), weight.clone(), bias.clone()],
        None => vec![input.clone(), weight.clone()],
    };
    ConvNd::new(&ConvNdArgs::from(args)).f(&mut v)[0].clone()
}

pub fn linear<T>(input: &Variable<T>, weight: &mut Variable<T>, bias_: Option<&mut Variable<T>>) -> Variable<T>{
    let mut v = if let Some(bias) = bias_ {
        vec![input.clone(), weight.clone(), bias.clone()]
    } else {
        vec![input.clone(), weight.clone()]
    };
    LinearF::new().f(&mut v)[0].clone()
}

pub fn relu<T>(input: &Variable<T>) -> Variable<T> {
    Threshold::new(0., 0., false).f(&mut vec![input.clone()])[0].clone()
}

pub fn relu_<T>(input: &mut Variable<T>) -> Variable<T> {
    Threshold::new(0., 0., true).f(&mut vec![input.clone()])[0].clone()
}

pub fn log_softmax<T>(input: &Variable<T>) -> Variable<T> {
    LogSoftmax::new().f(&mut vec![input.clone()])[0].clone()
}

pub fn nll_loss<T: Default + Copy>(input: &Variable<T>,
                                   target: &Variable<i64>,
                                   args: &NLLLossArgs<T>)
                                   -> Variable<T> {
    NLLLoss::new(args).fx(&vec![input.clone()], &vec![target.clone()])[0].clone()
}
<|endoftext|>


<commit_before>
extern mod sax;

use self::sax::*;

pub struct Registry {
    enum_nss: ~[EnumNs],
    cmd_nss: ~[CmdNs],
}

impl Registry {
    pub fn from_xml(data: &str) -> Registry {
        RegistryBuilder::parse(data)
    }
}

pub struct EnumNs {
    namespace: ~str,
    enums: ~[Enum],
    group: Option<~str>,
    ty: Option<~str>,
    start: Option<~str>,
    end: Option<~str>,
    vendor: Option<~str>,
    comment: Option<~str>,
}

pub struct Enum {
    ident: ~str,
    value: ~str,
}

pub struct ReturnType(Option<~str>);

pub struct CmdNs {
    namespace: ~str,
    cmds: ~[Cmd],
}

pub struct Cmd {
    ident: ~str,
    ty: ReturnType,
    params: ~[Param]
}

pub struct Param {
    ptype: ~str,
    ident: ~str,
}

struct RegistryBuilder {
    priv port: SaxPort,
}

impl<'self> RegistryBuilder {
    fn recv(&self) -> ParseEvent {
        match self.port.recv() {
            Ok(msg) => msg,
            Err(err) => fail!("XML error: %s", err.to_str())
        }
    }

    fn parse(data: &str) -> Registry {
        let builder = RegistryBuilder {
            port: parse_xml(data)
        };
        match builder.recv() {
            StartDocument => (),
            msg => fail!("Expected start of document, found: %?", msg.to_str()),
        }
        match builder.recv() {
            StartElement(~"registry", _) => builder.consume_registry(),
            msg => fail!("Expected <registry>, found: %?", msg.to_str()),
        }
    }

    fn skip_until(&self, event: ParseEvent) {
        loop {
            let msg = self.recv();
            if msg == event || msg == EndDocument { break }
        }
    }

    fn consume_registry(&self) -> Registry {
        let mut registry = Registry { enum_nss: ~[], cmd_nss: ~[] };
        loop {
            match self.recv() {
                // ignores
                Characters(_) | Comment(_) | IgnorableWhitespace(_) => (),
                StartElement(~"comment", _) => self.skip_until(EndElement(~"comment")),
                StartElement(~"types", _) => self.skip_until(EndElement(~"types")),
                StartElement(~"groups", _) => self.skip_until(EndElement(~"groups")),
                StartElement(~"feature", _) => self.skip_until(EndElement(~"feature")),
                StartElement(~"extensions", _) => self.skip_until(EndElement(~"extensions")),

                // add enum namespace
                StartElement(~"enums", ref atts) => {
                    registry.enum_nss.push(
                        EnumNs {
                            namespace:  atts.get_copy(&~"namespace"),
                            enums:      self.consume_enums(),
                            group:      atts.find_copy(&~"group"),
                            ty:         atts.find_copy(&~"type"),
                            start:      atts.find_copy(&~"start"),
                            end:        atts.find_copy(&~"end"),
                            vendor:     atts.find_copy(&~"vendor"),
                            comment:    atts.find_copy(&~"comment"),
                        }
                    )
                }
                // add command namespace
                StartElement(~"commands", _) => self.skip_until(EndElement(~"commands")),

                // finished building the registry
                EndElement(~"registry") => break,

                // error handling
                msg => fail!("Expected </registry>, found: %?", msg.to_str()),
            }
        }
        registry
    }

    fn consume_enums(&self) -> ~[Enum] {
        let mut enums = ~[];
        loop {
            match self.recv() {
                // ignores
                Characters(_) | Comment(_) | IgnorableWhitespace(_) => (),
                StartElement(~"unused", _) => self.skip_until(EndElement(~"unused")),
                // add enum definition
                StartElement(~"enum", ref atts) => {
                    enums.push(
                        Enum {
                            ident:  atts.get_copy(&~"name"),
                            value:  atts.get_copy(&~"value"),
                        }
                    );
                    match self.recv() {
                        EndElement(~"enum") => (),
                        msg => fail!("Expected </enum>, found: %?", msg.to_str()),
                    }
                }
                // finished building the namespace
                EndElement(~"enums") => break,
                // error handling
                msg => fail!("Expected </enums>, found: %?", msg.to_str()),
            }
        }
        enums
    }

    // TODO: Consume command namespaces
}<commit_msg>Parse command prototypes<commit_after>
extern mod sax;

use self::sax::*;

pub struct Registry {
    enum_nss: ~[EnumNs],
    cmd_nss: ~[CmdNs],
}

impl Registry {
    pub fn from_xml(data: &str) -> Registry {
        RegistryBuilder::parse(data)
    }
}

pub struct EnumNs {
    namespace: ~str,
    group: Option<~str>,
    ty: Option<~str>,
    start: Option<~str>,
    end: Option<~str>,
    vendor: Option<~str>,
    comment: Option<~str>,
    enums: ~[Enum],
}

pub struct Enum {
    ident: ~str,
    value: ~str,
}

pub struct CmdNs {
    namespace: ~str,
    cmds: ~[Cmd],
}

pub struct Binding {
    ident: ~str,
    ty: ~str,
}

pub struct Cmd {
    proto: Binding,
    params: ~[Binding],
}

struct RegistryBuilder {
    priv port: SaxPort,
}

impl<'self> RegistryBuilder {
    fn recv(&self) -> ParseEvent {
        loop {
            match self.port.recv() {
                Ok(StartDocument) => (),
                Ok(Comment(_)) => (),
                Ok(Characters(ref ch)) if ch.is_whitespace() => (),
                Ok(EndDocument) => fail!("The end of the document has been reached"),
                Ok(event) => return event,
                Err(err) => fail!("XML error: %s", err.to_str()),
            }
        }
    }

    fn parse(data: &str) -> Registry {
        RegistryBuilder {
            port: parse_xml(data)
        }.consume_registry()
    }

    fn expect_characters(&self) -> ~str {
        match self.recv() {
            Characters(ref ch) => ch.clone(),
            msg => fail!("Expected characters, found: %?", msg.to_str()),
        }
    }

    fn expect_start_element(&self, name: &str) -> Attributes {
        match self.recv() {
            StartElement(ref n, ref atts) if name == *n => atts.clone(),
            msg => fail!("Expected <%s>, found: %?", name, msg.to_str()),
        }
    }

    fn expect_end_element(&self, name: &str) {
        match self.recv() {
            EndElement(ref n) if name == *n => (),
            msg => fail!("Expected </%s>, found: %?", name, msg.to_str()),
        }
    }

    fn skip_until(&self, event: ParseEvent) {
        loop {
            let msg = self.recv();
            if msg == event || msg == EndDocument { break }
        }
    }

    fn consume_registry(&self) -> Registry {
        self.expect_start_element("registry");
        let mut registry = Registry { enum_nss: ~[], cmd_nss: ~[] };
        loop {
            match self.recv() {
                // ignores
                Characters(_) | Comment(_) => (),
                StartElement(~"comment", _) => self.skip_until(EndElement(~"comment")),
                StartElement(~"types", _) => self.skip_until(EndElement(~"types")),
                StartElement(~"groups", _) => self.skip_until(EndElement(~"groups")),
                StartElement(~"feature", _) => self.skip_until(EndElement(~"feature")),
                StartElement(~"extensions", _) => self.skip_until(EndElement(~"extensions")),

                // add enum namespace
                StartElement(~"enums", ref atts) => {
                    registry.enum_nss.push(
                        EnumNs {
                            namespace:  atts.get_copy(&~"namespace"),
                            group:      atts.find_copy(&~"group"),
                            ty:         atts.find_copy(&~"type"),
                            start:      atts.find_copy(&~"start"),
                            end:        atts.find_copy(&~"end"),
                            vendor:     atts.find_copy(&~"vendor"),
                            comment:    atts.find_copy(&~"comment"),
                            enums:      self.consume_enums(),
                        }
                    )
                }

                // add command namespace
                StartElement(~"commands", ref atts) => {
                    registry.cmd_nss.push(
                        CmdNs {
                            namespace:  atts.get_copy(&~"namespace"),
                            cmds:       self.consume_cmds(),
                        }
                    );
                }

                // finished building the registry
                EndElement(~"registry") => break,

                // error handling
                msg => fail!("Expected </registry>, found: %?", msg.to_str()),
            }
        }
        registry
    }

    fn consume_enums(&self) -> ~[Enum] {
        let mut enums = ~[];
        loop {
            match self.recv() {
                // ignores
                Characters(_) | Comment(_) => (),
                StartElement(~"unused", _) => self.skip_until(EndElement(~"unused")),

                // add enum definition
                StartElement(~"enum", ref atts) => {
                    enums.push(
                        Enum {
                            ident:  atts.get_copy(&~"name"),
                            value:  atts.get_copy(&~"value"),
                        }
                    );
                    self.expect_end_element("enum");
                }

                // finished building the namespace
                EndElement(~"enums") => break,
                // error handling
                msg => fail!("Expected </enums>, found: %?", msg.to_str()),
            }
        }
        enums
    }

    fn consume_cmds(&self) -> ~[Cmd] {
        let mut cmds = ~[];
        loop {
            match self.recv() {
                // add command definition
                StartElement(~"command", _) => {
                    self.expect_start_element("proto");
                    let proto = self.consume_binding();
                    self.expect_end_element("proto");

                    cmds.push(Cmd {
                        proto: proto,
                        params: ~[],
                    });

                    self.skip_until(EndElement(~"command"));
                }
                // finished building the namespace
                EndElement(~"commands") => break,
                // // error handling
                msg => fail!("Expected </commands>, found: %?", msg.to_str()),
            }
        }
        cmds
    }

    fn consume_binding(&self) -> Binding {
        // consume type
        let mut ty = ~"";
        loop {
            match self.recv() {
                Characters(ch) => ty.push_str(ch),
                StartElement(~"ptype", _) => (),
                EndElement(~"ptype") => (),
                StartElement(~"name", _) => break,
                msg => fail!("Expected binding, found: %?", msg.to_str()),
            }
        }
        let ident = self.expect_characters();
        // consume identifier
        self.expect_end_element("name");
        Binding {
            ident: ident,
            ty: ty,
        }
    }

    // TODO: Consume command parameters
}
<|endoftext|>