<commit_before>// leave this to allow easy breakpoints on assembly wrappers like _write for now
#![allow(private_no_mangle_fns)]

use std::str;
use std::slice;

// TODO: make this a mod like asm::

#[no_mangle]
pub extern fn _exit(code: u64) {
    unsafe {
        asm!("movq $$60, %rax
              syscall"
             :
             : "{rdi}"(code)
             );
    }
}

// this comes from asm.s
extern {
    fn _print(msg: *const u8, len: u64);
}

/*
fn _print(msg: *const u8, len: u64) {
    unsafe {
        let slice = slice::from_raw_parts(msg, len as usize);
        println!("{:?}", &slice);
    }
}
*/

#[no_mangle]
pub unsafe extern fn write(msg: &str){
    _print(msg.as_ptr(), msg.len() as u64);
}

/*
#[cfg(debug_assertions)]
macro_rules! debug_write {
    ($($t:tt)*) => {
        unsafe {
            write($($t)*)
        }
    }
}

#[cfg(not(debug_assertions))]
macro_rules! debug_write {
    ($($t:tt)*) => {
    }
}
*/

/*
// this is _totally_ broken and is massively side-effectful and unpredicatable
#[no_mangle]
pub extern fn write(msg: &str) {
    unsafe {
        asm!("pushq %rdi
              pushq %rax
              pushq %rdx
              pushq %rsi
              movq $$1, %rax
              movq $$1, %rdi
              syscall
              popq %rsi
              popq %rdx
              popq %rax
              popq %rdi
              "
             :
             : "{rsi}"(msg.as_ptr()), "{rdx}"(msg.len())
//             : "{rdi}","{rax}", "{rdx}", "{rsi}"
             //             :"{rsi}"(msg.as_ptr()), "{rdx}"(msg.len())
             //
             );
    }
}
*/
fn digit_to_char_code(i: u8) -> u8 {
    if i <= 9 {
        i + 48
    }else{
        0
    }
}

fn num_digits(i: u64) -> usize {
    if i == 0 {
        1
    } else {
        let mut count = 0;
        let mut current = i;
        while current > 0 {
            current /= 10;
            count += 1;
        }
        count
    }
}

#[test]
fn num_digits_t() {
    assert_eq!(num_digits(0), 1);
    assert_eq!(num_digits(10), 2);
    assert_eq!(num_digits(99), 2);
    assert_eq!(num_digits(999), 3);
}

#[no_mangle]
pub unsafe extern fn write_u64(i: u64, base16: bool) {
    if base16 {
        write(to_hex(&i, &mut [0; 16]));
    } else {
        let count = num_digits(i);
        let mut _stack = [0; 20];
        let mut chars = &mut _stack[0..count];
        let mut place = count;
        let mut current = i;
        let mut digit;
        loop {
            digit = current % 10;
            current = (current - digit) / 10;
            place -= 1;
            chars[place] = digit_to_char_code(digit as u8);
            if current <= 0 { break; }
        }
        write(str::from_utf8(chars).unwrap());
    }
}

fn to_hex<'a>(i: &u64, output: &'a mut[u8; 16]) -> &'a str {
    let mut input = *i;
    let hex = b"0123456789abcdef";
    let mut buffer = [0; 16];
    let mut i = 0;
    let mut j = 0;
    if input == 0 {
        buffer[0] = hex[0];
        i = 1;
    } else {
        while input > 0 {
            buffer[i] = hex[(input % 16) as usize];
            input = input / 16;
            i += 1;
        }
    }

    while i > 0 {
        i -= 1;
        output[j] = buffer[i];
        j += 1;
    }

    str::from_utf8(output).unwrap().trim_matches('\0')
}

pub fn as_str<'a>(cs: *const u8) -> &'a str {
    if cs.is_null() {
        ""
    }else {
        unsafe {
            let mut i = 0;
            let mut c = *cs;
            while c != 0 {
                i += 1;
                c = *cs.offset(i);
            }
            let slice = slice::from_raw_parts(cs, i as usize);
            str::from_utf8(slice).unwrap()
        }
    }
}

pub fn str_at<'a>(cs: *const u8, offset: isize) -> &'a str {
    if cs.is_null() {
        ""
    }else {
        let mut i = 0;
        unsafe {
            let ptr = cs.offset(offset);
            let mut c = *ptr;
            while c != 0 {
                i += 1;
                c = *ptr.offset(i);
            }
            let slice = slice::from_raw_parts(ptr, i as usize);
            str::from_utf8(slice).unwrap()
        }
    }
}

pub unsafe extern fn write_chars_at(cs: *const u8) {
    write(as_str(cs));
}

pub mod page {
   // from <sys/user.h>
    pub const PAGE_SHIFT:u64 = 12;
    pub const PAGE_SIZE:u64 = 1 << PAGE_SHIFT;
    pub const PAGE_MASK:u64 = !(PAGE_SIZE - 1);

    // from bionic
    /// Returns the address of the page containing address 'x'.
    #[inline(always)]
    pub fn page_start (x:u64) -> u64 { x & PAGE_MASK }

    /// Returns the offset of address 'x' in its page.
    #[inline(always)]
    pub fn page_offset (x:u64) -> u64 { x & !PAGE_MASK }

    /// Returns the address of the next page after address 'x', unless 'x' is
    /// itself at the start of a page.
    #[inline(always)]
    pub fn page_end (x:u64) -> u64 { page_start(x + (PAGE_SIZE - 1)) }

}

pub mod mmap {

    pub const PROT_READ:isize = 0x1; /* Page can be read.  */
    pub const PROT_WRITE:isize = 0x2; /* Page can be written.  */
    pub const PROT_EXEC:isize = 0x4; /* Page can be executed.  */
    pub const PROT_NONE:isize = 0x0; /* Page can not be accessed.  */
    pub const PROT_GROWSDOWN:isize = 0x01000000; /* Extend change to start of growsdown vma (mprotect only).  */
    pub const PROT_GROWSUP:isize = 0x02000000; /* Extend change to start of growsup vma (mprotect only).  */

    /* Sharing types (must choose one and only one of these).  */
    pub const MAP_SHARED:isize = 0x01; /* Share changes.  */
    pub const MAP_PRIVATE:isize = 0x02; /* Changes are private.  */
    pub const MAP_ANONYMOUS:isize = 0x20; // just guessing, this is wrapped in a ifdef with __MAP_ANONYMOUS as the value
    /* Other flags.  */
    pub const MAP_FIXED:isize = 0x10; /* Interpret addr exactly.  */

    /// map failed, from sys/mman.h, technically ((void *) - 1) ...
    pub const MAP_FAILED:u64 = !0;

    // from musl libc
    use std::os::raw::{c_int};
    extern {
        pub fn mmap(addr: *const u64, len: usize, prot: isize, flags: c_int, fildes: c_int, off: usize) -> u64;
    }

}
<commit_msg>swap use location<commit_after>// leave this to allow easy breakpoints on assembly wrappers like _write for now
#![allow(private_no_mangle_fns)]

use std::os::raw::{c_int};

use std::str;
use std::slice;

// TODO: make this a mod like asm::

#[no_mangle]
pub extern fn _exit(code: u64) {
    unsafe {
        asm!("movq $$60, %rax
              syscall"
             :
             : "{rdi}"(code)
             );
    }
}

// this comes from asm.s
extern {
    fn _print(msg: *const u8, len: u64);
}

/*
fn _print(msg: *const u8, len: u64) {
    unsafe {
        let slice = slice::from_raw_parts(msg, len as usize);
        println!("{:?}", &slice);
    }
}
*/

#[no_mangle]
pub unsafe extern fn write(msg: &str){
    _print(msg.as_ptr(), msg.len() as u64);
}

/*
#[cfg(debug_assertions)]
macro_rules! debug_write {
    ($($t:tt)*) => {
        unsafe {
            write($($t)*)
        }
    }
}

#[cfg(not(debug_assertions))]
macro_rules! debug_write {
    ($($t:tt)*) => {
    }
}
*/

/*
// this is _totally_ broken and is massively side-effectful and unpredicatable
#[no_mangle]
pub extern fn write(msg: &str) {
    unsafe {
        asm!("pushq %rdi
              pushq %rax
              pushq %rdx
              pushq %rsi
              movq $$1, %rax
              movq $$1, %rdi
              syscall
              popq %rsi
              popq %rdx
              popq %rax
              popq %rdi
              "
             :
             : "{rsi}"(msg.as_ptr()), "{rdx}"(msg.len())
//             : "{rdi}","{rax}", "{rdx}", "{rsi}"
             //             :"{rsi}"(msg.as_ptr()), "{rdx}"(msg.len())
             //
             );
    }
}
*/
fn digit_to_char_code(i: u8) -> u8 {
    if i <= 9 {
        i + 48
    }else{
        0
    }
}

fn num_digits(i: u64) -> usize {
    if i == 0 {
        1
    } else {
        let mut count = 0;
        let mut current = i;
        while current > 0 {
            current /= 10;
            count += 1;
        }
        count
    }
}

#[test]
fn num_digits_t() {
    assert_eq!(num_digits(0), 1);
    assert_eq!(num_digits(10), 2);
    assert_eq!(num_digits(99), 2);
    assert_eq!(num_digits(999), 3);
}

#[no_mangle]
pub unsafe extern fn write_u64(i: u64, base16: bool) {
    if base16 {
        write(to_hex(&i, &mut [0; 16]));
    } else {
        let count = num_digits(i);
        let mut _stack = [0; 20];
        let mut chars = &mut _stack[0..count];
        let mut place = count;
        let mut current = i;
        let mut digit;
        loop {
            digit = current % 10;
            current = (current - digit) / 10;
            place -= 1;
            chars[place] = digit_to_char_code(digit as u8);
            if current <= 0 { break; }
        }
        write(str::from_utf8(chars).unwrap());
    }
}

fn to_hex<'a>(i: &u64, output: &'a mut[u8; 16]) -> &'a str {
    let mut input = *i;
    let hex = b"0123456789abcdef";
    let mut buffer = [0; 16];
    let mut i = 0;
    let mut j = 0;
    if input == 0 {
        buffer[0] = hex[0];
        i = 1;
    } else {
        while input > 0 {
            buffer[i] = hex[(input % 16) as usize];
            input = input / 16;
            i += 1;
        }
    }

    while i > 0 {
        i -= 1;
        output[j] = buffer[i];
        j += 1;
    }

    str::from_utf8(output).unwrap().trim_matches('\0')
}

pub fn as_str<'a>(cs: *const u8) -> &'a str {
    if cs.is_null() {
        ""
    }else {
        unsafe {
            let mut i = 0;
            let mut c = *cs;
            while c != 0 {
                i += 1;
                c = *cs.offset(i);
            }
            let slice = slice::from_raw_parts(cs, i as usize);
            str::from_utf8(slice).unwrap()
        }
    }
}

pub fn str_at<'a>(cs: *const u8, offset: isize) -> &'a str {
    if cs.is_null() {
        ""
    }else {
        let mut i = 0;
        unsafe {
            let ptr = cs.offset(offset);
            let mut c = *ptr;
            while c != 0 {
                i += 1;
                c = *ptr.offset(i);
            }
            let slice = slice::from_raw_parts(ptr, i as usize);
            str::from_utf8(slice).unwrap()
        }
    }
}

pub unsafe extern fn write_chars_at(cs: *const u8) {
    write(as_str(cs));
}

pub mod page {
   // from <sys/user.h>
    pub const PAGE_SHIFT:u64 = 12;
    pub const PAGE_SIZE:u64 = 1 << PAGE_SHIFT;
    pub const PAGE_MASK:u64 = !(PAGE_SIZE - 1);

    // from bionic
    /// Returns the address of the page containing address 'x'.
    #[inline(always)]
    pub fn page_start (x:u64) -> u64 { x & PAGE_MASK }

    /// Returns the offset of address 'x' in its page.
    #[inline(always)]
    pub fn page_offset (x:u64) -> u64 { x & !PAGE_MASK }

    /// Returns the address of the next page after address 'x', unless 'x' is
    /// itself at the start of a page.
    #[inline(always)]
    pub fn page_end (x:u64) -> u64 { page_start(x + (PAGE_SIZE - 1)) }

}

pub mod mmap {

    pub const PROT_READ:isize = 0x1; /* Page can be read.  */
    pub const PROT_WRITE:isize = 0x2; /* Page can be written.  */
    pub const PROT_EXEC:isize = 0x4; /* Page can be executed.  */
    pub const PROT_NONE:isize = 0x0; /* Page can not be accessed.  */
    pub const PROT_GROWSDOWN:isize = 0x01000000; /* Extend change to start of growsdown vma (mprotect only).  */
    pub const PROT_GROWSUP:isize = 0x02000000; /* Extend change to start of growsup vma (mprotect only).  */

    /* Sharing types (must choose one and only one of these).  */
    pub const MAP_SHARED:isize = 0x01; /* Share changes.  */
    pub const MAP_PRIVATE:isize = 0x02; /* Changes are private.  */
    pub const MAP_ANONYMOUS:isize = 0x20; // just guessing, this is wrapped in a ifdef with __MAP_ANONYMOUS as the value
    /* Other flags.  */
    pub const MAP_FIXED:isize = 0x10; /* Interpret addr exactly.  */

    /// map failed, from sys/mman.h, technically ((void *) - 1) ...
    pub const MAP_FAILED:u64 = !0;

    // from musl libc
    extern {
        pub fn mmap(addr: *const u64, len: usize, prot: isize, flags: c_int, fildes: c_int, off: usize) -> u64;
    }

}
<|endoftext|>


<commit_before>use std::path::{Path, PathBuf};
use std::io;
use std::fs;
use std::fs::File;
use std::io::Read;
use std::collections::HashMap;
use std::hash::Hash;
use std;
use log;

#[cfg(all(windows, target_env = "msvc"))]
pub fn is_msvc() -> bool {
  true
}

#[cfg(not(all(windows, target_env = "msvc")))]
pub fn is_msvc() -> bool {
  false
}

pub trait JoinWithString<S> {
  fn join(self, separator: S) -> String;
}

impl<S, S2, X> JoinWithString<S2> for X
  where S: AsRef<str>,
        S2: AsRef<str>,
        X: Iterator<Item = S>
{
  fn join(self, separator: S2) -> String {
    self.fold("".to_string(), |a, b| {
      let m = if a.len() > 0 {
        a + separator.as_ref()
      } else {
        a
      };
      m + b.as_ref()
    })
  }
}

pub trait PathBufPushTweak {
  fn with_added<P: AsRef<Path>>(&self, path: P) -> PathBuf;
}

impl PathBufPushTweak for PathBuf {
  fn with_added<P: AsRef<Path>>(&self, path: P) -> PathBuf {
    let mut p = self.clone();
    p.push(path);
    p
  }
}

impl PathBufPushTweak for Path {
  fn with_added<P: AsRef<Path>>(&self, path: P) -> PathBuf {
    let mut p = self.to_path_buf();
    p.push(path);
    p
  }
}

pub fn move_files(src: &PathBuf, dst: &PathBuf) -> io::Result<()> {
  if src.as_path().is_dir() {
    if !dst.as_path().is_dir() {
      log::info(format!("New dir created: {}", dst.to_str().unwrap()));
      try!(fs::create_dir(dst));
    }

    for item in try!(fs::read_dir(dst)) {
      let item = try!(item);
      if !src.with_added(item.file_name()).as_path().exists() {
        let path = item.path();
        if path.as_path().is_dir() {
          log::info(format!("Old dir removed: {}", path.to_str().unwrap()));
          try!(fs::remove_dir_all(path));
        } else {
          log::info(format!("Old file removed: {}", path.to_str().unwrap()));
          try!(fs::remove_file(path));
        }
      }
    }

    for item in try!(fs::read_dir(src)) {
      let item = try!(item);
      try!(move_files(&item.path().to_path_buf(),
                      &dst.with_added(item.file_name())));
    }
    try!(fs::remove_dir_all(src));
  } else {
    try!(move_one_file(src, dst));
  }
  Ok(())
}

pub fn copy_recursively(src: &PathBuf, dst: &PathBuf) -> io::Result<()> {
  if src.as_path().is_dir() {
    try!(fs::create_dir(dst));
    for item in try!(fs::read_dir(src)) {
      let item = try!(item);
      try!(copy_recursively(&item.path().to_path_buf(),
                            &dst.with_added(item.file_name())));
    }
  } else {
    try!(fs::copy(src, dst));
  }
  Ok(())
}

pub fn move_one_file(old_path: &PathBuf, new_path: &PathBuf) -> io::Result<()> {
  let is_changed = if new_path.as_path().is_file() {
    let mut string1 = String::new();
    let mut string2 = String::new();
    try!(try!(File::open(old_path)).read_to_string(&mut string1));
    try!(try!(File::open(new_path)).read_to_string(&mut string2));
    string1 != string2
  } else {
    true
  };

  if is_changed {
    if new_path.as_path().exists() {
      try!(fs::remove_file(new_path));
    }
    try!(fs::rename(old_path, new_path));
    log::noisy(format!("File changed: {}", new_path.to_str().unwrap()));
  } else {
    try!(fs::remove_file(old_path));
    log::noisy(format!("File not changed: {}", new_path.to_str().unwrap()));
  }
  Ok(())
}

#[derive(PartialEq, Debug)]
enum WordCase {
  Upper,
  Lower,
  Capitalized,
}

pub struct WordIterator<'a> {
  string: &'a str,
  index: usize,
  previous_word_case: Option<WordCase>,
}

impl<'a> WordIterator<'a> {
  pub fn new(string: &str) -> WordIterator {
    WordIterator {
      string: string,
      index: 0,
      previous_word_case: None,
    }
  }
}

impl<'a> Iterator for WordIterator<'a> {
  type Item = &'a str;
  fn next(&mut self) -> Option<&'a str> {
    while self.index < self.string.len() && &self.string[self.index..self.index + 1] == "_" {
      self.index = self.index + 1;
    }
    if self.index >= self.string.len() {
      return None;
    }
    let mut i = self.index;
    let mut word_case = WordCase::Lower;
    while i < self.string.len() {
      let current = &self.string[i..i + 1].chars().next().unwrap();
      if current == &'_' {
        break;
      }
      if i - self.index == 0 {
        // first letter
        if current.is_uppercase() {
          word_case = WordCase::Capitalized;
        } else {
          word_case = WordCase::Lower;
        }
      } else if i - self.index == 1 {
        if current.is_uppercase() {
          if word_case == WordCase::Capitalized {
            let next_not_upper = if i + 1 < self.string.len() {
              !self.string[i + 1..i + 2].chars().next().unwrap().is_uppercase()
            } else {
              true
            };
            if next_not_upper || self.previous_word_case == Some(WordCase::Capitalized) {
              break;
            } else {
              word_case = WordCase::Upper;
            }
          } else if word_case == WordCase::Lower {
            break;
          }
        }
      } else {
        match word_case {
          WordCase::Lower | WordCase::Capitalized => {
            if current.is_uppercase() {
              break;
            }
          }
          WordCase::Upper => {
            if !current.is_uppercase() {
              break;
            }
          }
        }
      }
      i = i + 1;
    }
    let result = &self.string[self.index..i];
    self.index = i;
    self.previous_word_case = Some(word_case);
    return Some(result);
  }
}

pub trait CaseOperations {
  fn to_class_case(&self) -> String;
  fn to_snake_case(&self) -> String;
}
pub trait VecCaseOperations {
  fn to_class_case(self) -> String;
  fn to_snake_case(self) -> String;
}

fn iterator_to_class_case<'a, S: AsRef<str>, T: Iterator<Item = S>>(it: T) -> String {
  it.map(|x| {
      format!("{}{}",
              x.as_ref()[0..1].to_uppercase(),
              x.as_ref()[1..].to_lowercase())
    })
    .join("")
}

fn iterator_to_snake_case<'a, S: AsRef<str>, T: Iterator<Item = S>>(it: T) -> String {
  it.map(|x| x.as_ref().to_lowercase()).join("_")
}

fn replace_all_sub_vecs(parts: &mut Vec<String>, needle: Vec<&str>) {
  let mut any_found = true;
  while any_found {
    any_found = false;
    if parts.len() + 1 >= needle.len() {
      for i in 0..parts.len() + 1 - needle.len() {
        if &parts[i..i + needle.len()] == &needle[..] {
          for _ in 0..needle.len() - 1 {
            parts.remove(i + 1);
          }
          parts[i] = needle.join("");
          any_found = true;
          break;
        }
      }
    }
  }
}

impl CaseOperations for String {
  fn to_class_case(&self) -> Self {
    iterator_to_class_case(WordIterator::new(self))
  }
  fn to_snake_case(&self) -> Self {
    let mut parts: Vec<_> = WordIterator::new(self).map(|x| x.to_lowercase()).collect();
    replace_all_sub_vecs(&mut parts, vec!["na", "n"]);
    replace_all_sub_vecs(&mut parts, vec!["open", "g", "l"]);
    parts.join("_")
  }
}

impl<'a> VecCaseOperations for Vec<&'a str> {
  fn to_class_case(self) -> String {
    iterator_to_class_case(self.into_iter())
  }
  fn to_snake_case(self) -> String {
    iterator_to_snake_case(self.into_iter())
  }
}

pub fn add_to_multihash<K: Eq + Hash + Clone, T, V: Default + Extend<T>>(hash: &mut HashMap<K, V>,
                                                                         key: &K,
                                                                         value: T) {
  if !hash.contains_key(key) {
    hash.insert(key.clone(), Default::default());
  }
  hash.get_mut(key).unwrap().extend(std::iter::once(value));
}
<commit_msg>move_files log removed<commit_after>use std::path::{Path, PathBuf};
use std::io;
use std::fs;
use std::fs::File;
use std::io::Read;
use std::collections::HashMap;
use std::hash::Hash;
use std;
use log;

#[cfg(all(windows, target_env = "msvc"))]
pub fn is_msvc() -> bool {
  true
}

#[cfg(not(all(windows, target_env = "msvc")))]
pub fn is_msvc() -> bool {
  false
}

pub trait JoinWithString<S> {
  fn join(self, separator: S) -> String;
}

impl<S, S2, X> JoinWithString<S2> for X
  where S: AsRef<str>,
        S2: AsRef<str>,
        X: Iterator<Item = S>
{
  fn join(self, separator: S2) -> String {
    self.fold("".to_string(), |a, b| {
      let m = if a.len() > 0 {
        a + separator.as_ref()
      } else {
        a
      };
      m + b.as_ref()
    })
  }
}

pub trait PathBufPushTweak {
  fn with_added<P: AsRef<Path>>(&self, path: P) -> PathBuf;
}

impl PathBufPushTweak for PathBuf {
  fn with_added<P: AsRef<Path>>(&self, path: P) -> PathBuf {
    let mut p = self.clone();
    p.push(path);
    p
  }
}

impl PathBufPushTweak for Path {
  fn with_added<P: AsRef<Path>>(&self, path: P) -> PathBuf {
    let mut p = self.to_path_buf();
    p.push(path);
    p
  }
}

pub fn move_files(src: &PathBuf, dst: &PathBuf) -> io::Result<()> {
  if src.as_path().is_dir() {
    if !dst.as_path().is_dir() {
      log::noisy(format!("New dir created: {}", dst.to_str().unwrap()));
      try!(fs::create_dir(dst));
    }

    for item in try!(fs::read_dir(dst)) {
      let item = try!(item);
      if !src.with_added(item.file_name()).as_path().exists() {
        let path = item.path();
        if path.as_path().is_dir() {
          log::noisy(format!("Old dir removed: {}", path.to_str().unwrap()));
          try!(fs::remove_dir_all(path));
        } else {
          log::noisy(format!("Old file removed: {}", path.to_str().unwrap()));
          try!(fs::remove_file(path));
        }
      }
    }

    for item in try!(fs::read_dir(src)) {
      let item = try!(item);
      try!(move_files(&item.path().to_path_buf(),
                      &dst.with_added(item.file_name())));
    }
    try!(fs::remove_dir_all(src));
  } else {
    try!(move_one_file(src, dst));
  }
  Ok(())
}

pub fn copy_recursively(src: &PathBuf, dst: &PathBuf) -> io::Result<()> {
  if src.as_path().is_dir() {
    try!(fs::create_dir(dst));
    for item in try!(fs::read_dir(src)) {
      let item = try!(item);
      try!(copy_recursively(&item.path().to_path_buf(),
                            &dst.with_added(item.file_name())));
    }
  } else {
    try!(fs::copy(src, dst));
  }
  Ok(())
}

pub fn move_one_file(old_path: &PathBuf, new_path: &PathBuf) -> io::Result<()> {
  let is_changed = if new_path.as_path().is_file() {
    let mut string1 = String::new();
    let mut string2 = String::new();
    try!(try!(File::open(old_path)).read_to_string(&mut string1));
    try!(try!(File::open(new_path)).read_to_string(&mut string2));
    string1 != string2
  } else {
    true
  };

  if is_changed {
    if new_path.as_path().exists() {
      try!(fs::remove_file(new_path));
    }
    try!(fs::rename(old_path, new_path));
    log::noisy(format!("File changed: {}", new_path.to_str().unwrap()));
  } else {
    try!(fs::remove_file(old_path));
    log::noisy(format!("File not changed: {}", new_path.to_str().unwrap()));
  }
  Ok(())
}

#[derive(PartialEq, Debug)]
enum WordCase {
  Upper,
  Lower,
  Capitalized,
}

pub struct WordIterator<'a> {
  string: &'a str,
  index: usize,
  previous_word_case: Option<WordCase>,
}

impl<'a> WordIterator<'a> {
  pub fn new(string: &str) -> WordIterator {
    WordIterator {
      string: string,
      index: 0,
      previous_word_case: None,
    }
  }
}

impl<'a> Iterator for WordIterator<'a> {
  type Item = &'a str;
  fn next(&mut self) -> Option<&'a str> {
    while self.index < self.string.len() && &self.string[self.index..self.index + 1] == "_" {
      self.index = self.index + 1;
    }
    if self.index >= self.string.len() {
      return None;
    }
    let mut i = self.index;
    let mut word_case = WordCase::Lower;
    while i < self.string.len() {
      let current = &self.string[i..i + 1].chars().next().unwrap();
      if current == &'_' {
        break;
      }
      if i - self.index == 0 {
        // first letter
        if current.is_uppercase() {
          word_case = WordCase::Capitalized;
        } else {
          word_case = WordCase::Lower;
        }
      } else if i - self.index == 1 {
        if current.is_uppercase() {
          if word_case == WordCase::Capitalized {
            let next_not_upper = if i + 1 < self.string.len() {
              !self.string[i + 1..i + 2].chars().next().unwrap().is_uppercase()
            } else {
              true
            };
            if next_not_upper || self.previous_word_case == Some(WordCase::Capitalized) {
              break;
            } else {
              word_case = WordCase::Upper;
            }
          } else if word_case == WordCase::Lower {
            break;
          }
        }
      } else {
        match word_case {
          WordCase::Lower | WordCase::Capitalized => {
            if current.is_uppercase() {
              break;
            }
          }
          WordCase::Upper => {
            if !current.is_uppercase() {
              break;
            }
          }
        }
      }
      i = i + 1;
    }
    let result = &self.string[self.index..i];
    self.index = i;
    self.previous_word_case = Some(word_case);
    return Some(result);
  }
}

pub trait CaseOperations {
  fn to_class_case(&self) -> String;
  fn to_snake_case(&self) -> String;
}
pub trait VecCaseOperations {
  fn to_class_case(self) -> String;
  fn to_snake_case(self) -> String;
}

fn iterator_to_class_case<'a, S: AsRef<str>, T: Iterator<Item = S>>(it: T) -> String {
  it.map(|x| {
      format!("{}{}",
              x.as_ref()[0..1].to_uppercase(),
              x.as_ref()[1..].to_lowercase())
    })
    .join("")
}

fn iterator_to_snake_case<'a, S: AsRef<str>, T: Iterator<Item = S>>(it: T) -> String {
  it.map(|x| x.as_ref().to_lowercase()).join("_")
}

fn replace_all_sub_vecs(parts: &mut Vec<String>, needle: Vec<&str>) {
  let mut any_found = true;
  while any_found {
    any_found = false;
    if parts.len() + 1 >= needle.len() {
      for i in 0..parts.len() + 1 - needle.len() {
        if &parts[i..i + needle.len()] == &needle[..] {
          for _ in 0..needle.len() - 1 {
            parts.remove(i + 1);
          }
          parts[i] = needle.join("");
          any_found = true;
          break;
        }
      }
    }
  }
}

impl CaseOperations for String {
  fn to_class_case(&self) -> Self {
    iterator_to_class_case(WordIterator::new(self))
  }
  fn to_snake_case(&self) -> Self {
    let mut parts: Vec<_> = WordIterator::new(self).map(|x| x.to_lowercase()).collect();
    replace_all_sub_vecs(&mut parts, vec!["na", "n"]);
    replace_all_sub_vecs(&mut parts, vec!["open", "g", "l"]);
    parts.join("_")
  }
}

impl<'a> VecCaseOperations for Vec<&'a str> {
  fn to_class_case(self) -> String {
    iterator_to_class_case(self.into_iter())
  }
  fn to_snake_case(self) -> String {
    iterator_to_snake_case(self.into_iter())
  }
}

pub fn add_to_multihash<K: Eq + Hash + Clone, T, V: Default + Extend<T>>(hash: &mut HashMap<K, V>,
                                                                         key: &K,
                                                                         value: T) {
  if !hash.contains_key(key) {
    hash.insert(key.clone(), Default::default());
  }
  hash.get_mut(key).unwrap().extend(std::iter::once(value));
}
<|endoftext|>


<commit_before>use libc::{c_char, c_uint, c_int};
use ffi::prelude::LLVMValueRef;
use ffi::{core, LLVMAttribute};
use std::ffi::CString;
use std::{fmt, mem, ptr};
use std::ops::{Deref, Index};
use block::BasicBlock;
use context::{Context, GetContext};
use ty::{FunctionType, Type};
use util::{self, CastFrom};

/// A typed value that can be used as an operand in instructions.
pub struct Value;
native_ref!(&Value = LLVMValueRef);
impl Value {
    /// Create a new constant struct from the values given.
    pub fn new_struct<'a>(context: &'a Context, vals: &[&'a Value], packed: bool) -> &'a Value {
        unsafe { core::LLVMConstStructInContext(context.into(), vals.as_ptr() as *mut LLVMValueRef, vals.len() as c_uint, packed as c_int) }.into()
    }
    /// Create a new constant vector from the values given.
    pub fn new_vector<'a>(vals: &[&'a Value]) -> &'a Value {
        unsafe { core::LLVMConstVector(vals.as_ptr() as *mut LLVMValueRef, vals.len() as c_uint).into() }
    }
    /// Create a new constant C string from the text given.
    pub fn new_string<'a>(context: &'a Context, text: &str, rust_style: bool) -> &'a Value {
        unsafe {
            let ptr = text.as_ptr() as *const c_char;
            let len = text.len() as c_uint;
            core::LLVMConstStringInContext(context.into(), ptr, len, rust_style as c_int).into()
        }
    }
    /// Create a new constant undefined value of the given type.
    pub fn new_undef<'a>(ty: &'a Type) -> &'a Value {
        unsafe { core::LLVMGetUndef(ty.into()).into() }
    }
    /// Returns the name of this value, or `None` if it lacks a name
    pub fn get_name(&self) -> Option<&str> {
        unsafe {
            let c_name = core::LLVMGetValueName(self.into());
            util::to_null_str(c_name as *mut i8)
        }
    }
    /// Sets the name of this value
    pub fn set_name(&self, name: &str) {
        let c_name = CString::new(name).unwrap();
        unsafe {
            core::LLVMSetValueName(self.into(), c_name.as_ptr())
        }
    }
    /// Returns the type of this value
    pub fn get_type(&self) -> &Type {
        unsafe { core::LLVMTypeOf(self.into()) }.into()
    }
}

pub struct GlobalValue;
native_ref!(&GlobalValue = LLVMValueRef);
deref!(GlobalValue, Value);

impl GlobalValue
{
	/// Sets the initial value for this global.
	pub fn set_initializer(&self, value: &Value)
	{
	  unsafe { core::LLVMSetInitializer(self.into(), value.into()) }
	}

	/// Gets the initial value for this global.
	pub fn get_initializer(&self) -> &Value
	{
	  unsafe { core::LLVMGetInitializer(self.into()) }.into()
	}
}

impl CastFrom for GlobalValue
{
  type From = Value;

  fn cast<'a>(val: &'a Value) -> Option<&'a GlobalValue>
  {
    let gv = unsafe { core::LLVMIsAGlobalValue(val.into()) };
    if gv == ptr::null_mut() {
      None
    } else {
      Some(gv.into())
    }
 }
}

/// Comparative operations on values.
#[derive(Copy, Clone, Eq, PartialEq)]
pub enum Predicate {
    Equal,
    NotEqual,
    GreaterThan,
    GreaterThanOrEqual,
    LessThan,
    LessThanOrEqual
}
/// A function argument.
pub struct Arg;
native_ref!(&Arg = LLVMValueRef);
impl Deref for Arg {
    type Target = Value;
    fn deref(&self) -> &Value {
        unsafe { mem::transmute(self) }
    }
}
impl Arg {
    /// Add the attribute given to this argument.
    pub fn add_attribute(&self, attr: Attribute) {
        unsafe { core::LLVMAddAttribute(self.into(), attr.into()) }
    }
    /// Add all the attributes given to this argument.
    pub fn add_attributes(&self, attrs: &[Attribute]) {
        let mut sum = LLVMAttribute::empty();
        for attr in attrs {
            let attr:LLVMAttribute = (*attr).into();
            sum = sum | attr;
        }
        unsafe { core::LLVMAddAttribute(self.into(), sum.into()) }
    }
    /// Returns true if this argument has the attribute given.
    pub fn has_attribute(&self, attr: Attribute) -> bool {
        unsafe {
            let other = core::LLVMGetAttribute(self.into());
            other.contains(attr.into())
        }
    }
    /// Returns true if this argument has all the attributes given.
    pub fn has_attributes(&self, attrs: &[Attribute]) -> bool {
        unsafe {
            let other = core::LLVMGetAttribute(self.into());
            for &attr in attrs {
                if !other.contains(attr.into()) {
                    return false;
                }
            }
            return true;
        }
    }
    /// Remove an attribute from this argument.
    pub fn remove_attribute(&self, attr: Attribute) {
        unsafe { core::LLVMRemoveAttribute(self.into(), attr.into()) }
    }
}
/// A function that can be called and contains blocks.
pub struct Function;
native_ref!(&Function = LLVMValueRef);
impl Deref for Function {
    type Target = Value;
    fn deref(&self) -> &Value {
        unsafe { mem::transmute(self) }
    }
}
impl Index<usize> for Function {
    type Output = Arg;
    fn index(&self, index: usize) -> &Arg {
        unsafe {
            if index < core::LLVMCountParams(self.into()) as usize {
                core::LLVMGetParam(self.into(), index as c_uint).into()
            } else {
                panic!("no such index {} on {:?}", index, self.get_type())
            }
        }
    }
}
impl CastFrom for Function {
    type From = Value;
    fn cast<'a>(val: &'a Value) -> Option<&'a Function> {
        let ty = val.get_type();
        let mut is_func = ty.is_function();
        if let Some(elem) = ty.get_element() {
            is_func = is_func || elem.is_function()
        }
        if is_func {
            Some(unsafe { mem::transmute(val) })
        } else {
            None
        }
    }
}
impl Function {
    /// Add a basic block with the name given to the function and return it.
    pub fn append<'a>(&'a self, name: &str) -> &'a BasicBlock {
        util::with_cstr(name, |ptr| unsafe {
            core::LLVMAppendBasicBlockInContext(self.get_context().into(), self.into(), ptr).into()
        })
    }
    /// Returns the entry block of this function or `None` if there is none.
    pub fn get_entry(&self) -> Option<&BasicBlock> {
        unsafe { mem::transmute(core::LLVMGetEntryBasicBlock(self.into())) }
    }
    /// Returns the name of this function.
    pub fn get_name(&self) -> &str {
        unsafe {
            let c_name = core::LLVMGetValueName(self.into());
            util::to_str(c_name as *mut i8)
        }
    }
    /// Returns the function signature representing this function's signature.
    pub fn get_signature(&self) -> &FunctionType {
        unsafe {
            let ty = core::LLVMTypeOf(self.into());
            core::LLVMGetElementType(ty).into()
        }
    }
    /// Add the attribute given to this function.
    pub fn add_attribute(&self, attr: Attribute) {
        unsafe { core::LLVMAddFunctionAttr(self.into(), attr.into()) }
    }
    /// Add all the attributes given to this function.
    pub fn add_attributes(&self, attrs: &[Attribute]) {
        let mut sum = LLVMAttribute::empty();
        for attr in attrs {
            let attr:LLVMAttribute = (*attr).into();
            sum = sum | attr;
        }
        unsafe { core::LLVMAddFunctionAttr(self.into(), sum.into()) }
    }
    /// Returns true if the attribute given is set in this function.
    pub fn has_attribute(&self, attr: Attribute) -> bool {
        unsafe {
            let other = core::LLVMGetFunctionAttr(self.into());
            other.contains(attr.into())
        }
    }
    /// Returns true if all the attributes given is set in this function.
    pub fn has_attributes(&self, attrs: &[Attribute]) -> bool {
        unsafe {
            let other = core::LLVMGetFunctionAttr(self.into());
            for &attr in attrs {
                if !other.contains(attr.into()) {
                    return false;
                }
            }
            return true;
        }
    }
    /// Remove the attribute given from this function.
    pub fn remove_attribute(&self, attr: Attribute) {
        unsafe { core::LLVMRemoveFunctionAttr(self.into(), attr.into()) }
    }
}
impl GetContext for Function {
    fn get_context(&self) -> &Context {
        self.get_type().get_context()
    }
}
/// A way of indicating to LLVM how you want arguments / functions to be handled.
#[derive(Copy, Clone, Eq, PartialEq, Debug)]
#[repr(C)]
pub enum Attribute {
    /// Zero-extended before or after call.
    ZExt =              0b1,
    /// Sign-extended before or after call.
    SExt =              0b10,
    /// Mark the function as not returning.
    NoReturn =          0b100,
    /// Force argument to be passed in register.
    InReg =             0b1000,
    /// Hidden pointer to structure to return.
    StructRet =         0b10000,
    /// Function doesn't unwind stack.
    NoUnwind =          0b100000,
    /// Consider to not alias after call.
    NoAlias =           0b1000000,
    /// Pass structure by value.
    ByVal =             0b10000000,
    /// Nested function static chain.
    Nest =              0b100000000,
    /// Function doesn't access memory.
    ReadNone =          0b1000000000,
    /// Function only reads from memory.
    ReadOnly =          0b10000000000,
    /// Never inline this function.
    NoInline =          0b100000000000,
    /// Always inline this function.
    AlwaysInline =      0b1000000000000,
    /// Optimize this function for size.
    OptimizeForSize =   0b10000000000000,
    /// Stack protection.
    StackProtect =      0b100000000000000,
    /// Stack protection required.
    StackProtectReq =   0b1000000000000000,
    /// Alignment of parameter (5 bits) stored as log2 of alignment with +1 bias 0 means unaligned (different from align(1)).
    Alignment =         0b10000000000000000,
    /// Function creates no aliases of pointer.
    NoCapture =         0b100000000000000000,
    /// Disable redzone.
    NoRedZone =         0b1000000000000000000,
    /// Disable implicit float instructions.
    NoImplicitFloat =   0b10000000000000000000,
    /// Naked function.
    Naked =             0b100000000000000000000,
    /// The source language has marked this function as inline.
    InlineHint =        0b1000000000000000000000,
    /// Alignment of stack for function (3 bits) stored as log2 of alignment with +1 bias 0 means unaligned (different from alignstack=(1)).
    StackAlignment =    0b11100000000000000000000000000,
    /// This function returns twice.
    ReturnsTwice =      0b100000000000000000000000000000,
    /// Function must be in unwind table.
    UWTable =           0b1000000000000000000000000000000,
    /// Function is called early/often, so lazy binding isn't effective.
    NonLazyBind =       0b10000000000000000000000000000000
}
impl From<LLVMAttribute> for Attribute {
    fn from(attr: LLVMAttribute) -> Attribute {
        unsafe { mem::transmute(attr) }
    }
}
impl From<Attribute> for LLVMAttribute {
    fn from(attr: Attribute) -> LLVMAttribute {
        unsafe { mem::transmute(attr) }
    }
}
impl GetContext for Value {
    fn get_context(&self) -> &Context {
        self.get_type().get_context()
    }
}
impl_display!(Value, LLVMPrintValueToString);

/// Value Iterator implementation.
///
/// T can be all descendent types of LLVMValueRef.
#[derive(Copy, Clone)]
pub struct ValueIter<'a, T: From<LLVMValueRef>> {
  cur    : LLVMValueRef,
  step   : unsafe extern "C" fn(LLVMValueRef) -> LLVMValueRef,
  marker1: ::std::marker::PhantomData<&'a ()>,
  marker2: ::std::marker::PhantomData<T>,
}

impl<'a, T: From<LLVMValueRef>> ValueIter<'a, T>
{
	pub fn new(cur: LLVMValueRef,
		         step: unsafe extern "C" fn(LLVMValueRef) -> LLVMValueRef) -> Self
	{
		ValueIter {
			cur: cur,
			step: step,
			marker1: ::std::marker::PhantomData,
			marker2: ::std::marker::PhantomData
		}
	}
}

impl<'a, T: From<LLVMValueRef>> Iterator for ValueIter<'a, T> {
  type Item = T;

  fn next(&mut self) -> Option<T> {
    let old: LLVMValueRef = self.cur;
      if !old.is_null() {
        self.cur = unsafe { (self.step)(old) };
        Some(old.into())
      } else {
        None
      }
    }
}<commit_msg>Implement IntoIterator for &Arg.<commit_after>use libc::{c_char, c_uint, c_int};
use ffi::prelude::LLVMValueRef;
use ffi::{core, LLVMAttribute};
use std::ffi::CString;
use std::{fmt, mem, ptr};
use std::ops::{Deref, Index};
use block::BasicBlock;
use context::{Context, GetContext};
use ty::{FunctionType, Type};
use util::{self, CastFrom};

/// A typed value that can be used as an operand in instructions.
pub struct Value;
native_ref!(&Value = LLVMValueRef);
impl Value {
    /// Create a new constant struct from the values given.
    pub fn new_struct<'a>(context: &'a Context, vals: &[&'a Value], packed: bool) -> &'a Value {
        unsafe { core::LLVMConstStructInContext(context.into(), vals.as_ptr() as *mut LLVMValueRef, vals.len() as c_uint, packed as c_int) }.into()
    }
    /// Create a new constant vector from the values given.
    pub fn new_vector<'a>(vals: &[&'a Value]) -> &'a Value {
        unsafe { core::LLVMConstVector(vals.as_ptr() as *mut LLVMValueRef, vals.len() as c_uint).into() }
    }
    /// Create a new constant C string from the text given.
    pub fn new_string<'a>(context: &'a Context, text: &str, rust_style: bool) -> &'a Value {
        unsafe {
            let ptr = text.as_ptr() as *const c_char;
            let len = text.len() as c_uint;
            core::LLVMConstStringInContext(context.into(), ptr, len, rust_style as c_int).into()
        }
    }
    /// Create a new constant undefined value of the given type.
    pub fn new_undef<'a>(ty: &'a Type) -> &'a Value {
        unsafe { core::LLVMGetUndef(ty.into()).into() }
    }
    /// Returns the name of this value, or `None` if it lacks a name
    pub fn get_name(&self) -> Option<&str> {
        unsafe {
            let c_name = core::LLVMGetValueName(self.into());
            util::to_null_str(c_name as *mut i8)
        }
    }
    /// Sets the name of this value
    pub fn set_name(&self, name: &str) {
        let c_name = CString::new(name).unwrap();
        unsafe {
            core::LLVMSetValueName(self.into(), c_name.as_ptr())
        }
    }
    /// Returns the type of this value
    pub fn get_type(&self) -> &Type {
        unsafe { core::LLVMTypeOf(self.into()) }.into()
    }
}

pub struct GlobalValue;
native_ref!(&GlobalValue = LLVMValueRef);
deref!(GlobalValue, Value);

impl GlobalValue
{
	/// Sets the initial value for this global.
	pub fn set_initializer(&self, value: &Value)
	{
	  unsafe { core::LLVMSetInitializer(self.into(), value.into()) }
	}

	/// Gets the initial value for this global.
	pub fn get_initializer(&self) -> &Value
	{
	  unsafe { core::LLVMGetInitializer(self.into()) }.into()
	}
}

impl CastFrom for GlobalValue
{
  type From = Value;

  fn cast<'a>(val: &'a Value) -> Option<&'a GlobalValue>
  {
    let gv = unsafe { core::LLVMIsAGlobalValue(val.into()) };
    if gv == ptr::null_mut() {
      None
    } else {
      Some(gv.into())
    }
 }
}

/// Comparative operations on values.
#[derive(Copy, Clone, Eq, PartialEq)]
pub enum Predicate {
    Equal,
    NotEqual,
    GreaterThan,
    GreaterThanOrEqual,
    LessThan,
    LessThanOrEqual
}
/// A function argument.
pub struct Arg;
native_ref!(&Arg = LLVMValueRef);
impl Deref for Arg {
    type Target = Value;
    fn deref(&self) -> &Value {
        unsafe { mem::transmute(self) }
    }
}
impl Arg {
    /// Add the attribute given to this argument.
    pub fn add_attribute(&self, attr: Attribute) {
        unsafe { core::LLVMAddAttribute(self.into(), attr.into()) }
    }
    /// Add all the attributes given to this argument.
    pub fn add_attributes(&self, attrs: &[Attribute]) {
        let mut sum = LLVMAttribute::empty();
        for attr in attrs {
            let attr:LLVMAttribute = (*attr).into();
            sum = sum | attr;
        }
        unsafe { core::LLVMAddAttribute(self.into(), sum.into()) }
    }
    /// Returns true if this argument has the attribute given.
    pub fn has_attribute(&self, attr: Attribute) -> bool {
        unsafe {
            let other = core::LLVMGetAttribute(self.into());
            other.contains(attr.into())
        }
    }
    /// Returns true if this argument has all the attributes given.
    pub fn has_attributes(&self, attrs: &[Attribute]) -> bool {
        unsafe {
            let other = core::LLVMGetAttribute(self.into());
            for &attr in attrs {
                if !other.contains(attr.into()) {
                    return false;
                }
            }
            return true;
        }
    }
    /// Remove an attribute from this argument.
    pub fn remove_attribute(&self, attr: Attribute) {
        unsafe { core::LLVMRemoveAttribute(self.into(), attr.into()) }
    }
}

/// A function that can be called and contains blocks.
pub struct Function;
native_ref!(&Function = LLVMValueRef);
impl Deref for Function {
    type Target = Value;
    fn deref(&self) -> &Value {
        unsafe { mem::transmute(self) }
    }
}
impl Index<usize> for Function {
    type Output = Arg;
    fn index(&self, index: usize) -> &Arg {
        unsafe {
            if index < core::LLVMCountParams(self.into()) as usize {
                core::LLVMGetParam(self.into(), index as c_uint).into()
            } else {
                panic!("no such index {} on {:?}", index, self.get_type())
            }
        }
    }
}
impl CastFrom for Function {
    type From = Value;
    fn cast<'a>(val: &'a Value) -> Option<&'a Function> {
        let ty = val.get_type();
        let mut is_func = ty.is_function();
        if let Some(elem) = ty.get_element() {
            is_func = is_func || elem.is_function()
        }
        if is_func {
            Some(unsafe { mem::transmute(val) })
        } else {
            None
        }
    }
}
impl Function {
    /// Add a basic block with the name given to the function and return it.
    pub fn append<'a>(&'a self, name: &str) -> &'a BasicBlock {
        util::with_cstr(name, |ptr| unsafe {
            core::LLVMAppendBasicBlockInContext(self.get_context().into(), self.into(), ptr).into()
        })
    }
    /// Returns the entry block of this function or `None` if there is none.
    pub fn get_entry(&self) -> Option<&BasicBlock> {
        unsafe { mem::transmute(core::LLVMGetEntryBasicBlock(self.into())) }
    }
    /// Returns the name of this function.
    pub fn get_name(&self) -> &str {
        unsafe {
            let c_name = core::LLVMGetValueName(self.into());
            util::to_str(c_name as *mut i8)
        }
    }
    /// Returns the function signature representing this function's signature.
    pub fn get_signature(&self) -> &FunctionType {
        unsafe {
            let ty = core::LLVMTypeOf(self.into());
            core::LLVMGetElementType(ty).into()
        }
    }
    /// Add the attribute given to this function.
    pub fn add_attribute(&self, attr: Attribute) {
        unsafe { core::LLVMAddFunctionAttr(self.into(), attr.into()) }
    }
    /// Add all the attributes given to this function.
    pub fn add_attributes(&self, attrs: &[Attribute]) {
        let mut sum = LLVMAttribute::empty();
        for attr in attrs {
            let attr:LLVMAttribute = (*attr).into();
            sum = sum | attr;
        }
        unsafe { core::LLVMAddFunctionAttr(self.into(), sum.into()) }
    }
    /// Returns true if the attribute given is set in this function.
    pub fn has_attribute(&self, attr: Attribute) -> bool {
        unsafe {
            let other = core::LLVMGetFunctionAttr(self.into());
            other.contains(attr.into())
        }
    }
    /// Returns true if all the attributes given is set in this function.
    pub fn has_attributes(&self, attrs: &[Attribute]) -> bool {
        unsafe {
            let other = core::LLVMGetFunctionAttr(self.into());
            for &attr in attrs {
                if !other.contains(attr.into()) {
                    return false;
                }
            }
            return true;
        }
    }
    /// Remove the attribute given from this function.
    pub fn remove_attribute(&self, attr: Attribute) {
        unsafe { core::LLVMRemoveFunctionAttr(self.into(), attr.into()) }
    }
}

impl<'a> IntoIterator for &'a Function
{
  type Item = &'a Arg;
  type IntoIter = ValueIter<'a, &'a Arg>;
  /// Iterate through the functions in the module
  fn into_iter(self) -> ValueIter<'a, &'a Arg>
  {
 		ValueIter::new(
 			unsafe { core::LLVMGetFirstParam(self.into()) },
 			core::LLVMGetNextParam
 		)
  }
}

impl GetContext for Function {
    fn get_context(&self) -> &Context {
        self.get_type().get_context()
    }
}
/// A way of indicating to LLVM how you want arguments / functions to be handled.
#[derive(Copy, Clone, Eq, PartialEq, Debug)]
#[repr(C)]
pub enum Attribute {
    /// Zero-extended before or after call.
    ZExt =              0b1,
    /// Sign-extended before or after call.
    SExt =              0b10,
    /// Mark the function as not returning.
    NoReturn =          0b100,
    /// Force argument to be passed in register.
    InReg =             0b1000,
    /// Hidden pointer to structure to return.
    StructRet =         0b10000,
    /// Function doesn't unwind stack.
    NoUnwind =          0b100000,
    /// Consider to not alias after call.
    NoAlias =           0b1000000,
    /// Pass structure by value.
    ByVal =             0b10000000,
    /// Nested function static chain.
    Nest =              0b100000000,
    /// Function doesn't access memory.
    ReadNone =          0b1000000000,
    /// Function only reads from memory.
    ReadOnly =          0b10000000000,
    /// Never inline this function.
    NoInline =          0b100000000000,
    /// Always inline this function.
    AlwaysInline =      0b1000000000000,
    /// Optimize this function for size.
    OptimizeForSize =   0b10000000000000,
    /// Stack protection.
    StackProtect =      0b100000000000000,
    /// Stack protection required.
    StackProtectReq =   0b1000000000000000,
    /// Alignment of parameter (5 bits) stored as log2 of alignment with +1 bias 0 means unaligned (different from align(1)).
    Alignment =         0b10000000000000000,
    /// Function creates no aliases of pointer.
    NoCapture =         0b100000000000000000,
    /// Disable redzone.
    NoRedZone =         0b1000000000000000000,
    /// Disable implicit float instructions.
    NoImplicitFloat =   0b10000000000000000000,
    /// Naked function.
    Naked =             0b100000000000000000000,
    /// The source language has marked this function as inline.
    InlineHint =        0b1000000000000000000000,
    /// Alignment of stack for function (3 bits) stored as log2 of alignment with +1 bias 0 means unaligned (different from alignstack=(1)).
    StackAlignment =    0b11100000000000000000000000000,
    /// This function returns twice.
    ReturnsTwice =      0b100000000000000000000000000000,
    /// Function must be in unwind table.
    UWTable =           0b1000000000000000000000000000000,
    /// Function is called early/often, so lazy binding isn't effective.
    NonLazyBind =       0b10000000000000000000000000000000
}
impl From<LLVMAttribute> for Attribute {
    fn from(attr: LLVMAttribute) -> Attribute {
        unsafe { mem::transmute(attr) }
    }
}
impl From<Attribute> for LLVMAttribute {
    fn from(attr: Attribute) -> LLVMAttribute {
        unsafe { mem::transmute(attr) }
    }
}
impl GetContext for Value {
    fn get_context(&self) -> &Context {
        self.get_type().get_context()
    }
}
impl_display!(Value, LLVMPrintValueToString);

/// Value Iterator implementation.
///
/// T can be all descendent types of LLVMValueRef.
#[derive(Copy, Clone)]
pub struct ValueIter<'a, T: From<LLVMValueRef>> {
  cur    : LLVMValueRef,
  step   : unsafe extern "C" fn(LLVMValueRef) -> LLVMValueRef,
  marker1: ::std::marker::PhantomData<&'a ()>,
  marker2: ::std::marker::PhantomData<T>,
}

impl<'a, T: From<LLVMValueRef>> ValueIter<'a, T>
{
	pub fn new(cur: LLVMValueRef,
		         step: unsafe extern "C" fn(LLVMValueRef) -> LLVMValueRef) -> Self
	{
		ValueIter {
			cur: cur,
			step: step,
			marker1: ::std::marker::PhantomData,
			marker2: ::std::marker::PhantomData
		}
	}
}

impl<'a, T: From<LLVMValueRef>> Iterator for ValueIter<'a, T> {
  type Item = T;

  fn next(&mut self) -> Option<T> {
    let old: LLVMValueRef = self.cur;
      if !old.is_null() {
        self.cur = unsafe { (self.step)(old) };
        Some(old.into())
      } else {
        None
      }
    }
}<|endoftext|>


<commit_before>pub type c_char = i8;
pub type wchar_t = i32;

s! {
    pub struct mcontext_t {
        __private: [u32; 22]
    }

    pub struct ucontext_t {
        pub uc_flags: ::c_ulong,
        pub uc_link: *mut ucontext_t,
        pub uc_stack: ::stack_t,
        pub uc_mcontext: mcontext_t,
        pub uc_sigmask: ::sigset_t,
        __private: [u8; 112],
    }
}

pub const O_DIRECT: ::c_int = 0x4000;
pub const O_DIRECTORY: ::c_int = 0x10000;
pub const O_NOFOLLOW: ::c_int = 0x20000;

pub const MAP_LOCKED: ::c_int = 0x02000;
pub const MAP_NORESERVE: ::c_int = 0x04000;
pub const MAP_32BIT: ::c_int = 0x0040;

pub const EDEADLOCK: ::c_int = 35;

pub const SO_PEERCRED: ::c_int = 17;
pub const SO_RCVLOWAT: ::c_int = 18;
pub const SO_SNDLOWAT: ::c_int = 19;
pub const SO_RCVTIMEO: ::c_int = 20;
pub const SO_SNDTIMEO: ::c_int = 21;

pub const FIOCLEX: ::c_ulong = 0x5451;
pub const FIONBIO: ::c_ulong = 0x5421;

pub const SYS_gettid: ::c_long = 224;
pub const SYS_perf_event_open: ::c_long = 336;

extern {
    pub fn getcontext(ucp: *mut ucontext_t) -> ::c_int;
    pub fn setcontext(ucp: *const ucontext_t) -> ::c_int;
    pub fn makecontext(ucp: *mut ucontext_t,
                       func:  extern fn (),
                       argc: ::c_int, ...);
    pub fn swapcontext(uocp: *mut ucontext_t,
                       ucp: *const ucontext_t) -> ::c_int;
}
<commit_msg>Refine definition of mcontext_t on x86.<commit_after>pub type c_char = i8;
pub type wchar_t = i32;
pub type greg_t = i32;

s! {
    pub struct _libc_fpreg {
        pub significand: [u16; 4],
        pub exponent: u16,
    }

    pub struct _libc_fpstate {
        pub cw: ::c_ulong,
        pub sw: ::c_ulong,
        pub tag: ::c_ulong,
        pub ipoff: ::c_ulong,
        pub cssel: ::c_ulong,
        pub dataoff: ::c_ulong,
        pub datasel: ::c_ulong,
        pub _st: [_libc_fpreg; 8],
        pub status: ::c_ulong,
    }

    pub struct mcontext_t {
        pub gregs: [greg_t; 19],
        pub fpregs: *mut _libc_fpstate,
        pub oldmask: ::c_ulong,
        pub cr2: ::c_ulong,
    }

    pub struct ucontext_t {
        pub uc_flags: ::c_ulong,
        pub uc_link: *mut ucontext_t,
        pub uc_stack: ::stack_t,
        pub uc_mcontext: mcontext_t,
        pub uc_sigmask: ::sigset_t,
        __private: [u8; 112],
    }
}

pub const O_DIRECT: ::c_int = 0x4000;
pub const O_DIRECTORY: ::c_int = 0x10000;
pub const O_NOFOLLOW: ::c_int = 0x20000;

pub const MAP_LOCKED: ::c_int = 0x02000;
pub const MAP_NORESERVE: ::c_int = 0x04000;
pub const MAP_32BIT: ::c_int = 0x0040;

pub const EDEADLOCK: ::c_int = 35;

pub const SO_PEERCRED: ::c_int = 17;
pub const SO_RCVLOWAT: ::c_int = 18;
pub const SO_SNDLOWAT: ::c_int = 19;
pub const SO_RCVTIMEO: ::c_int = 20;
pub const SO_SNDTIMEO: ::c_int = 21;

pub const FIOCLEX: ::c_ulong = 0x5451;
pub const FIONBIO: ::c_ulong = 0x5421;

pub const SYS_gettid: ::c_long = 224;
pub const SYS_perf_event_open: ::c_long = 336;

extern {
    pub fn getcontext(ucp: *mut ucontext_t) -> ::c_int;
    pub fn setcontext(ucp: *const ucontext_t) -> ::c_int;
    pub fn makecontext(ucp: *mut ucontext_t,
                       func:  extern fn (),
                       argc: ::c_int, ...);
    pub fn swapcontext(uocp: *mut ucontext_t,
                       ucp: *const ucontext_t) -> ::c_int;
}
<|endoftext|>


<commit_before>//! Endpoints for the public room directory.

pub mod get_public_rooms;
pub mod get_public_rooms_filtered;
pub mod get_room_visibility;
pub mod set_room_visibility;

use js_int::UInt;
use ruma_identifiers::{RoomAliasId, RoomId};
use serde::{Deserialize, Serialize};

/// A chunk of a room list response, describing one room
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct PublicRoomsChunk {
    /// Aliases of the room.
    #[serde(default, skip_serializing_if = "Vec::is_empty")]
    pub aliases: Vec<RoomAliasId>,

    /// The canonical alias of the room, if any.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub canonical_alias: Option<RoomAliasId>,

    /// The name of the room, if any.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub name: Option<String>,

    /// The number of members joined to the room.
    pub num_joined_members: UInt,

    /// The ID of the room.
    pub room_id: RoomId,

    /// The topic of the room, if any.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub topic: Option<String>,

    /// Whether the room may be viewed by guest users without joining.
    pub world_readable: bool,

    /// Whether guest users may join the room and participate in it.
    ///
    /// If they can, they will be subject to ordinary power level rules like any other user.
    pub guest_can_join: bool,

    /// The URL for the room's avatar, if one is set.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub avatar_url: Option<String>,
}
<commit_msg>client-api: Make directory::PublicRoomsChunk non-exhaustive<commit_after>//! Endpoints for the public room directory.

pub mod get_public_rooms;
pub mod get_public_rooms_filtered;
pub mod get_room_visibility;
pub mod set_room_visibility;

use js_int::{uint, UInt};
use ruma_identifiers::{RoomAliasId, RoomId};
use serde::{Deserialize, Serialize};

/// A chunk of a room list response, describing one room
#[derive(Clone, Debug, Deserialize, Serialize)]
#[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)]
pub struct PublicRoomsChunk {
    /// Aliases of the room.
    #[serde(default, skip_serializing_if = "Vec::is_empty")]
    pub aliases: Vec<RoomAliasId>,

    /// The canonical alias of the room, if any.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub canonical_alias: Option<RoomAliasId>,

    /// The name of the room, if any.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub name: Option<String>,

    /// The number of members joined to the room.
    pub num_joined_members: UInt,

    /// The ID of the room.
    pub room_id: RoomId,

    /// The topic of the room, if any.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub topic: Option<String>,

    /// Whether the room may be viewed by guest users without joining.
    pub world_readable: bool,

    /// Whether guest users may join the room and participate in it.
    ///
    /// If they can, they will be subject to ordinary power level rules like any other user.
    pub guest_can_join: bool,

    /// The URL for the room's avatar, if one is set.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub avatar_url: Option<String>,
}

impl PublicRoomsChunk {
    /// Creates a `PublicRoomsChunk` with the given room ID.
    ///
    /// All other fields will be propagated with default values (an empty list of aliases, `None`
    /// for all `Option`al fields and `false` for all boolean fields), which should be overriden;
    /// the `assign!` macro from the `assign` crate can simplify this.
    pub fn new(room_id: RoomId) -> Self {
        Self {
            room_id,
            aliases: Vec::new(),
            canonical_alias: None,
            name: None,
            num_joined_members: uint!(0),
            topic: None,
            world_readable: false,
            guest_can_join: false,
            avatar_url: None,
        }
    }
}
<|endoftext|>


<commit_before>
use snake::*;
use point::*;
use direction::*;

use std::rand;
use std::rand::Rng;

type State = Vec<Vec<Square>>;

pub struct World {
	height: uint,
	width: uint,

	state: Box<State>,
	food: Point,

	snake: Snake,

	pub ended: bool
}

pub enum Square {
	SnakeHead,
	SnakeBody,
	Food,
	Empty
}

impl World {
	fn create_state(height: uint, width: uint) -> Box<State> {
		let mut state: Box<State> = box Vec::with_capacity(width);

		for i in range(0, width) {
			let mut tmp: Vec<Square> = Vec::with_capacity(height);
			for j in range(0, height) {
				tmp.push(Empty);
			}

			state.push(tmp);
		}

		state
	}

	pub fn new(height: uint, width: uint) -> World {
		let snake = Snake::new(width/2, height/2);

		let mut w = World {height: height, width: width, state:
			World::create_state(height, width), snake: snake,
			food: Point {x: 0, y: 0}, ended: false};
		w.add_food();
		w.update_state();

		w
	}

	pub fn to_string(&self) -> String {
		let mut text = "".to_string();
		for i in range(0, (self.width + 1) * 2) {
			text.push_str("-");
		}
		text.push_str("\n");

		for j in range (0, self.height) {
			text.push_str("|");
			for i in range(0, self.width) {
				match (*self.state)[i][j] {
					SnakeHead	=> text.push_str("@"),
					SnakeBody 	=> text.push_str("+"),
					Food	=> text.push_str("x"),
					Empty	=> text.push_str(" ")
				}

				text.push_str(" ");
			}

			text.push_str("|\n");
		}

		for i in range(0, (self.width + 1) * 2) {
			text.push_str("-");
		}

		text.push_str(("\nPisteesi: ".to_string() + self.score().to_string()).as_slice());
		text
	}

	fn check_dead(&self) -> bool {
		let body = self.snake.body();
		// checking if snake outside of field
		for p in body.iter() {
			if p.x < 0 || p.x > self.width - 1 ||
				p.y < 0 || p.y > self.height - 1 {
				return true;
			}
		}

		// checking if snake's body parts are overlapping
		for i in range(0, body.len()) {
			let p = body[i];
			for j in range(i + 1, body.len()) {
				if body[j] == p {
					return true;
				}
			}
		}

		return false;
	}

	fn check_eating(&mut self) {
		if self.snake.head == self.food {
			self.snake.eat();
			self.add_food();
		}
	}

	fn add_food(&mut self) {
   		let mut rng = rand::task_rng();

   		// looping if collision happens
   		loop {
   			let x: uint = rng.gen_range(0, self.width);
   			let y: uint = rng.gen_range(0, self.height);

   			let f = Point {x: x, y: y};
   			let mut collision = false;
   			for p in self.snake.body().iter() {
   				if *p == f {
   					collision = true;
   					break;
   				}
   			}

   			if collision {
   				continue;
   			}

   			self.food = f;
   			break;
   		}
	}

	pub fn score(&self) -> uint {
		self.snake.len
	}

	pub fn update(&mut self, direction: Direction) {
		self.snake.move(direction);
		if self.check_dead() {
			self.ended = true;
			return;
		}

		self.check_eating();
		self.state = World::create_state(self.height, self.width);
		self.update_state();
	}

	fn update_state(&mut self) {
		for p in self.snake.body().iter() {
			*self.state.get_mut(p.x).get_mut(p.y) = SnakeBody;
		}

		*self.state.get_mut(self.snake.head.x).get_mut(self.snake.head.y) = SnakeHead;
		*self.state.get_mut(self.food.x).get_mut(self.food.y) = Food;
	}
}
<commit_msg>Changed scoring.<commit_after>
use snake::*;
use point::*;
use direction::*;

use std::rand;
use std::rand::Rng;

type State = Vec<Vec<Square>>;

pub struct World {
	height: uint,
	width: uint,

	state: Box<State>,
	food: Point,

	snake: Snake,

	pub ended: bool
}

pub enum Square {
	SnakeHead,
	SnakeBody,
	Food,
	Empty
}

impl World {
	fn create_state(height: uint, width: uint) -> Box<State> {
		let mut state: Box<State> = box Vec::with_capacity(width);

		for i in range(0, width) {
			let mut tmp: Vec<Square> = Vec::with_capacity(height);
			for j in range(0, height) {
				tmp.push(Empty);
			}

			state.push(tmp);
		}

		state
	}

	pub fn new(height: uint, width: uint) -> World {
		let snake = Snake::new(width/2, height/2);

		let mut w = World {height: height, width: width, state:
			World::create_state(height, width), snake: snake,
			food: Point {x: 0, y: 0}, ended: false};
		w.add_food();
		w.update_state();

		w
	}

	pub fn to_string(&self) -> String {
		let mut text = "".to_string();
		for i in range(0, (self.width + 1) * 2) {
			text.push_str("-");
		}
		text.push_str("\n");

		for j in range (0, self.height) {
			text.push_str("|");
			for i in range(0, self.width) {
				match (*self.state)[i][j] {
					SnakeHead	=> text.push_str("@"),
					SnakeBody 	=> text.push_str("+"),
					Food	=> text.push_str("x"),
					Empty	=> text.push_str(" ")
				}

				text.push_str(" ");
			}

			text.push_str("|\n");
		}

		for i in range(0, (self.width + 1) * 2) {
			text.push_str("-");
		}

		text.push_str(("\nPisteesi: ".to_string() + self.score().to_string()).as_slice());
		text
	}

	fn check_dead(&self) -> bool {
		let body = self.snake.body();
		// checking if snake outside of field
		for p in body.iter() {
			if p.x < 0 || p.x > self.width - 1 ||
				p.y < 0 || p.y > self.height - 1 {
				return true;
			}
		}

		// checking if snake's body parts are overlapping
		for i in range(0, body.len()) {
			let p = body[i];
			for j in range(i + 1, body.len()) {
				if body[j] == p {
					return true;
				}
			}
		}

		return false;
	}

	fn check_eating(&mut self) {
		if self.snake.head == self.food {
			self.snake.eat();
			self.add_food();
		}
	}

	fn add_food(&mut self) {
   		let mut rng = rand::task_rng();

   		// looping if collision happens
   		loop {
   			let x: uint = rng.gen_range(0, self.width);
   			let y: uint = rng.gen_range(0, self.height);

   			let f = Point {x: x, y: y};
   			let mut collision = false;
   			for p in self.snake.body().iter() {
   				if *p == f {
   					collision = true;
   					break;
   				}
   			}

   			if collision {
   				continue;
   			}

   			self.food = f;
   			break;
   		}
	}

	pub fn score(&self) -> uint {
		(self.snake.len - 1) * 10
	}

	pub fn update(&mut self, direction: Direction) {
		self.snake.move(direction);
		if self.check_dead() {
			self.ended = true;
			return;
		}

		self.check_eating();
		self.state = World::create_state(self.height, self.width);
		self.update_state();
	}

	fn update_state(&mut self) {
		for p in self.snake.body().iter() {
			*self.state.get_mut(p.x).get_mut(p.y) = SnakeBody;
		}

		*self.state.get_mut(self.snake.head.x).get_mut(self.snake.head.y) = SnakeHead;
		*self.state.get_mut(self.food.x).get_mut(self.food.y) = Food;
	}
}
<|endoftext|>


<commit_before>use itertools::Itertools;
use std::collections::HashMap;
use std::fmt;
use rand::random;

pub type Point = (isize, isize);

#[derive(Debug, Clone)]
pub struct World {
    width: isize,
    height: isize,
    generation: Vec<Point>,
    age: usize,
}

impl World {
    pub fn new(width: isize, height: isize)  -> World {
        World { width: width, height: height, age: 0, generation: vec![] }
    }

    pub fn seed(mut self) -> World {
        self.generation = (0..self.width).cartesian_product(0..self.height)
            .filter(|_| random())
            .collect::<Vec<Point>>();
        self
    }

    pub fn evolve(&mut self) -> &World {
        let mut neighbours_counts = HashMap::new();
        for &(x, y) in &self.generation[..] {
            let neighbours = (-1..2).cartesian_product(-1..2)
                                    .filter(|&(dx, dy)| dx != 0 || dy != 0)
                                    .map(|(dx, dy)| (dx + x, dy + y));
            for n in neighbours {
                let counts = neighbours_counts.entry(n).or_insert(0);
                *counts = *counts + 1;
            }
        }
        self.generation = neighbours_counts.iter()
            .filter(|&(n, c)| if self.generation.contains(n) { *c == 3 || *c == 2 } else { *c == 3 })
            .map(|(n, _)| *n)
            .collect::<Vec<Point>>();
        self.age += 1;
        self
    }
}

impl fmt::Display for World {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let mut buf = String::new();
        for x in 0..self.width + 2 {
            buf.push(if x == 0 { '┌' } else if x == self.width + 1 { '┐' } else { '─' });
        }
        buf.push('\n');
        for y in 0..self.height {
            buf.push('│');
            for x in 0..self.width {
                buf.push(if self.generation.contains(&(x, y)) { '*' } else { ' ' });
            }
            buf.push('|');
            if y == 0 {
                buf.push_str(&format!(" cells: {}", self.generation.len()));
            }
            if y == 1 {
                buf.push_str(&format!(" age: {}", self.age));
            }
            buf.push('\n');
        }
        for x in 0..self.width + 2 {
            buf.push(if x == 0 { '└' } else if x == self.width + 1 { '┘' } else { '─' });
        }
        write!(f, "{}", buf)
    }
}
<commit_msg>Allocate buffer with capacity enough for representation of the world<commit_after>use itertools::Itertools;
use std::collections::HashMap;
use std::fmt;
use rand::random;

pub type Point = (isize, isize);

#[derive(Debug, Clone)]
pub struct World {
    width: isize,
    height: isize,
    generation: Vec<Point>,
    age: usize,
}

impl World {
    pub fn new(width: isize, height: isize)  -> World {
        World { width: width, height: height, age: 0, generation: vec![] }
    }

    pub fn seed(mut self) -> World {
        self.generation = (0..self.width).cartesian_product(0..self.height)
            .filter(|_| random())
            .collect::<Vec<Point>>();
        self
    }

    pub fn evolve(&mut self) -> &World {
        let mut neighbours_counts = HashMap::new();
        for &(x, y) in &self.generation[..] {
            let neighbours = (-1..2).cartesian_product(-1..2)
                                    .filter(|&(dx, dy)| dx != 0 || dy != 0)
                                    .map(|(dx, dy)| (dx + x, dy + y));
            for n in neighbours {
                let counts = neighbours_counts.entry(n).or_insert(0);
                *counts = *counts + 1;
            }
        }
        self.generation = neighbours_counts.iter()
            .filter(|&(n, c)| if self.generation.contains(n) { *c == 3 || *c == 2 } else { *c == 3 })
            .map(|(n, _)| *n)
            .collect::<Vec<Point>>();
        self.age += 1;
        self
    }
}

impl fmt::Display for World {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let mut buf = String::with_capacity(((self.width + 2) * (self.height + 2) + 50) as usize);
        for x in 0..self.width + 2 {
            buf.push(if x == 0 { '┌' } else if x == self.width + 1 { '┐' } else { '─' });
        }
        buf.push('\n');
        for y in 0..self.height {
            buf.push('│');
            for x in 0..self.width {
                buf.push(if self.generation.contains(&(x, y)) { '*' } else { ' ' });
            }
            buf.push('|');
            if y == 0 {
                buf.push_str(&format!(" cells: {}", self.generation.len()));
            }
            if y == 1 {
                buf.push_str(&format!(" age: {}", self.age));
            }
            buf.push('\n');
        }
        for x in 0..self.width + 2 {
            buf.push(if x == 0 { '└' } else if x == self.width + 1 { '┘' } else { '─' });
        }
        write!(f, "{}", buf)
    }
}
<|endoftext|>


<commit_before>use {
    BackEnd,
    Borrowed,
    Draw,
    Field,
    Image,
    Matrix2d,
    Rectangle,
    RelativeRectangle,
    Value,
    Transform2d,
};
use vecmath::{
    margin_rectangle,
    multiply,
    relative_rectangle,
    rotate_radians,
    scale,
    shear,
    translate,
};
use triangulation::{
    rect_tri_list_xy_f32,
    rect_tri_list_rgba_f32,
    rect_tri_list_uv_f32,
};

/// An image rectangle context.
pub struct ImageRectangleContext<'a> {
    /// Base/original transformation.
    pub base: Field<'a, Matrix2d>,
    /// Current transformation.
    pub transform: Field<'a, Matrix2d>,
    /// Current rectangle.
    pub rect: Field<'a, Rectangle>,
    /// Current color.
    pub image: Field<'a, Image>,
}

impl<'a> Transform2d<'a> for ImageRectangleContext<'a> {
    #[inline(always)]
    fn trans(&'a self, x: f64, y: f64) -> ImageRectangleContext<'a> {
        ImageRectangleContext {
            base: Borrowed(self.base.get()),
            transform: {
                let trans = translate(x, y);
                Value(multiply(&trans, self.transform.get()))
            },
            rect: Borrowed(self.rect.get()),
            image: Borrowed(self.image.get()),
        }
    }

    #[inline(always)]
    fn trans_local(&'a self, x: f64, y: f64) -> ImageRectangleContext<'a> {
        ImageRectangleContext {
            base: Borrowed(self.base.get()),
            transform: {
                let trans = translate(x, y);
                Value(multiply(self.transform.get(), &trans))
            },
            rect: Borrowed(self.rect.get()),
            image: Borrowed(self.image.get()),
        }
    }

    #[inline(always)]
    fn rot_rad(&'a self, angle: f64) -> ImageRectangleContext<'a> {
        ImageRectangleContext {
            base: Borrowed(self.base.get()),
            transform: {
                let rot = rotate_radians(angle);
                Value(multiply(&rot, self.transform.get()))
            },
            rect: Borrowed(self.rect.get()),
            image: Borrowed(self.image.get()),
        }
    }

    #[inline(always)]
    fn rot_rad_local(&'a self, angle: f64) -> ImageRectangleContext<'a> {
        ImageRectangleContext {
            base: Borrowed(self.base.get()),
            transform: {
                let rot = rotate_radians(angle);
                Value(multiply(self.transform.get(), &rot))
            },
            rect: Borrowed(self.rect.get()),
            image: Borrowed(self.image.get()),
        }
    }

    #[inline(always)]
    fn scale(&'a self, sx: f64, sy: f64) -> ImageRectangleContext<'a> {
        ImageRectangleContext {
            base: Borrowed(self.base.get()),
            transform: {
                let scale = scale(sx, sy);
                Value(multiply(&scale, self.transform.get()))
            },
            rect: Borrowed(self.rect.get()),
            image: Borrowed(self.image.get()),
        }
    }

    #[inline(always)]
    fn scale_local(&'a self, sx: f64, sy: f64) -> ImageRectangleContext<'a> {
        ImageRectangleContext {
            base: Borrowed(self.base.get()),
            transform: {
                let scale = scale(sx, sy);
                Value(multiply(self.transform.get(), &scale))
            },
            rect: Borrowed(self.rect.get()),
            image: Borrowed(self.image.get()),
        }
    }

    #[inline(always)]
    fn shear(&'a self, sx: f64, sy: f64) -> ImageRectangleContext<'a> {
        ImageRectangleContext {
            base: Borrowed(self.base.get()),
            transform: {
                let shear = shear(sx, sy);
                Value(multiply(&shear, self.transform.get()))
            },
            rect: Borrowed(self.rect.get()),
            image: Borrowed(self.image.get()),
        }
    }

    #[inline(always)]
    fn shear_local(&'a self, sx: f64, sy: f64) -> ImageRectangleContext<'a> {
        ImageRectangleContext {
            base: Borrowed(self.base.get()),
            transform: {
                let shear = shear(sx, sy);
                Value(multiply(self.transform.get(), &shear))
            },
            rect: Borrowed(self.rect.get()),
            image: Borrowed(self.image.get()),
        }
    }
}

impl<'a> Draw<'a> for ImageRectangleContext<'a> {
    fn draw<B: BackEnd>(&'a self, back_end: &mut B) {
        if back_end.supports_single_texture()
        && back_end.supports_tri_list_xy_f32_rgba_f32_uv_f32() {
            let rect = self.rect.get();
            let color: [f32, ..4] = [1.0, 1.0, 1.0, 1.0];
            let texture_id = self.image.get().texture_id;
            // Complete transparency does not need to be rendered.
            if color[3] == 0.0 { return; }
            // Turn on alpha blending if not completely opaque or if the texture has alpha channel.
            let needs_alpha = color[3] != 1.0 || back_end.has_texture_alpha(texture_id);
            if needs_alpha { back_end.enable_alpha_blend(); }
            back_end.enable_single_texture(texture_id);
            back_end.tri_list_xy_f32_rgba_f32_uv_f32(
                rect_tri_list_xy_f32(self.transform.get(), rect),
                rect_tri_list_rgba_f32(color),
                rect_tri_list_uv_f32(self.image.get())
            );
            back_end.disable_single_texture();
            if needs_alpha { back_end.disable_alpha_blend(); }
        } else {
            unimplemented!();
        }
    }
}

impl<'a> RelativeRectangle<'a> for ImageRectangleContext<'a> {
    #[inline(always)]
    fn margin(&'a self, m: f64) -> ImageRectangleContext<'a> {
        ImageRectangleContext {
            base: Borrowed(self.base.get()),
            transform: Borrowed(self.transform.get()),
            image: Borrowed(self.image.get()),
            rect: Value(margin_rectangle(self.rect.get(), m)),
        }
    }

    #[inline(always)]
    fn rel(&'a self, x: f64, y: f64) -> ImageRectangleContext<'a> {
        ImageRectangleContext {
            base: Borrowed(self.base.get()),
            transform: Borrowed(self.transform.get()),
            image: Borrowed(self.image.get()),
            rect: Value(relative_rectangle(self.rect.get(), x, y)),
        }
    }
}
<commit_msg>Implemented `View` for `ImageRectangleContext`<commit_after>use {
    BackEnd,
    Borrowed,
    Draw,
    Field,
    Image,
    Matrix2d,
    Rectangle,
    RelativeRectangle,
    Transform2d,
    Value,
    View,
};
use vecmath::{
    identity,
    margin_rectangle,
    multiply,
    relative_rectangle,
    rotate_radians,
    scale,
    shear,
    translate,
};
use triangulation::{
    rect_tri_list_xy_f32,
    rect_tri_list_rgba_f32,
    rect_tri_list_uv_f32,
};

/// An image rectangle context.
pub struct ImageRectangleContext<'a> {
    /// Base/original transformation.
    pub base: Field<'a, Matrix2d>,
    /// Current transformation.
    pub transform: Field<'a, Matrix2d>,
    /// Current rectangle.
    pub rect: Field<'a, Rectangle>,
    /// Current color.
    pub image: Field<'a, Image>,
}

impl<'a> Transform2d<'a> for ImageRectangleContext<'a> {
    #[inline(always)]
    fn trans(&'a self, x: f64, y: f64) -> ImageRectangleContext<'a> {
        ImageRectangleContext {
            base: Borrowed(self.base.get()),
            transform: {
                let trans = translate(x, y);
                Value(multiply(&trans, self.transform.get()))
            },
            rect: Borrowed(self.rect.get()),
            image: Borrowed(self.image.get()),
        }
    }

    #[inline(always)]
    fn trans_local(&'a self, x: f64, y: f64) -> ImageRectangleContext<'a> {
        ImageRectangleContext {
            base: Borrowed(self.base.get()),
            transform: {
                let trans = translate(x, y);
                Value(multiply(self.transform.get(), &trans))
            },
            rect: Borrowed(self.rect.get()),
            image: Borrowed(self.image.get()),
        }
    }

    #[inline(always)]
    fn rot_rad(&'a self, angle: f64) -> ImageRectangleContext<'a> {
        ImageRectangleContext {
            base: Borrowed(self.base.get()),
            transform: {
                let rot = rotate_radians(angle);
                Value(multiply(&rot, self.transform.get()))
            },
            rect: Borrowed(self.rect.get()),
            image: Borrowed(self.image.get()),
        }
    }

    #[inline(always)]
    fn rot_rad_local(&'a self, angle: f64) -> ImageRectangleContext<'a> {
        ImageRectangleContext {
            base: Borrowed(self.base.get()),
            transform: {
                let rot = rotate_radians(angle);
                Value(multiply(self.transform.get(), &rot))
            },
            rect: Borrowed(self.rect.get()),
            image: Borrowed(self.image.get()),
        }
    }

    #[inline(always)]
    fn scale(&'a self, sx: f64, sy: f64) -> ImageRectangleContext<'a> {
        ImageRectangleContext {
            base: Borrowed(self.base.get()),
            transform: {
                let scale = scale(sx, sy);
                Value(multiply(&scale, self.transform.get()))
            },
            rect: Borrowed(self.rect.get()),
            image: Borrowed(self.image.get()),
        }
    }

    #[inline(always)]
    fn scale_local(&'a self, sx: f64, sy: f64) -> ImageRectangleContext<'a> {
        ImageRectangleContext {
            base: Borrowed(self.base.get()),
            transform: {
                let scale = scale(sx, sy);
                Value(multiply(self.transform.get(), &scale))
            },
            rect: Borrowed(self.rect.get()),
            image: Borrowed(self.image.get()),
        }
    }

    #[inline(always)]
    fn shear(&'a self, sx: f64, sy: f64) -> ImageRectangleContext<'a> {
        ImageRectangleContext {
            base: Borrowed(self.base.get()),
            transform: {
                let shear = shear(sx, sy);
                Value(multiply(&shear, self.transform.get()))
            },
            rect: Borrowed(self.rect.get()),
            image: Borrowed(self.image.get()),
        }
    }

    #[inline(always)]
    fn shear_local(&'a self, sx: f64, sy: f64) -> ImageRectangleContext<'a> {
        ImageRectangleContext {
            base: Borrowed(self.base.get()),
            transform: {
                let shear = shear(sx, sy);
                Value(multiply(self.transform.get(), &shear))
            },
            rect: Borrowed(self.rect.get()),
            image: Borrowed(self.image.get()),
        }
    }
}

impl<'a> Draw<'a> for ImageRectangleContext<'a> {
    fn draw<B: BackEnd>(&'a self, back_end: &mut B) {
        if back_end.supports_single_texture()
        && back_end.supports_tri_list_xy_f32_rgba_f32_uv_f32() {
            let rect = self.rect.get();
            let color: [f32, ..4] = [1.0, 1.0, 1.0, 1.0];
            let texture_id = self.image.get().texture_id;
            // Complete transparency does not need to be rendered.
            if color[3] == 0.0 { return; }
            // Turn on alpha blending if not completely opaque or if the texture has alpha channel.
            let needs_alpha = color[3] != 1.0 || back_end.has_texture_alpha(texture_id);
            if needs_alpha { back_end.enable_alpha_blend(); }
            back_end.enable_single_texture(texture_id);
            back_end.tri_list_xy_f32_rgba_f32_uv_f32(
                rect_tri_list_xy_f32(self.transform.get(), rect),
                rect_tri_list_rgba_f32(color),
                rect_tri_list_uv_f32(self.image.get())
            );
            back_end.disable_single_texture();
            if needs_alpha { back_end.disable_alpha_blend(); }
        } else {
            unimplemented!();
        }
    }
}

impl<'a> RelativeRectangle<'a> for ImageRectangleContext<'a> {
    #[inline(always)]
    fn margin(&'a self, m: f64) -> ImageRectangleContext<'a> {
        ImageRectangleContext {
            base: Borrowed(self.base.get()),
            transform: Borrowed(self.transform.get()),
            image: Borrowed(self.image.get()),
            rect: Value(margin_rectangle(self.rect.get(), m)),
        }
    }

    #[inline(always)]
    fn rel(&'a self, x: f64, y: f64) -> ImageRectangleContext<'a> {
        ImageRectangleContext {
            base: Borrowed(self.base.get()),
            transform: Borrowed(self.transform.get()),
            image: Borrowed(self.image.get()),
            rect: Value(relative_rectangle(self.rect.get(), x, y)),
        }
    }
}

impl<'a> View<'a> for ImageRectangleContext<'a> {
    #[inline(always)]
    fn view(&'a self) -> ImageRectangleContext<'a> {
        ImageRectangleContext {
            base: Borrowed(self.base.get()),
            transform: Borrowed(self.base.get()),
            rect: Borrowed(self.rect.get()),
            image: Borrowed(self.image.get()),
        }
    }

    #[inline(always)]
    fn reset(&'a self) -> ImageRectangleContext<'a> {
        ImageRectangleContext {
            base: Borrowed(self.base.get()),
            transform: Value(identity()),
            rect: Borrowed(self.rect.get()),
            image: Borrowed(self.image.get()),
        }
    }

    #[inline(always)]
    fn store_view(&'a self) -> ImageRectangleContext<'a> {
        ImageRectangleContext {
            base: Borrowed(self.transform.get()),
            transform: Borrowed(self.transform.get()),
            rect: Borrowed(self.rect.get()),
            image: Borrowed(self.image.get()),
        }
    }
}

<|endoftext|>