<commit_before>use crate::config;

use crate::infer_schema_internals::*;
use serde::de::{self, MapAccess, Visitor};
use serde::{Deserialize, Deserializer};
use std::error::Error;
use std::fmt::{self, Display, Formatter, Write};
use std::fs::File;
use std::io::{self, Error as IoError, ErrorKind, Write as IoWrite};
use std::path::Path;
use std::process::Command;
use tempfile::NamedTempFile;

pub enum Filtering {
    OnlyTables(Vec<TableName>),
    ExceptTables(Vec<TableName>),
    None,
}

impl Default for Filtering {
    fn default() -> Self {
        Filtering::None
    }
}

impl Filtering {
    pub fn should_ignore_table(&self, name: &TableName) -> bool {
        use self::Filtering::*;

        match *self {
            OnlyTables(ref names) => !names.contains(name),
            ExceptTables(ref names) => names.contains(name),
            None => false,
        }
    }
}

pub fn run_print_schema<W: IoWrite>(
    database_url: &str,
    config: &config::PrintSchema,
    output: &mut W,
) -> Result<(), Box<dyn Error>> {
    let tempfile = NamedTempFile::new()?;
    let file = tempfile.reopen()?;
    output_schema(database_url, config, file, tempfile.path())?;

    // patch "replaces" our tempfile, meaning the old handle
    // does not include the patched output.
    let mut file = File::open(tempfile.path())?;
    io::copy(&mut file, output)?;
    Ok(())
}

fn simplify_patch_error(err: IoError) -> Box<dyn Error> {
    match err.kind() {
        ErrorKind::NotFound => "Unable to find `patch` command, is it installed?".into(),
        _ => err.into(),
    }
}

pub fn output_schema(
    database_url: &str,
    config: &config::PrintSchema,
    mut out: File,
    out_path: &Path,
) -> Result<(), Box<dyn Error>> {
    let table_names = load_table_names(database_url, config.schema_name())?
        .into_iter()
        .filter(|t| !config.filter.should_ignore_table(t))
        .collect::<Vec<_>>();
    let foreign_keys = load_foreign_key_constraints(database_url, config.schema_name())?;
    let foreign_keys =
        remove_unsafe_foreign_keys_for_codegen(database_url, &foreign_keys, &table_names);
    let table_data = table_names
        .into_iter()
        .map(|t| load_table_data(database_url, t))
        .collect::<Result<_, Box<dyn Error>>>()?;
    let definitions = TableDefinitions {
        tables: table_data,
        fk_constraints: foreign_keys,
        include_docs: config.with_docs,
        import_types: config.import_types(),
    };

    if let Some(schema_name) = config.schema_name() {
        write!(out, "{}", ModuleDefinition(schema_name, definitions))?;
    } else {
        write!(out, "{}", definitions)?;
    }

    if let Some(ref patch_file) = config.patch_file {
        let output = Command::new("patch")
            .arg(out_path)
            .arg(patch_file)
            .output()
            .map_err(simplify_patch_error)?;
        if !output.status.success() {
            let stdout = String::from_utf8_lossy(&output.stdout);
            let stderr = String::from_utf8_lossy(&output.stderr);
            return Err(format!(
                "Failed to apply schema patch. stdout: {} stderr: {}",
                stdout, stderr,
            )
            .into());
        }
    }

    Ok(())
}

struct ModuleDefinition<'a>(&'a str, TableDefinitions<'a>);

impl<'a> Display for ModuleDefinition<'a> {
    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
        {
            let mut out = PadAdapter::new(f);
            writeln!(out, "pub mod {} {{", self.0)?;
            write!(out, "{}", self.1)?;
        }
        writeln!(f, "}}")?;
        Ok(())
    }
}

struct TableDefinitions<'a> {
    tables: Vec<TableData>,
    fk_constraints: Vec<ForeignKeyConstraint>,
    include_docs: bool,
    import_types: Option<&'a [String]>,
}

impl<'a> Display for TableDefinitions<'a> {
    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
        let mut is_first = true;
        for table in &self.tables {
            if is_first {
                is_first = false;
            } else {
                writeln!(f)?;
            }
            writeln!(
                f,
                "{}",
                TableDefinition {
                    table,
                    include_docs: self.include_docs,
                    import_types: self.import_types,
                }
            )?;
        }

        if !self.fk_constraints.is_empty() {
            writeln!(f)?;
        }

        for foreign_key in &self.fk_constraints {
            writeln!(f, "{}", Joinable(foreign_key))?;
        }

        if self.tables.len() > 1 {
            write!(f, "\nallow_tables_to_appear_in_same_query!(")?;
            {
                let mut out = PadAdapter::new(f);
                writeln!(out)?;
                for table in &self.tables {
                    if table.name.rust_name == table.name.sql_name {
                        writeln!(out, "{},", table.name.sql_name)?;
                    } else {
                        writeln!(out, "{},", table.name.rust_name)?;
                    }
                }
            }
            writeln!(f, ");")?;
        }

        Ok(())
    }
}

struct TableDefinition<'a> {
    table: &'a TableData,
    import_types: Option<&'a [String]>,
    include_docs: bool,
}

impl<'a> Display for TableDefinition<'a> {
    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
        write!(f, "table! {{")?;
        {
            let mut out = PadAdapter::new(f);
            writeln!(out)?;

            if let Some(types) = self.import_types {
                for import in types {
                    writeln!(out, "use {};", import)?;
                }
                writeln!(out)?;
            }

            if self.include_docs {
                for d in self.table.docs.lines() {
                    writeln!(out, "///{}{}", if d.is_empty() { "" } else { " " }, d)?;
                }
            }

            if self.table.name.rust_name != self.table.name.sql_name {
                writeln!(
                    out,
                    r#"#[sql_name = "{}"]"#,
                    self.table.name.full_sql_name()
                )?;
            }

            write!(out, "{} (", self.table.name)?;

            for (i, pk) in self.table.primary_key.iter().enumerate() {
                if i != 0 {
                    write!(out, ", ")?;
                }
                write!(out, "{}", pk)?;
            }

            write!(
                out,
                ") {}",
                ColumnDefinitions {
                    columns: &self.table.column_data,
                    include_docs: self.include_docs,
                }
            )?;
        }
        write!(f, "}}")?;
        Ok(())
    }
}

struct ColumnDefinitions<'a> {
    columns: &'a [ColumnDefinition],
    include_docs: bool,
}

impl<'a> Display for ColumnDefinitions<'a> {
    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
        {
            let mut out = PadAdapter::new(f);
            writeln!(out, "{{")?;
            for column in self.columns {
                if self.include_docs {
                    for d in column.docs.lines() {
                        writeln!(out, "///{}{}", if d.is_empty() { "" } else { " " }, d)?;
                    }
                }
                if column.rust_name == column.sql_name {
                    writeln!(out, "{} -> {},", column.sql_name, column.ty)?;
                } else {
                    writeln!(out, r#"#[sql_name = "{}"]"#, column.sql_name)?;
                    writeln!(out, "{} -> {},", column.rust_name, column.ty)?;
                }
            }
        }
        writeln!(f, "}}")?;
        Ok(())
    }
}

struct Joinable<'a>(&'a ForeignKeyConstraint);

impl<'a> Display for Joinable<'a> {
    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
        let child_table_name = &self.0.child_table.rust_name;

        let parent_table_name = &self.0.parent_table.rust_name;

        write!(
            f,
            "joinable!({} -> {} ({}));",
            child_table_name, parent_table_name, self.0.foreign_key_rust_name,
        )
    }
}

/// Lifted directly from libcore/fmt/builders.rs
struct PadAdapter<'a, 'b: 'a> {
    fmt: &'a mut Formatter<'b>,
    on_newline: bool,
}

impl<'a, 'b: 'a> PadAdapter<'a, 'b> {
    fn new(fmt: &'a mut Formatter<'b>) -> PadAdapter<'a, 'b> {
        PadAdapter {
            fmt,
            on_newline: false,
        }
    }
}

impl<'a, 'b: 'a> Write for PadAdapter<'a, 'b> {
    fn write_str(&mut self, mut s: &str) -> fmt::Result {
        while !s.is_empty() {
            let on_newline = self.on_newline;

            let split = match s.find('\n') {
                Some(pos) => {
                    self.on_newline = true;
                    pos + 1
                }
                None => {
                    self.on_newline = false;
                    s.len()
                }
            };

            let to_write = &s[..split];
            if on_newline && to_write != "\n" {
                self.fmt.write_str("    ")?;
            }
            self.fmt.write_str(to_write)?;

            s = &s[split..];
        }

        Ok(())
    }
}

impl<'de> Deserialize<'de> for Filtering {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: Deserializer<'de>,
    {
        struct FilteringVisitor;

        impl<'de> Visitor<'de> for FilteringVisitor {
            type Value = Filtering;

            fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
                f.write_str("either only_tables or except_tables")
            }

            fn visit_map<V>(self, mut map: V) -> Result<Self::Value, V::Error>
            where
                V: MapAccess<'de>,
            {
                let mut only_tables = None;
                let mut except_tables = None;
                while let Some((key, value)) = map.next_entry()? {
                    match key {
                        "only_tables" => {
                            if only_tables.is_some() {
                                return Err(de::Error::duplicate_field("only_tables"));
                            }
                            only_tables = Some(value);
                        }
                        "except_tables" => {
                            if except_tables.is_some() {
                                return Err(de::Error::duplicate_field("except_tables"));
                            }
                            except_tables = Some(value);
                        }
                        _ => {
                            return Err(de::Error::unknown_field(
                                key,
                                &["only_tables", "except_tables"],
                            ))
                        }
                    }
                }
                match (only_tables, except_tables) {
                    (Some(_), Some(_)) => Err(de::Error::duplicate_field("except_tables")),
                    (Some(w), None) => Ok(Filtering::OnlyTables(w)),
                    (None, Some(b)) => Ok(Filtering::ExceptTables(b)),
                    (None, None) => Ok(Filtering::None),
                }
            }
        }

        deserializer.deserialize_map(FilteringVisitor)
    }
}
<commit_msg>Use macros via full path when generating a `schema.rs` file<commit_after>use crate::config;

use crate::infer_schema_internals::*;
use serde::de::{self, MapAccess, Visitor};
use serde::{Deserialize, Deserializer};
use std::error::Error;
use std::fmt::{self, Display, Formatter, Write};
use std::fs::File;
use std::io::{self, Error as IoError, ErrorKind, Write as IoWrite};
use std::path::Path;
use std::process::Command;
use tempfile::NamedTempFile;

pub enum Filtering {
    OnlyTables(Vec<TableName>),
    ExceptTables(Vec<TableName>),
    None,
}

impl Default for Filtering {
    fn default() -> Self {
        Filtering::None
    }
}

impl Filtering {
    pub fn should_ignore_table(&self, name: &TableName) -> bool {
        use self::Filtering::*;

        match *self {
            OnlyTables(ref names) => !names.contains(name),
            ExceptTables(ref names) => names.contains(name),
            None => false,
        }
    }
}

pub fn run_print_schema<W: IoWrite>(
    database_url: &str,
    config: &config::PrintSchema,
    output: &mut W,
) -> Result<(), Box<dyn Error>> {
    let tempfile = NamedTempFile::new()?;
    let file = tempfile.reopen()?;
    output_schema(database_url, config, file, tempfile.path())?;

    // patch "replaces" our tempfile, meaning the old handle
    // does not include the patched output.
    let mut file = File::open(tempfile.path())?;
    io::copy(&mut file, output)?;
    Ok(())
}

fn simplify_patch_error(err: IoError) -> Box<dyn Error> {
    match err.kind() {
        ErrorKind::NotFound => "Unable to find `patch` command, is it installed?".into(),
        _ => err.into(),
    }
}

pub fn output_schema(
    database_url: &str,
    config: &config::PrintSchema,
    mut out: File,
    out_path: &Path,
) -> Result<(), Box<dyn Error>> {
    let table_names = load_table_names(database_url, config.schema_name())?
        .into_iter()
        .filter(|t| !config.filter.should_ignore_table(t))
        .collect::<Vec<_>>();
    let foreign_keys = load_foreign_key_constraints(database_url, config.schema_name())?;
    let foreign_keys =
        remove_unsafe_foreign_keys_for_codegen(database_url, &foreign_keys, &table_names);
    let table_data = table_names
        .into_iter()
        .map(|t| load_table_data(database_url, t))
        .collect::<Result<_, Box<dyn Error>>>()?;
    let definitions = TableDefinitions {
        tables: table_data,
        fk_constraints: foreign_keys,
        include_docs: config.with_docs,
        import_types: config.import_types(),
    };

    if let Some(schema_name) = config.schema_name() {
        write!(out, "{}", ModuleDefinition(schema_name, definitions))?;
    } else {
        write!(out, "{}", definitions)?;
    }

    if let Some(ref patch_file) = config.patch_file {
        let output = Command::new("patch")
            .arg(out_path)
            .arg(patch_file)
            .output()
            .map_err(simplify_patch_error)?;
        if !output.status.success() {
            let stdout = String::from_utf8_lossy(&output.stdout);
            let stderr = String::from_utf8_lossy(&output.stderr);
            return Err(format!(
                "Failed to apply schema patch. stdout: {} stderr: {}",
                stdout, stderr,
            )
            .into());
        }
    }

    Ok(())
}

struct ModuleDefinition<'a>(&'a str, TableDefinitions<'a>);

impl<'a> Display for ModuleDefinition<'a> {
    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
        {
            let mut out = PadAdapter::new(f);
            writeln!(out, "pub mod {} {{", self.0)?;
            write!(out, "{}", self.1)?;
        }
        writeln!(f, "}}")?;
        Ok(())
    }
}

struct TableDefinitions<'a> {
    tables: Vec<TableData>,
    fk_constraints: Vec<ForeignKeyConstraint>,
    include_docs: bool,
    import_types: Option<&'a [String]>,
}

impl<'a> Display for TableDefinitions<'a> {
    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
        let mut is_first = true;
        for table in &self.tables {
            if is_first {
                is_first = false;
            } else {
                writeln!(f)?;
            }
            writeln!(
                f,
                "{}",
                TableDefinition {
                    table,
                    include_docs: self.include_docs,
                    import_types: self.import_types,
                }
            )?;
        }

        if !self.fk_constraints.is_empty() {
            writeln!(f)?;
        }

        for foreign_key in &self.fk_constraints {
            writeln!(f, "{}", Joinable(foreign_key))?;
        }

        if self.tables.len() > 1 {
            write!(f, "\ndiesel::allow_tables_to_appear_in_same_query!(")?;
            {
                let mut out = PadAdapter::new(f);
                writeln!(out)?;
                for table in &self.tables {
                    if table.name.rust_name == table.name.sql_name {
                        writeln!(out, "{},", table.name.sql_name)?;
                    } else {
                        writeln!(out, "{},", table.name.rust_name)?;
                    }
                }
            }
            writeln!(f, ");")?;
        }

        Ok(())
    }
}

struct TableDefinition<'a> {
    table: &'a TableData,
    import_types: Option<&'a [String]>,
    include_docs: bool,
}

impl<'a> Display for TableDefinition<'a> {
    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
        write!(f, "diesel::table! {{")?;
        {
            let mut out = PadAdapter::new(f);
            writeln!(out)?;

            if let Some(types) = self.import_types {
                for import in types {
                    writeln!(out, "use {};", import)?;
                }
                writeln!(out)?;
            }

            if self.include_docs {
                for d in self.table.docs.lines() {
                    writeln!(out, "///{}{}", if d.is_empty() { "" } else { " " }, d)?;
                }
            }

            if self.table.name.rust_name != self.table.name.sql_name {
                writeln!(
                    out,
                    r#"#[sql_name = "{}"]"#,
                    self.table.name.full_sql_name()
                )?;
            }

            write!(out, "{} (", self.table.name)?;

            for (i, pk) in self.table.primary_key.iter().enumerate() {
                if i != 0 {
                    write!(out, ", ")?;
                }
                write!(out, "{}", pk)?;
            }

            write!(
                out,
                ") {}",
                ColumnDefinitions {
                    columns: &self.table.column_data,
                    include_docs: self.include_docs,
                }
            )?;
        }
        write!(f, "}}")?;
        Ok(())
    }
}

struct ColumnDefinitions<'a> {
    columns: &'a [ColumnDefinition],
    include_docs: bool,
}

impl<'a> Display for ColumnDefinitions<'a> {
    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
        {
            let mut out = PadAdapter::new(f);
            writeln!(out, "{{")?;
            for column in self.columns {
                if self.include_docs {
                    for d in column.docs.lines() {
                        writeln!(out, "///{}{}", if d.is_empty() { "" } else { " " }, d)?;
                    }
                }
                if column.rust_name == column.sql_name {
                    writeln!(out, "{} -> {},", column.sql_name, column.ty)?;
                } else {
                    writeln!(out, r#"#[sql_name = "{}"]"#, column.sql_name)?;
                    writeln!(out, "{} -> {},", column.rust_name, column.ty)?;
                }
            }
        }
        writeln!(f, "}}")?;
        Ok(())
    }
}

struct Joinable<'a>(&'a ForeignKeyConstraint);

impl<'a> Display for Joinable<'a> {
    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
        let child_table_name = &self.0.child_table.rust_name;

        let parent_table_name = &self.0.parent_table.rust_name;

        write!(
            f,
            "diesel::joinable!({} -> {} ({}));",
            child_table_name, parent_table_name, self.0.foreign_key_rust_name,
        )
    }
}

/// Lifted directly from libcore/fmt/builders.rs
struct PadAdapter<'a, 'b: 'a> {
    fmt: &'a mut Formatter<'b>,
    on_newline: bool,
}

impl<'a, 'b: 'a> PadAdapter<'a, 'b> {
    fn new(fmt: &'a mut Formatter<'b>) -> PadAdapter<'a, 'b> {
        PadAdapter {
            fmt,
            on_newline: false,
        }
    }
}

impl<'a, 'b: 'a> Write for PadAdapter<'a, 'b> {
    fn write_str(&mut self, mut s: &str) -> fmt::Result {
        while !s.is_empty() {
            let on_newline = self.on_newline;

            let split = match s.find('\n') {
                Some(pos) => {
                    self.on_newline = true;
                    pos + 1
                }
                None => {
                    self.on_newline = false;
                    s.len()
                }
            };

            let to_write = &s[..split];
            if on_newline && to_write != "\n" {
                self.fmt.write_str("    ")?;
            }
            self.fmt.write_str(to_write)?;

            s = &s[split..];
        }

        Ok(())
    }
}

impl<'de> Deserialize<'de> for Filtering {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: Deserializer<'de>,
    {
        struct FilteringVisitor;

        impl<'de> Visitor<'de> for FilteringVisitor {
            type Value = Filtering;

            fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
                f.write_str("either only_tables or except_tables")
            }

            fn visit_map<V>(self, mut map: V) -> Result<Self::Value, V::Error>
            where
                V: MapAccess<'de>,
            {
                let mut only_tables = None;
                let mut except_tables = None;
                while let Some((key, value)) = map.next_entry()? {
                    match key {
                        "only_tables" => {
                            if only_tables.is_some() {
                                return Err(de::Error::duplicate_field("only_tables"));
                            }
                            only_tables = Some(value);
                        }
                        "except_tables" => {
                            if except_tables.is_some() {
                                return Err(de::Error::duplicate_field("except_tables"));
                            }
                            except_tables = Some(value);
                        }
                        _ => {
                            return Err(de::Error::unknown_field(
                                key,
                                &["only_tables", "except_tables"],
                            ))
                        }
                    }
                }
                match (only_tables, except_tables) {
                    (Some(_), Some(_)) => Err(de::Error::duplicate_field("except_tables")),
                    (Some(w), None) => Ok(Filtering::OnlyTables(w)),
                    (None, Some(b)) => Ok(Filtering::ExceptTables(b)),
                    (None, None) => Ok(Filtering::None),
                }
            }
        }

        deserializer.deserialize_map(FilteringVisitor)
    }
}
<|endoftext|>


<commit_before>// Copyright 2014 The CGMath Developers. For a full listing of the authors,
// refer to the AUTHORS file at the top-level directory of this distribution.
//
// 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.

use cgmath::quaternion::*;
use cgmath::transform::*;
use cgmath::point::*;
use cgmath::vector::*;
use cgmath::approx::ApproxEq;

#[test]
fn test_invert() {
	let v = Vector3::new(1.0, 2.0, 3.0);
	let t = Transform3D::new(1.5, Quaternion::new(0.5,0.5,0.5,0.5), Vector3::new(6.0,-7.0,8.0));
	let ti = t.get().invert().expect("Expected successful inversion");
	let vt = t.get().transform_vector( &v );
    assert!(v.approx_eq( &ti.transform_vector( &vt ) ));
}

#[test]
fn test_look_at() {
	let eye = Point3::new(0.0, 0.0, -5.0);
	let center = Point3::new(0.0, 0.0, 0.0);
	let up = Vector3::new(1.0, 0.0, 0.0);
	let t: Decomposed<f64,Vector3<f64>,Quaternion<f64>> = Transform::look_at(&eye, &center, &up);
	let point = Point3::new(1.0, 0.0, 0.0);
	let view_point = Point3::new(0.0, 1.0, 5.0);
	assert!( t.transform_point(&point).approx_eq(&view_point) );
}
<commit_msg>Update transform test to use Decomposed instead of Transform3D<commit_after>// Copyright 2014 The CGMath Developers. For a full listing of the authors,
// refer to the AUTHORS file at the top-level directory of this distribution.
//
// 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.

use cgmath::quaternion::*;
use cgmath::transform::*;
use cgmath::point::*;
use cgmath::vector::*;
use cgmath::approx::ApproxEq;

#[test]
fn test_invert() {
	let v = Vector3::new(1.0, 2.0, 3.0);
	let t = Decomposed {
        scale: 1.5,
        rot: Quaternion::new(0.5,0.5,0.5,0.5),
        disp: Vector3::new(6.0,-7.0,8.0)
    };
	let ti = t.invert().expect("Expected successful inversion");
	let vt = t.transform_vector( &v );
    assert!(v.approx_eq( &ti.transform_vector( &vt ) ));
}

#[test]
fn test_look_at() {
	let eye = Point3::new(0.0, 0.0, -5.0);
	let center = Point3::new(0.0, 0.0, 0.0);
	let up = Vector3::new(1.0, 0.0, 0.0);
	let t: Decomposed<f64,Vector3<f64>,Quaternion<f64>> = Transform::look_at(&eye, &center, &up);
	let point = Point3::new(1.0, 0.0, 0.0);
	let view_point = Point3::new(0.0, 1.0, 5.0);
	assert!( t.transform_point(&point).approx_eq(&view_point) );
}
<|endoftext|>


<commit_before>// pest. The Elegant Parser
// Copyright (C) 2017  Dragoș Tiselice
//
// 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/.

#![doc(html_root_url = "https://docs.rs/pest_derive/1.0.0")]

#[macro_use]
extern crate pest;
extern crate proc_macro;
#[macro_use]
extern crate quote;
extern crate syn;

use std::rc::Rc;

use pest::inputs::FileInput;
use pest::Parser;
use proc_macro::TokenStream;
use quote::{Tokens, ToTokens};
use syn::{Attribute, Lit, MetaItem, NestedMetaItem};

mod ast;
mod generator;
mod optimizer;
mod parser;
mod validator;

use parser::{GrammarParser, GrammarRule};

#[proc_macro_derive(Parser, attributes(grammar))]
pub fn derive_parser(input: TokenStream) -> TokenStream {
    let source = input.to_string();

    let (tokens, filename) = parse_derive(source);

    let input = match FileInput::new(&filename) {
        Ok(input) => Rc::new(input),
        Err(error) => panic!("error opening {:?}: {}", filename, error)
    };
    let pairs = match GrammarParser::parse(GrammarRule::rules, input) {
        Ok(pairs) => pairs,
        Err(error) => panic!("error parsing {:?}\n\n{}", filename, error.renamed_rules(|rule| {
            match *rule {
                GrammarRule::eoi => "end-of-input".to_owned(),
                GrammarRule::assignment_operator => "`=`".to_owned(),
                GrammarRule::silent_modifier => "`_`".to_owned(),
                GrammarRule::atomic_modifier => "`@`".to_owned(),
                GrammarRule::non_atomic_modifier => "`!@`".to_owned(),
                GrammarRule::opening_brace => "`{`".to_owned(),
                GrammarRule::closing_brace => "`}`".to_owned(),
                GrammarRule::opening_paren => "`(`".to_owned(),
                GrammarRule::positive_predicate_operator => "`&`".to_owned(),
                GrammarRule::negative_predicate_operator => "`!`".to_owned(),
                GrammarRule::sequence_operator => "`&`".to_owned(),
                GrammarRule::choice_operator => "`|`".to_owned(),
                GrammarRule::optional_operator => "`?`".to_owned(),
                GrammarRule::repeat_operator => "`*`".to_owned(),
                GrammarRule::repeat_once_operator => "`+`".to_owned(),
                GrammarRule::closing_paren => "`)`".to_owned(),
                GrammarRule::quote => "`\"`".to_owned(),
                GrammarRule::insensitive_string => "`^`".to_owned(),
                GrammarRule::range_operator => "`..`".to_owned(),
                GrammarRule::single_quote => "`'`".to_owned(),
                rule => format!("{:?}", rule)
            }
        }))
    };
    let ast = parser::consume_rules(pairs);

    "".parse().unwrap()
}

fn parse_derive(source: String) -> (Tokens, String) {
    let ast = syn::parse_macro_input(&source).unwrap();

    let (grammar, attrs): (Vec<_>, Vec<_>) = ast.attrs.iter().partition(|attr| {
        match attr.value {
            MetaItem::NameValue(ref ident, _) => format!("{}", ident) == "grammar",
            _ => false
        }
    });

    let filename = match grammar.len() {
        0 => panic!("a grammar file needs to be provided with the #[grammar(\"...\")] attribute"),
        1 => get_filename(grammar[0]),
        _ => panic!("only 1 grammar file can be provided")
    };

    let mut tokens = Tokens::new();

    let mut ast = ast.clone();
    ast.attrs = attrs.into_iter().cloned().collect::<Vec<_>>();
    ast.to_tokens(&mut tokens);

    (tokens, filename)
}

fn get_filename(attr: &Attribute) -> String {
    if let MetaItem::NameValue(_, ref lit) = attr.value {
        if let &Lit::Str(ref string, _) = lit {
            string.clone()
        } else {
            panic!("grammar attribute must be a string")
        }
    } else {
        unreachable!();
    }
}

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

    #[test]
    fn derive_ok() {
        let (tokens, filename) = parse_derive("
            #[other_attr]
            #[grammar = \"myfile.pest\"]
            pub struct MyParser<'a, T>;
        ".to_owned());

        assert_eq!(tokens.as_str(), "# [ other_attr ] pub struct MyParser < \'a , T > ;");
        assert_eq!(filename, "myfile.pest");
    }

    #[test]
    #[should_panic(expected = "only 1 grammar file can be provided")]
    fn derive_multiple_grammars() {
        let (tokens, filename) = parse_derive("
            #[other_attr]
            #[grammar = \"myfile1.pest\"]
            #[grammar = \"myfile2.pest\"]
            pub struct MyParser<'a, T>;
        ".to_owned());
    }

    #[test]
    #[should_panic(expected = "grammar attribute must be a string")]
    fn derive_wrong_arg() {
        let (tokens, filename) = parse_derive("
            #[other_attr]
            #[grammar = 1]
            pub struct MyParser<'a, T>;
        ".to_owned());
    }
}
<commit_msg>Changed macro to open files from src.<commit_after>// pest. The Elegant Parser
// Copyright (C) 2017  Dragoș Tiselice
//
// 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/.

#![doc(html_root_url = "https://docs.rs/pest_derive/1.0.0")]

#[macro_use]
extern crate pest;
extern crate proc_macro;
#[macro_use]
extern crate quote;
extern crate syn;

use std::path::Path;
use std::rc::Rc;

use pest::inputs::FileInput;
use pest::Parser;
use proc_macro::TokenStream;
use quote::{Tokens, ToTokens};
use syn::{Attribute, Lit, MetaItem, NestedMetaItem};

mod ast;
mod generator;
mod optimizer;
mod parser;
mod validator;

use parser::{GrammarParser, GrammarRule};

#[proc_macro_derive(Parser, attributes(grammar))]
pub fn derive_parser(input: TokenStream) -> TokenStream {
    let source = input.to_string();

    let (tokens, path) = parse_derive(source);

    let root = std::env::var("CARGO_MANIFEST_DIR").unwrap_or(".".into());
    let path = Path::new(&root).join("src/").join(&path);
    let file_name = match path.file_name() {
        Some(file_name) => file_name,
        None => panic!("grammar attribute should point to a file")
    };

    let input = match FileInput::new(&path) {
        Ok(input) => Rc::new(input),
        Err(error) => panic!("error opening {:?}: {}", file_name, error)
    };
    let pairs = match GrammarParser::parse(GrammarRule::rules, input) {
        Ok(pairs) => pairs,
        Err(error) => panic!("error parsing {:?}\n\n{}", file_name, error.renamed_rules(|rule| {
            match *rule {
                GrammarRule::eoi => "end-of-input".to_owned(),
                GrammarRule::assignment_operator => "`=`".to_owned(),
                GrammarRule::silent_modifier => "`_`".to_owned(),
                GrammarRule::atomic_modifier => "`@`".to_owned(),
                GrammarRule::non_atomic_modifier => "`!@`".to_owned(),
                GrammarRule::opening_brace => "`{`".to_owned(),
                GrammarRule::closing_brace => "`}`".to_owned(),
                GrammarRule::opening_paren => "`(`".to_owned(),
                GrammarRule::positive_predicate_operator => "`&`".to_owned(),
                GrammarRule::negative_predicate_operator => "`!`".to_owned(),
                GrammarRule::sequence_operator => "`&`".to_owned(),
                GrammarRule::choice_operator => "`|`".to_owned(),
                GrammarRule::optional_operator => "`?`".to_owned(),
                GrammarRule::repeat_operator => "`*`".to_owned(),
                GrammarRule::repeat_once_operator => "`+`".to_owned(),
                GrammarRule::closing_paren => "`)`".to_owned(),
                GrammarRule::quote => "`\"`".to_owned(),
                GrammarRule::insensitive_string => "`^`".to_owned(),
                GrammarRule::range_operator => "`..`".to_owned(),
                GrammarRule::single_quote => "`'`".to_owned(),
                rule => format!("{:?}", rule)
            }
        }))
    };
    let ast = parser::consume_rules(pairs);

    "".parse().unwrap()
}

fn parse_derive(source: String) -> (Tokens, String) {
    let ast = syn::parse_macro_input(&source).unwrap();

    let (grammar, attrs): (Vec<_>, Vec<_>) = ast.attrs.iter().partition(|attr| {
        match attr.value {
            MetaItem::NameValue(ref ident, _) => format!("{}", ident) == "grammar",
            _ => false
        }
    });

    let filename = match grammar.len() {
        0 => panic!("a grammar file needs to be provided with the #[grammar(\"...\")] attribute"),
        1 => get_filename(grammar[0]),
        _ => panic!("only 1 grammar file can be provided")
    };

    let mut tokens = Tokens::new();

    let mut ast = ast.clone();
    ast.attrs = attrs.into_iter().cloned().collect::<Vec<_>>();
    ast.to_tokens(&mut tokens);

    (tokens, filename)
}

fn get_filename(attr: &Attribute) -> String {
    if let MetaItem::NameValue(_, ref lit) = attr.value {
        if let &Lit::Str(ref string, _) = lit {
            string.clone()
        } else {
            panic!("grammar attribute must be a string")
        }
    } else {
        unreachable!();
    }
}

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

    #[test]
    fn derive_ok() {
        let (tokens, filename) = parse_derive("
            #[other_attr]
            #[grammar = \"myfile.pest\"]
            pub struct MyParser<'a, T>;
        ".to_owned());

        assert_eq!(tokens.as_str(), "# [ other_attr ] pub struct MyParser < \'a , T > ;");
        assert_eq!(filename, "myfile.pest");
    }

    #[test]
    #[should_panic(expected = "only 1 grammar file can be provided")]
    fn derive_multiple_grammars() {
        let (tokens, filename) = parse_derive("
            #[other_attr]
            #[grammar = \"myfile1.pest\"]
            #[grammar = \"myfile2.pest\"]
            pub struct MyParser<'a, T>;
        ".to_owned());
    }

    #[test]
    #[should_panic(expected = "grammar attribute must be a string")]
    fn derive_wrong_arg() {
        let (tokens, filename) = parse_derive("
            #[other_attr]
            #[grammar = 1]
            pub struct MyParser<'a, T>;
        ".to_owned());
    }
}
<|endoftext|>


<commit_before>use std::io;

use tag;
use err;
use serial;

impl serial::traits::Asn1Info for u64 {
  fn asn1_type(&self) -> tag::Type {
    tag::Type::from("INTEGER")
  }

  fn asn1_class(&self) -> tag::Class {
    tag::Class::Universal
  }

  fn asn1_tagnum(&self) -> tag::TagNum {
    tag::TagNum::from(2u8)
  }

  fn asn1_constructed(&self) -> bool {
    false
  }
}

impl serial::traits::Asn1Serialize for u64 {
  fn serialize<W: io::Write>(&self, writer: &mut W) -> Result<(), err::EncodeError> {
    unimplemented!();
  }
}

impl serial::traits::Asn1Deserialize for u64 {
  fn deserialize<I: Iterator<Item=io::Result<u8>>>(reader: I) -> Result<Self, err::DecodeError> {
    unimplemented!();
  }
}
<commit_msg>Add serialize implementation for u64<commit_after>use std::io;

use tag;
use err;
use serial;
use byte::write_byte;

impl serial::traits::Asn1Info for u64 {
  fn asn1_type(&self) -> tag::Type {
    tag::Type::from("INTEGER")
  }

  fn asn1_class(&self) -> tag::Class {
    tag::Class::Universal
  }

  fn asn1_tagnum(&self) -> tag::TagNum {
    tag::TagNum::from(2u8)
  }

  fn asn1_constructed(&self) -> bool {
    false
  }
}

impl serial::traits::Asn1Serialize for u64 {
  fn serialize<W: io::Write>(&self, writer: &mut W) -> Result<(), err::EncodeError> {
    let mut started = false;
    // Loop through bytes in int backwards, start writing when first non-zero byte is encounted.
    for offset in (0..8).rev() {
      let shifted: u64 = self >> (offset * 8);
      let byte: u8 = (shifted & 0xff) as u8;
      if !started {
        if byte == 0 {
          continue;
        }
        started = true;
      }
      try!(write_byte(writer, byte));
    }

    // If we haven't written anything, write a zero byte.
    if !started {
      try!(write_byte(writer, 0 as u8));
    }
    Ok(())
  }
}

impl serial::traits::Asn1Deserialize for u64 {
  fn deserialize<I: Iterator<Item=io::Result<u8>>>(reader: I) -> Result<Self, err::DecodeError> {
    unimplemented!();
  }
}
<|endoftext|>


<commit_before>use ::*;

#[get("/pvp")]
fn pvpindex<'a>() -> ContRes<'a> {
    let conn = lock_database();
    let mut stmt = conn.prepare("SELECT id, name FROM players order by name").unwrap();
    let names: Vec<_> = stmt.query_map(&[], |row| {
            Named {
                id: row.get(0),
                name: row.get(1)
            }
        })
        .unwrap()
        .map(Result::unwrap)
        .collect();

    let mut context = create_context("pvp");
    context.add("names", &names);

    respond_page("pvpindex", context)
}

#[get("/pvp/<p1>/<p2>")]
fn pvp<'a>(p1: i32, p2: i32) -> ContRes<'a> {
    let conn = lock_database();
    let mut stmt =
        conn.prepare("SELECT (SELECT name FROM players p WHERE p.id = g.home_id) AS home, \
                      (SELECT name FROM players p WHERE p.id = g.away_id) AS away, home_score, \
                      away_score, ball_id, (SELECT img FROM balls b WHERE ball_id = b.id), \
                      (SELECT name FROM balls b WHERE ball_id = b.id), dato, home_id FROM games g \
                      WHERE (home_id = ?1 and away_id = ?2) and dato > date('now','start of month') \
                      or (home_id = ?2 and away_id = ?1) and dato > date('now','start of month') \
                      ORDER BY dato DESC")
            .unwrap();

    let mut map = ((0, 0, "".to_owned()), (0, 0, "".to_owned()));

    let pvp: Vec<_> = stmt.query_map(&[&p1, &p2], |row| {
            let game = PlayedGame {
                home: row.get(0),
                away: row.get(1),
                home_score: row.get(2),
                away_score: row.get(3),
                ball: row.get(5),
                ball_name: row.get(6),
                dato: row.get(7),
            };
            let home_id: i32 = row.get(8);

            let home_win = game.home_score > game.away_score;
            {
                let home = if home_id == p1 {&mut map.0} else {&mut map.1};
                if home.2.is_empty() {
                    home.2 = game.home.clone();
                }
                home.0 += game.home_score;
                if home_win { home.1 += 1 }
            }
            {
                let away = if home_id == p1 {&mut map.1} else {&mut map.0};
                if away.2.is_empty() {
                    away.2 = game.away.clone();
                }
                away.0 += game.away_score;
                if !home_win { away.1 += 1 }
            }

            game
        })
        .unwrap()
        .map(Result::unwrap)
        .collect();

    print!("{:?}", map);

//      p1  mål     p1 vundne   p1 navn     p1 antal kampe
//      p2  mål     p2 vundne   p2 navn     p2 antal kampe

    let mut context = create_context("pvp");

    context.add("pvp", &pvp);
    context.add("map", &map);
    respond_page("pvp", context)
}
<commit_msg>Removed debug text<commit_after>use ::*;

#[get("/pvp")]
fn pvpindex<'a>() -> ContRes<'a> {
    let conn = lock_database();
    let mut stmt = conn.prepare("SELECT id, name FROM players order by name").unwrap();
    let names: Vec<_> = stmt.query_map(&[], |row| {
            Named {
                id: row.get(0),
                name: row.get(1)
            }
        })
        .unwrap()
        .map(Result::unwrap)
        .collect();

    let mut context = create_context("pvp");
    context.add("names", &names);

    respond_page("pvpindex", context)
}

#[get("/pvp/<p1>/<p2>")]
fn pvp<'a>(p1: i32, p2: i32) -> ContRes<'a> {
    let conn = lock_database();
    let mut stmt =
        conn.prepare("SELECT (SELECT name FROM players p WHERE p.id = g.home_id) AS home, \
                      (SELECT name FROM players p WHERE p.id = g.away_id) AS away, home_score, \
                      away_score, ball_id, (SELECT img FROM balls b WHERE ball_id = b.id), \
                      (SELECT name FROM balls b WHERE ball_id = b.id), dato, home_id FROM games g \
                      WHERE (home_id = ?1 and away_id = ?2) and dato > date('now','start of month') \
                      or (home_id = ?2 and away_id = ?1) and dato > date('now','start of month') \
                      ORDER BY dato DESC")
            .unwrap();

    let mut map = ((0, 0, "".to_owned()), (0, 0, "".to_owned()));

    let pvp: Vec<_> = stmt.query_map(&[&p1, &p2], |row| {
            let game = PlayedGame {
                home: row.get(0),
                away: row.get(1),
                home_score: row.get(2),
                away_score: row.get(3),
                ball: row.get(5),
                ball_name: row.get(6),
                dato: row.get(7),
            };
            let home_id: i32 = row.get(8);

            let home_win = game.home_score > game.away_score;
            {
                let home = if home_id == p1 {&mut map.0} else {&mut map.1};
                if home.2.is_empty() {
                    home.2 = game.home.clone();
                }
                home.0 += game.home_score;
                if home_win { home.1 += 1 }
            }
            {
                let away = if home_id == p1 {&mut map.1} else {&mut map.0};
                if away.2.is_empty() {
                    away.2 = game.away.clone();
                }
                away.0 += game.away_score;
                if !home_win { away.1 += 1 }
            }

            game
        })
        .unwrap()
        .map(Result::unwrap)
        .collect();

    // map is formatted like this:
    //      p1  goals   p1 wins     p1 name
    //      p2  goals   p2 wins     p2 name

    let mut context = create_context("pvp");

    context.add("pvp", &pvp);
    context.add("map", &map);
    respond_page("pvp", context)
}
<|endoftext|>


<commit_before>use autograd::Variable;
use tensor::Tensor;
use torch;
use itertools::zip;

pub fn get_numerical_jacobian(func: fn(&Variable<f64>) -> Variable<f64>,
                              input: &Variable<f64>,
                              target: &Vec<Variable<f64>>,
                              eps: Option<f64>)
                              -> Vec<Tensor<f64>> {

    let eps = match eps {
        Some(e) => e,
        None => 1e-3,
    };
    let input = input.contiguous();
    let output_size = func(&input).numel();
    // XXX look at when this may not be a flat vector
    let jacobian: Vec<Tensor<f64>> = target
        .iter()
        .map(|v| ::torch::zeros([v.numel(), output_size]))
        .collect();

    let x_tensors: Vec<Tensor<f64>> = target
        .iter()
        .filter_map(|v| if v.requires_grad() {
                        Some(v.data_borrow().clone())
                    } else {
                        None
                    })
        .collect();
    let j_tensors = jacobian.clone();

    let mut outa = torch::double_tensor(output_size);
    let mut outb = torch::double_tensor(output_size);

    for (ref x_tensor_, ref mut d_tensor) in zip(x_tensors, j_tensors) {
        let x_tensor: &Tensor<f64> = x_tensor_;
        let mut flat_tensor = x_tensor.view([-1]);
        for i in 0..flat_tensor.numel() {
            let orig = flat_tensor[i];
            flat_tensor[i] = orig - eps;
            outa.copy_(func(&input).data_borrow());
            flat_tensor[i] = orig + eps;
            outb.copy_(func(&input).data_borrow());
            flat_tensor[i] = orig;

            outb.addt_(-1., &outa).div_(2. * eps);
            d_tensor.s([i]).copy_(&outb);
        }
    }
    jacobian
}
<commit_msg>get_analytical_jacobian<commit_after>use autograd::Variable;
use tensor::Tensor;
use torch;
use itertools::zip;

type Var64List = Vec<Variable<f64>>;

pub fn get_numerical_jacobian(func: fn(&Variable<f64>) -> Variable<f64>,
                              input: &Variable<f64>,
                              target: &Var64List,
                              eps: Option<f64>)
                              -> Vec<Tensor<f64>> {

    let eps = match eps {
        Some(e) => e,
        None => 1e-3,
    };
    let input = input.contiguous();
    let output_size = func(&input).numel();
    // XXX look at when this may not be a flat vector
    let jacobian: Vec<Tensor<f64>> = target
        .iter()
        .map(|v| ::torch::zeros([v.numel(), output_size]))
        .collect();

    let x_tensors: Vec<Tensor<f64>> = target
        .iter()
        .filter_map(|v| if v.requires_grad() {
                        Some(v.data_borrow().clone())
                    } else {
                        None
                    })
        .collect();
    let j_tensors = jacobian.clone();

    let mut outa = torch::double_tensor(output_size);
    let mut outb = torch::double_tensor(output_size);

    for (ref x_tensor_, ref mut d_tensor) in zip(x_tensors, j_tensors) {
        let x_tensor: &Tensor<f64> = x_tensor_;
        let mut flat_tensor = x_tensor.view([-1]);
        for i in 0..flat_tensor.numel() {
            let orig = flat_tensor[i];
            flat_tensor[i] = orig - eps;
            outa.copy_(func(&input).data_borrow());
            flat_tensor[i] = orig + eps;
            outb.copy_(func(&input).data_borrow());
            flat_tensor[i] = orig;

            outb.addt_(-1., &outa).div_(2. * eps);
            d_tensor.s([i as isize]).copy_(&outb);
        }
    }
    jacobian
}

pub fn zero_gradients(input: &mut Var64List) {
    for v in input {
        if let &mut Some(ref mut grad) = v.grad() {
            grad.detach_();
            grad.data().zero_();
        }
    }
}

pub fn iter_gradients(input: &mut Var64List) -> Vec<Option<Tensor<f64>>> {
    input
        .iter_mut()
        .map(|v| if v.requires_grad() {
                 if let &mut Some(ref mut grad) = v.grad() {
                     Some(grad.data().clone())
                 } else {
                     None
                 }
             } else {
                 None
             })
        .collect()

}

pub fn get_analytical_jacobian(input: &mut Var64List, output: &Variable<f64>) -> Vec<Tensor<f64>> {
    let mut jacobian: Vec<Tensor<f64>> = input
        .iter()
        .map(|v| ::torch::zeros([v.numel(), output.numel()]))
        .collect();
    let grad_output: Tensor<f64> = torch::zeros(output.data_borrow().size());
    let mut flat_grad_output = grad_output.view([-1]);

    for i in 0..flat_grad_output.numel() {
        flat_grad_output.zero_();
        flat_grad_output[i] = 1.;
        zero_gradients(input);
        for (ref mut jacobian_x, ref d_x_) in zip(jacobian.iter_mut(), iter_gradients(input)) {
            let d_x_: &Option<Tensor<f64>> = d_x_;
            if let &Some(ref d_x) = d_x_ {
                jacobian_x.s([-1, i as isize]).copy_(d_x);
            }

        }

    }

    jacobian
}
<|endoftext|>


<commit_before>// C preprocessor

use crate::token::*;
use std::cell::RefCell;
use std::collections::HashMap;

thread_local! {
    static MACROS: RefCell<HashMap<String, Macro>> = RefCell::new(HashMap::new());

    static ENV: RefCell<Env> = RefCell::new(Env::new());
}

fn set_env(env: Env) {
    ENV.with(|c| {
        *c.borrow_mut() = env;
    })
}

fn get_env() -> Option<Env> {
    ENV.with(|c| {
        Some(c.borrow().clone())
    })
}

fn env_pop() {
    ENV.with(|c| {
        let next = c.borrow().next.clone();
        if next.is_some() {
            *c.borrow_mut() = *next.unwrap();
        }
    })
}

fn env_output() -> Vec<Token> {
    ENV.with(|c| {
        return c.borrow().output.clone();
    })
}

fn macros_get(key: &String) -> Option<Macro> {
    MACROS.with(|m| {
        match m.borrow().get(key) {
            Some(v) => Some(v.clone()),
            None => None,
        }
    })
}

fn macros_put(key: String, value: Macro) {
    MACROS.with(|m| {
        m.borrow_mut().insert(key, value);
    })
}

#[derive(Clone, Debug)]
struct Env {
    input: Vec<Token>,
    output: Vec<Token>,
    pos: usize,
    next: Option<Box<Env>>,
}

impl Env {
    fn new() -> Env {
        Env {
            input: Vec::new(),
            output: Vec::new(),
            pos: 0,
            next: None,
        }
    }
}

fn new_env(next: Option<Env>, input: Vec<Token>) -> Env {
    let mut ctx = Env::new();
    ctx.input = input;
    if next.is_none() {
        ctx.next = None;
    } else {
        ctx.next = Some(Box::new(next.unwrap()));
    }
    return ctx;
}

#[derive(Clone, Debug, PartialEq)]
enum MacroType {
    OBJLIKE,
    FUNCLIKE,
}

#[derive(Clone, Debug)]
struct Macro {
    ty: MacroType,
    tokens: Vec<Token>,
    params: Vec<String>,
}

fn new_macro(ty: MacroType, name: String) {
    let m = Macro {
        ty: ty,
        tokens: Vec::new(),
        params: Vec::new(),
    };
    macros_put(name, m);
}

fn append(v: &mut Vec<Token>) {
    ENV.with(|env| {
        env.borrow_mut().output.append(v);
    })
}

fn emit(t: Token) {
    ENV.with(|env| {
        env.borrow_mut().output.push(t);
    })
}

fn next() -> Token {
    ENV.with(|env| {
        let pos = env.borrow().pos;
        assert!(pos < env.borrow().input.len());
        env.borrow_mut().pos += 1;
        return env.borrow().input[pos].clone();
    })
}

fn is_eof() -> bool {
    ENV.with(|c| {
        let env = c.borrow();
        return env.pos == env.input.len();
    })
}

fn get(ty: TokenType, msg: String) -> Token {
    let t = next();
    if t.ty != ty {
        bad_token(&t, msg);
    }
    return t;
}

fn ident(msg: String) -> String {
    let t = get(TokenType::IDENT, msg);
    return t.name.clone();
}

fn peek() -> Token {
    ENV.with(|c| {
        let env = c.borrow();
        return env.input[env.pos].clone();
    })
}

fn consume(ty: TokenType) -> bool {
    if peek().ty != ty {
        return false;
    }
    ENV.with(|c| {
        c.borrow_mut().pos += 1;
    });
    return true;
}

fn read_until_eol() -> Vec<Token> {
    let mut v = Vec::new();
    while !is_eof() {
        let t = next();
        if t.ty == TokenType::NEW_LINE {
            break;
        }
        v.push(t.clone());
    }
    return v;
}

fn new_int(tmpl: & Token, val: i32) -> Token {
    let mut t = tmpl.clone();
    t.ty = TokenType::NUM;
    t.val = val;
    return t;
}

fn new_string(tmpl: & Token, str_cnt: String, len: usize) -> Token {
    let mut t = tmpl.clone();
    t.ty = TokenType::STR;
    t.str_cnt = str_cnt;
    t.len = len;
    return t;
}

fn new_param(tmpl: & Token, val: i32) -> Token {
    let mut t = tmpl.clone();
    t.ty = TokenType::PARAM;
    t.val = val;
    return t;
}

fn is_ident(t: &Token, s: &str) -> bool {
    return t.ty == TokenType::IDENT && t.name == s;
}

// Replaces macro parameter tokens with TokenType::PARAM tokens.
fn replace_macro_params(m: &mut Macro) {
    let params = m.params.clone();
    let mut tokens = m.tokens.clone();

    let mut map = HashMap::new();
    for i in 0..params.len() {
        let name = params[i].clone();
        map.insert(name, i as i32);
    }

    for i in 0..tokens.len() {
        let t = &tokens[i].clone();
        if t.ty != TokenType::IDENT {
            continue;
        }
        let n = match map.get(&t.name) {
            Some(i) => *i,
            None => {
                continue;
            }
        };
        tokens.remove(i);
        tokens.insert(i, new_param(t, n));
    }
    m.tokens = tokens;
}

// Replaces '#' followed by a macro parameter.
fn replace_hash_ident(m: &mut Macro) {
    let tokens = m.tokens.clone();
    let mut v = Vec::new();
    let mut i = 0;
    while i < tokens.len()-1 {
        let t1 = tokens[i].clone();
        let mut t2 = tokens[i+1].clone();

        if t1.ty == TokenType::SHARP && t2.ty == TokenType::PARAM {
            t2.stringize = true;
            v.push(t2);
            i += 1;
        } else {
            v.push(t1);
        }
        i += 1;
    }

    if i == tokens.len() - 1 {
        v.push(tokens[i].clone());
    }
    m.tokens = v;
}

fn read_one_arg() -> Vec<Token> {
    let mut v = Vec::new();
    let start = peek();
    let mut level = 0;

    while !is_eof() {
        let t = peek();
        if level == 0 {
            if t.ty == TokenType::KET || t.ty == TokenType::COMMA {
                return v;
            }
        }

        next();
        if t.ty == TokenType::BRA {
            level += 1;
        } else if t.ty == TokenType::KET {
            level -= 1;
        }
        v.push(t);
    }
    bad_token(&start, "unclosed macro argument".to_string());
    panic!();
}

fn read_args() -> HashMap<usize, Vec<Token>> {
    let mut v = HashMap::new();
    if consume(TokenType::KET) {
        return v;
    }
    let i = v.len();
    v.insert(i, read_one_arg());
    while !consume(TokenType::KET) {
        get(TokenType::COMMA, "comma expected".to_string());
        let i = v.len();
        v.insert(i, read_one_arg());
    }
    return v;
}

fn add_special_macro(t: & Token) -> bool {
    if is_ident(t, "__LINE__") {
        emit(new_int(t, get_line_number(t)));
        return true;
    }
    return false;
}

fn apply_objlike(m: &mut Macro, _start: & Token) {
    for t in m.tokens.iter() {
        if add_special_macro(t) {
            continue;
        }
        emit(t.clone());
    }
}

fn apply_functionlike(m: &mut Macro, start: & Token) {
    get(TokenType::BRA, "comma expected".to_string());
    let args = read_args();
    if m.params.len() != args.len() {
        bad_token(&start, format!("number of parameter does not match ({} != {})", m.params.len(), args.len()).to_string());
        panic!();
    }

    for i in 0..m.tokens.len() {
        let t = &m.tokens[i];
        if add_special_macro(t) {
            continue;
        }

        if t.ty == TokenType::PARAM {
            if t.stringize {
                let j = t.val as usize;
                let s = stringize(args.get(&j).unwrap().clone());
                emit(new_string(t, s.clone(), s.len()));
            } else {
                let j = t.val as usize;
                append(&mut args.get(&j).unwrap().clone());
            }
            continue;
        }
        emit(t.clone());
    }
}

fn apply(m: &mut Macro, start: & Token) {
    if m.ty == MacroType::OBJLIKE {
        apply_objlike(m, start);
    } else {
        apply_functionlike(m, start);
    }
}

fn define_funclike(name: String) {
    new_macro(MacroType::FUNCLIKE, name.clone());
    let mut m = macros_get(&name).unwrap();
    while !consume(TokenType::KET) {
        if m.params.len() > 0 {
            get(TokenType::COMMA, ", expected".to_string());
        }
        m.params.push(ident("parameter name expected".to_string()));
    }
    m.tokens = read_until_eol();

    replace_macro_params(&mut m);
    replace_hash_ident(&mut m);

    macros_put(name, m);
}

fn define_objlike(name: String) {
    new_macro(MacroType::OBJLIKE, name.clone());
    let mut m = macros_get(&name).unwrap();
    m.tokens = read_until_eol();
    macros_put(name, m);
}

fn define() {
    let name = ident("macro name expected".to_string());
    if consume(TokenType::BRA) {
        return define_funclike(name);
    }
    return define_objlike(name);
}

fn include() {
    let t = get(TokenType::STR, "string expected".to_string());
    let path = t.str_cnt;
    get(TokenType::NEW_LINE, "newline expected".to_string());
    return append(&mut tokenize(path, false));
}

pub fn preprocess(tokens: Vec<Token>) -> Vec<Token> {
    set_env(new_env(get_env(), tokens.clone()));

    while !is_eof() {
        let mut t = next();

        if t.ty == TokenType::IDENT {
            match macros_get(&t.name) {
                Some(macro_token) => {
                    apply(&mut macro_token.clone(), &t);
                }
                None => {
                    emit(t.clone());
                }
            }
            continue;
        }

        if t.ty != TokenType::SHARP {
            emit(t.clone());
            continue;
        }

        t = get(TokenType::IDENT, "identifier expected".to_string());

        if t.name == "define" {
            define();
        } else if t.name == "include" {
            include();
        } else {
            bad_token(&t, "unknown directive".to_string());
        }
    }

    let v = env_output();
    env_pop();
    return v;
}
<commit_msg>Rename.<commit_after>// C preprocessor

use crate::token::*;
use std::cell::RefCell;
use std::collections::HashMap;

thread_local! {
    static MACROS: RefCell<HashMap<String, Macro>> = RefCell::new(HashMap::new());

    static ENV: RefCell<Env> = RefCell::new(Env::new());
}

fn set_env(env: Env) {
    ENV.with(|c| {
        *c.borrow_mut() = env;
    })
}

fn get_env() -> Option<Env> {
    ENV.with(|c| {
        Some(c.borrow().clone())
    })
}

fn env_pop() {
    ENV.with(|c| {
        let next = c.borrow().next.clone();
        if next.is_some() {
            *c.borrow_mut() = *next.unwrap();
        }
    })
}

fn env_output() -> Vec<Token> {
    ENV.with(|c| {
        return c.borrow().output.clone();
    })
}

fn macros_get(key: &String) -> Option<Macro> {
    MACROS.with(|m| {
        match m.borrow().get(key) {
            Some(v) => Some(v.clone()),
            None => None,
        }
    })
}

fn macros_put(key: String, value: Macro) {
    MACROS.with(|m| {
        m.borrow_mut().insert(key, value);
    })
}

#[derive(Clone, Debug)]
struct Env {
    input: Vec<Token>,
    output: Vec<Token>,
    pos: usize,
    next: Option<Box<Env>>,
}

impl Env {
    fn new() -> Env {
        Env {
            input: Vec::new(),
            output: Vec::new(),
            pos: 0,
            next: None,
        }
    }
}

fn new_env(next: Option<Env>, input: Vec<Token>) -> Env {
    let mut ctx = Env::new();
    ctx.input = input;
    if next.is_none() {
        ctx.next = None;
    } else {
        ctx.next = Some(Box::new(next.unwrap()));
    }
    return ctx;
}

#[derive(Clone, Debug, PartialEq)]
enum MacroType {
    OBJLIKE,
    FUNCLIKE,
}

#[derive(Clone, Debug)]
struct Macro {
    ty: MacroType,
    tokens: Vec<Token>,
    params: Vec<String>,
}

fn new_macro(ty: MacroType, name: String) {
    let m = Macro {
        ty: ty,
        tokens: Vec::new(),
        params: Vec::new(),
    };
    macros_put(name, m);
}

fn append(v: &mut Vec<Token>) {
    ENV.with(|env| {
        env.borrow_mut().output.append(v);
    })
}

fn emit(t: Token) {
    ENV.with(|env| {
        env.borrow_mut().output.push(t);
    })
}

fn next() -> Token {
    ENV.with(|env| {
        let pos = env.borrow().pos;
        assert!(pos < env.borrow().input.len());
        env.borrow_mut().pos += 1;
        return env.borrow().input[pos].clone();
    })
}

fn is_eof() -> bool {
    ENV.with(|c| {
        let env = c.borrow();
        return env.pos == env.input.len();
    })
}

fn get(ty: TokenType, msg: String) -> Token {
    let t = next();
    if t.ty != ty {
        bad_token(&t, msg);
    }
    return t;
}

fn ident(msg: String) -> String {
    let t = get(TokenType::IDENT, msg);
    return t.name.clone();
}

fn peek() -> Token {
    ENV.with(|c| {
        let env = c.borrow();
        return env.input[env.pos].clone();
    })
}

fn consume(ty: TokenType) -> bool {
    if peek().ty != ty {
        return false;
    }
    ENV.with(|c| {
        c.borrow_mut().pos += 1;
    });
    return true;
}

fn read_until_eol() -> Vec<Token> {
    let mut v = Vec::new();
    while !is_eof() {
        let t = next();
        if t.ty == TokenType::NEW_LINE {
            break;
        }
        v.push(t.clone());
    }
    return v;
}

fn new_int(tmpl: & Token, val: i32) -> Token {
    let mut t = tmpl.clone();
    t.ty = TokenType::NUM;
    t.val = val;
    return t;
}

fn new_string(tmpl: & Token, str_cnt: String, len: usize) -> Token {
    let mut t = tmpl.clone();
    t.ty = TokenType::STR;
    t.str_cnt = str_cnt;
    t.len = len;
    return t;
}

fn new_param(tmpl: & Token, val: i32) -> Token {
    let mut t = tmpl.clone();
    t.ty = TokenType::PARAM;
    t.val = val;
    return t;
}

fn is_ident(t: &Token, s: &str) -> bool {
    return t.ty == TokenType::IDENT && t.name == s;
}

// Replaces macro parameter tokens with TokenType::PARAM tokens.
fn replace_macro_params(m: &mut Macro) {
    let params = m.params.clone();
    let mut tokens = m.tokens.clone();

    let mut map = HashMap::new();
    for i in 0..params.len() {
        let name = params[i].clone();
        map.insert(name, i as i32);
    }

    for i in 0..tokens.len() {
        let t = &tokens[i].clone();
        if t.ty != TokenType::IDENT {
            continue;
        }
        let n = match map.get(&t.name) {
            Some(i) => *i,
            None => {
                continue;
            }
        };
        tokens.remove(i);
        tokens.insert(i, new_param(t, n));
    }
    m.tokens = tokens;
}

// Replaces '#' followed by a macro parameter.
fn replace_hash_ident(m: &mut Macro) {
    let tokens = m.tokens.clone();
    let mut v = Vec::new();
    let mut i = 0;
    while i < tokens.len()-1 {
        let t1 = tokens[i].clone();
        let mut t2 = tokens[i+1].clone();

        if t1.ty == TokenType::SHARP && t2.ty == TokenType::PARAM {
            t2.stringize = true;
            v.push(t2);
            i += 1;
        } else {
            v.push(t1);
        }
        i += 1;
    }

    if i == tokens.len() - 1 {
        v.push(tokens[i].clone());
    }
    m.tokens = v;
}

fn read_one_arg() -> Vec<Token> {
    let mut v = Vec::new();
    let start = peek();
    let mut level = 0;

    while !is_eof() {
        let t = peek();
        if level == 0 {
            if t.ty == TokenType::KET || t.ty == TokenType::COMMA {
                return v;
            }
        }

        next();
        if t.ty == TokenType::BRA {
            level += 1;
        } else if t.ty == TokenType::KET {
            level -= 1;
        }
        v.push(t);
    }
    bad_token(&start, "unclosed macro argument".to_string());
    panic!();
}

fn read_args() -> HashMap<usize, Vec<Token>> {
    let mut v = HashMap::new();
    if consume(TokenType::KET) {
        return v;
    }
    let i = v.len();
    v.insert(i, read_one_arg());
    while !consume(TokenType::KET) {
        get(TokenType::COMMA, "comma expected".to_string());
        let i = v.len();
        v.insert(i, read_one_arg());
    }
    return v;
}

fn emit_special_macro(t: & Token) -> bool {
    if is_ident(t, "__LINE__") {
        emit(new_int(t, get_line_number(t)));
        return true;
    }
    return false;
}

fn apply_objlike(m: &mut Macro, _start: & Token) {
    for t in m.tokens.iter() {
        if emit_special_macro(t) {
            continue;
        }
        emit(t.clone());
    }
}

fn apply_functionlike(m: &mut Macro, start: & Token) {
    get(TokenType::BRA, "comma expected".to_string());
    let args = read_args();
    if m.params.len() != args.len() {
        bad_token(&start, format!("number of parameter does not match ({} != {})", m.params.len(), args.len()).to_string());
        panic!();
    }

    for i in 0..m.tokens.len() {
        let t = &m.tokens[i];
        if emit_special_macro(t) {
            continue;
        }

        if t.ty == TokenType::PARAM {
            if t.stringize {
                let j = t.val as usize;
                let s = stringize(args.get(&j).unwrap().clone());
                emit(new_string(t, s.clone(), s.len()));
            } else {
                let j = t.val as usize;
                append(&mut args.get(&j).unwrap().clone());
            }
            continue;
        }
        emit(t.clone());
    }
}

fn apply(m: &mut Macro, start: & Token) {
    if m.ty == MacroType::OBJLIKE {
        apply_objlike(m, start);
    } else {
        apply_functionlike(m, start);
    }
}

fn define_funclike(name: String) {
    new_macro(MacroType::FUNCLIKE, name.clone());
    let mut m = macros_get(&name).unwrap();
    while !consume(TokenType::KET) {
        if m.params.len() > 0 {
            get(TokenType::COMMA, ", expected".to_string());
        }
        m.params.push(ident("parameter name expected".to_string()));
    }
    m.tokens = read_until_eol();

    replace_macro_params(&mut m);
    replace_hash_ident(&mut m);

    macros_put(name, m);
}

fn define_objlike(name: String) {
    new_macro(MacroType::OBJLIKE, name.clone());
    let mut m = macros_get(&name).unwrap();
    m.tokens = read_until_eol();
    macros_put(name, m);
}

fn define() {
    let name = ident("macro name expected".to_string());
    if consume(TokenType::BRA) {
        return define_funclike(name);
    }
    return define_objlike(name);
}

fn include() {
    let t = get(TokenType::STR, "string expected".to_string());
    let path = t.str_cnt;
    get(TokenType::NEW_LINE, "newline expected".to_string());
    return append(&mut tokenize(path, false));
}

pub fn preprocess(tokens: Vec<Token>) -> Vec<Token> {
    set_env(new_env(get_env(), tokens.clone()));

    while !is_eof() {
        let mut t = next();

        if t.ty == TokenType::IDENT {
            match macros_get(&t.name) {
                Some(macro_token) => {
                    apply(&mut macro_token.clone(), &t);
                }
                None => {
                    emit(t.clone());
                }
            }
            continue;
        }

        if t.ty != TokenType::SHARP {
            emit(t.clone());
            continue;
        }

        t = get(TokenType::IDENT, "identifier expected".to_string());

        if t.name == "define" {
            define();
        } else if t.name == "include" {
            include();
        } else {
            bad_token(&t, "unknown directive".to_string());
        }
    }

    let v = env_output();
    env_pop();
    return v;
}
<|endoftext|>


<commit_before>/* automatically generated by rust-bindgen */

#![allow(dead_code,
         non_camel_case_types,
         non_upper_case_globals,
         non_snake_case)]
pub type ffi_arg = ::std::os::raw::c_ulong;
pub type ffi_sarg = ::std::os::raw::c_long;
pub const FFI_DEFAULT_ABI: ffi_abi = ffi_abi::FFI_UNIX64;
#[derive(Copy, Clone)]
#[repr(u32)]
#[derive(Debug)]
pub enum ffi_abi {
    FFI_FIRST_ABI = 0,
    FFI_SYSV = 1,
    FFI_UNIX64 = 2,
    FFI_THISCALL = 3,
    FFI_FASTCALL = 4,
    FFI_STDCALL = 5,
    FFI_PASCAL = 6,
    FFI_REGISTER = 7,
    FFI_LAST_ABI = 8,
}
pub type ptrdiff_t = isize;
pub type size_t = usize;
pub type wchar_t = ::std::os::raw::c_int;
pub type max_align_t = ::std::os::raw::c_double;
#[repr(C)]
#[derive(Copy, Clone)]
#[derive(Debug)]
pub struct _ffi_type {
    pub size: size_t,
    pub alignment: ::std::os::raw::c_ushort,
    pub type_: ::std::os::raw::c_ushort,
    pub elements: *mut *mut _ffi_type,
}
impl ::std::default::Default for _ffi_type {
    fn default() -> Self { unsafe { ::std::mem::zeroed() } }
}
pub type ffi_type = _ffi_type;
#[derive(Copy, Clone)]
#[repr(u32)]
#[derive(Debug)]
pub enum ffi_status { FFI_OK = 0, FFI_BAD_TYPEDEF = 1, FFI_BAD_ABI = 2, }
pub type FFI_TYPE = ::std::os::raw::c_uint;
#[repr(C)]
#[derive(Copy, Clone)]
#[derive(Debug)]
pub struct ffi_cif {
    pub abi: ffi_abi,
    pub nargs: ::std::os::raw::c_uint,
    pub arg_types: *mut *mut ffi_type,
    pub rtype: *mut ffi_type,
    pub bytes: ::std::os::raw::c_uint,
    pub flags: ::std::os::raw::c_uint,
}
impl ::std::default::Default for ffi_cif {
    fn default() -> Self { unsafe { ::std::mem::zeroed() } }
}
#[repr(C)]
#[derive(Copy, Clone)]
#[derive(Debug)]
pub struct ffi_raw {
    pub _bindgen_data_: [u64; 1usize],
}
impl ffi_raw {
    pub unsafe fn sint(&mut self) -> *mut ffi_sarg {
        let raw: *mut u8 = ::std::mem::transmute(&self._bindgen_data_);
        ::std::mem::transmute(raw.offset(0))
    }
    pub unsafe fn uint_(&mut self) -> *mut ffi_arg {
        let raw: *mut u8 = ::std::mem::transmute(&self._bindgen_data_);
        ::std::mem::transmute(raw.offset(0))
    }
    pub unsafe fn flt(&mut self) -> *mut ::std::os::raw::c_float {
        let raw: *mut u8 = ::std::mem::transmute(&self._bindgen_data_);
        ::std::mem::transmute(raw.offset(0))
    }
    pub unsafe fn data(&mut self) -> *mut [::std::os::raw::c_char; 8usize] {
        let raw: *mut u8 = ::std::mem::transmute(&self._bindgen_data_);
        ::std::mem::transmute(raw.offset(0))
    }
    pub unsafe fn ptr(&mut self) -> *mut *mut ::std::os::raw::c_void {
        let raw: *mut u8 = ::std::mem::transmute(&self._bindgen_data_);
        ::std::mem::transmute(raw.offset(0))
    }
}
impl ::std::default::Default for ffi_raw {
    fn default() -> Self { unsafe { ::std::mem::zeroed() } }
}
pub type ffi_java_raw = ffi_raw;
#[repr(C)]
#[derive(Copy, Clone)]
#[derive(Debug)]
pub struct ffi_closure {
    pub tramp: [::std::os::raw::c_char; 24usize],
    pub cif: *mut ffi_cif,
    pub fun: ::std::option::Option<unsafe extern "C" fn(arg1: *mut ffi_cif,
                                                        arg2:
                                                            *mut ::std::os::raw::c_void,
                                                        arg3:
                                                            *mut *mut ::std::os::raw::c_void,
                                                        arg4:
                                                            *mut ::std::os::raw::c_void)>,
    pub user_data: *mut ::std::os::raw::c_void,
}
impl ::std::default::Default for ffi_closure {
    fn default() -> Self { unsafe { ::std::mem::zeroed() } }
}
#[repr(C)]
#[derive(Copy, Clone)]
#[derive(Debug)]
pub struct ffi_raw_closure {
    pub tramp: [::std::os::raw::c_char; 24usize],
    pub cif: *mut ffi_cif,
    pub translate_args: ::std::option::Option<unsafe extern "C" fn(arg1:
                                                                       *mut ffi_cif,
                                                                   arg2:
                                                                       *mut ::std::os::raw::c_void,
                                                                   arg3:
                                                                       *mut *mut ::std::os::raw::c_void,
                                                                   arg4:
                                                                       *mut ::std::os::raw::c_void)>,
    pub this_closure: *mut ::std::os::raw::c_void,
    pub fun: ::std::option::Option<unsafe extern "C" fn(arg1: *mut ffi_cif,
                                                        arg2:
                                                            *mut ::std::os::raw::c_void,
                                                        arg3: *mut ffi_raw,
                                                        arg4:
                                                            *mut ::std::os::raw::c_void)>,
    pub user_data: *mut ::std::os::raw::c_void,
}
impl ::std::default::Default for ffi_raw_closure {
    fn default() -> Self { unsafe { ::std::mem::zeroed() } }
}
#[repr(C)]
#[derive(Copy, Clone)]
#[derive(Debug)]
pub struct ffi_java_raw_closure {
    pub tramp: [::std::os::raw::c_char; 24usize],
    pub cif: *mut ffi_cif,
    pub translate_args: ::std::option::Option<unsafe extern "C" fn(arg1:
                                                                       *mut ffi_cif,
                                                                   arg2:
                                                                       *mut ::std::os::raw::c_void,
                                                                   arg3:
                                                                       *mut *mut ::std::os::raw::c_void,
                                                                   arg4:
                                                                       *mut ::std::os::raw::c_void)>,
    pub this_closure: *mut ::std::os::raw::c_void,
    pub fun: ::std::option::Option<unsafe extern "C" fn(arg1: *mut ffi_cif,
                                                        arg2:
                                                            *mut ::std::os::raw::c_void,
                                                        arg3:
                                                            *mut ffi_java_raw,
                                                        arg4:
                                                            *mut ::std::os::raw::c_void)>,
    pub user_data: *mut ::std::os::raw::c_void,
}
impl ::std::default::Default for ffi_java_raw_closure {
    fn default() -> Self { unsafe { ::std::mem::zeroed() } }
}
#[derive(Copy, Clone)]
#[repr(u32)]
#[derive(Debug)]
pub enum ffi_type_enum { STRUCT = 13, COMPLEX = 15, }
extern "C" {
    pub static mut ffi_type_void: ffi_type;
    pub static mut ffi_type_uint8: ffi_type;
    pub static mut ffi_type_sint8: ffi_type;
    pub static mut ffi_type_uint16: ffi_type;
    pub static mut ffi_type_sint16: ffi_type;
    pub static mut ffi_type_uint32: ffi_type;
    pub static mut ffi_type_sint32: ffi_type;
    pub static mut ffi_type_uint64: ffi_type;
    pub static mut ffi_type_sint64: ffi_type;
    pub static mut ffi_type_float: ffi_type;
    pub static mut ffi_type_double: ffi_type;
    pub static mut ffi_type_pointer: ffi_type;
    pub static mut ffi_type_longdouble: ffi_type;
    pub static mut ffi_type_complex_float: ffi_type;
    pub static mut ffi_type_complex_double: ffi_type;
    pub static mut ffi_type_complex_longdouble: ffi_type;
}
extern "C" {
    pub fn ffi_prep_cif_core(cif: *mut ffi_cif, abi: ffi_abi,
                             isvariadic: ::std::os::raw::c_uint,
                             nfixedargs: ::std::os::raw::c_uint,
                             ntotalargs: ::std::os::raw::c_uint,
                             rtype: *mut ffi_type, atypes: *mut *mut ffi_type)
     -> ffi_status;
    pub fn ffi_raw_call(cif: *mut ffi_cif,
                        fn_: ::std::option::Option<extern "C" fn()>,
                        rvalue: *mut ::std::os::raw::c_void,
                        avalue: *mut ffi_raw);
    pub fn ffi_ptrarray_to_raw(cif: *mut ffi_cif,
                               args: *mut *mut ::std::os::raw::c_void,
                               raw: *mut ffi_raw);
    pub fn ffi_raw_to_ptrarray(cif: *mut ffi_cif, raw: *mut ffi_raw,
                               args: *mut *mut ::std::os::raw::c_void);
    pub fn ffi_raw_size(cif: *mut ffi_cif) -> size_t;
    pub fn ffi_java_raw_call(cif: *mut ffi_cif,
                             fn_: ::std::option::Option<extern "C" fn()>,
                             rvalue: *mut ::std::os::raw::c_void,
                             avalue: *mut ffi_java_raw);
    pub fn ffi_java_ptrarray_to_raw(cif: *mut ffi_cif,
                                    args: *mut *mut ::std::os::raw::c_void,
                                    raw: *mut ffi_java_raw);
    pub fn ffi_java_raw_to_ptrarray(cif: *mut ffi_cif, raw: *mut ffi_java_raw,
                                    args: *mut *mut ::std::os::raw::c_void);
    pub fn ffi_java_raw_size(cif: *mut ffi_cif) -> size_t;
    pub fn ffi_closure_alloc(size: size_t,
                             code: *mut *mut ::std::os::raw::c_void)
     -> *mut ::std::os::raw::c_void;
    pub fn ffi_closure_free(arg1: *mut ::std::os::raw::c_void);
    pub fn ffi_prep_closure(arg1: *mut ffi_closure, arg2: *mut ffi_cif,
                            fun:
                                ::std::option::Option<unsafe extern "C" fn(arg1:
                                                                               *mut ffi_cif,
                                                                           arg2:
                                                                               *mut ::std::os::raw::c_void,
                                                                           arg3:
                                                                               *mut *mut ::std::os::raw::c_void,
                                                                           arg4:
                                                                               *mut ::std::os::raw::c_void)>,
                            user_data: *mut ::std::os::raw::c_void)
     -> ffi_status;
    pub fn ffi_prep_closure_loc(arg1: *mut ffi_closure, arg2: *mut ffi_cif,
                                fun:
                                    ::std::option::Option<unsafe extern "C" fn(arg1:
                                                                                *mut ffi_cif,
                                                                               arg2:
                                                                                *mut ::std::os::raw::c_void,
                                                                               arg3:
                                                                                *mut *mut ::std::os::raw::c_void,
                                                                               arg4:
                                                                                *mut ::std::os::raw::c_void)>,
                                user_data: *mut ::std::os::raw::c_void,
                                codeloc: *mut ::std::os::raw::c_void)
     -> ffi_status;
    pub fn ffi_prep_raw_closure(arg1: *mut ffi_raw_closure, cif: *mut ffi_cif,
                                fun:
                                    ::std::option::Option<unsafe extern "C" fn(arg1:
                                                                                *mut ffi_cif,
                                                                               arg2:
                                                                                *mut ::std::os::raw::c_void,
                                                                               arg3:
                                                                                *mut ffi_raw,
                                                                               arg4:
                                                                                *mut ::std::os::raw::c_void)>,
                                user_data: *mut ::std::os::raw::c_void)
     -> ffi_status;
    pub fn ffi_prep_raw_closure_loc(arg1: *mut ffi_raw_closure,
                                    cif: *mut ffi_cif,
                                    fun:
                                        ::std::option::Option<unsafe extern "C" fn(arg1:
                                                                                *mut ffi_cif,
                                                                                arg2:
                                                                                *mut ::std::os::raw::c_void,
                                                                                arg3:
                                                                                *mut ffi_raw,
                                                                                arg4:
                                                                                *mut ::std::os::raw::c_void)>,
                                    user_data: *mut ::std::os::raw::c_void,
                                    codeloc: *mut ::std::os::raw::c_void)
     -> ffi_status;
    pub fn ffi_prep_java_raw_closure(arg1: *mut ffi_java_raw_closure,
                                     cif: *mut ffi_cif,
                                     fun:
                                         ::std::option::Option<unsafe extern "C" fn(arg1:
                                                                                *mut ffi_cif,
                                                                                arg2:
                                                                                *mut ::std::os::raw::c_void,
                                                                                arg3:
                                                                                *mut ffi_java_raw,
                                                                                arg4:
                                                                                *mut ::std::os::raw::c_void)>,
                                     user_data: *mut ::std::os::raw::c_void)
     -> ffi_status;
    pub fn ffi_prep_java_raw_closure_loc(arg1: *mut ffi_java_raw_closure,
                                         cif: *mut ffi_cif,
                                         fun:
                                             ::std::option::Option<unsafe extern "C" fn(arg1:
                                                                                *mut ffi_cif,
                                                                                arg2:
                                                                                *mut ::std::os::raw::c_void,
                                                                                arg3:
                                                                                *mut ffi_java_raw,
                                                                                arg4:
                                                                                *mut ::std::os::raw::c_void)>,
                                         user_data:
                                             *mut ::std::os::raw::c_void,
                                         codeloc: *mut ::std::os::raw::c_void)
     -> ffi_status;
    pub fn ffi_prep_cif(cif: *mut ffi_cif, abi: ffi_abi,
                        nargs: ::std::os::raw::c_uint, rtype: *mut ffi_type,
                        atypes: *mut *mut ffi_type) -> ffi_status;
    pub fn ffi_prep_cif_var(cif: *mut ffi_cif, abi: ffi_abi,
                            nfixedargs: ::std::os::raw::c_uint,
                            ntotalargs: ::std::os::raw::c_uint,
                            rtype: *mut ffi_type, atypes: *mut *mut ffi_type)
     -> ffi_status;
    pub fn ffi_call(cif: *mut ffi_cif,
                    fn_: ::std::option::Option<extern "C" fn()>,
                    rvalue: *mut ::std::os::raw::c_void,
                    avalue: *mut *mut ::std::os::raw::c_void);
}
<commit_msg>fixed .gitignore to ignore bindgen code<commit_after><|endoftext|>


<commit_before>#![allow(unused_variables)]
use domains::Transition;

pub trait Algorithm<S, A> {
    fn handle_transition(&mut self, transition: &Transition<S, A>);
    fn handle_terminal(&mut self, sample: &S);
}

pub trait BatchAlgorithm<S, A>: Algorithm<S, A> {
    fn solve(&mut self);

    fn handle_batch(&mut self, transitions: &Vec<Transition<S, A>>) {
        use domains::Observation::Terminal;

        transitions.into_iter().rev().for_each(|t| {
            self.handle_transition(t);

            if let Terminal(s) = t.to {
                self.handle_terminal(s);
            }
        });

        self.solve();
    }
}

pub trait Controller<S, A>: Algorithm<S, A> {
    /// Sample the target policy for a given state `s`.
    fn sample_target(&mut self, s: &S) -> A;

    /// Sample the behaviour policy for a given state `s`.
    fn sample_behaviour(&mut self, s: &S) -> A;
}

pub trait Predictor<S, A>: Algorithm<S, A> {
    fn predict_v(&mut self, s: &S) -> f64 { unimplemented!() }
    fn predict_qs(&mut self, s: &S) -> Vector<f64> { unimplemented!() }
    fn predict_qsa(&mut self, s: &S, a: A) -> f64 { self.predict_v(s) }
}

mod memory;
pub use self::memory::*;

mod parameter;
pub use self::parameter::Parameter;

mod experiment;
pub use self::experiment::*;

mod trace;
pub use self::trace::*;

pub use geometry::{Matrix, Vector};
<commit_msg>refactor(core): rename BatchAlgorithm::solve to BatchAlgorithm::consolidate<commit_after>#![allow(unused_variables)]
use domains::Transition;

pub trait Algorithm<S, A> {
    fn handle_transition(&mut self, transition: &Transition<S, A>);
    fn handle_terminal(&mut self, sample: &S);
}

pub trait BatchAlgorithm<S, A>: Algorithm<S, A> {
    fn consolidate(&mut self);

    fn handle_batch(&mut self, transitions: &Vec<Transition<S, A>>) {
        use domains::Observation::Terminal;

        transitions.into_iter().rev().for_each(|t| {
            self.handle_transition(t);

            if let Terminal(s) = t.to {
                self.handle_terminal(s);
            }
        });

        self.consolidate();
    }
}

pub trait Controller<S, A>: Algorithm<S, A> {
    /// Sample the target policy for a given state `s`.
    fn sample_target(&mut self, s: &S) -> A;

    /// Sample the behaviour policy for a given state `s`.
    fn sample_behaviour(&mut self, s: &S) -> A;
}

pub trait Predictor<S, A>: Algorithm<S, A> {
    fn predict_v(&mut self, s: &S) -> f64 { unimplemented!() }
    fn predict_qs(&mut self, s: &S) -> Vector<f64> { unimplemented!() }
    fn predict_qsa(&mut self, s: &S, a: A) -> f64 { self.predict_v(s) }
}

mod memory;
pub use self::memory::*;

mod parameter;
pub use self::parameter::Parameter;

mod experiment;
pub use self::experiment::*;

mod trace;
pub use self::trace::*;

pub use geometry::{Matrix, Vector};
<|endoftext|>


<commit_before>use std::cmp:: { PartialEq, PartialOrd, Ordering };
use std::fmt:: { Display, Binary, Formatter, Result };

#[derive(Debug)]
pub struct Coverage(f64);

impl Coverage {
    pub fn new(value: f64) -> Self {
        Coverage(value)
    }
    pub fn percent(&self) -> f64 {
        self.0 * 100.0
    }
}

impl PartialEq for Coverage {
    fn eq(&self, other: &Self) -> bool {
        self.0 == other.0
    }
    fn ne(&self, other: &Self) -> bool {
        self.0 != other.0
    }
}

impl PartialOrd for Coverage {
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
        self.0.partial_cmp(&other.0)
    }
    fn lt(&self, other: &Self) -> bool {
        self.0 < other.0
    }
    fn le(&self, other: &Self) -> bool {
        self.0 <= other.0
    }
    fn gt(&self, other: &Self) -> bool {
        self.0 > other.0
    }
    fn ge(&self, other: &Self) -> bool {
        self.0 >= other.0
    }
}

impl Display for Coverage {
    fn fmt(&self, f: &mut Formatter) -> Result {
        write!(f, "{}%", self.percent())
    }
}

impl Binary for Coverage {
    fn fmt(&self, f: &mut Formatter) -> Result {
        let decimals = f.precision().unwrap_or(2);
        let string = format!("{:.*}", decimals, self.percent());
        f.pad_integral(true, "", &string)
    }
}

#[cfg(test)]
mod tests {
    use coverage:: { Coverage };

    #[test]
    fn test_eq() {
        let v1 = Coverage::new(1.0);
        let v2 = Coverage::new(1.0);
        assert_eq!(v1, v2);
    }

    #[test]
    fn test_not_eq() {
        let v1 = Coverage::new(1.0);
        let v2 = Coverage::new(2.0);
        assert!(v1 != v2);
    }

    #[test]
    fn test_less() {
        let v1 = Coverage::new(1.0);
        let v2 = Coverage::new(2.0);
        assert!(v1 < v2);
    }

    #[test]
    fn test_less_eq() {
        let v1 = Coverage::new(2.0);
        let v2 = Coverage::new(2.0);
        assert!(v1 <= v2);

        let v1 = Coverage::new(1.0);
        let v2 = Coverage::new(2.0);
        assert!(v1 <= v2);
    }

    #[test]
    fn test_greater() {
        let v1 = Coverage::new(2.0);
        let v2 = Coverage::new(1.0);
        assert!(v1 > v2);
    }

    #[test]
    fn test_greater_eq() {
        let v1 = Coverage::new(2.0);
        let v2 = Coverage::new(1.0);
        assert!(v1 >= v2);

        let v1 = Coverage::new(2.0);
        let v2 = Coverage::new(2.0);
        assert!(v1 >= v2);
    }

    #[test]
    fn test_format_for_display() {
        let v = Coverage::new(1.0);
        println!("{}", v);
    }

    #[test]
    fn test_format_for_binary() {
        let v = Coverage::new(1.0);
        println!("{:10.3b}", v);
    }
}
<commit_msg>Add module header<commit_after>// Copyright (c) 2016 lcov-tool developers
//
// Licensed under the Apache License, Version 2.0
// <LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0> or the MIT
// license <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. All files in the project carrying such notice may not be copied,
// modified, or distributed except according to those terms.

//! Module of code coverage

use std::cmp:: { PartialEq, PartialOrd, Ordering };
use std::fmt:: { Display, Binary, Formatter, Result };

#[derive(Debug)]
pub struct Coverage(f64);

impl Coverage {
    pub fn new(value: f64) -> Self {
        Coverage(value)
    }
    pub fn percent(&self) -> f64 {
        self.0 * 100.0
    }
}

impl PartialEq for Coverage {
    fn eq(&self, other: &Self) -> bool {
        self.0 == other.0
    }
    fn ne(&self, other: &Self) -> bool {
        self.0 != other.0
    }
}

impl PartialOrd for Coverage {
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
        self.0.partial_cmp(&other.0)
    }
    fn lt(&self, other: &Self) -> bool {
        self.0 < other.0
    }
    fn le(&self, other: &Self) -> bool {
        self.0 <= other.0
    }
    fn gt(&self, other: &Self) -> bool {
        self.0 > other.0
    }
    fn ge(&self, other: &Self) -> bool {
        self.0 >= other.0
    }
}

impl Display for Coverage {
    fn fmt(&self, f: &mut Formatter) -> Result {
        write!(f, "{}%", self.percent())
    }
}

impl Binary for Coverage {
    fn fmt(&self, f: &mut Formatter) -> Result {
        let decimals = f.precision().unwrap_or(2);
        let string = format!("{:.*}", decimals, self.percent());
        f.pad_integral(true, "", &string)
    }
}

#[cfg(test)]
mod tests {
    use coverage:: { Coverage };

    #[test]
    fn test_eq() {
        let v1 = Coverage::new(1.0);
        let v2 = Coverage::new(1.0);
        assert_eq!(v1, v2);
    }

    #[test]
    fn test_not_eq() {
        let v1 = Coverage::new(1.0);
        let v2 = Coverage::new(2.0);
        assert!(v1 != v2);
    }

    #[test]
    fn test_less() {
        let v1 = Coverage::new(1.0);
        let v2 = Coverage::new(2.0);
        assert!(v1 < v2);
    }

    #[test]
    fn test_less_eq() {
        let v1 = Coverage::new(2.0);
        let v2 = Coverage::new(2.0);
        assert!(v1 <= v2);

        let v1 = Coverage::new(1.0);
        let v2 = Coverage::new(2.0);
        assert!(v1 <= v2);
    }

    #[test]
    fn test_greater() {
        let v1 = Coverage::new(2.0);
        let v2 = Coverage::new(1.0);
        assert!(v1 > v2);
    }

    #[test]
    fn test_greater_eq() {
        let v1 = Coverage::new(2.0);
        let v2 = Coverage::new(1.0);
        assert!(v1 >= v2);

        let v1 = Coverage::new(2.0);
        let v2 = Coverage::new(2.0);
        assert!(v1 >= v2);
    }

    #[test]
    fn test_format_for_display() {
        let v = Coverage::new(1.0);
        println!("{}", v);
    }

    #[test]
    fn test_format_for_binary() {
        let v = Coverage::new(1.0);
        println!("{:10.3b}", v);
    }
}
<|endoftext|>