<commit_before>use std::io;
use super::ipv4_header::IPv4Header;
use super::ipv4_packet::{IPv4Packet, MAX_PACKET_LENGTH};
use super::transport_header::TransportHeader;

/// Convert from level 5 to level 3 by appending correct IP and transport headers.
pub struct Packetizer {
    buffer: Box<[u8; MAX_PACKET_LENGTH]>,
    transport_index: usize,
    payload_index: usize,
    ipv4_header: IPv4Header,
    transport_header: TransportHeader,
}

impl Packetizer {
    pub fn new(raw: &mut [u8], mut ipv4_header: IPv4Header, mut transport_header: TransportHeader) -> Self {
        let mut buffer = Box::new([0; MAX_PACKET_LENGTH]);

        let mut ipv4_header = ipv4_header.clone();
        let mut transport_header = transport_header.clone();

        let transport_index = ipv4_header.header_length as usize;
        let payload_index = transport_index + transport_header.header_length() as usize;
        &mut buffer[..payload_index].copy_from_slice(&raw[..payload_index]);

        ipv4_header.swap_source_and_destination(&mut buffer[..]);
        transport_header.swap_source_and_destination(&mut buffer[transport_index..]);

        Self {
            buffer: buffer,
            transport_index: transport_index,
            payload_index: payload_index,
            ipv4_header: ipv4_header,
            transport_header: transport_header,
        }
    }

    pub fn packetize_empty_payload(&mut self) -> IPv4Packet {
        self.inflate(0)
    }

    pub fn packetize_chunk<R: io::Read>(&mut self, source: &mut R, max_chunk_size: usize) -> io::Result<IPv4Packet> {
        assert!(max_chunk_size <= self.buffer.len() - self.payload_index);
        let range = self.payload_index..self.payload_index + max_chunk_size;
        let r = source.read(&mut self.buffer[range])?;
        let ipv4_packet = self.inflate(r as u16);
        Ok(ipv4_packet)
    }

    pub fn packetize<R: io::Read>(&mut self, source: &mut R) -> io::Result<IPv4Packet> {
        let payload_max_length = self.buffer.len() - self.payload_index;
        self.packetize_chunk(source, payload_max_length)
    }

    fn inflate(&mut self, payload_length: u16) -> IPv4Packet {
        let total_length = self.payload_index as u16 + payload_length;

        self.ipv4_header.set_total_length(&mut self.buffer[..], total_length);
        self.transport_header.set_payload_length(&mut self.buffer[self.transport_index..], payload_length);

        let mut ipv4_packet = IPv4Packet::new(&mut self.buffer[..total_length as usize], self.ipv4_header, self.transport_header);
        ipv4_packet.compute_checksums();
        ipv4_packet
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use std::io;
    use byteorder::{BigEndian, WriteBytesExt};

    fn create_packet() -> Vec<u8> {
        let mut raw = Vec::new();
        raw.write_u8(4u8 << 4 | 5).unwrap();
        raw.write_u8(0).unwrap(); // ToS
        raw.write_u16::<BigEndian>(32).unwrap(); // total length 20 + 8 + 4
        raw.write_u32::<BigEndian>(0).unwrap(); // id_flags_fragment_offset
        raw.write_u8(0).unwrap(); // TTL
        raw.write_u8(17).unwrap(); // protocol (UDP)
        raw.write_u16::<BigEndian>(0).unwrap(); // checksum
        raw.write_u32::<BigEndian>(0x12345678).unwrap(); // source address
        raw.write_u32::<BigEndian>(0x42424242).unwrap(); // destination address

        raw.write_u16::<BigEndian>(1234).unwrap(); // source port
        raw.write_u16::<BigEndian>(5678).unwrap(); // destination port
        raw.write_u16::<BigEndian>(12).unwrap(); // length
        raw.write_u16::<BigEndian>(0).unwrap(); // checksum

        raw.write_u32::<BigEndian>(0x11223344).unwrap(); // payload
        raw
    }

    #[test]
    fn merge_headers_and_payload() {
        let mut raw = &mut create_packet()[..];
        let reference_packet = IPv4Packet::parse(raw);

        let data = [ 0x11u8, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88 ];
        let mut cursor = io::Cursor::new(&data);

        let transport_header = reference_packet.transport_header.unwrap();
        let mut packetizer = Packetizer::new(reference_packet.raw, reference_packet.ipv4_header, transport_header);

        let packet = packetizer.packetize(&mut cursor).unwrap();
        assert_eq!(36, packet.ipv4_header.total_length);
    }

    #[test]
    fn packetize_chunks() {
        let mut raw = &mut create_packet()[..];
        let reference_packet = IPv4Packet::parse(raw);

        let data = [ 0x11u8, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88 ];
        let mut cursor = io::Cursor::new(&data);

        let transport_header = reference_packet.transport_header.unwrap();
        let mut packetizer = Packetizer::new(reference_packet.raw, reference_packet.ipv4_header, transport_header);

        {
            let packet = packetizer.packetize_chunk(&mut cursor, 2).unwrap();
            assert_eq!(30, packet.ipv4_header.total_length);
            assert_eq!(2, packet.payload_length().unwrap());
            assert_eq!([0x11, 0x22], packet.raw[packet.payload_index().unwrap() as usize..]);
        }

        {
            let packet = packetizer.packetize_chunk(&mut cursor, 3).unwrap();
            assert_eq!(31, packet.ipv4_header.total_length);
            assert_eq!(3, packet.payload_length().unwrap());
            assert_eq!([0x33, 0x44, 0x55], packet.raw[packet.payload_index().unwrap() as usize..]);
        }

        {
            let packet = packetizer.packetize_chunk(&mut cursor, 1024).unwrap();
            assert_eq!(31, packet.ipv4_header.total_length);
            assert_eq!(3, packet.payload_length().unwrap());
            assert_eq!([0x66, 0x77, 0x88], packet.raw[packet.payload_index().unwrap() as usize..]);
        }
    }
}
<commit_msg>Borrow raw data as non-mutable in Packetizer<commit_after>use std::io;
use super::ipv4_header::IPv4Header;
use super::ipv4_packet::{IPv4Packet, MAX_PACKET_LENGTH};
use super::transport_header::TransportHeader;

/// Convert from level 5 to level 3 by appending correct IP and transport headers.
pub struct Packetizer {
    buffer: Box<[u8; MAX_PACKET_LENGTH]>,
    transport_index: usize,
    payload_index: usize,
    ipv4_header: IPv4Header,
    transport_header: TransportHeader,
}

impl Packetizer {
    pub fn new(raw: &[u8], mut ipv4_header: IPv4Header, mut transport_header: TransportHeader) -> Self {
        let mut buffer = Box::new([0; MAX_PACKET_LENGTH]);

        let mut ipv4_header = ipv4_header.clone();
        let mut transport_header = transport_header.clone();

        let transport_index = ipv4_header.header_length as usize;
        let payload_index = transport_index + transport_header.header_length() as usize;
        &mut buffer[..payload_index].copy_from_slice(&raw[..payload_index]);

        ipv4_header.swap_source_and_destination(&mut buffer[..]);
        transport_header.swap_source_and_destination(&mut buffer[transport_index..]);

        Self {
            buffer: buffer,
            transport_index: transport_index,
            payload_index: payload_index,
            ipv4_header: ipv4_header,
            transport_header: transport_header,
        }
    }

    pub fn packetize_empty_payload(&mut self) -> IPv4Packet {
        self.inflate(0)
    }

    pub fn packetize_chunk<R: io::Read>(&mut self, source: &mut R, max_chunk_size: usize) -> io::Result<IPv4Packet> {
        assert!(max_chunk_size <= self.buffer.len() - self.payload_index);
        let range = self.payload_index..self.payload_index + max_chunk_size;
        let r = source.read(&mut self.buffer[range])?;
        let ipv4_packet = self.inflate(r as u16);
        Ok(ipv4_packet)
    }

    pub fn packetize<R: io::Read>(&mut self, source: &mut R) -> io::Result<IPv4Packet> {
        let payload_max_length = self.buffer.len() - self.payload_index;
        self.packetize_chunk(source, payload_max_length)
    }

    fn inflate(&mut self, payload_length: u16) -> IPv4Packet {
        let total_length = self.payload_index as u16 + payload_length;

        self.ipv4_header.set_total_length(&mut self.buffer[..], total_length);
        self.transport_header.set_payload_length(&mut self.buffer[self.transport_index..], payload_length);

        let mut ipv4_packet = IPv4Packet::new(&mut self.buffer[..total_length as usize], self.ipv4_header, self.transport_header);
        ipv4_packet.compute_checksums();
        ipv4_packet
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use std::io;
    use byteorder::{BigEndian, WriteBytesExt};

    fn create_packet() -> Vec<u8> {
        let mut raw = Vec::new();
        raw.write_u8(4u8 << 4 | 5).unwrap();
        raw.write_u8(0).unwrap(); // ToS
        raw.write_u16::<BigEndian>(32).unwrap(); // total length 20 + 8 + 4
        raw.write_u32::<BigEndian>(0).unwrap(); // id_flags_fragment_offset
        raw.write_u8(0).unwrap(); // TTL
        raw.write_u8(17).unwrap(); // protocol (UDP)
        raw.write_u16::<BigEndian>(0).unwrap(); // checksum
        raw.write_u32::<BigEndian>(0x12345678).unwrap(); // source address
        raw.write_u32::<BigEndian>(0x42424242).unwrap(); // destination address

        raw.write_u16::<BigEndian>(1234).unwrap(); // source port
        raw.write_u16::<BigEndian>(5678).unwrap(); // destination port
        raw.write_u16::<BigEndian>(12).unwrap(); // length
        raw.write_u16::<BigEndian>(0).unwrap(); // checksum

        raw.write_u32::<BigEndian>(0x11223344).unwrap(); // payload
        raw
    }

    #[test]
    fn merge_headers_and_payload() {
        let mut raw = &mut create_packet()[..];
        let reference_packet = IPv4Packet::parse(raw);

        let data = [ 0x11u8, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88 ];
        let mut cursor = io::Cursor::new(&data);

        let transport_header = reference_packet.transport_header.unwrap();
        let mut packetizer = Packetizer::new(reference_packet.raw, reference_packet.ipv4_header, transport_header);

        let packet = packetizer.packetize(&mut cursor).unwrap();
        assert_eq!(36, packet.ipv4_header.total_length);
    }

    #[test]
    fn packetize_chunks() {
        let mut raw = &mut create_packet()[..];
        let reference_packet = IPv4Packet::parse(raw);

        let data = [ 0x11u8, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88 ];
        let mut cursor = io::Cursor::new(&data);

        let transport_header = reference_packet.transport_header.unwrap();
        let mut packetizer = Packetizer::new(reference_packet.raw, reference_packet.ipv4_header, transport_header);

        {
            let packet = packetizer.packetize_chunk(&mut cursor, 2).unwrap();
            assert_eq!(30, packet.ipv4_header.total_length);
            assert_eq!(2, packet.payload_length().unwrap());
            assert_eq!([0x11, 0x22], packet.raw[packet.payload_index().unwrap() as usize..]);
        }

        {
            let packet = packetizer.packetize_chunk(&mut cursor, 3).unwrap();
            assert_eq!(31, packet.ipv4_header.total_length);
            assert_eq!(3, packet.payload_length().unwrap());
            assert_eq!([0x33, 0x44, 0x55], packet.raw[packet.payload_index().unwrap() as usize..]);
        }

        {
            let packet = packetizer.packetize_chunk(&mut cursor, 1024).unwrap();
            assert_eq!(31, packet.ipv4_header.total_length);
            assert_eq!(3, packet.payload_length().unwrap());
            assert_eq!([0x66, 0x77, 0x88], packet.raw[packet.payload_index().unwrap() as usize..]);
        }
    }
}
<|endoftext|>


<commit_before>#[test]
fn from() {
    use core::convert::TryFrom;
    use core::num::TryFromIntError;

    // From
    const FROM: i64 = i64::from(1i32);
    assert_eq!(FROM, 1i64);

    // Upper bounded
    const U8_FROM_U16: Result<u8, TryFromIntError> = u8::try_from(1u16);
    assert_eq!(U8_FROM_U16, Ok(1u8));

    // Both bounded
    const I8_FROM_I16: Result<i8, TryFromIntError> = i8::try_from(1i16);
    assert_eq!(I8_FROM_I16, Ok(1i8));

    // Lower bounded
    const I16_FROM_U16: Result<i16, TryFromIntError> = i16::try_from(1u16);
    assert_eq!(I16_FROM_U16, Ok(1i16));
}
<commit_msg>Add test for int to float<commit_after>#[test]
fn from() {
    use core::convert::TryFrom;
    use core::num::TryFromIntError;

    // From
    const FROM: i64 = i64::from(1i32);
    assert_eq!(FROM, 1i64);

    // From int to float
    const FROM_F64: f64 = f64::from(42u8);
    assert_eq!(FROM_F64, 42f64);

    // Upper bounded
    const U8_FROM_U16: Result<u8, TryFromIntError> = u8::try_from(1u16);
    assert_eq!(U8_FROM_U16, Ok(1u8));

    // Both bounded
    const I8_FROM_I16: Result<i8, TryFromIntError> = i8::try_from(1i16);
    assert_eq!(I8_FROM_I16, Ok(1i8));

    // Lower bounded
    const I16_FROM_U16: Result<i16, TryFromIntError> = i16::try_from(1u16);
    assert_eq!(I16_FROM_U16, Ok(1i16));
}
<|endoftext|>


<commit_before>// Copyright 2016 Pierre Talbot (IRCAM)

// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at

//     http://www.apache.org/licenses/LICENSE-2.0

// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// This example models the n-queens problem using interval domain (with `i32` bounds).

use pcp::kernel::*;
use pcp::propagators::*;
use pcp::variable::ops::*;
use pcp::term::*;
use pcp::search::search_tree_visitor::Status::*;
use pcp::search::*;
use pcp::concept::*;
use interval::ops::Range;
use interval::interval_set::*;
use gcollections::ops::*;

pub fn nqueens(n: usize) {
  let mut space = FDSpace::empty();

  let mut queens = vec![];
  // 2 queens can't share the same line.
  for _ in 0..n {
    queens.push(Box::new(space.vstore.alloc(IntervalSet::new(1, n as i32))) as Var<VStore>);
  }
  for i in 0..n-1 {
    for j in i + 1..n {
      // 2 queens can't share the same diagonal.
      let q1 = (i + 1) as i32;
      let q2 = (j + 1) as i32;
      // Xi + i != Xj + j reformulated as: Xi != Xj + j - i
      space.cstore.alloc(Box::new(XNeqY::new(
        queens[i].bclone(), Box::new(Addition::new(queens[j].bclone(), q2 - q1)) as Var<VStore>));
      // Xi - i != Xj - j reformulated as: Xi != Xj - j + i
      space.cstore.alloc(Box::new(XNeqY::new(
        queens[i].bclone(), Box::new(Addition::new(queens[j].bclone(), -q2 + q1)) as Var<VStore>));
    }
  }
  // 2 queens can't share the same column.
  join_distinct(&mut space.vstore, &mut space.cstore, queens);
  // space.cstore.alloc(Box::new(Distinct::new(queens)));

  // Search step.
  let mut search = one_solution_engine();
  search.start(&space);
  let (frozen_space, status) = search.enter(space);
  let space = frozen_space.unfreeze();

  // Print result.
  match status {
    Satisfiable => {
      print!("{}-queens problem is satisfiable. The first solution is:\n[", n);
      for dom in space.vstore.iter() {
        // At this stage, dom.lower() == dom.upper().
        print!("{}, ", dom.lower());
      }
      println!("]");
    }
    Unsatisfiable => println!("{}-queens problem is unsatisfiable.", n),
    EndOfSearch => println!("Search terminated or was interrupted."),
    Unknown(_) => unreachable!(
      "After the search step, the problem instance should be either satisfiable or unsatisfiable.")
  }
}<commit_msg>[tests] update the tests on propagators and uncomment them.<commit_after>// Copyright 2016 Pierre Talbot (IRCAM)

// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at

//     http://www.apache.org/licenses/LICENSE-2.0

// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// This example models the n-queens problem using interval domain (with `i32` bounds).

use pcp::kernel::*;
use pcp::propagators::*;
use pcp::variable::ops::*;
use pcp::term::*;
use pcp::search::search_tree_visitor::Status::*;
use pcp::search::*;
use pcp::concept::*;
use interval::ops::Range;
use interval::interval_set::*;
use gcollections::ops::*;

pub fn nqueens(n: usize) {
  let mut space = FDSpace::empty();

  let mut queens = vec![];
  // 2 queens can't share the same line.
  for _ in 0..n {
    queens.push(Box::new(space.vstore.alloc(IntervalSet::new(1, n as i32))) as Var<VStore>);
  }
  for i in 0..n-1 {
    for j in i + 1..n {
      // 2 queens can't share the same diagonal.
      let q1 = (i + 1) as i32;
      let q2 = (j + 1) as i32;
      // Xi + i != Xj + j reformulated as: Xi != Xj + j - i
      space.cstore.alloc(Box::new(XNeqY::new(
        queens[i].bclone(), Box::new(Addition::new(queens[j].bclone(), q2 - q1)) as Var<VStore>)));
      // Xi - i != Xj - j reformulated as: Xi != Xj - j + i
      space.cstore.alloc(Box::new(XNeqY::new(
        queens[i].bclone(), Box::new(Addition::new(queens[j].bclone(), -q2 + q1)) as Var<VStore>)));
    }
  }
  // 2 queens can't share the same column.
  join_distinct(&mut space.vstore, &mut space.cstore, queens);
  // space.cstore.alloc(Box::new(Distinct::new(queens)));

  // Search step.
  let mut search = one_solution_engine();
  search.start(&space);
  let (frozen_space, status) = search.enter(space);
  let space = frozen_space.unfreeze();

  // Print result.
  match status {
    Satisfiable => {
      print!("{}-queens problem is satisfiable. The first solution is:\n[", n);
      for dom in space.vstore.iter() {
        // At this stage, dom.lower() == dom.upper().
        print!("{}, ", dom.lower());
      }
      println!("]");
    }
    Unsatisfiable => println!("{}-queens problem is unsatisfiable.", n),
    EndOfSearch => println!("Search terminated or was interrupted."),
    Unknown(_) => unreachable!(
      "After the search step, the problem instance should be either satisfiable or unsatisfiable.")
  }
}<|endoftext|>


<commit_before>// Traits can have associated types:
#![feature(collections)]

use std::fmt::Debug;
//use std::string;

// I thought that associated types could be used to encode existential
// types, as attempted below.  The trait T has associated type t.  I
// define two implementations for this trait, with different
// definitions of t.  Then, I try to create a packed up pair where the
// first and second components of the pair look "the same" (both just
// mention trait T, and each leaves t abstract, via an (implicit)
// existential quantifier.

// The only way I can get rustc to accept this code is when I leave
// these associated types "translucent", and expose their identities
// in terms of concrete types (i.e., String and u32).  This is exactly
// what I want to avoid.  In particular, the tuple pattern that works
// below doesn't generalize to the case where I have an array or a
// list.

trait T : Debug {
    type t;
    fn get (self:&Self) -> Self::t ;
    fn foo (self:&Self, Self::t ) -> String ;
}

#[derive(Debug)]
pub enum Foo { Foo }

#[derive(Debug)]
pub enum Bar { Bar }

impl T for Foo {
    type t = String;
    fn get (self:&Self) -> String { String::from_str("foo") }
    fn foo (self:&Self, s:Self::t) -> String { s }
}

impl T for Bar {
    type t = u32;
    fn get (self:&Self) -> u32 { 0 }
    fn foo (self:&Self, _s:Self::t) -> String { String::from_str("bar") }
}

#[derive(Debug)]
struct Packed {
    two : (Box<T<t=String>>,Box<T<t=u32>>)
}

pub fn main () {
    let a = Packed { two : (Box::new(Foo::Foo),
                            Box::new(Bar::Bar)) } ;
     println!("{:?}", a);
}
<commit_msg>help from @ogeon<commit_after>// Traits can have associated types:
#![feature(collections)]

use std::fmt::Debug;

// Help from @ogeon:
//   http://users.rust-lang.org/t/trait-objects-with-associated-types/746/19

trait T : Debug {
    type t;
    fn get (self:&Self) -> Self::t ;
    fn doit (self:&Self, Self::t ) -> String ;
}

trait Tabs : Debug {
    fn doit_abs (self:&Self) -> String ;
}

impl <A, B: T<t=A>> Tabs for B {
    fn doit_abs (self:&Self) -> String {
        self.doit ( self.get () )
    }
}

#[derive(Debug)]
pub enum Foo { Foo }

#[derive(Debug)]
pub enum Bar { Bar }

impl T for Foo {
    type t = String;
    fn get (self:&Self) -> String { String::from_str("foo") }
    fn doit (self:&Self, s:Self::t) -> String { s }
}

impl T for Bar {
    type t = u32;
    fn get (self:&Self) -> u32 { 0 }
    fn doit (self:&Self, _s:Self::t) -> String { String::from_str("bar") }
}

#[derive(Debug)]
struct Packed {
    two : (Box<Tabs>,Box<Tabs>)
}

pub fn main () {
    let a = Packed { two : (Box::new(Foo::Foo),
                            Box::new(Bar::Bar)) } ;
     println!("{:?}", a);
}
<|endoftext|>


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

//! Structured representation of a plugin's features and capabilities.

use std::io::{BufReader, Write};
use std::env;
use std::path::PathBuf;
use std::sync::{Arc, Mutex};
use std::thread;
use std::process::{Command, Stdio};

use serde_json::Value;

use xi_rpc::RpcLoop;

use super::PluginManager;
use super::{Plugin, PluginRef};

// example plugins. Eventually these should be loaded from disk.
pub fn debug_plugins() -> Vec<PluginDescription> {
    let mut path_base = env::current_exe().unwrap();
    path_base.pop();
    let make_path = |p: &str| -> PathBuf {
        let mut pb = path_base.clone();
        pb.push(p);
        pb
    };

    vec![
        PluginDescription::new("syntect", "0.0", make_path("xi-syntect-plugin")),
        PluginDescription::new("braces", "0.0", make_path("bracket_example.py")),
        PluginDescription::new("spellcheck", "0.0", make_path("spellcheck.py")),
        PluginDescription::new("shouty", "0.0", make_path("shouty.py")),
    ]
}

/// Describes attributes and capabilities of a plugin.
///
/// Note: - these will eventually be loaded from manifest files.
#[derive(Debug, Clone)]
pub struct PluginDescription {
    pub name: String,
    version: String,
    //scope: PluginScope,
    // more metadata ...
    /// path to plugin executable
    pub exec_path: PathBuf,
}

impl PluginDescription {
    fn new<S, P>(name: S, version: S, exec_path: P) -> Self
        where S: Into<String>, P: Into<PathBuf>
    {
        PluginDescription {
            name: name.into(),
            version: version.into(),
            exec_path: exec_path.into()
        }
    }

    /// Starts the executable described in this `PluginDescription`.
    pub fn launch<W, C>(&self, manager_ref: &Arc<Mutex<PluginManager<W>>>, buffer_id: &str, completion: C)
        where W: Write + Send + 'static,
              C: FnOnce(Result<PluginRef<W>, &'static str>) + Send + 'static
              // TODO: a real result type
    {
        let path = self.exec_path.clone();
        let buffer_id = buffer_id.to_owned();
        let manager_ref = manager_ref.clone();
        let description = self.clone();

        thread::spawn(move || {
            print_err!("starting plugin at path {:?}", path);
            let mut child = Command::new(&path)
                .stdin(Stdio::piped())
                .stdout(Stdio::piped())
                .spawn()
                .expect("plugin failed to start");
            let child_stdin = child.stdin.take().unwrap();
            let child_stdout = child.stdout.take().unwrap();
            let mut looper = RpcLoop::new(child_stdin);
            let peer = looper.get_peer();
            peer.send_rpc_notification("ping", &Value::Array(Vec::new()));
            let plugin = Plugin {
                peer: peer,
                //TODO: I had the bright idea of keeping this reference but
                // I'm not sure exactly what to do with it (stopping the plugin is one thing)
                process: child,
                manager: Arc::downgrade(&manager_ref),
                description: description,
                buffer_id: buffer_id,
            };
            let mut plugin_ref = PluginRef(Arc::new(Mutex::new(plugin)));
            completion(Ok(plugin_ref.clone()));
            looper.mainloop(|| BufReader::new(child_stdout), &mut plugin_ref);
        });
    }
}

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

//! Structured representation of a plugin's features and capabilities.

use std::io::{BufReader, Write};
use std::env;
use std::path::PathBuf;
use std::sync::{Arc, Mutex};
use std::thread;
use std::process::{Command, Stdio};

use serde_json::Value;

use xi_rpc::RpcLoop;

use syntax::SyntaxDefinition;
use super::PluginManager;
use super::{Plugin, PluginRef};

// example plugins. Eventually these should be loaded from disk.
pub fn debug_plugins() -> Vec<PluginDescription> {
    use self::PluginActivation::*;
    use self::SyntaxDefinition::*;
    let mut path_base = env::current_exe().unwrap();
    path_base.pop();
    let make_path = |p: &str| -> PathBuf {
        let mut pb = path_base.clone();
        pb.push(p);
        pb
    };

    vec![
        PluginDescription::new("syntect", "0.0", make_path("xi-syntect-plugin"),
        vec![Autorun]),
        PluginDescription::new("braces", "0.0", make_path("bracket_example.py"),
        Vec::new()),
        PluginDescription::new("spellcheck", "0.0", make_path("spellcheck.py"),
        vec![OnSyntax(Markdown), OnSyntax(Plaintext)]),
        PluginDescription::new("shouty", "0.0", make_path("shouty.py"),
        vec![OnSyntax(Markdown), OnSyntax(Plaintext)])
    ]
}

/// Describes attributes and capabilities of a plugin.
///
/// Note: - these will eventually be loaded from manifest files.
#[derive(Debug, Clone)]
pub struct PluginDescription {
    pub name: String,
    version: String,
    //scope: PluginScope,
    // more metadata ...
    /// path to plugin executable
    pub exec_path: PathBuf,
    /// Events that cause this plugin to run
    activations: Vec<PluginActivation>,
}

/// `PluginActivation`s represent events that trigger running a plugin.
#[derive(Debug, Clone)]
pub enum PluginActivation {
    /// Always run this plugin, when available.
    Autorun,
    /// Run this plugin if the provided SyntaxDefinition is active.
    OnSyntax(SyntaxDefinition),
    /// Run this plugin in response to a given command.
    #[allow(dead_code)]
    OnCommand,
}

impl PluginDescription {
    fn new<S, P>(name: S, version: S, exec_path: P, activations: Vec<PluginActivation>) -> Self
        where S: Into<String>, P: Into<PathBuf>
    {
        PluginDescription {
            name: name.into(),
            version: version.into(),
            exec_path: exec_path.into(),
            activations: activations,
        }
    }

    /// Starts the executable described in this `PluginDescription`.
    pub fn launch<W, C>(&self, manager_ref: &Arc<Mutex<PluginManager<W>>>, buffer_id: &str, completion: C)
        where W: Write + Send + 'static,
              C: FnOnce(Result<PluginRef<W>, &'static str>) + Send + 'static
              // TODO: a real result type
    {
        let path = self.exec_path.clone();
        let buffer_id = buffer_id.to_owned();
        let manager_ref = manager_ref.clone();
        let description = self.clone();

        thread::spawn(move || {
            print_err!("starting plugin at path {:?}", path);
            let mut child = Command::new(&path)
                .stdin(Stdio::piped())
                .stdout(Stdio::piped())
                .spawn()
                .expect("plugin failed to start");
            let child_stdin = child.stdin.take().unwrap();
            let child_stdout = child.stdout.take().unwrap();
            let mut looper = RpcLoop::new(child_stdin);
            let peer = looper.get_peer();
            peer.send_rpc_notification("ping", &Value::Array(Vec::new()));
            let plugin = Plugin {
                peer: peer,
                //TODO: I had the bright idea of keeping this reference but
                // I'm not sure exactly what to do with it (stopping the plugin is one thing)
                process: child,
                manager: Arc::downgrade(&manager_ref),
                description: description,
                buffer_id: buffer_id,
            };
            let mut plugin_ref = PluginRef(Arc::new(Mutex::new(plugin)));
            completion(Ok(plugin_ref.clone()));
            looper.mainloop(|| BufReader::new(child_stdout), &mut plugin_ref);
        });
    }
}

<|endoftext|>


<commit_before>extern crate crusty_chip;
extern crate sfml;
extern crate getopts;

use getopts::Options;

fn usage(progname: &str, opts: &Options) -> String {
    let brief = format!("{} rom_file", progname);
    format!("Usage: {}", opts.usage(&brief))
}

fn run() -> i32 {
    use sfml::window::{ContextSettings, Event, VideoMode, style};
    use sfml::graphics::{Color, RenderTarget, RenderWindow, Sprite, Texture, Transformable};
    use sfml::system::Clock;
    use std::fs::File;
    use std::io::Read;
    use crusty_chip::{DISPLAY_HEIGHT, DISPLAY_WIDTH, VirtualMachine, decode};

    let mut args = std::env::args();
    let progname = args.next().expect("Missing program name?");
    let mut opts = Options::new();
    opts.optflag("", "pause", "Start in a paused state");

    let matches = match opts.parse(args) {
        Ok(matches) => matches,
        Err(e) => {
            eprintln!("{}\n\n{}", e, usage(&progname, &opts));
            return 1;
        }
    };

    let mut paused = matches.opt_present("pause");

    let filename = match matches.free.get(0) {
        Some(filename) => filename,
        None => {
            eprintln!("Required filename as first positional argument.\n");
            eprintln!("{}", usage(&progname, &opts));
            return 1;
        }
    };

    let mut clock = Clock::start();

    let mut file = match File::open(&filename) {
        Ok(f) => f,
        Err(e) => {
            eprintln!("Failed to open \"{}\": {}", filename, e);
            return 1;
        }
    };

    if file.metadata().unwrap().len() > crusty_chip::MEM_SIZE as u64 {
        eprintln!(
            "File \"{}\" is too big to be a proper CHIP-8 ROM.",
            filename
        );
        return 1;
    }

    let mut data = [0; crusty_chip::MEM_SIZE];
    // TODO: Dunno if this always reads the whole file
    let bytes_read = file.read(&mut data)
        .unwrap_or_else(|e| panic!("Failed to read rom: {}", e));

    let scale = 10;

    let mut ch8 = VirtualMachine::new();
    match ch8.load_rom(&data[..bytes_read]) {
        Ok(data) => data,
        Err(e) => {
            eprintln!("Error loading rom: \"{}\". Aborting.", e);
            return 1;
        }
    }

    let ctx = ContextSettings::default();
    let mut win = RenderWindow::new(
        VideoMode::new(
            DISPLAY_WIDTH as u32 * scale,
            DISPLAY_HEIGHT as u32 * scale,
            32,
        ),
        "CrustyChip",
        style::CLOSE,
        &ctx,
    )
            .unwrap();

    let mut tex = Texture::new(DISPLAY_WIDTH as u32, DISPLAY_HEIGHT as u32).unwrap();

    win.clear(&Color::black());
    win.display();
    let mut saved_states = [None; 10];
    let mut printed_info = false;
    let mut cycles_made: u64 = 0;

    loop {
        let mut advance = false;
        let mut redisplay = false;
        for event in win.events() {
            use sfml::window::Key;
            fn key_mapping(code: Key) -> Option<usize> {
                match code {
                    Key::Num1 => Some(1),
                    Key::Num2 => Some(2),
                    Key::Num3 => Some(3),
                    Key::Num4 => Some(0xC),
                    Key::Q => Some(4),
                    Key::W => Some(5),
                    Key::E => Some(6),
                    Key::R => Some(0xD),
                    Key::A => Some(7),
                    Key::S => Some(8),
                    Key::D => Some(9),
                    Key::F => Some(0xE),
                    Key::Z => Some(0xA),
                    Key::X => Some(0),
                    Key::C => Some(0xB),
                    Key::V => Some(0xF),
                    _ => None,
                }
            }
            match event {
                Event::Closed => return 0,
                Event::KeyPressed { code, ctrl, shift, .. } => {
                    if code == Key::P {
                        paused = !paused;
                    } else if code == Key::R && ctrl {
                        ch8 = VirtualMachine::new();
                        ch8.load_rom(&data).expect("ROM data too big? It changed?");
                    } else if code == Key::Period {
                        advance = true;
                    } else if let Some(key) = key_mapping(code) {
                        ch8.press_key(key);
                    }
                    macro_rules! state_key (
                        ($s: expr, $k: ident) => (
                            if code == Key::$k {
                                if shift {
                                    saved_states[$s] = Some(ch8);
                                    eprintln!("Saved state {}.", $s);
                                } else if let Some(state) = saved_states[$s] {
                                    ch8 = state;
                                    eprintln!("Loaded state {}.", $s);
                                }
                            }
                        )
                    );
                    state_key!(0, F1);
                    state_key!(1, F2);
                    state_key!(2, F3);
                    state_key!(3, F4);
                    state_key!(4, F5);
                    state_key!(5, F6);
                    state_key!(6, F7);
                    state_key!(7, F8);
                    state_key!(8, F9);
                    state_key!(9, F10);
                }
                Event::KeyReleased { code, .. } => {
                    if let Some(key) = key_mapping(code) {
                        ch8.release_key(key);
                    }
                }
                Event::GainedFocus => redisplay = true,
                _ => {}
            }
        }

        if redisplay {
            win.display();
        }

        if clock.elapsed_time().as_seconds() >= 1.0 / 60.0 {
            ch8.decrement_timers();
            clock.restart();
        }

        if paused {
            std::thread::sleep(std::time::Duration::from_millis(25));
        }

        if paused && !printed_info {
            let raw_ins = ch8.get_ins();
            println!(
                "Cycle {}, pc @ {:x}, ins: {:?} ({:x})",
                cycles_made,
                ch8.pc(),
                decode(raw_ins),
                raw_ins
            );
            printed_info = true;
        }

        if !paused || advance {
            ch8.do_cycle();
            cycles_made += 1;
            printed_info = false;
        }

        if ch8.display_updated() {
            let mut pixels = [255u8; DISPLAY_WIDTH * DISPLAY_HEIGHT * 4];

            for (i, b) in ch8.display().iter().enumerate() {
                let idx = i * 4;
                if *b == 0u8 {
                    for p in pixels[idx..idx + 3].iter_mut() {
                        *p = 0;
                    }
                }
            }

            tex.update_from_pixels(&pixels, DISPLAY_WIDTH as u32, DISPLAY_HEIGHT as u32, 0, 0);
            let mut sprite = Sprite::with_texture(&tex);
            sprite.set_scale2f(scale as f32, scale as f32);
            win.draw(&sprite);
            win.display();
        }
    }
}

fn main() {
    std::process::exit(run());
}
<commit_msg>Judo flip, chop chop chop<commit_after>extern crate crusty_chip;
extern crate sfml;
extern crate getopts;

use getopts::Options;

fn usage(progname: &str, opts: &Options) -> String {
    let brief = format!("{} rom_file", progname);
    format!("Usage: {}", opts.usage(&brief))
}

fn run() -> i32 {
    use sfml::window::{ContextSettings, Event, VideoMode, style};
    use sfml::graphics::{Color, RenderTarget, RenderWindow, Sprite, Texture, Transformable};
    use sfml::system::Clock;
    use std::fs::File;
    use std::io::Read;
    use crusty_chip::{DISPLAY_HEIGHT, DISPLAY_WIDTH, VirtualMachine, decode};

    let mut args = std::env::args();
    let progname = args.next().expect("Missing program name?");
    let mut opts = Options::new();
    opts.optflag("", "pause", "Start in a paused state");

    let matches = match opts.parse(args) {
        Ok(matches) => matches,
        Err(e) => {
            eprintln!("{}\n\n{}", e, usage(&progname, &opts));
            return 1;
        }
    };

    let mut paused = matches.opt_present("pause");

    let filename = match matches.free.get(0) {
        Some(filename) => filename,
        None => {
            eprintln!("Required filename as first positional argument.\n");
            eprintln!("{}", usage(&progname, &opts));
            return 1;
        }
    };

    let mut clock = Clock::start();

    let mut file = match File::open(&filename) {
        Ok(f) => f,
        Err(e) => {
            eprintln!("Failed to open \"{}\": {}", filename, e);
            return 1;
        }
    };

    if file.metadata().unwrap().len() > crusty_chip::MEM_SIZE as u64 {
        eprintln!(
            "File \"{}\" is too big to be a proper CHIP-8 ROM.",
            filename
        );
        return 1;
    }

    let mut data = [0; crusty_chip::MEM_SIZE];
    // TODO: Dunno if this always reads the whole file
    let bytes_read = file.read(&mut data)
        .unwrap_or_else(|e| panic!("Failed to read rom: {}", e));

    let scale = 10;

    let mut ch8 = VirtualMachine::new();
    match ch8.load_rom(&data[..bytes_read]) {
        Ok(data) => data,
        Err(e) => {
            eprintln!("Error loading rom: \"{}\". Aborting.", e);
            return 1;
        }
    }

    let ctx = ContextSettings::default();
    let mut win = RenderWindow::new(
        VideoMode::new(
            DISPLAY_WIDTH as u32 * scale,
            DISPLAY_HEIGHT as u32 * scale,
            32,
        ),
        "CrustyChip",
        style::CLOSE,
        &ctx,
    ).unwrap();

    let mut tex = Texture::new(DISPLAY_WIDTH as u32, DISPLAY_HEIGHT as u32).unwrap();

    win.clear(&Color::black());
    win.display();
    let mut saved_states = [None; 10];
    let mut printed_info = false;
    let mut cycles_made: u64 = 0;

    loop {
        let mut advance = false;
        let mut redisplay = false;
        for event in win.events() {
            use sfml::window::Key;
            fn key_mapping(code: Key) -> Option<usize> {
                match code {
                    Key::Num1 => Some(1),
                    Key::Num2 => Some(2),
                    Key::Num3 => Some(3),
                    Key::Num4 => Some(0xC),
                    Key::Q => Some(4),
                    Key::W => Some(5),
                    Key::E => Some(6),
                    Key::R => Some(0xD),
                    Key::A => Some(7),
                    Key::S => Some(8),
                    Key::D => Some(9),
                    Key::F => Some(0xE),
                    Key::Z => Some(0xA),
                    Key::X => Some(0),
                    Key::C => Some(0xB),
                    Key::V => Some(0xF),
                    _ => None,
                }
            }
            match event {
                Event::Closed => return 0,
                Event::KeyPressed { code, ctrl, shift, .. } => {
                    if code == Key::P {
                        paused = !paused;
                    } else if code == Key::R && ctrl {
                        ch8 = VirtualMachine::new();
                        ch8.load_rom(&data).expect("ROM data too big? It changed?");
                    } else if code == Key::Period {
                        advance = true;
                    } else if let Some(key) = key_mapping(code) {
                        ch8.press_key(key);
                    }
                    macro_rules! state_key (
                        ($s: expr, $k: ident) => (
                            if code == Key::$k {
                                if shift {
                                    saved_states[$s] = Some(ch8);
                                    eprintln!("Saved state {}.", $s);
                                } else if let Some(state) = saved_states[$s] {
                                    ch8 = state;
                                    eprintln!("Loaded state {}.", $s);
                                }
                            }
                        )
                    );
                    state_key!(0, F1);
                    state_key!(1, F2);
                    state_key!(2, F3);
                    state_key!(3, F4);
                    state_key!(4, F5);
                    state_key!(5, F6);
                    state_key!(6, F7);
                    state_key!(7, F8);
                    state_key!(8, F9);
                    state_key!(9, F10);
                }
                Event::KeyReleased { code, .. } => {
                    if let Some(key) = key_mapping(code) {
                        ch8.release_key(key);
                    }
                }
                Event::GainedFocus => redisplay = true,
                _ => {}
            }
        }

        if redisplay {
            win.display();
        }

        if clock.elapsed_time().as_seconds() >= 1.0 / 60.0 {
            ch8.decrement_timers();
            clock.restart();
        }

        if paused {
            std::thread::sleep(std::time::Duration::from_millis(25));
        }

        if paused && !printed_info {
            let raw_ins = ch8.get_ins();
            println!(
                "Cycle {}, pc @ {:x}, ins: {:?} ({:x})",
                cycles_made,
                ch8.pc(),
                decode(raw_ins),
                raw_ins
            );
            printed_info = true;
        }

        if !paused || advance {
            ch8.do_cycle();
            cycles_made += 1;
            printed_info = false;
        }

        if ch8.display_updated() {
            let mut pixels = [255u8; DISPLAY_WIDTH * DISPLAY_HEIGHT * 4];

            for (i, b) in ch8.display().iter().enumerate() {
                let idx = i * 4;
                if *b == 0u8 {
                    for p in pixels[idx..idx + 3].iter_mut() {
                        *p = 0;
                    }
                }
            }

            tex.update_from_pixels(&pixels, DISPLAY_WIDTH as u32, DISPLAY_HEIGHT as u32, 0, 0);
            let mut sprite = Sprite::with_texture(&tex);
            sprite.set_scale2f(scale as f32, scale as f32);
            win.draw(&sprite);
            win.display();
        }
    }
}

fn main() {
    std::process::exit(run());
}
<|endoftext|>


<commit_before>// spell-checker:ignore (ToDO) arrnum mult basenum bufferval refd vals arrfloat conv intermed addl

pub fn arrnum_int_mult(arr_num: &[u8], basenum: u8, base_ten_int_fact: u8) -> Vec<u8> {
    let mut carry: u16 = 0;
    let mut rem: u16;
    let mut new_amount: u16;
    let fact: u16 = u16::from(base_ten_int_fact);
    let base: u16 = u16::from(basenum);

    let mut ret_rev: Vec<u8> = Vec::new();
    let mut it = arr_num.iter().rev();
    loop {
        let i = it.next();
        match i {
            Some(u) => {
                new_amount = (u16::from(*u) * fact) + carry;
                rem = new_amount % base;
                carry = (new_amount - rem) / base;
                ret_rev.push(rem as u8)
            }
            None => {
                while carry != 0 {
                    rem = carry % base;
                    carry = (carry - rem) / base;
                    ret_rev.push(rem as u8);
                }
                break;
            }
        }
    }
    let ret: Vec<u8> = ret_rev.into_iter().rev().collect();
    ret
}

pub struct Remainder<'a> {
    pub position: usize,
    pub replace: Vec<u8>,
    pub arr_num: &'a Vec<u8>,
}

pub struct DivOut<'a> {
    pub quotient: u8,
    pub remainder: Remainder<'a>,
}

pub fn arrnum_int_div_step(
    rem_in: Remainder,
    radix_in: u8,
    base_ten_int_divisor: u8,
    after_decimal: bool,
) -> DivOut {
    let mut rem_out = Remainder {
        position: rem_in.position,
        replace: Vec::new(),
        arr_num: rem_in.arr_num,
    };

    let mut bufferval: u16 = 0;
    let base: u16 = u16::from(radix_in);
    let divisor: u16 = u16::from(base_ten_int_divisor);
    let mut traversed = 0;

    let mut quotient = 0;
    let refd_vals = &rem_in.arr_num[rem_in.position + rem_in.replace.len()..];
    let mut it_replace = rem_in.replace.iter();
    let mut it_f = refd_vals.iter();
    loop {
        let u = match it_replace.next() {
            Some(u_rep) => u16::from(*u_rep),
            None => match it_f.next() {
                Some(u_orig) => u16::from(*u_orig),
                None => {
                    if !after_decimal {
                        break;
                    }
                    0
                }
            },
        };
        traversed += 1;
        bufferval += u;
        if bufferval > divisor {
            while bufferval >= divisor {
                quotient += 1;
                bufferval -= divisor;
            }
            rem_out.replace = if bufferval == 0 {
                Vec::new()
            } else {
                let remainder_as_arrnum = unsigned_to_arrnum(bufferval);
                base_conv_vec(&remainder_as_arrnum, 10, radix_in)
            };
            rem_out.position += 1 + (traversed - rem_out.replace.len());
            break;
        } else {
            bufferval *= base;
        }
    }
    DivOut {
        quotient,
        remainder: rem_out,
    }
}
pub fn arrnum_int_add(arrnum: &[u8], basenum: u8, base_ten_int_term: u8) -> Vec<u8> {
    let mut carry: u16 = u16::from(base_ten_int_term);
    let mut rem: u16;
    let mut new_amount: u16;
    let base: u16 = u16::from(basenum);

    let mut ret_rev: Vec<u8> = Vec::new();
    let mut it = arrnum.iter().rev();
    loop {
        let i = it.next();
        match i {
            Some(u) => {
                new_amount = u16::from(*u) + carry;
                rem = new_amount % base;
                carry = (new_amount - rem) / base;
                ret_rev.push(rem as u8)
            }
            None => {
                while carry != 0 {
                    rem = carry % base;
                    carry = (carry - rem) / base;
                    ret_rev.push(rem as u8);
                }
                break;
            }
        }
    }
    let ret: Vec<u8> = ret_rev.into_iter().rev().collect();
    ret
}

pub fn base_conv_vec(src: &[u8], radix_src: u8, radix_dest: u8) -> Vec<u8> {
    let mut result = vec![0];
    for i in src {
        result = arrnum_int_mult(&result, radix_dest, radix_src);
        result = arrnum_int_add(&result, radix_dest, *i);
    }
    result
}

pub fn unsigned_to_arrnum(src: u16) -> Vec<u8> {
    let mut result: Vec<u8> = Vec::new();
    let mut src_tmp: u16 = src;
    while src_tmp > 0 {
        result.push((src_tmp % 10) as u8);
        src_tmp /= 10;
    }
    result.reverse();
    result
}

// temporary needs-improvement-function
pub fn base_conv_float(src: &[u8], radix_src: u8, _radix_dest: u8) -> f64 {
    // it would require a lot of addl code
    // to implement this for arbitrary string input.
    // until then, the below operates as an outline
    // of how it would work.
    let result: Vec<u8> = vec![0];
    let mut factor: f64 = 1_f64;
    let radix_src_float: f64 = f64::from(radix_src);
    let mut r: f64 = 0_f64;
    for (i, u) in src.iter().enumerate() {
        if i > 15 {
            break;
        }
        factor /= radix_src_float;
        r += factor * f64::from(*u)
    }
    r
}

pub fn str_to_arrnum(src: &str, radix_def_src: &dyn RadixDef) -> Vec<u8> {
    let mut intermed_in: Vec<u8> = Vec::new();
    for c in src.chars() {
        #[allow(clippy::single_match)]
        match radix_def_src.from_char(c) {
            Some(u) => {
                intermed_in.push(u);
            }
            None => {} //todo err msg on incorrect
        }
    }
    intermed_in
}

pub fn arrnum_to_str(src: &[u8], radix_def_dest: &dyn RadixDef) -> String {
    let mut str_out = String::new();
    for u in src.iter() {
        #[allow(clippy::single_match)]
        match radix_def_dest.from_u8(*u) {
            Some(c) => {
                str_out.push(c);
            }
            None => {} //todo
        }
    }
    str_out
}

pub fn base_conv_str(
    src: &str,
    radix_def_src: &dyn RadixDef,
    radix_def_dest: &dyn RadixDef,
) -> String {
    let intermed_in: Vec<u8> = str_to_arrnum(src, radix_def_src);
    let intermed_out = base_conv_vec(
        &intermed_in,
        radix_def_src.get_max(),
        radix_def_dest.get_max(),
    );
    arrnum_to_str(&intermed_out, radix_def_dest)
}

pub trait RadixDef {
    fn get_max(&self) -> u8;
    fn from_char(&self, x: char) -> Option<u8>;
    fn from_u8(&self, x: u8) -> Option<char>;
}
pub struct RadixTen;

const ZERO_ASC: u8 = b'0';
const UPPER_A_ASC: u8 = b'A';
const LOWER_A_ASC: u8 = b'a';

impl RadixDef for RadixTen {
    fn get_max(&self) -> u8 {
        10
    }
    fn from_char(&self, c: char) -> Option<u8> {
        match c {
            '0'..='9' => Some(c as u8 - ZERO_ASC),
            _ => None,
        }
    }
    fn from_u8(&self, u: u8) -> Option<char> {
        match u {
            0..=9 => Some((ZERO_ASC + u) as char),
            _ => None,
        }
    }
}
pub struct RadixHex;
impl RadixDef for RadixHex {
    fn get_max(&self) -> u8 {
        16
    }
    fn from_char(&self, c: char) -> Option<u8> {
        match c {
            '0'..='9' => Some(c as u8 - ZERO_ASC),
            'A'..='F' => Some(c as u8 + 10 - UPPER_A_ASC),
            'a'..='f' => Some(c as u8 + 10 - LOWER_A_ASC),
            _ => None,
        }
    }
    fn from_u8(&self, u: u8) -> Option<char> {
        match u {
            0..=9 => Some((ZERO_ASC + u) as char),
            10..=15 => Some((UPPER_A_ASC + (u - 10)) as char),
            _ => None,
        }
    }
}

mod tests;
<commit_msg>printf: remove useless declaration<commit_after>// spell-checker:ignore (ToDO) arrnum mult basenum bufferval refd vals arrfloat conv intermed addl

pub fn arrnum_int_mult(arr_num: &[u8], basenum: u8, base_ten_int_fact: u8) -> Vec<u8> {
    let mut carry: u16 = 0;
    let mut rem: u16;
    let mut new_amount: u16;
    let fact: u16 = u16::from(base_ten_int_fact);
    let base: u16 = u16::from(basenum);

    let mut ret_rev: Vec<u8> = Vec::new();
    let mut it = arr_num.iter().rev();
    loop {
        let i = it.next();
        match i {
            Some(u) => {
                new_amount = (u16::from(*u) * fact) + carry;
                rem = new_amount % base;
                carry = (new_amount - rem) / base;
                ret_rev.push(rem as u8)
            }
            None => {
                while carry != 0 {
                    rem = carry % base;
                    carry = (carry - rem) / base;
                    ret_rev.push(rem as u8);
                }
                break;
            }
        }
    }
    let ret: Vec<u8> = ret_rev.into_iter().rev().collect();
    ret
}

pub struct Remainder<'a> {
    pub position: usize,
    pub replace: Vec<u8>,
    pub arr_num: &'a Vec<u8>,
}

pub struct DivOut<'a> {
    pub quotient: u8,
    pub remainder: Remainder<'a>,
}

pub fn arrnum_int_div_step(
    rem_in: Remainder,
    radix_in: u8,
    base_ten_int_divisor: u8,
    after_decimal: bool,
) -> DivOut {
    let mut rem_out = Remainder {
        position: rem_in.position,
        replace: Vec::new(),
        arr_num: rem_in.arr_num,
    };

    let mut bufferval: u16 = 0;
    let base: u16 = u16::from(radix_in);
    let divisor: u16 = u16::from(base_ten_int_divisor);
    let mut traversed = 0;

    let mut quotient = 0;
    let refd_vals = &rem_in.arr_num[rem_in.position + rem_in.replace.len()..];
    let mut it_replace = rem_in.replace.iter();
    let mut it_f = refd_vals.iter();
    loop {
        let u = match it_replace.next() {
            Some(u_rep) => u16::from(*u_rep),
            None => match it_f.next() {
                Some(u_orig) => u16::from(*u_orig),
                None => {
                    if !after_decimal {
                        break;
                    }
                    0
                }
            },
        };
        traversed += 1;
        bufferval += u;
        if bufferval > divisor {
            while bufferval >= divisor {
                quotient += 1;
                bufferval -= divisor;
            }
            rem_out.replace = if bufferval == 0 {
                Vec::new()
            } else {
                let remainder_as_arrnum = unsigned_to_arrnum(bufferval);
                base_conv_vec(&remainder_as_arrnum, 10, radix_in)
            };
            rem_out.position += 1 + (traversed - rem_out.replace.len());
            break;
        } else {
            bufferval *= base;
        }
    }
    DivOut {
        quotient,
        remainder: rem_out,
    }
}
pub fn arrnum_int_add(arrnum: &[u8], basenum: u8, base_ten_int_term: u8) -> Vec<u8> {
    let mut carry: u16 = u16::from(base_ten_int_term);
    let mut rem: u16;
    let mut new_amount: u16;
    let base: u16 = u16::from(basenum);

    let mut ret_rev: Vec<u8> = Vec::new();
    let mut it = arrnum.iter().rev();
    loop {
        let i = it.next();
        match i {
            Some(u) => {
                new_amount = u16::from(*u) + carry;
                rem = new_amount % base;
                carry = (new_amount - rem) / base;
                ret_rev.push(rem as u8)
            }
            None => {
                while carry != 0 {
                    rem = carry % base;
                    carry = (carry - rem) / base;
                    ret_rev.push(rem as u8);
                }
                break;
            }
        }
    }
    let ret: Vec<u8> = ret_rev.into_iter().rev().collect();
    ret
}

pub fn base_conv_vec(src: &[u8], radix_src: u8, radix_dest: u8) -> Vec<u8> {
    let mut result = vec![0];
    for i in src {
        result = arrnum_int_mult(&result, radix_dest, radix_src);
        result = arrnum_int_add(&result, radix_dest, *i);
    }
    result
}

pub fn unsigned_to_arrnum(src: u16) -> Vec<u8> {
    let mut result: Vec<u8> = Vec::new();
    let mut src_tmp: u16 = src;
    while src_tmp > 0 {
        result.push((src_tmp % 10) as u8);
        src_tmp /= 10;
    }
    result.reverse();
    result
}

// temporary needs-improvement-function
pub fn base_conv_float(src: &[u8], radix_src: u8, _radix_dest: u8) -> f64 {
    // it would require a lot of addl code
    // to implement this for arbitrary string input.
    // until then, the below operates as an outline
    // of how it would work.
    let mut factor: f64 = 1_f64;
    let radix_src_float: f64 = f64::from(radix_src);
    let mut r: f64 = 0_f64;
    for (i, u) in src.iter().enumerate() {
        if i > 15 {
            break;
        }
        factor /= radix_src_float;
        r += factor * f64::from(*u)
    }
    r
}

pub fn str_to_arrnum(src: &str, radix_def_src: &dyn RadixDef) -> Vec<u8> {
    let mut intermed_in: Vec<u8> = Vec::new();
    for c in src.chars() {
        #[allow(clippy::single_match)]
        match radix_def_src.from_char(c) {
            Some(u) => {
                intermed_in.push(u);
            }
            None => {} //todo err msg on incorrect
        }
    }
    intermed_in
}

pub fn arrnum_to_str(src: &[u8], radix_def_dest: &dyn RadixDef) -> String {
    let mut str_out = String::new();
    for u in src.iter() {
        #[allow(clippy::single_match)]
        match radix_def_dest.from_u8(*u) {
            Some(c) => {
                str_out.push(c);
            }
            None => {} //todo
        }
    }
    str_out
}

pub fn base_conv_str(
    src: &str,
    radix_def_src: &dyn RadixDef,
    radix_def_dest: &dyn RadixDef,
) -> String {
    let intermed_in: Vec<u8> = str_to_arrnum(src, radix_def_src);
    let intermed_out = base_conv_vec(
        &intermed_in,
        radix_def_src.get_max(),
        radix_def_dest.get_max(),
    );
    arrnum_to_str(&intermed_out, radix_def_dest)
}

pub trait RadixDef {
    fn get_max(&self) -> u8;
    fn from_char(&self, x: char) -> Option<u8>;
    fn from_u8(&self, x: u8) -> Option<char>;
}
pub struct RadixTen;

const ZERO_ASC: u8 = b'0';
const UPPER_A_ASC: u8 = b'A';
const LOWER_A_ASC: u8 = b'a';

impl RadixDef for RadixTen {
    fn get_max(&self) -> u8 {
        10
    }
    fn from_char(&self, c: char) -> Option<u8> {
        match c {
            '0'..='9' => Some(c as u8 - ZERO_ASC),
            _ => None,
        }
    }
    fn from_u8(&self, u: u8) -> Option<char> {
        match u {
            0..=9 => Some((ZERO_ASC + u) as char),
            _ => None,
        }
    }
}
pub struct RadixHex;
impl RadixDef for RadixHex {
    fn get_max(&self) -> u8 {
        16
    }
    fn from_char(&self, c: char) -> Option<u8> {
        match c {
            '0'..='9' => Some(c as u8 - ZERO_ASC),
            'A'..='F' => Some(c as u8 + 10 - UPPER_A_ASC),
            'a'..='f' => Some(c as u8 + 10 - LOWER_A_ASC),
            _ => None,
        }
    }
    fn from_u8(&self, u: u8) -> Option<char> {
        match u {
            0..=9 => Some((ZERO_ASC + u) as char),
            10..=15 => Some((UPPER_A_ASC + (u - 10)) as char),
            _ => None,
        }
    }
}

mod tests;
<|endoftext|>


<commit_before>//
// Sysinfo
//
// Copyright (c) 2017 Guillaume Gomez
//

#![crate_type = "bin"]
#![allow(unused_must_use, non_upper_case_globals)]

extern crate sysinfo;

use std::io::{self, BufRead, Write};
use std::str::FromStr;
use sysinfo::Signal::*;
use sysinfo::{
    NetworkExt, NetworksExt, Pid, ProcessExt, ProcessorExt, Signal, System, SystemExt, UserExt,
};

const signals: [Signal; 31] = [
    Hangup,
    Interrupt,
    Quit,
    Illegal,
    Trap,
    Abort,
    Bus,
    FloatingPointException,
    Kill,
    User1,
    Segv,
    User2,
    Pipe,
    Alarm,
    Term,
    Stklft,
    Child,
    Continue,
    Stop,
    TSTP,
    TTIN,
    TTOU,
    Urgent,
    XCPU,
    XFSZ,
    VirtualAlarm,
    Profiling,
    Winch,
    IO,
    Power,
    Sys,
];

fn print_help() {
    writeln!(&mut io::stdout(), "== Help menu ==");
    writeln!(&mut io::stdout(), "help               : show this menu");
    writeln!(
        &mut io::stdout(),
        "signals            : show the available signals"
    );
    writeln!(
        &mut io::stdout(),
        "refresh            : reloads all processes' information"
    );
    writeln!(
        &mut io::stdout(),
        "refresh [pid]      : reloads corresponding process' information"
    );
    writeln!(
        &mut io::stdout(),
        "refresh_disks      : reloads only disks' information"
    );
    writeln!(
        &mut io::stdout(),
        "refresh_users      : reloads only users' information"
    );
    writeln!(
        &mut io::stdout(),
        "show [pid | name]  : show information of the given process \
         corresponding to [pid | name]"
    );
    writeln!(
        &mut io::stdout(),
        "kill [pid] [signal]: send [signal] to the process with this \
         [pid]. 0 < [signal] < 32"
    );
    writeln!(
        &mut io::stdout(),
        "processors         : Displays processors state"
    );
    writeln!(
        &mut io::stdout(),
        "memory             : Displays memory state"
    );
    writeln!(
        &mut io::stdout(),
        "temperature        : Displays components' temperature"
    );
    writeln!(
        &mut io::stdout(),
        "disks              : Displays disks' information"
    );
    writeln!(
        &mut io::stdout(),
        "network            : Displays network' information"
    );
    writeln!(
        &mut io::stdout(),
        "all                : Displays all process name and pid"
    );
    writeln!(
        &mut io::stdout(),
        "uptime             : Displays system uptime"
    );
    writeln!(
        &mut io::stdout(),
        "boot_time          : Displays system boot time"
    );
    writeln!(
        &mut io::stdout(),
        "vendor_id          : Displays processor vendor id"
    );
    writeln!(
        &mut io::stdout(),
        "brand              : Displays processor brand"
    );
    writeln!(
        &mut io::stdout(),
        "load_avg           : Displays system load average"
    );
    writeln!(
        &mut io::stdout(),
        "frequency          : Displays processor frequency"
    );
    writeln!(&mut io::stdout(), "users              : Displays all users");
    writeln!(
        &mut io::stdout(),
        "system             : Displays system information (such as name, version and hostname)"
    );
    writeln!(&mut io::stdout(), "quit               : exit the program");
}

fn interpret_input(input: &str, sys: &mut System) -> bool {
    match input.trim() {
        "help" => print_help(),
        "refresh_disks" => {
            writeln!(&mut io::stdout(), "Refreshing disk list...");
            sys.refresh_disks_list();
            writeln!(&mut io::stdout(), "Done.");
        }
        "refresh_users" => {
            writeln!(&mut io::stdout(), "Refreshing user list...");
            sys.refresh_users_list();
            writeln!(&mut io::stdout(), "Done.");
        }
        "signals" => {
            let mut nb = 1i32;

            for sig in &signals {
                writeln!(&mut io::stdout(), "{:2}:{:?}", nb, sig);
                nb += 1;
            }
        }
        "processors" => {
            // Note: you should refresh a few times before using this, so that usage statistics
            // can be ascertained
            writeln!(
                &mut io::stdout(),
                "total process usage: {}%",
                sys.get_global_processor_info().get_cpu_usage()
            );
            for proc_ in sys.get_processors() {
                writeln!(&mut io::stdout(), "{:?}", proc_);
            }
        }
        "memory" => {
            writeln!(
                &mut io::stdout(),
                "total memory: {} KB",
                sys.get_total_memory()
            );
            writeln!(
                &mut io::stdout(),
                "used memory : {} KB",
                sys.get_used_memory()
            );
            writeln!(
                &mut io::stdout(),
                "total swap  : {} KB",
                sys.get_total_swap()
            );
            writeln!(
                &mut io::stdout(),
                "used swap   : {} KB",
                sys.get_used_swap()
            );
        }
        "quit" | "exit" => return true,
        "all" => {
            for (pid, proc_) in sys.get_processes() {
                writeln!(
                    &mut io::stdout(),
                    "{}:{} status={:?}",
                    pid,
                    proc_.name(),
                    proc_.status()
                );
            }
        }
        "frequency" => {
            writeln!(
                &mut io::stdout(),
                "{} MHz",
                sys.get_processors()[0].get_frequency()
            );
        }
        "vendor_id" => {
            writeln!(
                &mut io::stdout(),
                "vendor ID: {}",
                sys.get_processors()[0].get_vendor_id()
            );
        }
        "brand" => {
            writeln!(
                &mut io::stdout(),
                "brand: {}",
                sys.get_processors()[0].get_brand()
            );
        }
        "load_avg" => {
            let load_avg = sys.get_load_average();
            writeln!(&mut io::stdout(), "one minute     : {}%", load_avg.one);
            writeln!(&mut io::stdout(), "five minutes   : {}%", load_avg.five);
            writeln!(&mut io::stdout(), "fifteen minutes: {}%", load_avg.fifteen);
        }
        e if e.starts_with("show ") => {
            let tmp: Vec<&str> = e.split(' ').collect();

            if tmp.len() != 2 {
                writeln!(
                    &mut io::stdout(),
                    "show command takes a pid or a name in parameter!"
                );
                writeln!(&mut io::stdout(), "example: show 1254");
            } else if let Ok(pid) = Pid::from_str(tmp[1]) {
                match sys.get_process(pid) {
                    Some(p) => writeln!(&mut io::stdout(), "{:?}", *p),
                    None => writeln!(&mut io::stdout(), "pid \"{:?}\" not found", pid),
                };
            } else {
                let proc_name = tmp[1];
                for proc_ in sys.get_process_by_name(proc_name) {
                    writeln!(&mut io::stdout(), "==== {} ====", proc_.name());
                    writeln!(&mut io::stdout(), "{:?}", proc_);
                }
            }
        }
        "temperature" => {
            for component in sys.get_components() {
                writeln!(&mut io::stdout(), "{:?}", component);
            }
        }
        "network" => {
            for (interface_name, data) in sys.get_networks().iter() {
                writeln!(
                    &mut io::stdout(),
                    "{}:\n  input data  (new / total): {} / {} B\n  output data (new / total): {} / {} B",
                    interface_name,
                    data.get_received(),
                    data.get_total_received(),
                    data.get_transmitted(),
                    data.get_total_transmitted(),
                );
            }
        }
        "show" => {
            writeln!(
                &mut io::stdout(),
                "'show' command expects a pid number or a process name"
            );
        }
        e if e.starts_with("kill ") => {
            let tmp: Vec<&str> = e.split(' ').collect();

            if tmp.len() != 3 {
                writeln!(
                    &mut io::stdout(),
                    "kill command takes the pid and a signal number in parameter !"
                );
                writeln!(&mut io::stdout(), "example: kill 1254 9");
            } else {
                let pid = Pid::from_str(tmp[1]).unwrap();
                let signal = i32::from_str(tmp[2]).unwrap();

                if signal < 1 || signal > 31 {
                    writeln!(
                        &mut io::stdout(),
                        "Signal must be between 0 and 32 ! See the signals list with the \
                         signals command"
                    );
                } else {
                    match sys.get_process(pid) {
                        Some(p) => {
                            writeln!(
                                &mut io::stdout(),
                                "kill: {}",
                                p.kill(*signals.get(signal as usize - 1).unwrap())
                            );
                        }
                        None => {
                            writeln!(&mut io::stdout(), "pid not found");
                        }
                    };
                }
            }
        }
        "disks" => {
            for disk in sys.get_disks() {
                writeln!(&mut io::stdout(), "{:?}", disk);
            }
        }
        "users" => {
            for user in sys.get_users() {
                writeln!(&mut io::stdout(), "{:?}", user.get_name());
            }
        }
        "boot_time" => {
            writeln!(&mut io::stdout(), "{} seconds", sys.get_boot_time());
        }
        "uptime" => {
            let up = sys.get_uptime();
            let mut uptime = sys.get_uptime();
            let days = uptime / 86400;
            uptime -= days * 86400;
            let hours = uptime / 3600;
            uptime -= hours * 3600;
            let minutes = uptime / 60;
            writeln!(
                &mut io::stdout(),
                "{} days {} hours {} minutes ({} seconds in total)",
                days,
                hours,
                minutes,
                up,
            );
        }
        x if x.starts_with("refresh") => {
            if x == "refresh" {
                writeln!(&mut io::stdout(), "Getting processes' information...");
                sys.refresh_all();
                writeln!(&mut io::stdout(), "Done.");
            } else if x.starts_with("refresh ") {
                writeln!(&mut io::stdout(), "Getting process' information...");
                if let Some(pid) = x
                    .split(' ')
                    .filter_map(|pid| pid.parse().ok())
                    .take(1)
                    .next()
                {
                    if sys.refresh_process(pid) {
                        writeln!(&mut io::stdout(), "Process `{}` updated successfully", pid);
                    } else {
                        writeln!(
                            &mut io::stdout(),
                            "Process `{}` couldn't be updated...",
                            pid
                        );
                    }
                } else {
                    writeln!(&mut io::stdout(), "Invalid [pid] received...");
                }
            } else {
                writeln!(
                    &mut io::stdout(),
                    "\"{}\": Unknown command. Enter 'help' if you want to get the commands' \
                     list.",
                    x
                );
            }
        }
        "system" => {
            writeln!(
                &mut io::stdout(),
                "System name:           {}\n\
                System kernel version: {}\n\
                System OS version:     {}\n\
                System host name:      {}",
                sys.get_name().unwrap_or_else(|| "<unknown>".to_owned()),
                sys.get_kernel_version().unwrap_or_else(|| "<unknown>".to_owned()),
                sys.get_os_version().unwrap_or_else(|| "<unknown>".to_owned()),
                sys.get_host_name()
                    .unwrap_or_else(|| "<unknown>".to_owned()),
            );
        }
        e => {
            writeln!(
                &mut io::stdout(),
                "\"{}\": Unknown command. Enter 'help' if you want to get the commands' \
                 list.",
                e
            );
        }
    }
    false
}

fn main() {
    println!("Getting processes' information...");
    let mut t = System::new_all();
    println!("Done.");
    let t_stin = io::stdin();
    let mut stin = t_stin.lock();
    let mut done = false;

    println!("To get the commands' list, enter 'help'.");
    while !done {
        let mut input = String::new();
        write!(&mut io::stdout(), "> ");
        io::stdout().flush();

        stin.read_line(&mut input);
        if input.is_empty() {
            // The string is empty, meaning there is no '\n', meaning
            // that the user used CTRL+D so we can just quit!
            println!("\nLeaving, bye!");
            break;
        }
        if (&input as &str).ends_with('\n') {
            input.pop();
        }
        done = interpret_input(input.as_ref(), &mut t);
    }
}
<commit_msg>Add PID command<commit_after>//
// Sysinfo
//
// Copyright (c) 2017 Guillaume Gomez
//

#![crate_type = "bin"]
#![allow(unused_must_use, non_upper_case_globals)]

extern crate sysinfo;

use std::io::{self, BufRead, Write};
use std::str::FromStr;
use sysinfo::Signal::*;
use sysinfo::{
    NetworkExt, NetworksExt, Pid, ProcessExt, ProcessorExt, Signal, System, SystemExt, UserExt,
};

const signals: [Signal; 31] = [
    Hangup,
    Interrupt,
    Quit,
    Illegal,
    Trap,
    Abort,
    Bus,
    FloatingPointException,
    Kill,
    User1,
    Segv,
    User2,
    Pipe,
    Alarm,
    Term,
    Stklft,
    Child,
    Continue,
    Stop,
    TSTP,
    TTIN,
    TTOU,
    Urgent,
    XCPU,
    XFSZ,
    VirtualAlarm,
    Profiling,
    Winch,
    IO,
    Power,
    Sys,
];

fn print_help() {
    writeln!(&mut io::stdout(), "== Help menu ==");
    writeln!(&mut io::stdout(), "help               : show this menu");
    writeln!(
        &mut io::stdout(),
        "signals            : show the available signals"
    );
    writeln!(
        &mut io::stdout(),
        "refresh            : reloads all processes' information"
    );
    writeln!(
        &mut io::stdout(),
        "refresh [pid]      : reloads corresponding process' information"
    );
    writeln!(
        &mut io::stdout(),
        "refresh_disks      : reloads only disks' information"
    );
    writeln!(
        &mut io::stdout(),
        "refresh_users      : reloads only users' information"
    );
    writeln!(
        &mut io::stdout(),
        "show [pid | name]  : show information of the given process \
         corresponding to [pid | name]"
    );
    writeln!(
        &mut io::stdout(),
        "kill [pid] [signal]: send [signal] to the process with this \
         [pid]. 0 < [signal] < 32"
    );
    writeln!(
        &mut io::stdout(),
        "processors         : Displays processors state"
    );
    writeln!(
        &mut io::stdout(),
        "memory             : Displays memory state"
    );
    writeln!(
        &mut io::stdout(),
        "temperature        : Displays components' temperature"
    );
    writeln!(
        &mut io::stdout(),
        "disks              : Displays disks' information"
    );
    writeln!(
        &mut io::stdout(),
        "network            : Displays network' information"
    );
    writeln!(
        &mut io::stdout(),
        "all                : Displays all process name and pid"
    );
    writeln!(
        &mut io::stdout(),
        "uptime             : Displays system uptime"
    );
    writeln!(
        &mut io::stdout(),
        "boot_time          : Displays system boot time"
    );
    writeln!(
        &mut io::stdout(),
        "vendor_id          : Displays processor vendor id"
    );
    writeln!(
        &mut io::stdout(),
        "brand              : Displays processor brand"
    );
    writeln!(
        &mut io::stdout(),
        "load_avg           : Displays system load average"
    );
    writeln!(
        &mut io::stdout(),
        "frequency          : Displays processor frequency"
    );
    writeln!(&mut io::stdout(), "users              : Displays all users");
    writeln!(
        &mut io::stdout(),
        "system             : Displays system information (such as name, version and hostname)"
    );
    writeln!(
        &mut io::stdout(),
        "pid                : Display this example's PID"
    );
    writeln!(&mut io::stdout(), "quit               : Exit the program");
}

fn interpret_input(input: &str, sys: &mut System) -> bool {
    match input.trim() {
        "help" => print_help(),
        "refresh_disks" => {
            writeln!(&mut io::stdout(), "Refreshing disk list...");
            sys.refresh_disks_list();
            writeln!(&mut io::stdout(), "Done.");
        }
        "refresh_users" => {
            writeln!(&mut io::stdout(), "Refreshing user list...");
            sys.refresh_users_list();
            writeln!(&mut io::stdout(), "Done.");
        }
        "signals" => {
            let mut nb = 1i32;

            for sig in &signals {
                writeln!(&mut io::stdout(), "{:2}:{:?}", nb, sig);
                nb += 1;
            }
        }
        "processors" => {
            // Note: you should refresh a few times before using this, so that usage statistics
            // can be ascertained
            writeln!(
                &mut io::stdout(),
                "total process usage: {}%",
                sys.get_global_processor_info().get_cpu_usage()
            );
            for proc_ in sys.get_processors() {
                writeln!(&mut io::stdout(), "{:?}", proc_);
            }
        }
        "memory" => {
            writeln!(
                &mut io::stdout(),
                "total memory: {} KB",
                sys.get_total_memory()
            );
            writeln!(
                &mut io::stdout(),
                "used memory : {} KB",
                sys.get_used_memory()
            );
            writeln!(
                &mut io::stdout(),
                "total swap  : {} KB",
                sys.get_total_swap()
            );
            writeln!(
                &mut io::stdout(),
                "used swap   : {} KB",
                sys.get_used_swap()
            );
        }
        "quit" | "exit" => return true,
        "all" => {
            for (pid, proc_) in sys.get_processes() {
                writeln!(
                    &mut io::stdout(),
                    "{}:{} status={:?}",
                    pid,
                    proc_.name(),
                    proc_.status()
                );
            }
        }
        "frequency" => {
            writeln!(
                &mut io::stdout(),
                "{} MHz",
                sys.get_processors()[0].get_frequency()
            );
        }
        "vendor_id" => {
            writeln!(
                &mut io::stdout(),
                "vendor ID: {}",
                sys.get_processors()[0].get_vendor_id()
            );
        }
        "brand" => {
            writeln!(
                &mut io::stdout(),
                "brand: {}",
                sys.get_processors()[0].get_brand()
            );
        }
        "load_avg" => {
            let load_avg = sys.get_load_average();
            writeln!(&mut io::stdout(), "one minute     : {}%", load_avg.one);
            writeln!(&mut io::stdout(), "five minutes   : {}%", load_avg.five);
            writeln!(&mut io::stdout(), "fifteen minutes: {}%", load_avg.fifteen);
        }
        e if e.starts_with("show ") => {
            let tmp: Vec<&str> = e.split(' ').collect();

            if tmp.len() != 2 {
                writeln!(
                    &mut io::stdout(),
                    "show command takes a pid or a name in parameter!"
                );
                writeln!(&mut io::stdout(), "example: show 1254");
            } else if let Ok(pid) = Pid::from_str(tmp[1]) {
                match sys.get_process(pid) {
                    Some(p) => writeln!(&mut io::stdout(), "{:?}", *p),
                    None => writeln!(&mut io::stdout(), "pid \"{:?}\" not found", pid),
                };
            } else {
                let proc_name = tmp[1];
                for proc_ in sys.get_process_by_name(proc_name) {
                    writeln!(&mut io::stdout(), "==== {} ====", proc_.name());
                    writeln!(&mut io::stdout(), "{:?}", proc_);
                }
            }
        }
        "temperature" => {
            for component in sys.get_components() {
                writeln!(&mut io::stdout(), "{:?}", component);
            }
        }
        "network" => {
            for (interface_name, data) in sys.get_networks().iter() {
                writeln!(
                    &mut io::stdout(),
                    "{}:\n  input data  (new / total): {} / {} B\n  output data (new / total): {} / {} B",
                    interface_name,
                    data.get_received(),
                    data.get_total_received(),
                    data.get_transmitted(),
                    data.get_total_transmitted(),
                );
            }
        }
        "show" => {
            writeln!(
                &mut io::stdout(),
                "'show' command expects a pid number or a process name"
            );
        }
        e if e.starts_with("kill ") => {
            let tmp: Vec<&str> = e.split(' ').collect();

            if tmp.len() != 3 {
                writeln!(
                    &mut io::stdout(),
                    "kill command takes the pid and a signal number in parameter !"
                );
                writeln!(&mut io::stdout(), "example: kill 1254 9");
            } else {
                let pid = Pid::from_str(tmp[1]).unwrap();
                let signal = i32::from_str(tmp[2]).unwrap();

                if signal < 1 || signal > 31 {
                    writeln!(
                        &mut io::stdout(),
                        "Signal must be between 0 and 32 ! See the signals list with the \
                         signals command"
                    );
                } else {
                    match sys.get_process(pid) {
                        Some(p) => {
                            writeln!(
                                &mut io::stdout(),
                                "kill: {}",
                                p.kill(*signals.get(signal as usize - 1).unwrap())
                            );
                        }
                        None => {
                            writeln!(&mut io::stdout(), "pid not found");
                        }
                    };
                }
            }
        }
        "disks" => {
            for disk in sys.get_disks() {
                writeln!(&mut io::stdout(), "{:?}", disk);
            }
        }
        "users" => {
            for user in sys.get_users() {
                writeln!(&mut io::stdout(), "{:?}", user.get_name());
            }
        }
        "boot_time" => {
            writeln!(&mut io::stdout(), "{} seconds", sys.get_boot_time());
        }
        "uptime" => {
            let up = sys.get_uptime();
            let mut uptime = sys.get_uptime();
            let days = uptime / 86400;
            uptime -= days * 86400;
            let hours = uptime / 3600;
            uptime -= hours * 3600;
            let minutes = uptime / 60;
            writeln!(
                &mut io::stdout(),
                "{} days {} hours {} minutes ({} seconds in total)",
                days,
                hours,
                minutes,
                up,
            );
        }
        x if x.starts_with("refresh") => {
            if x == "refresh" {
                writeln!(&mut io::stdout(), "Getting processes' information...");
                sys.refresh_all();
                writeln!(&mut io::stdout(), "Done.");
            } else if x.starts_with("refresh ") {
                writeln!(&mut io::stdout(), "Getting process' information...");
                if let Some(pid) = x
                    .split(' ')
                    .filter_map(|pid| pid.parse().ok())
                    .take(1)
                    .next()
                {
                    if sys.refresh_process(pid) {
                        writeln!(&mut io::stdout(), "Process `{}` updated successfully", pid);
                    } else {
                        writeln!(
                            &mut io::stdout(),
                            "Process `{}` couldn't be updated...",
                            pid
                        );
                    }
                } else {
                    writeln!(&mut io::stdout(), "Invalid [pid] received...");
                }
            } else {
                writeln!(
                    &mut io::stdout(),
                    "\"{}\": Unknown command. Enter 'help' if you want to get the commands' \
                     list.",
                    x
                );
            }
        }
        "pid" => {
            writeln!(
                &mut io::stdout(),
                "PID: {}",
                sysinfo::get_current_pid().expect("failed to get PID")
            );
        }
        "system" => {
            writeln!(
                &mut io::stdout(),
                "System name:           {}\n\
                System kernel version: {}\n\
                System OS version:     {}\n\
                System host name:      {}",
                sys.get_name().unwrap_or_else(|| "<unknown>".to_owned()),
                sys.get_kernel_version()
                    .unwrap_or_else(|| "<unknown>".to_owned()),
                sys.get_os_version()
                    .unwrap_or_else(|| "<unknown>".to_owned()),
                sys.get_host_name()
                    .unwrap_or_else(|| "<unknown>".to_owned()),
            );
        }
        e => {
            writeln!(
                &mut io::stdout(),
                "\"{}\": Unknown command. Enter 'help' if you want to get the commands' \
                 list.",
                e
            );
        }
    }
    false
}

fn main() {
    println!("Getting processes' information...");
    let mut t = System::new_all();
    println!("Done.");
    let t_stin = io::stdin();
    let mut stin = t_stin.lock();
    let mut done = false;

    println!("To get the commands' list, enter 'help'.");
    while !done {
        let mut input = String::new();
        write!(&mut io::stdout(), "> ");
        io::stdout().flush();

        stin.read_line(&mut input);
        if input.is_empty() {
            // The string is empty, meaning there is no '\n', meaning
            // that the user used CTRL+D so we can just quit!
            println!("\nLeaving, bye!");
            break;
        }
        if (&input as &str).ends_with('\n') {
            input.pop();
        }
        done = interpret_input(input.as_ref(), &mut t);
    }
}
<|endoftext|>


<commit_before>//! Example of using urlencoded
extern crate iron;
extern crate urlencoded;

use std::io::net::ip::Ipv4Addr;

use iron::{Iron, ServerT, Request, Response, Alloy, Chain};
use iron::middleware::{Status, Continue, FromFn};

use urlencoded::{UrlEncoded, Encoded};

// urlencoded returns a Hashmap
// Here we create a function to log the hashmap we are storing in Alloy.
// Alloy is where your middleware can store data and we access it through
// the `find` API exposed by alloy.
fn log_hashmap( _ : &mut Request, _ : &mut Response, alloy: &mut Alloy) -> Status {
    let hashmap = alloy.find::<Encoded>();
    match hashmap {
        Some(&Encoded(ref encoded)) => println!("Url Encoded:\n {}", encoded),
        None => ()
    }
    Continue
}

// test out the server with `curl -i "127.0.0.1:3000/?name=franklin&name=trevor"`
fn main() {
    let mut server: ServerT = Iron::new();
    server.chain.link(UrlEncoded::new());
    server.chain.link(FromFn::new(log_hashmap));
    server.listen(Ipv4Addr(127, 0, 0, 1), 3000);
}
<commit_msg>(fix) Updated for ServerT removal<commit_after>//! Example of using urlencoded
extern crate iron;
extern crate urlencoded;

use std::io::net::ip::Ipv4Addr;

use iron::{Iron, Server, Request, Response, Alloy, Chain, Status, Continue, FromFn};
use urlencoded::{UrlEncoded, Encoded};

// urlencoded returns a Hashmap
// Here we create a function to log the hashmap we are storing in Alloy.
// Alloy is where your middleware can store data and we access it through
// the `find` API exposed by alloy.
fn log_hashmap( _ : &mut Request, _ : &mut Response, alloy: &mut Alloy) -> Status {
    let hashmap = alloy.find::<Encoded>();
    match hashmap {
        Some(&Encoded(ref encoded)) => println!("Url Encoded:\n {}", encoded),
        None => ()
    }
    Continue
}

// test out the server with `curl -i "127.0.0.1:3000/?name=franklin&name=trevor"`
fn main() {
    let mut server: ServerT = Iron::new();
    server.chain.link(UrlEncoded::new());
    server.chain.link(FromFn::new(log_hashmap));
    server.listen(Ipv4Addr(127, 0, 0, 1), 3000);
}
<|endoftext|>


<commit_before>// FIXME: disallow preemption to work around https://github.com/rust-lang/rust/issues/55005
//@compile-flags: -Zmiri-ignore-leaks -Zmiri-preemption-rate=0

//! Test that leaking threads works, and that their destructors are not executed.

use std::cell::RefCell;

struct LoudDrop(i32);
impl Drop for LoudDrop {
    fn drop(&mut self) {
        eprintln!("Dropping {}", self.0);
    }
}

thread_local! {
    static X: RefCell<Option<LoudDrop>> = RefCell::new(None);
}

fn main() {
    X.with(|x| *x.borrow_mut() = Some(LoudDrop(0)));

    // Set up a channel so that we can learn when the other thread initialized `X`
    // (so that we are sure there is something to drop).
    let (send, recv) = std::sync::mpsc::channel::<()>();

    let _detached = std::thread::spawn(move || {
        X.with(|x| *x.borrow_mut() = Some(LoudDrop(1)));
        send.send(()).unwrap();
        std::thread::yield_now();
        loop {}
    });

    std::thread::yield_now();

    // Wait until child thread has initialized its `X`.
    let () = recv.recv().unwrap();
}
<commit_msg>threadleak_ignored should now pass with preemption (the issue has been fixed a while ago)<commit_after>//@compile-flags: -Zmiri-ignore-leaks

//! Test that leaking threads works, and that their destructors are not executed.

use std::cell::RefCell;

struct LoudDrop(i32);
impl Drop for LoudDrop {
    fn drop(&mut self) {
        eprintln!("Dropping {}", self.0);
    }
}

thread_local! {
    static X: RefCell<Option<LoudDrop>> = RefCell::new(None);
}

fn main() {
    X.with(|x| *x.borrow_mut() = Some(LoudDrop(0)));

    // Set up a channel so that we can learn when the other thread initialized `X`
    // (so that we are sure there is something to drop).
    let (send, recv) = std::sync::mpsc::channel::<()>();

    let _detached = std::thread::spawn(move || {
        X.with(|x| *x.borrow_mut() = Some(LoudDrop(1)));
        send.send(()).unwrap();
        std::thread::yield_now();
        loop {}
    });

    std::thread::yield_now();

    // Wait until child thread has initialized its `X`.
    let () = recv.recv().unwrap();
}
<|endoftext|>