<commit_before>use rustc_serialize::json::Json;

use query::Query;
use query::parser::{QueryParseContext, QueryParseError, parse as parse_query};

pub fn parse(context: &QueryParseContext, json: &Json) -> Result<Query, QueryParseError> {
    let filters = try!(json.as_array().ok_or(QueryParseError::ExpectedArray));
    let mut sub_queries = Vec::new();

    for filter in filters.iter() {
        sub_queries.push(try!(parse_query(context, filter)));
    }

    Ok(Query::Bool {
        must: vec![],
        must_not: vec![],
        should: sub_queries,
        filter: vec![],
        minimum_should_match: 1,
    })
}

#[cfg(test)]
mod tests {
    use rustc_serialize::json::Json;

    use term::Term;
    use query::{Query, TermMatcher};
    use query::parser::{QueryParseContext, QueryParseError};
    use index::Index;

    use super::parse;

    #[test]
    fn test_or_query() {
        let query = parse(&QueryParseContext::new(&Index::new()), &Json::from_str("
        [
            {
                \"term\": {
                    \"test\":  \"foo\"
                }
            },
            {
                \"term\": {
                    \"test\":  \"bar\"
                }
            }
        ]
        ").unwrap());

        assert_eq!(query, Ok(Query::Bool {
            must: vec![],
            must_not: vec![],
            should: vec![
                Query::MatchTerm {
                    field: "test".to_string(),
                    term: Term::String("foo".to_string()),
                    matcher: TermMatcher::Exact
                },
                Query::MatchTerm {
                    field: "test".to_string(),
                    term: Term::String("bar".to_string()),
                    matcher: TermMatcher::Exact
                },
            ],
            filter: vec![],
            minimum_should_match: 1,
        }))
    }

    #[test]
    fn test_gives_error_for_incorrect_type() {
        // String
        let query = parse(&QueryParseContext::new(&Index::new()), &Json::from_str("
        \"hello\"
        ").unwrap());

        assert_eq!(query, Err(QueryParseError::ExpectedArray));

        // Object
        let query = parse(&QueryParseContext::new(&Index::new()), &Json::from_str("
        {
            \"foo\": \"bar\"
        }
        ").unwrap());

        assert_eq!(query, Err(QueryParseError::ExpectedArray));

        // Integer
        let query = parse(&QueryParseContext::new(&Index::new()), &Json::from_str("
        123
        ").unwrap());

        assert_eq!(query, Err(QueryParseError::ExpectedArray));

        // Float
        let query = parse(&QueryParseContext::new(&Index::new()), &Json::from_str("
        123.1234
        ").unwrap());

        assert_eq!(query, Err(QueryParseError::ExpectedArray));
    }
}
<commit_msg>Rewrite or query to not use Bool query<commit_after>use rustc_serialize::json::Json;

use query::Query;
use query::parser::{QueryParseContext, QueryParseError, parse as parse_query};

pub fn parse(context: &QueryParseContext, json: &Json) -> Result<Query, QueryParseError> {
    let filters = try!(json.as_array().ok_or(QueryParseError::ExpectedArray));
    let mut sub_queries = Vec::new();

    for filter in filters.iter() {
        sub_queries.push(try!(parse_query(context, filter)));
    }

    Ok(Query::Or {
        queries: sub_queries,
    })
}

#[cfg(test)]
mod tests {
    use rustc_serialize::json::Json;

    use term::Term;
    use query::{Query, TermMatcher};
    use query::parser::{QueryParseContext, QueryParseError};
    use index::Index;

    use super::parse;

    #[test]
    fn test_or_query() {
        let query = parse(&QueryParseContext::new(&Index::new()), &Json::from_str("
        [
            {
                \"term\": {
                    \"test\":  \"foo\"
                }
            },
            {
                \"term\": {
                    \"test\":  \"bar\"
                }
            }
        ]
        ").unwrap());

        assert_eq!(query, Ok(Query::Or {
            queries: vec![
                Query::MatchTerm {
                    field: "test".to_string(),
                    term: Term::String("foo".to_string()),
                    matcher: TermMatcher::Exact
                },
                Query::MatchTerm {
                    field: "test".to_string(),
                    term: Term::String("bar".to_string()),
                    matcher: TermMatcher::Exact
                },
            ],
        }))
    }

    #[test]
    fn test_gives_error_for_incorrect_type() {
        // String
        let query = parse(&QueryParseContext::new(&Index::new()), &Json::from_str("
        \"hello\"
        ").unwrap());

        assert_eq!(query, Err(QueryParseError::ExpectedArray));

        // Object
        let query = parse(&QueryParseContext::new(&Index::new()), &Json::from_str("
        {
            \"foo\": \"bar\"
        }
        ").unwrap());

        assert_eq!(query, Err(QueryParseError::ExpectedArray));

        // Integer
        let query = parse(&QueryParseContext::new(&Index::new()), &Json::from_str("
        123
        ").unwrap());

        assert_eq!(query, Err(QueryParseError::ExpectedArray));

        // Float
        let query = parse(&QueryParseContext::new(&Index::new()), &Json::from_str("
        123.1234
        ").unwrap());

        assert_eq!(query, Err(QueryParseError::ExpectedArray));
    }
}
<|endoftext|>


<commit_before>#![no_std]

#![feature(no_std)]
#![feature(asm)]
#![feature(lang_items)]
#![feature(box_syntax)]
#![feature(core)]
#![feature(unique)]

extern crate core;

use console::Color;

// Must be re-exported to be called from assembly
pub use interrupt::int_handler;

mod console;
mod asm;
mod interrupt;
mod error;

use core::ptr::Unique;

#[lang="owned_box"]
pub struct Box<T>(Unique<T>);

#[no_mangle]
#[no_stack_check]
pub fn main() {
    let mut console = console::Console::init();
    console.clear_screen(Color::LightRed);

    console.print_string("print_char: ");
    console.print_char('A');
    console.print_char('\n');

    console.print_int(1234567890);
    console.print_char('\n');

    let boxed = box 5;
    console.print_string("From box: ");
    console.print_int(*boxed);
    console.print_char('\n');

    console.print_string("Begin PCI Scan...\n");
    for bus in 0..255 {
        for slot in 0..31 {
            let vendor = pci_check_vendor(bus,slot);
            if vendor != 0xFFFF {
                console.print_string("Device found: ");
                console.print_int(bus as u32);
                console.print_string("-");
                console.print_int(slot as u32);
                console.print_char('\n');
                console.print_string("Vendor: ");
                console.print_int(vendor as u32);
                console.print_char('\n');
            }
        }
    }

    console.print_string("\n\nEnd of main()\n");
}

// Stubs for functions needed to build as static lib.
#[lang = "stack_exhausted"] extern fn stack_exhausted() {}
#[lang = "eh_personality"] extern fn eh_personality() {}
#[lang = "panic_fmt"] fn panic_fmt() -> ! { loop{} }

// Dynamic allocation of memory
static mut heap:u8 = 0;

#[lang="exchange_malloc"]
unsafe fn allocate(size: usize, _align: usize) -> *mut u8 {
    //TODO: Implement support more for than 1 byte :)
    let p:*mut u8 = &mut heap;
    return p;
}
#[lang="exchange_free"]
unsafe fn deallocate(ptr: *mut u8, _size: usize, _align: usize) {
    //TODO: Implement
}

// PCI, from OSDev wiki
fn pci_check_vendor(bus: u8, slot: u8) -> u16 {
    let vendor:u16 = pci_config_read_word(bus,slot,0,0);
    return vendor;
}

fn pci_config_read_word(bus: u8, slot: u8, func: u8, offset: u8) -> u16 {
    let address = ((bus as u32) << 16) | ((slot as u32) << 11) |
              ((func as u32) << 8) | ((offset as u32) & 0xfc) | (0x80000000 as u32);
    asm::out32(0xCF8, address);
    let tmp = ((asm::in32(0xCFC) >> ((offset & 2) * 8)) & 0xffff) as u16;
    return tmp;
}
<commit_msg>Cleanup boot messages.<commit_after>#![no_std]

#![feature(no_std)]
#![feature(asm)]
#![feature(lang_items)]
#![feature(box_syntax)]
#![feature(core)]
#![feature(unique)]

extern crate core;

use console::Color;

// Must be re-exported to be called from assembly
pub use interrupt::int_handler;

mod console;
mod asm;
mod interrupt;
mod error;

use core::ptr::Unique;

#[lang="owned_box"]
pub struct Box<T>(Unique<T>);

#[no_mangle]
#[no_stack_check]
pub fn main() {
    let mut console = console::Console::init();
    console.clear_screen(Color::Black);

    console.print_string("Welcome to rOSt.\n");

    console.print_string("Begin PCI Scan...\n");
    for bus in 0..255 {
        for slot in 0..31 {
            let vendor = pci_check_vendor(bus,slot);
            if vendor != 0xFFFF {
                console.print_string("Device found: ");
                console.print_int(bus as u32);
                console.print_string("-");
                console.print_int(slot as u32);
                console.print_char('\n');
                console.print_string("Vendor: ");
                console.print_int(vendor as u32);
                console.print_char('\n');
            }
        }
    }
}

// Stubs for functions needed to build as static lib.
#[lang = "stack_exhausted"] extern fn stack_exhausted() {}
#[lang = "eh_personality"] extern fn eh_personality() {}
#[lang = "panic_fmt"] fn panic_fmt() -> ! { loop{} }

// Dynamic allocation of memory
static mut heap:u8 = 0;

#[lang="exchange_malloc"]
unsafe fn allocate(size: usize, _align: usize) -> *mut u8 {
    //TODO: Implement support more for than 1 byte :)
    let p:*mut u8 = &mut heap;
    return p;
}
#[lang="exchange_free"]
unsafe fn deallocate(ptr: *mut u8, _size: usize, _align: usize) {
    //TODO: Implement
}

// PCI, from OSDev wiki
fn pci_check_vendor(bus: u8, slot: u8) -> u16 {
    let vendor:u16 = pci_config_read_word(bus,slot,0,0);
    return vendor;
}

fn pci_config_read_word(bus: u8, slot: u8, func: u8, offset: u8) -> u16 {
    let address = ((bus as u32) << 16) | ((slot as u32) << 11) |
              ((func as u32) << 8) | ((offset as u32) & 0xfc) | (0x80000000 as u32);
    asm::out32(0xCF8, address);
    let tmp = ((asm::in32(0xCFC) >> ((offset & 2) * 8)) & 0xffff) as u16;
    return tmp;
}
<|endoftext|>


<commit_before>//! Management of the directory layout of a build
//!
//! The directory layout is a little tricky at times, hence a separate file to
//! house this logic. The current layout looks like this:
//!
//! ```text
//! # This is the root directory for all output, the top-level package
//! # places all of its output here.
//! target/
//!
//!     # This is the root directory for all output of *dependencies*
//!     deps/
//!
//!     # Root directory for all compiled examples
//!     examples/
//!
//!     # This is the location at which the output of all custom build
//!     # commands are rooted
//!     build/
//!
//!         # Each package gets its own directory where its build script and
//!         # script output are placed
//!         $pkg1/
//!         $pkg2/
//!         $pkg3/
//!
//!             # Each directory package has a `out` directory where output
//!             # is placed.
//!             out/
//!
//!     # This is the location at which the output of all old custom build
//!     # commands are rooted
//!     native/
//!
//!         # Each package gets its own directory for where its output is
//!         # placed. We can't track exactly what's getting put in here, so
//!         # we just assume that all relevant output is in these
//!         # directories.
//!         $pkg1/
//!         $pkg2/
//!         $pkg3/
//!
//!     # Directory used to store incremental data for the compiler (when
//!     # incremental is enabled.
//!     incremental/
//!
//!     # Hidden directory that holds all of the fingerprint files for all
//!     # packages
//!     .fingerprint/
//! ```

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

use crate::core::Workspace;
use crate::util::{CargoResult, Config, FileLock, Filesystem};

/// Contains the paths of all target output locations.
///
/// See module docs for more information.
pub struct Layout {
    root: PathBuf,
    deps: PathBuf,
    native: PathBuf,
    build: PathBuf,
    incremental: PathBuf,
    fingerprint: PathBuf,
    examples: PathBuf,
    /// The lock file for a build, will be unlocked when this struct is `drop`ped.
    _lock: FileLock,
}

pub fn is_bad_artifact_name(name: &str) -> bool {
    ["deps", "examples", "build", "native", "incremental"]
        .iter()
        .any(|&reserved| reserved == name)
}

impl Layout {
    /// Calculate the paths for build output, lock the build directory, and return as a Layout.
    ///
    /// This function will block if the directory is already locked.
    ///
    /// Differs from `at` in that this calculates the root path from the workspace target directory,
    /// adding the target triple and the profile (debug, release, ...).
    pub fn new(ws: &Workspace<'_>, triple: Option<&str>, dest: &str) -> CargoResult<Layout> {
        let mut path = ws.target_dir();
        // Flexible target specifications often point at json files, so interpret
        // the target triple as a Path and then just use the file stem as the
        // component for the directory name in that case.
        if let Some(triple) = triple {
            let triple = Path::new(triple);
            if triple.extension().and_then(|s| s.to_str()) == Some("json") {
                path.push(
                    triple
                        .file_stem()
                        .ok_or_else(|| failure::format_err!("invalid target"))?,
                );
            } else {
                path.push(triple);
            }
        }
        path.push(dest);
        Layout::at(ws.config(), path)
    }

    /// Calculate the paths for build output, lock the build directory, and return as a Layout.
    ///
    /// This function will block if the directory is already locked.
    pub fn at(config: &Config, root: Filesystem) -> CargoResult<Layout> {
        // For now we don't do any more finer-grained locking on the artifact
        // directory, so just lock the entire thing for the duration of this
        // compile.
        let lock = root.open_rw(".cargo-lock", config, "build directory")?;
        let root = root.into_path_unlocked();

        Ok(Layout {
            deps: root.join("deps"),
            native: root.join("native"),
            build: root.join("build"),
            incremental: root.join("incremental"),
            fingerprint: root.join(".fingerprint"),
            examples: root.join("examples"),
            root,
            _lock: lock,
        })
    }

    #[cfg(not(target_os = "macos"))]
    fn exclude_from_backups(&self, _: &Path) {}

    #[cfg(target_os = "macos")]
    /// Marks files or directories as excluded from Time Machine on macOS
    ///
    /// This is recommended to prevent derived/temporary files from bloating backups.
    fn exclude_from_backups(&self, path: &Path) {
        use core_foundation::base::TCFType;
        use core_foundation::{number, string, url};
        use std::ptr;

        // For compatibility with 10.7 a string is used instead of global kCFURLIsExcludedFromBackupKey
        let is_excluded_key: Result<string::CFString, _> = "NSURLIsExcludedFromBackupKey".parse();
        let path = url::CFURL::from_path(path, false);
        if let (Some(path), Ok(is_excluded_key)) = (path, is_excluded_key) {
            unsafe {
                url::CFURLSetResourcePropertyForKey(
                    path.as_concrete_TypeRef(),
                    is_excluded_key.as_concrete_TypeRef(),
                    number::kCFBooleanTrue as *const _,
                    ptr::null_mut(),
                );
            }
        }
        // Errors are ignored, since it's an optional feature and failure
        // doesn't prevent Cargo from working
    }

    /// Makes sure all directories stored in the Layout exist on the filesystem.
    pub fn prepare(&mut self) -> io::Result<()> {
        if fs::metadata(&self.root).is_err() {
            fs::create_dir_all(&self.root)?;
            self.exclude_from_backups(&self.root);
        }

        mkdir(&self.deps)?;
        mkdir(&self.native)?;
        mkdir(&self.incremental)?;
        mkdir(&self.fingerprint)?;
        mkdir(&self.examples)?;
        mkdir(&self.build)?;

        return Ok(());

        fn mkdir(dir: &Path) -> io::Result<()> {
            if fs::metadata(&dir).is_err() {
                fs::create_dir(dir)?;
            }
            Ok(())
        }
    }

    /// Fetch the root path.
    pub fn dest(&self) -> &Path {
        &self.root
    }
    /// Fetch the deps path.
    pub fn deps(&self) -> &Path {
        &self.deps
    }
    /// Fetch the examples path.
    pub fn examples(&self) -> &Path {
        &self.examples
    }
    /// Fetch the root path.
    pub fn root(&self) -> &Path {
        &self.root
    }
    /// Fetch the incremental path.
    pub fn incremental(&self) -> &Path {
        &self.incremental
    }
    /// Fetch the fingerprint path.
    pub fn fingerprint(&self) -> &Path {
        &self.fingerprint
    }
    /// Fetch the build path.
    pub fn build(&self) -> &Path {
        &self.build
    }
}
<commit_msg>Auto merge of #7192 - alexcrichton:fix-backups, r=ehuss<commit_after>//! Management of the directory layout of a build
//!
//! The directory layout is a little tricky at times, hence a separate file to
//! house this logic. The current layout looks like this:
//!
//! ```text
//! # This is the root directory for all output, the top-level package
//! # places all of its output here.
//! target/
//!
//!     # This is the root directory for all output of *dependencies*
//!     deps/
//!
//!     # Root directory for all compiled examples
//!     examples/
//!
//!     # This is the location at which the output of all custom build
//!     # commands are rooted
//!     build/
//!
//!         # Each package gets its own directory where its build script and
//!         # script output are placed
//!         $pkg1/
//!         $pkg2/
//!         $pkg3/
//!
//!             # Each directory package has a `out` directory where output
//!             # is placed.
//!             out/
//!
//!     # This is the location at which the output of all old custom build
//!     # commands are rooted
//!     native/
//!
//!         # Each package gets its own directory for where its output is
//!         # placed. We can't track exactly what's getting put in here, so
//!         # we just assume that all relevant output is in these
//!         # directories.
//!         $pkg1/
//!         $pkg2/
//!         $pkg3/
//!
//!     # Directory used to store incremental data for the compiler (when
//!     # incremental is enabled.
//!     incremental/
//!
//!     # Hidden directory that holds all of the fingerprint files for all
//!     # packages
//!     .fingerprint/
//! ```

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

use crate::core::Workspace;
use crate::util::{CargoResult, Config, FileLock, Filesystem};

/// Contains the paths of all target output locations.
///
/// See module docs for more information.
pub struct Layout {
    root: PathBuf,
    deps: PathBuf,
    native: PathBuf,
    build: PathBuf,
    incremental: PathBuf,
    fingerprint: PathBuf,
    examples: PathBuf,
    /// The lock file for a build, will be unlocked when this struct is `drop`ped.
    _lock: FileLock,
}

pub fn is_bad_artifact_name(name: &str) -> bool {
    ["deps", "examples", "build", "native", "incremental"]
        .iter()
        .any(|&reserved| reserved == name)
}

impl Layout {
    /// Calculate the paths for build output, lock the build directory, and return as a Layout.
    ///
    /// This function will block if the directory is already locked.
    ///
    /// Differs from `at` in that this calculates the root path from the workspace target directory,
    /// adding the target triple and the profile (debug, release, ...).
    pub fn new(ws: &Workspace<'_>, triple: Option<&str>, dest: &str) -> CargoResult<Layout> {
        let mut path = ws.target_dir();
        // Flexible target specifications often point at json files, so interpret
        // the target triple as a Path and then just use the file stem as the
        // component for the directory name in that case.
        if let Some(triple) = triple {
            let triple = Path::new(triple);
            if triple.extension().and_then(|s| s.to_str()) == Some("json") {
                path.push(
                    triple
                        .file_stem()
                        .ok_or_else(|| failure::format_err!("invalid target"))?,
                );
            } else {
                path.push(triple);
            }
        }
        path.push(dest);
        Layout::at(ws.config(), path)
    }

    /// Calculate the paths for build output, lock the build directory, and return as a Layout.
    ///
    /// This function will block if the directory is already locked.
    pub fn at(config: &Config, root: Filesystem) -> CargoResult<Layout> {
        // If the root directory doesn't already exist go ahead and create it
        // here. Use this opportunity to exclude it from backups as well if the
        // system supports it since this is a freshly created folder.
        if !root.as_path_unlocked().exists() {
            root.create_dir()?;
            exclude_from_backups(root.as_path_unlocked());
        }

        // For now we don't do any more finer-grained locking on the artifact
        // directory, so just lock the entire thing for the duration of this
        // compile.
        let lock = root.open_rw(".cargo-lock", config, "build directory")?;
        let root = root.into_path_unlocked();

        Ok(Layout {
            deps: root.join("deps"),
            native: root.join("native"),
            build: root.join("build"),
            incremental: root.join("incremental"),
            fingerprint: root.join(".fingerprint"),
            examples: root.join("examples"),
            root,
            _lock: lock,
        })
    }

    /// Makes sure all directories stored in the Layout exist on the filesystem.
    pub fn prepare(&mut self) -> io::Result<()> {
        mkdir(&self.deps)?;
        mkdir(&self.native)?;
        mkdir(&self.incremental)?;
        mkdir(&self.fingerprint)?;
        mkdir(&self.examples)?;
        mkdir(&self.build)?;

        return Ok(());

        fn mkdir(dir: &Path) -> io::Result<()> {
            if fs::metadata(&dir).is_err() {
                fs::create_dir(dir)?;
            }
            Ok(())
        }
    }

    /// Fetch the root path.
    pub fn dest(&self) -> &Path {
        &self.root
    }
    /// Fetch the deps path.
    pub fn deps(&self) -> &Path {
        &self.deps
    }
    /// Fetch the examples path.
    pub fn examples(&self) -> &Path {
        &self.examples
    }
    /// Fetch the root path.
    pub fn root(&self) -> &Path {
        &self.root
    }
    /// Fetch the incremental path.
    pub fn incremental(&self) -> &Path {
        &self.incremental
    }
    /// Fetch the fingerprint path.
    pub fn fingerprint(&self) -> &Path {
        &self.fingerprint
    }
    /// Fetch the build path.
    pub fn build(&self) -> &Path {
        &self.build
    }
}

#[cfg(not(target_os = "macos"))]
fn exclude_from_backups(_: &Path) {}

#[cfg(target_os = "macos")]
/// Marks files or directories as excluded from Time Machine on macOS
///
/// This is recommended to prevent derived/temporary files from bloating backups.
fn exclude_from_backups(path: &Path) {
    use core_foundation::base::TCFType;
    use core_foundation::{number, string, url};
    use std::ptr;

    // For compatibility with 10.7 a string is used instead of global kCFURLIsExcludedFromBackupKey
    let is_excluded_key: Result<string::CFString, _> = "NSURLIsExcludedFromBackupKey".parse();
    let path = url::CFURL::from_path(path, false);
    if let (Some(path), Ok(is_excluded_key)) = (path, is_excluded_key) {
        unsafe {
            url::CFURLSetResourcePropertyForKey(
                path.as_concrete_TypeRef(),
                is_excluded_key.as_concrete_TypeRef(),
                number::kCFBooleanTrue as *const _,
                ptr::null_mut(),
            );
        }
    }
    // Errors are ignored, since it's an optional feature and failure
    // doesn't prevent Cargo from working
}
<|endoftext|>


<commit_before>// library
extern crate my_extern_lib;

// modules
mod simple_functions {
    pub fn print_hello_world() {
        println!("Hello, World! (from the simple_functions module)");
     }

    // nested modules
    pub mod simple_math {
        pub fn multiple_two_integers(a: i32, b: i32) -> i32 {
            a * b
        }
    }
}

use simple_functions::simple_math::multiple_two_integers;

fn print_some_msg() {
    println!("Modules: printing from the outer function");
}

mod sample_module {

    pub fn call_sample_module() {
        use second_module::print_some_msg as print_second;
        use self::second_module::print_some_msg as print_second_sample;
        use super::print_some_msg as print_outside;
        print_outside();
        print_second();
        print_some_msg();
        print_second_sample();
    }

    mod second_module {

        pub fn print_some_msg() {
            println!("Modules: printing from the second module inside the sample module");
        }

    }

    fn print_some_msg() {
        println!("Modules: printing from the inside of the sample module");
    }

}

mod second_module {
    pub fn print_some_msg() {
        println!("Modules: printing from the second module");
    }
}

mod modules;

fn main() {

    // formatted output
    println!("Hello, Rust!");
    println!("Integer number = {}", 23);
    println!("Float number = {}", 1.012);
    println!("Repeat printing: {0}, {1}, {1}, {3}, {2}", 2, 1, 44, 9);
    println!("Named arguments: {name}, {age}, {occupation}", age="24", name="Ann", occupation="Designer");
    println!("{:08b} XOR {:08b} = {:08b}", 3i8, 32i8, 3i8 ^ 34i8);
    println!("Floating point number {:?}", 2.910210);
    println!("Hex: {:08X}, {:08x}", 131342112, 131342112);
    // TODO find out why this doesn't work:
    //println!("{0:08X}, {0:08x}", 7661);

    // variables
    let integer = 3i32;
    let floating_point = 2.1137;

    let mut u_integer = 3u32;
    //integer += 1; error: an immutable variable
    u_integer += 1;

    println!("{}, {}, {}", integer, floating_point, u_integer);
    // TODO find out why snake case instead of camel case

    // shadowing
    let first_var = 4;
    {
        let first_var = 51;
        println!("first_var = {}", first_var);
    }
    println!("first_var = {}", first_var);

    // unitialized variables
    let uninit_var;
    //println!("uninit_var = {}", uninit_var); error: use of an init variable
    uninit_var = 231.2;
    println!("already initialized uninit_var = {}", uninit_var);

    // type casting
    let a_integer = 0x40_u8;
    let a_char = a_integer as char;
    println!("char cast from integer {}: {}", a_integer, a_char);

    let a_float = 8.45511;
    println!("integer cast from float {}: {}", a_float, a_float as i32);

    println!("Binary represntation of {}: {:08b}", -1_i8, -1_i8);
    println!("Binary represntation of {}: {:08b}", -2_i8, -2_i8);

    // aliases
    type FloatingPoint32 = f32;
    let a_float_2 : FloatingPoint32 = 3 as f32;
    println!("Type alias: {}, size of var {}", a_float_2, std::mem::size_of_val(&a_float_2));

    // expressions
    let expr = {
        let x = 4.09;
        let y = 1.28;
        println!("x = {}, y = {}", x, y);
        x / y
    };
    println!("expr = {}", expr);

    // if-statement (every if-statement is an expression too, which is really a cool thing)
    let speed = 10;
    let mass = 890;
    let consumption =
        if speed < 0 {
            -1.0
        }
        else if speed == 0 {
            0.8
        }
        else if speed > 0 && speed < 10 {
            18.52
        }
        else if speed >= 10 && speed < 30 {
            let x = mass / speed;
            (x as f32) * 0.05
        }
        else {
            11.71
        };
        println!("Speed = {}, consumption = {}", speed, consumption);

        // loop
        let mut count = 0u32;
        loop {
            println!("loop iteration #{}", count);
            count += 1;
            if count > 9 {
            break;
            }
        }

        count = 0;
        while count < 10 {
            println!("while loop iteration #{}", count);
            count += 1;
        }

        for n in 0u32..10 {
            println!("for loop iteration #{}", n);
        }

        // matching
        let age = 19;
        match age {
            1  => println!("Seems like 1"),
            5  => println!("It's 5"),
            18 => println!("Exactly 18!"),
            _  => println!("I couldn't guess :("),
        }

        match age {
            a if a > 1 && a <= 9  => println!("The age is in range [1,9]"),
            a if a > 9 && a <= 19 => println!("The age is in range [10, 19]"),
            _                     => println!("Nothing, I don't know what range the age is in :("),
        }

        // the previous match is equivalent to the following:
        match age {
            a @ 1...9   => println!("The age is {} and in range [1,9]", a),
            a @ 10...19 => println!("The age is {} and in range [10, 19]", a),
            a           => println!("Nothing, I don't know what range the age {} is in :(", a),
        }

        // if let
        let a_some = Some(0.0008);
        if let Some(i) = a_some {
            println!("a_some is not None, {}", i);
            println!("result {}",  9.0 / i);
        }
        else {
            println!("None");
        }

        // while let
        let mut a_optional = Some(10);

        while let Some(i) = a_optional {
            if i == 20 {
                println!("while let: i equals 20, leave");
                a_optional = None;
            }
            else {
                a_optional = Some(i + 1);
            }
        }

        // functions, finally!
        let first_integer: i32 = -20;
        let second_integer: i32 = 8;
        let result_of_addition = add_two_integers(first_integer, second_integer);
        println!("{} + {} = {}", first_integer, second_integer, result_of_addition);

        simple_functions::print_hello_world();
        let mul_result = simple_functions::simple_math::multiple_two_integers(3, 15);
        println!("Modules: multiplication result = {}", mul_result);

        // this doesn't work.. why?
        println!("Modules: multiplication result 2 = {}", multiple_two_integers(-1, 8));

        // "super" and "self"
        sample_module::call_sample_module();

        // file hierarchy
        {
            let a : i32 = 4;
            let b : i32 = 15;
            println!("modules::math {} + {} = {}", a, b, modules::math::add_two_int(a, b));
        }

        // call external library
        my_extern_lib::run(5);

        // tuples
        let pair = ("key", 4);
        println!("tuple value: ({}, {})", pair.0, pair.1);
        println!("tuple value: {:?}", pair);

        // structs
        let bmw: Car = Car {color: "Blue".to_string(), weight: 940};
        println!("BMW: {} - {}", bmw.color, bmw.weight);

        // tuple structs
        let color_1: RgbColor = RgbColor(123, 33, 81);
        println!("RGB color: {}, {}, {}", color_1.0, color_1.1, color_1.2);

        // unit structs
        let _nil = Nil;

        // a struct with a constructor and getter
        let rabbit = my_extern_lib::Animal::new(2, 4, "The King");
        println!("Rabbit: {}, {}, {}", rabbit.age, rabbit.weight, rabbit.get_secret_info());

        // generics
        {
            struct ThreeValues<T, U, V> {
                first: T,
                second: U,
                third: V,
            }

            let three_values = ThreeValues { first: 4, second: 2.01, third: "hello" };
            println!("Generic data structure: {}, {}, {}", three_values.first, three_values.second, three_values.third);

            // generic function
            fn swap<U, V>(first_value: U, second_value: V) -> (V, U) {
                (second_value, first_value)
            }

            let random_tuple = swap(4, 2);
            println!("Use unused variables: {} {}", random_tuple.0, random_tuple.1);

        }

        // box (heap allocation)
        {

            let toyota: Car = Car {color: "Green".to_string(), weight: 1040,};
            let porche: Box<Car> = Box::new(Car {color: "Black".to_string(), weight: 876, });

            println!("Toyota's size on stack is {}", std::mem::size_of_val(&toyota));
            println!("Boxed porche's size on stack is {}", std::mem::size_of_val(&porche));

            let unboxed_porche: Car = *porche;
            println!("Unboxed porche's size on stack is {}", std::mem::size_of_val(&unboxed_porche));

            // ownership
            let bmw : Box<Car> = Box::new(Car {color: "Yellow".to_string(), weight: 1620});
            println!("Boxed BMW at {:p}: {}/{}", &bmw, bmw.color, bmw.weight);
            let moved_bmw: Box<Car> = bmw;
            println!("Moved BMW at {:p}: {}/{}", &moved_bmw, moved_bmw.color, moved_bmw.weight);
            // can't do the following, the ownership has been moved
            // println!("Boxed BMW at {:p}: {}/{}", &bmw, bmw.color, bmw.weight);

            // mutability
            let immutable_car = Box::new(Car {color: "Pink".to_string(), weight: 510});
            // can't do this
            // immutable_car.weight = 403;

            // but we can change mutability
            let mut mutable_car = immutable_car;
            mutable_car.weight = 401;

        }

}

// a C-like struct
struct Car {
    color: String,
    weight: u32,
}

// a tuple struct s
struct RgbColor(i8, i8, i8);

// a unit struct
struct Nil;

fn add_two_integers(a: i32, b: i32) -> i32 {
    a + b
}
<commit_msg>Progress: the ref pattern<commit_after>// library
extern crate my_extern_lib;

// modules
mod simple_functions {
    pub fn print_hello_world() {
        println!("Hello, World! (from the simple_functions module)");
     }

    // nested modules
    pub mod simple_math {
        pub fn multiple_two_integers(a: i32, b: i32) -> i32 {
            a * b
        }
    }
}

use simple_functions::simple_math::multiple_two_integers;

fn print_some_msg() {
    println!("Modules: printing from the outer function");
}

mod sample_module {

    pub fn call_sample_module() {
        use second_module::print_some_msg as print_second;
        use self::second_module::print_some_msg as print_second_sample;
        use super::print_some_msg as print_outside;
        print_outside();
        print_second();
        print_some_msg();
        print_second_sample();
    }

    mod second_module {

        pub fn print_some_msg() {
            println!("Modules: printing from the second module inside the sample module");
        }

    }

    fn print_some_msg() {
        println!("Modules: printing from the inside of the sample module");
    }

}

mod second_module {
    pub fn print_some_msg() {
        println!("Modules: printing from the second module");
    }
}

mod modules;

fn main() {

    // formatted output
    println!("Hello, Rust!");
    println!("Integer number = {}", 23);
    println!("Float number = {}", 1.012);
    println!("Repeat printing: {0}, {1}, {1}, {3}, {2}", 2, 1, 44, 9);
    println!("Named arguments: {name}, {age}, {occupation}", age="24", name="Ann", occupation="Designer");
    println!("{:08b} XOR {:08b} = {:08b}", 3i8, 32i8, 3i8 ^ 34i8);
    println!("Floating point number {:?}", 2.910210);
    println!("Hex: {:08X}, {:08x}", 131342112, 131342112);
    // TODO find out why this doesn't work:
    //println!("{0:08X}, {0:08x}", 7661);

    // variables
    let integer = 3i32;
    let floating_point = 2.1137;

    let mut u_integer = 3u32;
    //integer += 1; error: an immutable variable
    u_integer += 1;

    println!("{}, {}, {}", integer, floating_point, u_integer);
    // TODO find out why snake case instead of camel case

    // shadowing
    let first_var = 4;
    {
        let first_var = 51;
        println!("first_var = {}", first_var);
    }
    println!("first_var = {}", first_var);

    // unitialized variables
    let uninit_var;
    //println!("uninit_var = {}", uninit_var); error: use of an init variable
    uninit_var = 231.2;
    println!("already initialized uninit_var = {}", uninit_var);

    // type casting
    let a_integer = 0x40_u8;
    let a_char = a_integer as char;
    println!("char cast from integer {}: {}", a_integer, a_char);

    let a_float = 8.45511;
    println!("integer cast from float {}: {}", a_float, a_float as i32);

    println!("Binary represntation of {}: {:08b}", -1_i8, -1_i8);
    println!("Binary represntation of {}: {:08b}", -2_i8, -2_i8);

    // aliases
    type FloatingPoint32 = f32;
    let a_float_2 : FloatingPoint32 = 3 as f32;
    println!("Type alias: {}, size of var {}", a_float_2, std::mem::size_of_val(&a_float_2));

    // expressions
    let expr = {
        let x = 4.09;
        let y = 1.28;
        println!("x = {}, y = {}", x, y);
        x / y
    };
    println!("expr = {}", expr);

    // if-statement (every if-statement is an expression too, which is really a cool thing)
    let speed = 10;
    let mass = 890;
    let consumption =
        if speed < 0 {
            -1.0
        }
        else if speed == 0 {
            0.8
        }
        else if speed > 0 && speed < 10 {
            18.52
        }
        else if speed >= 10 && speed < 30 {
            let x = mass / speed;
            (x as f32) * 0.05
        }
        else {
            11.71
        };
        println!("Speed = {}, consumption = {}", speed, consumption);

        // loop
        let mut count = 0u32;
        loop {
            println!("loop iteration #{}", count);
            count += 1;
            if count > 9 {
            break;
            }
        }

        count = 0;
        while count < 10 {
            println!("while loop iteration #{}", count);
            count += 1;
        }

        for n in 0u32..10 {
            println!("for loop iteration #{}", n);
        }

        // matching
        let age = 19;
        match age {
            1  => println!("Seems like 1"),
            5  => println!("It's 5"),
            18 => println!("Exactly 18!"),
            _  => println!("I couldn't guess :("),
        }

        match age {
            a if a > 1 && a <= 9  => println!("The age is in range [1,9]"),
            a if a > 9 && a <= 19 => println!("The age is in range [10, 19]"),
            _                     => println!("Nothing, I don't know what range the age is in :("),
        }

        // the previous match is equivalent to the following:
        match age {
            a @ 1...9   => println!("The age is {} and in range [1,9]", a),
            a @ 10...19 => println!("The age is {} and in range [10, 19]", a),
            a           => println!("Nothing, I don't know what range the age {} is in :(", a),
        }

        // if let
        let a_some = Some(0.0008);
        if let Some(i) = a_some {
            println!("a_some is not None, {}", i);
            println!("result {}",  9.0 / i);
        }
        else {
            println!("None");
        }

        // while let
        let mut a_optional = Some(10);

        while let Some(i) = a_optional {
            if i == 20 {
                println!("while let: i equals 20, leave");
                a_optional = None;
            }
            else {
                a_optional = Some(i + 1);
            }
        }

        // functions, finally!
        let first_integer: i32 = -20;
        let second_integer: i32 = 8;
        let result_of_addition = add_two_integers(first_integer, second_integer);
        println!("{} + {} = {}", first_integer, second_integer, result_of_addition);

        simple_functions::print_hello_world();
        let mul_result = simple_functions::simple_math::multiple_two_integers(3, 15);
        println!("Modules: multiplication result = {}", mul_result);

        // this doesn't work.. why?
        println!("Modules: multiplication result 2 = {}", multiple_two_integers(-1, 8));

        // "super" and "self"
        sample_module::call_sample_module();

        // file hierarchy
        {
            let a : i32 = 4;
            let b : i32 = 15;
            println!("modules::math {} + {} = {}", a, b, modules::math::add_two_int(a, b));
        }

        // call external library
        my_extern_lib::run(5);

        // tuples
        let pair = ("key", 4);
        println!("tuple value: ({}, {})", pair.0, pair.1);
        println!("tuple value: {:?}", pair);

        // structs
        let bmw: Car = Car {color: "Blue".to_string(), weight: 940};
        println!("BMW: {} - {}", bmw.color, bmw.weight);

        // tuple structs
        let color_1: RgbColor = RgbColor(123, 33, 81);
        println!("RGB color: {}, {}, {}", color_1.0, color_1.1, color_1.2);

        // unit structs
        let _nil = Nil;

        // a struct with a constructor and getter
        let rabbit = my_extern_lib::Animal::new(2, 4, "The King");
        println!("Rabbit: {}, {}, {}", rabbit.age, rabbit.weight, rabbit.get_secret_info());

        // generics
        {
            struct ThreeValues<T, U, V> {
                first: T,
                second: U,
                third: V,
            }

            let three_values = ThreeValues { first: 4, second: 2.01, third: "hello" };
            println!("Generic data structure: {}, {}, {}", three_values.first, three_values.second, three_values.third);

            // generic function
            fn swap<U, V>(first_value: U, second_value: V) -> (V, U) {
                (second_value, first_value)
            }

            let random_tuple = swap(4, 2);
            println!("Use unused variables: {} {}", random_tuple.0, random_tuple.1);

        }

        // box (heap allocation)
        {

            let toyota: Car = Car {color: "Green".to_string(), weight: 1040,};
            let porche: Box<Car> = Box::new(Car {color: "Black".to_string(), weight: 876, });

            println!("Toyota's size on stack is {}", std::mem::size_of_val(&toyota));
            println!("Boxed porche's size on stack is {}", std::mem::size_of_val(&porche));

            let unboxed_porche: Car = *porche;
            println!("Unboxed porche's size on stack is {}", std::mem::size_of_val(&unboxed_porche));

            // ownership
            let bmw : Box<Car> = Box::new(Car {color: "Yellow".to_string(), weight: 1620});
            println!("Boxed BMW at {:p}: {}/{}", &bmw, bmw.color, bmw.weight);
            let moved_bmw: Box<Car> = bmw;
            println!("Moved BMW at {:p}: {}/{}", &moved_bmw, moved_bmw.color, moved_bmw.weight);
            // can't do the following, the ownership has been moved
            // println!("Boxed BMW at {:p}: {}/{}", &bmw, bmw.color, bmw.weight);

            // mutability
            let immutable_car = Box::new(Car {color: "Pink".to_string(), weight: 510});
            // can't do this
            // immutable_car.weight = 403;

            // but we can change mutability
            let mut mutable_car = immutable_car;
            mutable_car.weight = 401;

        }

        // ref
        {

            let mut bmw: Car = Car {color: "Green".to_string(), weight: 870};
            println!("Ref: bmw {},{}", bmw.color, bmw.weight);

            {
                let Car {color: _, weight: ref weight_reference} = bmw;

                println!("Ref: {}", *weight_reference);
            }

            {
                let Car {color: _, weight: ref mut weight_mut_ref} = bmw;

                *weight_mut_ref = 200;
            }

            println!("Ref: bmw {},{}", bmw.color, bmw.weight);

        }

}

// a C-like struct
struct Car {
    color: String,
    weight: u32,
}

// a tuple struct s
struct RgbColor(i8, i8, i8);

// a unit struct
struct Nil;

fn add_two_integers(a: i32, b: i32) -> i32 {
    a + b
}
<|endoftext|>


<commit_before>#[allow(ctypes)];
#[no_std];
#[no_core];

use drivers::keyboard;

pub mod zero;
mod drivers {
    pub mod keyboard;
}

#[inline]
pub fn size_of_val<T>(_val: *mut T) -> uint {
    unsafe { zero::size_of::<T>() }
}

#[packed]
struct idt_reg {
    size: u16,
    addr: *mut [idt_entry, ..256],
}

static Present: u8 = 1 << 7;
static PM32Bit: u8 = 1 << 3;

#[packed]
struct idt_entry {
    addr_lo: u16,
    sel: u16,
    zero: u8,
    flags: u8,
    addr_hi: u16
}

fn idt_entry(proc: u32, sel: u16, flags: u8) -> idt_entry {
    idt_entry {
        addr_lo: (proc & 0xffff) as u16,
        sel: sel,
        zero: 0,
        flags: flags | 0b110,
        addr_hi: (proc >> 16) as u16
    }
}

enum Color {
    Black       = 0,
    Blue        = 1,
    Green       = 2,
    Cyan        = 3,
    Red         = 4,
    Pink        = 5,
    Brown       = 6,
    LightGray   = 7,
    DarkGray    = 8,
    LightBlue   = 9,
    LightGreen  = 10,
    LightCyan   = 11,
    LightRed    = 12,
    LightPink   = 13,
    Yellow      = 14,
    White       = 15,
}

fn range(lo: uint, hi: uint, it: &fn(uint)) {
    let mut iter = lo;
    while iter < hi {
        it(iter);
        iter += 1;
    }
}

unsafe fn clear_screen(background: Color) {
    range(0, 80*25, |i| {
        *((0xb8000 + i * 2) as *mut u16) = (background as u16) << 12;
    });
}

unsafe fn pic_remap() {
    asm!("
        mov al, 0x11
        out 0x20, al
        out 0xa0, al

        mov al, 0x20
        out 0x21, al
        mov al, 0x28
        out 0xa1, al

        mov al, 4
        out 0x21, al
        mov al, 2
        out 0xa1, al

        mov al, 1
        out 0x21, al
        out 0xa1, al

        mov al, 0xff
        out 0x21, al
        out 0xa1, al"
        :::: "intel");
}

unsafe fn pic_enable(irq: u8) {
    let port: u16 = if (irq & 0b1000) == 0 { 0x21 } else { 0xa1 };
    let mask: u8 = !(1u8 << (irq & 0b111));

    asm!("
        mov dx, $0
        in al, dx
        and al, $1
        out dx, al"
        :: "r"(port), "r"(mask) : "al", "dx" : "intel")
}

#[no_mangle]
extern "C" fn keyup(code: u32) { }

pub static ascii_table: &'static str = "\
\x00\x1B1234567890-=\x08\
\tqwertyuiop[]\n\
\x00asdfghjkl;'`\
\x00\\zxcvbnm,./\x00\
*\x00 ";

fn keydown(code: u32) {
    let screen = 0xb8000 as *mut [u16, ..2000];
    // mutable statics are incorrectly dereferenced in PIC!
    static mut pos: u32 = 0;

    if(code & (1 << 7) == 0) {
        unsafe {
            let char = ascii_table[code];
            if char == 8 && pos > 0 {
                pos -= 1;
                (*screen)[pos] &= 0xff00;
            } else if char == '\n' as u8 {
                pos += 80 - pos % 80;
            } else {
                (*screen)[pos] |= char as u16;
                pos += 1;
            }
        }
    }
}

#[no_mangle]
pub unsafe fn main() {
    clear_screen(LightRed);
    // invalid deref when &fn?
    keyboard::callback = keyboard::Some(keydown);

    let idt = 0x100000 as *mut [idt_entry, ..256];

    (*idt)[keyboard::IRQ] = idt_entry(keyboard::isr_addr(), 1 << 3, PM32Bit | Present);

    let idt_table = 0x100800 as *mut idt_reg;
    *idt_table = idt_reg {
        addr: idt,
        size: size_of_val(idt) as u16
    };

    pic_remap();
    pic_enable(keyboard::IRQ);

    asm!("
        lidt [$0]
        sti"
        :: "n"(idt_table) :: "intel");
}
<commit_msg>Fix inline intel assembly (workaround)<commit_after>#[allow(ctypes)];
#[no_std];
#[no_core];

use drivers::keyboard;

pub mod zero;
mod drivers {
    pub mod keyboard;
}

#[inline]
pub fn size_of_val<T>(_val: *mut T) -> uint {
    unsafe { zero::size_of::<T>() }
}

#[packed]
struct idt_reg {
    size: u16,
    addr: *mut [idt_entry, ..256],
}

static Present: u8 = 1 << 7;
static PM32Bit: u8 = 1 << 3;

#[packed]
struct idt_entry {
    addr_lo: u16,
    sel: u16,
    zero: u8,
    flags: u8,
    addr_hi: u16
}

fn idt_entry(proc: u32, sel: u16, flags: u8) -> idt_entry {
    idt_entry {
        addr_lo: (proc & 0xffff) as u16,
        sel: sel,
        zero: 0,
        flags: flags | 0b110,
        addr_hi: (proc >> 16) as u16
    }
}

enum Color {
    Black       = 0,
    Blue        = 1,
    Green       = 2,
    Cyan        = 3,
    Red         = 4,
    Pink        = 5,
    Brown       = 6,
    LightGray   = 7,
    DarkGray    = 8,
    LightBlue   = 9,
    LightGreen  = 10,
    LightCyan   = 11,
    LightRed    = 12,
    LightPink   = 13,
    Yellow      = 14,
    White       = 15,
}

fn range(lo: uint, hi: uint, it: &fn(uint)) {
    let mut iter = lo;
    while iter < hi {
        it(iter);
        iter += 1;
    }
}

unsafe fn clear_screen(background: Color) {
    range(0, 80*25, |i| {
        *((0xb8000 + i * 2) as *mut u16) = (background as u16) << 12;
    });
}

unsafe fn pic_remap() {
    asm!("
        mov al, 0x11
        mov dx, 0x20
        out dx, al
        mov dx, 0xA0
        out dx, al

        mov al, 0x20
        mov dx, 0x21
        mov bx, 0xA1
        out dx, al
        mov al, 0x28
        xchg bx, dx
        out dx, al

        mov al, 4
        xchg bx, dx
        out dx, al
        mov al, 2
        xchg bx, dx
        out dx, al

        mov al, 1
        xchg bx, dx
        out dx, al
        xchg bx, dx
        out dx, al

        mov al, 0xff
        xchg bx, dx
        out dx, al
        xchg bx, dx
        out dx, al"
        ::: "al", "bx", "dx" : "volatile", "intel");
}

#[inline(never)]
unsafe fn pic_enable(irq: u8) {
    let port: u16 = if (irq & 0b1000) == 0 { 0x21 } else { 0xa1 };
    let mask: u8 = !(1u8 << (irq & 0b111));

    asm!("
        mov dx, $0
        in al, dx
        and al, $1
        out dx, al"
        :: "r"(port), "r"(mask) : "al", "dx" : "intel")
}

#[no_mangle]
extern "C" fn keyup(code: u32) { }

pub static ascii_table: &'static str = "\
\x00\x1B1234567890-=\x08\
\tqwertyuiop[]\n\
\x00asdfghjkl;'`\
\x00\\zxcvbnm,./\x00\
*\x00 ";

fn keydown(code: u32) {
    let screen = 0xb8000 as *mut [u16, ..2000];
    // mutable statics are incorrectly dereferenced in PIC!
    static mut pos: u32 = 0;

    if(code & (1 << 7) == 0) {
        unsafe {
            let char = ascii_table[code];
            if char == 8 && pos > 0 {
                pos -= 1;
                (*screen)[pos] &= 0xff00;
            } else if char == '\n' as u8 {
                pos += 80 - pos % 80;
            } else {
                (*screen)[pos] |= char as u16;
                pos += 1;
            }
        }
    }
}

#[no_mangle]
pub unsafe fn main() {
    clear_screen(LightRed);
    // invalid deref when &fn?
    keyboard::callback = keyboard::Some(keydown);

    let idt = 0x100000 as *mut [idt_entry, ..256];

    (*idt)[keyboard::IRQ] = idt_entry(keyboard::isr_addr(), 1 << 3, PM32Bit | Present);

    let idt_table = 0x100800 as *mut idt_reg;
    *idt_table = idt_reg {
        addr: idt,
        size: size_of_val(idt) as u16
    };

    pic_remap();
    pic_enable(keyboard::IRQ);

    asm!("
        lidt [$0]
        sti"
        :: "n"(idt_table) :: "intel");
}
<|endoftext|>


<commit_before>// library
extern crate my_extern_lib;

// modules
mod simple_functions {
    pub fn print_hello_world() {
        println!("Hello, World! (from the simple_functions module)");
     }

    // nested modules
    pub mod simple_math {
        pub fn multiple_two_integers(a: i32, b: i32) -> i32 {
            a * b
        }
    }
}

use simple_functions::simple_math::multiple_two_integers;

fn print_some_msg() {
    println!("Modules: printing from the outer function");
}

mod sample_module {

    pub fn call_sample_module() {
        use second_module::print_some_msg as print_second;
        use self::second_module::print_some_msg as print_second_sample;
        use super::print_some_msg as print_outside;
        print_outside();
        print_second();
        print_some_msg();
        print_second_sample();
    }

    mod second_module {

        pub fn print_some_msg() {
            println!("Modules: printing from the second module inside the sample module");
        }

    }

    fn print_some_msg() {
        println!("Modules: printing from the inside of the sample module");
    }

}

mod second_module {
    pub fn print_some_msg() {
        println!("Modules: printing from the second module");
    }
}

mod modules;

fn main() {

    // formatted output
    println!("Hello, Rust!");
    println!("Integer number = {}", 23);
    println!("Float number = {}", 1.012);
    println!("Repeat printing: {0}, {1}, {1}, {3}, {2}", 2, 1, 44, 9);
    println!("Named arguments: {name}, {age}, {occupation}", age="24", name="Ann", occupation="Designer");
    println!("{:08b} XOR {:08b} = {:08b}", 3i8, 32i8, 3i8 ^ 34i8);
    println!("Floating point number {:?}", 2.910210);
    println!("Hex: {:08X}, {:08x}", 131342112, 131342112);
    // TODO find out why this doesn't work:
    //println!("{0:08X}, {0:08x}", 7661);

    // variables
    let integer = 3i32;
    let floating_point = 2.1137;

    let mut u_integer = 3u32;
    //integer += 1; error: an immutable variable
    u_integer += 1;

    println!("{}, {}, {}", integer, floating_point, u_integer);
    // TODO find out why snake case instead of camel case

    // shadowing
    let first_var = 4;
    {
        let first_var = 51;
        println!("first_var = {}", first_var);
    }
    println!("first_var = {}", first_var);

    // unitialized variables
    let uninit_var;
    //println!("uninit_var = {}", uninit_var); error: use of an init variable
    uninit_var = 231.2;
    println!("already initialized uninit_var = {}", uninit_var);

    // type casting
    let a_integer = 0x40_u8;
    let a_char = a_integer as char;
    println!("char cast from integer {}: {}", a_integer, a_char);

    let a_float = 8.45511;
    println!("integer cast from float {}: {}", a_float, a_float as i32);

    println!("Binary represntation of {}: {:08b}", -1_i8, -1_i8);
    println!("Binary represntation of {}: {:08b}", -2_i8, -2_i8);

    // aliases
    type FloatingPoint32 = f32;
    let a_float_2 : FloatingPoint32 = 3 as f32;
    println!("Type alias: {}, size of var {}", a_float_2, std::mem::size_of_val(&a_float_2));

    // expressions
    let expr = {
        let x = 4.09;
        let y = 1.28;
        println!("x = {}, y = {}", x, y);
        x / y
    };
    println!("expr = {}", expr);

    // if-statement (every if-statement is an expression too, which is really a cool thing)
    let speed = 10;
    let mass = 890;
    let consumption =
        if speed < 0 {
            -1.0
        }
        else if speed == 0 {
            0.8
        }
        else if speed > 0 && speed < 10 {
            18.52
        }
        else if speed >= 10 && speed < 30 {
            let x = mass / speed;
            (x as f32) * 0.05
        }
        else {
            11.71
        };
        println!("Speed = {}, consumption = {}", speed, consumption);

        // loop
        let mut count = 0u32;
        loop {
            println!("loop iteration #{}", count);
            count += 1;
            if count > 9 {
            break;
            }
        }

        count = 0;
        while count < 10 {
            println!("while loop iteration #{}", count);
            count += 1;
        }

        for n in 0u32..10 {
            println!("for loop iteration #{}", n);
        }

        // matching
        let age = 19;
        match age {
            1  => println!("Seems like 1"),
            5  => println!("It's 5"),
            18 => println!("Exactly 18!"),
            _  => println!("I couldn't guess :("),
        }

        match age {
            a if a > 1 && a <= 9  => println!("The age is in range [1,9]"),
            a if a > 9 && a <= 19 => println!("The age is in range [10, 19]"),
            _                     => println!("Nothing, I don't know what range the age is in :("),
        }

        // the previous match is equivalent to the following:
        match age {
            a @ 1...9   => println!("The age is {} and in range [1,9]", a),
            a @ 10...19 => println!("The age is {} and in range [10, 19]", a),
            a           => println!("Nothing, I don't know what range the age {} is in :(", a),
        }

        // if let
        let a_some = Some(0.0008);
        if let Some(i) = a_some {
            println!("a_some is not None, {}", i);
            println!("result {}",  9.0 / i);
        }
        else {
            println!("None");
        }

        // while let
        let mut a_optional = Some(10);

        while let Some(i) = a_optional {
            if i == 20 {
                println!("while let: i equals 20, leave");
                a_optional = None;
            }
            else {
                a_optional = Some(i + 1);
            }
        }

        // functions, finally!
        let first_integer: i32 = -20;
        let second_integer: i32 = 8;
        let result_of_addition = add_two_integers(first_integer, second_integer);
        println!("{} + {} = {}", first_integer, second_integer, result_of_addition);

        simple_functions::print_hello_world();
        let mul_result = simple_functions::simple_math::multiple_two_integers(3, 15);
        println!("Modules: multiplication result = {}", mul_result);

        // this doesn't work.. why?
        println!("Modules: multiplication result 2 = {}", multiple_two_integers(-1, 8));

        // "super" and "self"
        sample_module::call_sample_module();

        // file hierarchy
        {
            let a : i32 = 4;
            let b : i32 = 15;
            println!("modules::math {} + {} = {}", a, b, modules::math::add_two_int(a, b));
        }

        // call external library
        my_extern_lib::run(5);

        // tuples
        let pair = ("key", 4);
        println!("tuple value: ({}, {})", pair.0, pair.1);
        println!("tuple value: {:?}", pair);

        // structs
        let bmw: Car = Car {color: "Blue".to_string(), weight: 940};
        println!("BMW: {} - {}", bmw.color, bmw.weight);

        // tuple structs
        let color_1: RgbColor = RgbColor(123, 33, 81);
        println!("RGB color: {}, {}, {}", color_1.0, color_1.1, color_1.2);

        // unit structs
        let _nil = Nil;

        // a struct with a constructor and getter
        let rabbit = my_extern_lib::Animal::new(2, 4, "The King");
        println!("Rabbit: {}, {}, {}", rabbit.age, rabbit.weight, rabbit.get_secret_info());
}

// a C-like struct
struct Car {
    color: String,
    weight: u32,
}

// a tuple struct s
struct RgbColor(i8, i8, i8);

// a unit struct
struct Nil;

fn add_two_integers(a: i32, b: i32) -> i32 {
    a + b
}
<commit_msg>Progress: generics (structs and functions)<commit_after>// library
extern crate my_extern_lib;

// modules
mod simple_functions {
    pub fn print_hello_world() {
        println!("Hello, World! (from the simple_functions module)");
     }

    // nested modules
    pub mod simple_math {
        pub fn multiple_two_integers(a: i32, b: i32) -> i32 {
            a * b
        }
    }
}

use simple_functions::simple_math::multiple_two_integers;

fn print_some_msg() {
    println!("Modules: printing from the outer function");
}

mod sample_module {

    pub fn call_sample_module() {
        use second_module::print_some_msg as print_second;
        use self::second_module::print_some_msg as print_second_sample;
        use super::print_some_msg as print_outside;
        print_outside();
        print_second();
        print_some_msg();
        print_second_sample();
    }

    mod second_module {

        pub fn print_some_msg() {
            println!("Modules: printing from the second module inside the sample module");
        }

    }

    fn print_some_msg() {
        println!("Modules: printing from the inside of the sample module");
    }

}

mod second_module {
    pub fn print_some_msg() {
        println!("Modules: printing from the second module");
    }
}

mod modules;

fn main() {

    // formatted output
    println!("Hello, Rust!");
    println!("Integer number = {}", 23);
    println!("Float number = {}", 1.012);
    println!("Repeat printing: {0}, {1}, {1}, {3}, {2}", 2, 1, 44, 9);
    println!("Named arguments: {name}, {age}, {occupation}", age="24", name="Ann", occupation="Designer");
    println!("{:08b} XOR {:08b} = {:08b}", 3i8, 32i8, 3i8 ^ 34i8);
    println!("Floating point number {:?}", 2.910210);
    println!("Hex: {:08X}, {:08x}", 131342112, 131342112);
    // TODO find out why this doesn't work:
    //println!("{0:08X}, {0:08x}", 7661);

    // variables
    let integer = 3i32;
    let floating_point = 2.1137;

    let mut u_integer = 3u32;
    //integer += 1; error: an immutable variable
    u_integer += 1;

    println!("{}, {}, {}", integer, floating_point, u_integer);
    // TODO find out why snake case instead of camel case

    // shadowing
    let first_var = 4;
    {
        let first_var = 51;
        println!("first_var = {}", first_var);
    }
    println!("first_var = {}", first_var);

    // unitialized variables
    let uninit_var;
    //println!("uninit_var = {}", uninit_var); error: use of an init variable
    uninit_var = 231.2;
    println!("already initialized uninit_var = {}", uninit_var);

    // type casting
    let a_integer = 0x40_u8;
    let a_char = a_integer as char;
    println!("char cast from integer {}: {}", a_integer, a_char);

    let a_float = 8.45511;
    println!("integer cast from float {}: {}", a_float, a_float as i32);

    println!("Binary represntation of {}: {:08b}", -1_i8, -1_i8);
    println!("Binary represntation of {}: {:08b}", -2_i8, -2_i8);

    // aliases
    type FloatingPoint32 = f32;
    let a_float_2 : FloatingPoint32 = 3 as f32;
    println!("Type alias: {}, size of var {}", a_float_2, std::mem::size_of_val(&a_float_2));

    // expressions
    let expr = {
        let x = 4.09;
        let y = 1.28;
        println!("x = {}, y = {}", x, y);
        x / y
    };
    println!("expr = {}", expr);

    // if-statement (every if-statement is an expression too, which is really a cool thing)
    let speed = 10;
    let mass = 890;
    let consumption =
        if speed < 0 {
            -1.0
        }
        else if speed == 0 {
            0.8
        }
        else if speed > 0 && speed < 10 {
            18.52
        }
        else if speed >= 10 && speed < 30 {
            let x = mass / speed;
            (x as f32) * 0.05
        }
        else {
            11.71
        };
        println!("Speed = {}, consumption = {}", speed, consumption);

        // loop
        let mut count = 0u32;
        loop {
            println!("loop iteration #{}", count);
            count += 1;
            if count > 9 {
            break;
            }
        }

        count = 0;
        while count < 10 {
            println!("while loop iteration #{}", count);
            count += 1;
        }

        for n in 0u32..10 {
            println!("for loop iteration #{}", n);
        }

        // matching
        let age = 19;
        match age {
            1  => println!("Seems like 1"),
            5  => println!("It's 5"),
            18 => println!("Exactly 18!"),
            _  => println!("I couldn't guess :("),
        }

        match age {
            a if a > 1 && a <= 9  => println!("The age is in range [1,9]"),
            a if a > 9 && a <= 19 => println!("The age is in range [10, 19]"),
            _                     => println!("Nothing, I don't know what range the age is in :("),
        }

        // the previous match is equivalent to the following:
        match age {
            a @ 1...9   => println!("The age is {} and in range [1,9]", a),
            a @ 10...19 => println!("The age is {} and in range [10, 19]", a),
            a           => println!("Nothing, I don't know what range the age {} is in :(", a),
        }

        // if let
        let a_some = Some(0.0008);
        if let Some(i) = a_some {
            println!("a_some is not None, {}", i);
            println!("result {}",  9.0 / i);
        }
        else {
            println!("None");
        }

        // while let
        let mut a_optional = Some(10);

        while let Some(i) = a_optional {
            if i == 20 {
                println!("while let: i equals 20, leave");
                a_optional = None;
            }
            else {
                a_optional = Some(i + 1);
            }
        }

        // functions, finally!
        let first_integer: i32 = -20;
        let second_integer: i32 = 8;
        let result_of_addition = add_two_integers(first_integer, second_integer);
        println!("{} + {} = {}", first_integer, second_integer, result_of_addition);

        simple_functions::print_hello_world();
        let mul_result = simple_functions::simple_math::multiple_two_integers(3, 15);
        println!("Modules: multiplication result = {}", mul_result);

        // this doesn't work.. why?
        println!("Modules: multiplication result 2 = {}", multiple_two_integers(-1, 8));

        // "super" and "self"
        sample_module::call_sample_module();

        // file hierarchy
        {
            let a : i32 = 4;
            let b : i32 = 15;
            println!("modules::math {} + {} = {}", a, b, modules::math::add_two_int(a, b));
        }

        // call external library
        my_extern_lib::run(5);

        // tuples
        let pair = ("key", 4);
        println!("tuple value: ({}, {})", pair.0, pair.1);
        println!("tuple value: {:?}", pair);

        // structs
        let bmw: Car = Car {color: "Blue".to_string(), weight: 940};
        println!("BMW: {} - {}", bmw.color, bmw.weight);

        // tuple structs
        let color_1: RgbColor = RgbColor(123, 33, 81);
        println!("RGB color: {}, {}, {}", color_1.0, color_1.1, color_1.2);

        // unit structs
        let _nil = Nil;

        // a struct with a constructor and getter
        let rabbit = my_extern_lib::Animal::new(2, 4, "The King");
        println!("Rabbit: {}, {}, {}", rabbit.age, rabbit.weight, rabbit.get_secret_info());

        // generics
        {
            struct ThreeValues<T, U, V> {
                first: T,
                second: U,
                third: V,
            }

            let three_values = ThreeValues { first: 4, second: 2.01, third: "hello" };
            println!("Generic data structure: {}, {}, {}", three_values.first, three_values.second, three_values.third);

            // generic function
            fn swap<U, V>(first_value: U, second_value: V) -> (V, U) {
                (second_value, first_value)
            }

            let random_tuple = swap(4, 2);
            println!("Use unused variables: {} {}", random_tuple.0, random_tuple.1);

        }
}

// a C-like struct
struct Car {
    color: String,
    weight: u32,
}

// a tuple struct s
struct RgbColor(i8, i8, i8);

// a unit struct
struct Nil;

fn add_two_integers(a: i32, b: i32) -> i32 {
    a + b
}
<|endoftext|>


<commit_before>// This is a brute-force solution, use `cargo test --release` for faster testing

extern crate itertools;
extern crate permutohedron;

use itertools::Itertools;
use permutohedron::Heap as Permutations;

use std::char;
use std::collections::HashMap;
use std::collections::HashSet;

fn test_equation(puzzle: &str, substitutions: &HashMap<char, u8>) -> bool {
    // Create a new String with characters changed to numbers
    let puzzle: String = puzzle
        .chars()
        .map(|c| {
            if let Some(&n) = substitutions.get(&c) {
                // If the character is in the substitutions, get the number and
                // convert it to a char
                char::from_digit(n as u32, 10).unwrap()
            } else {
                // Otherwise just copy over the character
                c
            }
        })
        .collect();

    // Split the puzzle into left and right side
    let equation: Vec<&str> = puzzle.split("==").collect();

    // Parse the number on the right side
    let right = equation[1].trim().parse::<u32>().unwrap();

    // Sum the parts on the left side
    let left: u32 = equation[0]
        .split('+')
        .map(str::trim)
        .map(|n| n.parse::<u32>().unwrap())
        .sum();

    // Create a String with just the numbers and spaces
    let just_numbers = puzzle
        .chars()
        .filter(|c| c.is_digit(10) || c.is_whitespace())
        .collect::<String>();
    // Split this into the numbers and check every number's first character
    let no_leading_zeroes = just_numbers
        .split_whitespace()
        .all(|number| number.chars().next().unwrap() != '0');

    // Return true if left and right side is equal and the equation doesnt
    // contain leading zeroes.
    left == right && no_leading_zeroes
}

pub fn solve(puzzle: &str) -> Option<HashMap<char, u8>> {
    // Get unique letters from the puzzle
    let letters: HashSet<char> = puzzle
        .chars()
        .filter(|&c| c.is_alphabetic() && c.is_uppercase())
        .collect();
    let letters: Vec<char> = letters.into_iter().collect();

    // All available numbers for substitution
    let numbers: &[u8] = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9];

    // Iterate every combination with the length of unique letters in the puzzle
    for combinations in numbers.iter().combinations(letters.len()) {
        let mut c = combinations;
        let permutations = Permutations::new(&mut c);
        // Iterate every permutation of a letter combination
        for p in permutations {
            let substitution: HashMap<char, u8> =
                letters.iter().zip(p).map(|(&c, &n)| (c, n)).collect();
            if test_equation(puzzle, &substitution) {
                // We found a good substitution
                return Some(substitution);
            }
        }
    }
    // If we tested every combination and did not found a solution then return None
    None
}
<commit_msg>alphametics: Use `starts_with`<commit_after>// This is a brute-force solution, use `cargo test --release` for faster testing

extern crate itertools;
extern crate permutohedron;

use itertools::Itertools;
use permutohedron::Heap as Permutations;

use std::char;
use std::collections::HashMap;
use std::collections::HashSet;

fn test_equation(puzzle: &str, substitutions: &HashMap<char, u8>) -> bool {
    // Create a new String with characters changed to numbers
    let puzzle: String = puzzle
        .chars()
        .map(|c| {
            if let Some(&n) = substitutions.get(&c) {
                // If the character is in the substitutions, get the number and
                // convert it to a char
                char::from_digit(n as u32, 10).unwrap()
            } else {
                // Otherwise just copy over the character
                c
            }
        })
        .collect();

    // Split the puzzle into left and right side
    let equation: Vec<&str> = puzzle.split("==").collect();

    // Parse the number on the right side
    let right = equation[1].trim().parse::<u32>().unwrap();

    // Sum the parts on the left side
    let left: u32 = equation[0]
        .split('+')
        .map(str::trim)
        .map(|n| n.parse::<u32>().unwrap())
        .sum();

    // Create a String with just the numbers and spaces
    let just_numbers = puzzle
        .chars()
        .filter(|c| c.is_digit(10) || c.is_whitespace())
        .collect::<String>();
    // Split this into the numbers and check every number's first character
    let no_leading_zeroes = just_numbers
        .split_whitespace()
        .all(|number| !number.starts_with('0'));

    // Return true if left and right side is equal and the equation doesnt
    // contain leading zeroes.
    left == right && no_leading_zeroes
}

pub fn solve(puzzle: &str) -> Option<HashMap<char, u8>> {
    // Get unique letters from the puzzle
    let letters: HashSet<char> = puzzle
        .chars()
        .filter(|&c| c.is_alphabetic() && c.is_uppercase())
        .collect();
    let letters: Vec<char> = letters.into_iter().collect();

    // All available numbers for substitution
    let numbers: &[u8] = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9];

    // Iterate every combination with the length of unique letters in the puzzle
    for combinations in numbers.iter().combinations(letters.len()) {
        let mut c = combinations;
        let permutations = Permutations::new(&mut c);
        // Iterate every permutation of a letter combination
        for p in permutations {
            let substitution: HashMap<char, u8> =
                letters.iter().zip(p).map(|(&c, &n)| (c, n)).collect();
            if test_equation(puzzle, &substitution) {
                // We found a good substitution
                return Some(substitution);
            }
        }
    }
    // If we tested every combination and did not found a solution then return None
    None
}
<|endoftext|>


<commit_before>// Copyright 2020 Google LLC
//
// 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
//
//    https://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 autocxx_engine::{
    build as engine_build, expect_build as engine_expect_build, BuilderBuild, BuilderError,
    RebuildDependencyRecorder,
};
use std::io::Write;
use std::{ffi::OsStr, path::Path};

/// Build autocxx C++ files and return a cc::Build you can use to build
/// more from a build.rs file.
/// You need to provide the Rust file path and the iterator of paths
/// which should be used as include directories.
pub fn build<P1, I, T>(
    rs_file: P1,
    autocxx_incs: I,
    definitions: &[impl AsRef<str>],
) -> Result<BuilderBuild, BuilderError>
where
    P1: AsRef<Path>,
    I: IntoIterator<Item = T>,
    T: AsRef<OsStr>,
{
    setup_logging();
    engine_build(
        rs_file,
        autocxx_incs,
        definitions,
        Some(Box::new(CargoRebuildDependencyRecorder)),
    )
    .map(|r| r.0)
}

/// Builds successfully, or exits the process displaying a suitable
/// message.
pub fn expect_build<P1, I, T>(
    rs_file: P1,
    autocxx_incs: I,
    definitions: &[impl AsRef<str>],
) -> BuilderBuild
where
    P1: AsRef<Path>,
    I: IntoIterator<Item = T>,
    T: AsRef<OsStr>,
{
    setup_logging();
    engine_expect_build(
        rs_file,
        autocxx_incs,
        definitions,
        Some(Box::new(CargoRebuildDependencyRecorder)),
    )
    .0
}

fn setup_logging() {
    env_logger::builder()
        .format(|buf, record| writeln!(buf, "cargo:warning=MESSAGE:{}", record.args()))
        .init();
}

#[derive(Debug)]
struct CargoRebuildDependencyRecorder;

impl RebuildDependencyRecorder for CargoRebuildDependencyRecorder {
    fn record_header_file_dependency(&self, filename: &str) {
        println!("cargo:rerun-if-changed={}", filename);
    }
}
<commit_msg>Cease to print duplicate dependencies.<commit_after>// Copyright 2020 Google LLC
//
// 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
//
//    https://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 autocxx_engine::{
    build as engine_build, expect_build as engine_expect_build, BuilderBuild, BuilderError,
    RebuildDependencyRecorder,
};
use std::{collections::HashSet, io::Write, sync::Mutex};
use std::{ffi::OsStr, path::Path};

/// Build autocxx C++ files and return a cc::Build you can use to build
/// more from a build.rs file.
/// You need to provide the Rust file path and the iterator of paths
/// which should be used as include directories.
pub fn build<P1, I, T>(
    rs_file: P1,
    autocxx_incs: I,
    definitions: &[impl AsRef<str>],
) -> Result<BuilderBuild, BuilderError>
where
    P1: AsRef<Path>,
    I: IntoIterator<Item = T>,
    T: AsRef<OsStr>,
{
    setup_logging();
    engine_build(
        rs_file,
        autocxx_incs,
        definitions,
        Some(Box::new(CargoRebuildDependencyRecorder::new())),
    )
    .map(|r| r.0)
}

/// Builds successfully, or exits the process displaying a suitable
/// message.
pub fn expect_build<P1, I, T>(
    rs_file: P1,
    autocxx_incs: I,
    definitions: &[impl AsRef<str>],
) -> BuilderBuild
where
    P1: AsRef<Path>,
    I: IntoIterator<Item = T>,
    T: AsRef<OsStr>,
{
    setup_logging();
    engine_expect_build(
        rs_file,
        autocxx_incs,
        definitions,
        Some(Box::new(CargoRebuildDependencyRecorder::new())),
    )
    .0
}

fn setup_logging() {
    env_logger::builder()
        .format(|buf, record| writeln!(buf, "cargo:warning=MESSAGE:{}", record.args()))
        .init();
}

#[derive(Debug)]
struct CargoRebuildDependencyRecorder {
    printed_already: Mutex<HashSet<String>>,
}

impl CargoRebuildDependencyRecorder {
    fn new() -> Self {
        Self {
            printed_already: Mutex::new(HashSet::new()),
        }
    }
}

impl RebuildDependencyRecorder for CargoRebuildDependencyRecorder {
    fn record_header_file_dependency(&self, filename: &str) {
        let mut already = self.printed_already.lock().unwrap();
        if already.insert(filename.into()) {
            println!("cargo:rerun-if-changed={}", filename);
        }
    }
}
<|endoftext|>


<commit_before>#![feature(plugin, custom_attribute)]
#![plugin(gfx_macros)]

extern crate piston;
extern crate shader_version;
extern crate vecmath;
extern crate cam;
extern crate gfx;
extern crate sdl2;
extern crate sdl2_window;

use std::cell::RefCell;
use std::mem::transmute;
use piston::quack::Set;
use piston::window::{ WindowSettings, CaptureCursor };
use piston::event::RenderEvent;
use shader_version::OpenGL;
use cam::{
    FirstPersonSettings,
    FirstPerson,
    CameraPerspective,
    model_view_projection
};
use gfx::{ Device, DeviceExt, ToSlice };
use sdl2::video::gl_get_proc_address;
use sdl2_window::Sdl2Window;

//----------------------------------------
// Cube associated data

#[vertex_format]
#[derive(Copy)]
struct Vertex {
    #[as_float]
    a_pos: [i8; 3],
    #[as_float]
    a_tex_coord: [u8; 2],
}

impl Vertex {
    fn new(pos: [i8; 3], tc: [u8; 2]) -> Vertex {
        Vertex {
            a_pos: pos,
            a_tex_coord: tc,
        }
    }
}

#[shader_param]
struct Params {
    u_model_view_proj: [[f32; 4]; 4],
    t_color: gfx::shade::TextureParam,
}

const VERTEX_SRC: [&'static [u8]; 2] = [ b"
    #version 120
    attribute vec3 a_pos;
    attribute vec2 a_tex_coord;
    varying vec2 v_TexCoord;
    uniform mat4 u_model_view_proj;
    void main() {
        v_TexCoord = a_tex_coord;
        gl_Position = u_model_view_proj * vec4(a_pos, 1.0);
    }
", b"
    #version 150 core
    in vec3 a_pos;
    in vec2 a_tex_coord;
    out vec2 v_TexCoord;
    uniform mat4 u_model_view_proj;
    void main() {
        v_TexCoord = a_tex_coord;
        gl_Position = u_model_view_proj * vec4(a_pos, 1.0);
    }
"];

const FRAGMENT_SRC: [&'static [u8]; 2] = [ b"
    #version 120
    varying vec2 v_TexCoord;
    uniform sampler2D t_color;
    void main() {
        vec4 tex = texture2D(t_color, v_TexCoord);
        float blend = dot(v_TexCoord-vec2(0.5,0.5), v_TexCoord-vec2(0.5,0.5));
        gl_FragColor = mix(tex, vec4(0.0,0.0,0.0,0.0), blend*1.0);
    }
", b"
    #version 150 core
    in vec2 v_TexCoord;
    out vec4 o_Color;
    uniform sampler2D t_color;
    void main() {
        vec4 tex = texture(t_color, v_TexCoord);
        float blend = dot(v_TexCoord-vec2(0.5,0.5), v_TexCoord-vec2(0.5,0.5));
        o_Color = mix(tex, vec4(0.0,0.0,0.0,0.0), blend*1.0);
    }
"];

//----------------------------------------

fn main() {
    let (win_width, win_height) = (640, 480);
    let mut window = Sdl2Window::new(
        OpenGL::_3_2,
        WindowSettings {
            title: "cube".to_string(),
            size: [win_width, win_height],
            fullscreen: false,
            exit_on_esc: true,
            samples: 4,
        }
    );

    window.set_mut(CaptureCursor(true));

    let vertex = gfx::ShaderSource {
        glsl_120: Some(VERTEX_SRC[0]),
        glsl_150: Some(VERTEX_SRC[1]),
        .. gfx::ShaderSource::empty()
    };
    let fragment = gfx::ShaderSource {
        glsl_120: Some(FRAGMENT_SRC[0]),
        glsl_150: Some(FRAGMENT_SRC[1]),
        .. gfx::ShaderSource::empty()
    };

    let mut device = gfx::GlDevice::new(|s| unsafe {
        transmute(gl_get_proc_address(s))
    });
    let frame = gfx::Frame::new(win_width as u16, win_height as u16);
    let state = gfx::DrawState::new().depth(gfx::state::Comparison::LessEqual, true);

    let vertex_data = vec![
        //top (0, 0, 1)
        Vertex::new([-1, -1,  1], [0, 0]),
        Vertex::new([ 1, -1,  1], [1, 0]),
        Vertex::new([ 1,  1,  1], [1, 1]),
        Vertex::new([-1,  1,  1], [0, 1]),
        //bottom (0, 0, -1)
        Vertex::new([ 1,  1, -1], [0, 0]),
        Vertex::new([-1,  1, -1], [1, 0]),
        Vertex::new([-1, -1, -1], [1, 1]),
        Vertex::new([ 1, -1, -1], [0, 1]),
        //right (1, 0, 0)
        Vertex::new([ 1, -1, -1], [0, 0]),
        Vertex::new([ 1,  1, -1], [1, 0]),
        Vertex::new([ 1,  1,  1], [1, 1]),
        Vertex::new([ 1, -1,  1], [0, 1]),
        //left (-1, 0, 0)
        Vertex::new([-1,  1,  1], [0, 0]),
        Vertex::new([-1, -1,  1], [1, 0]),
        Vertex::new([-1, -1, -1], [1, 1]),
        Vertex::new([-1,  1, -1], [0, 1]),
        //front (0, 1, 0)
        Vertex::new([-1,  1, -1], [0, 0]),
        Vertex::new([ 1,  1, -1], [1, 0]),
        Vertex::new([ 1,  1,  1], [1, 1]),
        Vertex::new([-1,  1,  1], [0, 1]),
        //back (0, -1, 0)
        Vertex::new([ 1, -1,  1], [0, 0]),
        Vertex::new([-1, -1,  1], [1, 0]),
        Vertex::new([-1, -1, -1], [1, 1]),
        Vertex::new([ 1, -1, -1], [0, 1]),
    ];

    let mesh = device.create_mesh(&vertex_data);

    let index_data: &[u8] = &[
         0,  1,  2,  2,  3,  0, // top
         4,  6,  5,  6,  4,  7, // bottom
         8,  9, 10, 10, 11,  8, // right
        12, 14, 13, 14, 12, 16, // left
        16, 18, 17, 18, 16, 19, // front
        20, 21, 22, 22, 23, 20, // back
    ];

    let slice = device.create_buffer_static::<u8>(index_data)
                      .to_slice(gfx::PrimitiveType::TriangleList);

    let tinfo = gfx::tex::TextureInfo {
        width: 1,
        height: 1,
        depth: 1,
        levels: 1,
        kind: gfx::tex::TextureKind::Texture2D,
        format: gfx::tex::RGBA8,
    };
    let img_info = tinfo.to_image_info();
    let texture = device.create_texture(tinfo).unwrap();
    device.update_texture(
        &texture,
        &img_info,
        &[0x20u8, 0xA0u8, 0xC0u8, 0x00u8]
    ).unwrap();

    let sampler = device.create_sampler(
        gfx::tex::SamplerInfo::new(
            gfx::tex::FilterMethod::Bilinear,
            gfx::tex::WrapMode::Clamp
        )
    );

    let shader_model = device.get_capabilities().shader_model;

    let program = device.link_program(
        vertex.choose(shader_model).unwrap(),
        fragment.choose(shader_model).unwrap()
    ).unwrap();

    let mut graphics = gfx::Graphics::new(device);
    let batch: gfx::batch::RefBatch<Params, gfx::GlResources> =
        graphics.make_batch(&program, &mesh, slice, &state).unwrap();

    let mut data = Params {
        u_model_view_proj: vecmath::mat4_id(),
        t_color: (texture, Some(sampler)),
    };

    let model = vecmath::mat4_id();
    let projection = CameraPerspective {
        fov: 90.0f32,
        near_clip: 0.1,
        far_clip: 1000.0,
        aspect_ratio: (win_width as f32) / (win_height as f32)
    }.projection();
    let mut first_person = FirstPerson::new(
        [0.5f32, 0.5, 4.0],
        FirstPersonSettings::keyboard_wasd()
    );

    let window = RefCell::new(window);
    for e in piston::events(&window) {
        first_person.event(&e);
        if let Some(args) = e.render_args() {
            graphics.clear(
                gfx::ClearData {
                    color: [0.3, 0.3, 0.3, 1.0],
                    depth: 1.0,
                    stencil: 0,
                },
                gfx::COLOR | gfx::DEPTH,
                &frame
            );
            data.u_model_view_proj = model_view_projection(
                model,
                first_person.camera(args.ext_dt).orthogonal(),
                projection
            );
            graphics.draw(&batch, &data, &frame).unwrap();
            graphics.end_frame();
        }
    }
}
<commit_msg>Update gfx_cube example to latest gfx<commit_after>#![feature(plugin, custom_attribute)]
#![plugin(gfx_macros)]

extern crate piston;
extern crate shader_version;
extern crate vecmath;
extern crate cam;
extern crate gfx;
extern crate sdl2;
extern crate sdl2_window;

use std::cell::RefCell;
use std::mem::transmute;
use piston::quack::Set;
use piston::window::{ WindowSettings, CaptureCursor };
use piston::event::RenderEvent;
use shader_version::OpenGL;
use cam::{
    FirstPersonSettings,
    FirstPerson,
    CameraPerspective,
    model_view_projection
};
use gfx::{ Device, DeviceExt, ToSlice };
use sdl2::video::gl_get_proc_address;
use sdl2_window::Sdl2Window;

//----------------------------------------
// Cube associated data

#[vertex_format]
#[derive(Copy)]
struct Vertex {
    #[as_float]
    a_pos: [i8; 3],
    #[as_float]
    a_tex_coord: [u8; 2],
}

impl Vertex {
    fn new(pos: [i8; 3], tc: [u8; 2]) -> Vertex {
        Vertex {
            a_pos: pos,
            a_tex_coord: tc,
        }
    }
}

#[shader_param]
struct Params {
    u_model_view_proj: [[f32; 4]; 4],
    t_color: gfx::shade::TextureParam<gfx::GlResources>,
}

const VERTEX_SRC: [&'static [u8]; 2] = [ b"
    #version 120
    attribute vec3 a_pos;
    attribute vec2 a_tex_coord;
    varying vec2 v_TexCoord;
    uniform mat4 u_model_view_proj;
    void main() {
        v_TexCoord = a_tex_coord;
        gl_Position = u_model_view_proj * vec4(a_pos, 1.0);
    }
", b"
    #version 150 core
    in vec3 a_pos;
    in vec2 a_tex_coord;
    out vec2 v_TexCoord;
    uniform mat4 u_model_view_proj;
    void main() {
        v_TexCoord = a_tex_coord;
        gl_Position = u_model_view_proj * vec4(a_pos, 1.0);
    }
"];

const FRAGMENT_SRC: [&'static [u8]; 2] = [ b"
    #version 120
    varying vec2 v_TexCoord;
    uniform sampler2D t_color;
    void main() {
        vec4 tex = texture2D(t_color, v_TexCoord);
        float blend = dot(v_TexCoord-vec2(0.5,0.5), v_TexCoord-vec2(0.5,0.5));
        gl_FragColor = mix(tex, vec4(0.0,0.0,0.0,0.0), blend*1.0);
    }
", b"
    #version 150 core
    in vec2 v_TexCoord;
    out vec4 o_Color;
    uniform sampler2D t_color;
    void main() {
        vec4 tex = texture(t_color, v_TexCoord);
        float blend = dot(v_TexCoord-vec2(0.5,0.5), v_TexCoord-vec2(0.5,0.5));
        o_Color = mix(tex, vec4(0.0,0.0,0.0,0.0), blend*1.0);
    }
"];

//----------------------------------------

fn main() {
    let (win_width, win_height) = (640, 480);
    let mut window = Sdl2Window::new(
        OpenGL::_3_2,
        WindowSettings {
            title: "cube".to_string(),
            size: [win_width, win_height],
            fullscreen: false,
            exit_on_esc: true,
            samples: 4,
        }
    );

    window.set_mut(CaptureCursor(true));

    let vertex = gfx::ShaderSource {
        glsl_120: Some(VERTEX_SRC[0]),
        glsl_150: Some(VERTEX_SRC[1]),
        .. gfx::ShaderSource::empty()
    };
    let fragment = gfx::ShaderSource {
        glsl_120: Some(FRAGMENT_SRC[0]),
        glsl_150: Some(FRAGMENT_SRC[1]),
        .. gfx::ShaderSource::empty()
    };

    let mut device = gfx::GlDevice::new(|s| unsafe {
        transmute(gl_get_proc_address(s))
    });
    let frame = gfx::Frame::new(win_width as u16, win_height as u16);
    let state = gfx::DrawState::new().depth(gfx::state::Comparison::LessEqual, true);

    let vertex_data = vec![
        //top (0, 0, 1)
        Vertex::new([-1, -1,  1], [0, 0]),
        Vertex::new([ 1, -1,  1], [1, 0]),
        Vertex::new([ 1,  1,  1], [1, 1]),
        Vertex::new([-1,  1,  1], [0, 1]),
        //bottom (0, 0, -1)
        Vertex::new([ 1,  1, -1], [0, 0]),
        Vertex::new([-1,  1, -1], [1, 0]),
        Vertex::new([-1, -1, -1], [1, 1]),
        Vertex::new([ 1, -1, -1], [0, 1]),
        //right (1, 0, 0)
        Vertex::new([ 1, -1, -1], [0, 0]),
        Vertex::new([ 1,  1, -1], [1, 0]),
        Vertex::new([ 1,  1,  1], [1, 1]),
        Vertex::new([ 1, -1,  1], [0, 1]),
        //left (-1, 0, 0)
        Vertex::new([-1,  1,  1], [0, 0]),
        Vertex::new([-1, -1,  1], [1, 0]),
        Vertex::new([-1, -1, -1], [1, 1]),
        Vertex::new([-1,  1, -1], [0, 1]),
        //front (0, 1, 0)
        Vertex::new([-1,  1, -1], [0, 0]),
        Vertex::new([ 1,  1, -1], [1, 0]),
        Vertex::new([ 1,  1,  1], [1, 1]),
        Vertex::new([-1,  1,  1], [0, 1]),
        //back (0, -1, 0)
        Vertex::new([ 1, -1,  1], [0, 0]),
        Vertex::new([-1, -1,  1], [1, 0]),
        Vertex::new([-1, -1, -1], [1, 1]),
        Vertex::new([ 1, -1, -1], [0, 1]),
    ];

    let mesh = device.create_mesh(&vertex_data);

    let index_data: &[u8] = &[
         0,  1,  2,  2,  3,  0, // top
         4,  6,  5,  6,  4,  7, // bottom
         8,  9, 10, 10, 11,  8, // right
        12, 14, 13, 14, 12, 16, // left
        16, 18, 17, 18, 16, 19, // front
        20, 21, 22, 22, 23, 20, // back
    ];

    let slice = device.create_buffer_static::<u8>(index_data)
                      .to_slice(gfx::PrimitiveType::TriangleList);

    let tinfo = gfx::tex::TextureInfo {
        width: 1,
        height: 1,
        depth: 1,
        levels: 1,
        kind: gfx::tex::TextureKind::Texture2D,
        format: gfx::tex::RGBA8,
    };
    let img_info = tinfo.to_image_info();
    let texture = device.create_texture(tinfo).unwrap();
    device.update_texture(
        &texture,
        &img_info,
        &[0x20u8, 0xA0u8, 0xC0u8, 0x00u8]
    ).unwrap();

    let sampler = device.create_sampler(
        gfx::tex::SamplerInfo::new(
            gfx::tex::FilterMethod::Bilinear,
            gfx::tex::WrapMode::Clamp
        )
    );

    let shader_model = device.get_capabilities().shader_model;

    let program = device.link_program(
        vertex.choose(shader_model).unwrap(),
        fragment.choose(shader_model).unwrap()
    ).unwrap();

    let mut graphics = gfx::Graphics::new(device);
    let batch: gfx::batch::RefBatch<Params> =
        graphics.make_batch(&program, &mesh, slice, &state).unwrap();

    let mut data = Params {
        u_model_view_proj: vecmath::mat4_id(),
        t_color: (texture, Some(sampler)),
    };

    let model = vecmath::mat4_id();
    let projection = CameraPerspective {
        fov: 90.0f32,
        near_clip: 0.1,
        far_clip: 1000.0,
        aspect_ratio: (win_width as f32) / (win_height as f32)
    }.projection();
    let mut first_person = FirstPerson::new(
        [0.5f32, 0.5, 4.0],
        FirstPersonSettings::keyboard_wasd()
    );

    let window = RefCell::new(window);
    for e in piston::events(&window) {
        first_person.event(&e);
        if let Some(args) = e.render_args() {
            graphics.clear(
                gfx::ClearData {
                    color: [0.3, 0.3, 0.3, 1.0],
                    depth: 1.0,
                    stencil: 0,
                },
                gfx::COLOR | gfx::DEPTH,
                &frame
            );
            data.u_model_view_proj = model_view_projection(
                model,
                first_person.camera(args.ext_dt).orthogonal(),
                projection
            );
            graphics.draw(&batch, &data, &frame).unwrap();
            graphics.end_frame();
        }
    }
}
<|endoftext|>