<commit_before>// run-pass

#![feature(generators)]

#![allow(non_camel_case_types)]
#![allow(dead_code)]
#![allow(unreachable_code)]
#![allow(unused_braces, unused_must_use, unused_parens)]

#![recursion_limit = "256"]

use std::cell::Cell;
use std::mem::swap;

// Just a grab bag of stuff that you wouldn't want to actually write.

fn strange() -> bool { let _x: bool = return true; }

fn funny() {
    fn f(_x: ()) { }
    f(return);
}

fn what() {
    fn the(x: &Cell<bool>) {
        return while !x.get() { x.set(true); };
    }
    let i = &Cell::new(false);
    let dont = {||the(i)};
    dont();
    assert!((i.get()));
}

fn zombiejesus() {
    loop {
        while (return) {
            if (return) {
                match (return) {
                    1 => {
                        if (return) {
                            return
                        } else {
                            return
                        }
                    }
                    _ => { return }
                };
            } else if (return) {
                return;
            }
        }
        if (return) { break; }
    }
}

fn notsure() {
    let mut _x: isize;
    let mut _y = (_x = 0) == (_x = 0);
    let mut _z = (_x = 0) < (_x = 0);
    let _a = (_x += 0) == (_x = 0);
    let _b = swap(&mut _y, &mut _z) == swap(&mut _y, &mut _z);
}

fn canttouchthis() -> usize {
    fn p() -> bool { true }
    let _a = (assert!((true)) == (assert!(p())));
    let _c = (assert!((p())) == ());
    let _b: bool = (println!("{}", 0) == (return 0));
}

fn angrydome() {
    loop { if break { } }
    let mut i = 0;
    loop { i += 1; if i == 1 { match (continue) { 1 => { }, _ => panic!("wat") } }
      break; }
}

fn evil_lincoln() { let _evil = println!("lincoln"); }

fn dots() {
    assert_eq!(String::from(".................................................."),
               format!("{:?}", .. .. .. .. .. .. .. .. .. .. .. .. ..
                               .. .. .. .. .. .. .. .. .. .. .. ..));
}

fn u8(u8: u8) {
    if u8 != 0u8 {
        assert_eq!(8u8, {
            macro_rules! u8 {
                (u8) => {
                    mod u8 {
                        pub fn u8<'u8: 'u8 + 'u8>(u8: &'u8 u8) -> &'u8 u8 {
                            "u8";
                            u8
                        }
                    }
                };
            }

            u8!(u8);
            let &u8: &u8 = u8::u8(&8u8);
            ::u8(0u8);
            u8
        });
    }
}

fn fishy() {
    assert_eq!(String::from("><>"),
               String::<>::from::<>("><>").chars::<>().rev::<>().collect::<String>());
}

fn union() {
    union union<'union> { union: &'union union<'union>, }
}

fn special_characters() {
    let val = !((|(..):(_,_),__@_|__)((&*"\\",'🤔')/**/,{})=={&[..=..][..];})//
    ;
    assert!(!val);
}

fn punch_card() -> impl std::fmt::Debug {
    ..=..=.. ..    .. .. .. ..    .. .. .. ..    .. ..=.. ..
    ..=.. ..=..    .. .. .. ..    .. .. .. ..    ..=..=..=..
    ..=.. ..=..    ..=.. ..=..    .. ..=..=..    .. ..=.. ..
    ..=..=.. ..    ..=.. ..=..    ..=.. .. ..    .. ..=.. ..
    ..=.. ..=..    ..=.. ..=..    .. ..=.. ..    .. ..=.. ..
    ..=.. ..=..    ..=.. ..=..    .. .. ..=..    .. ..=.. ..
    ..=.. ..=..    .. ..=..=..    ..=..=.. ..    .. ..=.. ..
}

fn r#match() {
    let val = match match match match match () {
        () => ()
    } {
        () => ()
    } {
        () => ()
    } {
        () => ()
    } {
        () => ()
    };
    assert_eq!(val, ());
}

fn i_yield() {
    static || {
        yield yield yield yield yield yield yield yield yield;
    };
}

fn match_nested_if() {
    let val = match () {
        () if if if if true {true} else {false} {true} else {false} {true} else {false} => true,
        _ => false,
    };
    assert!(val);
}

pub fn main() {
    strange();
    funny();
    what();
    zombiejesus();
    notsure();
    canttouchthis();
    angrydome();
    evil_lincoln();
    dots();
    u8(8u8);
    fishy();
    union();
    special_characters();
    punch_card();
    r#match();
    i_yield();
    match_nested_if();
}
<commit_msg>test: add `()=()=()=...` to weird-exprs.rs<commit_after>// run-pass

#![feature(generators)]
#![feature(destructuring_assignment)]

#![allow(non_camel_case_types)]
#![allow(dead_code)]
#![allow(unreachable_code)]
#![allow(unused_braces, unused_must_use, unused_parens)]

#![recursion_limit = "256"]

use std::cell::Cell;
use std::mem::swap;

// Just a grab bag of stuff that you wouldn't want to actually write.

fn strange() -> bool { let _x: bool = return true; }

fn funny() {
    fn f(_x: ()) { }
    f(return);
}

fn what() {
    fn the(x: &Cell<bool>) {
        return while !x.get() { x.set(true); };
    }
    let i = &Cell::new(false);
    let dont = {||the(i)};
    dont();
    assert!((i.get()));
}

fn zombiejesus() {
    loop {
        while (return) {
            if (return) {
                match (return) {
                    1 => {
                        if (return) {
                            return
                        } else {
                            return
                        }
                    }
                    _ => { return }
                };
            } else if (return) {
                return;
            }
        }
        if (return) { break; }
    }
}

fn notsure() {
    let mut _x: isize;
    let mut _y = (_x = 0) == (_x = 0);
    let mut _z = (_x = 0) < (_x = 0);
    let _a = (_x += 0) == (_x = 0);
    let _b = swap(&mut _y, &mut _z) == swap(&mut _y, &mut _z);
}

fn canttouchthis() -> usize {
    fn p() -> bool { true }
    let _a = (assert!((true)) == (assert!(p())));
    let _c = (assert!((p())) == ());
    let _b: bool = (println!("{}", 0) == (return 0));
}

fn angrydome() {
    loop { if break { } }
    let mut i = 0;
    loop { i += 1; if i == 1 { match (continue) { 1 => { }, _ => panic!("wat") } }
      break; }
}

fn evil_lincoln() { let _evil = println!("lincoln"); }

fn dots() {
    assert_eq!(String::from(".................................................."),
               format!("{:?}", .. .. .. .. .. .. .. .. .. .. .. .. ..
                               .. .. .. .. .. .. .. .. .. .. .. ..));
}

fn u8(u8: u8) {
    if u8 != 0u8 {
        assert_eq!(8u8, {
            macro_rules! u8 {
                (u8) => {
                    mod u8 {
                        pub fn u8<'u8: 'u8 + 'u8>(u8: &'u8 u8) -> &'u8 u8 {
                            "u8";
                            u8
                        }
                    }
                };
            }

            u8!(u8);
            let &u8: &u8 = u8::u8(&8u8);
            ::u8(0u8);
            u8
        });
    }
}

fn fishy() {
    assert_eq!(String::from("><>"),
               String::<>::from::<>("><>").chars::<>().rev::<>().collect::<String>());
}

fn union() {
    union union<'union> { union: &'union union<'union>, }
}

fn special_characters() {
    let val = !((|(..):(_,_),__@_|__)((&*"\\",'🤔')/**/,{})=={&[..=..][..];})//
    ;
    assert!(!val);
}

fn punch_card() -> impl std::fmt::Debug {
    ..=..=.. ..    .. .. .. ..    .. .. .. ..    .. ..=.. ..
    ..=.. ..=..    .. .. .. ..    .. .. .. ..    ..=..=..=..
    ..=.. ..=..    ..=.. ..=..    .. ..=..=..    .. ..=.. ..
    ..=..=.. ..    ..=.. ..=..    ..=.. .. ..    .. ..=.. ..
    ..=.. ..=..    ..=.. ..=..    .. ..=.. ..    .. ..=.. ..
    ..=.. ..=..    ..=.. ..=..    .. .. ..=..    .. ..=.. ..
    ..=.. ..=..    .. ..=..=..    ..=..=.. ..    .. ..=.. ..
}

fn r#match() {
    let val = match match match match match () {
        () => ()
    } {
        () => ()
    } {
        () => ()
    } {
        () => ()
    } {
        () => ()
    };
    assert_eq!(val, ());
}

fn i_yield() {
    static || {
        yield yield yield yield yield yield yield yield yield;
    };
}

fn match_nested_if() {
    let val = match () {
        () if if if if true {true} else {false} {true} else {false} {true} else {false} => true,
        _ => false,
    };
    assert!(val);
}

fn empty_tuple_assignment() {
    let val = ()=()=()=()=()=()=()=()=()=()=()=()=()=()=()=()=()=()=()=()=()=()=()=()=();
    assert_eq!(val, ());
}

pub fn main() {
    strange();
    funny();
    what();
    zombiejesus();
    notsure();
    canttouchthis();
    angrydome();
    evil_lincoln();
    dots();
    u8(8u8);
    fishy();
    union();
    special_characters();
    punch_card();
    r#match();
    i_yield();
    match_nested_if();
    empty_tuple_assignment();
}
<|endoftext|>


<commit_before>use std::fs::{File, OpenOptions};
use std::io;
use std::io::prelude::*;
use std::io::ErrorKind;
use std::path::{Path, PathBuf};

pub fn create(pass: Option<&str>, lint_name: Option<&str>, category: Option<&str>) -> Result<(), io::Error> {
    let pass = pass.expect("`pass` argument is validated by clap");
    let lint_name = lint_name.expect("`name` argument is validated by clap");
    let category = category.expect("`category` argument is validated by clap");

    match open_files(lint_name) {
        Ok((mut test_file, mut lint_file)) => {
            let (pass_type, pass_import, context_import) = match pass {
                "early" => ("EarlyLintPass", "use syntax::ast::*;", "EarlyContext"),
                "late" => ("LateLintPass", "use rustc_hir::*;", "LateContext"),
                _ => {
                    unreachable!("`pass_type` should only ever be `early` or `late`!");
                },
            };

            let camel_case_name = to_camel_case(lint_name);

            if let Err(e) = test_file.write_all(get_test_file_contents(lint_name).as_bytes()) {
                return Err(io::Error::new(
                    ErrorKind::Other,
                    format!("Could not write to test file: {}", e),
                ));
            };

            if let Err(e) = lint_file.write_all(
                get_lint_file_contents(
                    pass_type,
                    lint_name,
                    &camel_case_name,
                    category,
                    pass_import,
                    context_import,
                )
                .as_bytes(),
            ) {
                return Err(io::Error::new(
                    ErrorKind::Other,
                    format!("Could not write to lint file: {}", e),
                ));
            }
            Ok(())
        },
        Err(e) => Err(io::Error::new(
            ErrorKind::Other,
            format!("Unable to create lint: {}", e),
        )),
    }
}

fn open_files(lint_name: &str) -> Result<(File, File), io::Error> {
    let project_root = project_root()?;

    let test_file_path = project_root.join("tests").join("ui").join(format!("{}.rs", lint_name));
    let lint_file_path = project_root
        .join("clippy_lints")
        .join("src")
        .join(format!("{}.rs", lint_name));

    if Path::new(&test_file_path).exists() {
        return Err(io::Error::new(
            ErrorKind::AlreadyExists,
            format!("test file {:?} already exists", test_file_path),
        ));
    }
    if Path::new(&lint_file_path).exists() {
        return Err(io::Error::new(
            ErrorKind::AlreadyExists,
            format!("lint file {:?} already exists", lint_file_path),
        ));
    }

    let test_file = OpenOptions::new().write(true).create_new(true).open(test_file_path)?;
    let lint_file = OpenOptions::new().write(true).create_new(true).open(lint_file_path)?;

    Ok((test_file, lint_file))
}

fn project_root() -> Result<PathBuf, io::Error> {
    let current_dir = std::env::current_dir()?;
    for path in current_dir.ancestors() {
        let result = std::fs::read_to_string(path.join("Cargo.toml"));
        if let Err(err) = &result {
            if err.kind() == io::ErrorKind::NotFound {
                continue;
            }
        }

        let content = result?;
        if content.contains("[package]\nname = \"clippy\"") {
            return Ok(path.to_path_buf());
        }
    }
    Err(io::Error::new(ErrorKind::Other, "Unable to find project root"))
}

fn to_camel_case(name: &str) -> String {
    name.split('_')
        .map(|s| {
            if s.is_empty() {
                String::from("")
            } else {
                [&s[0..1].to_uppercase(), &s[1..]].concat()
            }
        })
        .collect()
}

fn get_test_file_contents(lint_name: &str) -> String {
    format!(
        "#![warn(clippy::{})]

fn main() {{
    // test code goes here
}}
",
        lint_name
    )
}

fn get_lint_file_contents(
    pass_type: &str,
    lint_name: &str,
    camel_case_name: &str,
    category: &str,
    pass_import: &str,
    context_import: &str,
) -> String {
    format!(
        "use rustc_lint::{{LintArray, LintPass, {type}, {context_import}}};
use rustc_session::{{declare_lint_pass, declare_tool_lint}};
{pass_import}

declare_clippy_lint! {{
    /// **What it does:**
    ///
    /// **Why is this bad?**
    ///
    /// **Known problems:** None.
    ///
    /// **Example:**
    ///
    /// ```rust
    /// // example code
    /// ```
    pub {name_upper},
    {category},
    \"default lint description\"
}}

declare_lint_pass!({name_camel} => [{name_upper}]);

impl {type} for {name_camel} {{}}
",
        type=pass_type,
        name_upper=lint_name.to_uppercase(),
        name_camel=camel_case_name,
        category=category,
        pass_import=pass_import,
        context_import=context_import
    )
}

#[test]
fn test_camel_case() {
    let s = "a_lint";
    let s2 = to_camel_case(s);
    assert_eq!(s2, "ALint");

    let name = "a_really_long_new_lint";
    let name2 = to_camel_case(name);
    assert_eq!(name2, "AReallyLongNewLint");

    let name3 = "lint__name";
    let name4 = to_camel_case(name3);
    assert_eq!(name4, "LintName");
}
<commit_msg>Add lifetimes to `LateLintPass`<commit_after>use std::fs::{File, OpenOptions};
use std::io;
use std::io::prelude::*;
use std::io::ErrorKind;
use std::path::{Path, PathBuf};

pub fn create(pass: Option<&str>, lint_name: Option<&str>, category: Option<&str>) -> Result<(), io::Error> {
    let pass = pass.expect("`pass` argument is validated by clap");
    let lint_name = lint_name.expect("`name` argument is validated by clap");
    let category = category.expect("`category` argument is validated by clap");

    match open_files(lint_name) {
        Ok((mut test_file, mut lint_file)) => {
            let (pass_type, pass_lifetimes, pass_import, context_import) = match pass {
                "early" => ("EarlyLintPass", "", "use syntax::ast::*;", "EarlyContext"),
                "late" => ("LateLintPass", "<'_, '_>", "use rustc_hir::*;", "LateContext"),
                _ => {
                    unreachable!("`pass_type` should only ever be `early` or `late`!");
                },
            };

            let camel_case_name = to_camel_case(lint_name);

            if let Err(e) = test_file.write_all(get_test_file_contents(lint_name).as_bytes()) {
                return Err(io::Error::new(
                    ErrorKind::Other,
                    format!("Could not write to test file: {}", e),
                ));
            };

            if let Err(e) = lint_file.write_all(
                get_lint_file_contents(
                    pass_type,
                    pass_lifetimes,
                    lint_name,
                    &camel_case_name,
                    category,
                    pass_import,
                    context_import,
                )
                .as_bytes(),
            ) {
                return Err(io::Error::new(
                    ErrorKind::Other,
                    format!("Could not write to lint file: {}", e),
                ));
            }
            Ok(())
        },
        Err(e) => Err(io::Error::new(
            ErrorKind::Other,
            format!("Unable to create lint: {}", e),
        )),
    }
}

fn open_files(lint_name: &str) -> Result<(File, File), io::Error> {
    let project_root = project_root()?;

    let test_file_path = project_root.join("tests").join("ui").join(format!("{}.rs", lint_name));
    let lint_file_path = project_root
        .join("clippy_lints")
        .join("src")
        .join(format!("{}.rs", lint_name));

    if Path::new(&test_file_path).exists() {
        return Err(io::Error::new(
            ErrorKind::AlreadyExists,
            format!("test file {:?} already exists", test_file_path),
        ));
    }
    if Path::new(&lint_file_path).exists() {
        return Err(io::Error::new(
            ErrorKind::AlreadyExists,
            format!("lint file {:?} already exists", lint_file_path),
        ));
    }

    let test_file = OpenOptions::new().write(true).create_new(true).open(test_file_path)?;
    let lint_file = OpenOptions::new().write(true).create_new(true).open(lint_file_path)?;

    Ok((test_file, lint_file))
}

fn project_root() -> Result<PathBuf, io::Error> {
    let current_dir = std::env::current_dir()?;
    for path in current_dir.ancestors() {
        let result = std::fs::read_to_string(path.join("Cargo.toml"));
        if let Err(err) = &result {
            if err.kind() == io::ErrorKind::NotFound {
                continue;
            }
        }

        let content = result?;
        if content.contains("[package]\nname = \"clippy\"") {
            return Ok(path.to_path_buf());
        }
    }
    Err(io::Error::new(ErrorKind::Other, "Unable to find project root"))
}

fn to_camel_case(name: &str) -> String {
    name.split('_')
        .map(|s| {
            if s.is_empty() {
                String::from("")
            } else {
                [&s[0..1].to_uppercase(), &s[1..]].concat()
            }
        })
        .collect()
}

fn get_test_file_contents(lint_name: &str) -> String {
    format!(
        "#![warn(clippy::{})]

fn main() {{
    // test code goes here
}}
",
        lint_name
    )
}

fn get_lint_file_contents(
    pass_type: &str,
    pass_lifetimes: &str,
    lint_name: &str,
    camel_case_name: &str,
    category: &str,
    pass_import: &str,
    context_import: &str,
) -> String {
    format!(
        "use rustc_lint::{{LintArray, LintPass, {type}, {context_import}}};
use rustc_session::{{declare_lint_pass, declare_tool_lint}};
{pass_import}

declare_clippy_lint! {{
    /// **What it does:**
    ///
    /// **Why is this bad?**
    ///
    /// **Known problems:** None.
    ///
    /// **Example:**
    ///
    /// ```rust
    /// // example code
    /// ```
    pub {name_upper},
    {category},
    \"default lint description\"
}}

declare_lint_pass!({name_camel} => [{name_upper}]);

impl {type}{lifetimes} for {name_camel} {{}}
",
        type=pass_type,
        lifetimes=pass_lifetimes,
        name_upper=lint_name.to_uppercase(),
        name_camel=camel_case_name,
        category=category,
        pass_import=pass_import,
        context_import=context_import
    )
}

#[test]
fn test_camel_case() {
    let s = "a_lint";
    let s2 = to_camel_case(s);
    assert_eq!(s2, "ALint");

    let name = "a_really_long_new_lint";
    let name2 = to_camel_case(name);
    assert_eq!(name2, "AReallyLongNewLint");

    let name3 = "lint__name";
    let name4 = to_camel_case(name3);
    assert_eq!(name4, "LintName");
}
<|endoftext|>


<commit_before>#![feature(no_core, lang_items, intrinsics, unboxed_closures, type_ascription, extern_types, untagged_unions)]
#![no_core]
#![allow(dead_code)]

#[lang = "sized"]
pub trait Sized {}

#[lang = "unsize"]
pub trait Unsize<T: ?Sized> {}

#[lang = "coerce_unsized"]
pub trait CoerceUnsized<T> {}

impl<'a, 'b: 'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<&'a U> for &'b T {}
impl<'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<&'a mut U> for &'a mut T {}
impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*const U> for *const T {}
impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*mut U> for *mut T {}

#[lang = "dispatch_from_dyn"]
pub trait DispatchFromDyn<T> {}

// &T -> &U
impl<'a, T: ?Sized+Unsize<U>, U: ?Sized> DispatchFromDyn<&'a U> for &'a T {}
// &mut T -> &mut U
impl<'a, T: ?Sized+Unsize<U>, U: ?Sized> DispatchFromDyn<&'a mut U> for &'a mut T {}
// *const T -> *const U
impl<T: ?Sized+Unsize<U>, U: ?Sized> DispatchFromDyn<*const U> for *const T {}
// *mut T -> *mut U
impl<T: ?Sized+Unsize<U>, U: ?Sized> DispatchFromDyn<*mut U> for *mut T {}
impl<T: ?Sized + Unsize<U>, U: ?Sized> DispatchFromDyn<Box<U>> for Box<T> {}

#[lang = "receiver"]
pub trait Receiver {}

impl<T: ?Sized> Receiver for &T {}
impl<T: ?Sized> Receiver for &mut T {}
impl<T: ?Sized> Receiver for Box<T> {}

#[lang = "copy"]
pub unsafe trait Copy {}

unsafe impl Copy for bool {}
unsafe impl Copy for u8 {}
unsafe impl Copy for u16 {}
unsafe impl Copy for u32 {}
unsafe impl Copy for u64 {}
unsafe impl Copy for usize {}
unsafe impl Copy for i8 {}
unsafe impl Copy for i16 {}
unsafe impl Copy for i32 {}
unsafe impl Copy for isize {}
unsafe impl Copy for char {}
unsafe impl<'a, T: ?Sized> Copy for &'a T {}
unsafe impl<T: ?Sized> Copy for *const T {}
unsafe impl<T: ?Sized> Copy for *mut T {}

#[lang = "sync"]
pub unsafe trait Sync {}

unsafe impl Sync for bool {}
unsafe impl Sync for u8 {}
unsafe impl Sync for u16 {}
unsafe impl Sync for u32 {}
unsafe impl Sync for u64 {}
unsafe impl Sync for usize {}
unsafe impl Sync for i8 {}
unsafe impl Sync for i16 {}
unsafe impl Sync for i32 {}
unsafe impl Sync for isize {}
unsafe impl Sync for char {}
unsafe impl<'a, T: ?Sized> Sync for &'a T {}
unsafe impl Sync for [u8; 16] {}

#[lang = "freeze"]
trait Freeze {}

#[lang = "not"]
pub trait Not {
    type Output;

    fn not(self) -> Self::Output;
}

impl Not for bool {
    type Output = bool;

    fn not(self) -> bool {
        !self
    }
}

#[lang = "mul"]
pub trait Mul<RHS = Self> {
    type Output;

    #[must_use]
    fn mul(self, rhs: RHS) -> Self::Output;
}

impl Mul for u8 {
    type Output = Self;

    fn mul(self, rhs: Self) -> Self::Output {
        self * rhs
    }
}

impl Mul for usize {
    type Output = Self;

    fn mul(self, rhs: Self) -> Self::Output {
        self * rhs
    }
}

#[lang = "add"]
pub trait Add<RHS = Self> {
    type Output;

    fn add(self, rhs: RHS) -> Self::Output;
}

impl Add for u8 {
    type Output = Self;

    fn add(self, rhs: Self) -> Self {
        self + rhs
    }
}

impl Add for i8 {
    type Output = Self;

    fn add(self, rhs: Self) -> Self {
        self + rhs
    }
}

impl Add for usize {
    type Output = Self;

    fn add(self, rhs: Self) -> Self {
        self + rhs
    }
}

#[lang = "sub"]
pub trait Sub<RHS = Self> {
    type Output;

    fn sub(self, rhs: RHS) -> Self::Output;
}

impl Sub for usize {
    type Output = Self;

    fn sub(self, rhs: Self) -> Self {
        self - rhs
    }
}

impl Sub for u8 {
    type Output = Self;

    fn sub(self, rhs: Self) -> Self {
        self - rhs
    }
}

impl Sub for i8 {
    type Output = Self;

    fn sub(self, rhs: Self) -> Self {
        self - rhs
    }
}

impl Sub for i16 {
    type Output = Self;

    fn sub(self, rhs: Self) -> Self {
        self - rhs
    }
}

#[lang = "bitor"]
pub trait BitOr<RHS = Self> {
    type Output;

    #[must_use]
    fn bitor(self, rhs: RHS) -> Self::Output;
}

impl BitOr for bool {
    type Output = bool;

    fn bitor(self, rhs: bool) -> bool {
        self | rhs
    }
}

impl<'a> BitOr<bool> for &'a bool {
    type Output = bool;

    fn bitor(self, rhs: bool) -> bool {
        *self | rhs
    }
}

#[lang = "eq"]
pub trait PartialEq<Rhs: ?Sized = Self> {
    fn eq(&self, other: &Rhs) -> bool;
    fn ne(&self, other: &Rhs) -> bool;
}

impl PartialEq for u8 {
    fn eq(&self, other: &u8) -> bool {
        (*self) == (*other)
    }
    fn ne(&self, other: &u8) -> bool {
        (*self) != (*other)
    }
}

impl PartialEq for u16 {
    fn eq(&self, other: &u16) -> bool {
        (*self) == (*other)
    }
    fn ne(&self, other: &u16) -> bool {
        (*self) != (*other)
    }
}

impl PartialEq for u32 {
    fn eq(&self, other: &u32) -> bool {
        (*self) == (*other)
    }
    fn ne(&self, other: &u32) -> bool {
        (*self) != (*other)
    }
}

impl PartialEq for u64 {
    fn eq(&self, other: &u64) -> bool {
        (*self) == (*other)
    }
    fn ne(&self, other: &u64) -> bool {
        (*self) != (*other)
    }
}

impl PartialEq for usize {
    fn eq(&self, other: &usize) -> bool {
        (*self) == (*other)
    }
    fn ne(&self, other: &usize) -> bool {
        (*self) != (*other)
    }
}

impl PartialEq for i32 {
    fn eq(&self, other: &i32) -> bool {
        (*self) == (*other)
    }
    fn ne(&self, other: &i32) -> bool {
        (*self) != (*other)
    }
}

impl PartialEq for isize {
    fn eq(&self, other: &isize) -> bool {
        (*self) == (*other)
    }
    fn ne(&self, other: &isize) -> bool {
        (*self) != (*other)
    }
}

impl PartialEq for char {
    fn eq(&self, other: &char) -> bool {
        (*self) == (*other)
    }
    fn ne(&self, other: &char) -> bool {
        (*self) != (*other)
    }
}

impl<T: ?Sized> PartialEq for *const T {
    fn eq(&self, other: &*const T) -> bool {
        *self == *other
    }
    fn ne(&self, other: &*const T) -> bool {
        *self != *other
    }
}

#[lang = "neg"]
pub trait Neg {
    type Output;

    fn neg(self) -> Self::Output;
}

impl Neg for i8 {
    type Output = i8;

    fn neg(self) -> i8 {
        -self
    }
}

impl Neg for i16 {
    type Output = i16;

    fn neg(self) -> i16 {
        self
    }
}

impl Neg for isize {
    type Output = isize;

    fn neg(self) -> isize {
        -self
    }
}

pub enum Option<T> {
    Some(T),
    None,
}

pub use Option::*;

#[lang = "phantom_data"]
pub struct PhantomData<T: ?Sized>;

#[lang = "fn_once"]
#[rustc_paren_sugar]
pub trait FnOnce<Args> {
    type Output;

    extern "rust-call" fn call_once(self, args: Args) -> Self::Output;
}

#[lang = "fn_mut"]
#[rustc_paren_sugar]
pub trait FnMut<Args>: FnOnce<Args> {
    extern "rust-call" fn call_mut(&mut self, args: Args) -> Self::Output;
}

#[lang = "panic"]
// Make it available to jited mini_core_hello_world
// FIXME remove next line when jit supports linking rlibs
#[inline(always)]
pub fn panic(&(_msg, _file, _line, _col): &(&'static str, &'static str, u32, u32)) -> ! {
    unsafe {
        libc::puts("Panicking\0" as *const str as *const u8);
        intrinsics::abort();
    }
}

#[lang = "eh_personality"]
fn eh_personality() -> ! {
    loop {}
}

#[lang = "drop_in_place"]
#[allow(unconditional_recursion)]
pub unsafe fn drop_in_place<T: ?Sized>(to_drop: *mut T) {
    // Code here does not matter - this is replaced by the
    // real drop glue by the compiler.
    drop_in_place(to_drop);
}

#[lang = "deref"]
pub trait Deref {
    type Target: ?Sized;

    fn deref(&self) -> &Self::Target;
}

#[lang = "owned_box"]
pub struct Box<T: ?Sized>(*mut T);

impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<Box<U>> for Box<T> {}

impl<T: ?Sized> Drop for Box<T> {
    fn drop(&mut self) {
        // drop is currently performed by compiler.
    }
}

impl<T> Deref for Box<T> {
    type Target = T;

    fn deref(&self) -> &Self::Target {
        &**self
    }
}

#[lang = "exchange_malloc"]
// Make it available to jited mini_core_hello_world
// FIXME remove next line when jit supports linking rlibs
#[inline(always)]
unsafe fn allocate(size: usize, _align: usize) -> *mut u8 {
    libc::malloc(size)
}

#[lang = "box_free"]
#[inline(always)]
unsafe fn box_free<T: ?Sized>(ptr: *mut T) {
    libc::free(ptr as *mut u8);
}

#[lang = "drop"]
pub trait Drop {
    fn drop(&mut self);
}

pub union MaybeUninit<T> {
    pub uninit: (),
    pub value: T,
}

pub mod intrinsics {
    extern "rust-intrinsic" {
        pub fn abort() -> !;
        pub fn size_of<T>() -> usize;
        pub fn size_of_val<T: ?::Sized>(val: &T) -> usize;
        pub fn min_align_of<T>() -> usize;
        pub fn min_align_of_val<T: ?::Sized>(val: &T) -> usize;
        pub fn copy<T>(src: *const T, dst: *mut T, count: usize);
        pub fn transmute<T, U>(e: T) -> U;
        pub fn init<T>() -> T;
        pub fn ctlz_nonzero<T>(x: T) -> T;
        pub fn needs_drop<T>() -> bool;
        pub fn bitreverse<T>(x: T) -> T;
        pub fn bswap<T>(x: T) -> T;
    }
}

pub mod libc {
    #[link(name = "c")]
    extern "C" {
        pub fn puts(s: *const u8);
        pub fn printf(format: *const i8, ...) -> i32;
        pub fn malloc(size: usize) -> *mut u8;
        pub fn free(ptr: *mut u8);
        pub fn memcpy(dst: *mut u8, src: *const u8, size: usize);
        pub fn memmove(dst: *mut u8, src: *const u8, size: usize);
        pub fn strncpy(dst: *mut u8, src: *const u8, size: usize);
    }
}

#[lang = "index"]
pub trait Index<Idx: ?Sized> {
    type Output: ?Sized;
    fn index(&self, index: Idx) -> &Self::Output;
}

impl<T> Index<usize> for [T; 3] {
    type Output = T;

    fn index(&self, index: usize) -> &Self::Output {
        &self[index]
    }
}

impl<T> Index<usize> for [T] {
    type Output = T;

    fn index(&self, index: usize) -> &Self::Output {
        &self[index]
    }
}

extern {
    type VaListImpl;
}

#[lang = "va_list"]
#[repr(transparent)]
pub struct VaList<'a>(&'a mut VaListImpl);
<commit_msg>Rustup to rustc 1.38.0-nightly (c798dffac 2019-07-27)<commit_after>#![feature(
    no_core, lang_items, intrinsics, unboxed_closures, type_ascription, extern_types,
    untagged_unions, decl_macro, rustc_attrs
)]
#![no_core]
#![allow(dead_code)]

#[lang = "sized"]
pub trait Sized {}

#[lang = "unsize"]
pub trait Unsize<T: ?Sized> {}

#[lang = "coerce_unsized"]
pub trait CoerceUnsized<T> {}

impl<'a, 'b: 'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<&'a U> for &'b T {}
impl<'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<&'a mut U> for &'a mut T {}
impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*const U> for *const T {}
impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*mut U> for *mut T {}

#[lang = "dispatch_from_dyn"]
pub trait DispatchFromDyn<T> {}

// &T -> &U
impl<'a, T: ?Sized+Unsize<U>, U: ?Sized> DispatchFromDyn<&'a U> for &'a T {}
// &mut T -> &mut U
impl<'a, T: ?Sized+Unsize<U>, U: ?Sized> DispatchFromDyn<&'a mut U> for &'a mut T {}
// *const T -> *const U
impl<T: ?Sized+Unsize<U>, U: ?Sized> DispatchFromDyn<*const U> for *const T {}
// *mut T -> *mut U
impl<T: ?Sized+Unsize<U>, U: ?Sized> DispatchFromDyn<*mut U> for *mut T {}
impl<T: ?Sized + Unsize<U>, U: ?Sized> DispatchFromDyn<Box<U>> for Box<T> {}

#[lang = "receiver"]
pub trait Receiver {}

impl<T: ?Sized> Receiver for &T {}
impl<T: ?Sized> Receiver for &mut T {}
impl<T: ?Sized> Receiver for Box<T> {}

#[lang = "copy"]
pub unsafe trait Copy {}

unsafe impl Copy for bool {}
unsafe impl Copy for u8 {}
unsafe impl Copy for u16 {}
unsafe impl Copy for u32 {}
unsafe impl Copy for u64 {}
unsafe impl Copy for usize {}
unsafe impl Copy for i8 {}
unsafe impl Copy for i16 {}
unsafe impl Copy for i32 {}
unsafe impl Copy for isize {}
unsafe impl Copy for char {}
unsafe impl<'a, T: ?Sized> Copy for &'a T {}
unsafe impl<T: ?Sized> Copy for *const T {}
unsafe impl<T: ?Sized> Copy for *mut T {}

#[lang = "sync"]
pub unsafe trait Sync {}

unsafe impl Sync for bool {}
unsafe impl Sync for u8 {}
unsafe impl Sync for u16 {}
unsafe impl Sync for u32 {}
unsafe impl Sync for u64 {}
unsafe impl Sync for usize {}
unsafe impl Sync for i8 {}
unsafe impl Sync for i16 {}
unsafe impl Sync for i32 {}
unsafe impl Sync for isize {}
unsafe impl Sync for char {}
unsafe impl<'a, T: ?Sized> Sync for &'a T {}
unsafe impl Sync for [u8; 16] {}

#[lang = "freeze"]
trait Freeze {}

#[lang = "not"]
pub trait Not {
    type Output;

    fn not(self) -> Self::Output;
}

impl Not for bool {
    type Output = bool;

    fn not(self) -> bool {
        !self
    }
}

#[lang = "mul"]
pub trait Mul<RHS = Self> {
    type Output;

    #[must_use]
    fn mul(self, rhs: RHS) -> Self::Output;
}

impl Mul for u8 {
    type Output = Self;

    fn mul(self, rhs: Self) -> Self::Output {
        self * rhs
    }
}

impl Mul for usize {
    type Output = Self;

    fn mul(self, rhs: Self) -> Self::Output {
        self * rhs
    }
}

#[lang = "add"]
pub trait Add<RHS = Self> {
    type Output;

    fn add(self, rhs: RHS) -> Self::Output;
}

impl Add for u8 {
    type Output = Self;

    fn add(self, rhs: Self) -> Self {
        self + rhs
    }
}

impl Add for i8 {
    type Output = Self;

    fn add(self, rhs: Self) -> Self {
        self + rhs
    }
}

impl Add for usize {
    type Output = Self;

    fn add(self, rhs: Self) -> Self {
        self + rhs
    }
}

#[lang = "sub"]
pub trait Sub<RHS = Self> {
    type Output;

    fn sub(self, rhs: RHS) -> Self::Output;
}

impl Sub for usize {
    type Output = Self;

    fn sub(self, rhs: Self) -> Self {
        self - rhs
    }
}

impl Sub for u8 {
    type Output = Self;

    fn sub(self, rhs: Self) -> Self {
        self - rhs
    }
}

impl Sub for i8 {
    type Output = Self;

    fn sub(self, rhs: Self) -> Self {
        self - rhs
    }
}

impl Sub for i16 {
    type Output = Self;

    fn sub(self, rhs: Self) -> Self {
        self - rhs
    }
}

#[lang = "bitor"]
pub trait BitOr<RHS = Self> {
    type Output;

    #[must_use]
    fn bitor(self, rhs: RHS) -> Self::Output;
}

impl BitOr for bool {
    type Output = bool;

    fn bitor(self, rhs: bool) -> bool {
        self | rhs
    }
}

impl<'a> BitOr<bool> for &'a bool {
    type Output = bool;

    fn bitor(self, rhs: bool) -> bool {
        *self | rhs
    }
}

#[lang = "eq"]
pub trait PartialEq<Rhs: ?Sized = Self> {
    fn eq(&self, other: &Rhs) -> bool;
    fn ne(&self, other: &Rhs) -> bool;
}

impl PartialEq for u8 {
    fn eq(&self, other: &u8) -> bool {
        (*self) == (*other)
    }
    fn ne(&self, other: &u8) -> bool {
        (*self) != (*other)
    }
}

impl PartialEq for u16 {
    fn eq(&self, other: &u16) -> bool {
        (*self) == (*other)
    }
    fn ne(&self, other: &u16) -> bool {
        (*self) != (*other)
    }
}

impl PartialEq for u32 {
    fn eq(&self, other: &u32) -> bool {
        (*self) == (*other)
    }
    fn ne(&self, other: &u32) -> bool {
        (*self) != (*other)
    }
}

impl PartialEq for u64 {
    fn eq(&self, other: &u64) -> bool {
        (*self) == (*other)
    }
    fn ne(&self, other: &u64) -> bool {
        (*self) != (*other)
    }
}

impl PartialEq for usize {
    fn eq(&self, other: &usize) -> bool {
        (*self) == (*other)
    }
    fn ne(&self, other: &usize) -> bool {
        (*self) != (*other)
    }
}

impl PartialEq for i32 {
    fn eq(&self, other: &i32) -> bool {
        (*self) == (*other)
    }
    fn ne(&self, other: &i32) -> bool {
        (*self) != (*other)
    }
}

impl PartialEq for isize {
    fn eq(&self, other: &isize) -> bool {
        (*self) == (*other)
    }
    fn ne(&self, other: &isize) -> bool {
        (*self) != (*other)
    }
}

impl PartialEq for char {
    fn eq(&self, other: &char) -> bool {
        (*self) == (*other)
    }
    fn ne(&self, other: &char) -> bool {
        (*self) != (*other)
    }
}

impl<T: ?Sized> PartialEq for *const T {
    fn eq(&self, other: &*const T) -> bool {
        *self == *other
    }
    fn ne(&self, other: &*const T) -> bool {
        *self != *other
    }
}

#[lang = "neg"]
pub trait Neg {
    type Output;

    fn neg(self) -> Self::Output;
}

impl Neg for i8 {
    type Output = i8;

    fn neg(self) -> i8 {
        -self
    }
}

impl Neg for i16 {
    type Output = i16;

    fn neg(self) -> i16 {
        self
    }
}

impl Neg for isize {
    type Output = isize;

    fn neg(self) -> isize {
        -self
    }
}

pub enum Option<T> {
    Some(T),
    None,
}

pub use Option::*;

#[lang = "phantom_data"]
pub struct PhantomData<T: ?Sized>;

#[lang = "fn_once"]
#[rustc_paren_sugar]
pub trait FnOnce<Args> {
    type Output;

    extern "rust-call" fn call_once(self, args: Args) -> Self::Output;
}

#[lang = "fn_mut"]
#[rustc_paren_sugar]
pub trait FnMut<Args>: FnOnce<Args> {
    extern "rust-call" fn call_mut(&mut self, args: Args) -> Self::Output;
}

#[lang = "panic"]
// Make it available to jited mini_core_hello_world
// FIXME remove next line when jit supports linking rlibs
#[inline(always)]
pub fn panic(&(_msg, _file, _line, _col): &(&'static str, &'static str, u32, u32)) -> ! {
    unsafe {
        libc::puts("Panicking\0" as *const str as *const u8);
        intrinsics::abort();
    }
}

#[lang = "eh_personality"]
fn eh_personality() -> ! {
    loop {}
}

#[lang = "drop_in_place"]
#[allow(unconditional_recursion)]
pub unsafe fn drop_in_place<T: ?Sized>(to_drop: *mut T) {
    // Code here does not matter - this is replaced by the
    // real drop glue by the compiler.
    drop_in_place(to_drop);
}

#[lang = "deref"]
pub trait Deref {
    type Target: ?Sized;

    fn deref(&self) -> &Self::Target;
}

#[lang = "owned_box"]
pub struct Box<T: ?Sized>(*mut T);

impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<Box<U>> for Box<T> {}

impl<T: ?Sized> Drop for Box<T> {
    fn drop(&mut self) {
        // drop is currently performed by compiler.
    }
}

impl<T> Deref for Box<T> {
    type Target = T;

    fn deref(&self) -> &Self::Target {
        &**self
    }
}

#[lang = "exchange_malloc"]
// Make it available to jited mini_core_hello_world
// FIXME remove next line when jit supports linking rlibs
#[inline(always)]
unsafe fn allocate(size: usize, _align: usize) -> *mut u8 {
    libc::malloc(size)
}

#[lang = "box_free"]
#[inline(always)]
unsafe fn box_free<T: ?Sized>(ptr: *mut T) {
    libc::free(ptr as *mut u8);
}

#[lang = "drop"]
pub trait Drop {
    fn drop(&mut self);
}

pub union MaybeUninit<T> {
    pub uninit: (),
    pub value: T,
}

pub mod intrinsics {
    extern "rust-intrinsic" {
        pub fn abort() -> !;
        pub fn size_of<T>() -> usize;
        pub fn size_of_val<T: ?::Sized>(val: &T) -> usize;
        pub fn min_align_of<T>() -> usize;
        pub fn min_align_of_val<T: ?::Sized>(val: &T) -> usize;
        pub fn copy<T>(src: *const T, dst: *mut T, count: usize);
        pub fn transmute<T, U>(e: T) -> U;
        pub fn init<T>() -> T;
        pub fn ctlz_nonzero<T>(x: T) -> T;
        pub fn needs_drop<T>() -> bool;
        pub fn bitreverse<T>(x: T) -> T;
        pub fn bswap<T>(x: T) -> T;
    }
}

pub mod libc {
    #[link(name = "c")]
    extern "C" {
        pub fn puts(s: *const u8);
        pub fn printf(format: *const i8, ...) -> i32;
        pub fn malloc(size: usize) -> *mut u8;
        pub fn free(ptr: *mut u8);
        pub fn memcpy(dst: *mut u8, src: *const u8, size: usize);
        pub fn memmove(dst: *mut u8, src: *const u8, size: usize);
        pub fn strncpy(dst: *mut u8, src: *const u8, size: usize);
    }
}

#[lang = "index"]
pub trait Index<Idx: ?Sized> {
    type Output: ?Sized;
    fn index(&self, index: Idx) -> &Self::Output;
}

impl<T> Index<usize> for [T; 3] {
    type Output = T;

    fn index(&self, index: usize) -> &Self::Output {
        &self[index]
    }
}

impl<T> Index<usize> for [T] {
    type Output = T;

    fn index(&self, index: usize) -> &Self::Output {
        &self[index]
    }
}

extern {
    type VaListImpl;
}

#[lang = "va_list"]
#[repr(transparent)]
pub struct VaList<'a>(&'a mut VaListImpl);

#[rustc_builtin_macro]
#[rustc_macro_transparency = "semitransparent"]
pub macro stringify($($t:tt)*) { /* compiler built-in */ }

#[rustc_builtin_macro]
#[rustc_macro_transparency = "semitransparent"]
pub macro file() { /* compiler built-in */ }

#[rustc_builtin_macro]
#[rustc_macro_transparency = "semitransparent"]
pub macro line() { /* compiler built-in */ }
<|endoftext|>


<commit_before>extern mod glfw;

fn error_callback(_error: libc::c_int, description: ~str) {
    io::println(fmt!("GLFW Error: %s", description));
}

fn main() {
    glfw::set_error_callback(error_callback);

    do glfw::spawn {

        glfw::window_hint::visible(true);

        let window = glfw::Window::create(640, 480, "Defaults", glfw::Windowed).get();

        window.make_context_current();

        let (width, height) = window.get_size();
        io::println(fmt!("window size: %? x %?", width, height));

        println(fmt!("Context version major: %?",     window.get_context_version_major()));
        println(fmt!("Context version minor: %?",     window.get_context_version_minor()));
        println(fmt!("OpenGL forward compatible: %?", window.is_opengl_forward_compat()));
        println(fmt!("OpenGL debug context: %?",      window.is_opengl_debug_context()));
        println(fmt!("OpenGL profile: %?",            window.get_opengl_profile()));

        let gl_params = [
            (gl::RED_BITS,          None,   "red bits"          ),
            (gl::GREEN_BITS,        None,   "green bits"        ),
            (gl::BLUE_BITS,         None,   "blue bits"         ),
            (gl::ALPHA_BITS,        None,   "alpha bits"        ),
            (gl::DEPTH_BITS,        None,   "depth bits"        ),
            (gl::STENCIL_BITS,      None,   "stencil bits"      ),
            (gl::ACCUM_RED_BITS,    None,   "accum red bits"    ),
            (gl::ACCUM_GREEN_BITS,  None,   "accum green bits"  ),
            (gl::ACCUM_BLUE_BITS,   None,   "accum blue bits"   ),
            (gl::ACCUM_ALPHA_BITS,  None,   "accum alpha bits"  ),
            (gl::STEREO,            None,   "stereo"            ),
            (gl::SAMPLES_ARB,       Some("GL_ARB_multisample"), "FSAA samples" ),
        ];

        for gl_params.each |&p| {
            let (param, ext, name) = p;

            if do ext.map_default(true) |&s| {
                glfw::extension_supported(s)
            } {
                unsafe {
                    let value = 0;
                    gl::GetIntegerv(param, &value);
                    println(fmt!("OpenGL %s: %?", name, value));
                }
            };
        }
    }
}

mod gl {
    #[nolink]
    #[link_args="-framework OpenGL"]
    #[cfg(target_os = "macos")]
    pub extern { }

    #[nolink]
    #[link_args="-lGL"]
    #[cfg(target_os = "linux")]
    pub extern { }

    pub type GLenum = libc::c_uint;
    pub type GLint  = libc::c_int;

    pub static RED_BITS              : GLenum = 0x0D52;
    pub static GREEN_BITS            : GLenum = 0x0D53;
    pub static BLUE_BITS             : GLenum = 0x0D54;
    pub static ALPHA_BITS            : GLenum = 0x0D55;
    pub static DEPTH_BITS            : GLenum = 0x0D56;
    pub static STENCIL_BITS          : GLenum = 0x0D57;
    pub static ACCUM_RED_BITS        : GLenum = 0x0D58;
    pub static ACCUM_GREEN_BITS      : GLenum = 0x0D59;
    pub static ACCUM_BLUE_BITS       : GLenum = 0x0D5A;
    pub static ACCUM_ALPHA_BITS      : GLenum = 0x0D5B;
    pub static STEREO                : GLenum = 0x0C33;
    pub static SAMPLES_ARB           : GLenum = 0x80A9;

    pub extern "C" {
        #[link_name="glGetIntegerv"]
        pub fn GetIntegerv(pname: GLenum, params: *GLint);
    }
}<commit_msg>Use pattern matching to remove intermediate variable<commit_after>extern mod glfw;

fn error_callback(_error: libc::c_int, description: ~str) {
    io::println(fmt!("GLFW Error: %s", description));
}

fn main() {
    glfw::set_error_callback(error_callback);

    do glfw::spawn {

        glfw::window_hint::visible(true);

        let window = glfw::Window::create(640, 480, "Defaults", glfw::Windowed).get();

        window.make_context_current();

        let (width, height) = window.get_size();
        io::println(fmt!("window size: %? x %?", width, height));

        println(fmt!("Context version major: %?",     window.get_context_version_major()));
        println(fmt!("Context version minor: %?",     window.get_context_version_minor()));
        println(fmt!("OpenGL forward compatible: %?", window.is_opengl_forward_compat()));
        println(fmt!("OpenGL debug context: %?",      window.is_opengl_debug_context()));
        println(fmt!("OpenGL profile: %?",            window.get_opengl_profile()));

        let gl_params = [
            (gl::RED_BITS,          None,   "red bits"          ),
            (gl::GREEN_BITS,        None,   "green bits"        ),
            (gl::BLUE_BITS,         None,   "blue bits"         ),
            (gl::ALPHA_BITS,        None,   "alpha bits"        ),
            (gl::DEPTH_BITS,        None,   "depth bits"        ),
            (gl::STENCIL_BITS,      None,   "stencil bits"      ),
            (gl::ACCUM_RED_BITS,    None,   "accum red bits"    ),
            (gl::ACCUM_GREEN_BITS,  None,   "accum green bits"  ),
            (gl::ACCUM_BLUE_BITS,   None,   "accum blue bits"   ),
            (gl::ACCUM_ALPHA_BITS,  None,   "accum alpha bits"  ),
            (gl::STEREO,            None,   "stereo"            ),
            (gl::SAMPLES_ARB,       Some("GL_ARB_multisample"), "FSAA samples" ),
        ];

        for gl_params.each |&(param, ext, name)| {
            if do ext.map_default(true) |&s| {
                glfw::extension_supported(s)
            } {
                unsafe {
                    let value = 0;
                    gl::GetIntegerv(param, &value);
                    println(fmt!("OpenGL %s: %?", name, value));
                }
            };
        }
    }
}

mod gl {
    #[nolink]
    #[link_args="-framework OpenGL"]
    #[cfg(target_os = "macos")]
    pub extern { }

    #[nolink]
    #[link_args="-lGL"]
    #[cfg(target_os = "linux")]
    pub extern { }

    pub type GLenum = libc::c_uint;
    pub type GLint  = libc::c_int;

    pub static RED_BITS              : GLenum = 0x0D52;
    pub static GREEN_BITS            : GLenum = 0x0D53;
    pub static BLUE_BITS             : GLenum = 0x0D54;
    pub static ALPHA_BITS            : GLenum = 0x0D55;
    pub static DEPTH_BITS            : GLenum = 0x0D56;
    pub static STENCIL_BITS          : GLenum = 0x0D57;
    pub static ACCUM_RED_BITS        : GLenum = 0x0D58;
    pub static ACCUM_GREEN_BITS      : GLenum = 0x0D59;
    pub static ACCUM_BLUE_BITS       : GLenum = 0x0D5A;
    pub static ACCUM_ALPHA_BITS      : GLenum = 0x0D5B;
    pub static STEREO                : GLenum = 0x0C33;
    pub static SAMPLES_ARB           : GLenum = 0x80A9;

    pub extern "C" {
        #[link_name="glGetIntegerv"]
        pub fn GetIntegerv(pname: GLenum, params: *GLint);
    }
}<|endoftext|>


<commit_before>use crate::{api::prelude::*, proc_macros::*};

/// Used for selection.
pub enum SelectionAction {
    ToggleSelection,
}

/// The `SelectionBehaviorState` handles the `SelectionBehavior` widget.
#[derive(Default, AsAny)]
pub struct SelectionBehaviorState {
    target: Entity,
}

impl State for SelectionBehaviorState {
    fn init(&mut self, _: &mut Registry, ctx: &mut Context) {
        self.target = (*ctx.widget().get::<u32>("target")).into();
        toggle_flag("selected", &mut ctx.get_widget(self.target));
        ctx.get_widget(self.target).update(false);
    }

    fn messages(
        &mut self,
        mut messages: MessageReader,
        _registry: &mut Registry,
        ctx: &mut Context,
    ) {
        for message in messages.read::<SelectionAction>() {
            match message {
                SelectionAction::ToggleSelection => {
                    let selected = *ctx.get_widget(self.target).get::<bool>("selected");
                    ctx.get_widget(self.target).set("selected", !selected);
                    toggle_flag("selected", &mut ctx.get_widget(self.target));
                    ctx.get_widget(self.target).update(false);
                }
            };
        }
    }
}

widget!(
    /// The `SelectionBehavior` widget will take care to handle the actions,
    /// that should be triggered if text regions are marked or selected.
    ///
    /// **style:** `check-box`
    SelectionBehavior<SelectionBehaviorState>: MouseHandler {
        /// Sets or shares the target of the behavior.
        target: u32,

        /// Sets or shares the selected property.
        selected: bool,

        /// Sets the parent id.
        parent: u32
    }
);

impl Template for SelectionBehavior {
    fn template(self, id: Entity, _: &mut BuildContext) -> Self {
        self.name("SelectionBehavior")
            .selected(true)
            .on_click(move |ctx, _| {
                ctx.send_message(SelectionAction::ToggleSelection, id);
                false
            })
    }
}
<commit_msg>orbtk_widgets: fix typo bug in `selection_behavior`<commit_after>use crate::{api::prelude::*, proc_macros::*};

/// Used for selection.
pub enum SelectionAction {
    ToggleSelection,
}

/// The `SelectionBehaviorState` handles the `SelectionBehavior` widget.
#[derive(Default, AsAny)]
pub struct SelectionBehaviorState {
    target: Entity,
}

impl State for SelectionBehaviorState {
    fn init(&mut self, _: &mut Registry, ctx: &mut Context) {
        self.target = (*ctx.widget().get::<u32>("target")).into();
        toggle_flag("selected", &mut ctx.get_widget(self.target));
        ctx.get_widget(self.target).update(false);
    }

    fn messages(
        &mut self,
        mut messages: MessageReader,
        _registry: &mut Registry,
        ctx: &mut Context,
    ) {
        for message in messages.read::<SelectionAction>() {
            match message {
                SelectionAction::ToggleSelection => {
                    let selected = *ctx.get_widget(self.target).get::<bool>("selected");
                    ctx.get_widget(self.target).set("selected", !selected);
                    toggle_flag("selected", &mut ctx.get_widget(self.target));
                    ctx.get_widget(self.target).update(false);
                }
            };
        }
    }
}

widget!(
    /// The `SelectionBehavior` widget will take care to handle the actions,
    /// that should be triggered if text regions are marked or selected.
    ///
    /// **style:** `check_box`
    SelectionBehavior<SelectionBehaviorState>: MouseHandler {
        /// Sets or shares the target of the behavior.
        target: u32,

        /// Sets or shares the selected property.
        selected: bool,

        /// Sets the parent id.
        parent: u32
    }
);

impl Template for SelectionBehavior {
    fn template(self, id: Entity, _: &mut BuildContext) -> Self {
        self.name("SelectionBehavior")
            .selected(true)
            .on_click(move |ctx, _| {
                ctx.send_message(SelectionAction::ToggleSelection, id);
                false
            })
    }
}
<|endoftext|>


<commit_before>// TODO: Implement `libtock_runtime` and `libtock_unittest`, which are
// referenced in the comment on `RawSyscalls`.

/// `RawSyscalls` allows a fake Tock kernel to be injected into components for
/// unit testing. It is implemented by `libtock_runtime::TockSyscalls` and
/// `libtock_unittest::FakeSyscalls`. Components should not use `RawSyscalls`
/// directly; instead, use the `Syscalls` trait, which provides higher-level
/// interfaces to the system calls.

// RawSyscalls is designed to minimize the amount of handwritten assembly code
// needed without generating unnecessary instructions. There are a few major
// factors affecting its design:
//     1. Most system calls only clobber r0-r4, while yield has a far longer
//        clobber list. As such, yield must have its own assembly
//        implementation.
//     2. The compiler is unable to optimize away unused arguments. For example,
//        memop's "get process RAM start address" operation only needs r0 set,
//        while memop's "break" operation needs both r0 and r1 set. If our
//        inline assembly calls "get process RAM start address" but sets both r0
//        and r1, the compiler doesn't know that r1 will be
//        ignored so setting that register will not be optimized away. Therefore
//        we want to set the minimum number of argument registers possible.
//     3. The cost of specifying unused return registers is only that of
//        unnecessarily marking a register as clobbered. Explanation: After
//        inlining, an unused register is marked as "changed by the assembly"
//        but can immediately be re-used by the compiler, which is the same as a
//        clobbered register. System calls should generally be
//        inlined -- and even if they aren't, the unused return values will
//        probably be passed in caller-saved registers (this is true for the C
//        ABI, so probably true for the Rust ABI), which are treated as
//        clobbered regardless.
//
// Currently, yield takes exactly one argument, to specify what yield type to
// do. Therefore we only need one raw yield call.
//
// Subscribe, command, read-write allow, and read-only allow all take four
// argument types. Even when calling command IDs that have unused arguments, we
// still need to clear the argument registers so as to avoid passing
// confidential data to capsules (this is in line with Tock's threat model). As
// such, four_arg_syscall() is used for all subscribe, command, read-only allow,
// and read-write allow system calls.
//
// Memop takes 1 or 2 arguments (operation and an optional argument). Because it
// is part of the core kernel, it is okay for us to leave arbitrary data in the
// argument register for operations where the argument register is unused
// (again, in line with Tock's threat model). Memop returns up to 2 return
// arguments, so we don't need to mark r2 and r3 as clobbered. As such, we need
// two raw memop calls: one for operations without an argument and one for
// operations with an argument.
//
// Because the variables passed in and out of raw system calls represent
// register values, they are of type usize. In cases where it doesn't make sense
// to pass a pointer-sized value, libtock_unittest::FakeSyscalls may panic if a
// too-large value is passed.
pub trait RawSyscalls {
    // raw_yield should:
    //     1. Call syscall class 0
    //     2. Use register r0 for input and output as an inlateout register,
    //        passing in r0_in and returning its value.
    //     3. Mark all caller-saved registers as lateout clobbers.
    //     4. NOT provide any of the following options:
    //            pure             (yield has side effects)
    //            nomem            (a callback can read + write globals)
    //            readonly         (a callback can write globals)
    //            preserves_flags  (a callback can change flags)
    //            noreturn         (yield is expected to return)
    //            nostack          (a callback needs the stack)
    //
    // Design note: This is safe because the yield types that currently exist
    // are safe. If an unsafe yield type is added, we will need to make
    // raw_yield unsafe. Although raw_yield shouldn't be called by code outside
    // this crate, it can be, so that is a backwards-incompatible change. We
    // pass YieldType rather than a usize because if we used usize directly then
    // this API becomes unsound if the kernel adds support for an unsafe yield
    // type (or even one that takes one more argument).
    fn raw_yield(r0_in: YieldType) -> usize;

    // four_arg_syscall is used to invoke the subscribe, command, read-write
    // allow, and read-only allow system calls.
    //
    // four_arg_syscall's inline assembly should have the following properties:
    //     1. Calls the syscall class specified by class
    //     2. Passes r0-r3 in the corresponding registers as inlateout
    //        registers. Returns r0-r3 in order.
    //     3. Does not mark any registers as clobbered.
    //     4. Has all of the following options:
    //            preserves_flags  (these system calls do not touch flags)
    //            nostack          (these system calls do not touch the stack)
    //     5. Does NOT have any of the following options:
    //            pure      (these system calls have side effects)
    //            nomem     (the compiler needs to write to globals before allow)
    //            readonly  (rw allow can modify memory)
    //            noreturn  (all these system calls are expected to return)
    //
    /// # Safety
    /// `four_arg_syscall` must NOT be used to invoke yield. Otherwise, it has
    /// the same safety invariants as the underlying system call, which varies
    /// depending on the system call class.
    unsafe fn four_arg_syscall(
        r0: usize,
        r1: usize,
        r2: usize,
        r3: usize,
        class: u8,
    ) -> (usize, usize, usize, usize);

    // zero_arg_memop is used to invoke memop operations that do not accept an
    // argument register. Because there are no memop commands that set r2 or r3,
    // this only needs to return r0 and r1.
    //
    // Memop commands may panic in the unit test environment, as not all memop
    // calls can be sensibly implemented in that environment.
    //
    // zero_arg_memop's inline assembly should have the following properties:
    //     1. Calls syscall class 5
    //     2. Specifies r0 as an inlateout register, and r1 as a lateout
    //        register.
    //     3. Does not mark any registers as clobbered.
    //     4. Has all of the following options:
    //            preserves_flags
    //            nostack
    //            nomem            (it is okay for the compiler to cache globals
    //                              across memop calls)
    //     5. Does NOT have any of the following options:
    //            pure      (two invocations of the same memop can return
    //                       different values)
    //            readonly  (incompatible with nomem)
    //            noreturn
    //
    // Design note: like raw_yield, this is safe because memops that currently
    // exist are safe. zero_arg_memop takes a ZeroArgMemop rather than a usize
    // so that if the kernel adds an unsafe memop this API doesn't become
    // unsound.
    fn zero_arg_memop(r0_in: ZeroArgMemop) -> (usize, usize);

    // one_arg_memop is used to invoke memop operations that take an argument.
    // Because there are no memop operations that set r2 or r3, this only needs
    // to return r0 and r1.
    //
    // one_arg_memop's inline assembly should:
    //     1. Call syscall class 5
    //     2. Specify r0 and r1 as inlateout registers, and return (r0, r1)
    //     3. Not mark any registers as clobbered.
    //     4. Have all of the following options:
    //            preserves_flags
    //            nostack
    //            nomem            (the compiler can cache globals across memop
    //                              calls)
    //     5. Does NOT have any of the following options:
    //            pure      Two invocations of sbrk can return different values
    //            readonly  Incompatible with nomem
    //            noreturn
    //
    // Design note: like raw_yield, this is safe because memops that currently
    // exist are safe. zero_arg_memop takes a ZeroArgMemop rather than a usize
    // so that if the kernel adds an unsafe memop this API doesn't become
    // unsound.
    fn one_arg_memop(r0_in: OneArgMemop, r1: usize) -> (usize, usize);
}

#[non_exhaustive]
#[repr(usize)]
pub enum OneArgMemop {
    Brk = 0,
    Sbrk = 1,
    FlashRegionStart = 8,
    FlashRegionEnd = 9,
    SpecifyStackTop = 10,
    SpecifyHeapStart = 11,
}

// TODO: When the numeric values (0 and 1) are assigned to the yield types,
// specify those values here.
#[non_exhaustive]
#[repr(usize)]
pub enum YieldType {
    Wait,
    NoWait,
}

#[non_exhaustive]
#[repr(usize)]
pub enum ZeroArgMemop {
    MemoryStart = 2,
    MemoryEnd = 3,
    FlashStart = 4,
    FlashEnd = 5,
    GrantStart = 6,
    FlashRegions = 7,
}
<commit_msg>Add a note describing the register naming convention in `raw_syscalls.rs` (for real this time).<commit_after>// TODO: Implement `libtock_runtime` and `libtock_unittest`, which are
// referenced in the comment on `RawSyscalls`.

/// `RawSyscalls` allows a fake Tock kernel to be injected into components for
/// unit testing. It is implemented by `libtock_runtime::TockSyscalls` and
/// `libtock_unittest::FakeSyscalls`. Components should not use `RawSyscalls`
/// directly; instead, use the `Syscalls` trait, which provides higher-level
/// interfaces to the system calls.

// RawSyscalls is designed to minimize the amount of handwritten assembly code
// needed without generating unnecessary instructions. There are a few major
// factors affecting its design:
//     1. Most system calls only clobber r0-r4 (*), while yield has a far longer
//        clobber list. As such, yield must have its own assembly
//        implementation.
//     2. The compiler is unable to optimize away unused arguments. For example,
//        memop's "get process RAM start address" operation only needs r0 set,
//        while memop's "break" operation needs both r0 and r1 set. If our
//        inline assembly calls "get process RAM start address" but sets both r0
//        and r1, the compiler doesn't know that r1 will be
//        ignored so setting that register will not be optimized away. Therefore
//        we want to set the minimum number of argument registers possible.
//     3. The cost of specifying unused return registers is only that of
//        unnecessarily marking a register as clobbered. Explanation: After
//        inlining, an unused register is marked as "changed by the assembly"
//        but can immediately be re-used by the compiler, which is the same as a
//        clobbered register. System calls should generally be
//        inlined -- and even if they aren't, the unused return values will
//        probably be passed in caller-saved registers (this is true for the C
//        ABI, so probably true for the Rust ABI), which are treated as
//        clobbered regardless.
//
// (*) When this file refers to registers, it uses the same naming convention as
// the Tock 2.0 syscalls TRD. Registers r0-r4 correspond to ARM registers r0-r4
// and RISC-V registers a0-a4.
//
// Currently, yield takes exactly one argument, to specify what yield type to
// do. Therefore we only need one raw yield call.
//
// Subscribe, command, read-write allow, and read-only allow all take four
// argument types. Even when calling command IDs that have unused arguments, we
// still need to clear the argument registers so as to avoid passing
// confidential data to capsules (this is in line with Tock's threat model). As
// such, four_arg_syscall() is used for all subscribe, command, read-only allow,
// and read-write allow system calls.
//
// Memop takes 1 or 2 arguments (operation and an optional argument). Because it
// is part of the core kernel, it is okay for us to leave arbitrary data in the
// argument register for operations where the argument register is unused
// (again, in line with Tock's threat model). Memop returns up to 2 return
// arguments, so we don't need to mark r2 and r3 as clobbered. As such, we need
// two raw memop calls: one for operations without an argument and one for
// operations with an argument.
//
// Because the variables passed in and out of raw system calls represent
// register values, they are of type usize. In cases where it doesn't make sense
// to pass a pointer-sized value, libtock_unittest::FakeSyscalls may panic if a
// too-large value is passed.
pub trait RawSyscalls {
    // raw_yield should:
    //     1. Call syscall class 0
    //     2. Use register r0 for input and output as an inlateout register,
    //        passing in r0_in and returning its value.
    //     3. Mark all caller-saved registers as lateout clobbers.
    //     4. NOT provide any of the following options:
    //            pure             (yield has side effects)
    //            nomem            (a callback can read + write globals)
    //            readonly         (a callback can write globals)
    //            preserves_flags  (a callback can change flags)
    //            noreturn         (yield is expected to return)
    //            nostack          (a callback needs the stack)
    //
    // Design note: This is safe because the yield types that currently exist
    // are safe. If an unsafe yield type is added, we will need to make
    // raw_yield unsafe. Although raw_yield shouldn't be called by code outside
    // this crate, it can be, so that is a backwards-incompatible change. We
    // pass YieldType rather than a usize because if we used usize directly then
    // this API becomes unsound if the kernel adds support for an unsafe yield
    // type (or even one that takes one more argument).
    fn raw_yield(r0_in: YieldType) -> usize;

    // four_arg_syscall is used to invoke the subscribe, command, read-write
    // allow, and read-only allow system calls.
    //
    // four_arg_syscall's inline assembly should have the following properties:
    //     1. Calls the syscall class specified by class
    //     2. Passes r0-r3 in the corresponding registers as inlateout
    //        registers. Returns r0-r3 in order.
    //     3. Does not mark any registers as clobbered.
    //     4. Has all of the following options:
    //            preserves_flags  (these system calls do not touch flags)
    //            nostack          (these system calls do not touch the stack)
    //     5. Does NOT have any of the following options:
    //            pure      (these system calls have side effects)
    //            nomem     (the compiler needs to write to globals before allow)
    //            readonly  (rw allow can modify memory)
    //            noreturn  (all these system calls are expected to return)
    //
    /// # Safety
    /// `four_arg_syscall` must NOT be used to invoke yield. Otherwise, it has
    /// the same safety invariants as the underlying system call, which varies
    /// depending on the system call class.
    unsafe fn four_arg_syscall(
        r0: usize,
        r1: usize,
        r2: usize,
        r3: usize,
        class: u8,
    ) -> (usize, usize, usize, usize);

    // zero_arg_memop is used to invoke memop operations that do not accept an
    // argument register. Because there are no memop commands that set r2 or r3,
    // this only needs to return r0 and r1.
    //
    // Memop commands may panic in the unit test environment, as not all memop
    // calls can be sensibly implemented in that environment.
    //
    // zero_arg_memop's inline assembly should have the following properties:
    //     1. Calls syscall class 5
    //     2. Specifies r0 as an inlateout register, and r1 as a lateout
    //        register.
    //     3. Does not mark any registers as clobbered.
    //     4. Has all of the following options:
    //            preserves_flags
    //            nostack
    //            nomem            (it is okay for the compiler to cache globals
    //                              across memop calls)
    //     5. Does NOT have any of the following options:
    //            pure      (two invocations of the same memop can return
    //                       different values)
    //            readonly  (incompatible with nomem)
    //            noreturn
    //
    // Design note: like raw_yield, this is safe because memops that currently
    // exist are safe. zero_arg_memop takes a ZeroArgMemop rather than a usize
    // so that if the kernel adds an unsafe memop this API doesn't become
    // unsound.
    fn zero_arg_memop(r0_in: ZeroArgMemop) -> (usize, usize);

    // one_arg_memop is used to invoke memop operations that take an argument.
    // Because there are no memop operations that set r2 or r3, this only needs
    // to return r0 and r1.
    //
    // one_arg_memop's inline assembly should:
    //     1. Call syscall class 5
    //     2. Specify r0 and r1 as inlateout registers, and return (r0, r1)
    //     3. Not mark any registers as clobbered.
    //     4. Have all of the following options:
    //            preserves_flags
    //            nostack
    //            nomem            (the compiler can cache globals across memop
    //                              calls)
    //     5. Does NOT have any of the following options:
    //            pure      Two invocations of sbrk can return different values
    //            readonly  Incompatible with nomem
    //            noreturn
    //
    // Design note: like raw_yield, this is safe because memops that currently
    // exist are safe. zero_arg_memop takes a ZeroArgMemop rather than a usize
    // so that if the kernel adds an unsafe memop this API doesn't become
    // unsound.
    fn one_arg_memop(r0_in: OneArgMemop, r1: usize) -> (usize, usize);
}

#[non_exhaustive]
#[repr(usize)]
pub enum OneArgMemop {
    Brk = 0,
    Sbrk = 1,
    FlashRegionStart = 8,
    FlashRegionEnd = 9,
    SpecifyStackTop = 10,
    SpecifyHeapStart = 11,
}

// TODO: When the numeric values (0 and 1) are assigned to the yield types,
// specify those values here.
#[non_exhaustive]
#[repr(usize)]
pub enum YieldType {
    Wait,
    NoWait,
}

#[non_exhaustive]
#[repr(usize)]
pub enum ZeroArgMemop {
    MemoryStart = 2,
    MemoryEnd = 3,
    FlashStart = 4,
    FlashEnd = 5,
    GrantStart = 6,
    FlashRegions = 7,
}
<|endoftext|>


<commit_before>extern crate cgmath;
extern crate mikktspace;

use cgmath::prelude::*;

pub type Face = [u32; 3];
pub type Vec2 = [f32; 2];
pub type Vec3 = [f32; 3];
pub type Vec4 = [f32; 4];

#[derive(Debug)]
struct Vertex {
    position: Vec3,
    normal: Vec3,
    tex_coord: Vec2,
}

#[derive(Debug)]
struct NewVertex {
    position: Vec3,
    normal: Vec3,
    tex_coord: Vec2,
    tangent: Vec4,
}

fn make_cube() -> (Vec<Face>, Vec<Vertex>) {
    struct ControlPoint {
        uv: Vec2,
        dir: Vec3,
    }
    let mut faces = Vec::new();
    let mut ctl_pts = Vec::new();
    let mut vertices = Vec::new();

    // +x plane
    {
        let base = ctl_pts.len() as u32;
        faces.push([base, base + 1, base + 4]);
        faces.push([base + 1, base + 2, base + 4]);
        faces.push([base + 2, base + 3, base + 4]);
        faces.push([base + 3, base, base + 4]);
        ctl_pts.push(ControlPoint { uv: [0.0, 0.0], dir: [1.0, -1.0, 1.0] });
        ctl_pts.push(ControlPoint { uv: [0.0, 1.0], dir: [1.0, -1.0, -1.0] });
        ctl_pts.push(ControlPoint { uv: [1.0, 1.0], dir: [1.0, 1.0, -1.0] });
        ctl_pts.push(ControlPoint { uv: [1.0, 0.0], dir: [1.0, 1.0, 1.0] });
        ctl_pts.push(ControlPoint { uv: [0.5, 0.5], dir: [1.0, 0.0, 0.0] });
    }

    // -x plane
    {
        let base = ctl_pts.len() as u32;
        faces.push([base, base + 1, base + 4]);
        faces.push([base + 1, base + 2, base + 4]);
        faces.push([base + 2, base + 3, base + 4]);
        faces.push([base + 3, base, base + 4]);
        ctl_pts.push(ControlPoint { uv: [1.0, 0.0], dir: [-1.0, 1.0, 1.0] });
        ctl_pts.push(ControlPoint { uv: [1.0, 1.0], dir: [-1.0, 1.0, -1.0] });
        ctl_pts.push(ControlPoint { uv: [0.0, 1.0], dir: [-1.0, -1.0, -1.0] });
        ctl_pts.push(ControlPoint { uv: [0.0, 0.0], dir: [-1.0, -1.0, 1.0] });
        ctl_pts.push(ControlPoint { uv: [0.5, 0.5], dir: [-1.0, 0.0, 0.0] });
    }

    // +y plane
    {
        let base = ctl_pts.len() as u32;
        faces.push([base, base + 1, base + 4]);
        faces.push([base + 1, base + 2, base + 4]);
        faces.push([base + 2, base + 3, base + 4]);
        faces.push([base + 3, base, base + 4]);
        ctl_pts.push(ControlPoint { uv: [0.0, 0.0], dir: [1.0, 1.0, 1.0] });
        ctl_pts.push(ControlPoint { uv: [0.0, 1.0], dir: [1.0, 1.0, -1.0] });
        ctl_pts.push(ControlPoint { uv: [0.0, 1.0], dir: [-1.0, 1.0, -1.0] });
        ctl_pts.push(ControlPoint { uv: [0.0, 0.0], dir: [-1.0, 1.0, 1.0] });
        ctl_pts.push(ControlPoint { uv: [0.0, 0.5], dir: [0.0, 1.0, 0.0] });
    }

    // -y plane
    {
        let base = ctl_pts.len() as u32;
        faces.push([base, base + 1, base + 4]);
        faces.push([base + 1, base + 2, base + 4]);
        faces.push([base + 2, base + 3, base + 4]);
        faces.push([base + 3, base, base + 4]);
        ctl_pts.push(ControlPoint { uv: [0.0, 0.0], dir: [-1.0, -1.0, 1.0] });
        ctl_pts.push(ControlPoint { uv: [0.0, 1.0], dir: [-1.0, -1.0, -1.0] });
        ctl_pts.push(ControlPoint { uv: [0.0, 1.0], dir: [1.0, -1.0, -1.0] });
        ctl_pts.push(ControlPoint { uv: [0.0, 0.0], dir: [1.0, -1.0, 1.0] });
        ctl_pts.push(ControlPoint { uv: [0.0, 0.5], dir: [0.0, -1.0, 0.0] });
    }

    // +z plane
    {
        let base = ctl_pts.len() as u32;
        faces.push([base, base + 1, base + 4]);
        faces.push([base + 1, base + 2, base + 4]);
        faces.push([base + 2, base + 3, base + 4]);
        faces.push([base + 3, base, base + 4]);
        ctl_pts.push(ControlPoint { uv: [0.0, 0.0], dir: [-1.0, 1.0, 1.0] });
        ctl_pts.push(ControlPoint { uv: [0.0, 1.0], dir: [-1.0, -1.0, 1.0] });
        ctl_pts.push(ControlPoint { uv: [1.0, 1.0], dir: [1.0, -1.0, 1.0] });
        ctl_pts.push(ControlPoint { uv: [1.0, 0.0], dir: [1.0, 1.0, 1.0] });
        ctl_pts.push(ControlPoint { uv: [0.5, 0.5], dir: [0.0, 0.0, 1.0] });
    }

    // -z plane
    {
        let base = ctl_pts.len() as u32;
        faces.push([base, base + 1, base + 4]);
        faces.push([base + 1, base + 2, base + 4]);
        faces.push([base + 2, base + 3, base + 4]);
        faces.push([base + 3, base, base + 4]);
        ctl_pts.push(ControlPoint { uv: [1.0, 0.0], dir: [1.0, 1.0, -1.0] });
        ctl_pts.push(ControlPoint { uv: [1.0, 1.0], dir: [1.0, -1.0, -1.0] });
        ctl_pts.push(ControlPoint { uv: [0.0, 1.0], dir: [-1.0, -1.0, -1.0] });
        ctl_pts.push(ControlPoint { uv: [0.0, 0.0], dir: [-1.0, 1.0, -1.0] });
        ctl_pts.push(ControlPoint { uv: [0.5, 0.5], dir: [0.0, 0.0, -1.0] });
    }

    for pt in ctl_pts {
        let p: cgmath::Vector3<f32> = pt.dir.into();
        let n: cgmath::Vector3<f32> = p.normalize();
        let t: cgmath::Vector2<f32> = pt.uv.into();
        vertices.push(Vertex {
            position: (p / 2.0).into(),
            normal: n.into(),
            tex_coord: t.into(),
        });
    }

    (faces, vertices)
}

fn main() {
    let (faces, vertices) = make_cube();

    let vertex = |face, vert| {
        let vs: &[u32; 3] = &faces[face % faces.len()];
        &vertices[vs[vert] as usize % vertices.len()]
    };
    let vertices_per_face = || 3;
    let face_count = || faces.len();
    let position = |face, vert| &vertex(face, vert).position;
    let normal = |face, vert| &vertex(face, vert).normal;
    let tex_coord = |face, vert| &vertex(face, vert).tex_coord;

    let mut new_vertices = Vec::new();
    {
        let mut set_tangent = |face, vert, tangent| {
            new_vertices.push(NewVertex {
                position: *position(face, vert),
                normal: *normal(face, vert),
                tex_coord: *tex_coord(face, vert),
                tangent: tangent,
            });
        };
        let ret = mikktspace::generate(
            &vertices_per_face,
            &face_count,
            &position,
            &normal,
            &tex_coord,
            &mut set_tangent,
        );
        assert_eq!(true, ret);
    }
    println!("{:#?}", new_vertices);
}
<commit_msg>Remove debug moduli<commit_after>extern crate cgmath;
extern crate mikktspace;

use cgmath::prelude::*;

pub type Face = [u32; 3];
pub type Vec2 = [f32; 2];
pub type Vec3 = [f32; 3];
pub type Vec4 = [f32; 4];

#[derive(Debug)]
struct Vertex {
    position: Vec3,
    normal: Vec3,
    tex_coord: Vec2,
}

#[derive(Debug)]
struct NewVertex {
    position: Vec3,
    normal: Vec3,
    tex_coord: Vec2,
    tangent: Vec4,
}

fn make_cube() -> (Vec<Face>, Vec<Vertex>) {
    struct ControlPoint {
        uv: Vec2,
        dir: Vec3,
    }
    let mut faces = Vec::new();
    let mut ctl_pts = Vec::new();
    let mut vertices = Vec::new();

    // +x plane
    {
        let base = ctl_pts.len() as u32;
        faces.push([base, base + 1, base + 4]);
        faces.push([base + 1, base + 2, base + 4]);
        faces.push([base + 2, base + 3, base + 4]);
        faces.push([base + 3, base, base + 4]);
        ctl_pts.push(ControlPoint { uv: [0.0, 0.0], dir: [1.0, -1.0, 1.0] });
        ctl_pts.push(ControlPoint { uv: [0.0, 1.0], dir: [1.0, -1.0, -1.0] });
        ctl_pts.push(ControlPoint { uv: [1.0, 1.0], dir: [1.0, 1.0, -1.0] });
        ctl_pts.push(ControlPoint { uv: [1.0, 0.0], dir: [1.0, 1.0, 1.0] });
        ctl_pts.push(ControlPoint { uv: [0.5, 0.5], dir: [1.0, 0.0, 0.0] });
    }

    // -x plane
    {
        let base = ctl_pts.len() as u32;
        faces.push([base, base + 1, base + 4]);
        faces.push([base + 1, base + 2, base + 4]);
        faces.push([base + 2, base + 3, base + 4]);
        faces.push([base + 3, base, base + 4]);
        ctl_pts.push(ControlPoint { uv: [1.0, 0.0], dir: [-1.0, 1.0, 1.0] });
        ctl_pts.push(ControlPoint { uv: [1.0, 1.0], dir: [-1.0, 1.0, -1.0] });
        ctl_pts.push(ControlPoint { uv: [0.0, 1.0], dir: [-1.0, -1.0, -1.0] });
        ctl_pts.push(ControlPoint { uv: [0.0, 0.0], dir: [-1.0, -1.0, 1.0] });
        ctl_pts.push(ControlPoint { uv: [0.5, 0.5], dir: [-1.0, 0.0, 0.0] });
    }

    // +y plane
    {
        let base = ctl_pts.len() as u32;
        faces.push([base, base + 1, base + 4]);
        faces.push([base + 1, base + 2, base + 4]);
        faces.push([base + 2, base + 3, base + 4]);
        faces.push([base + 3, base, base + 4]);
        ctl_pts.push(ControlPoint { uv: [0.0, 0.0], dir: [1.0, 1.0, 1.0] });
        ctl_pts.push(ControlPoint { uv: [0.0, 1.0], dir: [1.0, 1.0, -1.0] });
        ctl_pts.push(ControlPoint { uv: [0.0, 1.0], dir: [-1.0, 1.0, -1.0] });
        ctl_pts.push(ControlPoint { uv: [0.0, 0.0], dir: [-1.0, 1.0, 1.0] });
        ctl_pts.push(ControlPoint { uv: [0.0, 0.5], dir: [0.0, 1.0, 0.0] });
    }

    // -y plane
    {
        let base = ctl_pts.len() as u32;
        faces.push([base, base + 1, base + 4]);
        faces.push([base + 1, base + 2, base + 4]);
        faces.push([base + 2, base + 3, base + 4]);
        faces.push([base + 3, base, base + 4]);
        ctl_pts.push(ControlPoint { uv: [0.0, 0.0], dir: [-1.0, -1.0, 1.0] });
        ctl_pts.push(ControlPoint { uv: [0.0, 1.0], dir: [-1.0, -1.0, -1.0] });
        ctl_pts.push(ControlPoint { uv: [0.0, 1.0], dir: [1.0, -1.0, -1.0] });
        ctl_pts.push(ControlPoint { uv: [0.0, 0.0], dir: [1.0, -1.0, 1.0] });
        ctl_pts.push(ControlPoint { uv: [0.0, 0.5], dir: [0.0, -1.0, 0.0] });
    }

    // +z plane
    {
        let base = ctl_pts.len() as u32;
        faces.push([base, base + 1, base + 4]);
        faces.push([base + 1, base + 2, base + 4]);
        faces.push([base + 2, base + 3, base + 4]);
        faces.push([base + 3, base, base + 4]);
        ctl_pts.push(ControlPoint { uv: [0.0, 0.0], dir: [-1.0, 1.0, 1.0] });
        ctl_pts.push(ControlPoint { uv: [0.0, 1.0], dir: [-1.0, -1.0, 1.0] });
        ctl_pts.push(ControlPoint { uv: [1.0, 1.0], dir: [1.0, -1.0, 1.0] });
        ctl_pts.push(ControlPoint { uv: [1.0, 0.0], dir: [1.0, 1.0, 1.0] });
        ctl_pts.push(ControlPoint { uv: [0.5, 0.5], dir: [0.0, 0.0, 1.0] });
    }

    // -z plane
    {
        let base = ctl_pts.len() as u32;
        faces.push([base, base + 1, base + 4]);
        faces.push([base + 1, base + 2, base + 4]);
        faces.push([base + 2, base + 3, base + 4]);
        faces.push([base + 3, base, base + 4]);
        ctl_pts.push(ControlPoint { uv: [1.0, 0.0], dir: [1.0, 1.0, -1.0] });
        ctl_pts.push(ControlPoint { uv: [1.0, 1.0], dir: [1.0, -1.0, -1.0] });
        ctl_pts.push(ControlPoint { uv: [0.0, 1.0], dir: [-1.0, -1.0, -1.0] });
        ctl_pts.push(ControlPoint { uv: [0.0, 0.0], dir: [-1.0, 1.0, -1.0] });
        ctl_pts.push(ControlPoint { uv: [0.5, 0.5], dir: [0.0, 0.0, -1.0] });
    }

    for pt in ctl_pts {
        let p: cgmath::Vector3<f32> = pt.dir.into();
        let n: cgmath::Vector3<f32> = p.normalize();
        let t: cgmath::Vector2<f32> = pt.uv.into();
        vertices.push(Vertex {
            position: (p / 2.0).into(),
            normal: n.into(),
            tex_coord: t.into(),
        });
    }

    (faces, vertices)
}

fn main() {
    let (faces, vertices) = make_cube();

    let vertex = |face, vert| {
        let vs: &[u32; 3] = &faces[face];
        &vertices[vs[vert] as usize]
    };
    let vertices_per_face = || 3;
    let face_count = || faces.len();
    let position = |face, vert| &vertex(face, vert).position;
    let normal = |face, vert| &vertex(face, vert).normal;
    let tex_coord = |face, vert| &vertex(face, vert).tex_coord;

    let mut new_vertices = Vec::new();
    {
        let mut set_tangent = |face, vert, tangent| {
            new_vertices.push(NewVertex {
                position: *position(face, vert),
                normal: *normal(face, vert),
                tex_coord: *tex_coord(face, vert),
                tangent: tangent,
            });
        };
        let ret = mikktspace::generate(
            &vertices_per_face,
            &face_count,
            &position,
            &normal,
            &tex_coord,
            &mut set_tangent,
        );
        assert_eq!(true, ret);
    }
    println!("{:#?}", new_vertices);
}
<|endoftext|>


<commit_before>//! An example that timelines the specified folder.
//!
//! The timeline action is one of the filesystem tools that the GRR agent
//! exposes. Its description is pretty simple: given a folder, it returns a
//! stream of stat entries for all the files in it (including all subfolders).
//!
//! This example is a tiny wrapper around this action that allows to execute it
//! as a standalone binary without all the RRG setup required. A primary reason
//! for its existence is to compare the efficiency Rust implementation against
//! the existing Python one.

use std::fs::File;
use std::path::{Path, PathBuf};

use rrg::action::timeline;
use rrg::session::Sink;
use structopt::StructOpt;

/// A type for the timelining example command-line arguments.
#[derive(StructOpt)]
#[structopt(name = "timeline", about = "A binary for the timeline action.")]
struct Opts {
    /// A path to the root directory to timeline.
    #[structopt(long="root", name="FILE", default_value="/",
                help="Root directory to timeline")]
    root: PathBuf,

    /// A path to a file to dump the results into.
    #[structopt(long="output", name="DIRECTORY",
                help="File to dump the results into")]
    output: PathBuf,
}

/// A session type of the timeline example.
///
/// Every action handler needs a session object. "Real" sessions handle comms
/// with the GRR server, error reporting and alike. However, this is not needed
/// here and the example session simply dumps everything into the specified file
/// encoding data in the gzchunked format.
struct Session {
    /// A file into which the data chunks of the output are dumped.
    output: File,
}

impl Session {

    /// Creates a session object that will write to the given `output` path.
    fn open<P: AsRef<Path>>(output: P) -> Session {
        let output = File::create(output)
            .expect("failed to create the output file");

        Session {
            output: output,
        }
    }
}

impl rrg::session::Session for Session {

    fn reply<R>(&mut self, response: R) -> rrg::session::Result<()>
    where
        R: rrg::action::Response + 'static,
    {
        // For now we are not interested in doing anything useful with chunk ids
        // since everything is dumped into one file and there is no need to
        // refer to a particular chunk.
        //
        // In the future they might be useful for printing some statistics about
        // the collected files.
        drop(response);

        Ok(())
    }

    fn send<R>(&mut self, sink: Sink, response: R) -> rrg::session::Result<()>
    where
        R: rrg::action::Response + 'static,
    {
        use std::io::Write as _;
        use byteorder::{BigEndian, WriteBytesExt as _};

        // Just a sanity check in case the implementation of the timeline action
        // starts sending data to other sinks.
        assert_eq!(sink, Sink::TRANSFER_STORE);

        let response = (&response as &dyn std::any::Any)
            .downcast_ref::<timeline::Chunk>()
            .expect("unexpected response type");

        self.output.write_u64::<BigEndian>(response.data.len() as u64)
            .expect("failed to write chunk size tag");
        self.output.write_all(&response.data[..])
            .expect("failed to write chunk data");

        Ok(())
    }
}

fn main() {
    let opts = Opts::from_args();

    timeline::handle(&mut Session::open(opts.output), timeline::Request {
        root: opts.root,
    }).expect("failed to execute the action");
}
<commit_msg>Improve style consistency of CLI specification.<commit_after>//! An example that timelines the specified folder.
//!
//! The timeline action is one of the filesystem tools that the GRR agent
//! exposes. Its description is pretty simple: given a folder, it returns a
//! stream of stat entries for all the files in it (including all subfolders).
//!
//! This example is a tiny wrapper around this action that allows to execute it
//! as a standalone binary without all the RRG setup required. A primary reason
//! for its existence is to compare the efficiency Rust implementation against
//! the existing Python one.

use std::fs::File;
use std::path::{Path, PathBuf};

use rrg::action::timeline;
use rrg::session::Sink;
use structopt::StructOpt;

/// A type for the timelining example command-line arguments.
#[derive(StructOpt)]
#[structopt(name = "timeline", about = "A binary for the timeline action.")]
struct Opts {
    /// A path to the root directory to timeline.
    #[structopt(long = "root", name = "FILE", default_value = "/",
                help = "Root directory to timeline")]
    root: PathBuf,

    /// A path to a file to dump the results into.
    #[structopt(long = "output", name = "DIRECTORY",
                help = "File to dump the results into")]
    output: PathBuf,
}

/// A session type of the timeline example.
///
/// Every action handler needs a session object. "Real" sessions handle comms
/// with the GRR server, error reporting and alike. However, this is not needed
/// here and the example session simply dumps everything into the specified file
/// encoding data in the gzchunked format.
struct Session {
    /// A file into which the data chunks of the output are dumped.
    output: File,
}

impl Session {

    /// Creates a session object that will write to the given `output` path.
    fn open<P: AsRef<Path>>(output: P) -> Session {
        let output = File::create(output)
            .expect("failed to create the output file");

        Session {
            output: output,
        }
    }
}

impl rrg::session::Session for Session {

    fn reply<R>(&mut self, response: R) -> rrg::session::Result<()>
    where
        R: rrg::action::Response + 'static,
    {
        // For now we are not interested in doing anything useful with chunk ids
        // since everything is dumped into one file and there is no need to
        // refer to a particular chunk.
        //
        // In the future they might be useful for printing some statistics about
        // the collected files.
        drop(response);

        Ok(())
    }

    fn send<R>(&mut self, sink: Sink, response: R) -> rrg::session::Result<()>
    where
        R: rrg::action::Response + 'static,
    {
        use std::io::Write as _;
        use byteorder::{BigEndian, WriteBytesExt as _};

        // Just a sanity check in case the implementation of the timeline action
        // starts sending data to other sinks.
        assert_eq!(sink, Sink::TRANSFER_STORE);

        let response = (&response as &dyn std::any::Any)
            .downcast_ref::<timeline::Chunk>()
            .expect("unexpected response type");

        self.output.write_u64::<BigEndian>(response.data.len() as u64)
            .expect("failed to write chunk size tag");
        self.output.write_all(&response.data[..])
            .expect("failed to write chunk data");

        Ok(())
    }
}

fn main() {
    let opts = Opts::from_args();

    timeline::handle(&mut Session::open(opts.output), timeline::Request {
        root: opts.root,
    }).expect("failed to execute the action");
}
<|endoftext|>