<commit_before>// build.rs

extern crate pkg_config;
extern crate bindgen;
extern crate cmake;
extern crate cc;

use std::env;
use std::path::Path;

use std::fs::{self, File};
use std::io::Write;

fn format_write(builder: bindgen::Builder, output: &str) {
    let s = builder
        .generate()
        .unwrap()
        .to_string()
        .replace("/**", "/*")
        .replace("/*!", "/*");

    let mut file = File::create(output).unwrap();

    let _ = file.write(s.as_bytes());
}

fn main() {
    let cargo_dir = env::var("CARGO_MANIFEST_DIR").unwrap();
    let build_path = Path::new(&cargo_dir).join("aom_build/aom");

    let dst = cmake::Config::new(build_path)
        .define("CONFIG_DEBUG", "1")
        .define("CONFIG_EXPERIMENTAL", "1")
        .define("CONFIG_UNIT_TESTS", "0")
        .define("CONFIG_EXT_PARTITION", "0")
        .define("CONFIG_EXT_PARTITION_TYPES", "0")
        .define("CONFIG_OBU", "0")
        .define("CONFIG_FILTER_INTRA", "0")
        .define("CONFIG_EXT_SKIP", "0")
        .define("CONFIG_LV_MAP", "1")
        .define("CONFIG_ANALYZER", "0")
        .define("CONFIG_Q_ADAPT_PROBS", "0")
        .define("CONFIG_INTRA_EDGE", "0")
        .define("AOM_TARGET_CPU", "generic")
        .define("ENABLE_DOCS", "0")
        .build();

    // Dirty hack to force a rebuild whenever the defaults are changed upstream
    let _ = fs::remove_file(dst.join("build/CMakeCache.txt"));

    env::set_var("PKG_CONFIG_PATH", dst.join("lib/pkgconfig"));

    let libs = pkg_config::Config::new().statik(true).probe("aom").unwrap();
    let headers = libs.include_paths.clone();

    let mut builder = bindgen::builder()
        .raw_line("#![allow(dead_code)]")
        .raw_line("#![allow(non_camel_case_types)]")
        .raw_line("#![allow(non_snake_case)]")
        .raw_line("#![allow(non_upper_case_globals)]")
        .blacklist_type("max_align_t")
        .rustfmt_bindings(false)
        .header("data/aom.h");

    for header in headers {
        builder = builder.clang_arg("-I").clang_arg(header.to_str().unwrap());
    }

    // Manually fix the comment so rustdoc won't try to pick them
    format_write(builder, "tests/aom.rs");

    {
        use std::fs;
        fn rerun_dir<P: AsRef<Path>>(dir: P) {
            for entry in fs::read_dir(dir).unwrap() {
                let entry = entry.unwrap();
                let path = entry.path();
                println!("cargo:rerun-if-changed={}", path.to_string_lossy());

                if path.is_dir() {
                    rerun_dir(path);
                }
            }
        }

        rerun_dir("aom_build");
    }
}
<commit_msg>Build aom matching the profile<commit_after>// build.rs

extern crate pkg_config;
extern crate bindgen;
extern crate cmake;
extern crate cc;

use std::env;
use std::path::Path;

use std::fs::{self, File};
use std::io::Write;

fn format_write(builder: bindgen::Builder, output: &str) {
    let s = builder
        .generate()
        .unwrap()
        .to_string()
        .replace("/**", "/*")
        .replace("/*!", "/*");

    let mut file = File::create(output).unwrap();

    let _ = file.write(s.as_bytes());
}

fn main() {
    let cargo_dir = env::var("CARGO_MANIFEST_DIR").unwrap();
    let build_path = Path::new(&cargo_dir).join("aom_build/aom");
    let debug = if let Some(v) = env::var("PROFILE").ok() {
        match v.as_str() {
            "bench" | "release" => "0",
            _ => "1",
        }
    } else {
        "0"
    };

    let dst = cmake::Config::new(build_path)
        .define("CONFIG_DEBUG", debug)
        .define("CONFIG_EXPERIMENTAL", "1")
        .define("CONFIG_UNIT_TESTS", "0")
        .define("CONFIG_EXT_PARTITION", "0")
        .define("CONFIG_EXT_PARTITION_TYPES", "0")
        .define("CONFIG_OBU", "0")
        .define("CONFIG_FILTER_INTRA", "0")
        .define("CONFIG_EXT_SKIP", "0")
        .define("CONFIG_LV_MAP", "1")
        .define("CONFIG_ANALYZER", "0")
        .define("CONFIG_Q_ADAPT_PROBS", "0")
        .define("CONFIG_INTRA_EDGE", "0")
        .define("AOM_TARGET_CPU", "generic")
        .define("ENABLE_DOCS", "0")
        .build();

    // Dirty hack to force a rebuild whenever the defaults are changed upstream
    let _ = fs::remove_file(dst.join("build/CMakeCache.txt"));

    env::set_var("PKG_CONFIG_PATH", dst.join("lib/pkgconfig"));

    let libs = pkg_config::Config::new().statik(true).probe("aom").unwrap();
    let headers = libs.include_paths.clone();

    let mut builder = bindgen::builder()
        .raw_line("#![allow(dead_code)]")
        .raw_line("#![allow(non_camel_case_types)]")
        .raw_line("#![allow(non_snake_case)]")
        .raw_line("#![allow(non_upper_case_globals)]")
        .blacklist_type("max_align_t")
        .rustfmt_bindings(false)
        .header("data/aom.h");

    for header in headers {
        builder = builder.clang_arg("-I").clang_arg(header.to_str().unwrap());
    }

    // Manually fix the comment so rustdoc won't try to pick them
    format_write(builder, "tests/aom.rs");

    {
        use std::fs;
        fn rerun_dir<P: AsRef<Path>>(dir: P) {
            for entry in fs::read_dir(dir).unwrap() {
                let entry = entry.unwrap();
                let path = entry.path();
                println!("cargo:rerun-if-changed={}", path.to_string_lossy());

                if path.is_dir() {
                    rerun_dir(path);
                }
            }
        }

        rerun_dir("aom_build");
    }
}
<|endoftext|>


<commit_before>use std::fs::{OpenOptions};

fn main() {
    OpenOptions::new().create(true)
        .open("src/path_to_enlightenment.rs")
        .unwrap();
}
<commit_msg>Fixed initial cargo run due to invalid argument error (linux mint, rust 1.8.0)<commit_after>use std::fs::{OpenOptions};

fn main() {
    OpenOptions::new().create(true)
        .write(true)
        .open("src/path_to_enlightenment.rs")
        .unwrap();
}
<|endoftext|>


<commit_before>#[cfg(target_os="macos")]
fn build_flags(){
	println!("cargo:rustc-flags= -L native=/Library/Frameworks");
}

#[cfg(target_os="linux")]
fn build_flags(){
}

fn main(){
	build_flags();
}
<commit_msg>build.rs: fix osx framework path<commit_after>#[cfg(target_os="macos")]
fn build_flags(){
	println!("cargo:rustc-flags= -L framework=/Library/Frameworks");
}

#[cfg(target_os="linux")]
fn build_flags(){
}

fn main(){
	build_flags();
}
<|endoftext|>


<commit_before>use std::u32;
use std::sync::Arc;
use parking_lot::RwLock;
use elements::{MemoryType, ResizableLimits};
use interpreter::{Error, UserError};
use interpreter::module::check_limits;

/// Linear memory page size.
pub const LINEAR_MEMORY_PAGE_SIZE: u32 = 65536;
/// Maximal number of pages.
const LINEAR_MEMORY_MAX_PAGES: u32 = 65536;

/// Linear memory instance.
pub struct MemoryInstance<E: UserError> {
	/// Memofy limits.
	limits: ResizableLimits,
	/// Linear memory buffer.
	buffer: RwLock<Vec<u8>>,
	/// Maximum buffer size.
	maximum_size: u32,
	/// Dummy to avoid compilation error.
	_dummy: ::std::marker::PhantomData<E>,
}

struct CheckedRegion<'a, B: 'a> where B: ::std::ops::Deref<Target=Vec<u8>> {
	buffer: &'a B,
	offset: usize,
	size: usize,
}

impl<'a, B: 'a> CheckedRegion<'a, B> where B: ::std::ops::Deref<Target=Vec<u8>> {
	fn range(&self) -> ::std::ops::Range<usize> {
		self.offset..self.offset+self.size
	}

	fn slice(&self) -> &[u8] {
		&self.buffer[self.range()]
	}
}

impl<E> MemoryInstance<E> where E: UserError {
	/// Create new linear memory instance.
	pub fn new(memory_type: &MemoryType) -> Result<Arc<Self>, Error<E>> {
		check_limits(memory_type.limits())?;

		let maximum_size = match memory_type.limits().maximum() {
			Some(maximum_pages) if maximum_pages > LINEAR_MEMORY_MAX_PAGES =>
				return Err(Error::Memory(format!("maximum memory size must be at most {} pages", LINEAR_MEMORY_MAX_PAGES))),
			Some(maximum_pages) => maximum_pages.saturating_mul(LINEAR_MEMORY_PAGE_SIZE),
			None => u32::MAX,
		};
		let initial_size = calculate_memory_size(0, memory_type.limits().initial(), maximum_size)
			.ok_or(Error::Memory(format!("initial memory size must be at most {} pages", LINEAR_MEMORY_MAX_PAGES)))?;

		let memory = MemoryInstance {
			limits: memory_type.limits().clone(),
			buffer: RwLock::new(vec![0; initial_size as usize]),
			maximum_size: maximum_size,
			_dummy: Default::default(),
		};

		Ok(Arc::new(memory))
	}

	/// Return linear memory limits.
	pub fn limits(&self) -> &ResizableLimits {
		&self.limits
	}

	/// Return linear memory size (in pages).
	pub fn size(&self) -> u32 {
		self.buffer.read().len() as u32 / LINEAR_MEMORY_PAGE_SIZE
	}

	/// Get data at given offset.
	pub fn get(&self, offset: u32, size: usize) -> Result<Vec<u8>, Error<E>> {
		let buffer = self.buffer.read();
		let region = self.checked_region(&buffer, offset as usize, size)?;

		Ok(region.slice().to_vec())
	}

	/// Write memory slice into another slice
	pub fn get_into(&self, offset: u32, target: &mut [u8]) -> Result<(), Error<E>> {
		let buffer = self.buffer.read();
		let region = self.checked_region(&buffer, offset as usize, target.len())?;

		target.copy_from_slice(region.slice());

		Ok(())
	}

	/// Set data at given offset.
	pub fn set(&self, offset: u32, value: &[u8]) -> Result<(), Error<E>> {
		let mut buffer = self.buffer.write();
		let range = self.checked_region(&buffer, offset as usize, value.len())?.range();

		buffer[range].copy_from_slice(value);

		Ok(())
	}

	/// Increases the size of the linear memory by given number of pages.
	/// Returns -1 if allocation fails or previous memory size, if succeeds.
	pub fn grow(&self, pages: u32) -> Result<u32, Error<E>> {
		let mut buffer = self.buffer.write();
		let old_size = buffer.len() as u32;
		match calculate_memory_size(old_size, pages, self.maximum_size) {
			None => Ok(u32::MAX),
			Some(new_size) => {
				buffer.resize(new_size as usize, 0);
				Ok(old_size / LINEAR_MEMORY_PAGE_SIZE)
			},
		}
	}

	fn checked_region<'a, B>(&self, buffer: &'a B, offset: usize, size: usize) -> Result<CheckedRegion<'a, B>, Error<E>>
		where B: ::std::ops::Deref<Target=Vec<u8>>
	{
		let end = offset.checked_add(size)
			.ok_or(Error::Memory(format!("trying to access memory block of size {} from offset {}", size, offset)))?;

		if end > buffer.len() {
			return Err(Error::Memory(format!("trying to access region [{}..{}] in memory [0..{}]", offset, end, buffer.len())));
		}

		Ok(CheckedRegion {
			buffer: buffer,
			offset: offset,
			size: size,
		})
	}

	/// Copy memory region
	pub fn copy(&self, src_offset: usize, dst_offset: usize, len: usize) -> Result<(), Error<E>> {
		let buffer = self.buffer.write();

		let read_region = self.checked_region(&buffer, src_offset, len)?;
		let write_region = self.checked_region(&buffer, dst_offset, len)?;

		unsafe { ::std::ptr::copy(
			buffer[read_region.range()].as_ptr(),
			buffer[write_region.range()].as_ptr() as *mut _,
			len,
		)}

		Ok(())
	}

	/// Zero memory region
	pub fn zero(&self, offset: usize, len: usize) -> Result<(), Error<E>> {
		let mut buffer = self.buffer.write();

		let range = self.checked_region(&buffer, offset, len)?.range();
		for val in &mut buffer[range] { *val = 0 }
		Ok(())
	}
}

fn calculate_memory_size(old_size: u32, additional_pages: u32, maximum_size: u32) -> Option<u32> {
	additional_pages
		.checked_mul(LINEAR_MEMORY_PAGE_SIZE)
		.and_then(|size| size.checked_add(old_size))
		.and_then(|size| if size > maximum_size {
			None
		} else {
			Some(size)
		})
}

#[cfg(test)]
mod tests {

	use super::MemoryInstance;
	use elements::MemoryType;
	use interpreter::DummyUserError;

	#[test]
	fn get_into() {
		let mem = MemoryInstance::<DummyUserError>::new(&MemoryType::new(1, None)).expect("memory instance creation should not fail");
		mem.set(6, &[13, 17, 129]).expect("memory set should not fail");

		let mut data = [0u8; 2];
		mem.get_into(7, &mut data[..]).expect("get_into should not fail");

		assert_eq!(data, [17, 129]);
	}

}<commit_msg>remove space<commit_after>use std::u32;
use std::sync::Arc;
use parking_lot::RwLock;
use elements::{MemoryType, ResizableLimits};
use interpreter::{Error, UserError};
use interpreter::module::check_limits;

/// Linear memory page size.
pub const LINEAR_MEMORY_PAGE_SIZE: u32 = 65536;
/// Maximal number of pages.
const LINEAR_MEMORY_MAX_PAGES: u32 = 65536;

/// Linear memory instance.
pub struct MemoryInstance<E: UserError> {
	/// Memofy limits.
	limits: ResizableLimits,
	/// Linear memory buffer.
	buffer: RwLock<Vec<u8>>,
	/// Maximum buffer size.
	maximum_size: u32,
	/// Dummy to avoid compilation error.
	_dummy: ::std::marker::PhantomData<E>,
}

struct CheckedRegion<'a, B: 'a> where B: ::std::ops::Deref<Target=Vec<u8>> {
	buffer: &'a B,
	offset: usize,
	size: usize,
}

impl<'a, B: 'a> CheckedRegion<'a, B> where B: ::std::ops::Deref<Target=Vec<u8>> {
	fn range(&self) -> ::std::ops::Range<usize> {
		self.offset..self.offset+self.size
	}

	fn slice(&self) -> &[u8] {
		&self.buffer[self.range()]
	}
}

impl<E> MemoryInstance<E> where E: UserError {
	/// Create new linear memory instance.
	pub fn new(memory_type: &MemoryType) -> Result<Arc<Self>, Error<E>> {
		check_limits(memory_type.limits())?;

		let maximum_size = match memory_type.limits().maximum() {
			Some(maximum_pages) if maximum_pages > LINEAR_MEMORY_MAX_PAGES =>
				return Err(Error::Memory(format!("maximum memory size must be at most {} pages", LINEAR_MEMORY_MAX_PAGES))),
			Some(maximum_pages) => maximum_pages.saturating_mul(LINEAR_MEMORY_PAGE_SIZE),
			None => u32::MAX,
		};
		let initial_size = calculate_memory_size(0, memory_type.limits().initial(), maximum_size)
			.ok_or(Error::Memory(format!("initial memory size must be at most {} pages", LINEAR_MEMORY_MAX_PAGES)))?;

		let memory = MemoryInstance {
			limits: memory_type.limits().clone(),
			buffer: RwLock::new(vec![0; initial_size as usize]),
			maximum_size: maximum_size,
			_dummy: Default::default(),
		};

		Ok(Arc::new(memory))
	}

	/// Return linear memory limits.
	pub fn limits(&self) -> &ResizableLimits {
		&self.limits
	}

	/// Return linear memory size (in pages).
	pub fn size(&self) -> u32 {
		self.buffer.read().len() as u32 / LINEAR_MEMORY_PAGE_SIZE
	}

	/// Get data at given offset.
	pub fn get(&self, offset: u32, size: usize) -> Result<Vec<u8>, Error<E>> {
		let buffer = self.buffer.read();
		let region = self.checked_region(&buffer, offset as usize, size)?;

		Ok(region.slice().to_vec())
	}

	/// Write memory slice into another slice
	pub fn get_into(&self, offset: u32, target: &mut [u8]) -> Result<(), Error<E>> {
		let buffer = self.buffer.read();
		let region = self.checked_region(&buffer, offset as usize, target.len())?;

		target.copy_from_slice(region.slice());

		Ok(())
	}

	/// Set data at given offset.
	pub fn set(&self, offset: u32, value: &[u8]) -> Result<(), Error<E>> {
		let mut buffer = self.buffer.write();
		let range = self.checked_region(&buffer, offset as usize, value.len())?.range();

		buffer[range].copy_from_slice(value);

		Ok(())
	}

	/// Increases the size of the linear memory by given number of pages.
	/// Returns -1 if allocation fails or previous memory size, if succeeds.
	pub fn grow(&self, pages: u32) -> Result<u32, Error<E>> {
		let mut buffer = self.buffer.write();
		let old_size = buffer.len() as u32;
		match calculate_memory_size(old_size, pages, self.maximum_size) {
			None => Ok(u32::MAX),
			Some(new_size) => {
				buffer.resize(new_size as usize, 0);
				Ok(old_size / LINEAR_MEMORY_PAGE_SIZE)
			},
		}
	}

	fn checked_region<'a, B>(&self, buffer: &'a B, offset: usize, size: usize) -> Result<CheckedRegion<'a, B>, Error<E>>
		where B: ::std::ops::Deref<Target=Vec<u8>>
	{
		let end = offset.checked_add(size)
			.ok_or(Error::Memory(format!("trying to access memory block of size {} from offset {}", size, offset)))?;

		if end > buffer.len() {
			return Err(Error::Memory(format!("trying to access region [{}..{}] in memory [0..{}]", offset, end, buffer.len())));
		}

		Ok(CheckedRegion {
			buffer: buffer,
			offset: offset,
			size: size,
		})
	}

	/// Copy memory region
	pub fn copy(&self, src_offset: usize, dst_offset: usize, len: usize) -> Result<(), Error<E>> {
		let buffer = self.buffer.write();

		let read_region = self.checked_region(&buffer, src_offset, len)?;
		let write_region = self.checked_region(&buffer, dst_offset, len)?;

		unsafe { ::std::ptr::copy(
			buffer[read_region.range()].as_ptr(),
			buffer[write_region.range()].as_ptr() as *mut _,
			len,
		)}

		Ok(())
	}

	/// Zero memory region
	pub fn zero(&self, offset: usize, len: usize) -> Result<(), Error<E>> {
		let mut buffer = self.buffer.write();

		let range = self.checked_region(&buffer, offset, len)?.range();
		for val in &mut buffer[range] { *val = 0 }
		Ok(())
	}
}

fn calculate_memory_size(old_size: u32, additional_pages: u32, maximum_size: u32) -> Option<u32> {
	additional_pages
		.checked_mul(LINEAR_MEMORY_PAGE_SIZE)
		.and_then(|size| size.checked_add(old_size))
		.and_then(|size| if size > maximum_size {
			None
		} else {
			Some(size)
		})
}

#[cfg(test)]
mod tests {

	use super::MemoryInstance;
	use elements::MemoryType;
	use interpreter::DummyUserError;

	#[test]
	fn get_into() {
		let mem = MemoryInstance::<DummyUserError>::new(&MemoryType::new(1, None)).expect("memory instance creation should not fail");
		mem.set(6, &[13, 17, 129]).expect("memory set should not fail");

		let mut data = [0u8; 2];
		mem.get_into(7, &mut data[..]).expect("get_into should not fail");

		assert_eq!(data, [17, 129]);
	}
}<|endoftext|>


<commit_before>use std::{
    fs::File,
    io::{BufRead, BufReader},
    thread,
    time::Duration,
};

use anyhow::Context;
use cargo_registry_index::{Repository, RepositoryConfig};
use diesel::prelude::*;
use indicatif::{ProgressBar, ProgressIterator, ProgressStyle};

use crate::{
    admin::dialoguer,
    db,
    schema::{crates, dependencies, versions},
};

#[derive(clap::Parser, Debug, Copy, Clone)]
#[clap(
    name = "git-import",
    about = "Import missing fields from git into the database"
)]
pub struct Opts {
    /// Time in milliseconds to sleep between crate updates to reduce database load.
    #[clap(long)]
    delay: u64,
}

pub fn run(opts: Opts) -> anyhow::Result<()> {
    let conn = db::oneoff_connection().unwrap();
    println!("fetching git repo");
    let config = RepositoryConfig::from_environment();
    let repo = Repository::open(&config)?;
    repo.reset_head()?;
    println!("HEAD is at {}", repo.head_oid()?);
    let files = repo.get_files_modified_since(None)?;
    println!("found {} crates", files.len());
    if !dialoguer::confirm("continue?") {
        return Ok(());
    }

    let pb = ProgressBar::new(files.len() as u64);
    pb.set_style(ProgressStyle::with_template("{bar:60} ({pos}/{len}, ETA {eta})").unwrap());

    for file in files.iter().progress_with(pb) {
        thread::sleep(Duration::from_millis(opts.delay));
        let crate_name = file.file_name().unwrap().to_str().unwrap();
        let path = repo.index_file(crate_name);
        if !path.exists() {
            continue;
        }
        let file = File::open(path)?;
        let reader = BufReader::new(file);
        for line in reader.lines() {
            let krate: cargo_registry_index::Crate = serde_json::from_str(&line?)?;
            conn.transaction(|| {
                import_data(&conn, &krate)
                    .with_context(|| format!("failed to update crate: {krate:?}"))
            })?;
        }
    }

    Ok(())
}

fn import_data(conn: &PgConnection, krate: &cargo_registry_index::Crate) -> QueryResult<()> {
    let version_id: i32 = versions::table
        .inner_join(crates::table)
        .filter(crates::name.eq(&krate.name))
        .filter(versions::num.eq(&krate.vers))
        .select(versions::id)
        .first(conn)?;

    // Update the `checksum` and `links` fields.
    diesel::update(versions::table)
        .set((
            versions::checksum.eq(&krate.cksum),
            versions::links.eq(&krate.links),
        ))
        .filter(versions::id.eq(version_id))
        .execute(conn)?;
    // Update the `explicit_name` field for each dependency.
    for dep in &krate.deps {
        if let Some(package) = &dep.package {
            // This is a little tricky because there can be two identical deps in the
            // database. The only difference in git is the field we're trying to
            // fill (explicit_name). Using `first` here & filtering out existing `explicit_name`
            // entries ensure that we assign one explicit_name to each dep.
            let id: i32 = dependencies::table
                .inner_join(crates::table)
                .filter(dependencies::explicit_name.is_null())
                .filter(dependencies::version_id.eq(version_id))
                .filter(dependencies::req.eq(&dep.req))
                .filter(dependencies::features.eq(&dep.features))
                .filter(dependencies::optional.eq(&dep.optional))
                .filter(dependencies::default_features.eq(&dep.default_features))
                .filter(dependencies::target.is_not_distinct_from(&dep.target))
                .filter(dependencies::kind.eq(dep.kind.map(|k| k as i32).unwrap_or_default()))
                .filter(crates::name.eq(package))
                .select(dependencies::id)
                .first(conn)?;
            diesel::update(dependencies::table)
                .set(dependencies::explicit_name.eq(&dep.name))
                .filter(dependencies::id.eq(id))
                .execute(conn)?;
        }
    }
    Ok(())
}
<commit_msg>git-import admin tool can resume partial imports (#5120)<commit_after>use std::{
    fs::File,
    io::{BufRead, BufReader},
    thread,
    time::Duration,
};

use anyhow::Context;
use cargo_registry_index::{Repository, RepositoryConfig};
use diesel::prelude::*;
use indicatif::{ProgressBar, ProgressIterator, ProgressStyle};

use crate::{
    admin::dialoguer,
    db,
    schema::{crates, dependencies, versions},
};

#[derive(clap::Parser, Debug, Copy, Clone)]
#[clap(
    name = "git-import",
    about = "Import missing fields from git into the database"
)]
pub struct Opts {
    /// Time in milliseconds to sleep between crate updates to reduce database load.
    #[clap(long)]
    delay: u64,
}

pub fn run(opts: Opts) -> anyhow::Result<()> {
    let conn = db::oneoff_connection().unwrap();
    println!("fetching git repo");
    let config = RepositoryConfig::from_environment();
    let repo = Repository::open(&config)?;
    repo.reset_head()?;
    println!("HEAD is at {}", repo.head_oid()?);
    let files = repo.get_files_modified_since(None)?;
    println!("found {} crates", files.len());
    if !dialoguer::confirm("continue?") {
        return Ok(());
    }

    let pb = ProgressBar::new(files.len() as u64);
    pb.set_style(ProgressStyle::with_template("{bar:60} ({pos}/{len}, ETA {eta})").unwrap());

    for file in files.iter().progress_with(pb.clone()) {
        thread::sleep(Duration::from_millis(opts.delay));
        let crate_name = file.file_name().unwrap().to_str().unwrap();
        let path = repo.index_file(crate_name);
        if !path.exists() {
            pb.suspend(|| println!("skipping {}", path.display()));
            continue;
        }
        let file = File::open(path)?;
        let reader = BufReader::new(file);
        let result = conn.transaction(|| -> anyhow::Result<()> {
            for line in reader.lines() {
                let krate: cargo_registry_index::Crate = serde_json::from_str(&line?)?;
                import_data(&conn, &krate).with_context(|| {
                    format!("Failed to update crate {}#{}", krate.name, krate.vers)
                })?
            }
            Ok(())
        });
        if let Err(err) = result {
            println!("{}", err);
        }
    }
    println!("completed");

    Ok(())
}

fn import_data(conn: &PgConnection, krate: &cargo_registry_index::Crate) -> anyhow::Result<()> {
    let version_id: i32 = versions::table
        .inner_join(crates::table)
        .filter(crates::name.eq(&krate.name))
        .filter(versions::num.eq(&krate.vers))
        .select(versions::id)
        .first(conn)
        .with_context(|| {
            format!(
                "Failed to find {}#{} in the database",
                krate.name, krate.vers
            )
        })?;

    // Update the `checksum` and `links` fields.
    diesel::update(versions::table)
        .set((
            versions::checksum.eq(&krate.cksum),
            versions::links.eq(&krate.links),
        ))
        .filter(versions::id.eq(version_id))
        .filter(versions::checksum.is_null())
        .filter(versions::links.is_null())
        .execute(conn)
        .with_context(|| {
            format!(
                "Failed to update checksum/links of {}#{} (id: {version_id})",
                krate.name, krate.vers
            )
        })?;

    // Check if any of this crate's dependencies have a missing explicit_name.
    if krate.deps.iter().any(|d| d.package.is_some())
        && dependencies::table
            .filter(dependencies::version_id.eq(version_id))
            .filter(dependencies::explicit_name.is_not_null())
            .count()
            .get_result::<i64>(conn)?
            == 0
    {
        for dep in &krate.deps {
            if let Some(package) = &dep.package {
                // This is a little tricky because there can be two identical deps in the
                // database. The only difference in git is the field we're trying to
                // fill (explicit_name). Using `first` here & filtering out existing `explicit_name`
                // entries ensure that we assign one explicit_name to each dep.

                let id: i32 = dependencies::table
                    .inner_join(crates::table)
                    .filter(dependencies::explicit_name.is_null())
                    .filter(dependencies::version_id.eq(version_id))
                    .filter(dependencies::req.eq(&dep.req))
                    .filter(dependencies::features.eq(&dep.features))
                    .filter(dependencies::optional.eq(&dep.optional))
                    .filter(dependencies::default_features.eq(&dep.default_features))
                    .filter(dependencies::target.is_not_distinct_from(&dep.target))
                    .filter(dependencies::kind.eq(dep.kind.map(|k| k as i32).unwrap_or_default()))
                    .filter(crates::name.eq(package))
                    .select(dependencies::id)
                    .first(conn)
                    .with_context(|| {
                        format!(
                            "{}#{}: Failed to find matching dependency: {} {}",
                            krate.name, krate.vers, package, dep.req
                        )
                    })?;

                diesel::update(dependencies::table)
                    .set(dependencies::explicit_name.eq(&dep.name))
                    .filter(dependencies::id.eq(id))
                    .execute(conn)
                    .with_context(|| {
                        format!(
                            "Failed to update `explicit_name` of dependency {id} to {}",
                            dep.name
                        )
                    })?;
            }
        }
    }
    Ok(())
}
<|endoftext|>


<commit_before>extern crate libc;
extern crate indyrs as indy;

use std::ptr;
use std::ffi::CStr;
use std::str::Utf8Error;

use self::libc::c_char;

#[test]
fn get_current_error_works_for_no_error() {
    let mut error_json_p: *const c_char = ptr::null();

    unsafe { indy_get_current_error(&mut error_json_p); }
    assert_eq!(None, c_str_to_string(error_json_p).unwrap());
}

#[test]
fn get_current_error_works_for_sync_error_occurred() {
    let mut error_json_p: *const c_char = ptr::null();

    unsafe { indy_set_runtime_config(ptr::null()) };

    unsafe { indy_get_current_error(&mut error_json_p); }
    assert!(c_str_to_string(error_json_p).unwrap().is_some());
}

#[test]
fn get_current_error_works_for_async_error_occurred() {
    extern fn cb(_command_handle_: i32,
                 _err: u32,
                 _verkey: *const c_char) {
        let mut error_json_p: *const c_char = ptr::null();
        unsafe {indy_get_current_error(&mut error_json_p) };
        assert!(c_str_to_string(error_json_p).unwrap().is_some());
    }

    let did = ::std::ffi::CString::new("wrongdid").unwrap();
    let verkey = ::std::ffi::CString::new("verkey").unwrap();
    unsafe { indy_abbreviate_verkey(1, did.as_ptr(), verkey.as_ptr(), Some(cb)) };
    ::std::thread::sleep(::std::time::Duration::from_secs(1));
}

extern {
    #[no_mangle]
    pub fn indy_set_runtime_config(config: *const c_char) -> i32;

    #[no_mangle]
    pub fn indy_get_current_error(error_json: *mut *const c_char);

    #[no_mangle]
    pub fn indy_abbreviate_verkey(command_handle: i32, did: *const c_char, full_verkey: *const c_char,
                                  cb: Option<extern fn(command_handle_: i32,
                                                       err: u32,
                                                       verkey: *const c_char)>) -> i32;
}

pub fn c_str_to_string<'a>(cstr: *const c_char) -> Result<Option<&'a str>, Utf8Error> {
    if cstr.is_null() {
        return Ok(None);
    }

    unsafe {
        match CStr::from_ptr(cstr).to_str() {
            Ok(str) => Ok(Some(str)),
            Err(err) => Err(err)
        }
    }
}<commit_msg>IS-1366:  Fixed get_error related test<commit_after>extern crate libc;
extern crate indyrs as indy;

use std::ptr;
use std::ffi::CStr;
use std::str::Utf8Error;

use self::libc::c_char;

#[test]
fn get_current_error_works_for_no_error() {
    let mut error_json_p: *const c_char = ptr::null();

    unsafe { indy_get_current_error(&mut error_json_p); }
    assert_eq!(None, c_str_to_string(error_json_p).unwrap());
}

#[test]
fn get_current_error_works_for_sync_error_occurred() {
    let mut error_json_p: *const c_char = ptr::null();

    unsafe { indy_set_runtime_config(ptr::null()) };

    unsafe { indy_get_current_error(&mut error_json_p); }
    assert!(c_str_to_string(error_json_p).unwrap().is_some());
}

#[test]
fn get_current_error_works_for_async_error_occurred() {
    extern fn cb(_command_handle_: i32,
                 _err: u32,
                 _verkey: *const c_char) {
        let mut error_json_p: *const c_char = ptr::null();
        unsafe {indy_get_current_error(&mut error_json_p) };
        assert!(c_str_to_string(error_json_p).unwrap().is_some());
    }

    let did = ::std::ffi::CString::new("VsKV7grR1BUE29mG2Fm2kX").unwrap();
    let verkey = ::std::ffi::CString::new("wrong_verkey").unwrap();
    unsafe { indy_abbreviate_verkey(1, did.as_ptr(), verkey.as_ptr(), Some(cb)) };
    ::std::thread::sleep(::std::time::Duration::from_secs(1));
}

extern {
    #[no_mangle]
    pub fn indy_set_runtime_config(config: *const c_char) -> i32;

    #[no_mangle]
    pub fn indy_get_current_error(error_json: *mut *const c_char);

    #[no_mangle]
    pub fn indy_abbreviate_verkey(command_handle: i32, did: *const c_char, full_verkey: *const c_char,
                                  cb: Option<extern fn(command_handle_: i32,
                                                       err: u32,
                                                       verkey: *const c_char)>) -> i32;
}

pub fn c_str_to_string<'a>(cstr: *const c_char) -> Result<Option<&'a str>, Utf8Error> {
    if cstr.is_null() {
        return Ok(None);
    }

    unsafe {
        match CStr::from_ptr(cstr).to_str() {
            Ok(str) => Ok(Some(str)),
            Err(err) => Err(err)
        }
    }
}<|endoftext|>


<commit_before>// Copyright 2019 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 kernel::common::cells::VolatileCell;
use kernel::common::registers::ReadWrite;

// The hardware flash controller. Cannot be used in userspace (accessing will
// trigger a fault), and should only be manipulated by the flash hardware.
pub static mut H1B_HW: *const H1bHw = 0x40720000 as *const H1bHw;

register_bitfields![u32,
	TransactionParameters [
		Offset OFFSET(0) NUMBITS(16) [],
		Bank   OFFSET(16) NUMBITS(1) [],
		Size   OFFSET(17) NUMBITS(5) []
	]
];

#[repr(C)]
pub struct H1bHw {
	/// Read/Program/Erase control for flash macro 0.
	_pe_control_0: VolatileCell<u32>,

	/// Read/Program/Erase control for flash macro 1.
	pe_control_1: VolatileCell<u32>,

	/// Write size and offset.
	transaction_parameters: ReadWrite<u32, TransactionParameters::Register>,

	/// Read/erase/program lockdown modes for the various flash regions.
	_lockdown_triggers: VolatileCell<u32>,

	/// Triggers a read of info 0 data to check for secure data write functionality. Only available
	/// in test mode.
	_enable_info0_shadow_read: VolatileCell<u32>,

	/// Operation-completion interrupt controls.
	_interrupt_control: VolatileCell<u32>,

	/// Operation-completion state. Cleared on read.
	_interrupt_state: VolatileCell<u32>,

	/// Macro 0 override signal unlock.
	_override_0_unlock: VolatileCell<u32>,

	/// Macro 1 override signal unlock.
	_override_1_unlock: VolatileCell<u32>,

	/// DIN override.
	_din_override: VolatileCell<u32>,

	/// Offset override.
	_offset_override: VolatileCell<u32>,

	/// Signal override values.
	_override_signal_values: VolatileCell<u32>,

	/// Signal override controls.
	_override_signal_control: VolatileCell<u32>,

	/// Controls whether the system may powerdown without waiting for graceful brownout completion.
	disable_brownout_wait: VolatileCell<u32>,

	/// The most recent value of Macro 0's DOUT.
	dout_value_0: VolatileCell<u32>,

	/// TC override read value.
	_tc_override_value_0: VolatileCell<u32>,

	/// The most recent value of Macro 1's DOUT.
	dout_value_1: VolatileCell<u32>,

	/// TC override read value.
	_tc_override_value_1: VolatileCell<u32>,

	/// Write data buffer.
	write_data: [VolatileCell<u32>; 32],

	/// Program and erase enable.
	program_erase_enable: VolatileCell<u32>,

	/// Redundancy remapping enablement and control for macro 0.
	redundancy_remapping_0: VolatileCell<u32>,

	/// Redundancy remapping enablement and control for macro 1.
	redundancy_remapping_1: VolatileCell<u32>,

	/// Error signalling.
	error_code: VolatileCell<u32>,

	/// Read operation duration.
	read_cycles: VolatileCell<u32>,

	/// The first cycle XE should be asserted during reads.
	read_xe_first_cycle: VolatileCell<u32>,

	/// The last cycle XE should be asserted during reads.
	read_xe_last_cycle: VolatileCell<u32>,

	/// The first cycle YE should be asserted during reads.
	read_ye_first_cycle: VolatileCell<u32>,

	/// The last cycle YE should be asserted during reads.
	read_ye_last_cycle: VolatileCell<u32>,

	/// The first cycle SE should be asserted during reads.
	read_se_first_cycle: VolatileCell<u32>,

	/// The last cycle SE should be asserted during reads.
	read_se_last_cycle: VolatileCell<u32>,

	/// The first cycle PV should be asserted during program verify reads.
	read_pv_first_cycle: VolatileCell<u32>,

	/// The last cycle PV should be asserted during program verify reads.
	read_pv_last_cycle: VolatileCell<u32>,

	/// The first cycle EV should be asserted during erase verify reads.
	read_ev_first_cycle: VolatileCell<u32>,

	/// The last cycle EV should be asserted during erase verify reads.
	read_ev_last_cycle: VolatileCell<u32>,

	/// Smart program algorithm enablement.
	enable_smart_program: VolatileCell<u32>,

	/// Single-word program timing.
	program_cycles: VolatileCell<u32>,

	/// The first cycle XE should be asserted during program.
	program_xe_first_cycle: VolatileCell<u32>,

	/// The last cycle XE should be asserted during program.
	program_xe_last_cycle: VolatileCell<u32>,

	/// The first cycle YE should be asserted during program.
	program_ye_first_cycle: VolatileCell<u32>,

	/// The last cycle YE should be asserted during program.
	program_ye_last_cycle: VolatileCell<u32>,

	/// The first cycle DIN and YADR are ready during program.
	program_din_yadr_first_cycle: VolatileCell<u32>,

	/// The last cycle DIN and YADR are ready during program.
	program_din_yadr_last_cycle: VolatileCell<u32>,

	/// The first cycle PROG should be asserted during program.
	program_prog_first_cycle: VolatileCell<u32>,

	/// The last cycle PROG should be asserted during program.
	program_prog_last_cycle: VolatileCell<u32>,

	/// The first cycle NVSTR should be asserted during program.
	program_nvstr_first_cycle: VolatileCell<u32>,

	/// The last cycle NVSTR should be asserted during program.
	program_nvstr_last_cycle: VolatileCell<u32>,

	/// Smart erase algorithm enablement.
	enable_smart_erase: VolatileCell<u32>,

	/// Flash erase cycle count.
	erase_cycles: VolatileCell<u32>,

	/// The first cycle XE should be asserted during erase.
	erase_xe_first_cycle: VolatileCell<u32>,

	/// The last cycle XE should be asserted during erase.
	erase_xe_last_cycle: VolatileCell<u32>,

	/// The first cycle ERASE should be asserted during erase.
	erase_erase_first_cycle: VolatileCell<u32>,

	/// The last cycle ERASE should be asserted during erase.
	erase_erase_last_cycle: VolatileCell<u32>,

	/// The first cycle NVSTR should be asserted during erase.
	erase_nvstr_first_cycle: VolatileCell<u32>,

	/// The last cycle NVSTR should be asserted during erase.
	erase_nvstr_last_cycle: VolatileCell<u32>,

	/// Enable smart erase for bulk erases.
	enable_bulk_smart_erase: VolatileCell<u32>,

	/// Duration of bulk erase operations.
	bulk_erase_cycles: VolatileCell<u32>,

	/// The first cycle XE should be asserted during bulkerase.
	bulkerase_xe_first_cycle: VolatileCell<u32>,

	/// The last cycle XE should be asserted during bulkerase.
	bulkerase_xe_last_cycle: VolatileCell<u32>,

	/// The first cycle BULKERASE should be asserted during bulkerase.
	bulkerase_bulkerase_first_cycle: VolatileCell<u32>,

	/// The last cycle BULKERASE should be asserted during bulkerase.
	bulkerase_bulkerase_last_cycle: VolatileCell<u32>,

	/// The first cycle MAS1 should be asserted during bulkerase.
	bulkerase_mas1_first_cycle: VolatileCell<u32>,

	/// The last cycle MAS1 should be asserted during bulkerase.
	bulkerase_mas1_last_cycle: VolatileCell<u32>,

	/// The first cycle NVSTR should be asserted during bulkerase.
	bulkerase_nvstr_first_cycle: VolatileCell<u32>,

	/// The last cycle NVSTR should be asserted during bulkerase.
	bulkerase_nvstr_last_cycle: VolatileCell<u32>,

	/// Controller debug signals.
	debug_signals: VolatileCell<u32>,

	// The integration test controls are omitted because they are unnecessary
	// and are after a large address space gap.
}

impl super::hardware::Hardware for H1bHw {
	fn is_programming(&self) -> bool {
		// TODO(jrvanwhy): Only checks the second flash bank.
		self.pe_control_1.get() != 0
	}

	fn read(&self, offset: usize) -> u32 {
		// The two flash macros are in consecutive memory locations, so they can
		// be addressed as one.
		unsafe { ::core::ptr::read_volatile((0x40000 as *const u32).add(offset)) }
	}

	fn read_error(&self) -> u16 {
		self.error_code.get() as u16
	}

	fn set_transaction(&self, offset: usize, size: usize) {
		use self::TransactionParameters::{Offset,Size};
		// The offset is relative to the beginning of the flash module. There
		// are 128 pages per flash module.
		// TODO(jrvanwhy): Assumes the read is from the second flash bank.
		let offset = offset - 128 * super::WORDS_PER_PAGE;
		self.transaction_parameters.write(Offset.val(offset as u32) + Size.val(size as u32));
	}

	fn set_write_data(&self, data: &[u32]) {
		for (i, &v) in data.iter().enumerate() { self.write_data[i].set(v); }
	}

	fn trigger(&self, opcode: u32) {
		self.program_erase_enable.set(0xb11924e1);
		// TODO(jrvanwhy): Assumes the write is to the second flash bank (where
		// the nvmem counter is).
		self.pe_control_1.set(opcode);
	}
}
<commit_msg>Check bounds of offset on flash operations.<commit_after>// Copyright 2019 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.

#![allow(unused)]

use kernel::common::cells::VolatileCell;
use kernel::common::registers::ReadWrite;

// The hardware flash controller. Cannot be used in userspace (accessing will
// trigger a fault), and should only be manipulated by the flash hardware.
pub static mut H1B_HW: *const H1bHw = 0x40720000 as *const H1bHw;

const H1B_FLASH_START: usize     = 0x40000;
const H1B_FLASH_BANK_SIZE: usize = 0x40000;
const H1B_FLASH_SIZE: usize      = 0x80000; // Two banks

const H1B_INFO_0_START: usize    = 0x20000;
const H1B_INFO_1_START: usize    = 0x28000;
const H1B_INFO_SIZE: usize       = 0x00800;

register_bitfields![u32,
        TransactionParameters [
                Offset OFFSET(0) NUMBITS(16) [],
                Bank   OFFSET(16) NUMBITS(1) [],
                Size   OFFSET(17) NUMBITS(5) []
        ]
];

#[repr(C)]
pub struct H1bHw {
        /// Read/Program/Erase control for flash macro 0.
        _pe_control_0: VolatileCell<u32>,

        /// Read/Program/Erase control for flash macro 1.
        pe_control_1: VolatileCell<u32>,

        /// Write size and offset.
        transaction_parameters: ReadWrite<u32, TransactionParameters::Register>,

        /// Read/erase/program lockdown modes for the various flash regions.
        _lockdown_triggers: VolatileCell<u32>,

        /// Triggers a read of info 0 data to check for secure data write functionality. Only available
        /// in test mode.
        _enable_info0_shadow_read: VolatileCell<u32>,

        /// Operation-completion interrupt controls.
        _interrupt_control: VolatileCell<u32>,

        /// Operation-completion state. Cleared on read.
        _interrupt_state: VolatileCell<u32>,

        /// Macro 0 override signal unlock.
        _override_0_unlock: VolatileCell<u32>,

        /// Macro 1 override signal unlock.
        _override_1_unlock: VolatileCell<u32>,

        /// DIN override.
        _din_override: VolatileCell<u32>,

        /// Offset override.
        _offset_override: VolatileCell<u32>,

        /// Signal override values.
        _override_signal_values: VolatileCell<u32>,

        /// Signal override controls.
        _override_signal_control: VolatileCell<u32>,

        /// Controls whether the system may powerdown without waiting for graceful brownout completion.
        disable_brownout_wait: VolatileCell<u32>,

        /// The most recent value of Macro 0's DOUT.
        dout_value_0: VolatileCell<u32>,

        /// TC override read value.
        _tc_override_value_0: VolatileCell<u32>,

        /// The most recent value of Macro 1's DOUT.
        dout_value_1: VolatileCell<u32>,

        /// TC override read value.
        _tc_override_value_1: VolatileCell<u32>,

        /// Write data buffer.
        write_data: [VolatileCell<u32>; 32],

        /// Program and erase enable.
        program_erase_enable: VolatileCell<u32>,

        /// Redundancy remapping enablement and control for macro 0.
        redundancy_remapping_0: VolatileCell<u32>,

        /// Redundancy remapping enablement and control for macro 1.
        redundancy_remapping_1: VolatileCell<u32>,

        /// Error signalling.
        error_code: VolatileCell<u32>,

        /// Read operation duration.
        read_cycles: VolatileCell<u32>,

        /// The first cycle XE should be asserted during reads.
        read_xe_first_cycle: VolatileCell<u32>,

        /// The last cycle XE should be asserted during reads.
        read_xe_last_cycle: VolatileCell<u32>,

        /// The first cycle YE should be asserted during reads.
        read_ye_first_cycle: VolatileCell<u32>,

        /// The last cycle YE should be asserted during reads.
        read_ye_last_cycle: VolatileCell<u32>,

        /// The first cycle SE should be asserted during reads.
        read_se_first_cycle: VolatileCell<u32>,

        /// The last cycle SE should be asserted during reads.
        read_se_last_cycle: VolatileCell<u32>,

        /// The first cycle PV should be asserted during program verify reads.
        read_pv_first_cycle: VolatileCell<u32>,

        /// The last cycle PV should be asserted during program verify reads.
        read_pv_last_cycle: VolatileCell<u32>,

        /// The first cycle EV should be asserted during erase verify reads.
        read_ev_first_cycle: VolatileCell<u32>,

        /// The last cycle EV should be asserted during erase verify reads.
        read_ev_last_cycle: VolatileCell<u32>,

        /// Smart program algorithm enablement.
        enable_smart_program: VolatileCell<u32>,

        /// Single-word program timing.
        program_cycles: VolatileCell<u32>,

        /// The first cycle XE should be asserted during program.
        program_xe_first_cycle: VolatileCell<u32>,

        /// The last cycle XE should be asserted during program.
        program_xe_last_cycle: VolatileCell<u32>,

        /// The first cycle YE should be asserted during program.
        program_ye_first_cycle: VolatileCell<u32>,

        /// The last cycle YE should be asserted during program.
        program_ye_last_cycle: VolatileCell<u32>,

        /// The first cycle DIN and YADR are ready during program.
        program_din_yadr_first_cycle: VolatileCell<u32>,

        /// The last cycle DIN and YADR are ready during program.
        program_din_yadr_last_cycle: VolatileCell<u32>,

        /// The first cycle PROG should be asserted during program.
        program_prog_first_cycle: VolatileCell<u32>,

        /// The last cycle PROG should be asserted during program.
        program_prog_last_cycle: VolatileCell<u32>,

        /// The first cycle NVSTR should be asserted during program.
        program_nvstr_first_cycle: VolatileCell<u32>,

        /// The last cycle NVSTR should be asserted during program.
        program_nvstr_last_cycle: VolatileCell<u32>,

        /// Smart erase algorithm enablement.
        enable_smart_erase: VolatileCell<u32>,

        /// Flash erase cycle count.
        erase_cycles: VolatileCell<u32>,

        /// The first cycle XE should be asserted during erase.
        erase_xe_first_cycle: VolatileCell<u32>,

        /// The last cycle XE should be asserted during erase.
        erase_xe_last_cycle: VolatileCell<u32>,

        /// The first cycle ERASE should be asserted during erase.
        erase_erase_first_cycle: VolatileCell<u32>,

        /// The last cycle ERASE should be asserted during erase.
        erase_erase_last_cycle: VolatileCell<u32>,

        /// The first cycle NVSTR should be asserted during erase.
        erase_nvstr_first_cycle: VolatileCell<u32>,

        /// The last cycle NVSTR should be asserted during erase.
        erase_nvstr_last_cycle: VolatileCell<u32>,

        /// Enable smart erase for bulk erases.
        enable_bulk_smart_erase: VolatileCell<u32>,

        /// Duration of bulk erase operations.
        bulk_erase_cycles: VolatileCell<u32>,

        /// The first cycle XE should be asserted during bulkerase.
        bulkerase_xe_first_cycle: VolatileCell<u32>,

        /// The last cycle XE should be asserted during bulkerase.
        bulkerase_xe_last_cycle: VolatileCell<u32>,

        /// The first cycle BULKERASE should be asserted during bulkerase.
        bulkerase_bulkerase_first_cycle: VolatileCell<u32>,

        /// The last cycle BULKERASE should be asserted during bulkerase.
        bulkerase_bulkerase_last_cycle: VolatileCell<u32>,

        /// The first cycle MAS1 should be asserted during bulkerase.
        bulkerase_mas1_first_cycle: VolatileCell<u32>,

        /// The last cycle MAS1 should be asserted during bulkerase.
        bulkerase_mas1_last_cycle: VolatileCell<u32>,

        /// The first cycle NVSTR should be asserted during bulkerase.
        bulkerase_nvstr_first_cycle: VolatileCell<u32>,

        /// The last cycle NVSTR should be asserted during bulkerase.
        bulkerase_nvstr_last_cycle: VolatileCell<u32>,

        /// Controller debug signals.
        debug_signals: VolatileCell<u32>,

        // The integration test controls are omitted because they are unnecessary
        // and are after a large address space gap.
}

impl super::hardware::Hardware for H1bHw {
        fn is_programming(&self) -> bool {
                // TODO(jrvanwhy): Only checks the second flash bank.
                self.pe_control_1.get() != 0
        }

        fn read(&self, offset: usize) -> u32 {
            // The two flash macros are in consecutive memory locations, so they can
            // be addressed as one.
            if offset > H1B_FLASH_SIZE {
                0
            } else {
                unsafe { ::core::ptr::read_volatile((H1B_FLASH_START as *const u32).add(offset)) }
            }
        }

        fn read_error(&self) -> u16 {
                self.error_code.get() as u16
        }

        fn set_transaction(&self, offset: usize, size: usize) {
                use self::TransactionParameters::{Offset,Size};
                // The offset is relative to the beginning of the flash module. There
                // are 128 pages per flash module.
                // TODO(jrvanwhy): Assumes the read is from the second flash bank.
                if offset > H1B_FLASH_SIZE {
                   return; // TODO(pal): Fails silently!
                }

                let offset = offset - 128 * super::WORDS_PER_PAGE;
                self.transaction_parameters.write(Offset.val(offset as u32) + Size.val(size as u32));
        }

        fn set_write_data(&self, data: &[u32]) {
                for (i, &v) in data.iter().enumerate() { self.write_data[i].set(v); }
        }

        fn trigger(&self, opcode: u32) {
                self.program_erase_enable.set(0xb11924e1);
                // TODO(jrvanwhy): Assumes the write is to the second flash bank (where
                // the nvmem counter is).
                self.pe_control_1.set(opcode);
        }
}
<|endoftext|>


<commit_before>// Copyright 2020 Google LLC
//
// Use of this source code is governed by an MIT-style license that can be found
// in the LICENSE file or at https://opensource.org/licenses/MIT.

use std::path::PathBuf;

/// Interprets given bytes as an operating system path.
///
/// On Linux, the path is constructed from bytes as is since system paths can
/// be made of arbitrary sequence of bytes.
///
/// On Windows, the behaviour is unspecified (for now).
///
/// ```
/// use std::ffi::OsStr;
///
/// let path = rrg_proto::path::from_bytes(b"foo/bar/baz".to_vec());
///
/// let mut components = path.components()
///     .map(|component| component.as_os_str());
///
/// assert_eq!(components.next(), Some(OsStr::new("foo")));
/// assert_eq!(components.next(), Some(OsStr::new("bar")));
/// assert_eq!(components.next(), Some(OsStr::new("baz")));
/// assert_eq!(components.next(), None);
/// ```
pub fn from_bytes(bytes: Vec<u8>) -> PathBuf {
    from_bytes_impl(bytes)
}

/// Serializes given path to a byte sequence.
///
/// On Linux, the path is emitted as is since system paths can consist of
/// arbitrary bytes.
///
/// On Windows, the behaviour is unspecified (for now).
///
/// ```
/// use std::path::PathBuf;
///
/// let path = PathBuf::from("foo/bar/baz");
/// assert_eq!(rrg_proto::path::to_bytes(path), b"foo/bar/baz");
/// ```
pub fn to_bytes(path: PathBuf) -> Vec<u8> {
    to_bytes_impl(path)
}

#[cfg(target_family = "unix")]
fn from_bytes_impl(bytes: Vec<u8>) -> PathBuf {
    use std::os::unix::ffi::OsStringExt as _;
    std::ffi::OsString::from_vec(bytes).into()
}

#[cfg(target_family = "windows")]
fn from_bytes_impl(bytes: Vec<u8>) -> PathBuf {
    // TODO: This is just a quick hack that treats UTF-8-encoded strings as
    // UTF-16. This works for trivial cases but should be reworked once the GRR
    // protocol for paths is defined.
    let bytes_u16 = bytes.iter().map(|byte| *byte as u16).collect::<Vec<_>>();

    use std::os::windows::ffi::OsStringExt as _;
    std::ffi::OsString::from_wide(&bytes_u16).into()
}

#[cfg(target_family = "unix")]
fn to_bytes_impl(path: PathBuf) -> Vec<u8> {
    use std::os::unix::ffi::OsStringExt as _;
    std::ffi::OsString::from(path).into_vec()
}

#[cfg(target_family = "windows")]
fn to_bytes_impl(path: PathBuf) -> Vec<u8> {
    let string = std::ffi::OsString::from(path);

    // TODO: See explanation in `from_bytes_impl` on Windows.
    use std::os::windows::ffi::OsStrExt as _;
    string.as_os_str().encode_wide().map(|byte| byte as u8).collect()
}
<commit_msg>Add missing example headers in docs.<commit_after>// Copyright 2020 Google LLC
//
// Use of this source code is governed by an MIT-style license that can be found
// in the LICENSE file or at https://opensource.org/licenses/MIT.

use std::path::PathBuf;

/// Interprets given bytes as an operating system path.
///
/// On Linux, the path is constructed from bytes as is since system paths can
/// be made of arbitrary sequence of bytes.
///
/// On Windows, the behaviour is unspecified (for now).
///
/// # Examples
///
/// ```
/// use std::ffi::OsStr;
///
/// let path = rrg_proto::path::from_bytes(b"foo/bar/baz".to_vec());
///
/// let mut components = path.components()
///     .map(|component| component.as_os_str());
///
/// assert_eq!(components.next(), Some(OsStr::new("foo")));
/// assert_eq!(components.next(), Some(OsStr::new("bar")));
/// assert_eq!(components.next(), Some(OsStr::new("baz")));
/// assert_eq!(components.next(), None);
/// ```
pub fn from_bytes(bytes: Vec<u8>) -> PathBuf {
    from_bytes_impl(bytes)
}

/// Serializes given path to a byte sequence.
///
/// On Linux, the path is emitted as is since system paths can consist of
/// arbitrary bytes.
///
/// On Windows, the behaviour is unspecified (for now).
///
/// # Examples
///
/// ```
/// use std::path::PathBuf;
///
/// let path = PathBuf::from("foo/bar/baz");
/// assert_eq!(rrg_proto::path::to_bytes(path), b"foo/bar/baz");
/// ```
pub fn to_bytes(path: PathBuf) -> Vec<u8> {
    to_bytes_impl(path)
}

#[cfg(target_family = "unix")]
fn from_bytes_impl(bytes: Vec<u8>) -> PathBuf {
    use std::os::unix::ffi::OsStringExt as _;
    std::ffi::OsString::from_vec(bytes).into()
}

#[cfg(target_family = "windows")]
fn from_bytes_impl(bytes: Vec<u8>) -> PathBuf {
    // TODO: This is just a quick hack that treats UTF-8-encoded strings as
    // UTF-16. This works for trivial cases but should be reworked once the GRR
    // protocol for paths is defined.
    let bytes_u16 = bytes.iter().map(|byte| *byte as u16).collect::<Vec<_>>();

    use std::os::windows::ffi::OsStringExt as _;
    std::ffi::OsString::from_wide(&bytes_u16).into()
}

#[cfg(target_family = "unix")]
fn to_bytes_impl(path: PathBuf) -> Vec<u8> {
    use std::os::unix::ffi::OsStringExt as _;
    std::ffi::OsString::from(path).into_vec()
}

#[cfg(target_family = "windows")]
fn to_bytes_impl(path: PathBuf) -> Vec<u8> {
    let string = std::ffi::OsString::from(path);

    // TODO: See explanation in `from_bytes_impl` on Windows.
    use std::os::windows::ffi::OsStrExt as _;
    string.as_os_str().encode_wide().map(|byte| byte as u8).collect()
}
<|endoftext|>


<commit_before>use std::collections::hash_map::HashMap;
use js_types::js_type::{JsType, JsT};

pub struct JsObj {
    proto: Option<Box<JsObj>>,
    dict: HashMap<JsType, JsType>,
}

impl JsT for JsObj {}

impl JsObj {
    pub fn new() -> JsObj {
        JsObj {
            proto: None,
            dict: HashMap::new(),
        }
    }
}
<commit_msg>Add JsProto type alias and allow JsObj to take a vec of (k,v) pairs<commit_after>use std::collections::hash_map::HashMap;
use std::vec::Vec;
use js_types::js_type::{JsType, JsT};

pub type JsProto = Option<Box<JsObj>>;

macro_rules! hash_map {
    ( $( $k:expr => $v:expr),* ) => {{
            let mut temp_hash_map = HashMap::new();
            $(
                temp_hash_map.insert($k, $v);
            )*
            temp_hash_map
    }}
}

pub struct JsObj {
    proto: JsProto,
    dict: HashMap<JsType, JsType>,
}

impl JsT for JsObj {}

impl JsObj {
    pub fn new(proto: JsProto, kv_pairs: Vec<(JsType, JsType)>) -> JsObj {
        let mut obj_map = HashMap::new();
        kv_pairs.into_iter().map(|(k,v)| obj_map.insert(k, v));
        JsObj {
            proto: None,
            dict: obj_map,
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>Fix long lines, indents, etc.<commit_after><|endoftext|>


<commit_before>use cpu::common_defs::OpcodeExecInfo;
use cpu::CpuState;
use cpu::DecodeRegister;
use cpu::common_defs::address_mode::AddressMode;
use cpu::common_defs::opcode_class::OpcodeClass;
use memory::Memory;
use std::collections::HashMap;

pub struct CpuExecutor {
    op_table: HashMap<u8,OpcodeExecInfo>,
}

impl CpuExecutor {

	/// Construct a new CpuExecutor.
    pub fn new(opcodes: Vec<OpcodeExecInfo> ) -> CpuExecutor {
        // Construct the HashMap and copy it over to CpuExecutor's constructor.
        let mut op_table_temp: HashMap<u8, OpcodeExecInfo> = HashMap::new();
        for oc in opcodes {
            if op_table_temp.contains_key(&oc.opcode) {
                println!("Encountered duplicate opcode: {:#x}", oc.opcode);
                println!("Replacing previous opcode, which was {{ opcode: {:#x}, len: {}, cycles: {}, page_cycles: {} }}", oc.opcode, oc.len, oc.cycles, oc.page_cycles);
            }
            op_table_temp.insert(oc.opcode, oc);
        }

        CpuExecutor {
            op_table: op_table_temp,
        }
    }

	/// Reset the given cpu_state.
    pub fn power_on(self: &CpuExecutor, cpu_state: &mut CpuState, mem:&mut Memory) {
        self.reset(cpu_state,mem);
    }
	/// Reset the given cpu_state.
    pub fn reset(self: &CpuExecutor, cpu_state: &mut CpuState, mem:&mut Memory) {
        cpu_state.pc = mem.read16(0xFFFC).unwrap();
        cpu_state.sp = 0xFD;
        cpu_state.pack_flags(0x24);
    }

    /// Execute a single instruction in the given memory and cpu_state context.
    pub fn step(self: &CpuExecutor, cpu_state: &mut CpuState,mem:&mut Memory) {
        self.fetch_and_decode(cpu_state,mem);
        self.execute(cpu_state,mem);
    }

	/// Fetch the next instruction and perform address resolution.
    pub fn fetch_and_decode(self: &CpuExecutor, cpu_state: &mut CpuState,mem:&mut Memory) {
        cpu_state.instruction_register = mem.read8(cpu_state.pc).unwrap();
        cpu_state.decode_register = self.decode(cpu_state,mem);
        cpu_state.pc = cpu_state.pc+1;
    }

    /// Perform address resolution, returning the info in a DecodeRegister.
    fn decode(self: &CpuExecutor, cpu_state: &CpuState, mem: &Memory) -> DecodeRegister {
        let mut dr = DecodeRegister {
            info : self.op_table[&cpu_state.instruction_register].clone(),
            ..Default::default()
        };
        match dr.info.address_mode {
            // no explicit addresses for the following modes
            AddressMode::Accumulator  => { },
            AddressMode::Implied      => { },

            // explicit addresses from here on out
            AddressMode::Absolute => {
                dr.addr_final  = Some(mem.read16(cpu_state.pc+1).unwrap());
                dr.value_final = Some(mem.read8(dr.addr_final.unwrap()).unwrap());
            },
            AddressMode::AbsoluteX       => {
                dr.addr_final  = Some( ((mem.read16(cpu_state.pc+1).unwrap() as u32 + cpu_state.x as u32) % 65536) as u16);
                dr.value_final = Some(mem.read8(dr.addr_final.unwrap()).unwrap());
            },
            AddressMode::AbsoluteY       => {
                dr.addr_final  = Some( ((mem.read16(cpu_state.pc+1).unwrap() as u32 + cpu_state.y as u32) % 65536) as u16);
                dr.value_final = Some(mem.read8(dr.addr_final.unwrap()).unwrap());
            },
            AddressMode::Immediate       => {
                dr.addr_final  = Some(cpu_state.pc+1);
                dr.value_final = Some(mem.read8(dr.addr_final.unwrap()).unwrap());
            },
            AddressMode::Indirect        => {
                dr.addr_intermediate = Some(mem.read16(cpu_state.pc+1).unwrap());
                dr.addr_final        = Some(mem.read16(dr.addr_intermediate.unwrap()).unwrap());
            },
            AddressMode::IndexedIndirect => {
                dr.addr_intermediate = Some( (mem.read8(cpu_state.pc+1).unwrap() + cpu_state.x) as u16);
                dr.addr_final        = Some(mem.read16(dr.addr_intermediate.unwrap()).unwrap());
                dr.value_final       = Some(mem.read8(dr.addr_final.unwrap()).unwrap());
            },
            AddressMode::IndirectIndexed => {
                dr.addr_init         = Some(mem.read8(cpu_state.pc+1).unwrap() as u16);
                dr.addr_intermediate = Some(mem.read16(dr.addr_init.unwrap()).unwrap());
                dr.addr_final        = Some( ((dr.addr_intermediate.unwrap() as u32 + cpu_state.y as u32) % 65536) as u16);
                dr.value_final       = Some(mem.read8(dr.addr_final.unwrap()).unwrap());
            },
            AddressMode::Relative        => {
                dr.addr_final  = Some(cpu_state.pc+1);
                dr.value_final = Some(mem.read8(dr.addr_final.unwrap()).unwrap());
            },
            AddressMode::ZeroPage        => {
                dr.addr_final  = Some(mem.read8(cpu_state.pc+1).unwrap() as u16);
                dr.value_final = Some(mem.read8(dr.addr_final.unwrap()).unwrap());
            },
            AddressMode::ZeroPageX       => {
                dr.addr_final  = Some( (mem.read8(cpu_state.pc+1).unwrap() as u16 + cpu_state.x as u16) % 256);
                dr.value_final = Some(mem.read8(dr.addr_final.unwrap()).unwrap());
            },
            AddressMode::ZeroPageY       => {
                dr.addr_final  = Some( (mem.read8(cpu_state.pc+1).unwrap() as u16 + cpu_state.y as u16) % 256);
                dr.value_final = Some(mem.read8(dr.addr_final.unwrap()).unwrap());
            },
            _ => panic!("unrecognized addressing mode while decoding instruction_register!")
        }

        return dr;
    }

    /// Perform the current instruction, returning the CpuState after execution.
    pub fn execute(self: &CpuExecutor, cpu_state: &mut CpuState, mem:&mut Memory) {
    	// Figure out which opcode is being executed.
    	let ref decode_register = cpu_state.decode_register;

    	match decode_register.info.opcode_class {
    		// Arithmetic Shift Left
    		OpcodeClass::ASL => {
				cpu_state.a = cpu_state.a << 1;
				cpu_state.C = (128 & cpu_state.a) > 0;
    			if cpu_state.a == 0 { cpu_state.Z = true; }

                cpu_state.pc = cpu_state.pc + (decode_register.info.len as u16 -1);
    		},
    		// Load Accumulator
    		OpcodeClass::LDA => {
    			cpu_state.a = decode_register.value_final.unwrap();
                cpu_state.pc = cpu_state.pc + (decode_register.info.len as u16 -1);
    		},
    		// Load X
    		OpcodeClass::LDX => {
    			cpu_state.x = decode_register.value_final.unwrap();
                cpu_state.pc = cpu_state.pc + (decode_register.info.len as u16 -1);
    		},
    		// Load Y
    		OpcodeClass::LDY => {
    			cpu_state.y = decode_register.value_final.unwrap();
                cpu_state.pc = cpu_state.pc + (decode_register.info.len as u16 -1);
    		},
    		// Logical Shift Right
    		OpcodeClass::LSR => {
    			cpu_state.a = cpu_state.a >> 1;
    			cpu_state.C = 1 & cpu_state.a > 0;
    			if cpu_state.a == 0 { cpu_state.Z = true; }

                cpu_state.pc = cpu_state.pc + (decode_register.info.len as u16 -1);
    		},
    		// Jump
    		OpcodeClass::JMP => {
    			cpu_state.pc = decode_register.addr_final.unwrap();
    		},
    		// NOP (No Operation)
    		OpcodeClass::NOP => {},
    		// Store X
    		OpcodeClass::STX => {
                mem.write8(decode_register.addr_final.unwrap(),decode_register.value_final.unwrap());
                cpu_state.pc = cpu_state.pc + (decode_register.info.len as u16 -1);
    		},

    		// Default: not sure what this opcode is.
			_ => panic!("Unrecognised opcode class: {:?}", decode_register.info.opcode_class)

    	}
    }
}

<commit_msg>fixed issue with LDX not setting the cpu flags properly<commit_after>use cpu::common_defs::OpcodeExecInfo;
use cpu::CpuState;
use cpu::DecodeRegister;
use cpu::common_defs::address_mode::AddressMode;
use cpu::common_defs::opcode_class::OpcodeClass;
use memory::Memory;
use std::collections::HashMap;

macro_rules! set_zs {
    ($cpu_state:expr,$val:expr) => ($cpu_state.Z = $val == 0;$cpu_state.S = $val >= 0x80 );
}

pub struct CpuExecutor {
    op_table: HashMap<u8,OpcodeExecInfo>,
}

impl CpuExecutor {

	/// Construct a new CpuExecutor.
    pub fn new(opcodes: Vec<OpcodeExecInfo> ) -> CpuExecutor {
        // Construct the HashMap and copy it over to CpuExecutor's constructor.
        let mut op_table_temp: HashMap<u8, OpcodeExecInfo> = HashMap::new();
        for oc in opcodes {
            if op_table_temp.contains_key(&oc.opcode) {
                println!("Encountered duplicate opcode: {:#x}", oc.opcode);
                println!("Replacing previous opcode, which was {{ opcode: {:#x}, len: {}, cycles: {}, page_cycles: {} }}", oc.opcode, oc.len, oc.cycles, oc.page_cycles);
            }
            op_table_temp.insert(oc.opcode, oc);
        }

        CpuExecutor {
            op_table: op_table_temp,
        }
    }

	/// Reset the given cpu_state.
    pub fn power_on(self: &CpuExecutor, cpu_state: &mut CpuState, mem:&mut Memory) {
        self.reset(cpu_state,mem);
    }
	/// Reset the given cpu_state.
    pub fn reset(self: &CpuExecutor, cpu_state: &mut CpuState, mem:&mut Memory) {
        cpu_state.pc = mem.read16(0xFFFC).unwrap();
        cpu_state.sp = 0xFD;
        cpu_state.pack_flags(0x24);
    }

    /// Execute a single instruction in the given memory and cpu_state context.
    pub fn step(self: &CpuExecutor, cpu_state: &mut CpuState,mem:&mut Memory) {
        self.fetch_and_decode(cpu_state,mem);
        self.execute(cpu_state,mem);
    }

	/// Fetch the next instruction and perform address resolution.
    pub fn fetch_and_decode(self: &CpuExecutor, cpu_state: &mut CpuState,mem:&mut Memory) {
        cpu_state.instruction_register = mem.read8(cpu_state.pc).unwrap();
        cpu_state.decode_register = self.decode(cpu_state,mem);
        cpu_state.pc = cpu_state.pc+1;
    }

    /// Perform address resolution, returning the info in a DecodeRegister.
    fn decode(self: &CpuExecutor, cpu_state: &CpuState, mem: &Memory) -> DecodeRegister {
        let mut dr = DecodeRegister {
            info : self.op_table[&cpu_state.instruction_register].clone(),
            ..Default::default()
        };
        match dr.info.address_mode {
            // no explicit addresses for the following modes
            AddressMode::Accumulator  => { },
            AddressMode::Implied      => { },

            // explicit addresses from here on out
            AddressMode::Absolute => {
                dr.addr_final  = Some(mem.read16(cpu_state.pc+1).unwrap());
                dr.value_final = Some(mem.read8(dr.addr_final.unwrap()).unwrap());
            },
            AddressMode::AbsoluteX       => {
                dr.addr_final  = Some( ((mem.read16(cpu_state.pc+1).unwrap() as u32 + cpu_state.x as u32) % 65536) as u16);
                dr.value_final = Some(mem.read8(dr.addr_final.unwrap()).unwrap());
            },
            AddressMode::AbsoluteY       => {
                dr.addr_final  = Some( ((mem.read16(cpu_state.pc+1).unwrap() as u32 + cpu_state.y as u32) % 65536) as u16);
                dr.value_final = Some(mem.read8(dr.addr_final.unwrap()).unwrap());
            },
            AddressMode::Immediate       => {
                dr.addr_final  = Some(cpu_state.pc+1);
                dr.value_final = Some(mem.read8(dr.addr_final.unwrap()).unwrap());
            },
            AddressMode::Indirect        => {
                dr.addr_intermediate = Some(mem.read16(cpu_state.pc+1).unwrap());
                dr.addr_final        = Some(mem.read16(dr.addr_intermediate.unwrap()).unwrap());
            },
            AddressMode::IndexedIndirect => {
                dr.addr_intermediate = Some( (mem.read8(cpu_state.pc+1).unwrap() + cpu_state.x) as u16);
                dr.addr_final        = Some(mem.read16(dr.addr_intermediate.unwrap()).unwrap());
                dr.value_final       = Some(mem.read8(dr.addr_final.unwrap()).unwrap());
            },
            AddressMode::IndirectIndexed => {
                dr.addr_init         = Some(mem.read8(cpu_state.pc+1).unwrap() as u16);
                dr.addr_intermediate = Some(mem.read16(dr.addr_init.unwrap()).unwrap());
                dr.addr_final        = Some( ((dr.addr_intermediate.unwrap() as u32 + cpu_state.y as u32) % 65536) as u16);
                dr.value_final       = Some(mem.read8(dr.addr_final.unwrap()).unwrap());
            },
            AddressMode::Relative        => {
                dr.addr_final  = Some(cpu_state.pc+1);
                dr.value_final = Some(mem.read8(dr.addr_final.unwrap()).unwrap());
            },
            AddressMode::ZeroPage        => {
                dr.addr_final  = Some(mem.read8(cpu_state.pc+1).unwrap() as u16);
                dr.value_final = Some(mem.read8(dr.addr_final.unwrap()).unwrap());
            },
            AddressMode::ZeroPageX       => {
                dr.addr_final  = Some( (mem.read8(cpu_state.pc+1).unwrap() as u16 + cpu_state.x as u16) % 256);
                dr.value_final = Some(mem.read8(dr.addr_final.unwrap()).unwrap());
            },
            AddressMode::ZeroPageY       => {
                dr.addr_final  = Some( (mem.read8(cpu_state.pc+1).unwrap() as u16 + cpu_state.y as u16) % 256);
                dr.value_final = Some(mem.read8(dr.addr_final.unwrap()).unwrap());
            },
            _ => panic!("unrecognized addressing mode while decoding instruction_register!")
        }

        return dr;
    }

    /// Perform the current instruction, returning the CpuState after execution.
    pub fn execute(self: &CpuExecutor, cpu_state: &mut CpuState, mem:&mut Memory) {
    	// Figure out which opcode is being executed.
    	match cpu_state.decode_register.info.opcode_class {
    		OpcodeClass::ASL => {
				cpu_state.a = cpu_state.a << 1;
				cpu_state.C = (128 & cpu_state.a) > 0;
    			if cpu_state.a == 0 { cpu_state.Z = true; }

                cpu_state.pc = cpu_state.pc + (cpu_state.decode_register.info.len as u16 -1);
    		},
    		OpcodeClass::LDA => {
    			cpu_state.a = cpu_state.decode_register.value_final.unwrap();
                set_zs!(cpu_state,cpu_state.a);

                //let tup = self.get_zs(cpu_state.a); cpu_state.Z = tup.0; cpu_state.S = tup.1;
                 //match self.get_zs(cpu_state.a) {
                     //(z,s) => { cpu_state.Z = z; cpu_state.S = s;}
                 //}

                cpu_state.pc = cpu_state.pc + (cpu_state.decode_register.info.len as u16 -1);
    		},
    		OpcodeClass::LDX => {
    			cpu_state.x = cpu_state.decode_register.value_final.unwrap();
                set_zs!(cpu_state,cpu_state.x);

                cpu_state.pc = cpu_state.pc + (cpu_state.decode_register.info.len as u16 -1);
    		},
    		OpcodeClass::LDY => {
    			cpu_state.y = cpu_state.decode_register.value_final.unwrap();
                set_zs!(cpu_state,cpu_state.y);

                cpu_state.pc = cpu_state.pc + (cpu_state.decode_register.info.len as u16 -1);
    		},
    		OpcodeClass::LSR => {
    			cpu_state.a = cpu_state.a >> 1;
    			cpu_state.C = 1 & cpu_state.a > 0;
    			if cpu_state.a == 0 { cpu_state.Z = true; }

                cpu_state.pc = cpu_state.pc + (cpu_state.decode_register.info.len as u16 -1);
    		},
    		OpcodeClass::JMP => {
    			cpu_state.pc = cpu_state.decode_register.addr_final.unwrap();
    		},
    		OpcodeClass::NOP => {},
    		OpcodeClass::STX => {
                mem.write8(cpu_state.decode_register.addr_final.unwrap(),cpu_state.decode_register.value_final.unwrap());
                cpu_state.pc = cpu_state.pc + (cpu_state.decode_register.info.len as u16 -1);
    		},

    		// Default: not sure what this opcode is.
			_ => panic!("Unrecognised opcode class: {:?}", cpu_state.decode_register.info.opcode_class)

    	}
    }
}

<|endoftext|>


<commit_before>use hyper::Client;
use super::helper::KinesisHelper;
use utils::screen::Screen;
use utils::screen::Status;

use rusoto::{
    DefaultCredentialsProvider,
    Region
};

enum State {
    Root,
    End,
    StreamList(Vec<String>),
    ShardList(String, Vec<String>),
    RecordList(String),  // iterator_id, records
    Record(String, String), // itrator_id, record
}

pub fn run(credential_provider: DefaultCredentialsProvider, client: Client, region: Region) {

    let kinesis_helper = KinesisHelper::new(client, credential_provider, region);
    let mut screen: Screen = Screen::new();
    let mut state: State = State::Root;

    loop {

        state = match state {

            State::Root                           => root(screen, kinesis_helper),
            State::StreamList(streams)            => stream_list(screen, kinesis_helper, streams),
            State::ShardList(stream_name, shards) => shared_list(screen, kinesis_helper, stream_name, shards),
            State::RecordList(shard_iterator) => {

                match kinesis_helper.get_records(&shard_iterator) {

                    Ok((results, iterator)) => {

                        screen.update_screen("🍓  Kinesis > Streams > Shards > Records",
                                             &kinesis_helper.decode_records(&results));

                        match screen.select_line() {
                            Status::Error | Status::Quit => State::End,
                            Status::Selected(ref c) if c == "n" => {
                                match iterator {
                                    Some(iterator) => State::RecordList(iterator),
                                    None => State::Root
                                }
                            },
                            Status::Selected(ref record) => State::Record(shard_iterator, record.to_string()),
                            _ => State::Root
                        }
                    },
                    Err(e) => State::Root,
                }
            },
            State::Record(shard_iterator, record) => {

                screen.update_screen("🍓  Kinesis > Streams > Shards > Records > Record", &vec!(String::new()));

                match screen.render(&kinesis_helper.format_record(&record)) {
                    Status::Error | Status::Quit => State::End,
                    Status::Escaped  => State::RecordList(shard_iterator),
                    _ => State::Root
                }
            }
            State::End => {
                break;
            }
        };

    }
}

fn root(screen: &mut Screen, kinesis_helper: &KinesisHelper) -> State {

    let commands = vec!["l".to_string(), "q".to_string()];
    screen.update_screen("🍓  Kinesis", &commands);

    match screen.select_line() {
        Status::Error | Status::Quit => State::End,
        Status::Selected(ref c) if c == "l" => {
            match kinesis_helper.list_streams() {
                Ok(streams) => State::StreamList(streams),
                Err(e) =>  State::Root
            }
        }
        _ => State::Root
    }
}

fn stream_list(screen: &mut Screen, kinesis_helper: &KinesisHelper, stream: Vec<String>) -> State {

    screen.update_screen("🍓  Kinesis > Streams", &streams);

    match screen.select_line() {
        Status::Error | Status::Quit => State::End,
        Status::Selected(stream_name) => {
            match kinesis_helper.describe_shards(&stream_name) {
                Ok(shards) => State::ShardList(stream_name.to_string(), shards),
                Err(e) => State::Root,
            }
        }
        _ => State::Root
    }
}

fn shared_list(screen: &mut Screen, kinesis_helper: &KinesisHelper, stream_name: &str, shards: Vec<String>) -> State {

    screen.update_screen("🍓  Kinesis > Streams > Shards", &shards);

    match screen.select_line() {
        Status::Error | Status::Quit => State::End,
        Status::Selected(shard_id) => {
            match kinesis_helper.get_shard_iterator(&stream_name, &shard_id) {
                Ok(shard_iterator) => State::RecordList(shard_iterator),
                Err(e) => State::Root,
            }
        }
        _ => State::Root
    }

}
<commit_msg>Update<commit_after>use hyper::Client;
use super::helper::KinesisHelper;
use utils::screen::Screen;
use utils::screen::Status;

use rusoto::{
    DefaultCredentialsProvider,
    Region
};

enum State {
    Root,
    End,
    StreamList(Vec<String>),
    ShardList(String, Vec<String>),
    RecordList(String),  // iterator_id, records
    Record(String, String), // itrator_id, record
}

pub fn run(credential_provider: DefaultCredentialsProvider, client: Client, region: Region) {

    let kinesis_helper = KinesisHelper::new(client, credential_provider, region);
    let mut screen: Screen = Screen::new();
    let mut state: State = State::Root;

    loop {
        state = match state {
            State::Root                           => root(&screen, &kinesis_helper),
            State::StreamList(streams)            => stream_list(&screen, &kinesis_helper, streams),
            State::ShardList(stream_name, shards) => shared_list(&screen, &kinesis_helper, stream_name, shards),
            State::RecordList(shard_iterator)     => record_list(&screen, &kinesis_helper, shard_iterator),
            State::Record(shard_iterator, record) => record(&screen, &kinesis_helper, shard_iterator, record),
            State::End => {
                break;
            }
        };
    }
}

fn root(screen: &mut Screen, kinesis_helper: &KinesisHelper) -> State {

    let commands = vec!["l".to_string(), "q".to_string()];
    screen.update_screen("🍓  Kinesis", &commands);

    match screen.select_line() {
        Status::Error | Status::Quit => State::End,
        Status::Selected(ref c) if c == "l" => {
            match kinesis_helper.list_streams() {
                Ok(streams) => State::StreamList(streams),
                Err(e) =>  State::Root
            }
        }
        _ => State::Root
    }
}

fn stream_list(screen: &mut Screen, kinesis_helper: &KinesisHelper, streams: Vec<String>) -> State {

    screen.update_screen("🍓  Kinesis > Streams", &streams);

    match screen.select_line() {
        Status::Error | Status::Quit => State::End,
        Status::Selected(stream_name) => {
            match kinesis_helper.describe_shards(&stream_name) {
                Ok(shards) => State::ShardList(stream_name.to_string(), shards),
                Err(e) => State::Root,
            }
        }
        _ => State::Root
    }
}

fn shared_list(screen: &mut Screen, kinesis_helper: &KinesisHelper, stream_name: &str, shards: Vec<String>) -> State {

    screen.update_screen("🍓  Kinesis > Streams > Shards", &shards);

    match screen.select_line() {
        Status::Error | Status::Quit => State::End,
        Status::Selected(shard_id) => {
            match kinesis_helper.get_shard_iterator(&stream_name, &shard_id) {
                Ok(shard_iterator) => State::RecordList(shard_iterator),
                Err(e) => State::Root,
            }
        }
        _ => State::Root
    }

}

fn record_list(screen: &mut Screen, kinesis_helper: &KinesisHelper, shard_iterator: String) -> State {

    match kinesis_helper.get_records(&shard_iterator) {

        Ok((results, iterator)) => {

            screen.update_screen("🍓  Kinesis > Streams > Shards > Records",
                                 &kinesis_helper.decode_records(&results));

            match screen.select_line() {
                Status::Error | Status::Quit => State::End,
                Status::Selected(ref c) if c == "n" => {
                    match iterator {
                        Some(iterator) => State::RecordList(iterator),
                        None => State::Root
                    }
                },
                Status::Selected(ref record) => State::Record(&shard_iterator, record.to_string()),
                _ => State::Root
            }
        },
        Err(e) => State::Root,
    }
}

fn record(screen: &mut Screen, kinesis_helper: &KinesisHelper, shard_iterator: String, record: String) -> State {
    screen.update_screen("🍓  Kinesis > Streams > Shards > Records > Record", &vec!(String::new()));

    match screen.render(&kinesis_helper.format_record(&record)) {
        Status::Error | Status::Quit => State::End,
        Status::Escaped  => State::RecordList(shard_iterator),
        _ => State::Root
    }
}
<|endoftext|>