<commit_before>// Kevin Cantu
// Boyer-Moore string searching

use std;

// Function: findn_bytes
//
// Boyer-Moore string search, which returns
// up to `nn` byte positions of matched substrings
fn findn_bytes (needle: str, haystack: str, nn: uint) -> [uint] {

   let results = [];

   // empties
   if str::len(haystack) == 0u {
      ret results;
   }

   if str::len(needle) == 0u {
      vec::push(results, 0u);
      ret results;
   }

   if str::len(haystack) < str::len(needle) {
      ret results;
   }

   // generate the tables
   let ct = char_table(needle);
   let pt = prefix_table(needle);

   // simplify the table referencing
   let getShift = fn@(pos: uint) -> uint {
      let charShift, prefShift; // also: ct, pt, needle

      assert needle != "";
      assert pos >= 0u;
      assert pos < str::len(needle);

      alt ct.find(needle[pos] as uint) {
         option::none { charShift = str::len(needle);}
         option::some(x) { charShift = x;}
      }

      let offset = str::len(needle) - pos;

      assert offset >= 0u;
      assert offset < str::len(needle);

      alt pt.find(offset) {
         option::none { fail "something is out of range" }
         option::some(x) { prefShift = x;}
      }

      ret greaterOf(charShift, prefShift);
   };

   let hii = 0u;
   let njj = 0u;

   while hii < str::len(haystack) {

      njj = str::len(needle);

      // reverse through needle
      while 0u < njj {
         njj -= 1u;

         if njj+hii >= str::len(needle) {
            ret results;
         }

         // if still matching
         if needle[njj] == haystack[hii+njj] {

            // if full match
            if njj == 0u {
               vec::push(results, hii);
               log(warn, results);
               if vec::len(results) >= nn { ret results; }
            }

            hii += 1u;

         // if partial match
         } else {
            let shift = getShift(njj);

            hii += shift;
            njj = str::len(needle);
         }
      }
   }

   ret results;
}

fn char_table (needle: str) -> std::map::map<uint, uint> {
   let mm: std::map::map<uint, uint> = std::map::new_uint_hash();
   let len = str::len(needle);

   let jj = len - 1u; // drop the last byte

   assert jj >= 0u;
   assert jj < str::len(needle);

   // from last-1 to first
   while jj > 0u {
      jj -= 1u;
      if ! mm.contains_key(needle[jj] as uint) {
         // store reverse indexes
         mm.insert(needle[jj] as uint, len - 1u - jj);
      }
   }

   ret mm;
}

//#[test]
fn test_char_table () {
   let ct = char_table("ANPANMAN");
   assert 1u == ct.get('A' as uint);
   assert 2u == ct.get('M' as uint);
   assert 3u == ct.get('N' as uint);
   assert 5u == ct.get('P' as uint);
   assert option::none == ct.find('z' as uint);
}

fn prefix_table (needle: str) -> std::map::map<uint, uint> {
   let mm: std::map::map<uint, uint> = std::map::new_uint_hash();
   let lim   = str::len(needle);
   assert 0u < lim;

   // step to larger suffixes
   let sii = lim - 1u;
   while sii > 0u {
      //assert      lim-sii    < lim;
      //assert 0u <= lim-sii-1u;

      let suffix      = str::slice(needle, lim - sii,      lim);
      let suffix_plus = str::slice(needle, lim - sii - 1u, lim);
      let slen = str::len(suffix);

      // step to smaller prefixes
      let pii = lim - 1u;
      while pii > 0u {
         //assert       pii < lim;
         //assert 0u <= pii;

         let prefix = str::slice(needle, 0u, pii);
         let plen   = str::len(prefix);

         let msg = ("<"+suffix+"("+#fmt("%u",sii)+") × "+prefix+"("+#fmt("%u",pii)+")>");
         std::io::println(msg);

         if     str::ends_with(prefix, suffix)
            && !str::ends_with(prefix, suffix_plus)
            &&  slen < plen
         {
            if !mm.contains_key(sii) {
               mm.insert(sii, pii);
               std::io::println(#fmt("%u => %u",sii, pii));
            }
         }

         pii -= 1u;
      }

      // no matching prefix
      // i.e., what is the last prefix that was still partially matching,
      // e.g., for suffix "man", the prefix "an" works, and is +6...
      if ! mm.contains_key(lim - sii) {
         mm.insert(lim - sii, pii);
         std::io::println(#fmt("%u => %u",sii, pii));
      }

      sii -= 1u;
   }

   ret mm;
}

#[test]
fn test_prefix_table() {
   let pt = prefix_table("ANPANMAN");
                            //      ... 8

   assert 1u == pt.get(0u); //        (n)
/*
   assert 8u == pt.get(1u); //       (a)n
   assert 3u == pt.get(2u); //      (m)an
   assert 6u == pt.get(3u); //     (n)man
   assert 6u == pt.get(4u); //    (a)nman
   assert 6u == pt.get(5u); //   (p)anman
   assert 6u == pt.get(6u); //  (n)panman
   assert 6u == pt.get(7u); // (a)npanman
   //assert 0u == pt.get(8u); // fail
*/
}

////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////

// prefixes, smallest first
fn prefixes(ss: str) -> [str] unsafe {
   assert str::len(ss) > 0u;

   let vv = [];
   str::chars_iteri(ss) {|ii, _bb|
      vec::push(vv, str::slice(ss, 0u, ii));
   }
   vec::push(vv, ss);
   ret vv;
}

//#[test]
fn test_prefs() {
   assert ["", "a", "ab", "abc", "abcd"] == prefixes("abcd");
}

// suffixes, largest first
fn suffixes(ss: str) -> [str] unsafe {
   assert str::len(ss) > 0u;

   let vv = [];
   let lim = str::len(ss);
   str::chars_iteri(ss) {|ii, _bb|
      vec::push(vv, str::slice(ss, ii, lim));
   }
   vec::push(vv, "");
   ret vv;
}

//#[test]
fn test_sufs() {
   assert ["abcd", "bcd", "cd", "d", ""] == suffixes("abcd");
}

fn greaterOf(a: uint, b: uint) -> uint {
   if a > b { ret a; } else { ret b; }
}

//#[test]
fn test_greaterOf() {
   assert greaterOf(15u, 17u) == 17u;
   assert greaterOf(17u, 15u) == 17u;
}

fn find_bytes_(needle: str, haystack: str) -> option<uint> {
   let found = findn_bytes(needle, haystack, 1u);

   alt vec::len(found) {
      0u { option::none }
      xx { option::some(found[0u]) }
   }
}

//#[test]
fn test_findn() {
   assert [] == findn_bytes("banana", "apple pie", 1u);
}

//#[test]
fn test_find_bytes_A() {
  // byte positions
  assert (find_bytes_("banana", "apple pie") == option::none);
}

//#[test]
fn test_find_bytes_B() {
  assert (find_bytes_("", "") == option::none);
}

//#[test]
fn test_find_bytes_C() {
  let data = "ประเทศไทย中华Việt Nam";
//  assert (find_bytes_("", data)     == option::some( 0u));
// PENDING
  assert (find_bytes_("ประเ", data) == option::some( 0u));
//  assert (find_bytes_("ะเ", data)   == option::some( 6u));
//  assert (find_bytes_("中华", data) == option::some(27u));
//  assert (find_bytes_("ไท华", data) == option::none);
}

<commit_msg>ok, now the tables work again...<commit_after>// Kevin Cantu
// Boyer-Moore string searching

use std;

// Function: findn_bytes
//
// Boyer-Moore string search, which returns
// up to `nn` byte positions of matched substrings
fn findn_bytes (needle: str, haystack: str, nn: uint) -> [uint] {

   let results = [];

   // empties
   if str::len(haystack) == 0u {
      ret results;
   }

   if str::len(needle) == 0u {
      vec::push(results, 0u);
      ret results;
   }

   if str::len(haystack) < str::len(needle) {
      ret results;
   }

   // generate the tables
   let ct = char_table(needle);
   let pt = prefix_table(needle);

   // simplify the table referencing
   let getShift = fn@(pos: uint) -> uint {
      let charShift, prefShift; // also: ct, pt, needle

      assert needle != "";
      assert pos >= 0u;
      assert pos < str::len(needle);

      alt ct.find(needle[pos] as uint) {
         option::none { charShift = str::len(needle);}
         option::some(x) { charShift = x;}
      }

      let offset = str::len(needle) - pos;

      assert offset >= 0u;
      assert offset < str::len(needle);

      alt pt.find(offset) {
         option::none { fail "something is out of range" }
         option::some(x) { prefShift = x;}
      }

      ret greaterOf(charShift, prefShift);
   };

   let hii = 0u;
   let njj = 0u;

   while hii < str::len(haystack) {

      njj = str::len(needle);

      // reverse through needle
      while 0u < njj {
         njj -= 1u;

         if njj+hii >= str::len(needle) {
            ret results;
         }

         // if still matching
         if needle[njj] == haystack[hii+njj] {

            // if full match
            if njj == 0u {
               vec::push(results, hii);
               log(warn, results);
               if vec::len(results) >= nn { ret results; }
            }

            hii += 1u;

         // if partial match
         } else {
            let shift = getShift(njj);

            hii += shift;
            njj = str::len(needle);
         }
      }
   }

   ret results;
}

fn char_table (needle: str) -> std::map::map<uint, uint> {
   let mm: std::map::map<uint, uint> = std::map::new_uint_hash();
   let len = str::len(needle);

   let jj = len - 1u; // drop the last byte

   assert jj >= 0u;
   assert jj < str::len(needle);

   // from last-1 to first
   while jj > 0u {
      jj -= 1u;
      if ! mm.contains_key(needle[jj] as uint) {
         // store reverse indexes
         mm.insert(needle[jj] as uint, len - 1u - jj);
      }
   }

   ret mm;
}

#[test]
fn test_char_table () {
   let ct = char_table("ANPANMAN");
   assert 1u == ct.get('A' as uint);
   assert 2u == ct.get('M' as uint);
   assert 3u == ct.get('N' as uint);
   assert 5u == ct.get('P' as uint);
   assert option::none == ct.find('z' as uint);
}

fn prefix_table (needle: str) -> std::map::map<uint, uint> {
   let mm: std::map::map<uint, uint> = std::map::new_uint_hash();
   let lim   = str::len(needle);
   assert 0u < lim;

   // step to larger suffixes
   let sii = 0u;
   while sii < lim {
      //assert      lim-sii    < lim;
      //assert 0u <= lim-sii-1u;

      let suffix      = str::slice(needle, lim - sii,      lim);
      let suffix_plus = str::slice(needle, lim - sii - 1u, lim);
      let slen = str::len(suffix);

      // step to smaller prefixes
      let pii = lim - 1u;
      while pii > 0u {
         //assert       pii < lim;
         //assert 0u <= pii;

         let prefix = str::slice(needle, 0u, pii);
         let plen   = str::len(prefix);

         let msg = ("<"+suffix+"("+#fmt("%u",sii)+") × "+prefix+"("+#fmt("%u",pii)+")>");
         std::io::println(msg);

         // suffix might be fully matched
         if str::ends_with(prefix, suffix)
            && !str::ends_with(prefix, suffix_plus)
            &&  slen < plen
         {
            if !mm.contains_key(sii)
            {
               mm.insert(sii, lim-pii);
               std::io::println(#fmt("%u => %u",sii, lim-pii));
            }
         }

         // prefix is bigger than suffix, only tail can match
         if str::len(prefix) <= str::len(suffix)
            && str::ends_with(suffix, prefix)
         {
            if !mm.contains_key(sii)
            {
               mm.insert(sii, lim-pii);
               std::io::println(#fmt("%u => %u",sii, lim-pii));
            }
         }

         pii -= 1u;
      }

      // no matching prefix
      // i.e., what is the last prefix that was still partially matching,
      // e.g., for suffix "man", the prefix "an" works, and is +6...
      if ! mm.contains_key(sii) {
         mm.insert(sii, lim-pii);
         std::io::println(#fmt("%u => %u",sii, lim-pii));
      }

      sii += 1u;
   }

   ret mm;
}

#[test]
fn test_prefix_table() {
   let pt = prefix_table("ANPANMAN");
                            //      ... 8

   assert 1u == pt.get(0u); //        (n)
   assert 8u == pt.get(1u); //       (a)n
   assert 3u == pt.get(2u); //      (m)an
   assert 6u == pt.get(3u); //     (n)man
   assert 6u == pt.get(4u); //    (a)nman
   assert 6u == pt.get(5u); //   (p)anman
   assert 6u == pt.get(6u); //  (n)panman
   assert 6u == pt.get(7u); // (a)npanman
   //assert 0u == pt.get(8u); // fail
}

////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////

// prefixes, smallest first
fn prefixes(ss: str) -> [str] unsafe {
   assert str::len(ss) > 0u;

   let vv = [];
   str::chars_iteri(ss) {|ii, _bb|
      vec::push(vv, str::slice(ss, 0u, ii));
   }
   vec::push(vv, ss);
   ret vv;
}

#[test]
fn test_prefs() {
   assert ["", "a", "ab", "abc", "abcd"] == prefixes("abcd");
}

// suffixes, largest first
fn suffixes(ss: str) -> [str] unsafe {
   assert str::len(ss) > 0u;

   let vv = [];
   let lim = str::len(ss);
   str::chars_iteri(ss) {|ii, _bb|
      vec::push(vv, str::slice(ss, ii, lim));
   }
   vec::push(vv, "");
   ret vv;
}

#[test]
fn test_sufs() {
   assert ["abcd", "bcd", "cd", "d", ""] == suffixes("abcd");
}

fn greaterOf(a: uint, b: uint) -> uint {
   if a > b { ret a; } else { ret b; }
}

#[test]
fn test_greaterOf() {
   assert greaterOf(15u, 17u) == 17u;
   assert greaterOf(17u, 15u) == 17u;
}

fn find_bytes_(needle: str, haystack: str) -> option<uint> {
   let found = findn_bytes(needle, haystack, 1u);

   alt vec::len(found) {
      0u { option::none }
      xx { option::some(found[0u]) }
   }
}

#[test]
fn test_findn() {
   assert [] == findn_bytes("banana", "apple pie", 1u);
}

#[test]
fn test_find_bytes_A() {
  // byte positions
  assert (find_bytes_("banana", "apple pie") == option::none);
}

#[test]
fn test_find_bytes_B() {
  assert (find_bytes_("", "") == option::none);
}

#[test]
fn test_find_bytes_C() {
  let data = "ประเทศไทย中华Việt Nam";
//  assert (find_bytes_("", data)     == option::some( 0u));
// PENDING
  assert (find_bytes_("ประเ", data) == option::some( 0u));
//  assert (find_bytes_("ะเ", data)   == option::some( 6u));
//  assert (find_bytes_("中华", data) == option::some(27u));
//  assert (find_bytes_("ไท华", data) == option::none);
}

<|endoftext|>


<commit_before>//!
//! A session runs a filesystem implementation while it is being mounted
//! to a specific mount point. A session begins by mounting the filesystem
//! and ends by unmounting it. While the filesystem is mounted, the session
//! loop receives, dispatches and replies to kernel requests for filesystem
//! operations under its mount point.
//!

use std::task::TaskBuilder;
use libc::{EAGAIN, EINTR, ENODEV, ENOENT};
use native;
use channel;
use channel::Channel;
use Filesystem;
use request::{request, dispatch};

/// The max size of write requests from the kernel. The absolute minimum is 4k,
/// FUSE recommends at least 128k, max 16M. The FUSE default is 16M on OS X
/// and 128k on other systems.
pub static MAX_WRITE_SIZE: uint = 16*1024*1024;

/// Size of the buffer for reading a request from the kernel. Since the kernel may send
/// up to MAX_WRITE_SIZE bytes in a write request, we use that value plus some extra space.
static BUFFER_SIZE: uint = MAX_WRITE_SIZE + 4096;

/// The session data structure
pub struct Session<FS> {
	/// Filesystem operation implementations
	pub filesystem: FS,
	/// Path of the mounted filesystem
	pub mountpoint: Path,
	/// Communication channel to the kernel driver
	ch: Channel,
	/// FUSE protocol major version
	pub proto_major: uint,
	/// FUSE protocol minor version
	pub proto_minor: uint,
	/// True if the filesystem is initialized (init operation done)
	pub initialized: bool,
	/// True if the filesystem was destroyed (destroy operation done)
	pub destroyed: bool,
}

impl<FS: Filesystem+Send> Session<FS> {
	/// Create a new session by mounting the given filesystem to the given mountpoint
	pub fn new (filesystem: FS, mountpoint: &Path, options: &[&[u8]]) -> Session<FS> {
		info!("Mounting {}", mountpoint.display());
		let ch = match Channel::new(mountpoint, options) {
			Ok(ch) => ch,
			Err(err) => fail!("Unable to mount filesystem. Error {:i}", err),
		};
		Session {
			filesystem: filesystem,
			mountpoint: mountpoint.clone(),
			ch: ch,
			proto_major: 0,
			proto_minor: 0,
			initialized: false,
			destroyed: false,
		}
	}

	/// Run the session loop that receives kernel requests and dispatches them to method
	/// calls into the filesystem. This read-dispatch-loop is non-concurrent to prevent
	/// having multiple buffers (which take up much memory), but the filesystem methods
	/// may run concurrent by spawning tasks.
	/// Make sure to run this on a new single threaded scheduler since native I/O in the
	/// session loop can block.
	pub fn run (&mut self) {
		// Buffer for receiving requests from the kernel. Only one is allocated and
		// it is reused immediately after dispatching to conserve memory and allocations.
		let mut buffer = ~[0u8, ..BUFFER_SIZE];
		loop {
			// Read the next request from the given channel to kernel driver
			// The kernel driver makes sure that we get exactly one request per read
			match self.ch.receive(buffer) {
				Err(ENOENT) => continue,				// Operation interrupted. Accordingly to FUSE, this is safe to retry
				Err(EINTR) => continue,					// Interrupted system call, retry
				Err(EAGAIN) => continue,				// Explicitly try again
				Err(ENODEV) => break,					// Filesystem was unmounted, quit the loop
				Err(err) => fail!("Lost connection to FUSE device. Error {:i}", err),
				Ok(len) => match request(self.ch.sender(), buffer.slice_to(len)) {
					None => break,						// Illegal request, quit the loop
					Some(req) => dispatch(&req, self),
				},
			}
		}
	}

	/// Run the session loop in a background task
	pub fn spawn (self) -> BackgroundSession {
		BackgroundSession::new(self)
	}
}

#[unsafe_destructor]
impl<FS: Filesystem+Send> Drop for Session<FS> {
	fn drop (&mut self) {
		info!("Unmounted {}", self.mountpoint.display());
		// The actual unmounting takes place because self.ch is dropped here
	}
}

/// The background session data structure
pub struct BackgroundSession {
	/// Path of the mounted filesystem
	pub mountpoint: Path,
}

impl BackgroundSession {
	/// Create a new background session for the given session by running its
	/// session loop in a background task. If the returned handle is dropped,
	/// the filesystem is unmounted and the given session ends.
	pub fn new<FS: Filesystem+Send> (se: Session<FS>) -> BackgroundSession {
		let mountpoint = se.mountpoint.clone();
		// The background task is started using a a new native thread
		// since native I/O in the session loop can block
		let task = TaskBuilder::new().named(format!("FUSE {}", mountpoint.display()));
		native::task::spawn_opts(task.opts, proc() {
			let mut se = se;
			se.run();
		});
		BackgroundSession { mountpoint: mountpoint }
	}
}

impl Drop for BackgroundSession {
	fn drop (&mut self) {
		info!("Unmounting {}", self.mountpoint.display());
		// Unmounting the filesystem will eventually end the session loop,
		// drop the session and hence end the background task.
		channel::unmount(&self.mountpoint);
	}
}
<commit_msg>Remove use of ~[T]<commit_after>//!
//! A session runs a filesystem implementation while it is being mounted
//! to a specific mount point. A session begins by mounting the filesystem
//! and ends by unmounting it. While the filesystem is mounted, the session
//! loop receives, dispatches and replies to kernel requests for filesystem
//! operations under its mount point.
//!

use std::task::TaskBuilder;
use libc::{EAGAIN, EINTR, ENODEV, ENOENT};
use native;
use channel;
use channel::Channel;
use Filesystem;
use request::{request, dispatch};

/// The max size of write requests from the kernel. The absolute minimum is 4k,
/// FUSE recommends at least 128k, max 16M. The FUSE default is 16M on OS X
/// and 128k on other systems.
pub static MAX_WRITE_SIZE: uint = 16*1024*1024;

/// Size of the buffer for reading a request from the kernel. Since the kernel may send
/// up to MAX_WRITE_SIZE bytes in a write request, we use that value plus some extra space.
static BUFFER_SIZE: uint = MAX_WRITE_SIZE + 4096;

/// The session data structure
pub struct Session<FS> {
	/// Filesystem operation implementations
	pub filesystem: FS,
	/// Path of the mounted filesystem
	pub mountpoint: Path,
	/// Communication channel to the kernel driver
	ch: Channel,
	/// FUSE protocol major version
	pub proto_major: uint,
	/// FUSE protocol minor version
	pub proto_minor: uint,
	/// True if the filesystem is initialized (init operation done)
	pub initialized: bool,
	/// True if the filesystem was destroyed (destroy operation done)
	pub destroyed: bool,
}

impl<FS: Filesystem+Send> Session<FS> {
	/// Create a new session by mounting the given filesystem to the given mountpoint
	pub fn new (filesystem: FS, mountpoint: &Path, options: &[&[u8]]) -> Session<FS> {
		info!("Mounting {}", mountpoint.display());
		let ch = match Channel::new(mountpoint, options) {
			Ok(ch) => ch,
			Err(err) => fail!("Unable to mount filesystem. Error {:i}", err),
		};
		Session {
			filesystem: filesystem,
			mountpoint: mountpoint.clone(),
			ch: ch,
			proto_major: 0,
			proto_minor: 0,
			initialized: false,
			destroyed: false,
		}
	}

	/// Run the session loop that receives kernel requests and dispatches them to method
	/// calls into the filesystem. This read-dispatch-loop is non-concurrent to prevent
	/// having multiple buffers (which take up much memory), but the filesystem methods
	/// may run concurrent by spawning tasks.
	/// Make sure to run this on a new single threaded scheduler since native I/O in the
	/// session loop can block.
	pub fn run (&mut self) {
		// Buffer for receiving requests from the kernel. Only one is allocated and
		// it is reused immediately after dispatching to conserve memory and allocations.
		let mut buffer = Vec::from_elem(BUFFER_SIZE, 0u8);
		loop {
			// Read the next request from the given channel to kernel driver
			// The kernel driver makes sure that we get exactly one request per read
			match self.ch.receive(buffer.as_mut_slice()) {
				Err(ENOENT) => continue,				// Operation interrupted. Accordingly to FUSE, this is safe to retry
				Err(EINTR) => continue,					// Interrupted system call, retry
				Err(EAGAIN) => continue,				// Explicitly try again
				Err(ENODEV) => break,					// Filesystem was unmounted, quit the loop
				Err(err) => fail!("Lost connection to FUSE device. Error {:i}", err),
				Ok(len) => match request(self.ch.sender(), buffer.slice_to(len)) {
					None => break,						// Illegal request, quit the loop
					Some(req) => dispatch(&req, self),
				},
			}
		}
	}

	/// Run the session loop in a background task
	pub fn spawn (self) -> BackgroundSession {
		BackgroundSession::new(self)
	}
}

#[unsafe_destructor]
impl<FS: Filesystem+Send> Drop for Session<FS> {
	fn drop (&mut self) {
		info!("Unmounted {}", self.mountpoint.display());
		// The actual unmounting takes place because self.ch is dropped here
	}
}

/// The background session data structure
pub struct BackgroundSession {
	/// Path of the mounted filesystem
	pub mountpoint: Path,
}

impl BackgroundSession {
	/// Create a new background session for the given session by running its
	/// session loop in a background task. If the returned handle is dropped,
	/// the filesystem is unmounted and the given session ends.
	pub fn new<FS: Filesystem+Send> (se: Session<FS>) -> BackgroundSession {
		let mountpoint = se.mountpoint.clone();
		// The background task is started using a a new native thread
		// since native I/O in the session loop can block
		let task = TaskBuilder::new().named(format!("FUSE {}", mountpoint.display()));
		native::task::spawn_opts(task.opts, proc() {
			let mut se = se;
			se.run();
		});
		BackgroundSession { mountpoint: mountpoint }
	}
}

impl Drop for BackgroundSession {
	fn drop (&mut self) {
		info!("Unmounting {}", self.mountpoint.display());
		// Unmounting the filesystem will eventually end the session loop,
		// drop the session and hence end the background task.
		channel::unmount(&self.mountpoint);
	}
}
<|endoftext|>


<commit_before>s_no_extra_traits! {
    #[allow(missing_debug_implementations)]
    #[repr(align(16))]
    pub struct max_align_t {
        priv_: [f32; 8]
    }
}

s! {
    pub struct ucontext_t {
        pub uc_flags: ::c_ulong,
        pub uc_link: *mut ucontext_t,
        pub uc_stack: ::stack_t,
        pub uc_sigmask: ::sigset_t,
        pub uc_mcontext: mcontext_t,
    }

    #[repr(align(16))]
    pub struct mcontext_t {
        pub fault_address: ::c_ulonglong,
        pub regs: [::c_ulonglong; 31],
        pub sp: ::c_ulonglong,
        pub pc: ::c_ulonglong,
        pub pstate: ::c_ulonglong,
        // nested arrays to get the right size/length while being able to
        // auto-derive traits like Debug
        __reserved: [[u64; 32]; 16],
    }

    #[repr(align(16))]
    pub struct user_fpsimd_struct {
        pub vregs: [[u64; 2]; 32],
        pub fpsr: ::c_uint,
        pub fpcr: ::c_uint,
    }

    #[repr(align(8))]
    pub struct clone_args {
        pub flags: ::c_ulonglong,
        pub pidfd: ::c_ulonglong,
        pub child_tid: ::c_ulonglong,
        pub parent_tid: ::c_ulonglong,
        pub exit_signal: ::c_ulonglong,
        pub stack: ::c_ulonglong,
        pub stack_size: ::c_ulonglong,
        pub tls: ::c_ulonglong,
        pub set_tid: ::c_ulonglong,
        pub set_tid_size: ::c_ulonglong,
        pub cgroup: ::c_ulonglong,
    }
}
<commit_msg>Add sys/ucontext.h signatures for linux aarch64 glibc<commit_after>s_no_extra_traits! {
    #[allow(missing_debug_implementations)]
    #[repr(align(16))]
    pub struct max_align_t {
        priv_: [f32; 8]
    }
}

s! {
    pub struct ucontext_t {
        pub uc_flags: ::c_ulong,
        pub uc_link: *mut ucontext_t,
        pub uc_stack: ::stack_t,
        pub uc_sigmask: ::sigset_t,
        pub uc_mcontext: mcontext_t,
    }

    #[repr(align(16))]
    pub struct mcontext_t {
        pub fault_address: ::c_ulonglong,
        pub regs: [::c_ulonglong; 31],
        pub sp: ::c_ulonglong,
        pub pc: ::c_ulonglong,
        pub pstate: ::c_ulonglong,
        // nested arrays to get the right size/length while being able to
        // auto-derive traits like Debug
        __reserved: [[u64; 32]; 16],
    }

    #[repr(align(16))]
    pub struct user_fpsimd_struct {
        pub vregs: [[u64; 2]; 32],
        pub fpsr: ::c_uint,
        pub fpcr: ::c_uint,
    }

    #[repr(align(8))]
    pub struct clone_args {
        pub flags: ::c_ulonglong,
        pub pidfd: ::c_ulonglong,
        pub child_tid: ::c_ulonglong,
        pub parent_tid: ::c_ulonglong,
        pub exit_signal: ::c_ulonglong,
        pub stack: ::c_ulonglong,
        pub stack_size: ::c_ulonglong,
        pub tls: ::c_ulonglong,
        pub set_tid: ::c_ulonglong,
        pub set_tid_size: ::c_ulonglong,
        pub cgroup: ::c_ulonglong,
    }
}

extern "C" {
    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 "C" fn(), argc: ::c_int, ...);
    pub fn swapcontext(uocp: *mut ucontext_t, ucp: *const ucontext_t) -> ::c_int;
}
<|endoftext|>


<commit_before>use std::{
    sync::Arc,
    time,
};

use ra_db::{
    CheckCanceled, FileId, Canceled, SourceDatabase,
    salsa,
};

use crate::{LineIndex, symbol_index::{self, SymbolsDatabase}};

#[salsa::database(
    ra_db::SourceDatabaseStorage,
    LineIndexDatabaseStorage,
    symbol_index::SymbolsDatabaseStorage,
    hir::db::HirDatabaseStorage,
    hir::db::DefDatabaseStorage
)]
#[derive(Debug)]
pub(crate) struct RootDatabase {
    runtime: salsa::Runtime<RootDatabase>,
    pub(crate) last_gc: time::Instant,
    pub(crate) last_gc_check: time::Instant,
}

impl salsa::Database for RootDatabase {
    fn salsa_runtime(&self) -> &salsa::Runtime<RootDatabase> {
        &self.runtime
    }
    fn on_propagated_panic(&self) -> ! {
        Canceled::throw()
    }
}

impl Default for RootDatabase {
    fn default() -> RootDatabase {
        let mut db = RootDatabase {
            runtime: salsa::Runtime::default(),
            last_gc: time::Instant::now(),
            last_gc_check: time::Instant::now(),
        };
        db.set_crate_graph(Default::default());
        db.set_local_roots(Default::default());
        db.set_library_roots(Default::default());
        db
    }
}

impl salsa::ParallelDatabase for RootDatabase {
    fn snapshot(&self) -> salsa::Snapshot<RootDatabase> {
        salsa::Snapshot::new(RootDatabase {
            runtime: self.runtime.snapshot(self),
            last_gc: self.last_gc.clone(),
            last_gc_check: self.last_gc_check.clone(),
        })
    }
}

#[salsa::query_group(LineIndexDatabaseStorage)]
pub(crate) trait LineIndexDatabase: ra_db::SourceDatabase + CheckCanceled {
    fn line_index(&self, file_id: FileId) -> Arc<LineIndex>;
}

fn line_index(db: &impl ra_db::SourceDatabase, file_id: FileId) -> Arc<LineIndex> {
    let text = db.file_text(file_id);
    Arc::new(LineIndex::new(&*text))
}
<commit_msg>cancel salsa's validation<commit_after>use std::{
    sync::Arc,
    time,
};

use ra_db::{
    CheckCanceled, FileId, Canceled, SourceDatabase,
    salsa,
};

use crate::{LineIndex, symbol_index::{self, SymbolsDatabase}};

#[salsa::database(
    ra_db::SourceDatabaseStorage,
    LineIndexDatabaseStorage,
    symbol_index::SymbolsDatabaseStorage,
    hir::db::HirDatabaseStorage,
    hir::db::DefDatabaseStorage
)]
#[derive(Debug)]
pub(crate) struct RootDatabase {
    runtime: salsa::Runtime<RootDatabase>,
    pub(crate) last_gc: time::Instant,
    pub(crate) last_gc_check: time::Instant,
}

impl salsa::Database for RootDatabase {
    fn salsa_runtime(&self) -> &salsa::Runtime<RootDatabase> {
        &self.runtime
    }
    fn on_propagated_panic(&self) -> ! {
        Canceled::throw()
    }
    fn salsa_event(&self, event: impl Fn() -> salsa::Event<RootDatabase>) {
        if let salsa::EventKind::DidValidateMemoizedValue { .. } = event().kind {
            self.check_canceled();
        }
    }
}

impl Default for RootDatabase {
    fn default() -> RootDatabase {
        let mut db = RootDatabase {
            runtime: salsa::Runtime::default(),
            last_gc: time::Instant::now(),
            last_gc_check: time::Instant::now(),
        };
        db.set_crate_graph(Default::default());
        db.set_local_roots(Default::default());
        db.set_library_roots(Default::default());
        db
    }
}

impl salsa::ParallelDatabase for RootDatabase {
    fn snapshot(&self) -> salsa::Snapshot<RootDatabase> {
        salsa::Snapshot::new(RootDatabase {
            runtime: self.runtime.snapshot(self),
            last_gc: self.last_gc.clone(),
            last_gc_check: self.last_gc_check.clone(),
        })
    }
}

#[salsa::query_group(LineIndexDatabaseStorage)]
pub(crate) trait LineIndexDatabase: ra_db::SourceDatabase + CheckCanceled {
    fn line_index(&self, file_id: FileId) -> Arc<LineIndex>;
}

fn line_index(db: &impl ra_db::SourceDatabase, file_id: FileId) -> Arc<LineIndex> {
    let text = db.file_text(file_id);
    Arc::new(LineIndex::new(&*text))
}
<|endoftext|>


<commit_before>use std::collections::HashSet;
use std::cmp::{Ordering};
use std::fmt;
use std::num::{UnsignedInt, Int};
use time::now_utc;

use tx::{self, Transaction};
use sodiumoxide::crypto::hash::sha512::{self, Digest, HASHBYTES};

pub struct ProofHash([u8; HASHBYTES]);

impl ProofHash {
    fn from_u64(mut value: u64) -> ProofHash {
        let mut proof_hash = ProofHash([0; HASHBYTES]);
        let mut index = 0us;
        while value > 0u64 {
            proof_hash.0[index] = (value & 0xffu64) as u8;
            value = value >> 8;
            index += 1;
        }
        proof_hash
    }

    fn multiply_in_place(&mut self, other: &ProofHash) {
        let mut quot = 0u16;
        for index in range(0, HASHBYTES) {
            quot = self.0[index] as u16 * other.0[index] as u16 + quot;
            self.0[index] = (quot & 0x00ffu16) as u8;
            quot = quot >> 8;
        }
    }
}

impl PartialEq for ProofHash {
    fn eq(&self, other: &ProofHash) -> bool {
        for (byte1, byte2) in self.0.iter().zip(other.0.iter()) {
            if byte1 != byte2 {
                return false;
            }
        }
        true
    }
}

impl Eq for ProofHash {}

impl PartialOrd for ProofHash {
    fn partial_cmp(&self, other: &ProofHash) -> Option<Ordering> {
        for (byte1, byte2) in self.0.iter().rev().zip(
            other.0.iter().rev()) {
            if byte1 > byte2 {
                return Some(Ordering::Greater);
            } else if byte2 > byte1 {
                return Some(Ordering::Less);
            }
        }
        return Some(Ordering::Equal);
    }
}

impl Ord for ProofHash {
    fn cmp(&self, other: &ProofHash) -> Ordering {
        self.partial_cmp(other).unwrap()
    }
}

impl fmt::Debug for ProofHash {
    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
        write!(formatter, "{:?}", &self.0[])
    }
}

pub struct ThreadedStaker {
    tx_pool: HashSet<String>
}

#[test]
fn test_from_u64() {
    let mut hash1 = ProofHash::from_u64(2100);
    let mut hash2 = ProofHash::from_u64(65535);

    assert!(hash1.0[0] == 52);
    assert!(hash1.0[1] == 8);
    assert!(hash2.0[0] == 255);
    assert!(hash2.0[1] == 255);
    for i in range(3, HASHBYTES) {
        assert!(hash1.0[i] == 0);
        assert!(hash2.0[i] == 0);
    }
}

#[test]
fn test_hash_multiply() {
    let mut hash1 = ProofHash::from_u64(2100);
    let hash2 = ProofHash::from_u64(65535);
    hash1.multiply_in_place(&hash2);
    assert!(hash1.0[0] == 204);
    assert!(hash1.0[1] == 43);
    assert!(hash1.0[2] == 8);
    for i in range(3, HASHBYTES) {
        assert!(hash1.0[i] == 0);
    }

    let mut hash3 = ProofHash::from_u64(65536);
    println!("* hash3: {:?}", hash3);
    println!("* hash3 == hash3: {}", hash3 == hash3);
    println!("* hash3 > hash3: {}", hash3 > hash3);
    println!("* hash3 > hash2: {}", hash3 > hash2);
    println!("* hash3 < hash2: {}", hash3 < hash2);
    // hash3.multiply
}

#[test]
fn test_proof_hash_ord() {
    let hashes = [
        ProofHash::from_u64(0), ProofHash::from_u64(2100),
        ProofHash::from_u64(65535), ProofHash::from_u64(65536),
        ProofHash::from_u64(65536 * 100000)];

    for i in range(0, hashes.len() - 1) {
        for j in range(i + 1, hashes.len()) {
            assert!(hashes[i] < hashes[j]);
            assert!(hashes[j] > hashes[i]);
        }
    }
}

#[test]
fn test_proof_hash() {
    let Digest(target_hash_bytes) = sha512::hash(b"hello world2");
    let target_hash = ProofHash(target_hash_bytes);
    let now_secs = now_utc().to_timespec().sec;
    println!("now_secs = {}", now_secs);
    println!("target_hash = {:?}", target_hash);
    for i in range(0, 100) {
        let Digest(hash_bytes) = sha512::hash(
            format!("{}", now_secs + i).as_bytes());
        let hash = ProofHash(hash_bytes);
        if hash > target_hash {
            println!("hash({}) = {:?}", now_secs + i, hash);
        }
    }
}

// use std::sync::mpsc::{channel, Sender, Receiver};
// struct SimplesService {
//     tx_sender: Sender<simples_pb::Transaction>,
// }

// impl Service for SimplesService {
//     fn pub_transaction(
//         &mut self, request: simples_pb::PublishTransactionRequest) ->
//         SimplesResult<simples_pb::PublishTransactionResponse> {
//             println!("{:?}", request.get_transaction());
//             let response = simples_pb::PublishTransactionResponse::new();
//             Ok(response)
//             // tx_sender.send(msg).unwrap();
//             // let reply = format!("reply");
//         }
// }
<commit_msg>Moved ProofHash to crypto and renamed it to DigestHash.<commit_after>use std::collections::HashSet;

use tx::{self, Transaction};
use sodiumoxide::crypto::hash::sha512::{self, Digest, HASHBYTES};

pub struct ThreadedStaker {
    tx_pool: HashSet<String>
}

// use std::sync::mpsc::{channel, Sender, Receiver};
// struct SimplesService {
//     tx_sender: Sender<simples_pb::Transaction>,
// }

// impl Service for SimplesService {
//     fn pub_transaction(
//         &mut self, request: simples_pb::PublishTransactionRequest) ->
//         SimplesResult<simples_pb::PublishTransactionResponse> {
//             println!("{:?}", request.get_transaction());
//             let response = simples_pb::PublishTransactionResponse::new();
//             Ok(response)
//             // tx_sender.send(msg).unwrap();
//             // let reply = format!("reply");
//         }
// }
<|endoftext|>


<commit_before>use serde_json;
use reqwest;
use std;
use std::fs::File;
use std::io::Read;
use toml;

#[derive(Deserialize, Debug, Clone)]
pub struct Config {
    pub token: String,
    pub org: String,
    pub team: String,
    #[serde(default = "default_endpoint")]
    pub endpoint: String,
    #[serde(default = "default_home")]
    pub home: String,
    #[serde(default = "default_gid")]
    pub gid: u64,
    #[serde(default = "default_sh")]
    pub sh: String,
    pub group: Option<String>,
    #[serde(default = "default_cache_duration")]
    pub cache_duration: u64,
    #[serde(default = "default_cert_path")]
    pub cert_path: String,
}

fn default_endpoint() -> String { String::from("https://api.github.com") }
fn default_home() -> String { String::from("/home/{}") }
fn default_gid() -> u64 { 2000 }
fn default_sh() -> String { String::from("/bin/bash") }
fn default_cache_duration() -> u64 { 3600 }
fn default_cert_path() -> String { String::from("/etc/ssl/certs/ca-certificates.crt") }

impl Config {
    pub fn new(configpath: &str) -> Result<Self, CliError> {
        let mut file = File::open(configpath)?;
        let mut contents = String::new();
        file.read_to_string(&mut contents)?;
        Ok(toml::from_str::<Config>(&contents)?)
    }
}

#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct PersonalConfig {
    pub sh: Option<String>,
}

impl PersonalConfig {
    pub fn new(configpath: &str) -> Result<Self, CliError> {
        let mut file = File::open(configpath)?;
        let mut contents = String::new();
        file.read_to_string(&mut contents)?;
        Ok(toml::from_str::<PersonalConfig>(&contents)?)
    }
}

#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct Team {
    pub id: u64,
    pub name: String,
}

#[derive(Serialize, Deserialize, Debug)]
pub struct Member {
    pub id: u64,
    pub login: String,
}

#[derive(Serialize, Deserialize, Debug)]
pub struct PublicKey {
    pub id: u64,
    pub key: String,
}

#[derive(Debug)]
pub enum CliError {
    Serde(serde_json::Error),
    Reqwest(reqwest::Error),
    Io(std::io::Error),
    Toml(toml::de::Error),
}

impl From<serde_json::Error> for CliError {
    fn from(err: serde_json::Error) -> CliError { CliError::Serde(err) }
}
impl From<reqwest::Error> for CliError {
    fn from(err: reqwest::Error) -> CliError { CliError::Reqwest(err) }
}
impl From<std::io::Error> for CliError {
    fn from(err: std::io::Error) -> CliError { CliError::Io(err) }
}
impl From<toml::de::Error> for CliError {
    fn from(err: toml::de::Error) -> CliError { CliError::Toml(err) }
}
<commit_msg>Allow dead code for main<commit_after>use serde_json;
use reqwest;
use std;
use std::fs::File;
use std::io::Read;
use toml;

#[derive(Deserialize, Debug, Clone)]
pub struct Config {
    pub token: String,
    pub org: String,
    pub team: String,
    #[serde(default = "default_endpoint")]
    pub endpoint: String,
    #[serde(default = "default_home")]
    pub home: String,
    #[serde(default = "default_gid")]
    pub gid: u64,
    #[serde(default = "default_sh")]
    pub sh: String,
    pub group: Option<String>,
    #[serde(default = "default_cache_duration")]
    pub cache_duration: u64,
    #[serde(default = "default_cert_path")]
    pub cert_path: String,
}

fn default_endpoint() -> String { String::from("https://api.github.com") }
fn default_home() -> String { String::from("/home/{}") }
fn default_gid() -> u64 { 2000 }
fn default_sh() -> String { String::from("/bin/bash") }
fn default_cache_duration() -> u64 { 3600 }
fn default_cert_path() -> String { String::from("/etc/ssl/certs/ca-certificates.crt") }

impl Config {
    pub fn new(configpath: &str) -> Result<Self, CliError> {
        let mut file = File::open(configpath)?;
        let mut contents = String::new();
        file.read_to_string(&mut contents)?;
        Ok(toml::from_str::<Config>(&contents)?)
    }
}

#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct PersonalConfig {
    pub sh: Option<String>,
}

impl PersonalConfig {
    #[allow(dead_code)]
    pub fn new(configpath: &str) -> Result<Self, CliError> {
        let mut file = File::open(configpath)?;
        let mut contents = String::new();
        file.read_to_string(&mut contents)?;
        Ok(toml::from_str::<PersonalConfig>(&contents)?)
    }
}

#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct Team {
    pub id: u64,
    pub name: String,
}

#[derive(Serialize, Deserialize, Debug)]
pub struct Member {
    pub id: u64,
    pub login: String,
}

#[derive(Serialize, Deserialize, Debug)]
pub struct PublicKey {
    pub id: u64,
    pub key: String,
}

#[derive(Debug)]
pub enum CliError {
    Serde(serde_json::Error),
    Reqwest(reqwest::Error),
    Io(std::io::Error),
    Toml(toml::de::Error),
}

impl From<serde_json::Error> for CliError {
    fn from(err: serde_json::Error) -> CliError { CliError::Serde(err) }
}
impl From<reqwest::Error> for CliError {
    fn from(err: reqwest::Error) -> CliError { CliError::Reqwest(err) }
}
impl From<std::io::Error> for CliError {
    fn from(err: std::io::Error) -> CliError { CliError::Io(err) }
}
impl From<toml::de::Error> for CliError {
    fn from(err: toml::de::Error) -> CliError { CliError::Toml(err) }
}
<|endoftext|>


<commit_before>
use std::vec::Vec;

enum TagTree<Leaf, Node, Edge> {
    Leaf(Leaf),
    Node(Node, Vec<(Edge, Box<TagTree<Leaf, Node, Edge>>)>)
}

impl<Leaf, Node, Edge> TagTree<Leaf, Node, Edge> {

    fn fold_tag_tree<T, FL, FN, FE> (
        &self,
        ref reduce_leaf: FL,
        ref reduce_node: FN,
        ref reduce_edge: FE) -> T
        where
            FL: Fn(&Leaf) -> T,
            FN: Fn(&Node, Vec<T>) -> T,
            FE: Fn(&Edge, T) -> T
            {
                match self {
                    &TagTree::Leaf(ref leaf) => reduce_leaf(leaf),
                    &TagTree::Node(ref node, ref children) => {
                        let subs = children.iter().map(|edgeChild| {
                            match edgeChild {
                                &(ref edge, box ref child) => {
                                    let childT = child.fold_tag_tree(reduce_leaf, reduce_node, reduce_edge);
                                    reduce_edge(edge, childT)
                                }
                            }
                        }).collect();
                        reduce_node(node, subs)
                    }
                }
            }
}
<commit_msg>warnings<commit_after>
use std::vec::Vec;

pub enum TagTree<Leaf, Node, Edge> {
    Leaf(Leaf),
    Node(Node, Vec<(Edge, Box<TagTree<Leaf, Node, Edge>>)>)
}

impl<Leaf, Node, Edge> TagTree<Leaf, Node, Edge> {

    pub fn fold_tag_tree<T, FL, FN, FE> (
        &self,
        ref reduce_leaf: FL,
        ref reduce_node: FN,
        ref reduce_edge: FE) -> T
        where
            FL: Fn(&Leaf) -> T,
            FN: Fn(&Node, Vec<T>) -> T,
            FE: Fn(&Edge, T) -> T
            {
                match self {
                    &TagTree::Leaf(ref leaf) => reduce_leaf(leaf),
                    &TagTree::Node(ref node, ref children) => {
                        let subs = children.iter().map(|edge_child| {
                            match edge_child {
                                &(ref edge, box ref child) => {
                                    let sub = child.fold_tag_tree(reduce_leaf, reduce_node, reduce_edge);
                                    reduce_edge(edge, sub)
                                }
                            }
                        }).collect();
                        reduce_node(node, subs)
                    }
                }
            }
}
<|endoftext|>


<commit_before>use std::ops;

///A 2D Vector with x and y coordinates: Vector2
#[derive(PartialEq, Debug)]
pub struct Vector2 {
    x: f32,
    y: f32,
}

///A 2D Vector with x and y coordinates: Vector2
#[derive(PartialEq, Debug)]
pub struct Point2 {
    x: f32,
    y: f32,
}

impl Vector2 {
    ///Instantiates a new vector with to be defined values of x and y;
    pub fn new(x: f32, y: f32) -> Vector2 {
        Vector2 {x: x, y: y}
    }

    ///Instantiates a new Vector2 from 2 Point2 (initial position, final position).
    ///The new fector is created as final - initial (Points)
    pub fn diff(initialPoint: Point2, finalPoint: Point2) -> Vector2 {
        Vector2 {x: finalPoint.x - initialPoint.x, y: finalPoint.y - initialPoint.y}
    }

    ///Defines a Vector with UP direction (y=1, x=0)
    pub fn UP() -> Vector2 {
        Vector2 {x: 0f32, y: 1f32}
    }

    ///Defines a Vector with DOWN direction (y=-1, x=0)
    pub fn DOWN() -> Vector2 {
        Vector2 {x: 0f32, y: -1f32}
    }

    ///Defines a Vector with RIGHT direction (y=0, x=1)
    pub fn RIGHT() -> Vector2 {
        Vector2 {x: 1f32, y: 0f32}
    }

    ///Defines a Vector with LEFT direction (y=0, x=-1)
    pub fn LEFT() -> Vector2 {
        Vector2 {x: -1f32, y: 0f32}
    }

    ///Defines a 2D Vector with x=1 and y=1
    pub fn ONE() -> Vector2 {
        Vector2 {x: 1f32, y: 1f32}
    }

    ///Defines a Modulus ZERO Vector (x=0, y=0)
    pub fn ZERO() -> Vector2 {
        Vector2 {x: 0f32, y: 0f32}
    }

    ///Vector magnitude: the square root of the sum of each vector part to the power of 2
    pub fn magnitude(self) -> f32 {
        f32::sqrt(self.x.powi(2) + self.y.powi(2))
    }
}

impl ops::Add for Vector2 {
    type Output = Vector2;

    ///Implements the Vector2 '+' trait
    fn add(self, new_vec: Vector2) -> Vector2 {
        Vector2 {x: self.x + new_vec.x, y: self.y + new_vec.y}
    }
}

impl ops::Mul<f32> for Vector2 {
    type Output = Vector2;

    ///Implements the scalar multiplication of a Vector2 with a f32. Other numbers should
    ///be passed with 'i as f32'
    fn mul(self, value: f32) -> Vector2 {
        Vector2 {x: self.x * value, y: self.y * value}
    }
}

impl ops::Mul<Vector2> for Vector2 {
    type Output = f32;

    ///Implements the dot product of 2 Vector2 as '*'.
    fn mul(self, new_vec: Vector2) -> f32 {
        self.x * new_vec.x + self.y * new_vec.y
    }
}

impl ops::Sub for Vector2 {
    type Output = Vector2;

    ///Implements the Vector2 '-' trait
    fn sub(self, new_vec: Vector2) -> Vector2 {
        Vector2 {x: self.x - new_vec.x, y: self.y - new_vec.y}
    }
}

impl Point2 {
    pub fn new(x: f32, y: f32) -> Point2 {
        Point2 {x: x, y: y}
    }

    pub fn to_vec(self) -> Vector2 {
        Vector2::diff(Point2::ZERO(), self)
    }

    fn ZERO() -> Point2 {
        Point2::new(0f32, 0f32)
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn creates_vector2_with_parameters() {
        let actual = Vector2::new(1f32, 1f32);
        let expected = Vector2 {x: 1f32, y: 1f32};
        assert!(expected.x == actual.x &&
            expected.y == actual.y);
    }

    #[test]
    fn creates_vector2_up() {
        let actual = Vector2::UP();
        assert!(actual.x == 0f32 &&
            actual.y == 1f32);
    }

    #[test]
    fn adds_right_and_left_vectors() {
         let actual = Vector2::RIGHT() + Vector2::LEFT();
         assert_eq!(actual.x, 0f32);
    }

    #[test]
    fn adds_right_and_up() {
        let actual = Vector2::RIGHT() + Vector2::UP();
        assert_eq!(actual.x, 1f32);
        assert_eq!(actual.y, 1f32);
    }

    #[test]
    fn mult_one_by_3() {
        let actual = Vector2::ONE() * 3f32;
        assert_eq!(actual.x, 3f32);
        assert_eq!(actual.y, 3f32);
    }

    #[test]
    fn sub_right_from_one() {
        let actual = Vector2::ONE() - Vector2::RIGHT();
        assert_eq!(actual.x, 0f32);
        assert_eq!(actual.y, 1f32);
    }

    #[test]
    fn magnitude_of_vector() {
        let vec = Vector2 {x: 3f32, y: 4f32};
        assert_eq!(vec.magnitude(), 5f32);
    }

    #[test]
    fn magnitude_of_vector_is_positive() {
        let vec = Vector2 {x: -3f32, y: 4f32};
        assert!(vec.magnitude() >= 0f32);
    }

    #[test]
    fn dot_product() {
        let vec1 = Vector2 {x: 2f32, y: 1f32};
        let vec2 = Vector2 {x: 1f32, y: 2f32};
        let actual = vec1 * vec2;
        let expected = 4f32;
        assert_eq!(actual, expected);
    }

    #[test]
    fn constructs_vector2_from_points2() {
        let vec = Vector2::diff(Point2 {x: 1f32, y: -1f32}, Point2 {x: 2f32, y: 3f32});
        assert_eq!(vec.x, 1f32);
        assert_eq!(vec.y, 4f32);
    }

    #[test]
    fn creates_point2_with_parameters() {
        let actual = Point2::new(1f32, 1f32);
        let expected = Point2 {x: 1f32, y: 1f32};
        assert!(expected.x == actual.x &&
            expected.y == actual.y);
    }

    #[test]
    fn creates_vector_from_point2() {
        let point = Point2::new(1f32, 1f32);
        let actual = point.to_vec();
        let expected = Vector2::ONE();
        assert!(expected.x == actual.x &&
            expected.y == actual.y);
    }
}
<commit_msg>added P + PQ = Q logic<commit_after>use std::ops;

///A 2D Vector with x and y coordinates: Vector2
#[derive(PartialEq, Debug)]
pub struct Vector2 {
    x: f32,
    y: f32,
}

///A 2D Vector with x and y coordinates: Vector2
#[derive(PartialEq, Debug)]
pub struct Point2 {
    x: f32,
    y: f32,
}

impl Vector2 {
    ///Instantiates a new vector with to be defined values of x and y;
    pub fn new(x: f32, y: f32) -> Vector2 {
        Vector2 {x: x, y: y}
    }

    ///Instantiates a new Vector2 from 2 Point2 (initial position, final position).
    ///The new fector is created as final - initial (Points)
    pub fn diff(initialPoint: Point2, finalPoint: Point2) -> Vector2 {
        Vector2 {x: finalPoint.x - initialPoint.x, y: finalPoint.y - initialPoint.y}
    }

    ///Defines a Vector with UP direction (y=1, x=0)
    pub fn UP() -> Vector2 {
        Vector2 {x: 0f32, y: 1f32}
    }

    ///Defines a Vector with DOWN direction (y=-1, x=0)
    pub fn DOWN() -> Vector2 {
        Vector2 {x: 0f32, y: -1f32}
    }

    ///Defines a Vector with RIGHT direction (y=0, x=1)
    pub fn RIGHT() -> Vector2 {
        Vector2 {x: 1f32, y: 0f32}
    }

    ///Defines a Vector with LEFT direction (y=0, x=-1)
    pub fn LEFT() -> Vector2 {
        Vector2 {x: -1f32, y: 0f32}
    }

    ///Defines a 2D Vector with x=1 and y=1
    pub fn ONE() -> Vector2 {
        Vector2 {x: 1f32, y: 1f32}
    }

    ///Defines a Modulus ZERO Vector (x=0, y=0)
    pub fn ZERO() -> Vector2 {
        Vector2 {x: 0f32, y: 0f32}
    }

    ///Vector magnitude: the square root of the sum of each vector part to the power of 2
    pub fn magnitude(self) -> f32 {
        f32::sqrt(self.x.powi(2) + self.y.powi(2))
    }
}

impl ops::Add for Vector2 {
    type Output = Vector2;

    ///Implements the Vector2 '+' trait
    fn add(self, new_vec: Vector2) -> Vector2 {
        Vector2 {x: self.x + new_vec.x, y: self.y + new_vec.y}
    }
}

impl ops::Mul<f32> for Vector2 {
    type Output = Vector2;

    ///Implements the scalar multiplication of a Vector2 with a f32. Other numbers should
    ///be passed with 'i as f32'
    fn mul(self, value: f32) -> Vector2 {
        Vector2 {x: self.x * value, y: self.y * value}
    }
}

impl ops::Mul<Vector2> for Vector2 {
    type Output = f32;

    ///Implements the dot product of 2 Vector2 as '*'.
    fn mul(self, new_vec: Vector2) -> f32 {
        self.x * new_vec.x + self.y * new_vec.y
    }
}

impl ops::Sub for Vector2 {
    type Output = Vector2;

    ///Implements the Vector2 '-' trait
    fn sub(self, new_vec: Vector2) -> Vector2 {
        Vector2 {x: self.x - new_vec.x, y: self.y - new_vec.y}
    }
}

impl Point2 {
    ///Instantiates a new Point2D with x and y.
    pub fn new(x: f32, y: f32) -> Point2 {
        Point2 {x: x, y: y}
    }

    ///Creates a new Vector2 relative to position (0, 0)
    pub fn to_vec(self) -> Vector2 {
        Vector2::diff(Point2::ZERO(), self)
    }

    ///Instantiates a Point2 with (0, 0)
    fn ZERO() -> Point2 {
        Point2::new(0f32, 0f32)
    }
}

impl ops::Add<Vector2> for Point2 {
    type Output = Point2;

    ///Overloads + for Points and Vectors: P + PQ = Q
    fn add(self, new_vec: Vector2) -> Point2 {
        Point2 {x: self.x + new_vec.x, y: self.y + new_vec.y}
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn creates_vector2_with_parameters() {
        let actual = Vector2::new(1f32, 1f32);
        let expected = Vector2 {x: 1f32, y: 1f32};
        assert!(expected.x == actual.x &&
            expected.y == actual.y);
    }

    #[test]
    fn creates_vector2_up() {
        let actual = Vector2::UP();
        assert!(actual.x == 0f32 &&
            actual.y == 1f32);
    }

    #[test]
    fn adds_right_and_left_vectors() {
         let actual = Vector2::RIGHT() + Vector2::LEFT();
         assert_eq!(actual.x, 0f32);
    }

    #[test]
    fn adds_right_and_up() {
        let actual = Vector2::RIGHT() + Vector2::UP();
        assert_eq!(actual.x, 1f32);
        assert_eq!(actual.y, 1f32);
    }

    #[test]
    fn mult_one_by_3() {
        let actual = Vector2::ONE() * 3f32;
        assert_eq!(actual.x, 3f32);
        assert_eq!(actual.y, 3f32);
    }

    #[test]
    fn sub_right_from_one() {
        let actual = Vector2::ONE() - Vector2::RIGHT();
        assert_eq!(actual.x, 0f32);
        assert_eq!(actual.y, 1f32);
    }

    #[test]
    fn magnitude_of_vector() {
        let vec = Vector2 {x: 3f32, y: 4f32};
        assert_eq!(vec.magnitude(), 5f32);
    }

    #[test]
    fn magnitude_of_vector_is_positive() {
        let vec = Vector2 {x: -3f32, y: 4f32};
        assert!(vec.magnitude() >= 0f32);
    }

    #[test]
    fn dot_product() {
        let vec1 = Vector2 {x: 2f32, y: 1f32};
        let vec2 = Vector2 {x: 1f32, y: 2f32};
        let actual = vec1 * vec2;
        let expected = 4f32;
        assert_eq!(actual, expected);
    }

    #[test]
    fn constructs_vector2_from_points2() {
        let vec = Vector2::diff(Point2 {x: 1f32, y: -1f32}, Point2 {x: 2f32, y: 3f32});
        assert_eq!(vec.x, 1f32);
        assert_eq!(vec.y, 4f32);
    }

    #[test]
    fn creates_point2_with_parameters() {
        let actual = Point2::new(1f32, 1f32);
        let expected = Point2 {x: 1f32, y: 1f32};
        assert!(expected.x == actual.x &&
            expected.y == actual.y);
    }

    #[test]
    fn creates_vector_from_point2() {
        let point = Point2::new(1f32, 1f32);
        let actual = point.to_vec();
        let expected = Vector2::ONE();
        assert!(expected.x == actual.x &&
            expected.y == actual.y);
    }

    #[test]
    fn point_add_vector_result_new_point() {
        let point = Point2::ZERO();
        let vec = Vector2::new(2f32, 3f32);
        let actual = point + vec;
        assert_eq!(actual.x, 2f32);
        assert_eq!(actual.y, 3f32);
    }
}
<|endoftext|>


<commit_before>// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// 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. This file may not be copied, modified, or distributed
// except according to those terms.

use syntax::ast;
use syntax::codemap::{self, CodeMap, Span, BytePos};
use syntax::visit;

use utils;

use {MAX_WIDTH, TAB_SPACES, SKIP_ANNOTATION};
use changes::ChangeSet;

pub struct FmtVisitor<'a> {
    pub codemap: &'a CodeMap,
    pub changes: ChangeSet<'a>,
    pub last_pos: BytePos,
    // TODO RAII util for indenting
    pub block_indent: usize,
}

impl<'a, 'v> visit::Visitor<'v> for FmtVisitor<'a> {
    fn visit_expr(&mut self, ex: &'v ast::Expr) {
        debug!("visit_expr: {:?} {:?}",
               self.codemap.lookup_char_pos(ex.span.lo),
               self.codemap.lookup_char_pos(ex.span.hi));
        self.format_missing(ex.span.lo);
        let offset = self.changes.cur_offset_span(ex.span);
        let new_str = self.rewrite_expr(ex, MAX_WIDTH - offset, offset);
        self.changes.push_str_span(ex.span, &new_str);
        self.last_pos = ex.span.hi;
    }

    fn visit_stmt(&mut self, stmt: &'v ast::Stmt) {
        // If the stmt is actually an item, then we'll handle any missing spans
        // there. This is important because of annotations.
        // Although it might make more sense for the statement span to include
        // any annotations on the item.
        let skip_missing = match stmt.node {
            ast::Stmt_::StmtDecl(ref decl, _) => {
                match decl.node {
                    ast::Decl_::DeclItem(_) => true,
                    _ => false,
                }
            }
            _ => false,
        };
        if !skip_missing {
            self.format_missing_with_indent(stmt.span.lo);
        }
        visit::walk_stmt(self, stmt);
    }

    fn visit_block(&mut self, b: &'v ast::Block) {
        debug!("visit_block: {:?} {:?}",
               self.codemap.lookup_char_pos(b.span.lo),
               self.codemap.lookup_char_pos(b.span.hi));
        self.format_missing(b.span.lo);

        self.changes.push_str_span(b.span, "{");
        self.last_pos = self.last_pos + BytePos(1);
        self.block_indent += TAB_SPACES;

        for stmt in &b.stmts {
            self.visit_stmt(&stmt)
        }
        match b.expr {
            Some(ref e) => {
                self.format_missing_with_indent(e.span.lo);
                self.visit_expr(e);
            }
            None => {}
        }

        self.block_indent -= TAB_SPACES;
        // TODO we should compress any newlines here to just one
        self.format_missing_with_indent(b.span.hi - BytePos(1));
        self.changes.push_str_span(b.span, "}");
        self.last_pos = b.span.hi;
    }

    // Note that this only gets called for function defintions. Required methods
    // on traits do not get handled here.
    fn visit_fn(&mut self,
                fk: visit::FnKind<'v>,
                fd: &'v ast::FnDecl,
                b: &'v ast::Block,
                s: Span,
                _: ast::NodeId) {
        self.format_missing(s.lo);
        self.last_pos = s.lo;

        let indent = self.block_indent;
        match fk {
            visit::FkItemFn(ident, ref generics, ref unsafety, ref abi, vis) => {
                let new_fn = self.rewrite_fn(indent,
                                             ident,
                                             fd,
                                             None,
                                             generics,
                                             unsafety,
                                             abi,
                                             vis,
                                             b.span);
                self.changes.push_str_span(s, &new_fn);
            }
            visit::FkMethod(ident, ref sig, vis) => {
                let new_fn = self.rewrite_fn(indent,
                                             ident,
                                             fd,
                                             Some(&sig.explicit_self),
                                             &sig.generics,
                                             &sig.unsafety,
                                             &sig.abi,
                                             vis.unwrap_or(ast::Visibility::Inherited),
                                             b.span);
                self.changes.push_str_span(s, &new_fn);
            }
            visit::FkFnBlock(..) => {}
        }

        self.last_pos = b.span.lo;
        self.visit_block(b)
    }

    fn visit_item(&mut self, item: &'v ast::Item) {
        // Don't look at attributes for modules.
        // We want to avoid looking at attributes in another file, which the AST
        // doesn't distinguish. FIXME This is overly conservative and means we miss
        // attributes on inline modules.
        match item.node {
            ast::Item_::ItemMod(_) => {}
            _ => {
                if self.visit_attrs(&item.attrs) {
                    return;
                }
            }
        }

        match item.node {
            ast::Item_::ItemUse(ref vp) => {
                match vp.node {
                    ast::ViewPath_::ViewPathList(ref path, ref path_list) => {
                        self.format_missing(item.span.lo);
                        let new_str = self.rewrite_use_list(path, path_list, vp.span);
                        self.changes.push_str_span(item.span, &new_str);
                        self.last_pos = item.span.hi;
                    }
                    ast::ViewPath_::ViewPathGlob(_) => {
                        // FIXME convert to list?
                    }
                    _ => {}
                }
                visit::walk_item(self, item);
            }
            ast::Item_::ItemImpl(..) => {
                self.block_indent += TAB_SPACES;
                visit::walk_item(self, item);
                self.block_indent -= TAB_SPACES;
            }
            ast::Item_::ItemMod(_) => {
                self.block_indent += TAB_SPACES;
                visit::walk_item(self, item);
                self.block_indent -= TAB_SPACES;
            }
            ast::Item_::ItemExternCrate(_) => {
                self.format_missing_with_indent(item.span.lo);
                let new_str = self.snippet(item.span);
                self.changes.push_str_span(item.span, &new_str);
                self.last_pos = item.span.hi;
            }
            _ => {
                visit::walk_item(self, item);
            }
        }
    }

    fn visit_trait_item(&mut self, ti: &'v ast::TraitItem) {
        if self.visit_attrs(&ti.attrs) {
            return;
        }
        visit::walk_trait_item(self, ti)
    }

    fn visit_impl_item(&mut self, ii: &'v ast::ImplItem) {
        if self.visit_attrs(&ii.attrs) {
            return;
        }
        visit::walk_impl_item(self, ii)
    }

    fn visit_mac(&mut self, mac: &'v ast::Mac) {
        visit::walk_mac(self, mac)
    }

    fn visit_mod(&mut self, m: &'v ast::Mod, s: Span, _: ast::NodeId) {
        // Only visit inline mods here.
        if self.codemap.lookup_char_pos(s.lo).file.name !=
           self.codemap.lookup_char_pos(m.inner.lo).file.name {
            return;
        }
        visit::walk_mod(self, m);
    }
}

impl<'a> FmtVisitor<'a> {
    pub fn from_codemap<'b>(codemap: &'b CodeMap) -> FmtVisitor<'b> {
        FmtVisitor {
            codemap: codemap,
            changes: ChangeSet::from_codemap(codemap),
            last_pos: BytePos(0),
            block_indent: 0,
        }
    }

    pub fn snippet(&self, span: Span) -> String {
        match self.codemap.span_to_snippet(span) {
            Ok(s) => s,
            Err(_) => {
                println!("Couldn't make snippet for span {:?}->{:?}",
                         self.codemap.lookup_char_pos(span.lo),
                         self.codemap.lookup_char_pos(span.hi));
                "".to_string()
            }
        }
    }

    // Returns true if we should skip the following item.
    fn visit_attrs(&mut self, attrs: &[ast::Attribute]) -> bool {
        if attrs.len() == 0 {
            return false;
        }

        let first = &attrs[0];
        self.format_missing_with_indent(first.span.lo);

        match self.rewrite_attrs(attrs, self.block_indent) {
            Some(s) => {
                self.changes.push_str_span(first.span, &s);
                let last = attrs.last().unwrap();
                self.last_pos = last.span.hi;
                false
            }
            None => true
        }
    }

    fn rewrite_attrs(&self, attrs: &[ast::Attribute], indent: usize) -> Option<String> {
        let mut result = String::new();
        let indent = utils::make_indent(indent);

        for (i, a) in attrs.iter().enumerate() {
            if is_skip(&a.node.value) {
                return None;
            }

            result.push_str(&self.snippet(a.span));

            if i < attrs.len() - 1 {
                result.push('\n');
                result.push_str(&indent);

                let comment = self.snippet(codemap::mk_sp(a.span.hi, attrs[i+1].span.lo));
                let comment = comment.trim();
                if comment.len() > 0 {
                    result.push_str(&self.snippet(a.span));
                    result.push('\n');
                    result.push_str(comment);
                }
            }
        }

        Some(result)
    }
}

fn is_skip(meta_item: &ast::MetaItem) -> bool {
    match meta_item.node {
        ast::MetaItem_::MetaWord(ref s) => *s == SKIP_ANNOTATION,
        _ => false,
    }
}
<commit_msg>Better handle trait items<commit_after>// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// 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. This file may not be copied, modified, or distributed
// except according to those terms.

use syntax::ast;
use syntax::codemap::{self, CodeMap, Span, BytePos};
use syntax::visit;

use utils;

use {MAX_WIDTH, TAB_SPACES, SKIP_ANNOTATION};
use changes::ChangeSet;

pub struct FmtVisitor<'a> {
    pub codemap: &'a CodeMap,
    pub changes: ChangeSet<'a>,
    pub last_pos: BytePos,
    // TODO RAII util for indenting
    pub block_indent: usize,
}

impl<'a, 'v> visit::Visitor<'v> for FmtVisitor<'a> {
    fn visit_expr(&mut self, ex: &'v ast::Expr) {
        debug!("visit_expr: {:?} {:?}",
               self.codemap.lookup_char_pos(ex.span.lo),
               self.codemap.lookup_char_pos(ex.span.hi));
        self.format_missing(ex.span.lo);
        let offset = self.changes.cur_offset_span(ex.span);
        let new_str = self.rewrite_expr(ex, MAX_WIDTH - offset, offset);
        self.changes.push_str_span(ex.span, &new_str);
        self.last_pos = ex.span.hi;
    }

    fn visit_stmt(&mut self, stmt: &'v ast::Stmt) {
        // If the stmt is actually an item, then we'll handle any missing spans
        // there. This is important because of annotations.
        // Although it might make more sense for the statement span to include
        // any annotations on the item.
        let skip_missing = match stmt.node {
            ast::Stmt_::StmtDecl(ref decl, _) => {
                match decl.node {
                    ast::Decl_::DeclItem(_) => true,
                    _ => false,
                }
            }
            _ => false,
        };
        if !skip_missing {
            self.format_missing_with_indent(stmt.span.lo);
        }
        visit::walk_stmt(self, stmt);
    }

    fn visit_block(&mut self, b: &'v ast::Block) {
        debug!("visit_block: {:?} {:?}",
               self.codemap.lookup_char_pos(b.span.lo),
               self.codemap.lookup_char_pos(b.span.hi));
        self.format_missing(b.span.lo);

        self.changes.push_str_span(b.span, "{");
        self.last_pos = self.last_pos + BytePos(1);
        self.block_indent += TAB_SPACES;

        for stmt in &b.stmts {
            self.visit_stmt(&stmt)
        }
        match b.expr {
            Some(ref e) => {
                self.format_missing_with_indent(e.span.lo);
                self.visit_expr(e);
            }
            None => {}
        }

        self.block_indent -= TAB_SPACES;
        // TODO we should compress any newlines here to just one
        self.format_missing_with_indent(b.span.hi - BytePos(1));
        self.changes.push_str_span(b.span, "}");
        self.last_pos = b.span.hi;
    }

    // Note that this only gets called for function defintions. Required methods
    // on traits do not get handled here.
    fn visit_fn(&mut self,
                fk: visit::FnKind<'v>,
                fd: &'v ast::FnDecl,
                b: &'v ast::Block,
                s: Span,
                _: ast::NodeId) {
        self.format_missing(s.lo);
        self.last_pos = s.lo;

        let indent = self.block_indent;
        match fk {
            visit::FkItemFn(ident, ref generics, ref unsafety, ref abi, vis) => {
                let new_fn = self.rewrite_fn(indent,
                                             ident,
                                             fd,
                                             None,
                                             generics,
                                             unsafety,
                                             abi,
                                             vis,
                                             b.span);
                self.changes.push_str_span(s, &new_fn);
            }
            visit::FkMethod(ident, ref sig, vis) => {
                let new_fn = self.rewrite_fn(indent,
                                             ident,
                                             fd,
                                             Some(&sig.explicit_self),
                                             &sig.generics,
                                             &sig.unsafety,
                                             &sig.abi,
                                             vis.unwrap_or(ast::Visibility::Inherited),
                                             b.span);
                self.changes.push_str_span(s, &new_fn);
            }
            visit::FkFnBlock(..) => {}
        }

        self.last_pos = b.span.lo;
        self.visit_block(b)
    }

    fn visit_item(&mut self, item: &'v ast::Item) {
        // Don't look at attributes for modules.
        // We want to avoid looking at attributes in another file, which the AST
        // doesn't distinguish. FIXME This is overly conservative and means we miss
        // attributes on inline modules.
        match item.node {
            ast::Item_::ItemMod(_) => {}
            _ => {
                if self.visit_attrs(&item.attrs) {
                    return;
                }
            }
        }

        match item.node {
            ast::Item_::ItemUse(ref vp) => {
                match vp.node {
                    ast::ViewPath_::ViewPathList(ref path, ref path_list) => {
                        self.format_missing(item.span.lo);
                        let new_str = self.rewrite_use_list(path, path_list, vp.span);
                        self.changes.push_str_span(item.span, &new_str);
                        self.last_pos = item.span.hi;
                    }
                    ast::ViewPath_::ViewPathGlob(_) => {
                        // FIXME convert to list?
                    }
                    _ => {}
                }
                visit::walk_item(self, item);
            }
            ast::Item_::ItemImpl(..) |
            ast::Item_::ItemMod(_) |
            ast::Item_::ItemTrait(..) => {
                self.block_indent += TAB_SPACES;
                visit::walk_item(self, item);
                self.block_indent -= TAB_SPACES;
            }
            ast::Item_::ItemExternCrate(_) => {
                self.format_missing_with_indent(item.span.lo);
                let new_str = self.snippet(item.span);
                self.changes.push_str_span(item.span, &new_str);
                self.last_pos = item.span.hi;
            }
            _ => {
                visit::walk_item(self, item);
            }
        }
    }

    fn visit_trait_item(&mut self, ti: &'v ast::TraitItem) {
        if self.visit_attrs(&ti.attrs) {
            return;
        }
        visit::walk_trait_item(self, ti)
    }

    fn visit_impl_item(&mut self, ii: &'v ast::ImplItem) {
        if self.visit_attrs(&ii.attrs) {
            return;
        }
        visit::walk_impl_item(self, ii)
    }

    fn visit_mac(&mut self, mac: &'v ast::Mac) {
        visit::walk_mac(self, mac)
    }

    fn visit_mod(&mut self, m: &'v ast::Mod, s: Span, _: ast::NodeId) {
        // Only visit inline mods here.
        if self.codemap.lookup_char_pos(s.lo).file.name !=
           self.codemap.lookup_char_pos(m.inner.lo).file.name {
            return;
        }
        visit::walk_mod(self, m);
    }
}

impl<'a> FmtVisitor<'a> {
    pub fn from_codemap<'b>(codemap: &'b CodeMap) -> FmtVisitor<'b> {
        FmtVisitor {
            codemap: codemap,
            changes: ChangeSet::from_codemap(codemap),
            last_pos: BytePos(0),
            block_indent: 0,
        }
    }

    pub fn snippet(&self, span: Span) -> String {
        match self.codemap.span_to_snippet(span) {
            Ok(s) => s,
            Err(_) => {
                println!("Couldn't make snippet for span {:?}->{:?}",
                         self.codemap.lookup_char_pos(span.lo),
                         self.codemap.lookup_char_pos(span.hi));
                "".to_string()
            }
        }
    }

    // Returns true if we should skip the following item.
    fn visit_attrs(&mut self, attrs: &[ast::Attribute]) -> bool {
        if attrs.len() == 0 {
            return false;
        }

        let first = &attrs[0];
        self.format_missing_with_indent(first.span.lo);

        match self.rewrite_attrs(attrs, self.block_indent) {
            Some(s) => {
                self.changes.push_str_span(first.span, &s);
                let last = attrs.last().unwrap();
                self.last_pos = last.span.hi;
                false
            }
            None => true
        }
    }

    fn rewrite_attrs(&self, attrs: &[ast::Attribute], indent: usize) -> Option<String> {
        let mut result = String::new();
        let indent = utils::make_indent(indent);

        for (i, a) in attrs.iter().enumerate() {
            if is_skip(&a.node.value) {
                return None;
            }

            result.push_str(&self.snippet(a.span));

            if i < attrs.len() - 1 {
                result.push('\n');
                result.push_str(&indent);

                let comment = self.snippet(codemap::mk_sp(a.span.hi, attrs[i+1].span.lo));
                let comment = comment.trim();
                if comment.len() > 0 {
                    result.push_str(&self.snippet(a.span));
                    result.push('\n');
                    result.push_str(comment);
                }
            }
        }

        Some(result)
    }
}

fn is_skip(meta_item: &ast::MetaItem) -> bool {
    match meta_item.node {
        ast::MetaItem_::MetaWord(ref s) => *s == SKIP_ANNOTATION,
        _ => false,
    }
}
<|endoftext|>


<commit_before>use std::cmp::Ordering;
use std::collections::BinaryHeap;
use angle::Angle;
use point::Point;
use events::{Event, EventKind};
use beach::{Beach, Arc, ArcStart};
use diagram::{Diagram, Vertex, Cell};
use cgmath::InnerSpace;

#[derive(Default)]
struct Builder {
    events: BinaryHeap<Event>,
    beach: Beach,
    diagram: Diagram,
    scan_theta: Angle,
    temporary: Vec<Vertex>,
}

impl Builder {
    fn new(points: &[Point]) -> Self {
        let mut builder = Builder::default();
        for &point in points {
            let cell = builder.diagram.add_cell(point);
            builder.events.push(Event {
                theta: point.theta.value,
                kind: EventKind::Site(cell),
            });
        }
        builder
    }

    pub fn build(mut self, relaxations: usize) -> Diagram {
        self.build_iter();
        for _ in 1..relaxations {
            self.reset();
            self.build_iter();
        }
        self.finish();
        self.diagram
    }

    fn build_iter(&mut self) {
        while let Some(event) = self.events.pop() {
            //println!("{:?}", event);
            self.scan_theta = Angle::from(event.theta);
            match event.kind {
                EventKind::Site(cell) => self.site_event(cell),
                EventKind::Circle(arc) => self.circle_event(arc),
            }
        }
    }

    fn reset(&mut self) {
        self.diagram.reset();
        self.events.clear();
        self.temporary.clear();
        self.beach.clear();
        self.scan_theta = Angle::default();
        for cell in self.diagram.cells() {
            self.events.push(Event {
                theta: self.diagram.cell_point(cell).theta.value,
                kind: EventKind::Site(cell)
            });
        }
    }

    fn arc_point(&self, arc: Arc) -> &Point {
        &self.diagram.cell_point(self.beach.cell(arc))
    }

    fn create_temporary(&mut self, arc0: Arc, arc1: Arc) {
        let index = self.temporary.len();
        self.temporary.push(Vertex::invalid());
        self.beach.set_start(arc0, ArcStart::Temporary(index));
        self.beach.set_start(arc1, ArcStart::Temporary(index));
    }

    fn site_event(&mut self, cell: Cell) {
        if let Some(mut arc) = self.beach.root() {
            if self.beach.len() == 1 {
                self.beach.insert_after(Some(arc), cell);
                let arc0 = self.beach.first();
                let arc1 = self.beach.last();
                self.create_temporary(arc0, arc1);
                return;
            }
            let point = *self.diagram.cell_point(cell);
            let mut use_tree = true;
            loop {
                let prev = self.beach.prev(arc);
                let next = self.beach.next(arc);
                let start = self.arcs_intersection(prev, arc);
                let end = self.arcs_intersection(arc, next);
                match point.phi.is_in_range(start, end) {
                    Ordering::Less => {
                        if use_tree {
                            if let Some(left) = self.beach.left(arc) {
                                arc = left;
                            } else {
                                // the tree has failed us, do the linear search from now on.
                                arc = self.beach.last();
                                use_tree = false;
                            }
                        } else {
                            arc = self.beach.prev(arc);
                        }
                    },
                    Ordering::Greater => {
                        if use_tree {
                            if let Some(right) = self.beach.right(arc) {
                                arc = right;
                            } else {
                                // the tree has failed us, do the linear search from now on.
                                arc = self.beach.first();
                                use_tree = false;
                            }
                        } else {
                            arc = self.beach.next(arc);
                        }
                    },
                    Ordering::Equal => {
                        self.beach.detach(arc);
                        let twin = {
                            let cell = self.beach.cell(arc);
                            let a = if prev == self.beach.last() {
                                None
                            } else {
                                Some(prev)
                            };
                            self.beach.insert_after(a, cell)
                        };
                        let new = self.beach.insert_after(Some(twin), cell);
                        self.create_temporary(twin, new);
                        self.attach_circle(twin, prev, new, point.theta.value);
                        self.attach_circle(arc, new, next, point.theta.value);
                        break;
                    }
                }
            }
        } else {
            self.beach.insert_after(None, cell);
        }
    }

    fn merge_arcs(&mut self, arc: Arc, prev: Arc, next: Arc, vertex: Option<Vertex>) {
        let theta = self.scan_theta.value;
        if self.attach_circle(arc, prev, next, theta) {
            if let Some(vertex) = vertex {
                self.beach.set_start(arc, ArcStart::Vertex(vertex));
            }
        }
    }

    fn create_edge(&mut self, arc: Arc, end: Vertex) {
        match self.beach.start(arc) {
            ArcStart::Temporary(index) => {
                let start = self.temporary[index];
                if start.is_invalid() {
                    self.temporary[index] = end;
                } else {
                    self.diagram.add_edge(start, end);
                }
            },
            ArcStart::Vertex(start) => {
                self.diagram.add_edge(start, end);
            },
            ArcStart::None => {},
        };
    }

    fn circle_event(&mut self, arc: Arc) {
        if !self.beach.is_valid(arc) {
            return;
        }
        let prev = self.beach.prev(arc);
        let next = self.beach.next(arc);
        self.beach.detach(arc);
        self.beach.detach(prev);
        self.beach.detach(next);
        let point = self.beach.center(arc);
        let vertex = self.diagram.add_vertex(point, &[self.beach.cell(prev), self.beach.cell(arc), self.beach.cell(next)]);
        self.create_edge(prev, vertex);
        self.create_edge(arc, vertex);
        self.beach.remove(arc);
        if self.beach.prev(prev) == next {
            self.create_edge(next, vertex);
            self.beach.remove(prev);
            self.beach.remove(next);
        } else {
            let prev_prev = self.beach.prev(prev);
            let next_next = self.beach.next(next);
            self.merge_arcs(prev, prev_prev, next, Some(vertex));
            self.merge_arcs(next, prev, next_next, None);
        }
    }

    fn arcs_intersection(&self, arc0: Arc, arc1: Arc) -> f64 {
        let point0 = self.arc_point(arc0);
        let point1 = self.arc_point(arc1);
        let u1 = (self.scan_theta.cos - point1.theta.cos) * point0.theta.sin;
        let u2 = (self.scan_theta.cos - point0.theta.cos) * point1.theta.sin;
        let a = u1 * point0.phi.cos - u2 * point1.phi.cos;
        let b = u1 * point0.phi.sin - u2 * point1.phi.sin;
        let c = (point0.theta.cos - point1.theta.cos) * self.scan_theta.sin;
        let length = (a * a + b * b).sqrt();
        let gamma = a.atan2(b);
        let phi_plus_gamma = (c / length).asin();
        Angle::wrap(phi_plus_gamma - gamma)
    }

    fn attach_circle(&mut self, arc: Arc, prev: Arc, next: Arc, min_theta: f64) -> bool {
        let position = self.arc_point(arc).position;
        let from_prev = self.arc_point(prev).position - position;
        let from_next = self.arc_point(next).position - position;
        let center = from_prev.cross(from_next).normalize();
        let radius = center.dot(position).acos();
        let theta = center.z.acos() + radius;
        if theta >= min_theta {
            self.beach.attach(arc, center);
            self.events.push(Event {
                theta: theta,
                kind: EventKind::Circle(arc),
            });
            true
        } else {
            false
        }
    }

    fn finish(&mut self) {
        for edge in self.diagram.edges() {
            let mut common = Vec::new();
            let (vertex0, vertex1) = self.diagram.edge_vertices(edge);
            for &cell0 in self.diagram.vertex_cells(vertex0) {
                for &cell1 in self.diagram.vertex_cells(vertex1) {
                    if cell0 == cell1 {
                        common.push(cell0);
                    }
                }
            }
            assert_eq!(common.len(), 2);
            self.diagram.set_edge_cells(edge, common[0], common[1]);
        }
    }
}

pub fn build(points: &[Point], relaxations: usize) -> Diagram {
    Builder::new(points).build(relaxations)
}
<commit_msg>Make scan_theta f64.<commit_after>use std::cmp::Ordering;
use std::collections::BinaryHeap;
use angle::Angle;
use point::Point;
use events::{Event, EventKind};
use beach::{Beach, Arc, ArcStart};
use diagram::{Diagram, Vertex, Cell};
use cgmath::InnerSpace;

#[derive(Default)]
struct Builder {
    events: BinaryHeap<Event>,
    beach: Beach,
    diagram: Diagram,
    scan_theta: f64,
    temporary: Vec<Vertex>,
}

impl Builder {
    fn new(points: &[Point]) -> Self {
        let mut builder = Builder::default();
        for &point in points {
            let cell = builder.diagram.add_cell(point);
            builder.events.push(Event {
                theta: point.theta.value,
                kind: EventKind::Site(cell),
            });
        }
        builder
    }

    pub fn build(mut self, relaxations: usize) -> Diagram {
        self.build_iter();
        for _ in 1..relaxations {
            self.reset();
            self.build_iter();
        }
        self.finish();
        self.diagram
    }

    fn build_iter(&mut self) {
        while let Some(event) = self.events.pop() {
            //println!("{:?}", event);
            match event.kind {
                EventKind::Site(cell) => self.site_event(cell),
                EventKind::Circle(arc) => self.circle_event(arc, event.theta),
            }
        }
    }

    fn reset(&mut self) {
        self.diagram.reset();
        self.events.clear();
        self.temporary.clear();
        self.beach.clear();
        self.scan_theta = 0.0;
        for cell in self.diagram.cells() {
            self.events.push(Event {
                theta: self.diagram.cell_point(cell).theta.value,
                kind: EventKind::Site(cell)
            });
        }
    }

    fn arc_point(&self, arc: Arc) -> &Point {
        &self.diagram.cell_point(self.beach.cell(arc))
    }

    fn create_temporary(&mut self, arc0: Arc, arc1: Arc) {
        let index = self.temporary.len();
        self.temporary.push(Vertex::invalid());
        self.beach.set_start(arc0, ArcStart::Temporary(index));
        self.beach.set_start(arc1, ArcStart::Temporary(index));
    }

    fn site_event(&mut self, cell: Cell) {
        if let Some(mut arc) = self.beach.root() {
            if self.beach.len() == 1 {
                self.beach.insert_after(Some(arc), cell);
                let arc0 = self.beach.first();
                let arc1 = self.beach.last();
                self.create_temporary(arc0, arc1);
                return;
            }
            let point = *self.diagram.cell_point(cell);
            let mut use_tree = true;
            loop {
                let prev = self.beach.prev(arc);
                let next = self.beach.next(arc);
                let start = self.arcs_intersection(prev, arc, point.theta);
                let end = self.arcs_intersection(arc, next, point.theta);
                match point.phi.is_in_range(start, end) {
                    Ordering::Less => {
                        if use_tree {
                            if let Some(left) = self.beach.left(arc) {
                                arc = left;
                            } else {
                                // the tree has failed us, do the linear search from now on.
                                arc = self.beach.last();
                                use_tree = false;
                            }
                        } else {
                            arc = self.beach.prev(arc);
                        }
                    },
                    Ordering::Greater => {
                        if use_tree {
                            if let Some(right) = self.beach.right(arc) {
                                arc = right;
                            } else {
                                // the tree has failed us, do the linear search from now on.
                                arc = self.beach.first();
                                use_tree = false;
                            }
                        } else {
                            arc = self.beach.next(arc);
                        }
                    },
                    Ordering::Equal => {
                        self.beach.detach(arc);
                        let twin = {
                            let cell = self.beach.cell(arc);
                            let a = if prev == self.beach.last() {
                                None
                            } else {
                                Some(prev)
                            };
                            self.beach.insert_after(a, cell)
                        };
                        let new = self.beach.insert_after(Some(twin), cell);
                        self.create_temporary(twin, new);
                        self.attach_circle(twin, prev, new, point.theta.value);
                        self.attach_circle(arc, new, next, point.theta.value);
                        break;
                    }
                }
            }
        } else {
            self.beach.insert_after(None, cell);
        }
    }

        fn circle_event(&mut self, arc: Arc, theta: f64) {
        if !self.beach.is_valid(arc) {
            return;
        }
        self.scan_theta = theta;
        let prev = self.beach.prev(arc);
        let next = self.beach.next(arc);
        self.beach.detach(arc);
        self.beach.detach(prev);
        self.beach.detach(next);
        let point = self.beach.center(arc);
        let vertex = self.diagram.add_vertex(point, &[self.beach.cell(prev), self.beach.cell(arc), self.beach.cell(next)]);
        self.create_edge(prev, vertex);
        self.create_edge(arc, vertex);
        self.beach.remove(arc);
        if self.beach.prev(prev) == next {
            self.create_edge(next, vertex);
            self.beach.remove(prev);
            self.beach.remove(next);
        } else {
            let prev_prev = self.beach.prev(prev);
            let next_next = self.beach.next(next);
            self.merge_arcs(prev, prev_prev, next, Some(vertex));
            self.merge_arcs(next, prev, next_next, None);
        }
    }

    fn merge_arcs(&mut self, arc: Arc, prev: Arc, next: Arc, vertex: Option<Vertex>) {
        let theta = self.scan_theta;
        if self.attach_circle(arc, prev, next, theta) {
            if let Some(vertex) = vertex {
                self.beach.set_start(arc, ArcStart::Vertex(vertex));
            }
        }
    }

    fn create_edge(&mut self, arc: Arc, end: Vertex) {
        match self.beach.start(arc) {
            ArcStart::Temporary(index) => {
                let start = self.temporary[index];
                if start.is_invalid() {
                    self.temporary[index] = end;
                } else {
                    self.diagram.add_edge(start, end);
                }
            },
            ArcStart::Vertex(start) => {
                self.diagram.add_edge(start, end);
            },
            ArcStart::None => {},
        };
    }

    fn arcs_intersection(&self, arc0: Arc, arc1: Arc, theta: Angle) -> f64 {
        let point0 = self.arc_point(arc0);
        let point1 = self.arc_point(arc1);
        let u1 = (theta.cos - point1.theta.cos) * point0.theta.sin;
        let u2 = (theta.cos - point0.theta.cos) * point1.theta.sin;
        let a = u1 * point0.phi.cos - u2 * point1.phi.cos;
        let b = u1 * point0.phi.sin - u2 * point1.phi.sin;
        let c = (point0.theta.cos - point1.theta.cos) * theta.sin;
        let length = (a * a + b * b).sqrt();
        let gamma = a.atan2(b);
        let phi_plus_gamma = (c / length).asin();
        Angle::wrap(phi_plus_gamma - gamma)
    }

    fn attach_circle(&mut self, arc: Arc, prev: Arc, next: Arc, min_theta: f64) -> bool {
        let position = self.arc_point(arc).position;
        let from_prev = self.arc_point(prev).position - position;
        let from_next = self.arc_point(next).position - position;
        let center = from_prev.cross(from_next).normalize();
        let radius = center.dot(position).acos();
        let theta = center.z.acos() + radius;
        if theta >= min_theta {
            self.beach.attach(arc, center);
            self.events.push(Event {
                theta: theta,
                kind: EventKind::Circle(arc),
            });
            true
        } else {
            false
        }
    }

    fn finish(&mut self) {
        for edge in self.diagram.edges() {
            let mut common = Vec::new();
            let (vertex0, vertex1) = self.diagram.edge_vertices(edge);
            for &cell0 in self.diagram.vertex_cells(vertex0) {
                for &cell1 in self.diagram.vertex_cells(vertex1) {
                    if cell0 == cell1 {
                        common.push(cell0);
                    }
                }
            }
            assert_eq!(common.len(), 2);
            self.diagram.set_edge_cells(edge, common[0], common[1]);
        }
    }
}

pub fn build(points: &[Point], relaxations: usize) -> Diagram {
    Builder::new(points).build(relaxations)
}
<|endoftext|>


<commit_before>use libc;
use std::io;

#[cfg(target_os="macos")]
const TIOCGWINSZ: libc::c_ulonglong = 0x5413;
#[cfg(target_os="macos")]
const TIOCSWINSZ: libc::c_ulonglong = 0x5414;

#[cfg(target_os="linux")]
const TIOCGWINSZ: libc::c_ulong = 0x5413;
#[cfg(target_os="linux")]
const TIOCSWINSZ: libc::c_ulong = 0x5414;

#[repr(C)]
#[derive(PartialEq, Debug)]
pub struct Winsize {
    pub ws_row: libc::c_ushort, // rows, in characters
    pub ws_col: libc::c_ushort, // columns, in characters
    pub ws_xpixel: libc::c_ushort, // horizontal size, pixels
    pub ws_ypixel: libc::c_ushort, // vertical size, pixels
}

pub fn from_fd(fd: libc::c_int) -> io::Result<Winsize> {
    let winsize = Winsize {
        ws_row: 0,
        ws_col: 0,
        ws_xpixel: 0,
        ws_ypixel: 0,
    };

    unsafe {
        libc::ioctl(fd, TIOCGWINSZ, &winsize);
    }

    Ok(winsize)
}

pub fn set(fd: libc::c_int, winsize: &Winsize) {
    unsafe {
        libc::ioctl(fd, TIOCSWINSZ, winsize);
    }
}
<commit_msg>implementations of Default for Winsize Structure<commit_after>use libc;
use std::io;

#[cfg(target_os="macos")]
const TIOCGWINSZ: libc::c_ulonglong = 0x5413;
#[cfg(target_os="macos")]
const TIOCSWINSZ: libc::c_ulonglong = 0x5414;

#[cfg(target_os="linux")]
const TIOCGWINSZ: libc::c_ulong = 0x5413;
#[cfg(target_os="linux")]
const TIOCSWINSZ: libc::c_ulong = 0x5414;

#[repr(C)]
#[derive(PartialEq, Debug, Default)]
pub struct Winsize {
    pub ws_row: libc::c_ushort, // rows, in characters
    pub ws_col: libc::c_ushort, // columns, in characters
    pub ws_xpixel: libc::c_ushort, // horizontal size, pixels
    pub ws_ypixel: libc::c_ushort, // vertical size, pixels
}

pub fn from_fd(fd: libc::c_int) -> io::Result<Winsize> {
    let winsize = Winsize::default();

    unsafe {
        libc::ioctl(fd, TIOCGWINSZ, &winsize);
    }

    Ok(winsize)
}

pub fn set(fd: libc::c_int, winsize: &Winsize) {
    unsafe {
        libc::ioctl(fd, TIOCSWINSZ, winsize);
    }
}
<|endoftext|>