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

#![feature(test)]
#![allow(dead_code)]

extern crate test;
extern crate tempdir;
#[macro_use]
extern crate exonum;

#[cfg(test)]
mod tests {
    use tempdir::TempDir;

    use test::Bencher;
    use std::collections::BTreeMap;

    use exonum::storage::{ProofMapIndex, Database, Fork, LevelDB, LevelDBOptions, LevelDBCache,
                          StorageValue, Patch, RocksDB, RocksDBOptions, RocksBlockOptions};

    use std::collections::BTreeMap;
    use exonum::blockchain::{Blockchain, Transaction};
    use exonum::crypto::{gen_keypair, Hash, PublicKey, SecretKey};
    use exonum::messages::Message;
    use exonum::helpers::{Height, ValidatorId};

    fn execute_timestamping(db: Box<Database>, b: &mut Bencher) {
        let mut blockchain = Blockchain::new(db, Vec::new());

        message! {
            struct Tx {
                const TYPE = 1;
                const ID = 0;
                const SIZE = 64;

                field from: &PublicKey [00 => 32]
                field data: &Hash      [32 => 64]
            }
        }

        impl Transaction for Tx {
            fn verify(&self) -> bool {
                self.verify_signature(self.from())
            }

            fn execute(&self, _: &mut Fork) {}
        }

        fn prepare_txs(height: u64, count: u64) -> (Vec<Hash>, BTreeMap<Hash, Box<Transaction>>) {
            let (pub_key, sec_key) = gen_keypair();
            let mut txs = Vec::new();
            let mut pool = BTreeMap::new();
            for i in (height * count)..((height + 1) * count) {
                let tx = Tx::new(&pub_key, &i.hash(), &sec_key);
                let tx_hash = Transaction::hash(&tx);
                txs.push(tx_hash);
                pool.insert(tx_hash, Box::new(tx) as Box<Transaction>);
            }
            (txs, pool)
        }

        fn execute_block(
            blockchain: &Blockchain,
            height: u64,
            txs: &[Hash],
            pool: &BTreeMap<Hash, Box<Transaction>>,
        ) -> Patch {
            blockchain
                .create_patch(ValidatorId::zero(), Height(height), txs, pool)
                .1
        }

        for i in 0..100 {
            let (txs, pool) = prepare_txs(i, 1000);
            let patch = execute_block(&blockchain, i, &txs, &pool);
            blockchain.merge(patch).unwrap();
        }

        let (txs, pool) = prepare_txs(100, 1000);

        b.iter(|| execute_block(&blockchain, 100, &txs, &pool));
    }

    fn execute_cryptocurrency(db: Box<Database>, b: &mut Bencher) {
        let mut blockchain = Blockchain::new(db, Vec::new());

        message! {
            struct Tx {
                const TYPE = 1;
                const ID = 0;
                const SIZE = 64;

                field from: &PublicKey [00 => 32]
                field to:   &PublicKey [32 => 64]
            }
        }

        impl Transaction for Tx {
            fn verify(&self) -> bool {
                self.verify_signature(self.from())
            }

            fn execute(&self, view: &mut Fork) {
                let mut index = ProofMapIndex::new(vec![1], view);
                let from_balance = index.get(self.from()).unwrap_or(0u64);
                let to_balance = index.get(self.to()).unwrap_or(0u64);
                index.put(self.from(), from_balance - 1);
                index.put(self.to(), to_balance + 1);
            }
        }

        let mut keys = Vec::new();

        for _ in 0..10_000 {
            keys.push(gen_keypair());
        }

        fn prepare_txs(
            height: u64,
            count: u64,
            keys: &[(PublicKey, SecretKey)],
        ) -> (Vec<Hash>, BTreeMap<Hash, Box<Transaction>>) {
            let mut txs = Vec::new();
            let mut pool = BTreeMap::new();
            for i in (height * count)..((height + 1) * count) {
                let tx = Tx::new(
                    &keys[i as usize % 10_000].0,
                    &keys[(i as usize + 3_456) % 10_000].0,
                    &keys[i as usize % 10_000].1,
                );
                let tx_hash = Transaction::hash(&tx);
                txs.push(tx_hash);
                pool.insert(tx_hash, Box::new(tx) as Box<Transaction>);
            }
            (txs, pool)
        }

        fn execute_block(
            blockchain: &Blockchain,
            height: u64,
            txs: &[Hash],
            pool: &BTreeMap<Hash, Box<Transaction>>,
        ) -> Patch {
            blockchain
                .create_patch(ValidatorId::zero(), Height(height), txs, pool)
                .1
        }

        for i in 0..100 {
            let (txs, pool) = prepare_txs(i, 1000, &keys);
            let patch = execute_block(&blockchain, i, &txs, &pool);
            blockchain.merge(patch).unwrap();
        }

        let (txs, pool) = prepare_txs(100, 1000, &keys);

        b.iter(|| execute_block(&blockchain, 100, &txs, &pool));
    }

    fn create_rocksdb(tempdir: &TempDir) -> Box<Database> {
        let mut block_options = RocksBlockOptions::default();
        block_options.set_block_size(4 * 1024);
        block_options.set_lru_cache(512 * 1024 * 1024);
        block_options.set_bloom_filter(128, true);
        block_options.set_cache_index_and_filter_blocks(true);
        let mut options = RocksDBOptions::default();
        options.create_if_missing(true);
        options.increase_parallelism(4);
        options.set_max_write_buffer_number(16);
        options.set_write_buffer_size(536870912);
        options.set_max_open_files(-1);
        options.set_block_based_table_factory(&block_options);
        options.set_max_bytes_for_level_base(512 * 1024 * 1024);
        let db = Box::new(RocksDB::open(tempdir.path(), options).unwrap());
        db as Box<Database>
    }

    #[bench]
    fn bench_execute_block_timestamping_leveldb(b: &mut Bencher) {
        let mut options = LevelDBOptions::new();
        options.create_if_missing = true;
        let path = TempDir::new("exonum").unwrap();
        let db = Box::new(LevelDB::open(path.path(), options).unwrap()) as Box<Database>;
        execute_timestamping(db, b)
    }

    #[bench]
    fn bench_execute_block_timestamping_leveldb_cache(b: &mut Bencher) {
        let mut options = LevelDBOptions::new();
        options.create_if_missing = true;
        options.cache = Some(LevelDBCache::new(100_000_000));
        let path = TempDir::new("exonum").unwrap();
        let db = Box::new(LevelDB::open(path.path(), options).unwrap()) as Box<Database>;
        execute_timestamping(db, b)
    }

    #[bench]
    fn bench_execute_block_cryptocurrency_leveldb(b: &mut Bencher) {
        let mut options = LevelDBOptions::new();
        options.create_if_missing = true;
        let path = TempDir::new("exonum").unwrap();
        let db = Box::new(LevelDB::open(path.path(), options).unwrap()) as Box<Database>;
        execute_cryptocurrency(db, b)
    }

    #[bench]
    fn bench_execute_block_cryptocurrency_leveldb_cache(b: &mut Bencher) {
        let mut options = LevelDBOptions::new();
        options.create_if_missing = true;
        options.cache = Some(LevelDBCache::new(100_000_000));
        let path = TempDir::new("exonum").unwrap();
        let db = Box::new(LevelDB::open(path.path(), options).unwrap()) as Box<Database>;
        execute_cryptocurrency(db, b)
    }

    #[bench]
    fn bench_execute_block_timestamping_rocksdb(b: &mut Bencher) {
        let tempdir = TempDir::new("exonum").unwrap();
        let db = create_rocksdb(&tempdir);
        execute_timestamping(db, b)
    }

    #[bench]
    fn bench_execute_block_cryptocurrency_rocksdb(b: &mut Bencher) {
        let tempdir = TempDir::new("exonum").unwrap();
        let db = create_rocksdb(&tempdir);
        execute_cryptocurrency(db, b)
    }
}
<commit_msg>Made changes for clippy<commit_after>// Copyright 2017 The Exonum Team
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#![feature(test)]
#![allow(dead_code)]

extern crate test;
extern crate tempdir;
#[macro_use]
extern crate exonum;

#[cfg(test)]
mod tests {
    use tempdir::TempDir;

    use test::Bencher;
    use std::collections::BTreeMap;

    use exonum::storage::{ProofMapIndex, Database, Fork, LevelDB, LevelDBOptions, LevelDBCache,
                          StorageValue, Patch, RocksDB, RocksDBOptions, RocksBlockOptions};

    use std::collections::BTreeMap;
    use exonum::blockchain::{Blockchain, Transaction};
    use exonum::crypto::{gen_keypair, Hash, PublicKey, SecretKey};
    use exonum::messages::Message;
    use exonum::helpers::{Height, ValidatorId};

    fn execute_timestamping(db: Box<Database>, b: &mut Bencher) {
        let mut blockchain = Blockchain::new(db, Vec::new());

        message! {
            struct Tx {
                const TYPE = 1;
                const ID = 0;
                const SIZE = 64;

                field from: &PublicKey [00 => 32]
                field data: &Hash      [32 => 64]
            }
        }

        impl Transaction for Tx {
            fn verify(&self) -> bool {
                self.verify_signature(self.from())
            }

            fn execute(&self, _: &mut Fork) {}
        }

        fn prepare_txs(height: u64, count: u64) -> (Vec<Hash>, BTreeMap<Hash, Box<Transaction>>) {
            let (pub_key, sec_key) = gen_keypair();
            let mut txs = Vec::new();
            let mut pool = BTreeMap::new();
            for i in (height * count)..((height + 1) * count) {
                let tx = Tx::new(&pub_key, &i.hash(), &sec_key);
                let tx_hash = Transaction::hash(&tx);
                txs.push(tx_hash);
                pool.insert(tx_hash, Box::new(tx) as Box<Transaction>);
            }
            (txs, pool)
        }

        fn execute_block(
            blockchain: &Blockchain,
            height: u64,
            txs: &[Hash],
            pool: &BTreeMap<Hash, Box<Transaction>>,
        ) -> Patch {
            blockchain
                .create_patch(ValidatorId::zero(), Height(height), txs, pool)
                .1
        }

        for i in 0..100 {
            let (txs, pool) = prepare_txs(i, 1000);
            let patch = execute_block(&blockchain, i, &txs, &pool);
            blockchain.merge(patch).unwrap();
        }

        let (txs, pool) = prepare_txs(100, 1000);

        b.iter(|| execute_block(&blockchain, 100, &txs, &pool));
    }

    fn execute_cryptocurrency(db: Box<Database>, b: &mut Bencher) {
        let mut blockchain = Blockchain::new(db, Vec::new());

        message! {
            struct Tx {
                const TYPE = 1;
                const ID = 0;
                const SIZE = 64;

                field from: &PublicKey [00 => 32]
                field to:   &PublicKey [32 => 64]
            }
        }

        impl Transaction for Tx {
            fn verify(&self) -> bool {
                self.verify_signature(self.from())
            }

            fn execute(&self, view: &mut Fork) {
                let mut index = ProofMapIndex::new(vec![1], view);
                let from_balance = index.get(self.from()).unwrap_or(0u64);
                let to_balance = index.get(self.to()).unwrap_or(0u64);
                index.put(self.from(), from_balance - 1);
                index.put(self.to(), to_balance + 1);
            }
        }

        let mut keys = Vec::new();

        for _ in 0..10_000 {
            keys.push(gen_keypair());
        }

        fn prepare_txs(
            height: u64,
            count: u64,
            keys: &[(PublicKey, SecretKey)],
        ) -> (Vec<Hash>, BTreeMap<Hash, Box<Transaction>>) {
            let mut txs = Vec::new();
            let mut pool = BTreeMap::new();
            for i in (height * count)..((height + 1) * count) {
                let tx = Tx::new(
                    &keys[i as usize % 10_000].0,
                    &keys[(i as usize + 3_456) % 10_000].0,
                    &keys[i as usize % 10_000].1,
                );
                let tx_hash = Transaction::hash(&tx);
                txs.push(tx_hash);
                pool.insert(tx_hash, Box::new(tx) as Box<Transaction>);
            }
            (txs, pool)
        }

        fn execute_block(
            blockchain: &Blockchain,
            height: u64,
            txs: &[Hash],
            pool: &BTreeMap<Hash, Box<Transaction>>,
        ) -> Patch {
            blockchain
                .create_patch(ValidatorId::zero(), Height(height), txs, pool)
                .1
        }

        for i in 0..100 {
            let (txs, pool) = prepare_txs(i, 1000, &keys);
            let patch = execute_block(&blockchain, i, &txs, &pool);
            blockchain.merge(patch).unwrap();
        }

        let (txs, pool) = prepare_txs(100, 1000, &keys);

        b.iter(|| execute_block(&blockchain, 100, &txs, &pool));
    }

    fn create_rocksdb(tempdir: &TempDir) -> Box<Database> {
        let mut block_options = RocksBlockOptions::default();
        block_options.set_block_size(4 * 1024);
        block_options.set_lru_cache(512 * 1024 * 1024);
        block_options.set_bloom_filter(128, true);
        block_options.set_cache_index_and_filter_blocks(true);
        let mut options = RocksDBOptions::default();
        options.create_if_missing(true);
        options.increase_parallelism(4);
        options.set_max_write_buffer_number(16);
        options.set_write_buffer_size(536_870_912);
        options.set_max_open_files(-1);
        options.set_block_based_table_factory(&block_options);
        options.set_max_bytes_for_level_base(512 * 1024 * 1024);
        let db = Box::new(RocksDB::open(tempdir.path(), options).unwrap());
        db as Box<Database>
    }

    #[bench]
    fn bench_execute_block_timestamping_leveldb(b: &mut Bencher) {
        let mut options = LevelDBOptions::new();
        options.create_if_missing = true;
        let path = TempDir::new("exonum").unwrap();
        let db = Box::new(LevelDB::open(path.path(), options).unwrap()) as Box<Database>;
        execute_timestamping(db, b)
    }

    #[bench]
    fn bench_execute_block_timestamping_leveldb_cache(b: &mut Bencher) {
        let mut options = LevelDBOptions::new();
        options.create_if_missing = true;
        options.cache = Some(LevelDBCache::new(100_000_000));
        let path = TempDir::new("exonum").unwrap();
        let db = Box::new(LevelDB::open(path.path(), options).unwrap()) as Box<Database>;
        execute_timestamping(db, b)
    }

    #[bench]
    fn bench_execute_block_cryptocurrency_leveldb(b: &mut Bencher) {
        let mut options = LevelDBOptions::new();
        options.create_if_missing = true;
        let path = TempDir::new("exonum").unwrap();
        let db = Box::new(LevelDB::open(path.path(), options).unwrap()) as Box<Database>;
        execute_cryptocurrency(db, b)
    }

    #[bench]
    fn bench_execute_block_cryptocurrency_leveldb_cache(b: &mut Bencher) {
        let mut options = LevelDBOptions::new();
        options.create_if_missing = true;
        options.cache = Some(LevelDBCache::new(100_000_000));
        let path = TempDir::new("exonum").unwrap();
        let db = Box::new(LevelDB::open(path.path(), options).unwrap()) as Box<Database>;
        execute_cryptocurrency(db, b)
    }

    #[bench]
    fn bench_execute_block_timestamping_rocksdb(b: &mut Bencher) {
        let tempdir = TempDir::new("exonum").unwrap();
        let db = create_rocksdb(&tempdir);
        execute_timestamping(db, b)
    }

    #[bench]
    fn bench_execute_block_cryptocurrency_rocksdb(b: &mut Bencher) {
        let tempdir = TempDir::new("exonum").unwrap();
        let db = create_rocksdb(&tempdir);
        execute_cryptocurrency(db, b)
    }
}
<|endoftext|>


<commit_before>// run-pass

#![feature(negative_impls)]
#![allow(dead_code)]

struct TestType;

trait TestTrait {
    fn dummy(&self) {}
}

impl !TestTrait for TestType {}

fn main() {}
<commit_msg>comment the `typeck-negative-impls-builtin` test<commit_after>// A simple test that we are able to create negative impls, when the
// feature gate is given.
//
// run-pass

#![feature(negative_impls)]
#![allow(dead_code)]

struct TestType;

trait TestTrait {
    fn dummy(&self) {}
}

impl !TestTrait for TestType {}

fn main() {}
<|endoftext|>


<commit_before>#![feature(macro_rules)]
#![feature(phase)]

#![unstable]

#[phase(plugin)]
extern crate compile_msg;

extern crate libc;

use std::sync::Mutex;

#[doc(hidden)]
pub mod ffi;

/// This static variable  will store the android_app* on creation, and set it back to 0 at
///  destruction.
/// Apart from this, the static is never written, so there is no risk of race condition.
static mut ANDROID_APP: *mut ffi::android_app = 0 as *mut ffi::android_app;

/// This is the structure that serves as user data in the android_app*
#[doc(hidden)]
struct Context {
    senders: Mutex<Vec<Sender<Event>>>,
}

/// An event triggered by the Android environment.
pub enum Event {
    EventUp,
    EventDown,
    EventMove(i32, i32),
}

#[cfg(not(target_os = "android"))]
compile_note!("You are not compiling for Android")

#[macro_export]
macro_rules! android_start(
    ($main: ident) => (
        pub mod __android_start {
            extern crate android_glue;

            // this function is here because we are sure that it will be included by the linker
            // so we call app_dummy in it, in order to be sure that the native glue will be included
            #[start]
            pub fn start(_: int, _: *const *const u8) -> int {
                unsafe { android_glue::ffi::app_dummy() };
                1
            }

            #[no_mangle]
            #[inline(never)]
            #[allow(non_snake_case)]
            pub extern "C" fn android_main(app: *mut ()) {
                android_glue::android_main2(app, proc() super::$main());
            }
        }
    )
)

/// This is the function that must be called by `android_main`
#[doc(hidden)]
pub fn android_main2(app: *mut (), main_function: proc(): Send) {
    use std::task::TaskBuilder;
    use std::{mem, ptr};

    write_log("Entering android_main");

    unsafe { ANDROID_APP = std::mem::transmute(app) };
    let app: &mut ffi::android_app = unsafe { std::mem::transmute(app) };

    // starting the runtime
    std::rt::start(1, &b"".as_ptr(), proc() {
        // creating the context that will be passed to the callback
        let context = Context { senders: Mutex::new(Vec::new()) };
        app.onAppCmd = commands_callback;
        app.onInputEvent = inputs_callback;
        app.userData = unsafe { std::mem::transmute(&context) };

        // executing the main function in parallel
        spawn(proc() {
            std::io::stdio::set_stdout(box std::io::LineBufferedWriter::new(ToLogWriter));
            std::io::stdio::set_stderr(box std::io::LineBufferedWriter::new(ToLogWriter));
            main_function()
        });

        // polling for events forever
        // note that this must be done in the same thread as android_main because ALooper are
        //  thread-local
        unsafe {
            loop {
                let mut events = mem::uninitialized();
                let mut source = mem::uninitialized();

                // passing -1 means that we are blocking
                let ident = ffi::ALooper_pollAll(-1, ptr::null_mut(), &mut events,
                    &mut source);

                // processing the event
                if !source.is_null() {
                    let source: *mut ffi::android_poll_source = mem::transmute(source);
                    ((*source).process)(ANDROID_APP, source);
                }
            }
        }
    });

    // terminating the application
    unsafe { ANDROID_APP = 0 as *mut ffi::android_app };
}

/// Writer that will redirect what is written to it to the logs.
struct ToLogWriter;

impl Writer for ToLogWriter {
    fn write(&mut self, buf: &[u8]) -> std::io::IoResult<()> {
        buf.with_c_str(|message| {
            b"RustAndroidGlueStdouterr".with_c_str(|tag| {
                unsafe { ffi::__android_log_write(3, tag, message) };
            });
        });
        Ok(())
    }
}

/// The callback for inputs.
pub extern fn inputs_callback(_: *mut ffi::android_app, event: *const ffi::AInputEvent)
    -> libc::int32_t
{
    fn send_event(event: Event) {
        for sender in get_context().senders.lock().iter() {
            sender.send(event);
        }
    }
    let action = unsafe { ffi::AMotionEvent_getAction(event) };
    let action_code = action & ffi::AMOTION_EVENT_ACTION_MASK;
    match action_code {
        ffi::AMOTION_EVENT_ACTION_UP
            | ffi::AMOTION_EVENT_ACTION_OUTSIDE
            | ffi::AMOTION_EVENT_ACTION_CANCEL
            | ffi::AMOTION_EVENT_ACTION_POINTER_UP =>
        {
            send_event(Event::EventUp);
        },
        ffi::AMOTION_EVENT_ACTION_DOWN
            | ffi::AMOTION_EVENT_ACTION_POINTER_DOWN =>
        {
            send_event(Event::EventDown);
        },
        _ => {
            let x = unsafe { ffi::AMotionEvent_getX(event, 0) };
            let y = unsafe { ffi::AMotionEvent_getY(event, 0) };
            send_event(Event::EventMove(x as i32, y as i32));
        },
    }
    0
}

/// The callback for commands.
#[doc(hidden)]
pub extern fn commands_callback(_: *mut ffi::android_app, command: libc::int32_t) {
    let context = get_context();

    match command {
        ffi::APP_CMD_INIT_WINDOW => {

        },

        ffi::APP_CMD_SAVE_STATE => {

        },

        ffi::APP_CMD_TERM_WINDOW => {

        },

        ffi::APP_CMD_GAINED_FOCUS => {

        },

        ffi::APP_CMD_LOST_FOCUS => {

        },

        _ => ()
    }
}

/// Returns the current Context.
fn get_context() -> &'static Context {
    let context = unsafe { (*ANDROID_APP).userData };
    unsafe { std::mem::transmute(context) }
}

/// Adds a sender where events will be sent to.
pub fn add_sender(sender: Sender<Event>) {
    get_context().senders.lock().push(sender);
}

/// Returns a handle to the native window.
pub unsafe fn get_native_window() -> ffi::NativeWindowType {
    if ANDROID_APP.is_null() {
        panic!("The application was not initialized from android_main");
    }

    loop {
        let value = (*ANDROID_APP).window;
        if !value.is_null() {
            return value;
        }

        // spin-locking
        std::io::timer::sleep(std::time::Duration::milliseconds(10));
    }
}

///
pub fn write_log(message: &str) {
    message.with_c_str(|message| {
        b"RustAndroidGlue".with_c_str(|tag| {
            unsafe { ffi::__android_log_write(3, tag, message) };
        });
    });
}
<commit_msg>Remove rt startup since it's been removed from rustc<commit_after>#![feature(macro_rules)]
#![feature(phase)]

#![unstable]

#[phase(plugin)]
extern crate compile_msg;

extern crate libc;

use std::sync::Mutex;

#[doc(hidden)]
pub mod ffi;

/// This static variable  will store the android_app* on creation, and set it back to 0 at
///  destruction.
/// Apart from this, the static is never written, so there is no risk of race condition.
static mut ANDROID_APP: *mut ffi::android_app = 0 as *mut ffi::android_app;

/// This is the structure that serves as user data in the android_app*
#[doc(hidden)]
struct Context {
    senders: Mutex<Vec<Sender<Event>>>,
}

/// An event triggered by the Android environment.
pub enum Event {
    EventUp,
    EventDown,
    EventMove(i32, i32),
}

#[cfg(not(target_os = "android"))]
compile_note!("You are not compiling for Android")

#[macro_export]
macro_rules! android_start(
    ($main: ident) => (
        pub mod __android_start {
            extern crate android_glue;

            // this function is here because we are sure that it will be included by the linker
            // so we call app_dummy in it, in order to be sure that the native glue will be included
            #[start]
            pub fn start(_: int, _: *const *const u8) -> int {
                unsafe { android_glue::ffi::app_dummy() };
                1
            }

            #[no_mangle]
            #[inline(never)]
            #[allow(non_snake_case)]
            pub extern "C" fn android_main(app: *mut ()) {
                android_glue::android_main2(app, proc() super::$main());
            }
        }
    )
)

/// This is the function that must be called by `android_main`
#[doc(hidden)]
pub fn android_main2(app: *mut (), main_function: proc(): Send) {
    use std::task::TaskBuilder;
    use std::{mem, ptr};

    write_log("Entering android_main");

    unsafe { ANDROID_APP = std::mem::transmute(app) };
    let app: &mut ffi::android_app = unsafe { std::mem::transmute(app) };

    // creating the context that will be passed to the callback
    let context = Context { senders: Mutex::new(Vec::new()) };
    app.onAppCmd = commands_callback;
    app.onInputEvent = inputs_callback;
    app.userData = unsafe { std::mem::transmute(&context) };

    // executing the main function in parallel
    spawn(proc() {
        std::io::stdio::set_stdout(box std::io::LineBufferedWriter::new(ToLogWriter));
        std::io::stdio::set_stderr(box std::io::LineBufferedWriter::new(ToLogWriter));
        main_function()
    });

    // polling for events forever
    // note that this must be done in the same thread as android_main because ALooper are
    //  thread-local
    unsafe {
        loop {
            let mut events = mem::uninitialized();
            let mut source = mem::uninitialized();

            // passing -1 means that we are blocking
            let ident = ffi::ALooper_pollAll(-1, ptr::null_mut(), &mut events,
                &mut source);

            // processing the event
            if !source.is_null() {
                let source: *mut ffi::android_poll_source = mem::transmute(source);
                ((*source).process)(ANDROID_APP, source);
            }
        }
    }

    // terminating the application
    unsafe { ANDROID_APP = 0 as *mut ffi::android_app };
}

/// Writer that will redirect what is written to it to the logs.
struct ToLogWriter;

impl Writer for ToLogWriter {
    fn write(&mut self, buf: &[u8]) -> std::io::IoResult<()> {
        buf.with_c_str(|message| {
            b"RustAndroidGlueStdouterr".with_c_str(|tag| {
                unsafe { ffi::__android_log_write(3, tag, message) };
            });
        });
        Ok(())
    }
}

/// The callback for inputs.
pub extern fn inputs_callback(_: *mut ffi::android_app, event: *const ffi::AInputEvent)
    -> libc::int32_t
{
    fn send_event(event: Event) {
        for sender in get_context().senders.lock().iter() {
            sender.send(event);
        }
    }
    let action = unsafe { ffi::AMotionEvent_getAction(event) };
    let action_code = action & ffi::AMOTION_EVENT_ACTION_MASK;
    match action_code {
        ffi::AMOTION_EVENT_ACTION_UP
            | ffi::AMOTION_EVENT_ACTION_OUTSIDE
            | ffi::AMOTION_EVENT_ACTION_CANCEL
            | ffi::AMOTION_EVENT_ACTION_POINTER_UP =>
        {
            send_event(Event::EventUp);
        },
        ffi::AMOTION_EVENT_ACTION_DOWN
            | ffi::AMOTION_EVENT_ACTION_POINTER_DOWN =>
        {
            send_event(Event::EventDown);
        },
        _ => {
            let x = unsafe { ffi::AMotionEvent_getX(event, 0) };
            let y = unsafe { ffi::AMotionEvent_getY(event, 0) };
            send_event(Event::EventMove(x as i32, y as i32));
        },
    }
    0
}

/// The callback for commands.
#[doc(hidden)]
pub extern fn commands_callback(_: *mut ffi::android_app, command: libc::int32_t) {
    let context = get_context();

    match command {
        ffi::APP_CMD_INIT_WINDOW => {

        },

        ffi::APP_CMD_SAVE_STATE => {

        },

        ffi::APP_CMD_TERM_WINDOW => {

        },

        ffi::APP_CMD_GAINED_FOCUS => {

        },

        ffi::APP_CMD_LOST_FOCUS => {

        },

        _ => ()
    }
}

/// Returns the current Context.
fn get_context() -> &'static Context {
    let context = unsafe { (*ANDROID_APP).userData };
    unsafe { std::mem::transmute(context) }
}

/// Adds a sender where events will be sent to.
pub fn add_sender(sender: Sender<Event>) {
    get_context().senders.lock().push(sender);
}

/// Returns a handle to the native window.
pub unsafe fn get_native_window() -> ffi::NativeWindowType {
    if ANDROID_APP.is_null() {
        panic!("The application was not initialized from android_main");
    }

    loop {
        let value = (*ANDROID_APP).window;
        if !value.is_null() {
            return value;
        }

        // spin-locking
        std::io::timer::sleep(std::time::Duration::milliseconds(10));
    }
}

///
pub fn write_log(message: &str) {
    message.with_c_str(|message| {
        b"RustAndroidGlue".with_c_str(|tag| {
            unsafe { ffi::__android_log_write(3, tag, message) };
        });
    });
}
<|endoftext|>


<commit_before>//
// gash.rs
//
// Starting code for PS2
// Running on Rust 0.9
//
// University of Virginia - cs4414 Spring 2014
// Weilin Xu, David Evans
// Version 0.4
//

extern mod extra;

use std::{io, run, os};
use std::io::buffered::BufferedReader;
use std::io::stdin;
use extra::getopts;

struct Shell {
    cmd_prompt: ~str,
    cmd_history: ~[~str]
}

impl Shell {
    fn new(prompt_str: &str) -> Shell {
        Shell {
            cmd_prompt: prompt_str.to_owned(),
	    cmd_history: ~[]
        }
    }

    fn run(&mut self) {
        let mut stdin = BufferedReader::new(stdin());

        loop {
            print(self.cmd_prompt);
            io::stdio::flush();

            let line = stdin.read_line().unwrap();
            let cmd_line = line.trim().to_owned();
	    self.cmd_history.push(cmd_line.clone());
            let program = cmd_line.splitn(' ', 1).nth(0).expect("no program");

            match program {
                ""      =>  { continue; }
                "exit"  =>  { return; }
                _       =>  { self.run_cmdline(cmd_line); }
            }
        }
    }

    fn run_cmdline(&mut self, cmd_line: &str) {
        let mut argv: ~[~str] =
            cmd_line.split(' ').filter_map(|x| if x != "" { Some(x.to_owned()) } else { None }).to_owned_vec();

        if argv.len() > 0 {
            let program: ~str = argv.remove(0);
            self.run_cmd(program, argv);
        }
    }

    fn run_cmd(&mut self, program: &str, argv: &[~str]) {
        if self.cmd_exists(program) {
	    if program == "cd" {
	       if argv.len() != 1 {
	       	  println!("Usage: cd <directory>!");
	       }
	       else {
	       	  let tar_path = Path::new(argv[0].clone());
		  match os::change_dir(&tar_path) {
		  	true => { return; }
			false => { println!("No such directory!"); }
		  }
	       }
	    }
	    else {
              run::process_status(program, argv);
            }
        }
	else if program == "history" {
	     for i in range(0, self.cmd_history.len()) {
	     	 println!("{:u} {:s}", i+1, self.cmd_history[i]);
	     }
	}
	else {
            println!("{:s}: command not found", program);
        }
    }

    fn cmd_exists(&mut self, cmd_path: &str) -> bool {
        let ret = run::process_output("which", [cmd_path.to_owned()]);
        return ret.expect("exit code error.").status.success();
    }
}

fn get_cmdline_from_args() -> Option<~str> {
    /* Begin processing program arguments and initiate the parameters. */
    let args = os::args();

    let opts = ~[
        getopts::optopt("c")
    ];

    let matches = match getopts::getopts(args.tail(), opts) {
        Ok(m) => { m }
        Err(f) => { fail!(f.to_err_msg()) }
    };

    if matches.opt_present("c") {
        let cmd_str = match matches.opt_str("c") {
                                                Some(cmd_str) => {cmd_str.to_owned()},
                                                None => {~""}
                                              };
        return Some(cmd_str);
    } else {
        return None;
    }
}

fn main() {
    let opt_cmd_line = get_cmdline_from_args();

    match opt_cmd_line {
        Some(cmd_line) => Shell::new("").run_cmdline(cmd_line),
        None           => Shell::new("gash > ").run()
    }
}
<commit_msg>& now works!<commit_after>//
// gash.rs
//
// Starting code for PS2
// Running on Rust 0.9
//
// University of Virginia - cs4414 Spring 2014
// Weilin Xu, David Evans
// Version 0.4
//

extern mod extra;

use std::{io, run, os};
use std::io::buffered::BufferedReader;
use std::io::stdin;
use extra::getopts;

struct Shell {
    cmd_prompt: ~str,
    cmd_history: ~[~str]
}

impl Shell {
    fn new(prompt_str: &str) -> Shell {
        Shell {
            cmd_prompt: prompt_str.to_owned(),
	    cmd_history: ~[]
        }
    }

    fn run(&mut self) {
        let mut stdin = BufferedReader::new(stdin());

        loop {
            print(self.cmd_prompt);
            io::stdio::flush();

            let line = stdin.read_line().unwrap();
            let cmd_line = line.trim().to_owned();
	    self.cmd_history.push(cmd_line.clone());
            let program = cmd_line.splitn(' ', 1).nth(0).expect("no program");

	    let mut mod_prog = program.clone();
	    let prog_length = mod_prog.len();
	    if mod_prog.slice_from(prog_length - 1) == "&" {
	       mod_prog = mod_prog.slice_to(prog_length - 1);
	    }

            match mod_prog {
                ""      =>  { continue; }
                "exit"  =>  { return; }
                _       =>  { self.run_cmdline(cmd_line); }
            }
        }
    }

    fn run_cmdline(&mut self, cmd_line: &str) {
        let mut argv: ~[~str] =
            cmd_line.split(' ').filter_map(|x| if x != "" { Some(x.to_owned()) } else { None }).to_owned_vec();
        if argv.len() > 0 {
	   let program: ~str = argv.remove(0);
	   let mut mod_prog = program.clone();
	   let mut background = false;
	   if argv.len() == 0 {
	      let prog_length = mod_prog.len();
	      if mod_prog.slice_from(prog_length - 1) == "&" {
	      	 mod_prog = mod_prog.slice_to(prog_length - 1).trim().to_owned();
	       	 background = true;
	      }
	   }
	   else {
	      let mut last_arg = argv[argv.len() - 1].clone();
	      if last_arg == ~"&" {
	      	 argv.pop();
		 background = true;
	      }
	      else {
	      	   let arg_length = last_arg.len();
	      	   if last_arg.slice_from(arg_length - 1) == "&" {
	      	      last_arg = last_arg.slice_to(arg_length - 1).to_owned();
		      argv.pop();
		      argv.push(last_arg);
		      background = true;
	      	   }
	      }
	   }
	   if background {
	      let prog = mod_prog.clone();
	      let arguments = argv.clone();
	      if self.cmd_exists(prog) {
	      	 do spawn {
		    run::process_status(prog, arguments);
		 }
	      }
	      else {
	      	 println!("{:s}: command not found", program);
	      }
	   }
	   else {
	   	self.run_cmd(program, argv);
	   }
        }
    }

    fn run_cmd(&mut self, program: &str, argv: &[~str]) {
        if self.cmd_exists(program) {
	    if program == "cd" {
	       if argv.len() != 1 {
	       	  println!("Usage: cd <directory>!");
	       }
	       else {
	       	  let tar_path = Path::new(argv[0].clone());
		  match os::change_dir(&tar_path) {
		  	true => { return; }
			false => { println!("No such directory!"); }
		  }
	       }
	    }
	    else {
            	 run::process_status(program, argv);
            }
        }
	else if program == "history" {
	     for i in range(0, self.cmd_history.len()) {
	     	 println!(" {:u} {:s}", i+1, self.cmd_history[i]);
	     }
	}
	else {
            println!("{:s}: command not found", program);
        }
    }

    fn cmd_exists(&mut self, cmd_path: &str) -> bool {
        let ret = run::process_output("which", [cmd_path.to_owned()]);
        return ret.expect("exit code error.").status.success();
    }
}

fn get_cmdline_from_args() -> Option<~str> {
    /* Begin processing program arguments and initiate the parameters. */
    let args = os::args();

    let opts = ~[
        getopts::optopt("c")
    ];

    let matches = match getopts::getopts(args.tail(), opts) {
        Ok(m) => { m }
        Err(f) => { fail!(f.to_err_msg()) }
    };

    if matches.opt_present("c") {
        let cmd_str = match matches.opt_str("c") {
                                                Some(cmd_str) => {cmd_str.to_owned()},
                                                None => {~""}
                                              };
        return Some(cmd_str);
    } else {
        return None;
    }
}

fn main() {
    let opt_cmd_line = get_cmdline_from_args();

    match opt_cmd_line {
        Some(cmd_line) => Shell::new("").run_cmdline(cmd_line),
        None           => Shell::new("gash > ").run()
    }
}
<|endoftext|>


<commit_before>//
// gash.rs
//
// Starting code for PS2
// Running on Rust 0.9
//
// University of Virginia - cs4414 Spring 2014
// Weilin Xu, David Evans
// Version 0.4
//

extern mod extra;

use std::{io, run, os};
use std::io::buffered::BufferedReader;
use std::io::stdin;
use extra::getopts;
use std::io::File;
use std::io::{File, io_error, Open, ReadWrite};

struct Shell {
    cmd_prompt: ~str,
    log:        ~[~str],
}

impl Shell {

    fn new(prompt_str: &str) -> Shell {
        Shell {
            cmd_prompt: prompt_str.to_owned(),
            log: ~[],
        }
    }

    fn run(&mut self) {
        let mut stdin = BufferedReader::new(stdin());

        loop {
            print(self.cmd_prompt); // prints 'gash >'
            io::stdio::flush();

            let line = stdin.read_line().unwrap(); // reads whats on the line
            let cmd_line = line.trim().to_owned();  // removes leading and trailing whitespace
            let user_input: ~[&str] = cmd_line.split(' ').collect();
            let mut index: uint = 0;

            for &string in user_input.iter(){
                let mut prog : ~str;    // saves command
                let mut input : ~str;
                let mut index1 : uint;
                let mut index2 : uint;
                let mut index3 : uint;
                let mut index4 : uint;

                match string {
                    "<" => {
                        let file  = user_input[index+1].to_owned(); // get file name
                        println(file);
                    }
                    ">" => {
			let file = user_input[index + 1].to_owned();
			let command = user_input[index - 1].to_owned();
			let mut write_str = self.find_prog(command, true).to_owned();
			let path = Path::new(file.clone());
			let mut write_fn = File::open_mode(&path, Open, ReadWrite);
			write_fn.write(write_str.as_bytes());

                    }
                    "|" => {

                    }
                    _ => {

                    }
                }
                index += 1;
            }

            let result = self.find_prog(cmd_line,false);
            match result {
                ~"return" => {return}
                ~"continue" => {continue;}
                _          => {continue;}
            }

        }
    }

    fn find_prog(&mut self, cmd_line : &str, output: bool) -> ~str{
         let program = cmd_line.splitn(' ', 1).nth(0).expect("no program"); // get command

         match program {
                ""      =>  { return ~"continue"; }
                "exit"  =>  { return ~"return"; }
                "history" => {
                    self.log.push(cmd_line.to_owned());
                    return self.run_history(output);
                }
                "cd" => {
                    self.log.push(cmd_line.to_owned());
                    self.run_cd(cmd_line);
                }
                _       =>  {
                    self.log.push(cmd_line.to_owned());
                    return self.run_cmdline(cmd_line, output);
                }
            }
        ~"fine"
    }

    fn run_cmdline(&mut self, cmd_line: &str, output: bool) -> ~str {
        let mut argv: ~[~str] =
            cmd_line.split(' ').filter_map(|x| if x != "" { Some(x.to_owned()) } else { None }).to_owned_vec();

	let length = argv.len()-1;

    	if argv[length] == ~"&" {
	    argv.remove(length);
            let program: ~str = argv.remove(0);
	    let argv2 = argv.clone();
	    if self.cmd_exists(program){

		spawn(proc() {run::process_status(program, argv2);});

	    }
            else {
		println!("{:s}: command not found", program);
            }
	return ~"none";
	}
	else{
        if argv.len() > 0 {
            let program: ~str = argv.remove(0);
            return self.run_cmd(program, argv, output);
        }
	}
	return ~"none";
    }

    fn run_cmd(&mut self, program: &str, argv: &[~str], output: bool)->~str {
        if self.cmd_exists(program) {
	    if output == false {
            run::process_status(program, argv);
	    return ~"none";
	    }
	    else {
	    	let output = run::process_output(program, argv);
	  	let output_str = output.unwrap().output;
		return std::str::from_utf8(output_str).to_owned();
	    }
        } else {
            println!("{:s}: command not found", program);
        }
	return ~"none";
    }

    fn cmd_exists(&mut self, cmd_path: &str) -> bool {
        let ret = run::process_output("which", [cmd_path.to_owned()]);
        return ret.expect("exit code error.").status.success();
    }

    fn run_history(&mut self, output: bool)-> ~str{
	if output == false{
        	for i in range(0, self.log.len()) {
            		println!("{}", self.log[i]);
        	}
		return ~"none";
	}
	else {
		let mut out: ~str = ~"";
		for i in range(0, self.log.len()){
			out = out + self.log[i].to_owned();
		}
		return out;
	}
    }

    fn run_cd(&mut self, cmd_line: &str) {
         let mut argv: ~[~str] =
            cmd_line.split(' ').filter_map(|x| if x != "" { Some(x.to_owned()) } else { None }).to_owned_vec();

        if argv.len() > 0 {

            if argv.len() == 1 {
                self.go_to_home_dir();
                return ;
            }

            let string: ~str = argv.remove(1);
            if string == ~"$HOME" || string == ~"$home"{
                self.go_to_home_dir();
                return ;
            }
            let path = ~Path::new(string);
            if (path.exists()){
                let success = std::os::change_dir(path);
                if !success {
                    println("Invalid path");
                }
            }
        }
        else {
            println("Invalid input");
        }
    }

    fn go_to_home_dir(&mut self){
        match std::os::homedir() {
            Some(path) => {
                    std::os::change_dir(~path);
               }
             None => {
                    println("$HOME is not set");
               }
         }
    }

}

fn get_cmdline_from_args() -> Option<~str> {
    /* Begin processing program arguments and initiate the parameters. */
    let args = os::args();

    let opts = ~[
        getopts::optopt("c")
    ];

    let matches = match getopts::getopts(args.tail(), opts) {
        Ok(m) => { m }
        Err(f) => { fail!(f.to_err_msg()) }
    };

    if matches.opt_present("c") {
        let cmd_str = match matches.opt_str("c") {
                                                Some(cmd_str) => {cmd_str.to_owned()},
                                                None => {~""}
                                              };
        return Some(cmd_str);
    } else {
        return None;
    }
}

fn main() {
    let opt_cmd_line = get_cmdline_from_args();

    match opt_cmd_line {
        Some(cmd_line) => {Shell::new("").run_cmdline(cmd_line, false);}
        None           => {Shell::new("gash > ").run();}
    }
}
<commit_msg>Cleaning up pipes<commit_after>//
// gash.rs
//
// Starting code for PS2
// Running on Rust 0.9
//
// University of Virginia - cs4414 Spring 2014
// Weilin Xu, David Evans
// Version 0.4
//

extern mod extra;

use std::{io, run, os};
use std::io::buffered::BufferedReader;
use std::io::stdin;
use extra::getopts;
use std::io::File;

struct Shell {
    cmd_prompt: ~str,
    log:        ~[~str],
}

impl Shell {

    fn new(prompt_str: &str) -> Shell {
        Shell {
            cmd_prompt: prompt_str.to_owned(),
            log: ~[],
        }
    }

    fn run(&mut self) {
        let mut stdin = BufferedReader::new(stdin());

        loop {
            print(self.cmd_prompt); // prints 'gash >'
            io::stdio::flush();

            let line = stdin.read_line().unwrap(); // reads whats on the line
            let cmd_line = line.trim().to_owned();  // removes leading and trailing whitespace
            let user_input: ~[&str] = cmd_line.split(' ').collect();
            let mut index: uint = 0;
            let mut line: ~str = ~"";

            for &string in user_input.iter(){

                match string {

                    "<" => {
                        let file  = user_input[index+1].to_owned(); // get file name
                        let message = read_file(file);
                        println(message);

                        line = ~"";
                    }

                    ">" => {
			            let file = user_input[index + 1].to_owned();
			            let command = line.trim().to_owned();
			            let message = self.find_prog(command, true).to_owned();
                        write_file(file,message);
                        line = ~"";
                        user_input.iter().next();
                    }

                    "|" => {
                        let command = line.trim().to_owned();
                        let message = self.find_prog(command, true).to_owned();
                        println(message);
                        line = ~"";
                    }
                    _ => {
                        line = line + " " + string;
                    }
                }
                index += 1;
            }

            let result = self.find_prog(line.trim(),false);
            match result {
                ~"return" => {return}
                ~"continue" => {continue;}
                _          => {continue;}
            }

        }
    }

    fn find_prog(&mut self, cmd_line : &str, output: bool) -> ~str{
         let program = cmd_line.splitn(' ', 1).nth(0).expect("no program"); // get command

         match program {
                ""      =>  { return ~"continue"; }
                "exit"  =>  { return ~"return"; }
                "history" => {
                    self.log.push(cmd_line.to_owned());
                    return self.run_history(output);
                }
                "cd" => {
                    self.log.push(cmd_line.to_owned());
                    self.run_cd(cmd_line);
                }
                _       =>  {
                    self.log.push(cmd_line.to_owned());
                    return self.run_cmdline(cmd_line, output);
                }
            }
        ~"fine"
    }

    fn run_cmdline(&mut self, cmd_line: &str, output: bool) -> ~str {
        let mut argv: ~[~str] =
            cmd_line.split(' ').filter_map(|x| if x != "" { Some(x.to_owned()) } else { None }).to_owned_vec();

	let length = argv.len()-1;

    	if argv[length] == ~"&" {
	    argv.remove(length);
            let program: ~str = argv.remove(0);
	    let argv2 = argv.clone();
	    if self.cmd_exists(program){

		spawn(proc() {run::process_status(program, argv2);});

	    }
            else {
		println!("{:s}: command not found", program);
            }
	return ~"none";
	}
	else{
        if argv.len() > 0 {
            let program: ~str = argv.remove(0);
            return self.run_cmd(program, argv, output);
        }
	}
	return ~"none";
    }

    fn run_cmd(&mut self, program: &str, argv: &[~str], output: bool)->~str {
        if self.cmd_exists(program) {
	    if output == false {
            run::process_status(program, argv);
	    return ~"none";
	    }
	    else {
	    	let output = run::process_output(program, argv);
	  	let output_str = output.unwrap().output;
		return std::str::from_utf8(output_str).to_owned();
	    }
        } else {
            println!("{:s}: command not found", program);
        }
	return ~"none";
    }

    fn cmd_exists(&mut self, cmd_path: &str) -> bool {
        let ret = run::process_output("which", [cmd_path.to_owned()]);
        return ret.expect("exit code error.").status.success();
    }

    fn run_history(&mut self, output: bool)-> ~str{
	if output == false{
        	for i in range(0, self.log.len()) {
            		println!("{}", self.log[i]);
        	}
		return ~"none";
	}
	else {
		let mut out: ~str = ~"";
		for i in range(0, self.log.len()){
			out = out + self.log[i].to_owned();
		}
		return out;
	}
    }

    fn run_cd(&mut self, cmd_line: &str) {
         let mut argv: ~[~str] =
            cmd_line.split(' ').filter_map(|x| if x != "" { Some(x.to_owned()) } else { None }).to_owned_vec();

        if argv.len() > 0 {

            if argv.len() == 1 {
                self.go_to_home_dir();
                return ;
            }

            let string: ~str = argv.remove(1);
            if string == ~"$HOME" || string == ~"$home"{
                self.go_to_home_dir();
                return ;
            }
            let path = ~Path::new(string);
            if (path.exists()){
                let success = std::os::change_dir(path);
                if !success {
                    println("Invalid path");
                }
            }
        }
        else {
            println("Invalid input");
        }
    }

    fn go_to_home_dir(&mut self){
        match std::os::homedir() {
            Some(path) => {
                    std::os::change_dir(&path);
               }
             None => {
                    println("$HOME is not set");
               }
         }
    }

}

fn write_file(filename: ~str, message: ~str){

    match File::create(&Path::new(filename)) {
        Some(mut file) => {
            file.write_str(message);
        }
        None =>{
            println("Opening file failed!");
        }
    }
}

fn read_file(filename: ~str) -> ~str{

    let path = Path::new(filename);
    match File::open(&path) {
        Some(file) => {
            let mut reader = BufferedReader::new(file);
            let input = reader.read_to_str();
            return input;
        }
        None =>{
            println("Opening file failed");
            return ~"";
        }
    }
}

fn get_cmdline_from_args() -> Option<~str> {
    /* Begin processing program arguments and initiate the parameters. */
    let args = os::args();

    let opts = ~[
        getopts::optopt("c")
    ];

    let matches = match getopts::getopts(args.tail(), opts) {
        Ok(m) => { m }
        Err(f) => { fail!(f.to_err_msg()) }
    };

    if matches.opt_present("c") {
        let cmd_str = match matches.opt_str("c") {
                                                Some(cmd_str) => {cmd_str.to_owned()},
                                                None => {~""}
                                              };
        return Some(cmd_str);
    } else {
        return None;
    }
}

fn main() {
    let opt_cmd_line = get_cmdline_from_args();

    match opt_cmd_line {
        Some(cmd_line) => {Shell::new("").run_cmdline(cmd_line, false);}
        None           => {Shell::new("gash > ").run();}
    }
}
<|endoftext|>


<commit_before>use winapi::*;
use d3d12_safe::*;
use std::marker::PhantomData;
use std::ops::Deref;
use std::mem;

pub fn shader_4component_mapping(a: u32, b: u32, c: u32, d: u32) -> UINT {
  (0x1000 | (a & 7) | ((b & 7)*8) | ((c & 7)*8*8) | ((d & 7)*8*8*8)) as UINT
}

pub fn resource_desc_buffer(size_in_bytes: u64) -> D3D12_RESOURCE_DESC {
  D3D12_RESOURCE_DESC {
    Dimension: D3D12_RESOURCE_DIMENSION_BUFFER,
    Alignment:  0,
    Width: size_in_bytes,
    Height: 1,
    DepthOrArraySize: 1,
    MipLevels: 1,
    Format: DXGI_FORMAT_UNKNOWN,
    SampleDesc: DXGI_SAMPLE_DESC {Count:1, Quality: 0,},
    Layout: D3D12_TEXTURE_LAYOUT_ROW_MAJOR,
    Flags: D3D12_RESOURCE_FLAG_NONE,
  }
}

pub fn resource_desc_tex2d_nomip(width: u64, height: u32, format: DXGI_FORMAT, flags: D3D12_RESOURCE_FLAGS) -> D3D12_RESOURCE_DESC {
  D3D12_RESOURCE_DESC {
    Dimension: D3D12_RESOURCE_DIMENSION_TEXTURE2D,
    Alignment:  0,
    Width: width,
    Height: height,
    DepthOrArraySize: 1,
    MipLevels: 1,
    Format: format,
    SampleDesc: DXGI_SAMPLE_DESC {Count:1, Quality: 0,},
    Layout: D3D12_TEXTURE_LAYOUT_UNKNOWN,
    Flags: flags,
  }
}

pub fn heap_properties_upload() -> D3D12_HEAP_PROPERTIES {
  D3D12_HEAP_PROPERTIES {
    Type: D3D12_HEAP_TYPE_UPLOAD,
    CPUPageProperty: D3D12_CPU_PAGE_PROPERTY_UNKNOWN,
    MemoryPoolPreference: D3D12_MEMORY_POOL_UNKNOWN,
    CreationNodeMask: 0,
    VisibleNodeMask: 0,
  }
}

pub fn heap_properties_default() -> D3D12_HEAP_PROPERTIES {
  D3D12_HEAP_PROPERTIES {
    Type: D3D12_HEAP_TYPE_DEFAULT,
    CPUPageProperty: D3D12_CPU_PAGE_PROPERTY_UNKNOWN,
    MemoryPoolPreference: D3D12_MEMORY_POOL_UNKNOWN,
    CreationNodeMask: 0,
    VisibleNodeMask: 0,
  }
}

pub enum ResourceBarrier<'a,'b> {
  Transition { data: D3D12_RESOURCE_BARRIER, phantom: PhantomData<&'a D3D12Resource>, },
  Aliasing { data: D3D12_RESOURCE_BARRIER, phantom1: PhantomData<&'a D3D12Resource>, phantom2: PhantomData<&'b D3D12Resource>, },
  Uav { data: D3D12_RESOURCE_BARRIER, phantom: PhantomData<&'a D3D12Resource>, },
}

impl<'e, 'f> ResourceBarrier<'e,'f> {
  pub fn transition<'a>(
    resource: &'a D3D12Resource,
    before: D3D12_RESOURCE_STATES, after: D3D12_RESOURCE_STATES
  ) -> ResourceBarrier<'a,'a> {
    let mut ret=
      D3D12_RESOURCE_BARRIER {
        Type: D3D12_RESOURCE_BARRIER_TYPE_TRANSITION,
        Flags: D3D12_RESOURCE_BARRIER_FLAG_NONE,
        u: unsafe{ ::std::mem::uninitialized() },
      };
    unsafe {
      *ret.Transition_mut() =
        D3D12_RESOURCE_TRANSITION_BARRIER {
           pResource: resource.iptr() as *mut _,
           StateBefore: before,
           StateAfter: after,
           Subresource: D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES,
         };
    };
    ResourceBarrier::Transition {
      data: ret,
      phantom: PhantomData::<&'a _>,
    }
  }

  pub fn transition_subresource<'a>(
    resource: &'a D3D12Resource, subresource: UINT,
    before: D3D12_RESOURCE_STATES, after: D3D12_RESOURCE_STATES
  ) -> ResourceBarrier<'a,'a> {
    let mut ret=
      D3D12_RESOURCE_BARRIER {
        Type: D3D12_RESOURCE_BARRIER_TYPE_TRANSITION,
        Flags: D3D12_RESOURCE_BARRIER_FLAG_NONE,
        u: unsafe{ ::std::mem::uninitialized() },
      };
    unsafe {
      *ret.Transition_mut() =
        D3D12_RESOURCE_TRANSITION_BARRIER {
           pResource: resource.iptr() as *mut _,
           StateBefore: before,
           StateAfter: after,
           Subresource: subresource,
         };
    };
    ResourceBarrier::Transition {
      data: ret,
      phantom: PhantomData::<&'a _>,
    }
  }

  pub fn aliasing<'a,'b>(
    before: Option<&'a D3D12Resource>, after: &'b D3D12Resource
  ) -> ResourceBarrier<'a,'b> {
    let mut ret=
      D3D12_RESOURCE_BARRIER {
        Type: D3D12_RESOURCE_BARRIER_TYPE_ALIASING,
        Flags: D3D12_RESOURCE_BARRIER_FLAG_NONE,
        u: unsafe{ ::std::mem::uninitialized() },
      };
    unsafe {
      *ret.Aliasing_mut() =
        D3D12_RESOURCE_ALIASING_BARRIER {
           pResourceBefore: before.map(|r|r.iptr()).unwrap_or(::std::ptr::null_mut()) as *mut _,
           pResourceAfter: after.iptr() as *mut _,
         };
    };
    ResourceBarrier::Aliasing {
      data: ret,
      phantom1: PhantomData::<&'a _>,
      phantom2: PhantomData::<&'b _>,
    }
  }

  pub fn uav<'a>(
    resource: &'a D3D12Resource
  ) -> ResourceBarrier<'a,'a> {
    let mut ret=
      D3D12_RESOURCE_BARRIER {
        Type: D3D12_RESOURCE_BARRIER_TYPE_UAV,
        Flags: D3D12_RESOURCE_BARRIER_FLAG_NONE,
        u: unsafe{ ::std::mem::uninitialized() },
      };
    unsafe {
      *ret.UAV_mut() =
        D3D12_RESOURCE_UAV_BARRIER {
           pResource: resource.iptr() as *mut _,
         };
    };
    ResourceBarrier::Uav {
      data: ret,
      phantom: PhantomData::<&'a _>,
    }
  }

  pub fn flags(self, flags: D3D12_RESOURCE_BARRIER_FLAGS) -> ResourceBarrier<'e,'f> {
    match self {
      ResourceBarrier::Transition {mut data, phantom: p} => {
        data.Flags = flags;
        ResourceBarrier::Transition {data: data, phantom: p}
      },
      ResourceBarrier::Aliasing {mut data, phantom1: p1, phantom2: p2} => {
          data.Flags = flags;
          ResourceBarrier::Aliasing {data: data, phantom1: p1, phantom2: p2 }
      },
      ResourceBarrier::Uav {mut data, phantom: p} => {
        data.Flags = flags;
        ResourceBarrier::Uav {data: data, phantom: p}
      },
    }
  }
}

impl<'e, 'f> Deref for ResourceBarrier<'e, 'f> {
  type Target = D3D12_RESOURCE_BARRIER;

  fn deref<'a>(&'a self) -> &'a Self::Target {
    match *self {
      ResourceBarrier::Transition {ref data, ..} => { data },
      ResourceBarrier::Aliasing {ref data, ..} => { data },
      ResourceBarrier::Uav {ref data, ..} => { data },
    }
  }
}

pub enum RootParameter<'a> {
  DescriptorTable { data: D3D12_ROOT_PARAMETER, ranges: PhantomData<&'a [D3D12_DESCRIPTOR_RANGE]>, },
  Other { data: D3D12_ROOT_PARAMETER, },
}

impl<'e> Deref for RootParameter<'e> {
  type Target = D3D12_ROOT_PARAMETER;

  fn deref<'a>(&'a self) -> &'a Self::Target {
    match *self {
      RootParameter::DescriptorTable {ref data, ..} => { data },
      RootParameter::Other {ref data, ..} => { data },
    }
  }
}

impl<'a> RootParameter<'a> {
  pub fn descriptor_table<'b>(ranges: &'b [D3D12_DESCRIPTOR_RANGE], visibility: D3D12_SHADER_VISIBILITY) -> RootParameter<'b> {
    let mut ret = D3D12_ROOT_PARAMETER {
      ParameterType: D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE,
      u: unsafe { ::std::mem::uninitialized() },
      ShaderVisibility: visibility,
    };
    unsafe{
      *ret.DescriptorTable_mut() = D3D12_ROOT_DESCRIPTOR_TABLE {
        NumDescriptorRanges: ranges.len() as UINT,
        pDescriptorRanges: ranges.as_ptr(),
      };
    };
    RootParameter::DescriptorTable {
      data: ret,
      ranges: PhantomData::<&'b _>,
    }
  }

  pub fn constants<'b>(shader_register: u32, register_space: u32, num_32bit_values: u32, visibility: D3D12_SHADER_VISIBILITY) -> RootParameter<'b> {
    let mut ret = D3D12_ROOT_PARAMETER {
      ParameterType: D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS,
      u: unsafe { ::std::mem::uninitialized() },
      ShaderVisibility: visibility,
    };
    unsafe{
      *ret.Constants_mut() = D3D12_ROOT_CONSTANTS {
        ShaderRegister: shader_register,
        RegisterSpace: register_space,
        Num32BitValues: num_32bit_values,
      };
    };
    RootParameter::Other {
      data: ret,
    }
  }

  fn other<'b>(shader_register: u32, register_space: u32, visibility: D3D12_SHADER_VISIBILITY, rptype: D3D12_ROOT_PARAMETER_TYPE) -> RootParameter<'b> {
    let mut ret = D3D12_ROOT_PARAMETER {
      ParameterType: rptype,
      u: unsafe { ::std::mem::uninitialized() },
      ShaderVisibility: visibility,
    };
    unsafe{
      *ret.Descriptor_mut() = D3D12_ROOT_DESCRIPTOR {
        ShaderRegister: shader_register,
        RegisterSpace: register_space,
      };
    };
    RootParameter::Other {
      data: ret,
    }
  }

  pub fn cbv<'b>(shader_register: u32, register_space: u32, visibility: D3D12_SHADER_VISIBILITY) -> RootParameter<'b> {
    Self::other(shader_register, register_space, visibility, D3D12_ROOT_PARAMETER_TYPE_CBV)
  }

  pub fn srv<'b>(shader_register: u32, register_space: u32, visibility: D3D12_SHADER_VISIBILITY) -> RootParameter<'b> {
    Self::other(shader_register, register_space, visibility, D3D12_ROOT_PARAMETER_TYPE_SRV)
  }

  pub fn uav<'b>(shader_register: u32, register_space: u32, visibility: D3D12_SHADER_VISIBILITY) -> RootParameter<'b> {
    Self::other(shader_register, register_space, visibility, D3D12_ROOT_PARAMETER_TYPE_UAV)
  }
}

pub fn texture_copy_location_footprint(res: &D3D12Resource, footprint: &D3D12_PLACED_SUBRESOURCE_FOOTPRINT) -> D3D12_TEXTURE_COPY_LOCATION {
  unsafe {
    let mut ret = D3D12_TEXTURE_COPY_LOCATION {
      pResource: res.iptr() as *mut _,
      Type: D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT,
      u: ::std::mem::uninitialized(),
    };
    *ret.PlacedFootprint_mut() = footprint.clone();
    ret
  }
}

pub fn texture_copy_location_index(res: &D3D12Resource, subresource_index: u32) -> D3D12_TEXTURE_COPY_LOCATION {
  unsafe {
    let mut ret = D3D12_TEXTURE_COPY_LOCATION {
      pResource: res.iptr() as *mut _,
      Type: D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX,
      u: ::std::mem::uninitialized(),
    };
    *ret.SubresourceIndex_mut() = subresource_index;
    ret
  }
}

pub fn shader_resource_view_tex2d(format : DXGI_FORMAT, four_comp_map: UINT, most_det_mip: UINT, mip_levels: UINT, plane_slice: UINT, res_min_lod_clamp: f32) -> D3D12_SHADER_RESOURCE_VIEW_DESC {
  let mut ret = D3D12_SHADER_RESOURCE_VIEW_DESC {
    Format: format,
    ViewDimension: D3D12_SRV_DIMENSION_TEXTURE2D,
    Shader4ComponentMapping: four_comp_map,
    u: unsafe{ mem::uninitialized() },
  };
  unsafe {
    *ret.Texture2D_mut() = D3D12_TEX2D_SRV {
      MostDetailedMip: most_det_mip,
      MipLevels: mip_levels,
      PlaneSlice: plane_slice,
      ResourceMinLODClamp: res_min_lod_clamp,
    };
  };
  ret
}

pub fn shader_resource_view_tex2d_default(format: DXGI_FORMAT) -> D3D12_SHADER_RESOURCE_VIEW_DESC {
  shader_resource_view_tex2d(format, shader_4component_mapping(0,1,2,3), 0, 1, 0, 0.0)
}

    Format: format,
    ViewDimension: D3D12_DSV_DIMENSION_TEXTURE2D,
    Flags: D3D12_DSV_FLAG_NONE,
  };
  unsafe {
    *ret.Texture2D_mut() = D3D12_TEX2D_DSV {
      MipSlice: 0,
    };
  };
  ret
}
<commit_msg>Depth stencil<commit_after>use winapi::*;
use d3d12_safe::*;
use std::marker::PhantomData;
use std::ops::Deref;
use std::mem;

pub fn shader_4component_mapping(a: u32, b: u32, c: u32, d: u32) -> UINT {
  (0x1000 | (a & 7) | ((b & 7)*8) | ((c & 7)*8*8) | ((d & 7)*8*8*8)) as UINT
}

pub fn resource_desc_buffer(size_in_bytes: u64) -> D3D12_RESOURCE_DESC {
  D3D12_RESOURCE_DESC {
    Dimension: D3D12_RESOURCE_DIMENSION_BUFFER,
    Alignment:  0,
    Width: size_in_bytes,
    Height: 1,
    DepthOrArraySize: 1,
    MipLevels: 1,
    Format: DXGI_FORMAT_UNKNOWN,
    SampleDesc: DXGI_SAMPLE_DESC {Count:1, Quality: 0,},
    Layout: D3D12_TEXTURE_LAYOUT_ROW_MAJOR,
    Flags: D3D12_RESOURCE_FLAG_NONE,
  }
}

pub fn resource_desc_tex2d_nomip(width: u64, height: u32, format: DXGI_FORMAT, flags: D3D12_RESOURCE_FLAGS) -> D3D12_RESOURCE_DESC {
  D3D12_RESOURCE_DESC {
    Dimension: D3D12_RESOURCE_DIMENSION_TEXTURE2D,
    Alignment:  0,
    Width: width,
    Height: height,
    DepthOrArraySize: 1,
    MipLevels: 1,
    Format: format,
    SampleDesc: DXGI_SAMPLE_DESC {Count:1, Quality: 0,},
    Layout: D3D12_TEXTURE_LAYOUT_UNKNOWN,
    Flags: flags,
  }
}

pub fn heap_properties_upload() -> D3D12_HEAP_PROPERTIES {
  D3D12_HEAP_PROPERTIES {
    Type: D3D12_HEAP_TYPE_UPLOAD,
    CPUPageProperty: D3D12_CPU_PAGE_PROPERTY_UNKNOWN,
    MemoryPoolPreference: D3D12_MEMORY_POOL_UNKNOWN,
    CreationNodeMask: 0,
    VisibleNodeMask: 0,
  }
}

pub fn heap_properties_default() -> D3D12_HEAP_PROPERTIES {
  D3D12_HEAP_PROPERTIES {
    Type: D3D12_HEAP_TYPE_DEFAULT,
    CPUPageProperty: D3D12_CPU_PAGE_PROPERTY_UNKNOWN,
    MemoryPoolPreference: D3D12_MEMORY_POOL_UNKNOWN,
    CreationNodeMask: 0,
    VisibleNodeMask: 0,
  }
}

pub enum ResourceBarrier<'a,'b> {
  Transition { data: D3D12_RESOURCE_BARRIER, phantom: PhantomData<&'a D3D12Resource>, },
  Aliasing { data: D3D12_RESOURCE_BARRIER, phantom1: PhantomData<&'a D3D12Resource>, phantom2: PhantomData<&'b D3D12Resource>, },
  Uav { data: D3D12_RESOURCE_BARRIER, phantom: PhantomData<&'a D3D12Resource>, },
}

impl<'e, 'f> ResourceBarrier<'e,'f> {
  pub fn transition<'a>(
    resource: &'a D3D12Resource,
    before: D3D12_RESOURCE_STATES, after: D3D12_RESOURCE_STATES
  ) -> ResourceBarrier<'a,'a> {
    let mut ret=
      D3D12_RESOURCE_BARRIER {
        Type: D3D12_RESOURCE_BARRIER_TYPE_TRANSITION,
        Flags: D3D12_RESOURCE_BARRIER_FLAG_NONE,
        u: unsafe{ ::std::mem::uninitialized() },
      };
    unsafe {
      *ret.Transition_mut() =
        D3D12_RESOURCE_TRANSITION_BARRIER {
           pResource: resource.iptr() as *mut _,
           StateBefore: before,
           StateAfter: after,
           Subresource: D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES,
         };
    };
    ResourceBarrier::Transition {
      data: ret,
      phantom: PhantomData::<&'a _>,
    }
  }

  pub fn transition_subresource<'a>(
    resource: &'a D3D12Resource, subresource: UINT,
    before: D3D12_RESOURCE_STATES, after: D3D12_RESOURCE_STATES
  ) -> ResourceBarrier<'a,'a> {
    let mut ret=
      D3D12_RESOURCE_BARRIER {
        Type: D3D12_RESOURCE_BARRIER_TYPE_TRANSITION,
        Flags: D3D12_RESOURCE_BARRIER_FLAG_NONE,
        u: unsafe{ ::std::mem::uninitialized() },
      };
    unsafe {
      *ret.Transition_mut() =
        D3D12_RESOURCE_TRANSITION_BARRIER {
           pResource: resource.iptr() as *mut _,
           StateBefore: before,
           StateAfter: after,
           Subresource: subresource,
         };
    };
    ResourceBarrier::Transition {
      data: ret,
      phantom: PhantomData::<&'a _>,
    }
  }

  pub fn aliasing<'a,'b>(
    before: Option<&'a D3D12Resource>, after: &'b D3D12Resource
  ) -> ResourceBarrier<'a,'b> {
    let mut ret=
      D3D12_RESOURCE_BARRIER {
        Type: D3D12_RESOURCE_BARRIER_TYPE_ALIASING,
        Flags: D3D12_RESOURCE_BARRIER_FLAG_NONE,
        u: unsafe{ ::std::mem::uninitialized() },
      };
    unsafe {
      *ret.Aliasing_mut() =
        D3D12_RESOURCE_ALIASING_BARRIER {
           pResourceBefore: before.map(|r|r.iptr()).unwrap_or(::std::ptr::null_mut()) as *mut _,
           pResourceAfter: after.iptr() as *mut _,
         };
    };
    ResourceBarrier::Aliasing {
      data: ret,
      phantom1: PhantomData::<&'a _>,
      phantom2: PhantomData::<&'b _>,
    }
  }

  pub fn uav<'a>(
    resource: &'a D3D12Resource
  ) -> ResourceBarrier<'a,'a> {
    let mut ret=
      D3D12_RESOURCE_BARRIER {
        Type: D3D12_RESOURCE_BARRIER_TYPE_UAV,
        Flags: D3D12_RESOURCE_BARRIER_FLAG_NONE,
        u: unsafe{ ::std::mem::uninitialized() },
      };
    unsafe {
      *ret.UAV_mut() =
        D3D12_RESOURCE_UAV_BARRIER {
           pResource: resource.iptr() as *mut _,
         };
    };
    ResourceBarrier::Uav {
      data: ret,
      phantom: PhantomData::<&'a _>,
    }
  }

  pub fn flags(self, flags: D3D12_RESOURCE_BARRIER_FLAGS) -> ResourceBarrier<'e,'f> {
    match self {
      ResourceBarrier::Transition {mut data, phantom: p} => {
        data.Flags = flags;
        ResourceBarrier::Transition {data: data, phantom: p}
      },
      ResourceBarrier::Aliasing {mut data, phantom1: p1, phantom2: p2} => {
          data.Flags = flags;
          ResourceBarrier::Aliasing {data: data, phantom1: p1, phantom2: p2 }
      },
      ResourceBarrier::Uav {mut data, phantom: p} => {
        data.Flags = flags;
        ResourceBarrier::Uav {data: data, phantom: p}
      },
    }
  }
}

impl<'e, 'f> Deref for ResourceBarrier<'e, 'f> {
  type Target = D3D12_RESOURCE_BARRIER;

  fn deref<'a>(&'a self) -> &'a Self::Target {
    match *self {
      ResourceBarrier::Transition {ref data, ..} => { data },
      ResourceBarrier::Aliasing {ref data, ..} => { data },
      ResourceBarrier::Uav {ref data, ..} => { data },
    }
  }
}

pub enum RootParameter<'a> {
  DescriptorTable { data: D3D12_ROOT_PARAMETER, ranges: PhantomData<&'a [D3D12_DESCRIPTOR_RANGE]>, },
  Other { data: D3D12_ROOT_PARAMETER, },
}

impl<'e> Deref for RootParameter<'e> {
  type Target = D3D12_ROOT_PARAMETER;

  fn deref<'a>(&'a self) -> &'a Self::Target {
    match *self {
      RootParameter::DescriptorTable {ref data, ..} => { data },
      RootParameter::Other {ref data, ..} => { data },
    }
  }
}

impl<'a> RootParameter<'a> {
  pub fn descriptor_table<'b>(ranges: &'b [D3D12_DESCRIPTOR_RANGE], visibility: D3D12_SHADER_VISIBILITY) -> RootParameter<'b> {
    let mut ret = D3D12_ROOT_PARAMETER {
      ParameterType: D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE,
      u: unsafe { ::std::mem::uninitialized() },
      ShaderVisibility: visibility,
    };
    unsafe{
      *ret.DescriptorTable_mut() = D3D12_ROOT_DESCRIPTOR_TABLE {
        NumDescriptorRanges: ranges.len() as UINT,
        pDescriptorRanges: ranges.as_ptr(),
      };
    };
    RootParameter::DescriptorTable {
      data: ret,
      ranges: PhantomData::<&'b _>,
    }
  }

  pub fn constants<'b>(shader_register: u32, register_space: u32, num_32bit_values: u32, visibility: D3D12_SHADER_VISIBILITY) -> RootParameter<'b> {
    let mut ret = D3D12_ROOT_PARAMETER {
      ParameterType: D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS,
      u: unsafe { ::std::mem::uninitialized() },
      ShaderVisibility: visibility,
    };
    unsafe{
      *ret.Constants_mut() = D3D12_ROOT_CONSTANTS {
        ShaderRegister: shader_register,
        RegisterSpace: register_space,
        Num32BitValues: num_32bit_values,
      };
    };
    RootParameter::Other {
      data: ret,
    }
  }

  fn other<'b>(shader_register: u32, register_space: u32, visibility: D3D12_SHADER_VISIBILITY, rptype: D3D12_ROOT_PARAMETER_TYPE) -> RootParameter<'b> {
    let mut ret = D3D12_ROOT_PARAMETER {
      ParameterType: rptype,
      u: unsafe { ::std::mem::uninitialized() },
      ShaderVisibility: visibility,
    };
    unsafe{
      *ret.Descriptor_mut() = D3D12_ROOT_DESCRIPTOR {
        ShaderRegister: shader_register,
        RegisterSpace: register_space,
      };
    };
    RootParameter::Other {
      data: ret,
    }
  }

  pub fn cbv<'b>(shader_register: u32, register_space: u32, visibility: D3D12_SHADER_VISIBILITY) -> RootParameter<'b> {
    Self::other(shader_register, register_space, visibility, D3D12_ROOT_PARAMETER_TYPE_CBV)
  }

  pub fn srv<'b>(shader_register: u32, register_space: u32, visibility: D3D12_SHADER_VISIBILITY) -> RootParameter<'b> {
    Self::other(shader_register, register_space, visibility, D3D12_ROOT_PARAMETER_TYPE_SRV)
  }

  pub fn uav<'b>(shader_register: u32, register_space: u32, visibility: D3D12_SHADER_VISIBILITY) -> RootParameter<'b> {
    Self::other(shader_register, register_space, visibility, D3D12_ROOT_PARAMETER_TYPE_UAV)
  }
}

pub fn texture_copy_location_footprint(res: &D3D12Resource, footprint: &D3D12_PLACED_SUBRESOURCE_FOOTPRINT) -> D3D12_TEXTURE_COPY_LOCATION {
  unsafe {
    let mut ret = D3D12_TEXTURE_COPY_LOCATION {
      pResource: res.iptr() as *mut _,
      Type: D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT,
      u: ::std::mem::uninitialized(),
    };
    *ret.PlacedFootprint_mut() = footprint.clone();
    ret
  }
}

pub fn texture_copy_location_index(res: &D3D12Resource, subresource_index: u32) -> D3D12_TEXTURE_COPY_LOCATION {
  unsafe {
    let mut ret = D3D12_TEXTURE_COPY_LOCATION {
      pResource: res.iptr() as *mut _,
      Type: D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX,
      u: ::std::mem::uninitialized(),
    };
    *ret.SubresourceIndex_mut() = subresource_index;
    ret
  }
}

pub fn shader_resource_view_tex2d(format : DXGI_FORMAT, four_comp_map: UINT, most_det_mip: UINT, mip_levels: UINT, plane_slice: UINT, res_min_lod_clamp: f32) -> D3D12_SHADER_RESOURCE_VIEW_DESC {
  let mut ret = D3D12_SHADER_RESOURCE_VIEW_DESC {
    Format: format,
    ViewDimension: D3D12_SRV_DIMENSION_TEXTURE2D,
    Shader4ComponentMapping: four_comp_map,
    u: unsafe{ mem::uninitialized() },
  };
  unsafe {
    *ret.Texture2D_mut() = D3D12_TEX2D_SRV {
      MostDetailedMip: most_det_mip,
      MipLevels: mip_levels,
      PlaneSlice: plane_slice,
      ResourceMinLODClamp: res_min_lod_clamp,
    };
  };
  ret
}

pub fn shader_resource_view_tex2d_default(format: DXGI_FORMAT) -> D3D12_SHADER_RESOURCE_VIEW_DESC {
  shader_resource_view_tex2d(format, shader_4component_mapping(0,1,2,3), 0, 1, 0, 0.0)
}

pub fn depth_stencil_view_desc_tex2d_default(format: DXGI_FORMAT) -> D3D12_DEPTH_STENCIL_VIEW_DESC {
  let mut ret = D3D12_DEPTH_STENCIL_VIEW_DESC {
    Format: format,
    ViewDimension: D3D12_DSV_DIMENSION_TEXTURE2D,
    Flags: D3D12_DSV_FLAG_NONE,
    u: unsafe{ mem::uninitialized() },
  };
  unsafe {
    *ret.Texture2D_mut() = D3D12_TEX2D_DSV {
      MipSlice: 0,
    };
  };
  ret
}
<|endoftext|>


<commit_before>//! This pass erases all early-bound regions from the types occurring in the MIR.
//! We want to do this once just before codegen, so codegen does not have to take
//! care erasing regions all over the place.
//! N.B., we do _not_ erase regions of statements that are relevant for
//! "types-as-contracts"-validation, namely, `AcquireValid` and `ReleaseValid`.

use rustc::ty::subst::SubstsRef;
use rustc::ty::{self, Ty, TyCtxt};
use rustc::mir::*;
use rustc::mir::visit::{MutVisitor, TyContext};
use crate::transform::{MirPass, MirSource};

struct EraseRegionsVisitor<'tcx> {
    tcx: TyCtxt<'tcx>,
}

impl EraseRegionsVisitor<'tcx> {
    pub fn new(tcx: TyCtxt<'tcx>) -> Self {
        EraseRegionsVisitor {
            tcx,
        }
    }
}

impl MutVisitor<'tcx> for EraseRegionsVisitor<'tcx> {
    fn visit_ty(&mut self, ty: &mut Ty<'tcx>, _: TyContext) {
        *ty = self.tcx.erase_regions(ty);
        self.super_ty(ty);
    }

    fn visit_region(&mut self, region: &mut ty::Region<'tcx>, _: Location) {
        *region = self.tcx.lifetimes.re_erased;
    }

    fn visit_const(&mut self, constant: &mut &'tcx ty::Const<'tcx>, _: Location) {
        *constant = self.tcx.erase_regions(constant);
    }

    fn visit_substs(&mut self, substs: &mut SubstsRef<'tcx>, _: Location) {
        *substs = self.tcx.erase_regions(substs);
    }

    fn visit_statement(&mut self,
                       statement: &mut Statement<'tcx>,
                       location: Location) {
        self.super_statement(statement, location);
    }
}

pub struct EraseRegions;

impl<'tcx> MirPass<'tcx> for EraseRegions {
    fn run_pass(&self, tcx: TyCtxt<'tcx>, _: MirSource<'tcx>, body: &mut Body<'tcx>) {
        EraseRegionsVisitor::new(tcx).visit_body(body);
    }
}
<commit_msg>Rollup merge of #65116 - spastorino:remove-unneeded-fn, r=oli-obk<commit_after>//! This pass erases all early-bound regions from the types occurring in the MIR.
//! We want to do this once just before codegen, so codegen does not have to take
//! care erasing regions all over the place.
//! N.B., we do _not_ erase regions of statements that are relevant for
//! "types-as-contracts"-validation, namely, `AcquireValid` and `ReleaseValid`.

use rustc::ty::subst::SubstsRef;
use rustc::ty::{self, Ty, TyCtxt};
use rustc::mir::*;
use rustc::mir::visit::{MutVisitor, TyContext};
use crate::transform::{MirPass, MirSource};

struct EraseRegionsVisitor<'tcx> {
    tcx: TyCtxt<'tcx>,
}

impl EraseRegionsVisitor<'tcx> {
    pub fn new(tcx: TyCtxt<'tcx>) -> Self {
        EraseRegionsVisitor {
            tcx,
        }
    }
}

impl MutVisitor<'tcx> for EraseRegionsVisitor<'tcx> {
    fn visit_ty(&mut self, ty: &mut Ty<'tcx>, _: TyContext) {
        *ty = self.tcx.erase_regions(ty);
        self.super_ty(ty);
    }

    fn visit_region(&mut self, region: &mut ty::Region<'tcx>, _: Location) {
        *region = self.tcx.lifetimes.re_erased;
    }

    fn visit_const(&mut self, constant: &mut &'tcx ty::Const<'tcx>, _: Location) {
        *constant = self.tcx.erase_regions(constant);
    }

    fn visit_substs(&mut self, substs: &mut SubstsRef<'tcx>, _: Location) {
        *substs = self.tcx.erase_regions(substs);
    }
}

pub struct EraseRegions;

impl<'tcx> MirPass<'tcx> for EraseRegions {
    fn run_pass(&self, tcx: TyCtxt<'tcx>, _: MirSource<'tcx>, body: &mut Body<'tcx>) {
        EraseRegionsVisitor::new(tcx).visit_body(body);
    }
}
<|endoftext|>