<commit_before>//
// writer.rs
// Copyright (C) 2015 Adrian Perez <aperez@igalia.com>
// Distributed under terms of the MIT license.
//

use std::io;
use std::fmt;
use std::collections::BTreeMap;
use super::value::Value;

trait Formatter {
    fn start_compound<W>(&mut self, writer: &mut W, ch: u8) -> io::Result<()>
        where W: io::Write;
    fn end_compound<W>(&mut self, writer: &mut W, ch: u8) -> io::Result<()>
        where W: io::Write;
    fn key_separator<W>(&mut self, writer: &mut W, next: &Value) -> io::Result<()>
        where W: io::Write;
    fn item_separator<W>(&mut self, writer: &mut W, next: &Value, in_dict: bool) -> io::Result<()>
        where W: io::Write;
}

pub struct CompactFormatter;

impl Formatter for CompactFormatter {
    fn start_compound<W>(&mut self, writer: &mut W, ch: u8) -> io::Result<()>
        where W: io::Write
    {
        writer.write_all(&[ch])
    }

    fn end_compound<W>(&mut self, writer: &mut W, ch: u8) -> io::Result<()>
        where W: io::Write
    {
        writer.write_all(&[ch])
    }

    fn key_separator<W>(&mut self, writer: &mut W, next: &Value) -> io::Result<()>
        where W: io::Write
    {
        match *next {
            Value::Dict(_) | Value::List(_) => Ok(()),
            _ => writer.write_all(b":"),
        }
    }

    fn item_separator<W>(&mut self, writer: &mut W, next: &Value, in_dict: bool) -> io::Result<()>
        where W: io::Write
    {
        match *next {
            Value::Dict(_) | Value::List(_) => Ok(()),
            _ => writer.write_all(b","),
        }
    }
}

pub struct PrettyFormatter {
    indent: usize,
}

impl PrettyFormatter {
    fn new() -> Self {
        PrettyFormatter { indent: 0 }
    }
}

#[inline]
fn indent<W>(writer: &mut W, indent: usize) -> io::Result<()>
    where W: io::Write
{
    for _ in 0..indent {
        try!(writer.write_all(b"  "));
    }
    Ok(())
}

impl Formatter for PrettyFormatter {
    fn start_compound<W>(&mut self, writer: &mut W, ch: u8) -> io::Result<()>
        where W: io::Write
    {
        self.indent += 1;
        try!(writer.write_all(&[ch, b'\n']));
        indent(writer, self.indent)
    }

    fn end_compound<W>(&mut self, writer: &mut W, ch: u8) -> io::Result<()>
        where W: io::Write
    {
        self.indent -= 1;
        try!(writer.write(b"\n"));
        try!(indent(writer, self.indent));
        writer.write_all(&[ch])
    }

    fn key_separator<W>(&mut self, writer: &mut W, next: &Value) -> io::Result<()>
        where W: io::Write
    {
        match *next {
            Value::Dict(_) | Value::List(_) => writer.write_all(b" "),
            _ => writer.write_all(b": "),
        }
    }

    fn item_separator<W>(&mut self, writer: &mut W, next: &Value, in_dict: bool) -> io::Result<()>
        where W: io::Write
    {
        try!(writer.write(b"\n"));
        indent(writer, self.indent)
    }
}

pub struct Writer<W, F=PrettyFormatter> {
    writer: W,
    format: F,
}

impl<W> Writer<W, CompactFormatter>
    where W: io::Write
{
    #[inline]
    pub fn compact(writer: W) -> Self {
        Writer::with_formatter(writer, CompactFormatter)
    }
}

impl<W> Writer<W>
    where W: io::Write
{
    #[inline]
    pub fn pretty(writer: W) -> Self {
        Writer::with_formatter(writer, PrettyFormatter::new())
    }
}

impl<W, F> Writer<W, F>
    where W: io::Write,
          F: Formatter,
{
    #[inline]
    fn with_formatter(writer: W, formatter: F) -> Self
        where W: io::Write,
              F: Formatter,
    {
        Writer {
            writer: writer,
            format: formatter,
        }
    }

    fn write_value(&mut self, value: &Value) -> io::Result<()> {
        match *value {
            Value::Bool(value) => self.write_bool(value),
            Value::Float(value) => self.write_float(value),
            Value::Integer(value) => self.write_integer(value),
            Value::String(ref value) => self.write_string(value),
            Value::List(ref value) => self.write_list(value),
            Value::Dict(ref value) => self.write_dict(value),
        }
    }

    fn write_bool(&mut self, value: bool) -> io::Result<()> {
        if value {
            self.writer.write_all(b"True")
        } else {
            self.writer.write_all(b"False")
        }
    }

    fn write_float(&mut self, value: f64) -> io::Result<()> {
        unreachable!();
    }

    fn write_integer(&mut self, value: i64) -> io::Result<()> {
        unreachable!();
    }

    fn write_string(&mut self, value: &String) -> io::Result<()> {
        try!(self.writer.write_all(b"\""));
        for ch in value.bytes() {
            try!(match ch {
                0x09 => self.writer.write_all(b"\\t"),
                0x0A => self.writer.write_all(b"\\n"),
                0x0D => self.writer.write_all(b"\\r"),
                0x22 => self.writer.write_all(b"\\\""),
                0x5C => self.writer.write_all(b"\\\\"),
                ch if ch < 0xF => write!(self.writer, "\\0{:X}", ch),
                ch if ch < 0x20 => write!(self.writer, "\\{:X}", ch),
                ch => self.writer.write_all(&[ch]),
            });
        }
        self.writer.write_all(b"\"")
    }

    fn write_list(&mut self, value: &Vec<Value>) -> io::Result<()> {
        if value.is_empty() {
            return self.writer.write_all(b"[]");
        }

        let mut iter = value.iter().peekable();
        try!(self.format.start_compound(&mut self.writer, b'['));
        loop {
            match iter.next() {
                None => break,
                Some(value) => {
                    try!(self.write_value(value));
                    match iter.peek () {
                        Some(&value_) =>
                            try!(self.format.item_separator(&mut self.writer, value, false)),
                        None => (),
                    }
                },
            }
        }
        self.format.end_compound(&mut self.writer, b']')
    }

    fn write_dict(&mut self, dict: &BTreeMap<String, Value>) -> io::Result<()> {
        if dict.is_empty() {
            return self.writer.write_all(b"{}");
        }

        try!(self.format.start_compound(&mut self.writer, b'{'));
        try!(self.write_keyval_items(dict));
        self.format.end_compound(&mut self.writer, b'}')
    }

    fn write_keyval_items(&mut self, dict: &BTreeMap<String, Value>) -> io::Result<()> {
        let mut iter = dict.iter().peekable();
        loop {
            match iter.next() {
                None => break,
                Some((key, value)) => {
                    try!(self.writer.write_all(key.as_bytes()));
                    try!(self.format.key_separator(&mut self.writer, value));
                    try!(self.write_value(value));
                    match iter.peek () {
                        Some(&(_, ref value)) =>
                            try!(self.format.item_separator(&mut self.writer, value, true)),
                        None => (),
                    }
                },
            }
        }
        Ok(())
    }

    pub fn write_message(&mut self, value: &BTreeMap<String, Value>) -> io::Result<()> {
        self.write_keyval_items(value)
    }

    #[inline]
    pub fn write_framed_message(&mut self, value: &BTreeMap<String, Value>) -> io::Result<()> {
        self.write_dict(value)
    }
}

#[cfg(test)]
mod tests {
	use super::*;
    use super::super::value::Value;
    use std::io::{Cursor, Write};
    use std::collections::BTreeMap;

    macro_rules! make_write_test {
        ($name:ident, $value:expr, $pretty:expr, $compact:expr) => {
            #[test]
            fn $name() {
                {
                    println!("Pretty");
                    let mut output = Cursor::new(Vec::new());
                    Writer::pretty(&mut output).write_value($value).ok();
                    assert_eq!($pretty, String::from_utf8(output.into_inner()).unwrap());
                }
                {
                    println!("Compact");
                    let mut output = Cursor::new(Vec::new());
                    Writer::compact(&mut output).write_value($value).ok();
                    assert_eq!($compact, String::from_utf8(output.into_inner()).unwrap());
                }
            }
        }
    }

    make_write_test!(bool_true,  &Value::Bool(true),  "True", "True");
    make_write_test!(bool_false, &Value::Bool(false), "False", "False");

    make_write_test!(list_empty, &Value::List(vec![]), "[]", "[]");
    make_write_test!(list_one,   &Value::List(vec![Value::Bool(true)]), "[\n  True\n]", "[True]");
    make_write_test!(list_two,   &Value::List(vec![Value::Bool(true), Value::Bool(false)]),
        "[\n  True\n  False\n]", "[True,False]");
    make_write_test!(list_nested,
                     &Value::List(vec![
                                  Value::Bool(true),
                                  Value::List(vec![Value::Bool(false)])]),
                     "[\n  True\n  [\n    False\n  ]\n]", "[True,[False]]");

    make_write_test!(dict_empty, &Value::Dict(BTreeMap::new()), "{}", "{}");
    make_write_test!(dict_one,   &Value::Dict((|| {
        let mut b = BTreeMap::new();
        b.insert("item".to_string(), Value::Bool(true));
        b
    })()), "{\n  item: True\n}", "{item:True}");
    make_write_test!(dict_two,   &Value::Dict((|| {
        let mut b = BTreeMap::new();
        b.insert("foo".to_string(), Value::Bool(true));
        b.insert("bar".to_string(), Value::Bool(false));
        b
    })()), "{\n  bar: False\n  foo: True\n}", "{bar:False,foo:True}");

    macro_rules! make_write_string_test {
        ($name:ident, $value:expr, $expected:expr) => {
            make_write_test!($name, &Value::String($value.to_string()), $expected, $expected);
        }
    }

    make_write_string_test!(string_empty, "", "\"\"");
    make_write_string_test!(string_non_empty, "foo bar", "\"foo bar\"");
    make_write_string_test!(string_unicode, "☺", "\"☺\"");
    make_write_string_test!(string_escapes, "\n\r\t\\\"", "\"\\n\\r\\t\\\\\\\"\"");
    make_write_string_test!(string_hexcode, "\0", "\"\\00\"");
}
<commit_msg>writer: Remove unused in_dict flag from formatters<commit_after>//
// writer.rs
// Copyright (C) 2015 Adrian Perez <aperez@igalia.com>
// Distributed under terms of the MIT license.
//

use std::io;
use std::fmt;
use std::collections::BTreeMap;
use super::value::Value;

trait Formatter {
    fn start_compound<W>(&mut self, writer: &mut W, ch: u8) -> io::Result<()>
        where W: io::Write;
    fn end_compound<W>(&mut self, writer: &mut W, ch: u8) -> io::Result<()>
        where W: io::Write;
    fn key_separator<W>(&mut self, writer: &mut W, next: &Value) -> io::Result<()>
        where W: io::Write;
    fn item_separator<W>(&mut self, writer: &mut W, next: &Value) -> io::Result<()>
        where W: io::Write;
}

pub struct CompactFormatter;

impl Formatter for CompactFormatter {
    fn start_compound<W>(&mut self, writer: &mut W, ch: u8) -> io::Result<()>
        where W: io::Write
    {
        writer.write_all(&[ch])
    }

    fn end_compound<W>(&mut self, writer: &mut W, ch: u8) -> io::Result<()>
        where W: io::Write
    {
        writer.write_all(&[ch])
    }

    fn key_separator<W>(&mut self, writer: &mut W, next: &Value) -> io::Result<()>
        where W: io::Write
    {
        match *next {
            Value::Dict(_) | Value::List(_) => Ok(()),
            _ => writer.write_all(b":"),
        }
    }

    fn item_separator<W>(&mut self, writer: &mut W, next: &Value) -> io::Result<()>
        where W: io::Write
    {
        match *next {
            Value::Dict(_) | Value::List(_) => Ok(()),
            _ => writer.write_all(b","),
        }
    }
}

pub struct PrettyFormatter {
    indent: usize,
}

impl PrettyFormatter {
    fn new() -> Self {
        PrettyFormatter { indent: 0 }
    }
}

#[inline]
fn indent<W>(writer: &mut W, indent: usize) -> io::Result<()>
    where W: io::Write
{
    for _ in 0..indent {
        try!(writer.write_all(b"  "));
    }
    Ok(())
}

impl Formatter for PrettyFormatter {
    fn start_compound<W>(&mut self, writer: &mut W, ch: u8) -> io::Result<()>
        where W: io::Write
    {
        self.indent += 1;
        try!(writer.write_all(&[ch, b'\n']));
        indent(writer, self.indent)
    }

    fn end_compound<W>(&mut self, writer: &mut W, ch: u8) -> io::Result<()>
        where W: io::Write
    {
        self.indent -= 1;
        try!(writer.write(b"\n"));
        try!(indent(writer, self.indent));
        writer.write_all(&[ch])
    }

    fn key_separator<W>(&mut self, writer: &mut W, next: &Value) -> io::Result<()>
        where W: io::Write
    {
        match *next {
            Value::Dict(_) | Value::List(_) => writer.write_all(b" "),
            _ => writer.write_all(b": "),
        }
    }

    fn item_separator<W>(&mut self, writer: &mut W, next: &Value) -> io::Result<()>
        where W: io::Write
    {
        try!(writer.write(b"\n"));
        indent(writer, self.indent)
    }
}

pub struct Writer<W, F=PrettyFormatter> {
    writer: W,
    format: F,
}

impl<W> Writer<W, CompactFormatter>
    where W: io::Write
{
    #[inline]
    pub fn compact(writer: W) -> Self {
        Writer::with_formatter(writer, CompactFormatter)
    }
}

impl<W> Writer<W>
    where W: io::Write
{
    #[inline]
    pub fn pretty(writer: W) -> Self {
        Writer::with_formatter(writer, PrettyFormatter::new())
    }
}

impl<W, F> Writer<W, F>
    where W: io::Write,
          F: Formatter,
{
    #[inline]
    fn with_formatter(writer: W, formatter: F) -> Self
        where W: io::Write,
              F: Formatter,
    {
        Writer {
            writer: writer,
            format: formatter,
        }
    }

    fn write_value(&mut self, value: &Value) -> io::Result<()> {
        match *value {
            Value::Bool(value) => self.write_bool(value),
            Value::Float(value) => self.write_float(value),
            Value::Integer(value) => self.write_integer(value),
            Value::String(ref value) => self.write_string(value),
            Value::List(ref value) => self.write_list(value),
            Value::Dict(ref value) => self.write_dict(value),
        }
    }

    fn write_bool(&mut self, value: bool) -> io::Result<()> {
        if value {
            self.writer.write_all(b"True")
        } else {
            self.writer.write_all(b"False")
        }
    }

    fn write_float(&mut self, value: f64) -> io::Result<()> {
        unreachable!();
    }

    fn write_integer(&mut self, value: i64) -> io::Result<()> {
        unreachable!();
    }

    fn write_string(&mut self, value: &String) -> io::Result<()> {
        try!(self.writer.write_all(b"\""));
        for ch in value.bytes() {
            try!(match ch {
                0x09 => self.writer.write_all(b"\\t"),
                0x0A => self.writer.write_all(b"\\n"),
                0x0D => self.writer.write_all(b"\\r"),
                0x22 => self.writer.write_all(b"\\\""),
                0x5C => self.writer.write_all(b"\\\\"),
                ch if ch < 0xF => write!(self.writer, "\\0{:X}", ch),
                ch if ch < 0x20 => write!(self.writer, "\\{:X}", ch),
                ch => self.writer.write_all(&[ch]),
            });
        }
        self.writer.write_all(b"\"")
    }

    fn write_list(&mut self, value: &Vec<Value>) -> io::Result<()> {
        if value.is_empty() {
            return self.writer.write_all(b"[]");
        }

        let mut iter = value.iter().peekable();
        try!(self.format.start_compound(&mut self.writer, b'['));
        loop {
            match iter.next() {
                None => break,
                Some(value) => {
                    try!(self.write_value(value));
                    match iter.peek () {
                        Some(_) =>
                            try!(self.format.item_separator(&mut self.writer, value)),
                        None => (),
                    }
                },
            }
        }
        self.format.end_compound(&mut self.writer, b']')
    }

    fn write_dict(&mut self, dict: &BTreeMap<String, Value>) -> io::Result<()> {
        if dict.is_empty() {
            return self.writer.write_all(b"{}");
        }

        try!(self.format.start_compound(&mut self.writer, b'{'));
        try!(self.write_keyval_items(dict));
        self.format.end_compound(&mut self.writer, b'}')
    }

    fn write_keyval_items(&mut self, dict: &BTreeMap<String, Value>) -> io::Result<()> {
        let mut iter = dict.iter().peekable();
        loop {
            match iter.next() {
                None => break,
                Some((key, value)) => {
                    try!(self.writer.write_all(key.as_bytes()));
                    try!(self.format.key_separator(&mut self.writer, value));
                    try!(self.write_value(value));
                    match iter.peek () {
                        Some(&(_, ref value)) =>
                            try!(self.format.item_separator(&mut self.writer, value)),
                        None => (),
                    }
                },
            }
        }
        Ok(())
    }

    pub fn write_message(&mut self, value: &BTreeMap<String, Value>) -> io::Result<()> {
        self.write_keyval_items(value)
    }

    #[inline]
    pub fn write_framed_message(&mut self, value: &BTreeMap<String, Value>) -> io::Result<()> {
        self.write_dict(value)
    }
}

#[cfg(test)]
mod tests {
	use super::*;
    use super::super::value::Value;
    use std::io::{Cursor, Write};
    use std::collections::BTreeMap;

    macro_rules! make_write_test {
        ($name:ident, $value:expr, $pretty:expr, $compact:expr) => {
            #[test]
            fn $name() {
                {
                    println!("Pretty");
                    let mut output = Cursor::new(Vec::new());
                    Writer::pretty(&mut output).write_value($value).ok();
                    assert_eq!($pretty, String::from_utf8(output.into_inner()).unwrap());
                }
                {
                    println!("Compact");
                    let mut output = Cursor::new(Vec::new());
                    Writer::compact(&mut output).write_value($value).ok();
                    assert_eq!($compact, String::from_utf8(output.into_inner()).unwrap());
                }
            }
        }
    }

    make_write_test!(bool_true,  &Value::Bool(true),  "True", "True");
    make_write_test!(bool_false, &Value::Bool(false), "False", "False");

    make_write_test!(list_empty, &Value::List(vec![]), "[]", "[]");
    make_write_test!(list_one,   &Value::List(vec![Value::Bool(true)]), "[\n  True\n]", "[True]");
    make_write_test!(list_two,   &Value::List(vec![Value::Bool(true), Value::Bool(false)]),
        "[\n  True\n  False\n]", "[True,False]");
    make_write_test!(list_nested,
                     &Value::List(vec![
                                  Value::Bool(true),
                                  Value::List(vec![Value::Bool(false)])]),
                     "[\n  True\n  [\n    False\n  ]\n]", "[True,[False]]");

    make_write_test!(dict_empty, &Value::Dict(BTreeMap::new()), "{}", "{}");
    make_write_test!(dict_one,   &Value::Dict((|| {
        let mut b = BTreeMap::new();
        b.insert("item".to_string(), Value::Bool(true));
        b
    })()), "{\n  item: True\n}", "{item:True}");
    make_write_test!(dict_two,   &Value::Dict((|| {
        let mut b = BTreeMap::new();
        b.insert("foo".to_string(), Value::Bool(true));
        b.insert("bar".to_string(), Value::Bool(false));
        b
    })()), "{\n  bar: False\n  foo: True\n}", "{bar:False,foo:True}");

    macro_rules! make_write_string_test {
        ($name:ident, $value:expr, $expected:expr) => {
            make_write_test!($name, &Value::String($value.to_string()), $expected, $expected);
        }
    }

    make_write_string_test!(string_empty, "", "\"\"");
    make_write_string_test!(string_non_empty, "foo bar", "\"foo bar\"");
    make_write_string_test!(string_unicode, "☺", "\"☺\"");
    make_write_string_test!(string_escapes, "\n\r\t\\\"", "\"\\n\\r\\t\\\\\\\"\"");
    make_write_string_test!(string_hexcode, "\0", "\"\\00\"");
}
<|endoftext|>


<commit_before>// Copyright 2018 The Bazel Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// A simple wrapper around a build_script execution to generate file to reuse
// by rust_library/rust_binary.
extern crate cargo_build_script_output_parser;

use cargo_build_script_output_parser::BuildScriptOutput;
use std::env;
use std::fs::{File, canonicalize, create_dir_all};
use std::io::Write;
use std::process::{exit, Command};

fn main() {
    let mut args = env::args().skip(1);
    let manifest_dir_env = env::var("CARGO_MANIFEST_DIR").expect("CARGO_MANIFEST_DIR was not set");
    let out_dir_env = env::var("OUT_DIR").expect("OUT_DIR was not set");
    // For some reason RBE does not creat the output directory, force create it
    create_dir_all(out_dir_env.clone()).expect(&format!("Failed to create OUT_DIR: {}", out_dir_env));
    let rustc_env = env::var("RUSTC").expect("RUSTC was not set");
    // Because of the Bazel's sandbox, bazel cannot provide full path, convert all relative path to correct path.
    let manifest_dir = canonicalize(&manifest_dir_env).expect(&format!("Failed to canonicalize '{}'", manifest_dir_env));
    let out_dir = canonicalize(&out_dir_env).expect(&format!("Failed to canonicalize '{}'", out_dir_env));
    let rustc = canonicalize(&rustc_env).expect(&format!("Failed to canonicalize '{}'", rustc_env));
    match (args.next(), args.next(), args.next(), args.next(), args.next()) {
        (Some(progname), Some(crate_name), Some(envfile), Some(flagfile), Some(depenvfile)) => {
            let output = BuildScriptOutput::from_command(
                    Command::new(
                        canonicalize(&progname).expect(&format!("Failed to canonicalize '{}'", progname)))
                .args(args)
                .current_dir(manifest_dir.clone())
                .env("OUT_DIR", out_dir)
                .env("CARGO_MANIFEST_DIR", manifest_dir)
                .env("RUSTC", rustc));
            let mut f =
                File::create(&envfile).expect(&format!("Unable to create file {}", envfile));
            f.write_all(BuildScriptOutput::to_env(&output).as_bytes())
                .expect(&format!("Unable to write file {}", envfile));
            let mut f =
                File::create(&depenvfile).expect(&format!("Unable to create file {}", depenvfile));
            f.write_all(BuildScriptOutput::to_dep_env(&output, &crate_name).as_bytes())
                .expect(&format!("Unable to write file {}", depenvfile));
            let mut f =
                File::create(&flagfile).expect(&format!("Unable to create file {}", flagfile));
            f.write_all(BuildScriptOutput::to_flags(&output).as_bytes())
                .expect(&format!("Unable to write file {}", flagfile));
        }
        _ => {
            eprintln!("Usage: $0 progname crate_name envfile flagfile depenvfile [arg1...argn]");
            exit(1);
        }
    }
}
<commit_msg>Use current_dir().join not canonicalize (#347)<commit_after>// Copyright 2018 The Bazel Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// A simple wrapper around a build_script execution to generate file to reuse
// by rust_library/rust_binary.
extern crate cargo_build_script_output_parser;

use cargo_build_script_output_parser::BuildScriptOutput;
use std::env;
use std::fs::{File, create_dir_all};
use std::io::Write;
use std::process::{exit, Command};

fn main() {
    // We use exec_root.join rather than std::fs::canonicalize, to avoid resolving symlinks, as
    // some execution strategies and remote execution environments may use symlinks in ways which
    // canonicalizing them may break them, e.g. by having input files be symlinks into a /cas
    // directory - resolving these may cause tools which inspect $0, or try to resolve files
    // relative to themselves, to fail.
    let exec_root = env::current_dir().expect("Failed to get current directory");

    let mut args = env::args().skip(1);
    let manifest_dir_env = env::var("CARGO_MANIFEST_DIR").expect("CARGO_MANIFEST_DIR was not set");
    let out_dir_env = env::var("OUT_DIR").expect("OUT_DIR was not set");
    // For some reason RBE does not creat the output directory, force create it
    create_dir_all(out_dir_env.clone()).expect(&format!("Failed to create OUT_DIR: {}", out_dir_env));
    let rustc_env = env::var("RUSTC").expect("RUSTC was not set");
    // Because of the Bazel's sandbox, bazel cannot provide full path, convert all relative path to correct path.
    let manifest_dir = exec_root.join(&manifest_dir_env);
    let out_dir = exec_root.join(&out_dir_env);
    let rustc = exec_root.join(&rustc_env);
    match (args.next(), args.next(), args.next(), args.next(), args.next()) {
        (Some(progname), Some(crate_name), Some(envfile), Some(flagfile), Some(depenvfile)) => {
            let output = BuildScriptOutput::from_command(
                    Command::new(exec_root.join(&progname))
                .args(args)
                .current_dir(manifest_dir.clone())
                .env("OUT_DIR", out_dir)
                .env("CARGO_MANIFEST_DIR", manifest_dir)
                .env("RUSTC", rustc));
            let mut f =
                File::create(&envfile).expect(&format!("Unable to create file {}", envfile));
            f.write_all(BuildScriptOutput::to_env(&output).as_bytes())
                .expect(&format!("Unable to write file {}", envfile));
            let mut f =
                File::create(&depenvfile).expect(&format!("Unable to create file {}", depenvfile));
            f.write_all(BuildScriptOutput::to_dep_env(&output, &crate_name).as_bytes())
                .expect(&format!("Unable to write file {}", depenvfile));
            let mut f =
                File::create(&flagfile).expect(&format!("Unable to create file {}", flagfile));
            f.write_all(BuildScriptOutput::to_flags(&output).as_bytes())
                .expect(&format!("Unable to write file {}", flagfile));
        }
        _ => {
            eprintln!("Usage: $0 progname crate_name envfile flagfile depenvfile [arg1...argn]");
            exit(1);
        }
    }
}
<|endoftext|>


<commit_before>

#![deny(mut_mut, zero_ptr, cmp_nan)]
#![allow(dead_code)]

#[macro_use]
extern crate lazy_static;

use std::collections::HashMap;

// ensure that we don't suggest `is_nan` and `is_null` inside constants
// FIXME: once const fn is stable, suggest these functions again in constants
const BAA: *const i32 = 0 as *const i32;
static mut BAR: *const i32 = BAA;
static mut FOO: *const i32 = 0 as *const i32;
static mut BUH: bool = 42.0 < std::f32::NAN;

#[allow(unused_variables, unused_mut)]
fn main() {
    lazy_static! {
        static ref MUT_MAP : HashMap<usize, &'static str> = {
            let mut m = HashMap::new();
            m.insert(0, "zero");
            m
        };
        static ref MUT_COUNT : usize = MUT_MAP.len();
    }
    assert_eq!(*MUT_COUNT, 1);
    // FIXME: don't lint in array length, requires `check_body`
    //let _ = [""; (42.0 < std::f32::NAN) as usize];
}
<commit_msg>mut_mut_macro is missing plugin(clippy)<commit_after>#![feature(plugin)]
#![plugin(clippy)]
#![deny(mut_mut, zero_ptr, cmp_nan)]
#![allow(dead_code)]

#[macro_use]
extern crate lazy_static;

use std::collections::HashMap;

// ensure that we don't suggest `is_nan` and `is_null` inside constants
// FIXME: once const fn is stable, suggest these functions again in constants
const BAA: *const i32 = 0 as *const i32;
static mut BAR: *const i32 = BAA;
static mut FOO: *const i32 = 0 as *const i32;
static mut BUH: bool = 42.0 < std::f32::NAN;

#[allow(unused_variables, unused_mut)]
fn main() {
    lazy_static! {
        static ref MUT_MAP : HashMap<usize, &'static str> = {
            let mut m = HashMap::new();
            m.insert(0, "zero");
            m
        };
        static ref MUT_COUNT : usize = MUT_MAP.len();
    }
    assert_eq!(*MUT_COUNT, 1);
    // FIXME: don't lint in array length, requires `check_body`
    //let _ = [""; (42.0 < std::f32::NAN) as usize];
}
<|endoftext|>


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

//! This module implements structured cloning, as defined by [HTML]
//! (https://html.spec.whatwg.org/multipage/#safe-passing-of-structured-data).

use dom::bindings::conversions::root_from_handleobject;
use dom::bindings::error::{Error, Fallible};
use dom::bindings::reflector::DomObject;
use dom::bindings::root::DomRoot;
use dom::blob::{Blob, BlobImpl};
use dom::globalscope::GlobalScope;
use js::jsapi::{JSAutoCompartment, JSContext};
use js::jsapi::{JSStructuredCloneCallbacks, JSStructuredCloneReader, JSStructuredCloneWriter};
use js::jsapi::{JS_ClearPendingException, JSObject};
use js::jsapi::{JS_ReadBytes, JS_WriteBytes};
use js::jsapi::{JS_ReadUint32Pair, JS_WriteUint32Pair};
use js::jsapi::HandleObject as RawHandleObject;
use js::jsapi::JS_STRUCTURED_CLONE_VERSION;
use js::jsapi::MutableHandleObject as RawMutableHandleObject;
use js::jsapi::TransferableOwnership;
use js::rust::{Handle, HandleValue, MutableHandleValue};
use js::rust::wrappers::{JS_WriteStructuredClone, JS_ReadStructuredClone};
use libc::size_t;
use std::os::raw;
use std::ptr;
use std::slice;

// TODO: Should we add Min and Max const to https://github.com/servo/rust-mozjs/blob/master/src/consts.rs?
// TODO: Determine for sure which value Min and Max should have.
// NOTE: Current values found at https://dxr.mozilla.org/mozilla-central/
// rev/ff04d410e74b69acfab17ef7e73e7397602d5a68/js/public/StructuredClone.h#323
#[repr(u32)]
enum StructuredCloneTags {
    /// To support additional types, add new tags with values incremented from the last one before Max.
    Min = 0xFFFF8000,
    DomBlob = 0xFFFF8001,
    Max = 0xFFFFFFFF,
}

#[cfg(target_pointer_width = "64")]
unsafe fn write_length(w: *mut JSStructuredCloneWriter,
                       length: usize) {
  let high: u32 = (length >> 32) as u32;
  let low: u32 = length as u32;
  assert!(JS_WriteUint32Pair(w, high, low));
}

#[cfg(target_pointer_width = "32")]
unsafe fn write_length(w: *mut JSStructuredCloneWriter,
                       length: usize) {
  assert!(JS_WriteUint32Pair(w, length as u32, 0));
}

#[cfg(target_pointer_width = "64")]
unsafe fn read_length(r: *mut JSStructuredCloneReader)
                      -> usize {
  let mut high: u32 = 0;
  let mut low: u32 = 0;
  assert!(JS_ReadUint32Pair(r, &mut high as *mut u32, &mut low as *mut u32));
  return (low << high) as usize;
}

#[cfg(target_pointer_width = "32")]
unsafe fn read_length(r: *mut JSStructuredCloneReader)
                      -> usize {
  let mut length: u32 = 0;
  let mut zero: u32 = 0;
  assert!(JS_ReadUint32Pair(r, &mut length as *mut u32, &mut zero as *mut u32));
  return length as usize;
}

struct StructuredCloneWriter {
    w: *mut JSStructuredCloneWriter,
}

impl StructuredCloneWriter {
    unsafe fn write_slice(&self, v: &[u8]) {
        let type_length = v.len();
        write_length(self.w, type_length);
        assert!(JS_WriteBytes(self.w, v.as_ptr() as *const raw::c_void, type_length));
    }
    unsafe fn write_str(&self, s: &str) {
        self.write_slice(s.as_bytes());
    }
}

struct StructuredCloneReader {
    r: *mut JSStructuredCloneReader,
}

impl StructuredCloneReader {
    unsafe fn read_bytes(&self) -> Vec<u8> {
        let mut bytes = vec![0u8; read_length(self.r)];
        let blob_length = bytes.len();
        assert!(JS_ReadBytes(self.r, bytes.as_mut_ptr() as *mut raw::c_void, blob_length));
        return bytes;
    }
    unsafe fn read_str(&self) -> String {
        let str_buffer = self.read_bytes();
        return String::from_utf8_unchecked(str_buffer);
    }
}

unsafe fn read_blob(cx: *mut JSContext,
                    r: *mut JSStructuredCloneReader)
                    -> *mut JSObject {
    let structured_reader = StructuredCloneReader { r: r };
    let blob_buffer = structured_reader.read_bytes();
    let type_str = structured_reader.read_str();
    let target_global = GlobalScope::from_context(cx);
    let blob = Blob::new(&target_global, BlobImpl::new_from_bytes(blob_buffer), type_str);
    return blob.reflector().get_jsobject().get()
}

unsafe fn write_blob(blob: DomRoot<Blob>,
                     w: *mut JSStructuredCloneWriter)
                     -> Result<(), ()> {
    let structured_writer = StructuredCloneWriter { w: w };
    let blob_vec = blob.get_bytes()?;
    assert!(JS_WriteUint32Pair(w, StructuredCloneTags::DomBlob as u32, 0));
    structured_writer.write_slice(&blob_vec);
    structured_writer.write_str(&blob.type_string());
    return Ok(())
}

unsafe extern "C" fn read_callback(cx: *mut JSContext,
                                   r: *mut JSStructuredCloneReader,
                                   tag: u32,
                                   _data: u32,
                                   _closure: *mut raw::c_void)
                                   -> *mut JSObject {
    assert!(tag < StructuredCloneTags::Max as u32, "tag should be lower than StructuredCloneTags::Max");
    assert!(tag > StructuredCloneTags::Min as u32, "tag should be higher than StructuredCloneTags::Min");
    if tag == StructuredCloneTags::DomBlob as u32 {
        return read_blob(cx, r)
    }
    return ptr::null_mut()
}

unsafe extern "C" fn write_callback(_cx: *mut JSContext,
                                    w: *mut JSStructuredCloneWriter,
                                    obj: RawHandleObject,
                                    _closure: *mut raw::c_void)
                                    -> bool {
    if let Ok(blob) = root_from_handleobject::<Blob>(Handle::from_raw(obj)) {
        return write_blob(blob, w).is_ok()
    }
    return false
}

unsafe extern "C" fn read_transfer_callback(_cx: *mut JSContext,
                                            _r: *mut JSStructuredCloneReader,
                                            _tag: u32,
                                            _content: *mut raw::c_void,
                                            _extra_data: u64,
                                            _closure: *mut raw::c_void,
                                            _return_object: RawMutableHandleObject)
                                            -> bool {
    false
}

unsafe extern "C" fn write_transfer_callback(_cx: *mut JSContext,
                                             _obj: RawHandleObject,
                                             _closure: *mut raw::c_void,
                                             _tag: *mut u32,
                                             _ownership: *mut TransferableOwnership,
                                             _content:  *mut *mut raw::c_void,
                                             _extra_data: *mut u64)
                                             -> bool {
    false
}

unsafe extern "C" fn free_transfer_callback(_tag: u32,
                                            _ownership: TransferableOwnership,
                                            _content: *mut raw::c_void,
                                            _extra_data: u64,
                                            _closure: *mut raw::c_void) {
}

unsafe extern "C" fn report_error_callback(_cx: *mut JSContext, _errorid: u32) {
}

static STRUCTURED_CLONE_CALLBACKS: JSStructuredCloneCallbacks = JSStructuredCloneCallbacks {
    read: Some(read_callback),
    write: Some(write_callback),
    reportError: Some(report_error_callback),
    readTransfer: Some(read_transfer_callback),
    writeTransfer: Some(write_transfer_callback),
    freeTransfer: Some(free_transfer_callback),
};

/// A buffer for a structured clone.
pub enum StructuredCloneData {
    /// A non-serializable (default) variant
    Struct(*mut u64, size_t),
    /// A variant that can be serialized
    Vector(Vec<u8>)
}

impl StructuredCloneData {
    /// Writes a structured clone. Returns a `DataClone` error if that fails.
    pub fn write(cx: *mut JSContext, message: HandleValue) -> Fallible<StructuredCloneData> {
        let mut data = ptr::null_mut();
        let mut nbytes = 0;
        let result = unsafe {
            JS_WriteStructuredClone(cx,
                                    message,
                                    &mut data,
                                    &mut nbytes,
                                    &STRUCTURED_CLONE_CALLBACKS,
                                    ptr::null_mut(),
                                    HandleValue::undefined())
        };
        if !result {
            unsafe {
                JS_ClearPendingException(cx);
            }
            return Err(Error::DataClone);
        }
        Ok(StructuredCloneData::Struct(data, nbytes))
    }

    /// Converts a StructuredCloneData to Vec<u8> for inter-thread sharing
    pub fn move_to_arraybuffer(self) -> Vec<u8> {
        match self {
            StructuredCloneData::Struct(data, nbytes) => {
                unsafe {
                    slice::from_raw_parts(data as *mut u8, nbytes).to_vec()
                }
            }
            StructuredCloneData::Vector(msg) => msg
        }
    }

    /// Reads a structured clone.
    ///
    /// Panics if `JS_ReadStructuredClone` fails.
    fn read_clone(global: &GlobalScope,
                  data: *mut u64,
                  nbytes: size_t,
                  rval: MutableHandleValue) {
        let cx = global.get_cx();
        let globalhandle = global.reflector().get_jsobject();
        let _ac = JSAutoCompartment::new(cx, globalhandle.get());
        unsafe {
            assert!(JS_ReadStructuredClone(cx,
                                           data,
                                           nbytes,
                                           JS_STRUCTURED_CLONE_VERSION,
                                           rval,
                                           &STRUCTURED_CLONE_CALLBACKS,
                                           ptr::null_mut()));
        }
    }

    /// Thunk for the actual `read_clone` method. Resolves proper variant for read_clone.
    pub fn read(self, global: &GlobalScope, rval: MutableHandleValue) {
        match self {
            StructuredCloneData::Vector(mut vec_msg) => {
                let nbytes = vec_msg.len();
                let data = vec_msg.as_mut_ptr() as *mut u64;
                StructuredCloneData::read_clone(global, data, nbytes, rval);
            }
            StructuredCloneData::Struct(data, nbytes) => StructuredCloneData::read_clone(global, data, nbytes, rval)
        }
    }
}

unsafe impl Send for StructuredCloneData {}
<commit_msg>use a structured clone holder to store rooted clones<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

//! This module implements structured cloning, as defined by [HTML]
//! (https://html.spec.whatwg.org/multipage/#safe-passing-of-structured-data).

use dom::bindings::conversions::root_from_handleobject;
use dom::bindings::error::{Error, Fallible};
use dom::bindings::reflector::DomObject;
use dom::bindings::root::DomRoot;
use dom::blob::{Blob, BlobImpl};
use dom::globalscope::GlobalScope;
use js::jsapi::{JSAutoCompartment, JSContext};
use js::jsapi::{JSStructuredCloneCallbacks, JSStructuredCloneReader, JSStructuredCloneWriter};
use js::jsapi::{JS_ClearPendingException, JSObject};
use js::jsapi::{JS_ReadBytes, JS_WriteBytes};
use js::jsapi::{JS_ReadUint32Pair, JS_WriteUint32Pair};
use js::jsapi::HandleObject as RawHandleObject;
use js::jsapi::JS_STRUCTURED_CLONE_VERSION;
use js::jsapi::MutableHandleObject as RawMutableHandleObject;
use js::jsapi::TransferableOwnership;
use js::rust::{Handle, HandleValue, MutableHandleValue};
use js::rust::wrappers::{JS_WriteStructuredClone, JS_ReadStructuredClone};
use libc::size_t;
use std::os::raw;
use std::ptr;
use std::slice;

// TODO: Should we add Min and Max const to https://github.com/servo/rust-mozjs/blob/master/src/consts.rs?
// TODO: Determine for sure which value Min and Max should have.
// NOTE: Current values found at https://dxr.mozilla.org/mozilla-central/
// rev/ff04d410e74b69acfab17ef7e73e7397602d5a68/js/public/StructuredClone.h#323
#[repr(u32)]
enum StructuredCloneTags {
    /// To support additional types, add new tags with values incremented from the last one before Max.
    Min = 0xFFFF8000,
    DomBlob = 0xFFFF8001,
    Max = 0xFFFFFFFF,
}

#[cfg(target_pointer_width = "64")]
unsafe fn write_length(w: *mut JSStructuredCloneWriter,
                       length: usize) {
  let high: u32 = (length >> 32) as u32;
  let low: u32 = length as u32;
  assert!(JS_WriteUint32Pair(w, high, low));
}

#[cfg(target_pointer_width = "32")]
unsafe fn write_length(w: *mut JSStructuredCloneWriter,
                       length: usize) {
  assert!(JS_WriteUint32Pair(w, length as u32, 0));
}

#[cfg(target_pointer_width = "64")]
unsafe fn read_length(r: *mut JSStructuredCloneReader)
                      -> usize {
  let mut high: u32 = 0;
  let mut low: u32 = 0;
  assert!(JS_ReadUint32Pair(r, &mut high as *mut u32, &mut low as *mut u32));
  return (low << high) as usize;
}

#[cfg(target_pointer_width = "32")]
unsafe fn read_length(r: *mut JSStructuredCloneReader)
                      -> usize {
  let mut length: u32 = 0;
  let mut zero: u32 = 0;
  assert!(JS_ReadUint32Pair(r, &mut length as *mut u32, &mut zero as *mut u32));
  return length as usize;
}

struct StructuredCloneWriter {
    w: *mut JSStructuredCloneWriter,
}

impl StructuredCloneWriter {
    unsafe fn write_slice(&self, v: &[u8]) {
        let type_length = v.len();
        write_length(self.w, type_length);
        assert!(JS_WriteBytes(self.w, v.as_ptr() as *const raw::c_void, type_length));
    }
    unsafe fn write_str(&self, s: &str) {
        self.write_slice(s.as_bytes());
    }
}

struct StructuredCloneReader {
    r: *mut JSStructuredCloneReader,
}

impl StructuredCloneReader {
    unsafe fn read_bytes(&self) -> Vec<u8> {
        let mut bytes = vec![0u8; read_length(self.r)];
        let blob_length = bytes.len();
        assert!(JS_ReadBytes(self.r, bytes.as_mut_ptr() as *mut raw::c_void, blob_length));
        return bytes;
    }
    unsafe fn read_str(&self) -> String {
        let str_buffer = self.read_bytes();
        return String::from_utf8_unchecked(str_buffer);
    }
}

unsafe fn read_blob(cx: *mut JSContext,
                    r: *mut JSStructuredCloneReader,
                    sc_holder: &mut StructuredCloneHolder)
                    -> *mut JSObject {
    let structured_reader = StructuredCloneReader { r: r };
    let blob_buffer = structured_reader.read_bytes();
    let type_str = structured_reader.read_str();
    let target_global = GlobalScope::from_context(cx);
    let blob = Blob::new(&target_global, BlobImpl::new_from_bytes(blob_buffer), type_str);
    let js_object = blob.reflector().get_jsobject().get();
    sc_holder.blob = Some(blob);
    js_object
}

unsafe fn write_blob(blob: DomRoot<Blob>,
                     w: *mut JSStructuredCloneWriter)
                     -> Result<(), ()> {
    let structured_writer = StructuredCloneWriter { w: w };
    let blob_vec = blob.get_bytes()?;
    assert!(JS_WriteUint32Pair(w, StructuredCloneTags::DomBlob as u32, 0));
    structured_writer.write_slice(&blob_vec);
    structured_writer.write_str(&blob.type_string());
    return Ok(())
}

unsafe extern "C" fn read_callback(cx: *mut JSContext,
                                   r: *mut JSStructuredCloneReader,
                                   tag: u32,
                                   _data: u32,
                                   closure: *mut raw::c_void)
                                   -> *mut JSObject {
    assert!(tag < StructuredCloneTags::Max as u32, "tag should be lower than StructuredCloneTags::Max");
    assert!(tag > StructuredCloneTags::Min as u32, "tag should be higher than StructuredCloneTags::Min");
    if tag == StructuredCloneTags::DomBlob as u32 {
        return read_blob(cx, r, &mut *(closure as *mut StructuredCloneHolder))
    }
    return ptr::null_mut()
}

unsafe extern "C" fn write_callback(_cx: *mut JSContext,
                                    w: *mut JSStructuredCloneWriter,
                                    obj: RawHandleObject,
                                    _closure: *mut raw::c_void)
                                    -> bool {
    if let Ok(blob) = root_from_handleobject::<Blob>(Handle::from_raw(obj)) {
        return write_blob(blob, w).is_ok()
    }
    return false
}

unsafe extern "C" fn read_transfer_callback(_cx: *mut JSContext,
                                            _r: *mut JSStructuredCloneReader,
                                            _tag: u32,
                                            _content: *mut raw::c_void,
                                            _extra_data: u64,
                                            _closure: *mut raw::c_void,
                                            _return_object: RawMutableHandleObject)
                                            -> bool {
    false
}

unsafe extern "C" fn write_transfer_callback(_cx: *mut JSContext,
                                             _obj: RawHandleObject,
                                             _closure: *mut raw::c_void,
                                             _tag: *mut u32,
                                             _ownership: *mut TransferableOwnership,
                                             _content:  *mut *mut raw::c_void,
                                             _extra_data: *mut u64)
                                             -> bool {
    false
}

unsafe extern "C" fn free_transfer_callback(_tag: u32,
                                            _ownership: TransferableOwnership,
                                            _content: *mut raw::c_void,
                                            _extra_data: u64,
                                            _closure: *mut raw::c_void) {
}

unsafe extern "C" fn report_error_callback(_cx: *mut JSContext, _errorid: u32) {
}

static STRUCTURED_CLONE_CALLBACKS: JSStructuredCloneCallbacks = JSStructuredCloneCallbacks {
    read: Some(read_callback),
    write: Some(write_callback),
    reportError: Some(report_error_callback),
    readTransfer: Some(read_transfer_callback),
    writeTransfer: Some(write_transfer_callback),
    freeTransfer: Some(free_transfer_callback),
};

struct StructuredCloneHolder {
    blob: Option<DomRoot<Blob>>
}

/// A buffer for a structured clone.
pub enum StructuredCloneData {
    /// A non-serializable (default) variant
    Struct(*mut u64, size_t),
    /// A variant that can be serialized
    Vector(Vec<u8>)
}

impl StructuredCloneData {
    /// Writes a structured clone. Returns a `DataClone` error if that fails.
    pub fn write(cx: *mut JSContext, message: HandleValue) -> Fallible<StructuredCloneData> {
        let mut data = ptr::null_mut();
        let mut nbytes = 0;
        let result = unsafe {
            JS_WriteStructuredClone(cx,
                                    message,
                                    &mut data,
                                    &mut nbytes,
                                    &STRUCTURED_CLONE_CALLBACKS,
                                    ptr::null_mut(),
                                    HandleValue::undefined())
        };
        if !result {
            unsafe {
                JS_ClearPendingException(cx);
            }
            return Err(Error::DataClone);
        }
        Ok(StructuredCloneData::Struct(data, nbytes))
    }

    /// Converts a StructuredCloneData to Vec<u8> for inter-thread sharing
    pub fn move_to_arraybuffer(self) -> Vec<u8> {
        match self {
            StructuredCloneData::Struct(data, nbytes) => {
                unsafe {
                    slice::from_raw_parts(data as *mut u8, nbytes).to_vec()
                }
            }
            StructuredCloneData::Vector(msg) => msg
        }
    }

    /// Reads a structured clone.
    ///
    /// Panics if `JS_ReadStructuredClone` fails.
    fn read_clone(global: &GlobalScope,
                  data: *mut u64,
                  nbytes: size_t,
                  rval: MutableHandleValue) {
        let cx = global.get_cx();
        let globalhandle = global.reflector().get_jsobject();
        let _ac = JSAutoCompartment::new(cx, globalhandle.get());
        let mut sc_holder = StructuredCloneHolder { blob: None };
        let sc_holder_ptr = &mut sc_holder as *mut _;
        unsafe {
            assert!(JS_ReadStructuredClone(cx,
                                           data,
                                           nbytes,
                                           JS_STRUCTURED_CLONE_VERSION,
                                           rval,
                                           &STRUCTURED_CLONE_CALLBACKS,
                                           sc_holder_ptr as *mut raw::c_void));
        }
    }

    /// Thunk for the actual `read_clone` method. Resolves proper variant for read_clone.
    pub fn read(self, global: &GlobalScope, rval: MutableHandleValue) {
        match self {
            StructuredCloneData::Vector(mut vec_msg) => {
                let nbytes = vec_msg.len();
                let data = vec_msg.as_mut_ptr() as *mut u64;
                StructuredCloneData::read_clone(global, data, nbytes, rval);
            }
            StructuredCloneData::Struct(data, nbytes) => StructuredCloneData::read_clone(global, data, nbytes, rval)
        }
    }
}

unsafe impl Send for StructuredCloneData {}
<|endoftext|>


<commit_before>// Copyright 2012-2013 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.

use trans::cabi::FnType;
use trans::cabi_arm;
use trans::context::CrateContext;
use trans::type_::Type;

pub fn compute_abi_info(ccx: &CrateContext,
                        atys: &[Type],
                        rty: Type,
                        ret_def: bool) -> FnType {
    cabi_arm::compute_abi_info(ccx, atys, rty, ret_def,
                               cabi_arm::Flavor::General)
}
<commit_msg>Fix the asmjs ABI<commit_after>// Copyright 2012-2013 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_upper_case_globals)]

use llvm::{Struct, Array, Attribute};
use trans::cabi::{FnType, ArgType};
use trans::context::CrateContext;
use trans::type_::Type;

// Data layout: e-p:32:32-i64:64-v128:32:128-n32-S128

// See the https://github.com/kripken/emscripten-fastcomp-clang repository.
// The class `EmscriptenABIInfo` in `/lib/CodeGen/TargetInfo.cpp` contains the ABI definitions.

fn classify_ret_ty(ccx: &CrateContext, ty: Type) -> ArgType {
    match ty.kind() {
        Struct => {
            let field_types = ty.field_types();
            if field_types.len() == 1 {
                ArgType::direct(ty, Some(field_types[0]), None, None)
            } else {
                ArgType::indirect(ty, Some(Attribute::StructRet))
            }
        },
        Array => {
            ArgType::indirect(ty, Some(Attribute::StructRet))
        },
        _ => {
            let attr = if ty == Type::i1(ccx) { Some(Attribute::ZExt) } else { None };
            ArgType::direct(ty, None, None, attr)
        }
    }
}

fn classify_arg_ty(ccx: &CrateContext, ty: Type) -> ArgType {
    if ty.is_aggregate() {
        ArgType::indirect(ty, Some(Attribute::ByVal))
    } else {
        let attr = if ty == Type::i1(ccx) { Some(Attribute::ZExt) } else { None };
        ArgType::direct(ty, None, None, attr)
    }
}

pub fn compute_abi_info(ccx: &CrateContext,
                        atys: &[Type],
                        rty: Type,
                        ret_def: bool) -> FnType {
    let mut arg_tys = Vec::new();
    for &aty in atys {
        let ty = classify_arg_ty(ccx, aty);
        arg_tys.push(ty);
    }

    let ret_ty = if ret_def {
        classify_ret_ty(ccx, rty)
    } else {
        ArgType::direct(Type::void(ccx), None, None, None)
    };

    return FnType {
        arg_tys: arg_tys,
        ret_ty: ret_ty,
    };
}
<|endoftext|>


<commit_before>/*
!poll #announcements Poll text goes here!
:one: Option one
:two: Option two

From @Bot in #announcements
Poll from @jkcclemens:
Poll text goes here!
:one: – Option one
:two: – Option two

@Bot reacts to the message with all the options

!poll #general Some other poll
Auto-generate options
No custom emoji

!poll #channel Another custom poll
:thumbsup: Yes
:thumbsdown: No
*/

use LalafellBot;
use commands::*;

use discord::model::{ChannelId, MessageId, ReactionEmoji};
use discord::builders::EmbedBuilder;

use std::sync::Arc;

const USAGE: &'static str = "!pollresults <channel> <message id>";
const VALID_EMOJI: &'static [&'static str] = &[
  "1⃣",
  "2⃣",
  "3⃣",
  "4⃣",
  "5⃣",
  "6⃣",
  "7⃣",
  "8⃣",
  "9⃣"
];

pub struct PollResultsCommand {
  bot: Arc<LalafellBot>
}

impl PollResultsCommand {
  pub fn new(bot: Arc<LalafellBot>) -> PollResultsCommand {
    PollResultsCommand {
      bot: bot
    }
  }
}

impl<'a> Command<'a> for PollResultsCommand {
  fn run(&self, _: &Message, params: &[&str]) -> CommandResult<'a> {
    if params.len() < 2 {
      return Err(ExternalCommandFailure::default()
        .message(|e: EmbedBuilder| e
          .title("Not enough parameters.")
          .description(USAGE))
        .wrap());
    }
    let channel = params[0];
    let channel = if channel.starts_with("<#") && channel.ends_with('>') {
      &channel[2..channel.len() - 1]
    } else {
      channel
    };
    let channel_id = match channel.parse::<u64>() {
      Ok(u) => ChannelId(u),
      Err(_) => return Err(ExternalCommandFailure::default()
                  .message(|e: EmbedBuilder| e
                    .description("Invalid channel."))
                  .wrap())
    };
    let message_id = match params[1].parse::<u64>() {
      Ok(u) => MessageId(u),
      Err(_) => return Err(ExternalCommandFailure::default()
                  .message(|e: EmbedBuilder| e
                    .description("Invalid message ID."))
                  .wrap())
    };
    let message = match self.bot.discord.get_message(channel_id, message_id) {
      Ok(m) => m,
      Err(e) => { println!("{:#?}", e); return Err(ExternalCommandFailure::default()
                  .message(|e: EmbedBuilder| e
                    .description("Could not get that message."))
                  .wrap());}
    };
    let mut reactions: Vec<(&String, u64)> = message.reactions.iter()
      .map(|r| match r.emoji {
        ReactionEmoji::Unicode(ref s) if VALID_EMOJI.contains(&s.as_str()) => {
          let count = if r.me {
            r.count - 1
          } else {
            r.count
          };
          Some((s, count))
        },
        _ => None
      })
      .filter(|x| x.is_some())
      .map(|x| x.unwrap())
      .collect();
    reactions.sort_by_key(|x| !x.1);
    let votes = reactions.iter()
      .map(|&(emoji, count)| format!("{} with {} vote{}", emoji, count, if count == 1 { "" } else { "s" }))
      .collect::<Vec<_>>()
      .join("\n");
    Ok(CommandSuccess::default()
      .message(move |e: EmbedBuilder| e.description(&votes)))
  }
}
<commit_msg>fix: only count reactions the bot has added<commit_after>/*
!poll #announcements Poll text goes here!
:one: Option one
:two: Option two

From @Bot in #announcements
Poll from @jkcclemens:
Poll text goes here!
:one: – Option one
:two: – Option two

@Bot reacts to the message with all the options

!poll #general Some other poll
Auto-generate options
No custom emoji

!poll #channel Another custom poll
:thumbsup: Yes
:thumbsdown: No
*/

use LalafellBot;
use commands::*;

use discord::model::{ChannelId, MessageId, ReactionEmoji};
use discord::builders::EmbedBuilder;

use std::sync::Arc;

const USAGE: &'static str = "!pollresults <channel> <message id>";
const VALID_EMOJI: &'static [&'static str] = &[
  "1⃣",
  "2⃣",
  "3⃣",
  "4⃣",
  "5⃣",
  "6⃣",
  "7⃣",
  "8⃣",
  "9⃣"
];

pub struct PollResultsCommand {
  bot: Arc<LalafellBot>
}

impl PollResultsCommand {
  pub fn new(bot: Arc<LalafellBot>) -> PollResultsCommand {
    PollResultsCommand {
      bot: bot
    }
  }
}

impl<'a> Command<'a> for PollResultsCommand {
  fn run(&self, _: &Message, params: &[&str]) -> CommandResult<'a> {
    if params.len() < 2 {
      return Err(ExternalCommandFailure::default()
        .message(|e: EmbedBuilder| e
          .title("Not enough parameters.")
          .description(USAGE))
        .wrap());
    }
    let channel = params[0];
    let channel = if channel.starts_with("<#") && channel.ends_with('>') {
      &channel[2..channel.len() - 1]
    } else {
      channel
    };
    let channel_id = match channel.parse::<u64>() {
      Ok(u) => ChannelId(u),
      Err(_) => return Err(ExternalCommandFailure::default()
                  .message(|e: EmbedBuilder| e
                    .description("Invalid channel."))
                  .wrap())
    };
    let message_id = match params[1].parse::<u64>() {
      Ok(u) => MessageId(u),
      Err(_) => return Err(ExternalCommandFailure::default()
                  .message(|e: EmbedBuilder| e
                    .description("Invalid message ID."))
                  .wrap())
    };
    let message = match self.bot.discord.get_message(channel_id, message_id) {
      Ok(m) => m,
      Err(e) => { println!("{:#?}", e); return Err(ExternalCommandFailure::default()
                  .message(|e: EmbedBuilder| e
                    .description("Could not get that message."))
                  .wrap());}
    };
    let mut reactions: Vec<(&String, u64)> = message.reactions.iter()
      .map(|r| match r.emoji {
        ReactionEmoji::Unicode(ref s) if VALID_EMOJI.contains(&s.as_str()) && r.me => Some((s, r.count - 1)),
        _ => None
      })
      .filter(|x| x.is_some())
      .map(|x| x.unwrap())
      .collect();
    reactions.sort_by_key(|x| !x.1);
    let votes = reactions.iter()
      .map(|&(emoji, count)| format!("{} with {} vote{}", emoji, count, if count == 1 { "" } else { "s" }))
      .collect::<Vec<_>>()
      .join("\n");
    Ok(CommandSuccess::default()
      .message(move |e: EmbedBuilder| e.description(&votes)))
  }
}
<|endoftext|>


<commit_before>extern crate scirust;
#[cfg(not(test))]
fn main(){
    /*
    use scirust::api::*;
    let a = matrix_cw_f64(2,2, [1., 4., 2., 8.].as_slice());
    println!("{}", a);
    let b = vector_f64([3.0, 6.0].as_slice());
    let result = GaussElimination::new(&a, &b).solve();
    match result {
        Ok(x) => println!("{}", x),
        Err(e) => println!("{}", e),
    }
    let m = matrix_cw_c64(2,2, [].as_slice());
    println!("{}", m);
    */
}
<commit_msg>restored main example<commit_after>extern crate scirust;
#[cfg(not(test))]
fn main(){
    use scirust::api::*;
    let a = matrix_cw_f64(2,2, &[1., 4., 2., 8.]);
    println!("{}", a);
    let b = vector_f64(&[3.0, 6.0]);
    let result = GaussElimination::new(&a, &b).solve();
    match result {
        Ok(x) => println!("{}", x),
        Err(e) => println!("{}", e),
    }
    let m = matrix_cw_c64(2,2, &[]);
    println!("{}", m);
}
<|endoftext|>


<commit_before>//! Runs rustfmt on the repository.

use crate::Build;
use build_helper::{output, t};
use ignore::WalkBuilder;
use std::path::Path;
use std::process::{Command, Stdio};

fn rustfmt(src: &Path, rustfmt: &Path, path: &Path, check: bool) {
    let mut cmd = Command::new(&rustfmt);
    // avoid the submodule config paths from coming into play,
    // we only allow a single global config for the workspace for now
    cmd.arg("--config-path").arg(&src.canonicalize().unwrap());
    cmd.arg("--edition").arg("2018");
    cmd.arg("--unstable-features");
    cmd.arg("--skip-children");
    if check {
        cmd.arg("--check");
    }
    cmd.arg(&path);
    let cmd_debug = format!("{:?}", cmd);
    let status = cmd.status().expect("executing rustfmt");
    if !status.success() {
        eprintln!(
            "Running `{}` failed.\nIf you're running `tidy`, \
            try again with `--bless`. Or, if you just want to format \
            code, run `./x.py fmt` instead.",
            cmd_debug,
        );
        std::process::exit(1);
    }
}

#[derive(serde::Deserialize)]
struct RustfmtConfig {
    ignore: Vec<String>,
}

pub fn format(build: &Build, check: bool) {
    if build.config.dry_run {
        return;
    }
    let mut builder = ignore::types::TypesBuilder::new();
    builder.add_defaults();
    builder.select("rust");
    let matcher = builder.build().unwrap();
    let rustfmt_config = build.src.join("rustfmt.toml");
    if !rustfmt_config.exists() {
        eprintln!("Not running formatting checks; rustfmt.toml does not exist.");
        eprintln!("This may happen in distributed tarballs.");
        return;
    }
    let rustfmt_config = t!(std::fs::read_to_string(&rustfmt_config));
    let rustfmt_config: RustfmtConfig = t!(toml::from_str(&rustfmt_config));
    let mut ignore_fmt = ignore::overrides::OverrideBuilder::new(&build.src);
    for ignore in rustfmt_config.ignore {
        ignore_fmt.add(&format!("!{}", ignore)).expect(&ignore);
    }
    let git_available = match Command::new("git")
        .arg("--version")
        .stdout(Stdio::null())
        .stderr(Stdio::null())
        .status()
    {
        Ok(status) => status.success(),
        Err(_) => false,
    };
    if git_available {
        let in_working_tree = match Command::new("git")
            .arg("rev-parse")
            .arg("--is-inside-work-tree")
            .stdout(Stdio::null())
            .stderr(Stdio::null())
            .status()
        {
            Ok(status) => status.success(),
            Err(_) => false,
        };
        if in_working_tree {
            let untracked_paths_output = output(
                Command::new("git")
                    .arg("status")
                    .arg("--porcelain")
                    .arg("--untracked-files=normal"),
            );
            let untracked_paths = untracked_paths_output
                .lines()
                .filter(|entry| entry.starts_with("??"))
                .map(|entry| {
                    entry.split(' ').nth(1).expect("every git status entry should list a path")
                });
            for untracked_path in untracked_paths {
                eprintln!("skip untracked path {} during rustfmt invocations", untracked_path);
                ignore_fmt.add(&format!("!{}", untracked_path)).expect(&untracked_path);
            }
        } else {
            eprintln!("Not in git tree. Skipping git-aware format checks");
        }
    } else {
        eprintln!("Could not find usable git. Skipping git-aware format checks");
    }
    let ignore_fmt = ignore_fmt.build().unwrap();

    let rustfmt_path = build.config.initial_rustfmt.as_ref().unwrap_or_else(|| {
        eprintln!("./x.py fmt is not supported on this channel");
        std::process::exit(1);
    });
    let src = &build.src;
    let walker = WalkBuilder::new(src).types(matcher).overrides(ignore_fmt).build_parallel();
    walker.run(|| {
        Box::new(move |entry| {
            let entry = t!(entry);
            if entry.file_type().map_or(false, |t| t.is_file()) {
                rustfmt(src, &rustfmt_path, &entry.path(), check);
            }
            ignore::WalkState::Continue
        })
    });
}
<commit_msg>parallelize x.py test tidy<commit_after>//! Runs rustfmt on the repository.

use crate::Build;
use build_helper::{output, t};
use ignore::WalkBuilder;
use std::collections::VecDeque;
use std::path::{Path, PathBuf};
use std::process::{Command, Stdio};
use std::sync::mpsc::SyncSender;

fn rustfmt(src: &Path, rustfmt: &Path, paths: &[PathBuf], check: bool) -> Box<impl FnMut()> {
    let mut cmd = Command::new(&rustfmt);
    // avoid the submodule config paths from coming into play,
    // we only allow a single global config for the workspace for now
    cmd.arg("--config-path").arg(&src.canonicalize().unwrap());
    cmd.arg("--edition").arg("2018");
    cmd.arg("--unstable-features");
    cmd.arg("--skip-children");
    if check {
        cmd.arg("--check");
    }
    cmd.args(paths);
    let cmd_debug = format!("{:?}", cmd);
    let mut cmd = cmd.spawn().expect("running rustfmt");
    // poor man's async: return a box that'll wait for rustfmt's completion
    Box::new(move || {
        let status = cmd.wait().unwrap();
        if !status.success() {
            eprintln!(
                "Running `{}` failed.\nIf you're running `tidy`, \
                        try again with `--bless`. Or, if you just want to format \
                        code, run `./x.py fmt` instead.",
                cmd_debug,
            );
            std::process::exit(1);
        }
    })
}

#[derive(serde::Deserialize)]
struct RustfmtConfig {
    ignore: Vec<String>,
}

pub fn format(build: &Build, check: bool) {
    if build.config.dry_run {
        return;
    }
    let mut builder = ignore::types::TypesBuilder::new();
    builder.add_defaults();
    builder.select("rust");
    let matcher = builder.build().unwrap();
    let rustfmt_config = build.src.join("rustfmt.toml");
    if !rustfmt_config.exists() {
        eprintln!("Not running formatting checks; rustfmt.toml does not exist.");
        eprintln!("This may happen in distributed tarballs.");
        return;
    }
    let rustfmt_config = t!(std::fs::read_to_string(&rustfmt_config));
    let rustfmt_config: RustfmtConfig = t!(toml::from_str(&rustfmt_config));
    let mut ignore_fmt = ignore::overrides::OverrideBuilder::new(&build.src);
    for ignore in rustfmt_config.ignore {
        ignore_fmt.add(&format!("!{}", ignore)).expect(&ignore);
    }
    let git_available = match Command::new("git")
        .arg("--version")
        .stdout(Stdio::null())
        .stderr(Stdio::null())
        .status()
    {
        Ok(status) => status.success(),
        Err(_) => false,
    };
    if git_available {
        let in_working_tree = match Command::new("git")
            .arg("rev-parse")
            .arg("--is-inside-work-tree")
            .stdout(Stdio::null())
            .stderr(Stdio::null())
            .status()
        {
            Ok(status) => status.success(),
            Err(_) => false,
        };
        if in_working_tree {
            let untracked_paths_output = output(
                Command::new("git")
                    .arg("status")
                    .arg("--porcelain")
                    .arg("--untracked-files=normal"),
            );
            let untracked_paths = untracked_paths_output
                .lines()
                .filter(|entry| entry.starts_with("??"))
                .map(|entry| {
                    entry.split(' ').nth(1).expect("every git status entry should list a path")
                });
            for untracked_path in untracked_paths {
                eprintln!("skip untracked path {} during rustfmt invocations", untracked_path);
                ignore_fmt.add(&format!("!{}", untracked_path)).expect(&untracked_path);
            }
        } else {
            eprintln!("Not in git tree. Skipping git-aware format checks");
        }
    } else {
        eprintln!("Could not find usable git. Skipping git-aware format checks");
    }
    let ignore_fmt = ignore_fmt.build().unwrap();

    let rustfmt_path = build
        .config
        .initial_rustfmt
        .as_ref()
        .unwrap_or_else(|| {
            eprintln!("./x.py fmt is not supported on this channel");
            std::process::exit(1);
        })
        .to_path_buf();
    let src = build.src.clone();
    let (tx, rx): (SyncSender<PathBuf>, _) = std::sync::mpsc::sync_channel(128);
    let walker =
        WalkBuilder::new(src.clone()).types(matcher).overrides(ignore_fmt).build_parallel();

    // there is a lot of blocking involved in spawning a child process and reading files to format.
    // spawn more processes than available cores to keep the CPU busy
    let max_processes = num_cpus::get() * 2;

    // spawn child processes on a separate thread so we can batch entries we have received from ignore
    let thread = std::thread::spawn(move || {
        let mut children = VecDeque::new();
        while let Ok(path) = rx.recv() {
            // try getting a few more paths from the channel to amortize the overhead of spawning processes
            let paths: Vec<_> = rx.try_iter().take(7).chain(std::iter::once(path)).collect();

            let child = rustfmt(&src, &rustfmt_path, paths.as_slice(), check);
            children.push_back(child);

            if children.len() > max_processes {
                // await oldest child
                children.pop_front().unwrap()();
            }
        }

        // await remaining children
        for mut child in children {
            child();
        }
    });

    walker.run(|| {
        let tx = tx.clone();
        Box::new(move |entry| {
            let entry = t!(entry);
            if entry.file_type().map_or(false, |t| t.is_file()) {
                t!(tx.send(entry.into_path()));
            }
            ignore::WalkState::Continue
        })
    });

    drop(tx);

    thread.join().unwrap();
}
<|endoftext|>


<commit_before>extern crate glib;
extern crate cairo;
extern crate cairo_sys;
extern crate libc;

use self::glib::translate::*;

use node::RsvgNode;
use path_builder::RsvgPathBuilder;
use state::RsvgState;

pub enum RsvgDrawingCtx {}

extern "C" {
    fn rsvg_drawing_ctx_get_dpi (draw_ctx: *const RsvgDrawingCtx,
                                 out_dpi_x: *mut f64,
                                 out_dpi_y: *mut f64);

    fn rsvg_drawing_ctx_get_normalized_font_size (draw_ctx: *const RsvgDrawingCtx) -> f64;

    fn rsvg_drawing_ctx_get_view_box_size (draw_ctx: *const RsvgDrawingCtx,
                                           out_x: *mut f64,
                                           out_y: *mut f64);

    fn rsvg_drawing_ctx_push_view_box (draw_ctx: *const RsvgDrawingCtx,
                                       width:     f64,
                                       height:    f64);

    fn rsvg_drawing_ctx_pop_view_box (draw_ctx: *const RsvgDrawingCtx);

    fn rsvg_drawing_ctx_acquire_node (draw_ctx: *const RsvgDrawingCtx,
                                      url:      *const libc::c_char) -> *mut RsvgNode;

    fn rsvg_drawing_ctx_release_node (draw_ctx: *const RsvgDrawingCtx,
                                      node:     *mut RsvgNode);

    fn rsvg_drawing_ctx_get_current_state_affine (draw_ctx: *const RsvgDrawingCtx) -> cairo::Matrix;

    fn rsvg_drawing_ctx_set_current_state_affine (draw_ctx: *const RsvgDrawingCtx,
                                                  affine:   *const cairo::Matrix);

    fn rsvg_drawing_ctx_add_clipping_rect (draw_ctx: *const RsvgDrawingCtx,
                                           x: f64,
                                           y: f64,
                                           w: f64,
                                           h: f64);

    fn rsvg_current_state (draw_ctx: *const RsvgDrawingCtx) -> *mut RsvgState;
    fn rsvg_state_new () -> *mut RsvgState;
    fn rsvg_state_reinit (state: *mut RsvgState);
    fn rsvg_state_reconstruct (state: *mut RsvgState, node: *const RsvgNode);
    fn rsvg_state_is_overflow (state: *const RsvgState) -> bool;

    fn rsvg_state_push (draw_ctx: *const RsvgDrawingCtx);
    fn rsvg_state_pop (draw_ctx: *const RsvgDrawingCtx);

    fn rsvg_state_reinherit_top (draw_ctx: *const RsvgDrawingCtx,
                                 state: *mut RsvgState,
                                 dominate: libc::c_int);

    fn rsvg_push_discrete_layer (draw_ctx: *const RsvgDrawingCtx);
    fn rsvg_pop_discrete_layer (draw_ctx: *const RsvgDrawingCtx);

    fn rsvg_render_path_builder (draw_ctx: *const RsvgDrawingCtx,
                                 builder: *const RsvgPathBuilder);

    fn rsvg_cairo_get_cairo_context (draw_ctx: *const RsvgDrawingCtx) -> *mut cairo_sys::cairo_t;
    fn rsvg_cairo_set_cairo_context (draw_ctx: *const RsvgDrawingCtx, cr: *const cairo_sys::cairo_t);

    fn _rsvg_node_draw_children (node: *const RsvgNode, draw_ctx: *const RsvgDrawingCtx, dominate: libc::c_int);
}

pub fn get_dpi (draw_ctx: *const RsvgDrawingCtx) -> (f64, f64) {
    let mut dpi_x: f64 = 0.0;
    let mut dpi_y: f64 = 0.0;

    unsafe { rsvg_drawing_ctx_get_dpi (draw_ctx, &mut dpi_x, &mut dpi_y); }

    (dpi_x, dpi_y)
}

pub fn get_normalized_font_size (draw_ctx: *const RsvgDrawingCtx) -> f64 {
    unsafe { rsvg_drawing_ctx_get_normalized_font_size (draw_ctx) }
}

pub fn get_view_box_size (draw_ctx: *const RsvgDrawingCtx) -> (f64, f64) {
    let mut w: f64 = 0.0;
    let mut h: f64 = 0.0;

    unsafe { rsvg_drawing_ctx_get_view_box_size (draw_ctx, &mut w, &mut h); }

    (w, h)
}

pub fn push_view_box (draw_ctx: *const RsvgDrawingCtx,
                      width:     f64,
                      height:    f64)
{
    unsafe { rsvg_drawing_ctx_push_view_box (draw_ctx, width, height); }
}

pub fn pop_view_box (draw_ctx: *const RsvgDrawingCtx) {
    unsafe { rsvg_drawing_ctx_pop_view_box (draw_ctx); }
}

pub fn acquire_node (draw_ctx: *const RsvgDrawingCtx,
                     url:      &str) -> *mut RsvgNode {
    unsafe { rsvg_drawing_ctx_acquire_node (draw_ctx, str::to_glib_none (url).0) }
}

pub fn release_node (draw_ctx: *const RsvgDrawingCtx,
                     node:     *mut RsvgNode) {
    unsafe { rsvg_drawing_ctx_release_node (draw_ctx, node); }
}

pub fn state_reinherit_top (draw_ctx: *const RsvgDrawingCtx,
                            state: *mut RsvgState,
                            dominate: i32) {
    unsafe { rsvg_state_reinherit_top (draw_ctx, state, dominate); }
}

pub fn push_discrete_layer (draw_ctx: *const RsvgDrawingCtx) {
    unsafe { rsvg_push_discrete_layer (draw_ctx); }
}

pub fn pop_discrete_layer (draw_ctx: *const RsvgDrawingCtx) {
    unsafe { rsvg_pop_discrete_layer (draw_ctx); }
}

pub fn render_path_builder (draw_ctx: *const RsvgDrawingCtx,
                            builder: &RsvgPathBuilder) {
    unsafe { rsvg_render_path_builder (draw_ctx, builder); }
}

pub fn get_cairo_context (draw_ctx: *const RsvgDrawingCtx) -> cairo::Context {
    unsafe {
        let raw_cr = rsvg_cairo_get_cairo_context (draw_ctx);

        let cr = cairo::Context::from_glib_none (raw_cr);

        cr
    }
}

pub fn set_cairo_context (draw_ctx: *const RsvgDrawingCtx, cr: &cairo::Context) {
    unsafe {
        let raw_cr = cr.to_glib_none ().0;

        rsvg_cairo_set_cairo_context (draw_ctx, raw_cr);
    }
}

pub fn get_current_state_affine (draw_ctx: *const RsvgDrawingCtx) -> cairo::Matrix {
    unsafe {
        rsvg_drawing_ctx_get_current_state_affine (draw_ctx)
    }
}

pub fn set_current_state_affine (draw_ctx: *const RsvgDrawingCtx, affine: cairo::Matrix) {
    unsafe {
        rsvg_drawing_ctx_set_current_state_affine (draw_ctx, &affine);
    }
}

pub fn add_clipping_rect (draw_ctx: *const RsvgDrawingCtx,
                          x: f64,
                          y: f64,
                          w: f64,
                          h: f64) {
    unsafe { rsvg_drawing_ctx_add_clipping_rect (draw_ctx, x, y, w, h); }
}

pub fn get_current_state (draw_ctx: *const RsvgDrawingCtx) -> *mut RsvgState {
    unsafe { rsvg_current_state (draw_ctx) }
}

pub fn state_new () -> *mut RsvgState {
    unsafe { rsvg_state_new () }
}

pub fn state_reinit (state: *mut RsvgState) {
    unsafe { rsvg_state_reinit (state); }
}

pub fn state_reconstruct (state: *mut RsvgState, node: *const RsvgNode) {
    unsafe { rsvg_state_reconstruct (state, node); }
}

pub fn state_is_overflow (state: *const RsvgState) -> bool {
    unsafe { rsvg_state_is_overflow (state) }
}

pub fn state_push (draw_ctx: *const RsvgDrawingCtx) {
    unsafe {
        rsvg_state_push (draw_ctx);
    }
}

pub fn state_pop (draw_ctx: *const RsvgDrawingCtx) {
    unsafe {
        rsvg_state_pop (draw_ctx);
    }
}

pub fn node_draw_children (draw_ctx: *const RsvgDrawingCtx, c_node: *const RsvgNode, dominate: libc::c_int) {
    unsafe {
        _rsvg_node_draw_children (c_node, draw_ctx, dominate);
    }
}
<commit_msg>drawing_ctx.rs: Import rsvg_drawing_ctx_acquire_node_of_type()<commit_after>extern crate glib;
extern crate cairo;
extern crate cairo_sys;
extern crate libc;

use self::glib::translate::*;

use node::RsvgNode;
use node::NodeType;
use path_builder::RsvgPathBuilder;
use state::RsvgState;

pub enum RsvgDrawingCtx {}

extern "C" {
    fn rsvg_drawing_ctx_get_dpi (draw_ctx: *const RsvgDrawingCtx,
                                 out_dpi_x: *mut f64,
                                 out_dpi_y: *mut f64);

    fn rsvg_drawing_ctx_get_normalized_font_size (draw_ctx: *const RsvgDrawingCtx) -> f64;

    fn rsvg_drawing_ctx_get_view_box_size (draw_ctx: *const RsvgDrawingCtx,
                                           out_x: *mut f64,
                                           out_y: *mut f64);

    fn rsvg_drawing_ctx_push_view_box (draw_ctx: *const RsvgDrawingCtx,
                                       width:     f64,
                                       height:    f64);

    fn rsvg_drawing_ctx_pop_view_box (draw_ctx: *const RsvgDrawingCtx);

    fn rsvg_drawing_ctx_acquire_node (draw_ctx: *const RsvgDrawingCtx,
                                      url:      *const libc::c_char) -> *mut RsvgNode;

    fn rsvg_drawing_ctx_acquire_node_of_type (draw_ctx:  *const RsvgDrawingCtx,
                                              url:       *const libc::c_char,
                                              node_type: NodeType) -> *mut RsvgNode;

    fn rsvg_drawing_ctx_release_node (draw_ctx: *const RsvgDrawingCtx,
                                      node:     *mut RsvgNode);

    fn rsvg_drawing_ctx_get_current_state_affine (draw_ctx: *const RsvgDrawingCtx) -> cairo::Matrix;

    fn rsvg_drawing_ctx_set_current_state_affine (draw_ctx: *const RsvgDrawingCtx,
                                                  affine:   *const cairo::Matrix);

    fn rsvg_drawing_ctx_add_clipping_rect (draw_ctx: *const RsvgDrawingCtx,
                                           x: f64,
                                           y: f64,
                                           w: f64,
                                           h: f64);

    fn rsvg_current_state (draw_ctx: *const RsvgDrawingCtx) -> *mut RsvgState;
    fn rsvg_state_new () -> *mut RsvgState;
    fn rsvg_state_reinit (state: *mut RsvgState);
    fn rsvg_state_reconstruct (state: *mut RsvgState, node: *const RsvgNode);
    fn rsvg_state_is_overflow (state: *const RsvgState) -> bool;

    fn rsvg_state_push (draw_ctx: *const RsvgDrawingCtx);
    fn rsvg_state_pop (draw_ctx: *const RsvgDrawingCtx);

    fn rsvg_state_reinherit_top (draw_ctx: *const RsvgDrawingCtx,
                                 state: *mut RsvgState,
                                 dominate: libc::c_int);

    fn rsvg_push_discrete_layer (draw_ctx: *const RsvgDrawingCtx);
    fn rsvg_pop_discrete_layer (draw_ctx: *const RsvgDrawingCtx);

    fn rsvg_render_path_builder (draw_ctx: *const RsvgDrawingCtx,
                                 builder: *const RsvgPathBuilder);

    fn rsvg_cairo_get_cairo_context (draw_ctx: *const RsvgDrawingCtx) -> *mut cairo_sys::cairo_t;
    fn rsvg_cairo_set_cairo_context (draw_ctx: *const RsvgDrawingCtx, cr: *const cairo_sys::cairo_t);

    fn _rsvg_node_draw_children (node: *const RsvgNode, draw_ctx: *const RsvgDrawingCtx, dominate: libc::c_int);
}

pub fn get_dpi (draw_ctx: *const RsvgDrawingCtx) -> (f64, f64) {
    let mut dpi_x: f64 = 0.0;
    let mut dpi_y: f64 = 0.0;

    unsafe { rsvg_drawing_ctx_get_dpi (draw_ctx, &mut dpi_x, &mut dpi_y); }

    (dpi_x, dpi_y)
}

pub fn get_normalized_font_size (draw_ctx: *const RsvgDrawingCtx) -> f64 {
    unsafe { rsvg_drawing_ctx_get_normalized_font_size (draw_ctx) }
}

pub fn get_view_box_size (draw_ctx: *const RsvgDrawingCtx) -> (f64, f64) {
    let mut w: f64 = 0.0;
    let mut h: f64 = 0.0;

    unsafe { rsvg_drawing_ctx_get_view_box_size (draw_ctx, &mut w, &mut h); }

    (w, h)
}

pub fn push_view_box (draw_ctx: *const RsvgDrawingCtx,
                      width:     f64,
                      height:    f64)
{
    unsafe { rsvg_drawing_ctx_push_view_box (draw_ctx, width, height); }
}

pub fn pop_view_box (draw_ctx: *const RsvgDrawingCtx) {
    unsafe { rsvg_drawing_ctx_pop_view_box (draw_ctx); }
}

pub fn acquire_node (draw_ctx: *const RsvgDrawingCtx,
                     url:      &str) -> *mut RsvgNode {
    unsafe { rsvg_drawing_ctx_acquire_node (draw_ctx, str::to_glib_none (url).0) }
}

pub fn acquire_node_of_type (draw_ctx:  *const RsvgDrawingCtx,
                             url:       &str,
                             node_type: NodeType) -> *mut RsvgNode {
    unsafe { rsvg_drawing_ctx_acquire_node_of_type (draw_ctx, str::to_glib_none (url).0, node_type) }
}

pub fn release_node (draw_ctx: *const RsvgDrawingCtx,
                     node:     *mut RsvgNode) {
    unsafe { rsvg_drawing_ctx_release_node (draw_ctx, node); }
}

pub fn state_reinherit_top (draw_ctx: *const RsvgDrawingCtx,
                            state: *mut RsvgState,
                            dominate: i32) {
    unsafe { rsvg_state_reinherit_top (draw_ctx, state, dominate); }
}

pub fn push_discrete_layer (draw_ctx: *const RsvgDrawingCtx) {
    unsafe { rsvg_push_discrete_layer (draw_ctx); }
}

pub fn pop_discrete_layer (draw_ctx: *const RsvgDrawingCtx) {
    unsafe { rsvg_pop_discrete_layer (draw_ctx); }
}

pub fn render_path_builder (draw_ctx: *const RsvgDrawingCtx,
                            builder: &RsvgPathBuilder) {
    unsafe { rsvg_render_path_builder (draw_ctx, builder); }
}

pub fn get_cairo_context (draw_ctx: *const RsvgDrawingCtx) -> cairo::Context {
    unsafe {
        let raw_cr = rsvg_cairo_get_cairo_context (draw_ctx);

        let cr = cairo::Context::from_glib_none (raw_cr);

        cr
    }
}

pub fn set_cairo_context (draw_ctx: *const RsvgDrawingCtx, cr: &cairo::Context) {
    unsafe {
        let raw_cr = cr.to_glib_none ().0;

        rsvg_cairo_set_cairo_context (draw_ctx, raw_cr);
    }
}

pub fn get_current_state_affine (draw_ctx: *const RsvgDrawingCtx) -> cairo::Matrix {
    unsafe {
        rsvg_drawing_ctx_get_current_state_affine (draw_ctx)
    }
}

pub fn set_current_state_affine (draw_ctx: *const RsvgDrawingCtx, affine: cairo::Matrix) {
    unsafe {
        rsvg_drawing_ctx_set_current_state_affine (draw_ctx, &affine);
    }
}

pub fn add_clipping_rect (draw_ctx: *const RsvgDrawingCtx,
                          x: f64,
                          y: f64,
                          w: f64,
                          h: f64) {
    unsafe { rsvg_drawing_ctx_add_clipping_rect (draw_ctx, x, y, w, h); }
}

pub fn get_current_state (draw_ctx: *const RsvgDrawingCtx) -> *mut RsvgState {
    unsafe { rsvg_current_state (draw_ctx) }
}

pub fn state_new () -> *mut RsvgState {
    unsafe { rsvg_state_new () }
}

pub fn state_reinit (state: *mut RsvgState) {
    unsafe { rsvg_state_reinit (state); }
}

pub fn state_reconstruct (state: *mut RsvgState, node: *const RsvgNode) {
    unsafe { rsvg_state_reconstruct (state, node); }
}

pub fn state_is_overflow (state: *const RsvgState) -> bool {
    unsafe { rsvg_state_is_overflow (state) }
}

pub fn state_push (draw_ctx: *const RsvgDrawingCtx) {
    unsafe {
        rsvg_state_push (draw_ctx);
    }
}

pub fn state_pop (draw_ctx: *const RsvgDrawingCtx) {
    unsafe {
        rsvg_state_pop (draw_ctx);
    }
}

pub fn node_draw_children (draw_ctx: *const RsvgDrawingCtx, c_node: *const RsvgNode, dominate: libc::c_int) {
    unsafe {
        _rsvg_node_draw_children (c_node, draw_ctx, dominate);
    }
}
<|endoftext|>


<commit_before>#[macro_use]
extern crate num_derive;
extern crate num_traits;

mod calculator;
mod card;
mod cards_iterator;
mod hand;
mod table;
mod types;

pub use self::card::Card;
pub use self::hand::Hand;
pub use self::table::Table;
pub use calculator::Calculator;

fn main() {
    let card1 = Card {
        rank: types::Rank::Three,
        suit: types::Suit::Diamonds,
    };

    let card2 = Card {
        rank: types::Rank::King,
        suit: types::Suit::Hearts,
    };

    let hand = Hand::new(card1, card2);
    let mut table = Table::new();

    table.add_card(Card {
        rank: types::Rank::Queen,
        suit: types::Suit::Hearts,
    });
    table.add_card(Card {
        rank: types::Rank::Jack,
        suit: types::Suit::Hearts,
    });
    table.add_card(Card {
        rank: types::Rank::Ten,
        suit: types::Suit::Diamonds,
    });
    table.add_card(Card {
        rank: types::Rank::Nine,
        suit: types::Suit::Hearts,
    });

    let cloned_table = table.clone();

    println!("hand: {}", hand);
    println!("table: {}", table);

    let cards_iterator = cards_iterator::CardsIterator::new();
    let mut counter = 0;
    for card in cards_iterator {
        let mut current_table = cloned_table.clone();
        if !hand.cards.contains(&card) && !table.cards.contains(&Some(card)) {
            current_table.add_card(card);
            println!("{} -> hand: {}", counter + 1, hand);
            println!("{} -> table: {}", counter + 1, table);
            println!(
                "{} -> {:?}",
                counter + 1,
                Calculator::get_highest_combination(&hand, &current_table)
            );
        } else {
            println!("{} -> already in game: {}", counter + 1, card);
        }

        counter = counter + 1;
    }

    println!("total iterations: {}", counter);
}
<commit_msg>fix in logging<commit_after>#[macro_use]
extern crate num_derive;
extern crate num_traits;

mod calculator;
mod card;
mod cards_iterator;
mod hand;
mod table;
mod types;

pub use self::card::Card;
pub use self::hand::Hand;
pub use self::table::Table;
pub use calculator::Calculator;

fn main() {
    let card1 = Card {
        rank: types::Rank::Three,
        suit: types::Suit::Diamonds,
    };

    let card2 = Card {
        rank: types::Rank::King,
        suit: types::Suit::Hearts,
    };

    let hand = Hand::new(card1, card2);
    let mut table = Table::new();

    table.add_card(Card {
        rank: types::Rank::Queen,
        suit: types::Suit::Hearts,
    });
    table.add_card(Card {
        rank: types::Rank::Jack,
        suit: types::Suit::Hearts,
    });
    table.add_card(Card {
        rank: types::Rank::Ten,
        suit: types::Suit::Hearts,
    });
    table.add_card(Card {
        rank: types::Rank::Nine,
        suit: types::Suit::Diamonds,
    });

    let cloned_table = table.clone();

    println!("hand: {}", hand);
    println!("table: {}", table);

    let cards_iterator = cards_iterator::CardsIterator::new();
    let mut counter = 0;
    for card in cards_iterator {
        let mut current_table = cloned_table.clone();
        if !hand.cards.contains(&card) && !table.cards.contains(&Some(card)) {
            current_table.add_card(card);
            println!("{} -> hand: {}", counter + 1, hand);
            println!("{} -> table: {}", counter + 1, current_table);
            println!(
                "{} -> {:?}",
                counter + 1,
                Calculator::get_highest_combination(&hand, &current_table)
            );
        } else {
            println!("{} -> already in game: {}", counter + 1, card);
        }

        counter = counter + 1;
    }

    println!("total iterations: {}", counter);
}
<|endoftext|>