<commit_before>// Copyright (c) 2016 The vulkano developers
// Licensed under the Apache License, Version 2.0
// <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT
// license <LICENSE-MIT or http://opensource.org/licenses/MIT>,
// at your option. All files in the project carrying such
// notice may not be copied, modified, or distributed except
// according to those terms.

use vk;

/// Describes how a buffer is going to be used. This is **not** an optimization.
///
/// If you try to use a buffer in a way that you didn't declare, a panic will happen.
///
/// Some methods are provided to build `BufferUsage` structs for some common situations. However
/// there is no restriction in the combination of BufferUsages that can be enabled.
#[derive(Debug, Copy, Clone)]
pub struct BufferUsage {
    pub transfer_source: bool,
    pub transfer_dest: bool,
    pub uniform_texel_buffer: bool,
    pub storage_texel_buffer: bool,
    pub uniform_buffer: bool,
    pub storage_buffer: bool,
    pub index_buffer: bool,
    pub vertex_buffer: bool,
    pub indirect_buffer: bool,
}

impl BufferUsage {
    /// Builds a `BufferUsage` with all values set to false.
    #[inline]
    pub fn none() -> BufferUsage {
        BufferUsage {
            transfer_source: false,
            transfer_dest: false,
            uniform_texel_buffer: false,
            storage_texel_buffer: false,
            uniform_buffer: false,
            storage_buffer: false,
            index_buffer: false,
            vertex_buffer: false,
            indirect_buffer: false,
        }
    }

    /// Builds a `BufferUsage` with all values set to true. Can be used for quick prototyping.
    #[inline]
    pub fn all() -> BufferUsage {
        BufferUsage {
            transfer_source: true,
            transfer_dest: true,
            uniform_texel_buffer: true,
            storage_texel_buffer: true,
            uniform_buffer: true,
            storage_buffer: true,
            index_buffer: true,
            vertex_buffer: true,
            indirect_buffer: true,
        }
    }

    /// Builds a `BufferUsage` with `transfer_source` set to true and the rest to false.
    #[inline]
    pub fn transfer_source() -> BufferUsage {
        BufferUsage {
            transfer_source: true,
            .. BufferUsage::none()
        }
    }

    /// Builds a `BufferUsage` with `transfer_dest` set to true and the rest to false.
    #[inline]
    pub fn transfer_dest() -> BufferUsage {
        BufferUsage {
            transfer_dest: true,
            .. BufferUsage::none()
        }
    }

    /// Builds a `BufferUsage` with `vertex_buffer` set to true and the rest to false.
    #[inline]
    pub fn vertex_buffer() -> BufferUsage {
        BufferUsage {
            vertex_buffer: true,
            .. BufferUsage::none()
        }
    }

    /// Builds a `BufferUsage` with `vertex_buffer` and `transfer_dest` set to true and the rest
    /// to false.
    #[inline]
    pub fn vertex_buffer_transfer_dest() -> BufferUsage {
        BufferUsage {
            vertex_buffer: true,
            transfer_dest: true,
            .. BufferUsage::none()
        }
    }

    /// Builds a `BufferUsage` with `index_buffer` set to true and the rest to false.
    #[inline]
    pub fn index_buffer() -> BufferUsage {
        BufferUsage {
            index_buffer: true,
            .. BufferUsage::none()
        }
    }

    /// Builds a `BufferUsage` with `index_buffer` and `transfer_dest` set to true and the rest to false.
    #[inline]
    pub fn index_buffer_transfer_dest() -> BufferUsage {
        BufferUsage {
            index_buffer: true,
            transfer_dest: true,
            .. BufferUsage::none()
        }
    }

    /// Builds a `BufferUsage` with `uniform_buffer` set to true and the rest to false.
    #[inline]
    pub fn uniform_buffer() -> BufferUsage {
        BufferUsage {
            uniform_buffer: true,
            .. BufferUsage::none()
        }
    }

    /// Builds a `BufferUsage` with `uniform_buffer` and `transfer_dest` set to true and the rest
    /// to false.
    #[inline]
    pub fn uniform_buffer_transfer_dest() -> BufferUsage {
        BufferUsage {
            uniform_buffer: true,
            transfer_dest: true,
            .. BufferUsage::none()
        }
    }

    /// Builds a `BufferUsage` with `indirect_buffer` set to true and the rest to false.
    #[inline]
    pub fn indirect_buffer() -> BufferUsage {
        BufferUsage {
            indirect_buffer: true,
            .. BufferUsage::none()
        }
    }

    /// Builds a `BufferUsage` with `indirect_buffer` and `transfer_dest` set to true and the rest
    /// to false.
    #[inline]
    pub fn indirect_buffer_transfer_dest() -> BufferUsage {
        BufferUsage {
            indirect_buffer: true,
            transfer_dest: true,
            .. BufferUsage::none()
        }
    }
}

/// Turns a `BufferUsage` into raw bits.
#[inline]
pub fn usage_to_bits(usage: &BufferUsage) -> vk::BufferUsageFlagBits {
    let mut result = 0;
    if usage.transfer_source { result |= vk::BUFFER_USAGE_TRANSFER_SRC_BIT; }
    if usage.transfer_dest { result |= vk::BUFFER_USAGE_TRANSFER_DST_BIT; }
    if usage.uniform_texel_buffer { result |= vk::BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT; }
    if usage.storage_texel_buffer { result |= vk::BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT; }
    if usage.uniform_buffer { result |= vk::BUFFER_USAGE_UNIFORM_BUFFER_BIT; }
    if usage.storage_buffer { result |= vk::BUFFER_USAGE_STORAGE_BUFFER_BIT; }
    if usage.index_buffer { result |= vk::BUFFER_USAGE_INDEX_BUFFER_BIT; }
    if usage.vertex_buffer { result |= vk::BUFFER_USAGE_VERTEX_BUFFER_BIT; }
    if usage.indirect_buffer { result |= vk::BUFFER_USAGE_INDIRECT_BUFFER_BIT; }
    result
}
<commit_msg>Implement BitOr for BufferUsage<commit_after>// Copyright (c) 2016 The vulkano developers
// Licensed under the Apache License, Version 2.0
// <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT
// license <LICENSE-MIT or http://opensource.org/licenses/MIT>,
// at your option. All files in the project carrying such
// notice may not be copied, modified, or distributed except
// according to those terms.

use std::ops::BitOr;
use vk;

/// Describes how a buffer is going to be used. This is **not** an optimization.
///
/// If you try to use a buffer in a way that you didn't declare, a panic will happen.
///
/// Some methods are provided to build `BufferUsage` structs for some common situations. However
/// there is no restriction in the combination of BufferUsages that can be enabled.
#[derive(Debug, Copy, Clone)]
pub struct BufferUsage {
    pub transfer_source: bool,
    pub transfer_dest: bool,
    pub uniform_texel_buffer: bool,
    pub storage_texel_buffer: bool,
    pub uniform_buffer: bool,
    pub storage_buffer: bool,
    pub index_buffer: bool,
    pub vertex_buffer: bool,
    pub indirect_buffer: bool,
}

impl BufferUsage {
    /// Builds a `BufferUsage` with all values set to false.
    #[inline]
    pub fn none() -> BufferUsage {
        BufferUsage {
            transfer_source: false,
            transfer_dest: false,
            uniform_texel_buffer: false,
            storage_texel_buffer: false,
            uniform_buffer: false,
            storage_buffer: false,
            index_buffer: false,
            vertex_buffer: false,
            indirect_buffer: false,
        }
    }

    /// Builds a `BufferUsage` with all values set to true. Can be used for quick prototyping.
    #[inline]
    pub fn all() -> BufferUsage {
        BufferUsage {
            transfer_source: true,
            transfer_dest: true,
            uniform_texel_buffer: true,
            storage_texel_buffer: true,
            uniform_buffer: true,
            storage_buffer: true,
            index_buffer: true,
            vertex_buffer: true,
            indirect_buffer: true,
        }
    }

    /// Builds a `BufferUsage` with `transfer_source` set to true and the rest to false.
    #[inline]
    pub fn transfer_source() -> BufferUsage {
        BufferUsage {
            transfer_source: true,
            .. BufferUsage::none()
        }
    }

    /// Builds a `BufferUsage` with `transfer_dest` set to true and the rest to false.
    #[inline]
    pub fn transfer_dest() -> BufferUsage {
        BufferUsage {
            transfer_dest: true,
            .. BufferUsage::none()
        }
    }

    /// Builds a `BufferUsage` with `vertex_buffer` set to true and the rest to false.
    #[inline]
    pub fn vertex_buffer() -> BufferUsage {
        BufferUsage {
            vertex_buffer: true,
            .. BufferUsage::none()
        }
    }

    /// Builds a `BufferUsage` with `vertex_buffer` and `transfer_dest` set to true and the rest
    /// to false.
    #[inline]
    pub fn vertex_buffer_transfer_dest() -> BufferUsage {
        BufferUsage {
            vertex_buffer: true,
            transfer_dest: true,
            .. BufferUsage::none()
        }
    }

    /// Builds a `BufferUsage` with `index_buffer` set to true and the rest to false.
    #[inline]
    pub fn index_buffer() -> BufferUsage {
        BufferUsage {
            index_buffer: true,
            .. BufferUsage::none()
        }
    }

    /// Builds a `BufferUsage` with `index_buffer` and `transfer_dest` set to true and the rest to false.
    #[inline]
    pub fn index_buffer_transfer_dest() -> BufferUsage {
        BufferUsage {
            index_buffer: true,
            transfer_dest: true,
            .. BufferUsage::none()
        }
    }

    /// Builds a `BufferUsage` with `uniform_buffer` set to true and the rest to false.
    #[inline]
    pub fn uniform_buffer() -> BufferUsage {
        BufferUsage {
            uniform_buffer: true,
            .. BufferUsage::none()
        }
    }

    /// Builds a `BufferUsage` with `uniform_buffer` and `transfer_dest` set to true and the rest
    /// to false.
    #[inline]
    pub fn uniform_buffer_transfer_dest() -> BufferUsage {
        BufferUsage {
            uniform_buffer: true,
            transfer_dest: true,
            .. BufferUsage::none()
        }
    }

    /// Builds a `BufferUsage` with `indirect_buffer` set to true and the rest to false.
    #[inline]
    pub fn indirect_buffer() -> BufferUsage {
        BufferUsage {
            indirect_buffer: true,
            .. BufferUsage::none()
        }
    }

    /// Builds a `BufferUsage` with `indirect_buffer` and `transfer_dest` set to true and the rest
    /// to false.
    #[inline]
    pub fn indirect_buffer_transfer_dest() -> BufferUsage {
        BufferUsage {
            indirect_buffer: true,
            transfer_dest: true,
            .. BufferUsage::none()
        }
    }
}

impl BitOr for BufferUsage {
    type Output = Self;

    #[inline]
    fn bitor(self, rhs: Self) -> Self {
        BufferUsage {
            transfer_source: self.transfer_source || rhs.transfer_source,
            transfer_dest: self.transfer_dest || rhs.transfer_dest,
            uniform_texel_buffer: self.uniform_texel_buffer || rhs.uniform_texel_buffer,
            storage_texel_buffer: self.storage_texel_buffer || rhs.storage_texel_buffer,
            uniform_buffer: self.uniform_buffer || rhs.uniform_buffer,
            storage_buffer: self.storage_buffer || rhs.storage_buffer,
            index_buffer: self.index_buffer || rhs.index_buffer,
            vertex_buffer: self.vertex_buffer || rhs.vertex_buffer,
            indirect_buffer: self.indirect_buffer || rhs.indirect_buffer,
        }
    }
}

/// Turns a `BufferUsage` into raw bits.
#[inline]
pub fn usage_to_bits(usage: &BufferUsage) -> vk::BufferUsageFlagBits {
    let mut result = 0;
    if usage.transfer_source { result |= vk::BUFFER_USAGE_TRANSFER_SRC_BIT; }
    if usage.transfer_dest { result |= vk::BUFFER_USAGE_TRANSFER_DST_BIT; }
    if usage.uniform_texel_buffer { result |= vk::BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT; }
    if usage.storage_texel_buffer { result |= vk::BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT; }
    if usage.uniform_buffer { result |= vk::BUFFER_USAGE_UNIFORM_BUFFER_BIT; }
    if usage.storage_buffer { result |= vk::BUFFER_USAGE_STORAGE_BUFFER_BIT; }
    if usage.index_buffer { result |= vk::BUFFER_USAGE_INDEX_BUFFER_BIT; }
    if usage.vertex_buffer { result |= vk::BUFFER_USAGE_VERTEX_BUFFER_BIT; }
    if usage.indirect_buffer { result |= vk::BUFFER_USAGE_INDIRECT_BUFFER_BIT; }
    result
}
<|endoftext|>


<commit_before>//! `hermit-abi` is small interface to call functions from the unikernel
//! [RustyHermit](https://github.com/hermitcore/libhermit-rs).

#![cfg_attr(feature = "rustc-dep-of-std", no_std)]
#![feature(const_raw_ptr_to_usize_cast)]
extern crate libc;

pub mod tcpstream;

use libc::c_void;

// sysmbols, which are part of the library operating system
extern "C" {
	fn sys_get_processor_count() -> usize;
	fn sys_malloc(size: usize, align: usize) -> *mut u8;
	fn sys_realloc(ptr: *mut u8, size: usize, align: usize, new_size: usize) -> *mut u8;
	fn sys_free(ptr: *mut u8, size: usize, align: usize);
	fn sys_notify(id: usize, count: i32) -> i32;
	fn sys_add_queue(id: usize, timeout_ns: i64) -> i32;
	fn sys_wait(id: usize) -> i32;
	fn sys_destroy_queue(id: usize) -> i32;
	fn sys_read(fd: i32, buf: *mut u8, len: usize) -> isize;
	fn sys_write(fd: i32, buf: *const u8, len: usize) -> isize;
	fn sys_close(fd: i32) -> i32;
	fn sys_sem_init(sem: *mut *const c_void, value: u32) -> i32;
	fn sys_sem_destroy(sem: *const c_void) -> i32;
	fn sys_sem_post(sem: *const c_void) -> i32;
	fn sys_sem_trywait(sem: *const c_void) -> i32;
	fn sys_sem_timedwait(sem: *const c_void, ms: u32) -> i32;
	fn sys_recmutex_init(recmutex: *mut *const c_void) -> i32;
	fn sys_recmutex_destroy(recmutex: *const c_void) -> i32;
	fn sys_recmutex_lock(recmutex: *const c_void) -> i32;
	fn sys_recmutex_unlock(recmutex: *const c_void) -> i32;
	fn sys_getpid() -> u32;
	fn sys_exit(arg: i32) -> !;
	fn sys_abort() -> !;
	fn sys_usleep(usecs: u64);
	fn sys_spawn(
		id: *mut Tid,
		func: extern "C" fn(usize),
		arg: usize,
		prio: u8,
		core_id: isize,
	) -> i32;
	fn sys_spawn2(
		func: extern "C" fn(usize),
		arg: usize,
		prio: u8,
		stack_size: usize,
		core_id: isize,
	) -> Tid;
	fn sys_join(id: Tid) -> i32;
	fn sys_yield();
	fn sys_clock_gettime(clock_id: u64, tp: *mut timespec) -> i32;
	fn sys_open(name: *const i8, flags: i32, mode: i32) -> i32;
	fn sys_unlink(name: *const i8) -> i32;
	fn sys_network_init() -> i32;
}

/// A thread handle type
pub type Tid = u32;

/// Priority of a thread
#[derive(PartialEq, Eq, PartialOrd, Ord, Debug, Clone, Copy)]
pub struct Priority(u8);

impl Priority {
	pub const fn into(self) -> u8 {
		self.0
	}

	pub const fn from(x: u8) -> Self {
		Priority(x)
	}
}

pub const HIGH_PRIO: Priority = Priority::from(3);
pub const NORMAL_PRIO: Priority = Priority::from(2);
pub const LOW_PRIO: Priority = Priority::from(1);

/// A handle, identifying a socket
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Default, Hash)]
pub struct Handle(usize);

pub const NSEC_PER_SEC: u64 = 1_000_000_000;
pub const CLOCK_REALTIME: u64 = 1;
pub const CLOCK_MONOTONIC: u64 = 4;
pub const STDIN_FILENO: libc::c_int = 0;
pub const STDOUT_FILENO: libc::c_int = 1;
pub const STDERR_FILENO: libc::c_int = 2;
pub const O_RDONLY: i32 = 0o0;
pub const O_WRONLY: i32 = 0o1;
pub const O_RDWR: i32 = 0o2;
pub const O_CREAT: i32 = 0o100;
pub const O_EXCL: i32 = 0o200;
pub const O_TRUNC: i32 = 0o1000;
pub const O_APPEND: i32 = 0o2000;

/// returns true if file descriptor `fd` is a tty
pub fn isatty(_fd: libc::c_int) -> bool {
	false
}

/// intialize the network stack
pub fn network_init() -> i32 {
	unsafe { sys_network_init() }
}

/// `timespec` is used by `clock_gettime` to retrieve the
/// current time
#[derive(Copy, Clone, Debug)]
#[repr(C)]
pub struct timespec {
	/// seconds
	pub tv_sec: i64,
	/// nanoseconds
	pub tv_nsec: i64,
}

/// determines the number of activated processors
#[inline(always)]
pub unsafe fn get_processor_count() -> usize {
	sys_get_processor_count()
}

#[doc(hidden)]
#[inline(always)]
pub unsafe fn malloc(size: usize, align: usize) -> *mut u8 {
	sys_malloc(size, align)
}

#[doc(hidden)]
#[inline(always)]
pub unsafe fn realloc(ptr: *mut u8, size: usize, align: usize, new_size: usize) -> *mut u8 {
	sys_realloc(ptr, size, align, new_size)
}

#[doc(hidden)]
#[inline(always)]
pub unsafe fn free(ptr: *mut u8, size: usize, align: usize) {
	sys_free(ptr, size, align)
}

#[inline(always)]
pub unsafe fn notify(id: usize, count: i32) -> i32 {
	sys_notify(id, count)
}

#[doc(hidden)]
#[inline(always)]
pub unsafe fn add_queue(id: usize, timeout_ns: i64) -> i32 {
	sys_add_queue(id, timeout_ns)
}

#[doc(hidden)]
#[inline(always)]
pub unsafe fn wait(id: usize) -> i32 {
	sys_wait(id)
}

#[doc(hidden)]
#[inline(always)]
pub unsafe fn destroy_queue(id: usize) -> i32 {
	sys_destroy_queue(id)
}

/// read from a file descriptor
///
/// read() attempts to read `len` bytes of data from the object
/// referenced by the descriptor `fd` into the buffer pointed
/// to by `buf`.
#[inline(always)]
pub unsafe fn read(fd: i32, buf: *mut u8, len: usize) -> isize {
	sys_read(fd, buf, len)
}

/// write to a file descriptor
///
/// write() attempts to write `len` of data to the object
/// referenced by the descriptor `fd` from the
/// buffer pointed to by `buf`.
#[inline(always)]
pub unsafe fn write(fd: i32, buf: *const u8, len: usize) -> isize {
	sys_write(fd, buf, len)
}

/// close a file descriptor
///
/// The close() call deletes a file descriptor `fd` from the object
/// reference table.
#[inline(always)]
pub unsafe fn close(fd: i32) -> i32 {
	sys_close(fd)
}

/// sem_init() initializes the unnamed semaphore at the address
/// pointed to by `sem`.  The `value` argument specifies the
/// initial value for the semaphore.
#[inline(always)]
pub unsafe fn sem_init(sem: *mut *const c_void, value: u32) -> i32 {
	sys_sem_init(sem, value)
}

/// sem_destroy() frees the unnamed semaphore at the address
/// pointed to by `sem`.
#[inline(always)]
pub unsafe fn sem_destroy(sem: *const c_void) -> i32 {
	sys_sem_destroy(sem)
}

/// sem_post() increments the semaphore pointed to by `sem`.
/// If the semaphore's value consequently becomes greater
/// than zero, then another thread blocked in a sem_wait call
/// will be woken up and proceed to lock the semaphore.
#[inline(always)]
pub unsafe fn sem_post(sem: *const c_void) -> i32 {
	sys_sem_post(sem)
}

/// try to decrement a semaphore
///
/// sem_trywait() is the same as sem_timedwait(), except that
/// if the  decrement cannot be immediately performed, then  call
/// returns a negative value instead of blocking.
#[inline(always)]
pub unsafe fn sem_trywait(sem: *const c_void) -> i32 {
	sys_sem_trywait(sem)
}

/// decrement a semaphore
///
/// sem_timedwait() decrements the semaphore pointed to by `sem`.
/// If the semaphore's value is greater than zero, then the
/// the function returns immediately. If the semaphore currently
/// has the value zero, then the call blocks until either
/// it becomes possible to perform the decrement of the time limit
/// to wait for the semaphore is expired. A time limit `ms` of
/// means infinity waiting time.
#[inline(always)]
pub unsafe fn sem_timedwait(sem: *const c_void, ms: u32) -> i32 {
	sys_sem_timedwait(sem, ms)
}

#[doc(hidden)]
#[inline(always)]
pub unsafe fn recmutex_init(recmutex: *mut *const c_void) -> i32 {
	sys_recmutex_init(recmutex)
}

#[doc(hidden)]
#[inline(always)]
pub unsafe fn recmutex_destroy(recmutex: *const c_void) -> i32 {
	sys_recmutex_destroy(recmutex)
}

#[doc(hidden)]
#[inline(always)]
pub unsafe fn recmutex_lock(recmutex: *const c_void) -> i32 {
	sys_recmutex_lock(recmutex)
}

#[doc(hidden)]
#[inline(always)]
pub unsafe fn recmutex_unlock(recmutex: *const c_void) -> i32 {
	sys_recmutex_unlock(recmutex)
}

/// Determines the id of the current thread
#[inline(always)]
pub unsafe fn getpid() -> u32 {
	sys_getpid()
}

/// cause normal termination and return `arg`
/// to the host system
#[inline(always)]
pub unsafe fn exit(arg: i32) -> ! {
	sys_exit(arg)
}

/// cause abnormal termination
#[inline(always)]
pub unsafe fn abort() -> ! {
	sys_abort()
}

/// suspend execution for microsecond intervals
///
/// The usleep() function suspends execution of the calling
/// thread for (at least) `usecs` microseconds.
#[inline(always)]
pub unsafe fn usleep(usecs: u64) {
	sys_usleep(usecs)
}

/// spawn a new thread
///
/// spawn() starts a new thread. The new thread starts execution
/// by invoking `func(usize)`; `arg` is passed as the argument
/// to `func`. `prio` defines the priority of the new thread,
/// which can be between `LOW_PRIO` and `HIGH_PRIO`.
/// `core_id` defines the core, where the thread is located.
/// A negative value give the operating system the possibility
/// to select the core by its own.
#[inline(always)]
pub unsafe fn spawn(
	id: *mut Tid,
	func: extern "C" fn(usize),
	arg: usize,
	prio: u8,
	core_id: isize,
) -> i32 {
	sys_spawn(id, func, arg, prio, core_id)
}

/// spawn a new thread with user-specified stack size
///
/// spawn2() starts a new thread. The new thread starts execution
/// by invoking `func(usize)`; `arg` is passed as the argument
/// to `func`. `prio` defines the priority of the new thread,
/// which can be between `LOW_PRIO` and `HIGH_PRIO`.
/// `core_id` defines the core, where the thread is located.
/// A negative value give the operating system the possibility
/// to select the core by its own.
/// In contrast to spawn(), spawn2() is able to define the
/// stack size.
#[inline(always)]
pub unsafe fn spawn2(
	func: extern "C" fn(usize),
	arg: usize,
	prio: u8,
	stack_size: usize,
	core_id: isize,
) -> Tid {
	sys_spawn2(func, arg, prio, stack_size, core_id)
}

/// join with a terminated thread
///
/// The join() function waits for the thread specified by `id`
/// to terminate.
#[inline(always)]
pub unsafe fn join(id: Tid) -> i32 {
	sys_join(id)
}

/// yield the processor
///
/// causes the calling thread to relinquish the CPU. The thread
/// is moved to the end of the queue for its static priority.
#[inline(always)]
pub unsafe fn yield_now() {
	sys_yield()
}

/// get current time
///
/// The clock_gettime() functions allow the calling thread
/// to retrieve the value used by a clock which is specified
/// by `clock_id`.
///
/// `CLOCK_REALTIME`: the system's real time clock,
/// expressed as the amount of time since the Epoch.
///
/// `CLOCK_MONOTONIC`: clock that increments monotonically,
/// tracking the time since an arbitrary point
#[inline(always)]
pub unsafe fn clock_gettime(clock_id: u64, tp: *mut timespec) -> i32 {
	sys_clock_gettime(clock_id, tp)
}

/// open and possibly create a file
///
/// The open() system call opens the file specified by `name`.
/// If the specified file does not exist, it may optionally
/// be created by open().
#[inline(always)]
pub unsafe fn open(name: *const i8, flags: i32, mode: i32) -> i32 {
	sys_open(name, flags, mode)
}

/// delete the file it refers to `name`
#[inline(always)]
pub unsafe fn unlink(name: *const i8) -> i32 {
	sys_unlink(name)
}
<commit_msg>add interface to intialize CondQueue<commit_after>//! `hermit-abi` is small interface to call functions from the unikernel
//! [RustyHermit](https://github.com/hermitcore/libhermit-rs).

#![cfg_attr(feature = "rustc-dep-of-std", no_std)]
#![feature(const_raw_ptr_to_usize_cast)]
extern crate libc;

pub mod tcpstream;

use libc::c_void;

// sysmbols, which are part of the library operating system
extern "C" {
	fn sys_get_processor_count() -> usize;
	fn sys_malloc(size: usize, align: usize) -> *mut u8;
	fn sys_realloc(ptr: *mut u8, size: usize, align: usize, new_size: usize) -> *mut u8;
	fn sys_free(ptr: *mut u8, size: usize, align: usize);
	fn sys_init_queue(ptr: usize) -> i32;
	fn sys_notify(id: usize, count: i32) -> i32;
	fn sys_add_queue(id: usize, timeout_ns: i64) -> i32;
	fn sys_wait(id: usize) -> i32;
	fn sys_destroy_queue(id: usize) -> i32;
	fn sys_read(fd: i32, buf: *mut u8, len: usize) -> isize;
	fn sys_write(fd: i32, buf: *const u8, len: usize) -> isize;
	fn sys_close(fd: i32) -> i32;
	fn sys_sem_init(sem: *mut *const c_void, value: u32) -> i32;
	fn sys_sem_destroy(sem: *const c_void) -> i32;
	fn sys_sem_post(sem: *const c_void) -> i32;
	fn sys_sem_trywait(sem: *const c_void) -> i32;
	fn sys_sem_timedwait(sem: *const c_void, ms: u32) -> i32;
	fn sys_recmutex_init(recmutex: *mut *const c_void) -> i32;
	fn sys_recmutex_destroy(recmutex: *const c_void) -> i32;
	fn sys_recmutex_lock(recmutex: *const c_void) -> i32;
	fn sys_recmutex_unlock(recmutex: *const c_void) -> i32;
	fn sys_getpid() -> u32;
	fn sys_exit(arg: i32) -> !;
	fn sys_abort() -> !;
	fn sys_usleep(usecs: u64);
	fn sys_spawn(
		id: *mut Tid,
		func: extern "C" fn(usize),
		arg: usize,
		prio: u8,
		core_id: isize,
	) -> i32;
	fn sys_spawn2(
		func: extern "C" fn(usize),
		arg: usize,
		prio: u8,
		stack_size: usize,
		core_id: isize,
	) -> Tid;
	fn sys_join(id: Tid) -> i32;
	fn sys_yield();
	fn sys_clock_gettime(clock_id: u64, tp: *mut timespec) -> i32;
	fn sys_open(name: *const i8, flags: i32, mode: i32) -> i32;
	fn sys_unlink(name: *const i8) -> i32;
	fn sys_network_init() -> i32;
}

/// A thread handle type
pub type Tid = u32;

/// Priority of a thread
#[derive(PartialEq, Eq, PartialOrd, Ord, Debug, Clone, Copy)]
pub struct Priority(u8);

impl Priority {
	pub const fn into(self) -> u8 {
		self.0
	}

	pub const fn from(x: u8) -> Self {
		Priority(x)
	}
}

pub const HIGH_PRIO: Priority = Priority::from(3);
pub const NORMAL_PRIO: Priority = Priority::from(2);
pub const LOW_PRIO: Priority = Priority::from(1);

/// A handle, identifying a socket
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Default, Hash)]
pub struct Handle(usize);

pub const NSEC_PER_SEC: u64 = 1_000_000_000;
pub const CLOCK_REALTIME: u64 = 1;
pub const CLOCK_MONOTONIC: u64 = 4;
pub const STDIN_FILENO: libc::c_int = 0;
pub const STDOUT_FILENO: libc::c_int = 1;
pub const STDERR_FILENO: libc::c_int = 2;
pub const O_RDONLY: i32 = 0o0;
pub const O_WRONLY: i32 = 0o1;
pub const O_RDWR: i32 = 0o2;
pub const O_CREAT: i32 = 0o100;
pub const O_EXCL: i32 = 0o200;
pub const O_TRUNC: i32 = 0o1000;
pub const O_APPEND: i32 = 0o2000;

/// returns true if file descriptor `fd` is a tty
pub fn isatty(_fd: libc::c_int) -> bool {
	false
}

/// intialize the network stack
pub fn network_init() -> i32 {
	unsafe { sys_network_init() }
}

/// `timespec` is used by `clock_gettime` to retrieve the
/// current time
#[derive(Copy, Clone, Debug)]
#[repr(C)]
pub struct timespec {
	/// seconds
	pub tv_sec: i64,
	/// nanoseconds
	pub tv_nsec: i64,
}

/// determines the number of activated processors
#[inline(always)]
pub unsafe fn get_processor_count() -> usize {
	sys_get_processor_count()
}

#[doc(hidden)]
#[inline(always)]
pub unsafe fn malloc(size: usize, align: usize) -> *mut u8 {
	sys_malloc(size, align)
}

#[doc(hidden)]
#[inline(always)]
pub unsafe fn realloc(ptr: *mut u8, size: usize, align: usize, new_size: usize) -> *mut u8 {
	sys_realloc(ptr, size, align, new_size)
}

#[doc(hidden)]
#[inline(always)]
pub unsafe fn free(ptr: *mut u8, size: usize, align: usize) {
	sys_free(ptr, size, align)
}

#[inline(always)]
pub unsafe fn notify(id: usize, count: i32) -> i32 {
	sys_notify(id, count)
}

#[doc(hidden)]
#[inline(always)]
pub unsafe fn add_queue(id: usize, timeout_ns: i64) -> i32 {
	sys_add_queue(id, timeout_ns)
}

#[doc(hidden)]
#[inline(always)]
pub unsafe fn wait(id: usize) -> i32 {
	sys_wait(id)
}

#[doc(hidden)]
#[inline(always)]
pub unsafe fn init_queue(id: usize) -> i32 {
	sys_init_queue(id)
}

#[doc(hidden)]
#[inline(always)]
pub unsafe fn destroy_queue(id: usize) -> i32 {
	sys_destroy_queue(id)
}

/// read from a file descriptor
///
/// read() attempts to read `len` bytes of data from the object
/// referenced by the descriptor `fd` into the buffer pointed
/// to by `buf`.
#[inline(always)]
pub unsafe fn read(fd: i32, buf: *mut u8, len: usize) -> isize {
	sys_read(fd, buf, len)
}

/// write to a file descriptor
///
/// write() attempts to write `len` of data to the object
/// referenced by the descriptor `fd` from the
/// buffer pointed to by `buf`.
#[inline(always)]
pub unsafe fn write(fd: i32, buf: *const u8, len: usize) -> isize {
	sys_write(fd, buf, len)
}

/// close a file descriptor
///
/// The close() call deletes a file descriptor `fd` from the object
/// reference table.
#[inline(always)]
pub unsafe fn close(fd: i32) -> i32 {
	sys_close(fd)
}

/// sem_init() initializes the unnamed semaphore at the address
/// pointed to by `sem`.  The `value` argument specifies the
/// initial value for the semaphore.
#[inline(always)]
pub unsafe fn sem_init(sem: *mut *const c_void, value: u32) -> i32 {
	sys_sem_init(sem, value)
}

/// sem_destroy() frees the unnamed semaphore at the address
/// pointed to by `sem`.
#[inline(always)]
pub unsafe fn sem_destroy(sem: *const c_void) -> i32 {
	sys_sem_destroy(sem)
}

/// sem_post() increments the semaphore pointed to by `sem`.
/// If the semaphore's value consequently becomes greater
/// than zero, then another thread blocked in a sem_wait call
/// will be woken up and proceed to lock the semaphore.
#[inline(always)]
pub unsafe fn sem_post(sem: *const c_void) -> i32 {
	sys_sem_post(sem)
}

/// try to decrement a semaphore
///
/// sem_trywait() is the same as sem_timedwait(), except that
/// if the  decrement cannot be immediately performed, then  call
/// returns a negative value instead of blocking.
#[inline(always)]
pub unsafe fn sem_trywait(sem: *const c_void) -> i32 {
	sys_sem_trywait(sem)
}

/// decrement a semaphore
///
/// sem_timedwait() decrements the semaphore pointed to by `sem`.
/// If the semaphore's value is greater than zero, then the
/// the function returns immediately. If the semaphore currently
/// has the value zero, then the call blocks until either
/// it becomes possible to perform the decrement of the time limit
/// to wait for the semaphore is expired. A time limit `ms` of
/// means infinity waiting time.
#[inline(always)]
pub unsafe fn sem_timedwait(sem: *const c_void, ms: u32) -> i32 {
	sys_sem_timedwait(sem, ms)
}

#[doc(hidden)]
#[inline(always)]
pub unsafe fn recmutex_init(recmutex: *mut *const c_void) -> i32 {
	sys_recmutex_init(recmutex)
}

#[doc(hidden)]
#[inline(always)]
pub unsafe fn recmutex_destroy(recmutex: *const c_void) -> i32 {
	sys_recmutex_destroy(recmutex)
}

#[doc(hidden)]
#[inline(always)]
pub unsafe fn recmutex_lock(recmutex: *const c_void) -> i32 {
	sys_recmutex_lock(recmutex)
}

#[doc(hidden)]
#[inline(always)]
pub unsafe fn recmutex_unlock(recmutex: *const c_void) -> i32 {
	sys_recmutex_unlock(recmutex)
}

/// Determines the id of the current thread
#[inline(always)]
pub unsafe fn getpid() -> u32 {
	sys_getpid()
}

/// cause normal termination and return `arg`
/// to the host system
#[inline(always)]
pub unsafe fn exit(arg: i32) -> ! {
	sys_exit(arg)
}

/// cause abnormal termination
#[inline(always)]
pub unsafe fn abort() -> ! {
	sys_abort()
}

/// suspend execution for microsecond intervals
///
/// The usleep() function suspends execution of the calling
/// thread for (at least) `usecs` microseconds.
#[inline(always)]
pub unsafe fn usleep(usecs: u64) {
	sys_usleep(usecs)
}

/// spawn a new thread
///
/// spawn() starts a new thread. The new thread starts execution
/// by invoking `func(usize)`; `arg` is passed as the argument
/// to `func`. `prio` defines the priority of the new thread,
/// which can be between `LOW_PRIO` and `HIGH_PRIO`.
/// `core_id` defines the core, where the thread is located.
/// A negative value give the operating system the possibility
/// to select the core by its own.
#[inline(always)]
pub unsafe fn spawn(
	id: *mut Tid,
	func: extern "C" fn(usize),
	arg: usize,
	prio: u8,
	core_id: isize,
) -> i32 {
	sys_spawn(id, func, arg, prio, core_id)
}

/// spawn a new thread with user-specified stack size
///
/// spawn2() starts a new thread. The new thread starts execution
/// by invoking `func(usize)`; `arg` is passed as the argument
/// to `func`. `prio` defines the priority of the new thread,
/// which can be between `LOW_PRIO` and `HIGH_PRIO`.
/// `core_id` defines the core, where the thread is located.
/// A negative value give the operating system the possibility
/// to select the core by its own.
/// In contrast to spawn(), spawn2() is able to define the
/// stack size.
#[inline(always)]
pub unsafe fn spawn2(
	func: extern "C" fn(usize),
	arg: usize,
	prio: u8,
	stack_size: usize,
	core_id: isize,
) -> Tid {
	sys_spawn2(func, arg, prio, stack_size, core_id)
}

/// join with a terminated thread
///
/// The join() function waits for the thread specified by `id`
/// to terminate.
#[inline(always)]
pub unsafe fn join(id: Tid) -> i32 {
	sys_join(id)
}

/// yield the processor
///
/// causes the calling thread to relinquish the CPU. The thread
/// is moved to the end of the queue for its static priority.
#[inline(always)]
pub unsafe fn yield_now() {
	sys_yield()
}

/// get current time
///
/// The clock_gettime() functions allow the calling thread
/// to retrieve the value used by a clock which is specified
/// by `clock_id`.
///
/// `CLOCK_REALTIME`: the system's real time clock,
/// expressed as the amount of time since the Epoch.
///
/// `CLOCK_MONOTONIC`: clock that increments monotonically,
/// tracking the time since an arbitrary point
#[inline(always)]
pub unsafe fn clock_gettime(clock_id: u64, tp: *mut timespec) -> i32 {
	sys_clock_gettime(clock_id, tp)
}

/// open and possibly create a file
///
/// The open() system call opens the file specified by `name`.
/// If the specified file does not exist, it may optionally
/// be created by open().
#[inline(always)]
pub unsafe fn open(name: *const i8, flags: i32, mode: i32) -> i32 {
	sys_open(name, flags, mode)
}

/// delete the file it refers to `name`
#[inline(always)]
pub unsafe fn unlink(name: *const i8) -> i32 {
	sys_unlink(name)
}
<|endoftext|>


<commit_before>extern crate clap;
extern crate glob;
#[macro_use] extern crate log;
extern crate serde_json;
extern crate semver;
extern crate toml;
#[macro_use] extern crate version;

extern crate task_hookrs;

extern crate libimagrt;
extern crate libimagstore;
extern crate libimagerror;
extern crate libimagtodo;

use std::process::exit;
use std::process::{Command, Stdio};
use std::io::stdin;

use toml::Value;

use task_hookrs::import::import_tasks;
use task_hookrs::status::TaskStatus;

use libimagrt::runtime::Runtime;
use libimagrt::setup::generate_runtime_setup;
use libimagtodo::task::Task;
use libimagerror::trace::trace_error;

mod ui;

use ui::build_ui;
fn main() {
    let rt = generate_runtime_setup("imag-todo",
                                    &version!()[..],
                                    "Interface with taskwarrior",
                                    build_ui);

    match rt.cli().subcommand_name() {
        Some("tw-hook") => tw_hook(&rt),
        Some("list") => list(&rt),
        None => {
            warn!("No command");
        },
        _ => unreachable!(),
    } // end match scmd
} // end main

fn tw_hook(rt: &Runtime) {
    let subcmd = rt.cli().subcommand_matches("tw-hook").unwrap();
    if subcmd.is_present("add") {
        let stdin = stdin();
        let stdin = stdin.lock(); // implements BufRead which is required for `Task::import()`

        match Task::import(rt.store(), stdin) {
            Ok((_, line, uuid)) => println!("{}\nTask {} stored in imag", line, uuid),
            Err(e) => {
                trace_error(&e);
                exit(1);
            }
        }
    } else if subcmd.is_present("delete") {
        // The used hook is "on-modify". This hook gives two json-objects
        // per usage und wants one (the second one) back.
        let stdin         = stdin();
        Task::delete_by_imports(rt.store(), stdin.lock())
            .map_err(|e| trace_error(&e))
            .ok();
    } else {
        // Should not be possible, as one argument is required via
        // ArgGroup
        unreachable!();
    }
}

fn list(rt: &Runtime) {
    let subcmd  = rt.cli().subcommand_matches("list").unwrap();
    let verbose = subcmd.is_present("verbose");

    let res = Task::all(rt.store()) // get all tasks
        .map(|iter| { // and if this succeeded
            // filter out the ones were we can read the uuid
            let uuids : Vec<_> = iter.filter_map(|t| match t {
                Ok(v) => match v.get_header().read("todo.uuid") {
                    Ok(Some(Value::String(ref u))) => Some(u.clone()),
                    Ok(Some(_)) => {
                        warn!("Header type error");
                        None
                    },
                    Ok(None) => None,
                    Err(e) => {
                        trace_error(&e);
                        None
                    }
                },
                Err(e) => {
                    trace_error(&e);
                    None
                }
            })
            .collect();

            // compose a `task` call with them, ...
            let outstring = if verbose { // ... if verbose
                let output = Command::new("task")
                    .stdin(Stdio::null())
                    .args(&uuids)
                    .spawn()
                    .unwrap_or_else(|e| {
                        trace_error(&e);
                        panic!("Failed to execute `task` on the commandline. I'm dying now.");
                    })
                    .wait_with_output()
                    .unwrap_or_else(|e| panic!("failed to unwrap output: {}", e));

                String::from_utf8(output.stdout)
                    .unwrap_or_else(|e| panic!("failed to execute: {}", e))
            } else { // ... else just join them
                uuids.join("\n")
            };

            // and then print that
            println!("{}", outstring);
        });

    if let Err(e) = res {
        trace_error(&e);
    }
}

<commit_msg>removed unused imports. functionality which required these imports has been moved to libimagtodo by matthiasbeyer<commit_after>extern crate clap;
extern crate glob;
#[macro_use] extern crate log;
extern crate serde_json;
extern crate semver;
extern crate toml;
#[macro_use] extern crate version;

extern crate task_hookrs;

extern crate libimagrt;
extern crate libimagstore;
extern crate libimagerror;
extern crate libimagtodo;

use std::process::exit;
use std::process::{Command, Stdio};
use std::io::stdin;

use toml::Value;

use libimagrt::runtime::Runtime;
use libimagrt::setup::generate_runtime_setup;
use libimagtodo::task::Task;
use libimagerror::trace::trace_error;

mod ui;

use ui::build_ui;
fn main() {
    let rt = generate_runtime_setup("imag-todo",
                                    &version!()[..],
                                    "Interface with taskwarrior",
                                    build_ui);

    match rt.cli().subcommand_name() {
        Some("tw-hook") => tw_hook(&rt),
        Some("list") => list(&rt),
        None => {
            warn!("No command");
        },
        _ => unreachable!(),
    } // end match scmd
} // end main

fn tw_hook(rt: &Runtime) {
    let subcmd = rt.cli().subcommand_matches("tw-hook").unwrap();
    if subcmd.is_present("add") {
        let stdin = stdin();
        let stdin = stdin.lock(); // implements BufRead which is required for `Task::import()`

        match Task::import(rt.store(), stdin) {
            Ok((_, line, uuid)) => println!("{}\nTask {} stored in imag", line, uuid),
            Err(e) => {
                trace_error(&e);
                exit(1);
            }
        }
    } else if subcmd.is_present("delete") {
        // The used hook is "on-modify". This hook gives two json-objects
        // per usage und wants one (the second one) back.
        let stdin         = stdin();
        Task::delete_by_imports(rt.store(), stdin.lock())
            .map_err(|e| trace_error(&e))
            .ok();
    } else {
        // Should not be possible, as one argument is required via
        // ArgGroup
        unreachable!();
    }
}

fn list(rt: &Runtime) {
    let subcmd  = rt.cli().subcommand_matches("list").unwrap();
    let verbose = subcmd.is_present("verbose");

    let res = Task::all(rt.store()) // get all tasks
        .map(|iter| { // and if this succeeded
            // filter out the ones were we can read the uuid
            let uuids : Vec<_> = iter.filter_map(|t| match t {
                Ok(v) => match v.get_header().read("todo.uuid") {
                    Ok(Some(Value::String(ref u))) => Some(u.clone()),
                    Ok(Some(_)) => {
                        warn!("Header type error");
                        None
                    },
                    Ok(None) => None,
                    Err(e) => {
                        trace_error(&e);
                        None
                    }
                },
                Err(e) => {
                    trace_error(&e);
                    None
                }
            })
            .collect();

            // compose a `task` call with them, ...
            let outstring = if verbose { // ... if verbose
                let output = Command::new("task")
                    .stdin(Stdio::null())
                    .args(&uuids)
                    .spawn()
                    .unwrap_or_else(|e| {
                        trace_error(&e);
                        panic!("Failed to execute `task` on the commandline. I'm dying now.");
                    })
                    .wait_with_output()
                    .unwrap_or_else(|e| panic!("failed to unwrap output: {}", e));

                String::from_utf8(output.stdout)
                    .unwrap_or_else(|e| panic!("failed to execute: {}", e))
            } else { // ... else just join them
                uuids.join("\n")
            };

            // and then print that
            println!("{}", outstring);
        });

    if let Err(e) = res {
        trace_error(&e);
    }
}

<|endoftext|>


<commit_before>use std::cmp::Reverse;
use std::collections::BinaryHeap;
use std::collections::HashMap;
use std::collections::HashSet;
use std::io::BufRead;
use std::io::BufReader;
use std::io::Read;

use common::manhattan_distance;
use common::Solution;

type Coordinate = (usize, usize);

#[derive(Debug, Eq, PartialEq, Ord, PartialOrd)]
struct Unit {
    pos: Coordinate,
    hp: u8,
    power: u8,
    faction: char,
}

impl Default for Unit {
    fn default() -> Self {
        Unit {
            pos: (0, 0),
            hp: 200,
            power: 3,
            faction: 'E',
        }
    }
}

impl Unit {
    pub fn is_alive(&self) -> bool {
        self.hp > 0
    }
}

#[derive(Default)]
pub struct Day15 {
    walls: Vec<Vec<bool>>,
    units: Vec<Unit>,
    alive: [usize; 2],
}

impl Day15 {
    pub fn new() -> Self {
        Default::default()
    }

    fn read_input(&mut self, input: &mut Read) {
        let reader = BufReader::new(input);

        for (y, line) in reader.lines().enumerate() {
            let line = line.unwrap();
            let mut current = vec![false; line.len()];

            for (x, c) in line.chars().enumerate() {
                match c {
                    '#' => { current[x] = true; }
                    'E' | 'G' => {
                        self.units.push(Unit {
                            pos: (y, x),
                            faction: c,
                            ..Default::default()
                        });
                        self.alive[if c == 'E' { 0 } else { 1 }] += 1;
                    }
                    '.' => {}
                    c => panic!("Invalid tile {}!", c),
                }
            }
            self.walls.push(current);
        }
    }

    fn get_movement(&self, unit: usize) -> Option<Coordinate> {
        let initial = self.units[unit].pos;
        let faction = self.units[unit].faction;

        let enemy_positions: HashSet<Coordinate> = self.units.iter()
            .filter(|x| x.faction != faction && x.is_alive())
            .map(|x| x.pos).collect();

        let all_positions: HashSet<Coordinate> = self.units.iter()
            .filter(|x| x.is_alive())
            .map(|x| x.pos).collect();

        let mut todo = BinaryHeap::new();
        let mut prev: HashMap<Coordinate, Coordinate> = HashMap::new();

        todo.push(Reverse((0, initial)));

        while let Some(Reverse((d, (y, x)))) = todo.pop() {
            let next = [
                (y - 1, x),
                (y, x - 1),
                (y, x + 1),
                (y + 1, x),
            ];

            for pos in &next {
                if !prev.contains_key(pos) && !self.walls[pos.0][pos.1] {
                    if enemy_positions.contains(pos) {
                        return prev.remove(&(y, x));
                    } else if !all_positions.contains(pos) {
                        ;
                        let prev_step = *prev.get(&(y, x)).unwrap_or(pos);
                        prev.insert(*pos, prev_step);
                        todo.push(Reverse((d + 1, *pos)));
                    }
                }
            }
        }
        None
    }

    fn get_attack(&self, unit: usize) -> Option<usize> {
        let initial = self.units[unit].pos;
        let faction = self.units[unit].faction;

        let to_attack = self.units.iter()
            .enumerate()
            .filter(|(_, x)| x.faction != faction && x.is_alive())
            .filter(|(_, x)| manhattan_distance(x.pos, initial) == 1)
            .min_by(|&(_, a), &(_, b)| a.hp.cmp(&b.hp).then(a.pos.cmp(&b.pos)));

        if let Some((index, _)) = to_attack {
            Some(index)
        } else {
            None
        }
    }

    fn simulate(&mut self) -> bool {
        self.units.sort_unstable();
        for i in 0..self.units.len() {
            if !self.units[i].is_alive() {
                continue;
            }

            if self.alive[0] == 0 || self.alive[1] == 0 {
                return false;
            }

            if let Some(new_pos) = self.get_movement(i) {
                self.units[i].pos = new_pos;
            }

            if let Some(target) = self.get_attack(i) {
                let power = self.units[i].power;
                let target = &mut self.units[target];
                target.hp = target.hp.saturating_sub(power);

                if target.hp == 0 {
                    match target.faction {
                        'E' => { self.alive[0] -= 1 }
                        'G' => { self.alive[1] -= 1 }
                        _ => panic!(),
                    };
                }
            }
        }

        true
    }

    #[allow(dead_code)]
    fn print(&self) {
        let positions: HashMap<_, _> = self.units.iter()
            .filter(|x| x.is_alive())
            .map(|x| (x.pos, x))
            .collect();

        for y in 0..self.walls.len() {
            let mut buf = String::new();
            let mut unit_buf = String::new();

            for x in 0..self.walls[y].len() {
                if let Some(unit) = positions.get(&(y, x)) {
                    buf.push(unit.faction);

                    unit_buf += &format!("    {}({})", unit.faction, unit.hp);
                } else if self.walls[y][x] {
                    buf.push('#');
                } else {
                    buf.push('.');
                }
            }
            println!("{}{}", buf, unit_buf);
        }
    }
}

impl Solution for Day15 {
    fn part1(&mut self, input: &mut Read) -> String {
        self.read_input(input);
        let mut rounds = 0;
        while self.simulate() {
            rounds += 1;
        }
        let result: usize = rounds * self.units.iter().map(|x| x.hp as usize)
            .sum::<usize>();

        format!("{}", result)
    }

    fn part2(&mut self, _input: &mut Read) -> String {
        unimplemented!()
    }
}

#[cfg(test)]
mod tests {
    use common::Solution;
    use day15::Day15;

    const SAMPLE_INPUT: [&[u8]; 6] = [
        include_bytes!("samples/15.1.txt"),
        include_bytes!("samples/15.2.txt"),
        include_bytes!("samples/15.3.txt"),
        include_bytes!("samples/15.4.txt"),
        include_bytes!("samples/15.5.txt"),
        include_bytes!("samples/15.6.txt"),
    ];

    const SAMPLE_OUTPUT: [&str; 6] = [
        "27730",
        "36334",
        "39514",
        "27755",
        "28944",
        "18740",
    ];

    #[test]
    fn sample_part1() {
        for (input, output) in SAMPLE_INPUT.iter().zip(SAMPLE_OUTPUT.iter()) {
            let mut instance = Day15::new();
            assert_eq!(*output, instance.part1(&mut input.as_ref()));
        }
    }
}
<commit_msg>Implement day 15 part 2.<commit_after>use std::cmp::Reverse;
use std::collections::BinaryHeap;
use std::collections::HashMap;
use std::collections::HashSet;
use std::io::BufRead;
use std::io::BufReader;
use std::io::Read;

use common::manhattan_distance;
use common::Solution;

type Coordinate = (usize, usize);

#[derive(Debug, Eq, PartialEq, Ord, PartialOrd, Copy, Clone)]
struct Unit {
    pos: Coordinate,
    hp: u8,
    power: u8,
    faction: char,
}

impl Default for Unit {
    fn default() -> Self {
        Unit {
            pos: (0, 0),
            hp: 200,
            power: 3,
            faction: 'E',
        }
    }
}

impl Unit {
    pub fn is_alive(&self) -> bool {
        self.hp > 0
    }
}

#[derive(Default)]
pub struct Day15 {
    walls: Vec<Vec<bool>>,
    units: Vec<Unit>,
    alive: [usize; 2],
}

impl Day15 {
    pub fn new() -> Self {
        Default::default()
    }

    fn read_input(&mut self, input: &mut Read) {
        let reader = BufReader::new(input);

        for (y, line) in reader.lines().enumerate() {
            let line = line.unwrap();
            let mut current = vec![false; line.len()];

            for (x, c) in line.chars().enumerate() {
                match c {
                    '#' => { current[x] = true; }
                    'E' | 'G' => {
                        self.units.push(Unit {
                            pos: (y, x),
                            faction: c,
                            ..Default::default()
                        });
                        self.alive[if c == 'E' { 0 } else { 1 }] += 1;
                    }
                    '.' => {}
                    c => panic!("Invalid tile {}!", c),
                }
            }
            self.walls.push(current);
        }
    }

    fn get_movement(&self, unit: usize) -> Option<Coordinate> {
        let initial = self.units[unit].pos;
        let faction = self.units[unit].faction;

        let enemy_positions: HashSet<Coordinate> = self.units.iter()
            .filter(|x| x.faction != faction && x.is_alive())
            .map(|x| x.pos).collect();

        let all_positions: HashSet<Coordinate> = self.units.iter()
            .filter(|x| x.is_alive())
            .map(|x| x.pos).collect();

        let mut todo = BinaryHeap::new();
        let mut prev: HashMap<Coordinate, Coordinate> = HashMap::new();

        todo.push(Reverse((0, initial)));

        while let Some(Reverse((d, (y, x)))) = todo.pop() {
            let next = [
                (y - 1, x),
                (y, x - 1),
                (y, x + 1),
                (y + 1, x),
            ];

            for pos in &next {
                if !prev.contains_key(pos) && !self.walls[pos.0][pos.1] {
                    if enemy_positions.contains(pos) {
                        return prev.remove(&(y, x));
                    } else if !all_positions.contains(pos) {
                        ;
                        let prev_step = *prev.get(&(y, x)).unwrap_or(pos);
                        prev.insert(*pos, prev_step);
                        todo.push(Reverse((d + 1, *pos)));
                    }
                }
            }
        }
        None
    }

    fn get_attack(&self, unit: usize) -> Option<usize> {
        let initial = self.units[unit].pos;
        let faction = self.units[unit].faction;

        let to_attack = self.units.iter()
            .enumerate()
            .filter(|(_, x)| x.faction != faction && x.is_alive())
            .filter(|(_, x)| manhattan_distance(x.pos, initial) == 1)
            .min_by(|&(_, a), &(_, b)| a.hp.cmp(&b.hp).then(a.pos.cmp(&b.pos)));

        if let Some((index, _)) = to_attack {
            Some(index)
        } else {
            None
        }
    }

    fn simulate(&mut self) -> bool {
        self.units.sort_unstable();
        for i in 0..self.units.len() {
            if !self.units[i].is_alive() {
                continue;
            }

            if self.alive[0] == 0 || self.alive[1] == 0 {
                return false;
            }

            if let Some(new_pos) = self.get_movement(i) {
                self.units[i].pos = new_pos;
            }

            if let Some(target) = self.get_attack(i) {
                let power = self.units[i].power;
                let target = &mut self.units[target];
                target.hp = target.hp.saturating_sub(power);

                if target.hp == 0 {
                    match target.faction {
                        'E' => { self.alive[0] -= 1 }
                        'G' => { self.alive[1] -= 1 }
                        _ => panic!(),
                    };
                }
            }
        }

        true
    }

    #[allow(dead_code)]
    fn print(&self) {
        let positions: HashMap<_, _> = self.units.iter()
            .filter(|x| x.is_alive())
            .map(|x| (x.pos, x))
            .collect();

        for y in 0..self.walls.len() {
            let mut buf = String::new();
            let mut unit_buf = String::new();

            for x in 0..self.walls[y].len() {
                if let Some(unit) = positions.get(&(y, x)) {
                    buf.push(unit.faction);

                    unit_buf += &format!("    {}({})", unit.faction, unit.hp);
                } else if self.walls[y][x] {
                    buf.push('#');
                } else {
                    buf.push('.');
                }
            }
            println!("{}{}", buf, unit_buf);
        }
    }

    fn return_score(&self, rounds: usize) -> String {
        let result: usize = rounds * self.units.iter().map(|x| x.hp as usize)
            .sum::<usize>();
        format!("{}", result)
    }

    fn set_elf_power(&mut self, power: u8) {
        for unit in self.units.iter_mut() {
            if unit.faction == 'E' {
                unit.power = power;
            }
        }
    }
}

impl Solution for Day15 {
    fn part1(&mut self, input: &mut Read) -> String {
        self.read_input(input);
        let mut rounds = 0;
        while self.simulate() {
            rounds += 1;
        }
        self.return_score(rounds)
    }

    fn part2(&mut self, input: &mut Read) -> String {
        self.read_input(input);
        let backup = self.units.clone();
        let starting_elves = self.alive[0];
        let starting_goblins = self.alive[1];

        for power in 4..=255 {
            self.units = backup.clone();
            self.alive[0] = starting_elves;
            self.alive[1] = starting_goblins;

            self.set_elf_power(power);
            let mut rounds = 0;
            while self.simulate() {
                rounds += 1;
            }

            if self.alive[0] == starting_elves {
                return self.return_score(rounds);
            }

        }
        unreachable!()
    }
}

#[cfg(test)]
mod tests {
    use common::Solution;
    use day15::Day15;

    const SAMPLE_INPUT: [&[u8]; 6] = [
        include_bytes!("samples/15.1.txt"),
        include_bytes!("samples/15.2.txt"),
        include_bytes!("samples/15.3.txt"),
        include_bytes!("samples/15.4.txt"),
        include_bytes!("samples/15.5.txt"),
        include_bytes!("samples/15.6.txt"),
    ];

    const SAMPLE1_OUTPUT: [&str; 6] = [
        "27730",
        "36334",
        "39514",
        "27755",
        "28944",
        "18740",
    ];

    #[test]
    fn sample_part1() {
        for (input, output) in SAMPLE_INPUT.iter().zip(SAMPLE1_OUTPUT.iter()) {
            let mut instance = Day15::new();
            assert_eq!(*output, instance.part1(&mut input.as_ref()));
        }
    }

    #[test]
    fn sample_part2() {
        let indices = [0, 2, 3, 4, 5];
        let outputs = [
            "4988",
            "31284",
            "3478",
            "6474",
            "1140",
        ];

        for (&input, output) in indices.iter().zip(outputs.iter()) {
            let mut instance = Day15::new();
            assert_eq!(*output, instance.part2(&mut SAMPLE_INPUT[input]));
        }
    }
}
<|endoftext|>


<commit_before>use std::libc::{c_char, c_int, c_void, c_uint, c_ushort};

#[link_args = "-lnspr4"]
#[nolink]

pub type PRBool = c_int;
pub type PRStatus = c_int;

pub static PRTrue: PRBool = 1;
pub static PRFalse: PRBool = 0;

pub static PRSuccess: PRStatus = 0;
pub static PRFailure: PRStatus = -1;

pub static PR_AF_INET: c_ushort = 2;

pub struct PRNetAddr {
     family: c_ushort,
     port: c_ushort,
     ip: c_uint,
     pad: [c_char, ..8],

}
extern "C" {
pub fn PR_OpenTCPSocket(af: c_ushort) -> *c_void;
pub fn PR_Connect(fd: *c_void, addr: *PRNetAddr, timout: c_uint) -> PRStatus;
pub fn PR_Close(fd: *c_void) -> PRStatus;
pub fn PR_StringToNetAddr(string: *c_char, addr: *c_void) -> PRStatus;
pub fn PR_GetError() -> c_int;
pub fn PR_ErrorToName(error: c_int) -> *c_char;
pub fn PR_htons(conversion: c_ushort) -> c_ushort;
pub fn PR_htonl(conversion: c_uint) -> c_uint;
pub fn PR_Write(fd: *c_void, buf: *c_void, amount: c_int) -> c_int;
pub fn PR_Read(fd: *c_void, buf: *c_void, amount: c_int) -> c_int;
}
<commit_msg>More changes<commit_after>use std::libc::{c_char, c_int, c_void, c_uint, c_ushort};

pub type PRBool = c_int;
pub type PRStatus = c_int;

pub static PRTrue: PRBool = 1;
pub static PRFalse: PRBool = 0;

pub static PRSuccess: PRStatus = 0;
pub static PRFailure: PRStatus = -1;

pub static PR_AF_INET: c_ushort = 2;

pub struct PRNetAddr {
     family: c_ushort,
     port: c_ushort,
     ip: c_uint,
     pad: [c_char, ..8],

}

#[link_args = "-lnspr4"]
extern "C" {
pub fn PR_OpenTCPSocket(af: c_ushort) -> *c_void;
pub fn PR_Connect(fd: *c_void, addr: *PRNetAddr, timout: c_uint) -> PRStatus;
pub fn PR_Close(fd: *c_void) -> PRStatus;
pub fn PR_StringToNetAddr(string: *c_char, addr: *c_void) -> PRStatus;
pub fn PR_GetError() -> c_int;
pub fn PR_ErrorToName(error: c_int) -> *c_char;
pub fn PR_htons(conversion: c_ushort) -> c_ushort;
pub fn PR_htonl(conversion: c_uint) -> c_uint;
pub fn PR_Write(fd: *c_void, buf: *c_void, amount: c_int) -> c_int;
pub fn PR_Read(fd: *c_void, buf: *c_void, amount: c_int) -> c_int;
}
<|endoftext|>


<commit_before>// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

use std::{
    env,
    fs::OpenOptions,
    io::{Seek, SeekFrom},
    process,
};

use env_logger::Builder;

use clap::{App, Arg};

use pretty_hex::pretty_hex;

use serde_json::Value;

use stratisd::engine::{StaticHeader, StaticHeaderResult, BDA};

/// Format metadata on a given device
/// Returns StaticHeader fields
/// Returns an additional bytes buffer if print_bytes flag is True
fn fmt_metadata(shr: &StaticHeaderResult, print_bytes: bool) -> String {
    let mut result = String::from("\nHeader:\n")
        + shr
            .header
            .as_ref()
            .map_or(String::from("Unreadable\n"), |h| {
                h.as_ref().map_or_else(
                    |e| format!("Error: {}\n", e),
                    |s| {
                        s.as_ref()
                            .map_or(String::from("No signature buffer\n"), |sh| {
                                format!("{:#?}\n", sh)
                            })
                    },
                )
            })
            .as_str();
    if print_bytes {
        result += "\n\nBytes:\n\n";
        match &shr.bytes {
            Ok(ref boxed) => {
                result += pretty_hex(boxed.as_ref()).as_str();
            }
            Err(e) => {
                result += e.to_string().as_str();
            }
        }
    }

    result
}

/// Configure and initialize the logger.
/// Read log configuration parameters from the environment if RUST_LOG
/// is set. Otherwise, just accept the default configuration, which is
/// to log at the severity of error only.
fn initialize_log() {
    let mut builder = Builder::new();

    if let Ok(s) = env::var("RUST_LOG") {
        builder.parse_filters(&s);
    }

    builder.init()
}

// Print metadata, such as StaticHeaders, BDA, and Pool Metadata of given device.
// If sigblocks match, display the StaticHeader fields of a single sigblock,
// Otherwise display the StaticHeader fields of both sigblocks.
// If print_bytes flag is set to True, display the bytes buffer
// of the sigblock alongside the StaticHeader.
fn run(devpath: &str, print_bytes: bool) -> Result<(), String> {
    let mut devfile = OpenOptions::new()
        .read(true)
        .open(&devpath)
        .map_err(|the_io_error| format!("Error opening device: {}", the_io_error))?;

    let read_results = StaticHeader::read_sigblocks(&mut devfile);
    if read_results.0 == read_results.1 {
        println!(
            "Signature block: \n{}",
            fmt_metadata(&read_results.0, print_bytes)
        );
    } else {
        println!(
            "Signature block 1: \n{}",
            fmt_metadata(&read_results.0, print_bytes)
        );
        println!(
            "Signature block 2: \n{}",
            fmt_metadata(&read_results.1, print_bytes)
        );
    }

    let header =
        StaticHeader::repair_sigblocks(&mut devfile, read_results, StaticHeader::do_nothing)
            .map_err(|repair_error| format!("No valid StaticHeader found: {}", repair_error))?
            .ok_or_else(|| "No valid Stratis signature found".to_string())?;
    let bda = BDA::load(header, &mut devfile)
        .map_err(|bda_load_error| format!("BDA detected but error found: {}", bda_load_error))?
        .ok_or_else(|| "No Stratis BDA metadata found".to_string())?;

    println!("\n{:#?}", bda);

    devfile
        .seek(SeekFrom::Start(0))
        .map_err(|seek_err| format!("Error during seek: {}", seek_err))?;

    let loaded_state = bda
        .load_state(&mut devfile)
        .map_err(|stateload_err| format!("Error during load state: {}", stateload_err))?;

    println!("\nPool metadata:");
    if let Some(loaded_state) = loaded_state {
        let state_json: Value = serde_json::from_slice(&loaded_state)
            .map_err(|extract_err| format!("Error during state JSON extract: {}", extract_err))?;
        let state_json_pretty: String = serde_json::to_string_pretty(&state_json)
            .map_err(|parse_err| format!("Error during state JSON parse: {}", parse_err))?;
        println!("{}", state_json_pretty);
    } else {
        println!("None found");
    }

    Ok(())
}

fn main() {
    let matches = App::new("stratis-dumpmetadata")
        .arg(
            Arg::with_name("dev")
                .required(true)
                .help("Print metadata of given device"),
        )
        .arg(
            Arg::with_name("print_bytes")
                .long("print-bytes")
                .short("b")
                .help("Print byte buffer of device"),
        )
        .get_matches();
    let devpath = matches.value_of("dev").unwrap();

    initialize_log();

    match run(devpath, matches.is_present("print_bytes")) {
        Ok(()) => {}
        Err(e) => {
            eprintln!("Error encountered: {}", e);
            process::exit(1);
        }
    }
}
<commit_msg>Update stratis_dumpmetadata to clap v3 API<commit_after>// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

use std::{
    env,
    fs::OpenOptions,
    io::{Seek, SeekFrom},
    process,
};

use env_logger::Builder;

use clap::{Arg, Command};

use pretty_hex::pretty_hex;

use serde_json::Value;

use stratisd::engine::{StaticHeader, StaticHeaderResult, BDA};

/// Format metadata on a given device
/// Returns StaticHeader fields
/// Returns an additional bytes buffer if print_bytes flag is True
fn fmt_metadata(shr: &StaticHeaderResult, print_bytes: bool) -> String {
    let mut result = String::from("\nHeader:\n")
        + shr
            .header
            .as_ref()
            .map_or(String::from("Unreadable\n"), |h| {
                h.as_ref().map_or_else(
                    |e| format!("Error: {}\n", e),
                    |s| {
                        s.as_ref()
                            .map_or(String::from("No signature buffer\n"), |sh| {
                                format!("{:#?}\n", sh)
                            })
                    },
                )
            })
            .as_str();
    if print_bytes {
        result += "\n\nBytes:\n\n";
        match &shr.bytes {
            Ok(ref boxed) => {
                result += pretty_hex(boxed.as_ref()).as_str();
            }
            Err(e) => {
                result += e.to_string().as_str();
            }
        }
    }

    result
}

/// Configure and initialize the logger.
/// Read log configuration parameters from the environment if RUST_LOG
/// is set. Otherwise, just accept the default configuration, which is
/// to log at the severity of error only.
fn initialize_log() {
    let mut builder = Builder::new();

    if let Ok(s) = env::var("RUST_LOG") {
        builder.parse_filters(&s);
    }

    builder.init()
}

// Print metadata, such as StaticHeaders, BDA, and Pool Metadata of given device.
// If sigblocks match, display the StaticHeader fields of a single sigblock,
// Otherwise display the StaticHeader fields of both sigblocks.
// If print_bytes flag is set to True, display the bytes buffer
// of the sigblock alongside the StaticHeader.
fn run(devpath: &str, print_bytes: bool) -> Result<(), String> {
    let mut devfile = OpenOptions::new()
        .read(true)
        .open(&devpath)
        .map_err(|the_io_error| format!("Error opening device: {}", the_io_error))?;

    let read_results = StaticHeader::read_sigblocks(&mut devfile);
    if read_results.0 == read_results.1 {
        println!(
            "Signature block: \n{}",
            fmt_metadata(&read_results.0, print_bytes)
        );
    } else {
        println!(
            "Signature block 1: \n{}",
            fmt_metadata(&read_results.0, print_bytes)
        );
        println!(
            "Signature block 2: \n{}",
            fmt_metadata(&read_results.1, print_bytes)
        );
    }

    let header =
        StaticHeader::repair_sigblocks(&mut devfile, read_results, StaticHeader::do_nothing)
            .map_err(|repair_error| format!("No valid StaticHeader found: {}", repair_error))?
            .ok_or_else(|| "No valid Stratis signature found".to_string())?;
    let bda = BDA::load(header, &mut devfile)
        .map_err(|bda_load_error| format!("BDA detected but error found: {}", bda_load_error))?
        .ok_or_else(|| "No Stratis BDA metadata found".to_string())?;

    println!("\n{:#?}", bda);

    devfile
        .seek(SeekFrom::Start(0))
        .map_err(|seek_err| format!("Error during seek: {}", seek_err))?;

    let loaded_state = bda
        .load_state(&mut devfile)
        .map_err(|stateload_err| format!("Error during load state: {}", stateload_err))?;

    println!("\nPool metadata:");
    if let Some(loaded_state) = loaded_state {
        let state_json: Value = serde_json::from_slice(&loaded_state)
            .map_err(|extract_err| format!("Error during state JSON extract: {}", extract_err))?;
        let state_json_pretty: String = serde_json::to_string_pretty(&state_json)
            .map_err(|parse_err| format!("Error during state JSON parse: {}", parse_err))?;
        println!("{}", state_json_pretty);
    } else {
        println!("None found");
    }

    Ok(())
}

fn main() {
    let matches = Command::new("stratis-dumpmetadata")
        .arg(
            Arg::new("dev")
                .required(true)
                .help("Print metadata of given device"),
        )
        .arg(
            Arg::new("print_bytes")
                .long("print-bytes")
                .short('b')
                .help("Print byte buffer of device"),
        )
        .get_matches();
    let devpath = matches.value_of("dev").unwrap();

    initialize_log();

    match run(devpath, matches.is_present("print_bytes")) {
        Ok(()) => {}
        Err(e) => {
            eprintln!("Error encountered: {}", e);
            process::exit(1);
        }
    }
}
<|endoftext|>


<commit_before>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#![feature(borrow_state)]
#![feature(box_raw)]
#![feature(box_syntax)]
#![feature(convert)]
#![feature(core_intrinsics)]
#![feature(filling_drop)]
#![feature(iter_arith)]
#![feature(link_args)]
#![feature(plugin)]
#![feature(str_utf16)]
#![feature(unicode)]
#![feature(unsafe_no_drop_flag)]

#![allow(non_camel_case_types)]

#![plugin(plugins)]

#[macro_use]
extern crate log;

extern crate servo;
extern crate compositing;

extern crate azure;
extern crate euclid;
extern crate gfx;
extern crate gleam;
extern crate glutin_app;
extern crate js;
extern crate layers;
extern crate png;
extern crate rustc_unicode;
extern crate script;
extern crate script_traits;

extern crate net_traits;
extern crate msg;
extern crate util;
extern crate style;
extern crate stb_image;

extern crate libc;
extern crate url as std_url;

#[cfg(target_os="macos")]
#[link_args="-Xlinker -undefined -Xlinker dynamic_lookup"]
extern { }

#[cfg(target_os="macos")]
extern crate cgl;
#[cfg(target_os="macos")]
extern crate cocoa;
#[cfg(target_os="macos")]
extern crate core_foundation;
#[cfg(target_os="macos")]
extern crate core_graphics;
#[cfg(target_os="macos")]
extern crate core_text;
#[cfg(target_os="macos")]
#[macro_use]
extern crate objc;
#[cfg(target_os="linux")] extern crate x11;

// Must come first.
pub mod macros;

pub mod browser;
pub mod browser_host;
pub mod command_line;
pub mod cookie;
pub mod core;
pub mod drag_data;
pub mod eutil;
pub mod frame;
pub mod interfaces;
pub mod print_settings;
pub mod process_message;
pub mod render_handler;
pub mod request;
pub mod request_context;
pub mod response;
pub mod stream;
pub mod string;
pub mod string_list;
pub mod string_map;
pub mod string_multimap;
pub mod stubs;
pub mod switches;
pub mod task;
pub mod types;
pub mod urlrequest;
pub mod v8;
pub mod values;
pub mod window;
pub mod wrappers;
pub mod xml_reader;
pub mod zip_reader;
<commit_msg>Remove the now-stable box_raw feature gate from cef.<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#![feature(borrow_state)]
#![feature(box_syntax)]
#![feature(convert)]
#![feature(core_intrinsics)]
#![feature(filling_drop)]
#![feature(iter_arith)]
#![feature(link_args)]
#![feature(plugin)]
#![feature(str_utf16)]
#![feature(unicode)]
#![feature(unsafe_no_drop_flag)]

#![allow(non_camel_case_types)]

#![plugin(plugins)]

#[macro_use]
extern crate log;

extern crate servo;
extern crate compositing;

extern crate azure;
extern crate euclid;
extern crate gfx;
extern crate gleam;
extern crate glutin_app;
extern crate js;
extern crate layers;
extern crate png;
extern crate rustc_unicode;
extern crate script;
extern crate script_traits;

extern crate net_traits;
extern crate msg;
extern crate util;
extern crate style;
extern crate stb_image;

extern crate libc;
extern crate url as std_url;

#[cfg(target_os="macos")]
#[link_args="-Xlinker -undefined -Xlinker dynamic_lookup"]
extern { }

#[cfg(target_os="macos")]
extern crate cgl;
#[cfg(target_os="macos")]
extern crate cocoa;
#[cfg(target_os="macos")]
extern crate core_foundation;
#[cfg(target_os="macos")]
extern crate core_graphics;
#[cfg(target_os="macos")]
extern crate core_text;
#[cfg(target_os="macos")]
#[macro_use]
extern crate objc;
#[cfg(target_os="linux")] extern crate x11;

// Must come first.
pub mod macros;

pub mod browser;
pub mod browser_host;
pub mod command_line;
pub mod cookie;
pub mod core;
pub mod drag_data;
pub mod eutil;
pub mod frame;
pub mod interfaces;
pub mod print_settings;
pub mod process_message;
pub mod render_handler;
pub mod request;
pub mod request_context;
pub mod response;
pub mod stream;
pub mod string;
pub mod string_list;
pub mod string_map;
pub mod string_multimap;
pub mod stubs;
pub mod switches;
pub mod task;
pub mod types;
pub mod urlrequest;
pub mod v8;
pub mod values;
pub mod window;
pub mod wrappers;
pub mod xml_reader;
pub mod zip_reader;
<|endoftext|>


<commit_before>//! Types and functions related to PG's and Sqlite's `ON CONFLICT` clause
//! If you use upsert, you need use PostgreSQL since version 9.0 or Sqlite3 since version 3.24.0.
//!
//! See [the methods on `InsertStatement`](../../query_builder/struct.InsertStatement.html#impl-1)
//! for usage examples.

mod on_conflict_actions;
mod on_conflict_clause;
mod on_conflict_extension;
mod on_conflict_target;

pub use self::on_conflict_actions::excluded;
pub use self::on_conflict_extension::*;
pub use self::on_conflict_target::*;
<commit_msg>Add line break<commit_after>//! Types and functions related to PG's and Sqlite's `ON CONFLICT` clause
//!
//! If you use upsert, you need use PostgreSQL since version 9.0 or Sqlite3 since version 3.24.0.
//! See [the methods on `InsertStatement`](../../query_builder/struct.InsertStatement.html#impl-1)
//! for usage examples.

mod on_conflict_actions;
mod on_conflict_clause;
mod on_conflict_extension;
mod on_conflict_target;

pub use self::on_conflict_actions::excluded;
pub use self::on_conflict_extension::*;
pub use self::on_conflict_target::*;
<|endoftext|>


<commit_before>extern crate pkg_config;
extern crate gcc;

use std::env;
use std::ffi::OsString;
use std::fs;
use std::path::{PathBuf, Path};
use std::process::Command;
use std::io::ErrorKind;

macro_rules! t {
    ($e:expr) => (match $e {
        Ok(t) => t,
        Err(e) => panic!("{} return the error {}", stringify!($e), e),
    })
}

fn main() {
    let target = env::var("TARGET").unwrap();
    let host = env::var("HOST").unwrap();
    let src = env::current_dir().unwrap();
    let dst = PathBuf::from(env::var_os("OUT_DIR").unwrap());
    let windows = target.contains("windows");

    // OSX ships libcurl by default, so we just use that version
    // unconditionally.
    if target.contains("apple") {
        return println!("cargo:rustc-flags=-l curl");
    }

    // Illumos/Solaris requires explicit linking with libnsl
    if target.contains("solaris") {
        println!("cargo:rustc-flags=-l nsl");
    }

    // Next, fall back and try to use pkg-config if its available.
    if !target.contains("windows") {
        match pkg_config::find_library("libcurl") {
            Ok(lib) => {
                for path in lib.include_paths.iter() {
                    println!("cargo:include={}", path.display());
                }
                return
            }
            Err(e) => println!("Couldn't find libcurl from \
                               pkgconfig ({:?}), compiling it from source...", e),
        }
    }

    if !Path::new("curl/.git").exists() {
        let _ = Command::new("git").args(&["submodule", "update", "--init"])
                                   .status();
    }

    println!("cargo:rustc-link-search={}/lib", dst.display());
    println!("cargo:rustc-link-lib=static=curl");
    println!("cargo:root={}", dst.display());
    println!("cargo:include={}/include", dst.display());
    if windows {
        println!("cargo:rustc-link-lib=ws2_32");
        println!("cargo:rustc-link-lib=crypt32");
    }

    // MSVC builds are just totally different
    if target.contains("msvc") {
        return build_msvc(&target);
    }

    let cfg = gcc::Config::new();
    let compiler = cfg.get_compiler();

    let _ = fs::create_dir(&dst.join("build"));

    let mut cmd = Command::new("sh");
    let mut cflags = OsString::new();
    for arg in compiler.args() {
        cflags.push(arg);
        cflags.push(" ");
    }

    // Can't run ./configure directly on msys2 b/c we're handing in
    // Windows-style paths (those starting with C:\), but it chokes on those.
    // For that reason we build up a shell script with paths converted to
    // posix versions hopefully...
    //
    // Also apparently the buildbots choke unless we manually set LD, who knows
    // why?!
    cmd.env("CC", compiler.path())
       .env("CFLAGS", cflags)
       .env("LD", &which("ld").unwrap())
       .env("VERBOSE", "1")
       .current_dir(&dst.join("build"))
       .arg(msys_compatible(&src.join("curl/configure")));

    // For now this build script doesn't support paths with spaces in them. This
    // is arguably a but in curl's configure script, but we could also try to
    // paper over it by using a tmp directory which *doesn't* have spaces in it.
    // As of now though that's not implemented so just give a nicer error for
    // the time being.
    let wants_space_error = windows &&
        (dst.to_str().map(|s| s.contains(" ")).unwrap_or(false) ||
         src.to_str().map(|s| s.contains(" ")).unwrap_or(false));
    if wants_space_error {
        panic!("\n\nunfortunately ./configure of libcurl is known to \
                fail if there's a space in the path to the current \
                directory\n\n\
                there's a space in either\n  {}\n  {}\nand this will cause the \
                build to fail\n\n\
                the MSVC build should work with a directory that has \
                spaces in it, and it would also work to move this to a \
                different directory without spaces\n\n",
               src.display(), dst.display())
    }

    if windows {
        cmd.arg("--with-winssl");
    } else {
        cmd.arg("--without-ca-bundle");
        cmd.arg("--without-ca-path");

        // DEP_OPENSSL_ROOT was what cargo used to use via overrides, and
        // OPENSSL_ROOT_DIR is also used by libssh2 which cargo uses and can be
        // set by various build scripts.
        let openssl_root = env::var("DEP_OPENSSL_ROOT").or_else(|_| {
            env::var("OPENSSL_ROOT_DIR")
        });
        if let Ok(s) = openssl_root {
            cmd.arg(format!("--with-ssl={}", s));
        }
    }
    cmd.arg("--enable-static=yes");
    cmd.arg("--enable-shared=no");
    match &env::var("PROFILE").unwrap()[..] {
        "bench" | "release" => {
            cmd.arg("--enable-optimize");
        }
        _ => {
            cmd.arg("--enable-debug");
            cmd.arg("--disable-optimize");
        }
    }
    cmd.arg(format!("--prefix={}", msys_compatible(&dst)));

    if target != host &&
       (!target.contains("windows") || !host.contains("windows")) {
        cmd.arg(format!("--host={}", host));
        cmd.arg(format!("--target={}", target));
    }

    cmd.arg("--without-librtmp");
    cmd.arg("--without-libidn");
    cmd.arg("--without-libssh2");
    cmd.arg("--without-nghttp2");
    cmd.arg("--disable-ldap");
    cmd.arg("--disable-ldaps");
    cmd.arg("--disable-ftp");
    cmd.arg("--disable-rtsp");
    cmd.arg("--disable-dict");
    cmd.arg("--disable-telnet");
    cmd.arg("--disable-tftp");
    cmd.arg("--disable-pop3");
    cmd.arg("--disable-imap");
    cmd.arg("--disable-smtp");
    cmd.arg("--disable-gopher");
    cmd.arg("--disable-manual");
    cmd.arg("--disable-smb");
    cmd.arg("--disable-sspi");

    run(&mut cmd, "sh");
    run(Command::new(make())
                .arg(&format!("-j{}", env::var("NUM_JOBS").unwrap()))
                .current_dir(&dst.join("build")), "make");
    run(Command::new(make())
                .arg("install")
                .current_dir(&dst.join("build")), "make");
}

fn run(cmd: &mut Command, program: &str) {
    println!("running: {:?}", cmd);
    let status = match cmd.status() {
        Ok(status) => status,
        Err(ref e) if e.kind() == ErrorKind::NotFound => {
            fail(&format!("failed to execute command: {}\nis `{}` not installed?",
                          e, program));
        }
        Err(e) => fail(&format!("failed to execute command: {}", e)),
    };
    if !status.success() {
        fail(&format!("command did not execute successfully, got: {}", status));
    }
}

fn fail(s: &str) -> ! {
    panic!("\n{}\n\nbuild script failed, must exit now", s)
}

fn make() -> &'static str {
    if cfg!(target_os = "freebsd") {"gmake"} else {"make"}
}

fn which(cmd: &str) -> Option<PathBuf> {
    let cmd = format!("{}{}", cmd, env::consts::EXE_SUFFIX);
    let paths = env::var_os("PATH").unwrap();
    env::split_paths(&paths).map(|p| p.join(&cmd)).find(|p| {
        fs::metadata(p).is_ok()
    })
}

fn msys_compatible(path: &Path) -> String {
    let path = path.to_str().unwrap();
    if !cfg!(windows) {
        return path.to_string()
    }
    path.replace("C:\\", "/c/")
        .replace("\\", "/")
}

fn build_msvc(target: &str) {
    let cmd = gcc::windows_registry::find(target, "nmake.exe");
    let mut cmd = cmd.unwrap_or(Command::new("nmake.exe"));
    let src = env::current_dir().unwrap();
    let dst = PathBuf::from(env::var_os("OUT_DIR").unwrap());
    let machine = if target.starts_with("x86_64") {
        "x64"
    } else if target.starts_with("i686") {
        "x86"
    } else {
        panic!("unknown msvc target: {}", target);
    };

    t!(fs::create_dir_all(dst.join("include/curl")));
    t!(fs::create_dir_all(dst.join("lib")));

    cmd.current_dir(src.join("curl/winbuild"));
    cmd.arg("/f").arg("Makefile.vc")
       .arg("MODE=static")
       .arg("ENABLE_IDN=yes")
       .arg("DEBUG=no")
       .arg("GEN_PDB=no")
       .arg("ENABLE_WINSSL=yes")
       .arg("ENABLE_SSPI=yes")
       .arg(format!("MACHINE={}", machine));

    if let Some(inc) = env::var_os("DEP_Z_ROOT") {
        let inc = PathBuf::from(inc);
        let mut s = OsString::from("WITH_DEVEL=");
        s.push(&inc);
        cmd.arg("WITH_ZLIB=static").arg(s);

        // the build system for curl expects this library to be called
        // zlib_a.lib, so make sure it's named correctly (where libz-sys just
        // produces zlib.lib)
        let _ = fs::remove_file(&inc.join("lib/zlib_a.lib"));
        t!(fs::hard_link(inc.join("lib/zlib.lib"), inc.join("lib/zlib_a.lib")));
    }
    run(&mut cmd, "nmake");

    let name = format!("libcurl-vc-{}-release-static-zlib-static-\
                        ipv6-sspi-winssl", machine);
    let libs = src.join("curl/builds").join(name);

    t!(fs::copy(libs.join("lib/libcurl_a.lib"), dst.join("lib/curl.lib")));
    for f in t!(fs::read_dir(libs.join("include/curl"))) {
        let path = t!(f).path();
        let dst = dst.join("include/curl").join(path.file_name().unwrap());
        t!(fs::copy(path, dst));
    }
    t!(fs::remove_dir_all(src.join("curl/builds")));
    println!("cargo:rustc-link-lib=wldap32");
    println!("cargo:rustc-link-lib=advapi32");
    println!("cargo:rustc-link-lib=normaliz");
}
<commit_msg>Support custom OpenSSL by looking at INCLUDE<commit_after>extern crate pkg_config;
extern crate gcc;

use std::env;
use std::ffi::OsString;
use std::fs;
use std::path::{PathBuf, Path};
use std::process::Command;
use std::io::ErrorKind;

macro_rules! t {
    ($e:expr) => (match $e {
        Ok(t) => t,
        Err(e) => panic!("{} return the error {}", stringify!($e), e),
    })
}

fn main() {
    let target = env::var("TARGET").unwrap();
    let host = env::var("HOST").unwrap();
    let src = env::current_dir().unwrap();
    let dst = PathBuf::from(env::var_os("OUT_DIR").unwrap());
    let windows = target.contains("windows");

    // OSX ships libcurl by default, so we just use that version
    // unconditionally.
    if target.contains("apple") {
        return println!("cargo:rustc-flags=-l curl");
    }

    // Illumos/Solaris requires explicit linking with libnsl
    if target.contains("solaris") {
        println!("cargo:rustc-flags=-l nsl");
    }

    // Next, fall back and try to use pkg-config if its available.
    if !target.contains("windows") {
        match pkg_config::find_library("libcurl") {
            Ok(lib) => {
                for path in lib.include_paths.iter() {
                    println!("cargo:include={}", path.display());
                }
                return
            }
            Err(e) => println!("Couldn't find libcurl from \
                               pkgconfig ({:?}), compiling it from source...", e),
        }
    }

    if !Path::new("curl/.git").exists() {
        let _ = Command::new("git").args(&["submodule", "update", "--init"])
                                   .status();
    }

    println!("cargo:rustc-link-search={}/lib", dst.display());
    println!("cargo:rustc-link-lib=static=curl");
    println!("cargo:root={}", dst.display());
    println!("cargo:include={}/include", dst.display());
    if windows {
        println!("cargo:rustc-link-lib=ws2_32");
        println!("cargo:rustc-link-lib=crypt32");
    }

    // MSVC builds are just totally different
    if target.contains("msvc") {
        return build_msvc(&target);
    }

    let cfg = gcc::Config::new();
    let compiler = cfg.get_compiler();

    let _ = fs::create_dir(&dst.join("build"));

    let mut cmd = Command::new("sh");
    let mut cflags = OsString::new();
    for arg in compiler.args() {
        cflags.push(arg);
        cflags.push(" ");
    }

    // Can't run ./configure directly on msys2 b/c we're handing in
    // Windows-style paths (those starting with C:\), but it chokes on those.
    // For that reason we build up a shell script with paths converted to
    // posix versions hopefully...
    //
    // Also apparently the buildbots choke unless we manually set LD, who knows
    // why?!
    cmd.env("CC", compiler.path())
       .env("CFLAGS", cflags)
       .env("LD", &which("ld").unwrap())
       .env("VERBOSE", "1")
       .current_dir(&dst.join("build"))
       .arg(msys_compatible(&src.join("curl/configure")));

    // For now this build script doesn't support paths with spaces in them. This
    // is arguably a but in curl's configure script, but we could also try to
    // paper over it by using a tmp directory which *doesn't* have spaces in it.
    // As of now though that's not implemented so just give a nicer error for
    // the time being.
    let wants_space_error = windows &&
        (dst.to_str().map(|s| s.contains(" ")).unwrap_or(false) ||
         src.to_str().map(|s| s.contains(" ")).unwrap_or(false));
    if wants_space_error {
        panic!("\n\nunfortunately ./configure of libcurl is known to \
                fail if there's a space in the path to the current \
                directory\n\n\
                there's a space in either\n  {}\n  {}\nand this will cause the \
                build to fail\n\n\
                the MSVC build should work with a directory that has \
                spaces in it, and it would also work to move this to a \
                different directory without spaces\n\n",
               src.display(), dst.display())
    }

    if windows {
        cmd.arg("--with-winssl");
    } else {
        cmd.arg("--without-ca-bundle");
        cmd.arg("--without-ca-path");

        // DEP_OPENSSL_ROOT was what cargo used to use via overrides, and
        // OPENSSL_ROOT_DIR is also used by libssh2 which cargo uses and can be
        // set by various build scripts.
        let openssl_root = env::var_os("DEP_OPENSSL_ROOT").or_else(|| {
            env::var_os("OPENSSL_ROOT_DIR")
        }).or_else(|| {
            env::var_os("DEP_OPENSSL_INCLUDE").and_then(|include| {
                let root = Path::new(&include).parent().unwrap();
                if root.exists() {
                    Some(root.as_os_str().to_owned())
                } else {
                    None
                }
            })
        });
        if let Some(s) = openssl_root {
            cmd.arg(format!("--with-ssl={}", s.to_str().unwrap()));
        }
    }
    cmd.arg("--enable-static=yes");
    cmd.arg("--enable-shared=no");
    match &env::var("PROFILE").unwrap()[..] {
        "bench" | "release" => {
            cmd.arg("--enable-optimize");
        }
        _ => {
            cmd.arg("--enable-debug");
            cmd.arg("--disable-optimize");
        }
    }
    cmd.arg(format!("--prefix={}", msys_compatible(&dst)));

    if target != host &&
       (!target.contains("windows") || !host.contains("windows")) {
        cmd.arg(format!("--host={}", host));
        cmd.arg(format!("--target={}", target));
    }

    cmd.arg("--without-librtmp");
    cmd.arg("--without-libidn");
    cmd.arg("--without-libssh2");
    cmd.arg("--without-nghttp2");
    cmd.arg("--disable-ldap");
    cmd.arg("--disable-ldaps");
    cmd.arg("--disable-ftp");
    cmd.arg("--disable-rtsp");
    cmd.arg("--disable-dict");
    cmd.arg("--disable-telnet");
    cmd.arg("--disable-tftp");
    cmd.arg("--disable-pop3");
    cmd.arg("--disable-imap");
    cmd.arg("--disable-smtp");
    cmd.arg("--disable-gopher");
    cmd.arg("--disable-manual");
    cmd.arg("--disable-smb");
    cmd.arg("--disable-sspi");

    run(&mut cmd, "sh");
    run(Command::new(make())
                .arg(&format!("-j{}", env::var("NUM_JOBS").unwrap()))
                .current_dir(&dst.join("build")), "make");
    run(Command::new(make())
                .arg("install")
                .current_dir(&dst.join("build")), "make");
}

fn run(cmd: &mut Command, program: &str) {
    println!("running: {:?}", cmd);
    let status = match cmd.status() {
        Ok(status) => status,
        Err(ref e) if e.kind() == ErrorKind::NotFound => {
            fail(&format!("failed to execute command: {}\nis `{}` not installed?",
                          e, program));
        }
        Err(e) => fail(&format!("failed to execute command: {}", e)),
    };
    if !status.success() {
        fail(&format!("command did not execute successfully, got: {}", status));
    }
}

fn fail(s: &str) -> ! {
    panic!("\n{}\n\nbuild script failed, must exit now", s)
}

fn make() -> &'static str {
    if cfg!(target_os = "freebsd") {"gmake"} else {"make"}
}

fn which(cmd: &str) -> Option<PathBuf> {
    let cmd = format!("{}{}", cmd, env::consts::EXE_SUFFIX);
    let paths = env::var_os("PATH").unwrap();
    env::split_paths(&paths).map(|p| p.join(&cmd)).find(|p| {
        fs::metadata(p).is_ok()
    })
}

fn msys_compatible(path: &Path) -> String {
    let path = path.to_str().unwrap();
    if !cfg!(windows) {
        return path.to_string()
    }
    path.replace("C:\\", "/c/")
        .replace("\\", "/")
}

fn build_msvc(target: &str) {
    let cmd = gcc::windows_registry::find(target, "nmake.exe");
    let mut cmd = cmd.unwrap_or(Command::new("nmake.exe"));
    let src = env::current_dir().unwrap();
    let dst = PathBuf::from(env::var_os("OUT_DIR").unwrap());
    let machine = if target.starts_with("x86_64") {
        "x64"
    } else if target.starts_with("i686") {
        "x86"
    } else {
        panic!("unknown msvc target: {}", target);
    };

    t!(fs::create_dir_all(dst.join("include/curl")));
    t!(fs::create_dir_all(dst.join("lib")));

    cmd.current_dir(src.join("curl/winbuild"));
    cmd.arg("/f").arg("Makefile.vc")
       .arg("MODE=static")
       .arg("ENABLE_IDN=yes")
       .arg("DEBUG=no")
       .arg("GEN_PDB=no")
       .arg("ENABLE_WINSSL=yes")
       .arg("ENABLE_SSPI=yes")
       .arg(format!("MACHINE={}", machine));

    if let Some(inc) = env::var_os("DEP_Z_ROOT") {
        let inc = PathBuf::from(inc);
        let mut s = OsString::from("WITH_DEVEL=");
        s.push(&inc);
        cmd.arg("WITH_ZLIB=static").arg(s);

        // the build system for curl expects this library to be called
        // zlib_a.lib, so make sure it's named correctly (where libz-sys just
        // produces zlib.lib)
        let _ = fs::remove_file(&inc.join("lib/zlib_a.lib"));
        t!(fs::hard_link(inc.join("lib/zlib.lib"), inc.join("lib/zlib_a.lib")));
    }
    run(&mut cmd, "nmake");

    let name = format!("libcurl-vc-{}-release-static-zlib-static-\
                        ipv6-sspi-winssl", machine);
    let libs = src.join("curl/builds").join(name);

    t!(fs::copy(libs.join("lib/libcurl_a.lib"), dst.join("lib/curl.lib")));
    for f in t!(fs::read_dir(libs.join("include/curl"))) {
        let path = t!(f).path();
        let dst = dst.join("include/curl").join(path.file_name().unwrap());
        t!(fs::copy(path, dst));
    }
    t!(fs::remove_dir_all(src.join("curl/builds")));
    println!("cargo:rustc-link-lib=wldap32");
    println!("cargo:rustc-link-lib=advapi32");
    println!("cargo:rustc-link-lib=normaliz");
}
<|endoftext|>


<commit_before>#![allow(unused)]
#[macro_use(s)]
extern crate ndarray;
extern crate num;

use num::Float;

use ndarray::{
    ArrayView,
    ArrayViewMut,
    OwnedArray,
    Ix,
};

type Ix2 = (Ix, Ix);
const SOBEL_X: [[f32; 3]; 3] = [[-1., 0., 1.], [-2., 0., 2.], [-1., 0., 1.]];
const SOBEL_Y: [[f32; 3]; 3] = [[ 1., 2., 1.], [ 0., 0., 0.], [-1., -2., -1.]];
const SHARPEN: [[f32; 3]; 3] = [[0., -1., 0.], [ -1., 5., -1.], [0., -1., 0.]];

type Kernel3x3<A> = [[A; 3]; 3];

#[inline(never)]
fn conv_3x3<F>(a: &ArrayView<F, Ix2>, out: &mut ArrayViewMut<F, Ix2>, kernel: &Kernel3x3<F>)
    where F: Float,
{
    let (n, m) = a.dim();
    let (np, mp) = out.dim();
    if n < 3 || m < 3 {
        return;
    }
    assert!(np >= n && mp >= m);
    // i, j offset by -1 so that we can use unsigned indices
    unsafe {
        for i in 0..n - 2 {
            for j in 0..m - 2 {
                let mut conv = F::zero();
                for k in 0..3 {
                    for l in 0..3 {
                        conv = conv + *a.uget((i + k, j + l)) * kernel[k][l];
                        //conv += a[[i + k, j + l]] * x_kernel[k][l];
                    }
                }
                *out.uget_mut((i + 1, j + 1)) = conv;
            }
        }
    }
}

fn main() {
    let n = 16;
    let mut a = OwnedArray::zeros((n, n));
    // make a circle
    let c = (8., 8.);
    for ((i, j), elt) in a.indexed_iter_mut() {
        {
            let s = ((i as f32) - c.0).powi(2) + (j as f32 - c.1).powi(2);
            if s.sqrt() > 3. && s.sqrt() < 6. {
                *elt = 1.;
            }
        }
    }
    println!("{:?}", a);
    let mut res = OwnedArray::zeros(a.dim());
    for _ in 0..1000 {
        conv_3x3(&a.view(), &mut res.view_mut(), &SOBEL_X);
    }
    println!("{:?}", res);
}
<commit_msg>Fix printout in convo.rs to be padded better<commit_after>#![allow(unused)]
#[macro_use(s)]
extern crate ndarray;
extern crate num;

use num::Float;

use ndarray::{
    ArrayView,
    ArrayViewMut,
    OwnedArray,
    Ix,
};

type Ix2 = (Ix, Ix);
const SOBEL_X: [[f32; 3]; 3] = [[-1., 0., 1.], [-2., 0., 2.], [-1., 0., 1.]];
const SOBEL_Y: [[f32; 3]; 3] = [[ 1., 2., 1.], [ 0., 0., 0.], [-1., -2., -1.]];
const SHARPEN: [[f32; 3]; 3] = [[0., -1., 0.], [ -1., 5., -1.], [0., -1., 0.]];

type Kernel3x3<A> = [[A; 3]; 3];

#[inline(never)]
fn conv_3x3<F>(a: &ArrayView<F, Ix2>, out: &mut ArrayViewMut<F, Ix2>, kernel: &Kernel3x3<F>)
    where F: Float,
{
    let (n, m) = a.dim();
    let (np, mp) = out.dim();
    if n < 3 || m < 3 {
        return;
    }
    assert!(np >= n && mp >= m);
    // i, j offset by -1 so that we can use unsigned indices
    unsafe {
        for i in 0..n - 2 {
            for j in 0..m - 2 {
                let mut conv = F::zero();
                for k in 0..3 {
                    for l in 0..3 {
                        conv = conv + *a.uget((i + k, j + l)) * kernel[k][l];
                        //conv += a[[i + k, j + l]] * x_kernel[k][l];
                    }
                }
                *out.uget_mut((i + 1, j + 1)) = conv;
            }
        }
    }
}

fn main() {
    let n = 16;
    let mut a = OwnedArray::zeros((n, n));
    // make a circle
    let c = (8., 8.);
    for ((i, j), elt) in a.indexed_iter_mut() {
        {
            let s = ((i as f32) - c.0).powi(2) + (j as f32 - c.1).powi(2);
            if s.sqrt() > 3. && s.sqrt() < 6. {
                *elt = 1.;
            }
        }
    }
    println!("{:2}", a);
    let mut res = OwnedArray::zeros(a.dim());
    for _ in 0..1000 {
        conv_3x3(&a.view(), &mut res.view_mut(), &SOBEL_X);
    }
    println!("{:2}", res);
}
<|endoftext|>