<commit_before>//! # The Redox OS Kernel, version 2
//!
//! The Redox OS Kernel is a microkernel that supports X86_64 systems and
//! provides Unix-like syscalls for primarily Rust applications

//#![deny(warnings)]
#![feature(alloc)]
#![feature(allocator_api)]
#![feature(asm)]
#![feature(collections)]
#![feature(concat_idents)]
#![feature(conservative_impl_trait)]
#![feature(const_atomic_usize_new)]
#![feature(const_fn)]
#![feature(const_max_value)]
#![feature(core_intrinsics)]
#![feature(drop_types_in_const)]
#![feature(global_allocator)]
#![feature(integer_atomics)]
#![feature(lang_items)]
#![feature(naked_functions)]
#![feature(never_type)]
#![feature(thread_local)]
#![feature(unique)]
#![feature(const_size_of)]
#![no_std]

extern crate alloc_kernel as allocator;
pub extern crate x86;

extern crate alloc;
#[macro_use]
extern crate collections;

#[macro_use]
extern crate bitflags;
extern crate goblin;
extern crate spin;

use alloc::arc::Arc;
use core::sync::atomic::{AtomicUsize, ATOMIC_USIZE_INIT, Ordering};
use spin::Mutex;

use scheme::FileHandle;

pub use consts::*;

#[macro_use]
/// Shared data structures
pub mod common;

/// Architecture-dependent stuff
#[macro_use]
pub mod arch;
pub use arch::*;

/// Constants like memory locations
pub mod consts;

/// ACPI table parsing
mod acpi;

/// Context management
pub mod context;

/// Architecture-independent devices
pub mod devices;

/// ELF file parsing
#[cfg(not(feature="doc"))]
pub mod elf;

/// External functions
pub mod externs;

/// Memory management
pub mod memory;

/// Panic
#[cfg(not(any(feature="doc", test)))]
pub mod panic;

/// Schemes, filesystem handlers
pub mod scheme;

/// Synchronization primitives
pub mod sync;

/// Syscall handlers
pub mod syscall;

/// Time
pub mod time;

/// Tests
#[cfg(test)]
pub mod tests;

#[global_allocator]
static ALLOCATOR: allocator::Allocator = allocator::Allocator;

/// A unique number that identifies the current CPU - used for scheduling
#[thread_local]
static CPU_ID: AtomicUsize = ATOMIC_USIZE_INIT;

/// Get the current CPU's scheduling ID
#[inline(always)]
pub fn cpu_id() -> usize {
    CPU_ID.load(Ordering::Relaxed)
}

/// The count of all CPUs that can have work scheduled
static CPU_COUNT : AtomicUsize = ATOMIC_USIZE_INIT;

/// Get the number of CPUs currently active
#[inline(always)]
pub fn cpu_count() -> usize {
    CPU_COUNT.load(Ordering::Relaxed)
}

/// Initialize userspace by running the initfs:bin/init process
/// This function will also set the CWD to initfs:bin and open debug: as stdio
pub extern fn userspace_init() {
    assert_eq!(syscall::chdir(b"initfs:"), Ok(0));

    assert_eq!(syscall::open(b"debug:", syscall::flag::O_RDONLY).map(FileHandle::into), Ok(0));
    assert_eq!(syscall::open(b"debug:", syscall::flag::O_WRONLY).map(FileHandle::into), Ok(1));
    assert_eq!(syscall::open(b"debug:", syscall::flag::O_WRONLY).map(FileHandle::into), Ok(2));

    syscall::exec(b"/bin/init", &[]).expect("failed to execute init");

    panic!("init returned");
}

/// This is the kernel entry point for the primary CPU. The arch crate is responsible for calling this
pub fn kmain(cpus: usize, env: &[u8]) -> ! {
    CPU_ID.store(0, Ordering::SeqCst);
    CPU_COUNT.store(cpus, Ordering::SeqCst);

    context::init();

    let pid = syscall::getpid();
    println!("BSP: {:?} {}", pid, cpus);
    println!("Env: {:?}", ::core::str::from_utf8(env));

    match context::contexts_mut().spawn(userspace_init) {
        Ok(context_lock) => {
            let mut context = context_lock.write();
            context.status = context::Status::Runnable;

            let mut context_env = context.env.lock();
            for line in env.split(|b| *b == b'\n') {
                let mut parts = line.splitn(2, |b| *b == b'=');
                if let Some(name) = parts.next() {
                    if let Some(data) = parts.next() {
                        context_env.insert(
                            name.to_vec().into_boxed_slice(),
                            Arc::new(Mutex::new(data.to_vec()))
                        );
                    }
                }
            }
        },
        Err(err) => {
            panic!("failed to spawn userspace_init: {:?}", err);
        }
    }

    loop {
        unsafe {
            interrupt::disable();
            if context::switch() {
                interrupt::enable_and_nop();
            } else {
                // Enable interrupts, then halt CPU (to save power) until the next interrupt is actually fired.
                interrupt::enable_and_halt();
            }
        }
    }
}

/// This is the main kernel entry point for secondary CPUs
#[allow(unreachable_code, unused_variables)]
pub fn kmain_ap(id: usize) -> ! {
    CPU_ID.store(id, Ordering::SeqCst);

    if cfg!(feature = "multi_core"){
        context::init();

        let pid = syscall::getpid();
        println!("AP {}: {:?}", id, pid);

        loop {
            unsafe {
                interrupt::disable();
                if context::switch() {
                    interrupt::enable_and_nop();
                } else {
                    // Enable interrupts, then halt CPU (to save power) until the next interrupt is actually fired.
                    interrupt::enable_and_halt();
                }
            }
        }
    } else {
        println!("AP {}: Disabled", id);

        loop {
            unsafe {
                interrupt::disable();
                interrupt::halt();
            }
        }
    }
}

/// Allow exception handlers to send signal to arch-independant kernel
#[no_mangle]
pub extern fn ksignal(signal: usize) {
    println!("SIGNAL {}, CPU {}, PID {:?}", signal, cpu_id(), context::context_id());
    {
        let contexts = context::contexts();
        if let Some(context_lock) = contexts.current() {
            let context = context_lock.read();
            println!("NAME {}", unsafe { ::core::str::from_utf8_unchecked(&context.name.lock()) });
        }
    }
    syscall::exit(signal & 0x7F);
}
<commit_msg>Set init namespace to 1<commit_after>//! # The Redox OS Kernel, version 2
//!
//! The Redox OS Kernel is a microkernel that supports X86_64 systems and
//! provides Unix-like syscalls for primarily Rust applications

//#![deny(warnings)]
#![feature(alloc)]
#![feature(allocator_api)]
#![feature(asm)]
#![feature(collections)]
#![feature(concat_idents)]
#![feature(conservative_impl_trait)]
#![feature(const_atomic_usize_new)]
#![feature(const_fn)]
#![feature(const_max_value)]
#![feature(core_intrinsics)]
#![feature(drop_types_in_const)]
#![feature(global_allocator)]
#![feature(integer_atomics)]
#![feature(lang_items)]
#![feature(naked_functions)]
#![feature(never_type)]
#![feature(thread_local)]
#![feature(unique)]
#![feature(const_size_of)]
#![no_std]

extern crate alloc_kernel as allocator;
pub extern crate x86;

extern crate alloc;
#[macro_use]
extern crate collections;

#[macro_use]
extern crate bitflags;
extern crate goblin;
extern crate spin;

use alloc::arc::Arc;
use core::sync::atomic::{AtomicUsize, ATOMIC_USIZE_INIT, Ordering};
use spin::Mutex;

use scheme::{FileHandle, SchemeNamespace};

pub use consts::*;

#[macro_use]
/// Shared data structures
pub mod common;

/// Architecture-dependent stuff
#[macro_use]
pub mod arch;
pub use arch::*;

/// Constants like memory locations
pub mod consts;

/// ACPI table parsing
mod acpi;

/// Context management
pub mod context;

/// Architecture-independent devices
pub mod devices;

/// ELF file parsing
#[cfg(not(feature="doc"))]
pub mod elf;

/// External functions
pub mod externs;

/// Memory management
pub mod memory;

/// Panic
#[cfg(not(any(feature="doc", test)))]
pub mod panic;

/// Schemes, filesystem handlers
pub mod scheme;

/// Synchronization primitives
pub mod sync;

/// Syscall handlers
pub mod syscall;

/// Time
pub mod time;

/// Tests
#[cfg(test)]
pub mod tests;

#[global_allocator]
static ALLOCATOR: allocator::Allocator = allocator::Allocator;

/// A unique number that identifies the current CPU - used for scheduling
#[thread_local]
static CPU_ID: AtomicUsize = ATOMIC_USIZE_INIT;

/// Get the current CPU's scheduling ID
#[inline(always)]
pub fn cpu_id() -> usize {
    CPU_ID.load(Ordering::Relaxed)
}

/// The count of all CPUs that can have work scheduled
static CPU_COUNT : AtomicUsize = ATOMIC_USIZE_INIT;

/// Get the number of CPUs currently active
#[inline(always)]
pub fn cpu_count() -> usize {
    CPU_COUNT.load(Ordering::Relaxed)
}

/// Initialize userspace by running the initfs:bin/init process
/// This function will also set the CWD to initfs:bin and open debug: as stdio
pub extern fn userspace_init() {
    assert_eq!(syscall::chdir(b"initfs:"), Ok(0));

    assert_eq!(syscall::open(b"debug:", syscall::flag::O_RDONLY).map(FileHandle::into), Ok(0));
    assert_eq!(syscall::open(b"debug:", syscall::flag::O_WRONLY).map(FileHandle::into), Ok(1));
    assert_eq!(syscall::open(b"debug:", syscall::flag::O_WRONLY).map(FileHandle::into), Ok(2));

    syscall::exec(b"/bin/init", &[]).expect("failed to execute init");

    panic!("init returned");
}

/// This is the kernel entry point for the primary CPU. The arch crate is responsible for calling this
pub fn kmain(cpus: usize, env: &[u8]) -> ! {
    CPU_ID.store(0, Ordering::SeqCst);
    CPU_COUNT.store(cpus, Ordering::SeqCst);

    context::init();

    let pid = syscall::getpid();
    println!("BSP: {:?} {}", pid, cpus);
    println!("Env: {:?}", ::core::str::from_utf8(env));

    match context::contexts_mut().spawn(userspace_init) {
        Ok(context_lock) => {
            let mut context = context_lock.write();
            context.rns = SchemeNamespace::from(1);
            context.ens = SchemeNamespace::from(1);
            context.status = context::Status::Runnable;

            let mut context_env = context.env.lock();
            for line in env.split(|b| *b == b'\n') {
                let mut parts = line.splitn(2, |b| *b == b'=');
                if let Some(name) = parts.next() {
                    if let Some(data) = parts.next() {
                        context_env.insert(
                            name.to_vec().into_boxed_slice(),
                            Arc::new(Mutex::new(data.to_vec()))
                        );
                    }
                }
            }
        },
        Err(err) => {
            panic!("failed to spawn userspace_init: {:?}", err);
        }
    }

    loop {
        unsafe {
            interrupt::disable();
            if context::switch() {
                interrupt::enable_and_nop();
            } else {
                // Enable interrupts, then halt CPU (to save power) until the next interrupt is actually fired.
                interrupt::enable_and_halt();
            }
        }
    }
}

/// This is the main kernel entry point for secondary CPUs
#[allow(unreachable_code, unused_variables)]
pub fn kmain_ap(id: usize) -> ! {
    CPU_ID.store(id, Ordering::SeqCst);

    if cfg!(feature = "multi_core"){
        context::init();

        let pid = syscall::getpid();
        println!("AP {}: {:?}", id, pid);

        loop {
            unsafe {
                interrupt::disable();
                if context::switch() {
                    interrupt::enable_and_nop();
                } else {
                    // Enable interrupts, then halt CPU (to save power) until the next interrupt is actually fired.
                    interrupt::enable_and_halt();
                }
            }
        }
    } else {
        println!("AP {}: Disabled", id);

        loop {
            unsafe {
                interrupt::disable();
                interrupt::halt();
            }
        }
    }
}

/// Allow exception handlers to send signal to arch-independant kernel
#[no_mangle]
pub extern fn ksignal(signal: usize) {
    println!("SIGNAL {}, CPU {}, PID {:?}", signal, cpu_id(), context::context_id());
    {
        let contexts = context::contexts();
        if let Some(context_lock) = contexts.current() {
            let context = context_lock.read();
            println!("NAME {}", unsafe { ::core::str::from_utf8_unchecked(&context.name.lock()) });
        }
    }
    syscall::exit(signal & 0x7F);
}
<|endoftext|>


<commit_before>//! **rosc** is an implementation of the [OSC 1.0](http://opensoundcontrol.org/spec-1_0) protocol in pure Rust.
//!

#![cfg_attr(not(feature = "std"), no_std)]

#[cfg(not(feature = "std"))]
#[macro_use] extern crate alloc;

#[cfg(feature = "std")]
extern crate std as core;
#[cfg(feature = "std")]
#[macro_use] extern crate std as alloc;

extern crate nom;
extern crate byteorder;
#[cfg(feature = "std")]
extern crate regex;

/// Crate specific error types.
mod errors;
/// OSC data types, see [OSC 1.0 specification](https://opensoundcontrol.stanford.edu/spec-1_0.html) for details.
mod types;

pub use crate::errors::*;
pub use crate::types::*;

/// Provides a decoding method for OSC packets.
pub mod decoder;
/// Encodes an `OscPacket` to a byte vector.
pub mod encoder;
/// Address checking and matching methods
#[cfg(feature = "std")]
pub mod address;
<commit_msg>Remove regex dependency<commit_after>//! **rosc** is an implementation of the [OSC 1.0](http://opensoundcontrol.org/spec-1_0) protocol in pure Rust.
//!

#![cfg_attr(not(feature = "std"), no_std)]

#[cfg(not(feature = "std"))]
#[macro_use] extern crate alloc;

#[cfg(feature = "std")]
extern crate std as core;
#[cfg(feature = "std")]
#[macro_use] extern crate std as alloc;

extern crate nom;
extern crate byteorder;

/// Crate specific error types.
mod errors;
/// OSC data types, see [OSC 1.0 specification](https://opensoundcontrol.stanford.edu/spec-1_0.html) for details.
mod types;

pub use crate::errors::*;
pub use crate::types::*;

/// Provides a decoding method for OSC packets.
pub mod decoder;
/// Encodes an `OscPacket` to a byte vector.
pub mod encoder;
/// Address checking and matching methods
#[cfg(feature = "std")]
pub mod address;
<|endoftext|>


<commit_before>// Copyright 2015 Corey Farwell
// Copyright 2015 Contributors of github.com/huonw/crates.io-graph
//
// 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.

use std::collections::HashMap;
use std::fs;
use std::io::{BufRead, BufReader};
use std::path::PathBuf;

extern crate git2;
extern crate glob;
extern crate rustc_serialize;

static INDEX_GIT_URL: &'static str = "https://github.com/rust-lang/crates.io-index";

#[derive(RustcDecodable)]
pub struct CrateInfo {
    pub name: String,
    pub vers: String,
    pub deps: Vec<DepInfo>,
    pub cksum: String,
    pub features: HashMap<String, Vec<String>>,
    pub yanked: bool,
}

#[derive(RustcDecodable)]
pub struct DepInfo {
    pub name: String,
    pub req: String,
    pub features: Vec<String>,
    pub optional: bool,
    pub default_features: bool,
    pub target: Option<String>,
    pub kind: Option<String>
}

pub struct CratesIndex {
    path: PathBuf,
}

impl CratesIndex {
    /// Construct a new CratesIndex supplying a path where the index lives or should live
    pub fn new(path: PathBuf) -> CratesIndex {
        CratesIndex{path: path}
    }

    /// Determines if *anything* exists at the path specified from the constructor
    pub fn exists(&self) -> bool {
        fs::metadata(&self.path).is_ok()
    }

    /// Clones the index to the path specified from the constructor
    pub fn clone_index(&self) -> Result<(), git2::Error> {
        let _ = try!(git2::Repository::clone(INDEX_GIT_URL, &self.path));
        Ok(())
    }

    /// Returns all the `.json` files in the index
    pub fn json_paths(&self) -> Vec<PathBuf> {
        let mut match_options = glob::MatchOptions::new();
        match_options.require_literal_leading_dot = true;

        let glob_pattern = format!("{}/*/*/*", self.path.to_str().unwrap());
        let index_paths1 = glob::glob_with(&glob_pattern, &match_options).unwrap();

        let glob_pattern = format!("{}/[12]/*", self.path.to_str().unwrap());
        let index_paths2 = glob::glob_with(&glob_pattern, &match_options).unwrap();

        let index_paths = index_paths1.chain(index_paths2);
        index_paths.map(|glob_result| glob_result.unwrap()).collect()
    }

    /// Generates a map of dependencies where the keys are crate names and the values are vectors
    /// of crate names that are its dependencies
    pub fn dependency_map(&self) -> HashMap<String, Vec<String>> {
        let mut map = HashMap::new();
        for index_path in self.json_paths() {
            let file = fs::File::open(&index_path).unwrap();
            let last_line = BufReader::new(file).lines().last().unwrap().unwrap();
            let crate_info: CrateInfo = rustc_serialize::json::decode(&last_line).unwrap();
            let mut deps_names = crate_info.deps.iter().map(|d| d.name.clone()).collect::<Vec<_>>();
            deps_names.sort_by(|a, b| a.cmp(b));
            deps_names.dedup();
            map.insert(crate_info.name, deps_names);
        }

        map
    }
}
<commit_msg>Remove redundant suffix on CratesIndex::clone_index<commit_after>// Copyright 2015 Corey Farwell
// Copyright 2015 Contributors of github.com/huonw/crates.io-graph
//
// 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.

use std::collections::HashMap;
use std::fs;
use std::io::{BufRead, BufReader};
use std::path::PathBuf;

extern crate git2;
extern crate glob;
extern crate rustc_serialize;

static INDEX_GIT_URL: &'static str = "https://github.com/rust-lang/crates.io-index";

#[derive(RustcDecodable)]
pub struct CrateInfo {
    pub name: String,
    pub vers: String,
    pub deps: Vec<DepInfo>,
    pub cksum: String,
    pub features: HashMap<String, Vec<String>>,
    pub yanked: bool,
}

#[derive(RustcDecodable)]
pub struct DepInfo {
    pub name: String,
    pub req: String,
    pub features: Vec<String>,
    pub optional: bool,
    pub default_features: bool,
    pub target: Option<String>,
    pub kind: Option<String>
}

pub struct CratesIndex {
    path: PathBuf,
}

impl CratesIndex {
    /// Construct a new CratesIndex supplying a path where the index lives or should live
    pub fn new(path: PathBuf) -> CratesIndex {
        CratesIndex{path: path}
    }

    /// Determines if *anything* exists at the path specified from the constructor
    pub fn exists(&self) -> bool {
        fs::metadata(&self.path).is_ok()
    }

    /// Clones the index to the path specified from the constructor
    pub fn clone(&self) -> Result<(), git2::Error> {
        let _ = try!(git2::Repository::clone(INDEX_GIT_URL, &self.path));
        Ok(())
    }

    /// Returns all the `.json` files in the index
    pub fn json_paths(&self) -> Vec<PathBuf> {
        let mut match_options = glob::MatchOptions::new();
        match_options.require_literal_leading_dot = true;

        let glob_pattern = format!("{}/*/*/*", self.path.to_str().unwrap());
        let index_paths1 = glob::glob_with(&glob_pattern, &match_options).unwrap();

        let glob_pattern = format!("{}/[12]/*", self.path.to_str().unwrap());
        let index_paths2 = glob::glob_with(&glob_pattern, &match_options).unwrap();

        let index_paths = index_paths1.chain(index_paths2);
        index_paths.map(|glob_result| glob_result.unwrap()).collect()
    }

    /// Generates a map of dependencies where the keys are crate names and the values are vectors
    /// of crate names that are its dependencies
    pub fn dependency_map(&self) -> HashMap<String, Vec<String>> {
        let mut map = HashMap::new();
        for index_path in self.json_paths() {
            let file = fs::File::open(&index_path).unwrap();
            let last_line = BufReader::new(file).lines().last().unwrap().unwrap();
            let crate_info: CrateInfo = rustc_serialize::json::decode(&last_line).unwrap();
            let mut deps_names = crate_info.deps.iter().map(|d| d.name.clone()).collect::<Vec<_>>();
            deps_names.sort_by(|a, b| a.cmp(b));
            deps_names.dedup();
            map.insert(crate_info.name, deps_names);
        }

        map
    }
}
<|endoftext|>


<commit_before>macro_rules! swrite {
    (@one $writer:expr, ($e:expr)) => { write!($writer, "{}", $e) };
    (@one $writer:expr, [$e:expr]) => { write!($writer, "{:?}", $e) };
    (@one $writer:expr, {$e:tt : $($fmt:tt)*}) => {
        write!($writer, concat!("{:", stringify!($($fmt)*), "}"), $e)
    };
    (@one $writer:expr, {$($arg:tt)*}) => {
        write!($writer, $($arg)*)
    };
    (@one $writer:expr, $string:tt) => {
        write!($writer, "{}", { let s: &str = $string; s })
    };
    ($writer:expr, $($part:tt)*) => {
        (||{
            let mut _w = $writer;
            $(
                match swrite!(@one _w, $part) {
                    Ok(()) => (),
                    error => return error,
                }
            )*
            Ok(())
        })()
    };
    ($writer:expr) => { swrite!($writer,) };
}

macro_rules! swriteln {
    ($($arg:tt)*) => { swrite!($($arg)* "\n") }
}

macro_rules! sprint {
    ($($arg:tt)*) => { {
        use ::std::io::Write;
        let o = ::std::io::stdout();
        swrite!(o.lock(), $($arg)*).unwrap();
    } }
}

macro_rules! sprintln {
    ($($arg:tt)*) => { sprint!($($arg)* "\n") }
}

macro_rules! sformat {
    () => { String::new() };
    ($($arg:tt)*) => { {
        use ::std::fmt::Write;
        let mut _s = String::new(); // TODO with capacity
        swrite!(&mut _s, $($arg)*).ok();
        _s
    } }
}

#[test]
fn basics() {
    let world = "World";
    assert_eq!(sformat!("Hello, "(world)"!"), "Hello, World!");
    let x = 3;
    assert_eq!(sformat!((x)" * 2 = "(x * 2)), "3 * 2 = 6");
}

#[test]
fn empty() {
    assert_eq!(sformat!(), "");
}

#[test]
fn vec() {
    let v = vec![1,2,3];
    assert_eq!(sformat!([v]), "[1, 2, 3]");
}

#[test]
fn write() {
    use std::io::Write;
    let mut v = Vec::new();
    swriteln!(&mut v, "hi" "!").unwrap();
    assert_eq!(v, "hi!\n".as_bytes());
}

#[test]
fn format() {
    assert_eq!( sformat!({5:02}), "05" );
    assert_eq!( sformat!({"{}-{}", 4, 2}), "4-2" );
}

#[test]
fn hello() {
    let foo = "foo";
    let x = 2;
    let y = 4;
    sprintln!("Bar "(foo)" and "(x));
    sprintln!( (x)"<"(y) );
}
<commit_msg>add sprerr and sprerrln<commit_after>macro_rules! swrite {
    (@one $writer:expr, ($e:expr)) => { write!($writer, "{}", $e) };
    (@one $writer:expr, [$e:expr]) => { write!($writer, "{:?}", $e) };
    (@one $writer:expr, {$e:tt : $($fmt:tt)*}) => {
        write!($writer, concat!("{:", stringify!($($fmt)*), "}"), $e)
    };
    (@one $writer:expr, {$($arg:tt)*}) => {
        write!($writer, $($arg)*)
    };
    (@one $writer:expr, $string:tt) => {
        write!($writer, "{}", { let s: &str = $string; s })
    };
    ($writer:expr, $($part:tt)*) => {
        (||{
            let mut _w = $writer;
            $(
                match swrite!(@one _w, $part) {
                    Ok(()) => (),
                    error => return error,
                }
            )*
            Ok(())
        })()
    };
    ($writer:expr) => { swrite!($writer,) };
}

macro_rules! swriteln {
    ($($arg:tt)*) => { swrite!($($arg)* "\n") }
}

macro_rules! sprint {
    ($($arg:tt)*) => { {
        use ::std::io::Write;
        let o = ::std::io::stdout();
        swrite!(o.lock(), $($arg)*).unwrap();
    } }
}

macro_rules! sprintln {
    ($($arg:tt)*) => { sprint!($($arg)* "\n") }
}

macro_rules! sprerr {
    ($($arg:tt)*) => { {
        use ::std::io::Write;
        let o = ::std::io::stderr();
        swrite!(o.lock(), $($arg)*).unwrap();
    } }
}

macro_rules! sprerrln {
    ($($arg:tt)*) => { sprerr!($($arg)* "\n") }
}

macro_rules! sformat {
    () => { String::new() };
    ($($arg:tt)*) => { {
        use ::std::fmt::Write;
        let mut _s = String::new(); // TODO with capacity
        swrite!(&mut _s, $($arg)*).ok();
        _s
    } }
}

#[test]
fn basics() {
    let world = "World";
    assert_eq!(sformat!("Hello, "(world)"!"), "Hello, World!");
    let x = 3;
    assert_eq!(sformat!((x)" * 2 = "(x * 2)), "3 * 2 = 6");
}

#[test]
fn empty() {
    assert_eq!(sformat!(), "");
}

#[test]
fn vec() {
    let v = vec![1,2,3];
    assert_eq!(sformat!([v]), "[1, 2, 3]");
}

#[test]
fn write() {
    use std::io::Write;
    let mut v = Vec::new();
    swriteln!(&mut v, "hi" "!").unwrap();
    assert_eq!(v, "hi!\n".as_bytes());
}

#[test]
fn format() {
    assert_eq!( sformat!({5:02}), "05" );
    assert_eq!( sformat!({"{}-{}", 4, 2}), "4-2" );
}

#[test]
fn hello() {
    let foo = "foo";
    let x = 2;
    let y = 4;
    sprintln!("Bar "(foo)" and "(x));
    sprintln!( (x)"<"(y) );
}
<|endoftext|>


<commit_before>#![feature(libc, int_uint, core, unique)]

extern crate libc;

use std::ptr::{self, Unique};
use std::ffi::{CStr,CString};
use std::default::Default;
use std::mem::transmute;
use std::slice::SliceExt;
use std::raw::Slice;
use std::ops::Deref;
use std::str;
mod raw;

/// An iterator over devices that pcap is aware about on the system.
pub struct Devices {
    orig: Unique<raw::Struct_pcap_if>,
    device: Unique<raw::Struct_pcap_if>
}

impl Devices {
    /// Construct a new `Devices` iterator by internally using `pcap_findalldevs()`
    pub fn list_all() -> Result<Devices, String> {
        unsafe {
            let mut errbuf = [0i8; 256];
            let mut dev_buf: *mut raw::Struct_pcap_if = ptr::null_mut();

            match raw::pcap_findalldevs(&mut dev_buf, errbuf.as_mut_ptr()) {
                0 => {
                    Ok(Devices {
                        orig: Unique::new(dev_buf),
                        device: Unique::new(dev_buf)
                    })
                },
                _ => {
                    Err(
                        cstr_to_string(errbuf.as_ptr()).unwrap()
                    )
                }
            }
        }
    }
}

impl Drop for Devices {
    fn drop(&mut self) {
        unsafe {
            raw::pcap_freealldevs(*self.orig);
        }
    }
}

#[derive(Debug)]
/// A network device as constructed with `Device::new()` or returned from `Devices::list_all()`.
pub struct Device {
    pub name: String,
    pub desc: Option<String>
}

impl Device {
    /// Create a new device with a given name, useful when you know the name of the device already.
    pub fn new(name: &str) -> Device {
        Device {
            name: name.to_string(),
            desc: None
        }
    }

    /// Open a `Capture` for this network device.
    pub fn open(&self) -> Result<Capture, String> {
        let name = CString::new(&self.name[..]).unwrap();
        let mut errbuf = [0i8; 256];

        unsafe {
            let pcap_t = raw::pcap_open_live(name.as_ptr(), 65535, 1, 0, errbuf.as_mut_ptr());
            if pcap_t.is_null() {
                Err(
                    cstr_to_string(errbuf.as_ptr()).unwrap()
                )
            } else {
                Ok(Capture{
                    handle: Unique::new(pcap_t)
                })
            }
        }
    }
}

/// A packet obtained from a `Capture`.
///
/// This can be dereferenced to access the raw packet data.
pub struct Packet<'a> {
    data: PacketData<'a>
}

impl<'a> Packet<'a> {
    fn new(content: &'a [u8]) -> Packet<'a> {
        Packet {
            data: PacketData::Borrowed(content)
        }
    }

    fn alloc(mut self) -> Packet<'a> {
        self.data = PacketData::Allocated(self.to_vec());
        self
    }
}

enum PacketData<'a> {
    Allocated(Vec<u8>),
    Borrowed(&'a [u8])
}

impl<'b> Deref for Packet<'b> {
    type Target = [u8];

    fn deref<'a>(&'a self) -> &'a [u8] {
        match self.data {
            PacketData::Allocated(ref v) => {
                v.as_slice()
            },
            PacketData::Borrowed(x) => x
        }
    }
}

/// An iterator over packets obtained from a `Capture` in realtime.
///
/// This iterator will allocate a `Vec<u8>` for each packet it receives. If this
/// is not tolerable, try using `.next()` on `Capture` directly instead of this
/// iterator.
pub struct Packets<'a> {
    capture: &'a mut Capture
}

impl<'a, 'b> Iterator for Packets<'a> {
    type Item = Packet<'b>;

    fn next(&mut self) -> Option<Packet> {
        self.capture.next().map(|x| x.alloc())
    }
}

/// This represents an open capture handle obtained by calling `.open()` on a `Device`.
/// Internally it represents a `pcap_t` handle obtained by `pcap_open_live()`.
pub struct Capture {
    handle: Unique<raw::pcap_t>
}

impl Capture {
    /// Returns an iterator over packets received on this capture handle.
    pub fn listen<'a>(&'a mut self) -> Packets<'a> {
        Packets {
            capture: self
        }
    }

    /// Blocks until a packet is returned from the capture handle or an error occurs.
    pub fn next<'a>(&'a mut self) -> Option<Packet<'a>> {
        unsafe {
            let mut header: *mut raw::Struct_pcap_pkthdr = ptr::null_mut();
            let mut packet: *const libc::c_uchar = ptr::null_mut();
            match raw::pcap_next_ex(*self.handle, &mut header, &mut packet) {
                1 => {
                    // packet was read without issue
                    let packet = transmute::<_, &[u8]>(Slice {
                        data: packet,
                        len: (*header).len as usize
                    });

                    Some(Packet::new(packet))
                },
                _ => {
                    None
                }
            }
        }
    }

    /// Adds a filter to the capture using the given BPF program string. Internally
    /// this is compiled using `pcap_compile()`.
    ///
    /// See http://biot.com/capstats/bpf.html for more information about this syntax.
    pub fn filter(&mut self, program: &str) -> Result<(), String> {
        let program = CString::new(program).unwrap();

        unsafe {
            let mut bpf_program: raw::Struct_bpf_program = Default::default();

            if -1 == raw::pcap_compile(*self.handle, &mut bpf_program, program.as_ptr(), 0, 0) {
                return Err(cstr_to_string(raw::pcap_geterr(*self.handle)).unwrap());
            }

            if -1 == raw::pcap_setfilter(*self.handle, &mut bpf_program) {
                raw::pcap_freecode(&mut bpf_program);
                return Err(cstr_to_string(raw::pcap_geterr(*self.handle)).unwrap());
            }

            raw::pcap_freecode(&mut bpf_program);
            Ok(())
        }
    }
}

impl Drop for Capture {
    fn drop(&mut self) {
        unsafe {
            raw::pcap_close(*self.handle)
        }
    }
}

impl Iterator for Devices {
    type Item = Device;

    fn next(&mut self) -> Option<Device> {
        if self.device.is_null() {
            None
        } else {
            unsafe {
                let ret = Device {
                    name: cstr_to_string(self.device.get().name).unwrap(),
                    desc: {
                        if !self.device.get().description.is_null() {
                            Some(cstr_to_string(self.device.get().description).unwrap())
                        } else {
                            None
                        }
                    }
                };
                self.device = Unique::new(self.device.get().next);

                Some(ret)
            }
        }
    }
}

fn cstr_to_string(ptr: *const libc::c_char) -> Result<String, str::Utf8Error> {
    Ok(try!(str::from_utf8(unsafe{CStr::from_ptr(ptr)}.to_bytes())).to_string())
}<commit_msg>Remove SliceExt<commit_after>#![feature(libc, int_uint, core, unique)]

extern crate libc;

use std::ptr::{self, Unique};
use std::ffi::{CStr,CString};
use std::default::Default;
use std::mem::transmute;
use std::raw::Slice;
use std::ops::Deref;
use std::str;
mod raw;

/// An iterator over devices that pcap is aware about on the system.
pub struct Devices {
    orig: Unique<raw::Struct_pcap_if>,
    device: Unique<raw::Struct_pcap_if>
}

impl Devices {
    /// Construct a new `Devices` iterator by internally using `pcap_findalldevs()`
    pub fn list_all() -> Result<Devices, String> {
        unsafe {
            let mut errbuf = [0i8; 256];
            let mut dev_buf: *mut raw::Struct_pcap_if = ptr::null_mut();

            match raw::pcap_findalldevs(&mut dev_buf, errbuf.as_mut_ptr()) {
                0 => {
                    Ok(Devices {
                        orig: Unique::new(dev_buf),
                        device: Unique::new(dev_buf)
                    })
                },
                _ => {
                    Err(
                        cstr_to_string(errbuf.as_ptr()).unwrap()
                    )
                }
            }
        }
    }
}

impl Drop for Devices {
    fn drop(&mut self) {
        unsafe {
            raw::pcap_freealldevs(*self.orig);
        }
    }
}

#[derive(Debug)]
/// A network device as constructed with `Device::new()` or returned from `Devices::list_all()`.
pub struct Device {
    pub name: String,
    pub desc: Option<String>
}

impl Device {
    /// Create a new device with a given name, useful when you know the name of the device already.
    pub fn new(name: &str) -> Device {
        Device {
            name: name.to_string(),
            desc: None
        }
    }

    /// Open a `Capture` for this network device.
    pub fn open(&self) -> Result<Capture, String> {
        let name = CString::new(&self.name[..]).unwrap();
        let mut errbuf = [0i8; 256];

        unsafe {
            let pcap_t = raw::pcap_open_live(name.as_ptr(), 65535, 1, 0, errbuf.as_mut_ptr());
            if pcap_t.is_null() {
                Err(
                    cstr_to_string(errbuf.as_ptr()).unwrap()
                )
            } else {
                Ok(Capture{
                    handle: Unique::new(pcap_t)
                })
            }
        }
    }
}

/// A packet obtained from a `Capture`.
///
/// This can be dereferenced to access the raw packet data.
pub struct Packet<'a> {
    data: PacketData<'a>
}

impl<'a> Packet<'a> {
    fn new(content: &'a [u8]) -> Packet<'a> {
        Packet {
            data: PacketData::Borrowed(content)
        }
    }

    fn alloc(mut self) -> Packet<'a> {
        self.data = PacketData::Allocated(self.to_vec());
        self
    }
}

enum PacketData<'a> {
    Allocated(Vec<u8>),
    Borrowed(&'a [u8])
}

impl<'b> Deref for Packet<'b> {
    type Target = [u8];

    fn deref<'a>(&'a self) -> &'a [u8] {
        match self.data {
            PacketData::Allocated(ref v) => {
                v.as_slice()
            },
            PacketData::Borrowed(x) => x
        }
    }
}

/// An iterator over packets obtained from a `Capture` in realtime.
///
/// This iterator will allocate a `Vec<u8>` for each packet it receives. If this
/// is not tolerable, try using `.next()` on `Capture` directly instead of this
/// iterator.
pub struct Packets<'a> {
    capture: &'a mut Capture
}

impl<'a, 'b> Iterator for Packets<'a> {
    type Item = Packet<'b>;

    fn next(&mut self) -> Option<Packet> {
        self.capture.next().map(|x| x.alloc())
    }
}

/// This represents an open capture handle obtained by calling `.open()` on a `Device`.
/// Internally it represents a `pcap_t` handle obtained by `pcap_open_live()`.
pub struct Capture {
    handle: Unique<raw::pcap_t>
}

impl Capture {
    /// Returns an iterator over packets received on this capture handle.
    pub fn listen<'a>(&'a mut self) -> Packets<'a> {
        Packets {
            capture: self
        }
    }

    /// Blocks until a packet is returned from the capture handle or an error occurs.
    pub fn next<'a>(&'a mut self) -> Option<Packet<'a>> {
        unsafe {
            let mut header: *mut raw::Struct_pcap_pkthdr = ptr::null_mut();
            let mut packet: *const libc::c_uchar = ptr::null_mut();
            match raw::pcap_next_ex(*self.handle, &mut header, &mut packet) {
                1 => {
                    // packet was read without issue
                    let packet = transmute::<_, &[u8]>(Slice {
                        data: packet,
                        len: (*header).len as usize
                    });

                    Some(Packet::new(packet))
                },
                _ => {
                    None
                }
            }
        }
    }

    /// Adds a filter to the capture using the given BPF program string. Internally
    /// this is compiled using `pcap_compile()`.
    ///
    /// See http://biot.com/capstats/bpf.html for more information about this syntax.
    pub fn filter(&mut self, program: &str) -> Result<(), String> {
        let program = CString::new(program).unwrap();

        unsafe {
            let mut bpf_program: raw::Struct_bpf_program = Default::default();

            if -1 == raw::pcap_compile(*self.handle, &mut bpf_program, program.as_ptr(), 0, 0) {
                return Err(cstr_to_string(raw::pcap_geterr(*self.handle)).unwrap());
            }

            if -1 == raw::pcap_setfilter(*self.handle, &mut bpf_program) {
                raw::pcap_freecode(&mut bpf_program);
                return Err(cstr_to_string(raw::pcap_geterr(*self.handle)).unwrap());
            }

            raw::pcap_freecode(&mut bpf_program);
            Ok(())
        }
    }
}

impl Drop for Capture {
    fn drop(&mut self) {
        unsafe {
            raw::pcap_close(*self.handle)
        }
    }
}

impl Iterator for Devices {
    type Item = Device;

    fn next(&mut self) -> Option<Device> {
        if self.device.is_null() {
            None
        } else {
            unsafe {
                let ret = Device {
                    name: cstr_to_string(self.device.get().name).unwrap(),
                    desc: {
                        if !self.device.get().description.is_null() {
                            Some(cstr_to_string(self.device.get().description).unwrap())
                        } else {
                            None
                        }
                    }
                };
                self.device = Unique::new(self.device.get().next);

                Some(ret)
            }
        }
    }
}

fn cstr_to_string(ptr: *const libc::c_char) -> Result<String, str::Utf8Error> {
    Ok(try!(str::from_utf8(unsafe{CStr::from_ptr(ptr)}.to_bytes())).to_string())
}
<|endoftext|>


<commit_before>//! [![Banner](https://raw.githubusercontent.com/nvzqz/static-assertions-rs/assets/Banner.png)](https://github.com/nvzqz/static-assertions-rs)
//!
//! Compile-time assertions to ensure that invariants are met.
//!
//! _All_ assertions within this crate are performed at [compile-time]. This
//! allows for finding errors quickly and early when it comes to ensuring
//! certain features or aspects of a codebase. These macros are especially
//! important when exposing a public API that requires types to be the same size
//! or implement certain traits.
//!
//! # Usage
//!
//! This crate is available [on crates.io][crate] and can be used by adding the
//! following to your project's [`Cargo.toml`]:
//!
//! ```toml
//! [dependencies]
//! static_assertions = "0.3.4"
//! ```
//!
//! and this to your crate root (`main.rs` or `lib.rs`):
//!
//! ```
//! #[macro_use]
//! extern crate static_assertions;
//! # fn main() {}
//! ```
//!
//! # Examples
//!
//! Very thorough examples are provided in the docs for
//! [each individual macro](#macros). Failure case examples are also documented.
//!
//! # Changes
//!
//! See [`CHANGELOG.md`](https://github.com/nvzqz/static-assertions-rs/blob/master/CHANGELOG.md)
//! for a complete list of what has changed from one version to another.
//!
//! # Donate
//!
//! This project is made freely available (as in free beer), but unfortunately
//! not all beer is free! So, if you would like to buy me a beer (or coffee or
//! *more*), then consider supporting my work that's benefited your project
//! and thousands of others.
//!
//!
//!
//!
//!
//!
//!
//!
//! [issue1]: https://github.com/nvzqz/static-assertions-rs/issues/1
//! [crate]: https://crates.io/crates/static_assertions
//! [compile-time]: https://en.wikipedia.org/wiki/Compile_time
//! [`Cargo.toml`]: https://doc.rust-lang.org/cargo/reference/manifest.html

#![doc(html_root_url = "https://docs.rs/static_assertions/0.3.4")]
#![doc(html_logo_url = "https://raw.githubusercontent.com/nvzqz/static-assertions-rs/assets/Icon.png")]

#![no_std]

#![deny(unused_macros)]

#[doc(hidden)]
pub extern crate core as _core;

mod assert_cfg;
mod assert_eq_size;
mod assert_fields;
mod assert_impl;
mod assert_not_impl;
mod assert_obj_safe;
mod assert_type;
mod const_assert;
<commit_msg>Change "complete" to "exhaustive"<commit_after>//! [![Banner](https://raw.githubusercontent.com/nvzqz/static-assertions-rs/assets/Banner.png)](https://github.com/nvzqz/static-assertions-rs)
//!
//! Compile-time assertions to ensure that invariants are met.
//!
//! _All_ assertions within this crate are performed at [compile-time]. This
//! allows for finding errors quickly and early when it comes to ensuring
//! certain features or aspects of a codebase. These macros are especially
//! important when exposing a public API that requires types to be the same size
//! or implement certain traits.
//!
//! # Usage
//!
//! This crate is available [on crates.io][crate] and can be used by adding the
//! following to your project's [`Cargo.toml`]:
//!
//! ```toml
//! [dependencies]
//! static_assertions = "0.3.4"
//! ```
//!
//! and this to your crate root (`main.rs` or `lib.rs`):
//!
//! ```
//! #[macro_use]
//! extern crate static_assertions;
//! # fn main() {}
//! ```
//!
//! # Examples
//!
//! Very thorough examples are provided in the docs for
//! [each individual macro](#macros). Failure case examples are also documented.
//!
//! # Changes
//!
//! See [`CHANGELOG.md`](https://github.com/nvzqz/static-assertions-rs/blob/master/CHANGELOG.md)
//! for an exhaustive list of what has changed from one version to another.
//!
//! # Donate
//!
//! This project is made freely available (as in free beer), but unfortunately
//! not all beer is free! So, if you would like to buy me a beer (or coffee or
//! *more*), then consider supporting my work that's benefited your project
//! and thousands of others.
//!
//!
//!
//!
//!
//!
//!
//!
//! [issue1]: https://github.com/nvzqz/static-assertions-rs/issues/1
//! [crate]: https://crates.io/crates/static_assertions
//! [compile-time]: https://en.wikipedia.org/wiki/Compile_time
//! [`Cargo.toml`]: https://doc.rust-lang.org/cargo/reference/manifest.html

#![doc(html_root_url = "https://docs.rs/static_assertions/0.3.4")]
#![doc(html_logo_url = "https://raw.githubusercontent.com/nvzqz/static-assertions-rs/assets/Icon.png")]

#![no_std]

#![deny(unused_macros)]

#[doc(hidden)]
pub extern crate core as _core;

mod assert_cfg;
mod assert_eq_size;
mod assert_fields;
mod assert_impl;
mod assert_not_impl;
mod assert_obj_safe;
mod assert_type;
mod const_assert;
<|endoftext|>


<commit_before>extern crate getopts;
use getopts::{optflag,getopts,OptGroup,usage};
use std::os;

use std::num::FromPrimitive;
use std::num::Int;
use std::char;
use std::old_io;
use std::old_io::{IoResult, IoError};
use std::old_io::BufferedReader;
use std::old_io::File;
use std::old_io::stdio;

pub fn print_usage(program: &str, opts: &[OptGroup]) {
    let brief = format!("Usage: {} [options]", program);
    print!("{}", usage(brief.as_slice(), opts));
}

pub fn cat(v: &Vec<String>, options: &getopts::Matches) {
    if options.opt_present("u") {
        let writer = Box::new(stdio::stdout_raw());
        stdio::set_stdout(writer);
    }
    if v.is_empty() {
        cat_stdin(options);
    }
    else {
        // read files
        cat_files(v, options);
    }
}

fn cat_files(v: &Vec<String>, options: &getopts::Matches) {
    let mut linenum = 1u32;
    for filename in v.iter() {
        let path = Path::new(filename);
        match File::open(&path) {
            Ok(fh) => {
                let mut file = BufferedReader::new(fh);
                linenum = cat_file(file, options, linenum);
            },
            Err(f) => {
                println!("{}", f);
            }
        }
    }
}

fn cat_stdin(options: &getopts::Matches) {
    let mut linenum = 1u32;
    let mut printempty: bool = false;
    for line in old_io::stdin().lock().lines() {
        let (a, b) = handle_line(line.unwrap(), &mut printempty, linenum, options);
        printempty = a;
        linenum = b;
    }
}

fn cat_file<'a>(
    mut file: old_io::BufferedReader<std::old_io::fs::File>,
    options: &getopts::Matches,
    mut linenum: u32,
    ) -> u32 {
    let mut printempty: bool = false;
    let mut read_buf = [0, 4096];
    let mut out_buf: Vec<u8> = vec![];
    loop {
        match file.read(&mut read_buf) {
            Ok(n) => {
                for c in read_buf[..n].iter() {
                    out_buf.push(*c);
                    if is_nl(c) {
                        let (a, b) = handle_buf(&out_buf, &mut printempty, linenum, options);
                        printempty = a;
                        linenum = b;
                        out_buf.clear();
                    }
                }
            },
            Err(f) => {
                let mut o = 0u32;
                if out_buf.len() > 0 {
                    handle_buf(&out_buf, &mut printempty, linenum, options);
                }
                break
            }
        }
    }
    linenum
}

fn handle_line<'a>(
    linestr: String,
    printempty: &'a mut bool,
    mut linenum: u32,
    options: &getopts::Matches) -> (bool, u32) {
    if options.opt_present("s") {
        if !is_empty(&linestr) {
            if *printempty == true {
                println!("");
            }
            linenum = print_string(&linestr, linenum, options);
        }
        else {
            *printempty = true;
        }
    }
    else {
        linenum = print_string(&linestr, linenum, options);
    }
    (*printempty, linenum)
}

fn handle_buf<'a>(
    out_buf: &Vec<u8>,
    printempty: &'a mut bool,
    mut linenum: u32,
    options: &getopts::Matches) -> (bool, u32) {
    if options.opt_present("s") {
        if !is_empty_out_buf(out_buf) {
            if *printempty == true {
                if options.opt_present("n") {
                    println!("     {}\t", linenum);
                    linenum = linenum + 1;
                }
                else {
                    println!("");
                }
            }
            linenum = print_buf(&out_buf, linenum, options);
        }
        else {
            *printempty = true;
        }
    }
    else {
        linenum = print_buf(&out_buf, linenum, options);
    }
    (*printempty, linenum)
}

fn print_string<'a>(s: &String, mut linenum: u32, options: &getopts::Matches) -> u32 {
    if options.opt_present("b") {
        if !is_empty(s) {
            print_numbered(s, linenum, options);
            linenum = linenum + 1;
        }
        else {
            print_unnumbered(s, options);
        }
    }
    else if options.opt_present("n") {
        print_numbered(s, linenum, options);
        linenum = linenum + 1;
    }
    else {
        print_unnumbered(s, options);
    }
    linenum
}

fn print_buf<'a>(out_buf: &Vec<u8>, mut linenum: u32, options: &getopts::Matches) -> u32 {
    if options.opt_present("b") {
        if !is_empty_out_buf(out_buf) {
            print_numbered_buf(out_buf, linenum, options);
            linenum = linenum + 1;
        }
        else {
            print_unnumbered_buf(out_buf, options);
        }
    }
    else if options.opt_present("n") {
        print_numbered_buf(out_buf, linenum, options);
        linenum = linenum + 1;
    }
    else {
        print_unnumbered_buf(out_buf, options);
    }
    linenum
}

fn print_numbered<'a>(s: &String, linenum: u32, options: &getopts::Matches) {
    if options.opt_present("v") || options.opt_present("t") {
        print!("     {}\t", linenum);
        for b in s.as_bytes().iter() {
            print_byte(b, options);
        }
    }
    else {
        print!("     {}\t{}", linenum, s);
    }
}

fn print_numbered_buf<'a>(out_buf: &Vec<u8>, linenum: u32, options: &getopts::Matches) {
    // if options.opt_present("v") || options.opt_present("t") {
        print!("     {}\t", linenum);
        let mut t = 0u32;
        for b in out_buf.iter() {
            if t > 0 {
                t = t + *b as u32;
                print!("t: {} ", t);
                print!("{}", char::from_u32(t).unwrap());
                t = 0;
            }
            else {
                if *b > 160 {
                    t = *b as u32;
                }
                else {
                    print_byte(b, options);
                }
            }
        }
    // }
}

fn print_unnumbered(s: &String, options: &getopts::Matches) {
    if options.opt_present("v") || options.opt_present("t") {
        for b in s.as_bytes().iter() {
            print_byte(b, options);
        }
    }
    else {
        print!("{}", s);
    }
}

fn print_unnumbered_buf(out_buf: &Vec<u8>, options: &getopts::Matches) {
    // if options.opt_present("v") || options.opt_present("t") {
        let mut t = 0;
        let mut buf: Vec<u8> = vec![];
        for b in out_buf.iter() {
            if t > 0 {
                buf.push(*b);
                t = t - 1;
                if t == 0 {
                    print_u8_buf(&mut buf, options);
                    buf.clear();
                }
            }
            else {
                if *b >= 240 {
                    //4th byte
                    t = 3;
                    buf.push(*b);
                }
                else if *b >= 224 {
                    t = 2;
                    buf.push(*b);
                }
                else if *b >= 192 {
                    t = 1;
                    buf.push(*b);
                }
                else {
                    print_byte(b, options);
                }
            }
        }
    // }
    // else {
        // print!("{}", s);
    // }
}

fn print_u8_buf(buf: &mut Vec<u8>, options: &getopts::Matches) {

    let o = convert_buf_to_codepoint(buf);
    print!("{}", char::from_u32(o).unwrap());
    // for b in buf.iter() {
        // print_byte(b, options);
    // }
}

fn convert_buf_to_codepoint(buf: &mut Vec<u8>) -> u32 {
    let mut s = 0u32;
    // println!("size: {}", buf.len());
    // println!("s: {}", s);
    let mut l = buf.len();
    for b in buf.iter() {
        // println!("l: {}", l);
        if l == 4 {
            s = s + (*b as u32 - 240 + 2.pow(19));
        }
        else if l == 3 {
            // 226 should be 224, no?
            s = s + (*b as u32 - 226 + 2.pow(13));
        }
        else if l == 2 {
            // println!("2b: {}", b);
            let newval = (*b & 15) << 6;
            // println!("newval: {}", newval);
            s = s + FromPrimitive::from_u8(newval).unwrap();
            // s = s + (*b as u32 - 192 + 2.pow(7));
            // println!("2: {}", s);
        }
        else if l == 1 {
            // println!("1b: {}", b);
            // println!("1b anded: {}", *b & 63);
            s = s + FromPrimitive::from_u8(*b & 63).unwrap();
        }
        l = l - 1;
    }
    s
}

fn is_empty(line: &String) -> bool {
    let newline_str = "\n".to_string();
    let crlf_str = "\r\n".to_string();
    if line.is_empty() {
        true
    }
    else if line.eq(&newline_str) || line.eq(&crlf_str) {
        true
    }
    else {
        false
    }
}

fn is_empty_out_buf(v: &Vec<u8>) -> bool {
    if v.len() > 1 {
        false
    }
    else if is_nl(&v[0]) {
        true
    }
    else {
        false
    }
}

fn is_nl(c: &u8) -> bool {
    *c == 10u8
}

fn print_byte(b: &u8, options: &getopts::Matches) {
    if (*b > 31 && *b < 127) || *b == 10 || *b == 9 {
        if options.opt_present("t") && *b == 9 {
            print_tab();
        }
        else {
            print!("{}", *b as char);
        }
    }
    else {
        if options.opt_present("v") || options.opt_present("t") {
            if *b < 32 {
                print!("^{}", (*b + 64) as char);
            }
            else if *b == 127 {
                // del char
                print!("^?");
            }
            else if *b > 127 {
                if *b == 255 {
                    print!("M-^?");
                }
                else {
                    let x = *b - 128;
                    if x < 32 {
                        print!("M-^{}", (x + 64) as char);
                    }
                    else {
                        print!("M-{}", (*b - 128) as char);
                    }
                }
            }
        }
    }
}

fn print_tab() {
    print!("^I");
}

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

    #[test]
    fn assert_is_empty() {
        let s = "".to_string();
        assert!(is_empty(&s));
    }
    #[test]
    fn assert_is_empty_newline() {
        let s = "\n".to_string();
        assert!(is_empty(&s));
    }

    #[test]
    fn assert_is_empty_crlf() {
        let s = "\r\n".to_string();
        assert!(is_empty(&s));
    }

    #[test]
    fn assert_is_empty_char() {
        let s = "d".to_string();
        assert!(!is_empty(&s));
    }

    #[test]
    fn assert_is_empty_ctrl_char() {
        let s = "".to_string();
        assert!(!is_empty(&s));
    }

    #[test]
    fn assert_buf_to_codepoint_24() {
        let mut b = vec![24u8];
        assert_eq!(convert_buf_to_codepoint(&mut b), 24u32);
    }

    #[test]
    fn assert_buf_to_codepoint_36() {
        let mut b = vec![164u8];
        assert_eq!(convert_buf_to_codepoint(&mut b), 36);
    }

    #[test]
    fn assert_buf_to_codepoint_162() {
        let mut b = vec![194u8, 162];
        assert_eq!(convert_buf_to_codepoint(&mut b), 162);
    }

    #[test]
    fn assert_buf_to_codepoint_8364() {
        let mut b = vec![226u8, 130, 172];
        assert_eq!(convert_buf_to_codepoint(&mut b), 8364);
    }

}
<commit_msg>all unit tests pass<commit_after>extern crate getopts;
use getopts::{optflag,getopts,OptGroup,usage};
use std::os;

use std::num::FromPrimitive;
use std::num::Int;
use std::char;
use std::old_io;
use std::old_io::{IoResult, IoError};
use std::old_io::BufferedReader;
use std::old_io::File;
use std::old_io::stdio;

pub fn print_usage(program: &str, opts: &[OptGroup]) {
    let brief = format!("Usage: {} [options]", program);
    print!("{}", usage(brief.as_slice(), opts));
}

pub fn cat(v: &Vec<String>, options: &getopts::Matches) {
    if options.opt_present("u") {
        let writer = Box::new(stdio::stdout_raw());
        stdio::set_stdout(writer);
    }
    if v.is_empty() {
        cat_stdin(options);
    }
    else {
        // read files
        cat_files(v, options);
    }
}

fn cat_files(v: &Vec<String>, options: &getopts::Matches) {
    let mut linenum = 1u32;
    for filename in v.iter() {
        let path = Path::new(filename);
        match File::open(&path) {
            Ok(fh) => {
                let mut file = BufferedReader::new(fh);
                linenum = cat_file(file, options, linenum);
            },
            Err(f) => {
                println!("{}", f);
            }
        }
    }
}

fn cat_stdin(options: &getopts::Matches) {
    let mut linenum = 1u32;
    let mut printempty: bool = false;
    for line in old_io::stdin().lock().lines() {
        let (a, b) = handle_line(line.unwrap(), &mut printempty, linenum, options);
        printempty = a;
        linenum = b;
    }
}

fn cat_file<'a>(
    mut file: old_io::BufferedReader<std::old_io::fs::File>,
    options: &getopts::Matches,
    mut linenum: u32,
    ) -> u32 {
    let mut printempty: bool = false;
    let mut read_buf = [0, 4096];
    let mut out_buf: Vec<u8> = vec![];
    loop {
        match file.read(&mut read_buf) {
            Ok(n) => {
                for c in read_buf[..n].iter() {
                    out_buf.push(*c);
                    if is_nl(c) {
                        let (a, b) = handle_buf(&out_buf, &mut printempty, linenum, options);
                        printempty = a;
                        linenum = b;
                        out_buf.clear();
                    }
                }
            },
            Err(f) => {
                let mut o = 0u32;
                if out_buf.len() > 0 {
                    handle_buf(&out_buf, &mut printempty, linenum, options);
                }
                break
            }
        }
    }
    linenum
}

fn handle_line<'a>(
    linestr: String,
    printempty: &'a mut bool,
    mut linenum: u32,
    options: &getopts::Matches) -> (bool, u32) {
    if options.opt_present("s") {
        if !is_empty(&linestr) {
            if *printempty == true {
                println!("");
            }
            linenum = print_string(&linestr, linenum, options);
        }
        else {
            *printempty = true;
        }
    }
    else {
        linenum = print_string(&linestr, linenum, options);
    }
    (*printempty, linenum)
}

fn handle_buf<'a>(
    out_buf: &Vec<u8>,
    printempty: &'a mut bool,
    mut linenum: u32,
    options: &getopts::Matches) -> (bool, u32) {
    if options.opt_present("s") {
        if !is_empty_out_buf(out_buf) {
            if *printempty == true {
                if options.opt_present("n") {
                    println!("     {}\t", linenum);
                    linenum = linenum + 1;
                }
                else {
                    println!("");
                }
            }
            linenum = print_buf(&out_buf, linenum, options);
        }
        else {
            *printempty = true;
        }
    }
    else {
        linenum = print_buf(&out_buf, linenum, options);
    }
    (*printempty, linenum)
}

fn print_string<'a>(s: &String, mut linenum: u32, options: &getopts::Matches) -> u32 {
    if options.opt_present("b") {
        if !is_empty(s) {
            print_numbered(s, linenum, options);
            linenum = linenum + 1;
        }
        else {
            print_unnumbered(s, options);
        }
    }
    else if options.opt_present("n") {
        print_numbered(s, linenum, options);
        linenum = linenum + 1;
    }
    else {
        print_unnumbered(s, options);
    }
    linenum
}

fn print_buf<'a>(out_buf: &Vec<u8>, mut linenum: u32, options: &getopts::Matches) -> u32 {
    if options.opt_present("b") {
        if !is_empty_out_buf(out_buf) {
            print_numbered_buf(out_buf, linenum, options);
            linenum = linenum + 1;
        }
        else {
            print_unnumbered_buf(out_buf, options);
        }
    }
    else if options.opt_present("n") {
        print_numbered_buf(out_buf, linenum, options);
        linenum = linenum + 1;
    }
    else {
        print_unnumbered_buf(out_buf, options);
    }
    linenum
}

fn print_numbered<'a>(s: &String, linenum: u32, options: &getopts::Matches) {
    if options.opt_present("v") || options.opt_present("t") {
        print!("     {}\t", linenum);
        for b in s.as_bytes().iter() {
            print_byte(b, options);
        }
    }
    else {
        print!("     {}\t{}", linenum, s);
    }
}

fn print_numbered_buf<'a>(out_buf: &Vec<u8>, linenum: u32, options: &getopts::Matches) {
    // if options.opt_present("v") || options.opt_present("t") {
        print!("     {}\t", linenum);
        let mut t = 0u32;
        for b in out_buf.iter() {
            if t > 0 {
                t = t + *b as u32;
                print!("t: {} ", t);
                print!("{}", char::from_u32(t).unwrap());
                t = 0;
            }
            else {
                if *b > 160 {
                    t = *b as u32;
                }
                else {
                    print_byte(b, options);
                }
            }
        }
    // }
}

fn print_unnumbered(s: &String, options: &getopts::Matches) {
    if options.opt_present("v") || options.opt_present("t") {
        for b in s.as_bytes().iter() {
            print_byte(b, options);
        }
    }
    else {
        print!("{}", s);
    }
}

fn print_unnumbered_buf(out_buf: &Vec<u8>, options: &getopts::Matches) {
    // if options.opt_present("v") || options.opt_present("t") {
        let mut t = 0;
        let mut buf: Vec<u8> = vec![];
        for b in out_buf.iter() {
            if t > 0 {
                buf.push(*b);
                t = t - 1;
                if t == 0 {
                    print_u8_buf(&mut buf, options);
                    buf.clear();
                }
            }
            else {
                if *b >= 240 {
                    //4th byte
                    t = 3;
                    buf.push(*b);
                }
                else if *b >= 224 {
                    t = 2;
                    buf.push(*b);
                }
                else if *b >= 192 {
                    t = 1;
                    buf.push(*b);
                }
                else {
                    print_byte(b, options);
                }
            }
        }
    // }
    // else {
        // print!("{}", s);
    // }
}

fn print_u8_buf(buf: &mut Vec<u8>, options: &getopts::Matches) {

    let o = convert_buf_to_codepoint(buf);
    print!("{}", char::from_u32(o).unwrap());
    // for b in buf.iter() {
        // print_byte(b, options);
    // }
}

fn convert_buf_to_codepoint(buf: &mut Vec<u8>) -> u32 {
    let mut s = 0u32;
    // println!("size: {}", buf.len());
    // println!("s: {}", s);
    let mut l = buf.len();
    let orig_l = l;
    for b in buf.iter() {
        // println!("l: {}", l);
        if l == 4 {
            s = s + (*b as u32 - 240 + 2.pow(19));
        }
        else if l == 3 {
            s = s + ((*b as u32 | 224) - 224) << 12
        }
        else if l == 2 {
            // println!("2b: {}", b);
            // let newval = (*b & 15) << 6;
            // println!("newval: {}", newval);
            // s = s + FromPrimitive::from_u8(newval).unwrap();
            s = s + (((*b as u32 | 192) - 192) << 6);
            // println!("2: {}", s);
        }
        else if l == 1 {
            // println!("1b: {}", b);
            // println!("1b anded: {}", *b & 63);
            if orig_l > 1 {
                s = s + FromPrimitive::from_u8((*b | 128) - 128).unwrap();
            }
            else {
                s = s + FromPrimitive::from_u8((*b | 192) - 192).unwrap();
            }
        }
        l = l - 1;
    }
    s
}

fn is_empty(line: &String) -> bool {
    let newline_str = "\n".to_string();
    let crlf_str = "\r\n".to_string();
    if line.is_empty() {
        true
    }
    else if line.eq(&newline_str) || line.eq(&crlf_str) {
        true
    }
    else {
        false
    }
}

fn is_empty_out_buf(v: &Vec<u8>) -> bool {
    if v.len() > 1 {
        false
    }
    else if is_nl(&v[0]) {
        true
    }
    else {
        false
    }
}

fn is_nl(c: &u8) -> bool {
    *c == 10u8
}

fn print_byte(b: &u8, options: &getopts::Matches) {
    if (*b > 31 && *b < 127) || *b == 10 || *b == 9 {
        if options.opt_present("t") && *b == 9 {
            print_tab();
        }
        else {
            print!("{}", *b as char);
        }
    }
    else {
        if options.opt_present("v") || options.opt_present("t") {
            if *b < 32 {
                print!("^{}", (*b + 64) as char);
            }
            else if *b == 127 {
                // del char
                print!("^?");
            }
            else if *b > 127 {
                if *b == 255 {
                    print!("M-^?");
                }
                else {
                    let x = *b - 128;
                    if x < 32 {
                        print!("M-^{}", (x + 64) as char);
                    }
                    else {
                        print!("M-{}", (*b - 128) as char);
                    }
                }
            }
        }
    }
}

fn print_tab() {
    print!("^I");
}

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

    #[test]
    fn assert_is_empty() {
        let s = "".to_string();
        assert!(is_empty(&s));
    }
    #[test]
    fn assert_is_empty_newline() {
        let s = "\n".to_string();
        assert!(is_empty(&s));
    }

    #[test]
    fn assert_is_empty_crlf() {
        let s = "\r\n".to_string();
        assert!(is_empty(&s));
    }

    #[test]
    fn assert_is_empty_char() {
        let s = "d".to_string();
        assert!(!is_empty(&s));
    }

    #[test]
    fn assert_is_empty_ctrl_char() {
        let s = "".to_string();
        assert!(!is_empty(&s));
    }

    #[test]
    fn assert_buf_to_codepoint_24() {
        let mut b = vec![24u8];
        assert_eq!(convert_buf_to_codepoint(&mut b), 24u32);
    }

    #[test]
    fn assert_buf_to_codepoint_36() {
        let mut b = vec![164u8];
        assert_eq!(convert_buf_to_codepoint(&mut b), 36);
    }

    #[test]
    fn assert_buf_to_codepoint_162() {
        // ¢
        // C2 A2
        // 11000010 10100010
        // 00010100010
        let mut b = vec![194u8, 162];
        assert_eq!(convert_buf_to_codepoint(&mut b), 162);
    }

    #[test]
    fn assert_buf_to_codepoint_8364() {
        // €
        // E2 82 AC
        // 11100010 10000010 10101100
        // 0010000010101100
        let mut b = vec![226u8, 130, 172];
        assert_eq!(convert_buf_to_codepoint(&mut b), 8364);
    }

    #[test]
    fn assert_buf_to_codepoint_294() {
        // c4 a6
        // 11000100 10100110
        // 00100100110
        let mut b = vec![196u8, 166];
        assert_eq!(convert_buf_to_codepoint(&mut b), 294);
    }

}
<|endoftext|>


<commit_before>
mod alias {
    pub enum Commands {
        NewBeacon = 15,
        DelBeacon = 17,
        RegisterAction = 60,
        Action = 62,
        ActionTxStatus = 64,
    }
}

// Commands
// Do not change order; acts as ABI
pub enum Commands {
    Unspec,
    GetWiPhy,
    SetWiPhy,
    NewWiPhy,
    DelWiPhy,

    GetInterface,
    SetInterface,
    NewInterface,
    DelIntreface,

    GetKey,
    SetKey,
    NewKey,
    DelKey,

    GetBeacon,
    SetBeacon,
    StartAp,
    AliasNewBeacon, // StartAp alias
    StopAp,
    AliasDelBeacon, // StopAp alias

    GetStation,
    SetStation,
    NewStation,
    DelStation,

    GetMPath,
    SetMPath,
    NewMPath,
    DelMPath,

    SetBss,

    SetReg,
    ReqSetReg,

    GetMeshConfig,
    SetMeshConfig,

    SetMgmtExtraIe, // Reserved; not used

    GetReg,

    GetScan,
    TriggerScan,
    NewScanResults,
    ScanAborted,

    RegChange,

    Authenticate,
    Associate,
    Deauthenticate,
    Disassociate,

    MichaelMicFailure,

    RegBeaconHint,

    JoinIbss,
    LeaveIbss,

    TestMode,
    Connect,
    Roam,
    Disconnect,

    SetWiPhyNetNs,

    GetSurvey,
    NewSurveyResults,

    SetPmksa,
    DelPmksa,
    FlushPmksa,

    RemainOnChannel,
    CancelRemainOnChannel,

    SetTxBitrateMask,

    RegisterFrame,
    AliasRegisterAction, // RegisterFrame alias
    Frame,
    AliasAction,         // Frame alias
    FrameTxStatus,
    AliasActionTxStatus, // FrameTxStatus

    SetPowerSave,
    GetPowerSave,

    SetCqm,
    NotifyCqm,

    SetChannel,
    SetWdsPeer,

    FrameWaitCancel,

    JoinMesh,
    LeaveMesh,

    UnprotDeathenticate,
    UnProtDisassociate,

    NewPeerCandidate,

    GetWowLan,
    SetWowLan,

    StartSchedScan,
    StopSchedScan,
    SchedScanResults,
    SchedScanStopped,

    SetRekeyOffload,

    PmksaCandidate,

    TdlsOper,
    TdlsMgmt,

    UnexpectedFrame,

    ProbeClient,

    RegisterBeacons,

    Unexpected4AddrFrame,

    SetNoAckMap,

    ChSwitchNotify,

    StartP2pDevice,
    StopP2pDevice,

    ConnFailed,

    SetMcastRate,

    SetMacAcl,

    RadarDetect,

    GetProtocolFeatures,

    UpdateFtIes,
    FtEvent,

    CritProtocolState,
    CritProtocolStop,

    GetCoalesce,
    SetCoalesce,

    Vendor,

    SetQosMap,

    AddTxTs,
    DelTxTs,

    GetMpp,

    AfterLast
}

// attributes
// Do not change order; acts as ABI
pub enum Attrs {
    Unspec,

    WiPhy,
    WiPhyName,

    IfIndex,
    IfName,
    IfType,

    Mac,

    KeyData,
    KeyIdx,
    KeyCipher,
    KeySeq,
    KeyDefault,

    BeaconInterval,
    DtimPeriod,
    BeaconHead,
    BeaconTail,

    StaAid,
    StaFlags,
    StaListenInterval,
    StaSupportedRates,
    StaVlan,
    StaInfo,

    WiPhyBands,

    MntrFlags,

    MeshId,
    StaPlinkAction,
    MpathNextHop,
    MpathInfo,

    BssCtsProt,
    BssShortPreamble,
    BssShortSlotTime,

    HtCapability,

    SupportedIfTypes,

    RegAlpha2,
    RegRules,

    MeshConfig,

    BssBasicRates,

    WiPhyTxqParams,
    WiPhyFreq,
    WiPhyChannelType,

    KeyDefaultMgmt,

    MgmtSubtype,
    Ie,

    MaxNumScanSsids,

    ScanFrequencies,
    ScanSsids,
    Generation,
    Bss,

    RegInitiator,
    RegType,

    SupportedCommands,

    Frame,
    Ssid,
    AuthType,
    ReasonCode,

    KeyType,

    MaxScanIeLen,
    CipherSuites,

    FreqBefore,
    FreqAfter,

    FreqFixed,

    WiPhyRetryShort,
    WiPhyRetryLong,
    WiPhyFragThreshold,
    WiPhyRtsThreshold,

    TimedOut,

    UseMfp,

    StaFlags2,

    ControlPort,

    TestData,

    Privacy,

    DisconnectedByAp,

    StatusCode,

    CipherSuitesPairwise,
    CipherSuiteGroup,
    WpaVersions,
    AkmSuites,

    ReqIe,
    RespIe,

    PrevBssid,

    Key,
    Keys,

    Pid,

    Addr4,

    SurveyInfo,

    PmkId,
    MaxNumPmkIds,

    Duration,

    Cookie,

    WiPhyCoverageClass,

    TxRates,

    FrameMatch,

    Ack,

    PsState,

    Cqm,

    LocalStateChange,

    ApIsolate,

    WiPhyTxPowerSetting,
    WiPhyTxPowerLevel,

    TxFrameTypes,
    RxFrameTypes,
    FrameType,

    ControlPortEthertype,
    ControlPortNoEncrypt,

    SupportIbssRsn,

    WiPhyAntennaTx,
    WiPhyAntennaRx,

    McastRate,

    OffChannelTxOk,

    BssHtOpmode,

    KeyDefaultTypes,

    MaxRemainOnChannelDuration,

    MeshSetup,

    WiPhyAntennaAvailTx,
    WiPhyAntennaAvailRx,

    SupportMeshAuth,
    StaPlinkState,

    WowLanTriggers,
    WowLanTriggersSupported,

    SchedScanInterval,

    InterfaceCombinations,
    SoftwareIfTypes,

    RekeyData,

    MaxNumSchedScanSsids,
    MaxSchedScanIeLen,

    ScanSuppRates,

    HiddenSsid,

    IeProbeResp,
    IeAssocResp,

    StaWme,
    SupportApUapsd,

    RoamSupport,

    AttrSchedScanMatch,
    MaxMatchSets,

    PmksaCandidate,

    TxNoCckRate,

    TdlsAction,
    TdlsDialogToken,
    TdlsOperation,
    TdlsSupport,
    TdlsExternalSetup,

    DeviceApSme,

    DontWaitForAck,

    FeatureFlags,

    ProbeRespOffload,

    ProbeResp,

    DfsRegion,

    DisableHt,
    HtCapabilityMask,

    NoackMap,

    InactivityTimeout,

    RxSignalDbm,

    BgScanPeriod,

    Wdev,

    UserRegHintType,

    ConnFailedReason,

    SaeData,

    VhtCapability,

    ScanFlags,

    ChannelWidth,
    CenterFreq1,
    CenterFreq2,

    P2pCtwindow,
    P2pOppps,

    LocalMeshPowerMode,

    AclPolicy,

    MacAddrs,

    MacAclMax,

    RadarEvent,

    ExtCapa,

    ExtCapaMask,

    StaCapability,
    StaExtCapability,

    ProtocolFeatures,
    SplitWiphyDump,

    DisableVht,
    VhtCapabilityMask,

    Mdid,

    IeRic,

    CritProtId,
    MaxCritProtDuration,

    PeerAid,

    CoalesceRule,

    ChSwitchCount,
    ChSwitchBlockTx,
    CsaIes,
    CsaCOffBeacon,
    CsaCOffPresp,

    RxmgmtFlags,

    StaSupportedChannels,
    StaSipportedOperClasses,

    HandleDfs,

    Support5Mhz,
    Support10Mhz,

    OpmodeNotif,

    VendorId,
    VendorSubcmd,
    VendorData,
    VendorEvents,

    QodMap,

    MacHint,
    WiPhyFreqHint,

    MaxApAssocSta,

    TdlsPeerCapability,

    IfaceSocketOwnder,
    CsaCOffsetsTx,
    MaxCsaCounters,

    TdlsInitiator,

    UseRrm,

    WiPhyDynAck,

    Tsid,
    UserPrio,
    AdmittedTime,

    SmpsMode,

    AfterLast
}

// Interface types
pub enum IfType {
    Unspecified,
    AdHoc,
    Station,
    Ap,
    ApVlan,
    Wds,
    Monitor,
    MeshPoint,
    P2pClient,
    P2pGo,
    P2pDevice,

    NumIfTypes
}

// Station flags
pub enum StaFlags {
    __Invalid,
    Authorized,
    ShortPreamble,
    Wme,
    Mfp,
    Authenticated,
    TdlsPeer,
    Associated,
    AfterLast
}

#[repr(C, packed)]
pub struct StaFlagUpdate {
    mask: u32,
    set: u32,
}

// attrubtes for getting station bitrate information
pub enum RateInfo {
    __Invalid,
    Bitrate,
    Mcs,
    Width40Mhz,
    ShortGi,
    Bitrate32,
    VhtMcs,
    VhtNss,
    Width80Mhz,
    Width80P80Mhz,
    Width160Mhz,

    AfterLast
}
<commit_msg>Include Station BSS information enum<commit_after>
mod alias {
    pub enum Commands {
        NewBeacon = 15,
        DelBeacon = 17,
        RegisterAction = 60,
        Action = 62,
        ActionTxStatus = 64,
    }
}

// Commands
// Do not change order; acts as ABI
pub enum Commands {
    Unspec,
    GetWiPhy,
    SetWiPhy,
    NewWiPhy,
    DelWiPhy,

    GetInterface,
    SetInterface,
    NewInterface,
    DelIntreface,

    GetKey,
    SetKey,
    NewKey,
    DelKey,

    GetBeacon,
    SetBeacon,
    StartAp,
    AliasNewBeacon, // StartAp alias
    StopAp,
    AliasDelBeacon, // StopAp alias

    GetStation,
    SetStation,
    NewStation,
    DelStation,

    GetMPath,
    SetMPath,
    NewMPath,
    DelMPath,

    SetBss,

    SetReg,
    ReqSetReg,

    GetMeshConfig,
    SetMeshConfig,

    SetMgmtExtraIe, // Reserved; not used

    GetReg,

    GetScan,
    TriggerScan,
    NewScanResults,
    ScanAborted,

    RegChange,

    Authenticate,
    Associate,
    Deauthenticate,
    Disassociate,

    MichaelMicFailure,

    RegBeaconHint,

    JoinIbss,
    LeaveIbss,

    TestMode,
    Connect,
    Roam,
    Disconnect,

    SetWiPhyNetNs,

    GetSurvey,
    NewSurveyResults,

    SetPmksa,
    DelPmksa,
    FlushPmksa,

    RemainOnChannel,
    CancelRemainOnChannel,

    SetTxBitrateMask,

    RegisterFrame,
    AliasRegisterAction, // RegisterFrame alias
    Frame,
    AliasAction,         // Frame alias
    FrameTxStatus,
    AliasActionTxStatus, // FrameTxStatus

    SetPowerSave,
    GetPowerSave,

    SetCqm,
    NotifyCqm,

    SetChannel,
    SetWdsPeer,

    FrameWaitCancel,

    JoinMesh,
    LeaveMesh,

    UnprotDeathenticate,
    UnProtDisassociate,

    NewPeerCandidate,

    GetWowLan,
    SetWowLan,

    StartSchedScan,
    StopSchedScan,
    SchedScanResults,
    SchedScanStopped,

    SetRekeyOffload,

    PmksaCandidate,

    TdlsOper,
    TdlsMgmt,

    UnexpectedFrame,

    ProbeClient,

    RegisterBeacons,

    Unexpected4AddrFrame,

    SetNoAckMap,

    ChSwitchNotify,

    StartP2pDevice,
    StopP2pDevice,

    ConnFailed,

    SetMcastRate,

    SetMacAcl,

    RadarDetect,

    GetProtocolFeatures,

    UpdateFtIes,
    FtEvent,

    CritProtocolState,
    CritProtocolStop,

    GetCoalesce,
    SetCoalesce,

    Vendor,

    SetQosMap,

    AddTxTs,
    DelTxTs,

    GetMpp,

    AfterLast
}

// attributes
// Do not change order; acts as ABI
pub enum Attrs {
    Unspec,

    WiPhy,
    WiPhyName,

    IfIndex,
    IfName,
    IfType,

    Mac,

    KeyData,
    KeyIdx,
    KeyCipher,
    KeySeq,
    KeyDefault,

    BeaconInterval,
    DtimPeriod,
    BeaconHead,
    BeaconTail,

    StaAid,
    StaFlags,
    StaListenInterval,
    StaSupportedRates,
    StaVlan,
    StaInfo,

    WiPhyBands,

    MntrFlags,

    MeshId,
    StaPlinkAction,
    MpathNextHop,
    MpathInfo,

    BssCtsProt,
    BssShortPreamble,
    BssShortSlotTime,

    HtCapability,

    SupportedIfTypes,

    RegAlpha2,
    RegRules,

    MeshConfig,

    BssBasicRates,

    WiPhyTxqParams,
    WiPhyFreq,
    WiPhyChannelType,

    KeyDefaultMgmt,

    MgmtSubtype,
    Ie,

    MaxNumScanSsids,

    ScanFrequencies,
    ScanSsids,
    Generation,
    Bss,

    RegInitiator,
    RegType,

    SupportedCommands,

    Frame,
    Ssid,
    AuthType,
    ReasonCode,

    KeyType,

    MaxScanIeLen,
    CipherSuites,

    FreqBefore,
    FreqAfter,

    FreqFixed,

    WiPhyRetryShort,
    WiPhyRetryLong,
    WiPhyFragThreshold,
    WiPhyRtsThreshold,

    TimedOut,

    UseMfp,

    StaFlags2,

    ControlPort,

    TestData,

    Privacy,

    DisconnectedByAp,

    StatusCode,

    CipherSuitesPairwise,
    CipherSuiteGroup,
    WpaVersions,
    AkmSuites,

    ReqIe,
    RespIe,

    PrevBssid,

    Key,
    Keys,

    Pid,

    Addr4,

    SurveyInfo,

    PmkId,
    MaxNumPmkIds,

    Duration,

    Cookie,

    WiPhyCoverageClass,

    TxRates,

    FrameMatch,

    Ack,

    PsState,

    Cqm,

    LocalStateChange,

    ApIsolate,

    WiPhyTxPowerSetting,
    WiPhyTxPowerLevel,

    TxFrameTypes,
    RxFrameTypes,
    FrameType,

    ControlPortEthertype,
    ControlPortNoEncrypt,

    SupportIbssRsn,

    WiPhyAntennaTx,
    WiPhyAntennaRx,

    McastRate,

    OffChannelTxOk,

    BssHtOpmode,

    KeyDefaultTypes,

    MaxRemainOnChannelDuration,

    MeshSetup,

    WiPhyAntennaAvailTx,
    WiPhyAntennaAvailRx,

    SupportMeshAuth,
    StaPlinkState,

    WowLanTriggers,
    WowLanTriggersSupported,

    SchedScanInterval,

    InterfaceCombinations,
    SoftwareIfTypes,

    RekeyData,

    MaxNumSchedScanSsids,
    MaxSchedScanIeLen,

    ScanSuppRates,

    HiddenSsid,

    IeProbeResp,
    IeAssocResp,

    StaWme,
    SupportApUapsd,

    RoamSupport,

    AttrSchedScanMatch,
    MaxMatchSets,

    PmksaCandidate,

    TxNoCckRate,

    TdlsAction,
    TdlsDialogToken,
    TdlsOperation,
    TdlsSupport,
    TdlsExternalSetup,

    DeviceApSme,

    DontWaitForAck,

    FeatureFlags,

    ProbeRespOffload,

    ProbeResp,

    DfsRegion,

    DisableHt,
    HtCapabilityMask,

    NoackMap,

    InactivityTimeout,

    RxSignalDbm,

    BgScanPeriod,

    Wdev,

    UserRegHintType,

    ConnFailedReason,

    SaeData,

    VhtCapability,

    ScanFlags,

    ChannelWidth,
    CenterFreq1,
    CenterFreq2,

    P2pCtwindow,
    P2pOppps,

    LocalMeshPowerMode,

    AclPolicy,

    MacAddrs,

    MacAclMax,

    RadarEvent,

    ExtCapa,

    ExtCapaMask,

    StaCapability,
    StaExtCapability,

    ProtocolFeatures,
    SplitWiphyDump,

    DisableVht,
    VhtCapabilityMask,

    Mdid,

    IeRic,

    CritProtId,
    MaxCritProtDuration,

    PeerAid,

    CoalesceRule,

    ChSwitchCount,
    ChSwitchBlockTx,
    CsaIes,
    CsaCOffBeacon,
    CsaCOffPresp,

    RxmgmtFlags,

    StaSupportedChannels,
    StaSipportedOperClasses,

    HandleDfs,

    Support5Mhz,
    Support10Mhz,

    OpmodeNotif,

    VendorId,
    VendorSubcmd,
    VendorData,
    VendorEvents,

    QodMap,

    MacHint,
    WiPhyFreqHint,

    MaxApAssocSta,

    TdlsPeerCapability,

    IfaceSocketOwnder,
    CsaCOffsetsTx,
    MaxCsaCounters,

    TdlsInitiator,

    UseRrm,

    WiPhyDynAck,

    Tsid,
    UserPrio,
    AdmittedTime,

    SmpsMode,

    AfterLast
}

// Interface types
pub enum IfType {
    Unspecified,
    AdHoc,
    Station,
    Ap,
    ApVlan,
    Wds,
    Monitor,
    MeshPoint,
    P2pClient,
    P2pGo,
    P2pDevice,

    NumIfTypes
}

// Station flags
pub enum StaFlags {
    __Invalid,
    Authorized,
    ShortPreamble,
    Wme,
    Mfp,
    Authenticated,
    TdlsPeer,
    Associated,
    AfterLast
}

#[repr(C, packed)]
pub struct StaFlagUpdate {
    mask: u32,
    set: u32,
}

// attrubtes for getting station bitrate information
pub enum RateInfo {
    __Invalid,
    Bitrate,
    Mcs,
    Width40Mhz,
    ShortGi,
    Bitrate32,
    VhtMcs,
    VhtNss,
    Width80Mhz,
    Width80P80Mhz,
    Width160Mhz,

    AfterLast
}

pub enum StaBssParam {
    __Invalid,
    CtsProt,
    ShortPreamble,
    ShortSlotTime,
    DtimPeriod,
    BeaconInterval,

    AfterLast
}
<|endoftext|>


<commit_before>//! Rust friendly bindings to the various *nix system functions.
//!
//! Modules are structured according to the C header file that they would be
//! defined in.
#![crate_name = "nix"]
#![cfg(unix)]
#![allow(non_camel_case_types)]
// latest bitflags triggers a rustc bug with cross-crate macro expansions causing dead_code
// warnings even though the macro expands into something with allow(dead_code)
#![allow(dead_code)]
#![deny(warnings)]

#[macro_use]
extern crate bitflags;

extern crate libc;

#[cfg(test)]
extern crate nix_test as nixtest;

// Re-export some libc constants
pub use libc::{c_int, c_void};

pub mod errno;
pub mod features;
pub mod fcntl;

#[cfg(any(target_os = "linux", target_os = "android"))]
pub mod mount;

#[cfg(any(target_os = "linux"))]
pub mod mqueue;

#[cfg(any(target_os = "linux", target_os = "macos"))]
pub mod poll;

pub mod net;

#[cfg(any(target_os = "linux", target_os = "android"))]
pub mod sched;

pub mod sys;
pub mod unistd;

/*
 *
 * ===== Result / Error =====
 *
 */

use libc::c_char;
use std::{ptr, result};
use std::ffi::{CStr, OsStr};
use std::path::{Path, PathBuf};
use std::os::unix::ffi::OsStrExt;
use std::io;
use std::fmt;
use std::error;
use libc::PATH_MAX;

pub type Result<T> = result::Result<T, Error>;

#[derive(Clone, Copy, Debug, PartialEq)]
pub enum Error {
    Sys(errno::Errno),
    InvalidPath,
}

impl Error {
    pub fn from_errno(errno: errno::Errno) -> Error {
        Error::Sys(errno)
    }

    pub fn last() -> Error {
        Error::Sys(errno::Errno::last())
    }

    pub fn invalid_argument() -> Error {
        Error::Sys(errno::EINVAL)
    }

    pub fn errno(&self) -> errno::Errno {
        match *self {
            Error::Sys(errno) => errno,
            Error::InvalidPath => errno::Errno::EINVAL,
        }
    }
}

impl From<errno::Errno> for Error {
    fn from(errno: errno::Errno) -> Error { Error::from_errno(errno) }
}

impl error::Error for Error {
    fn description(&self) -> &str {
        match self {
            &Error::InvalidPath => "Invalid path",
            &Error::Sys(ref errno) => errno.desc(),
        }
    }
}

impl fmt::Display for Error {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match self {
            &Error::InvalidPath => write!(f, "Invalid path"),
            &Error::Sys(errno) => write!(f, "{:?}: {}", errno, errno.desc()),
        }
    }
}

impl From<Error> for io::Error {
    fn from(err: Error) -> Self {
        match err {
            Error::InvalidPath => io::Error::new(io::ErrorKind::InvalidInput, err),
            Error::Sys(errno) => io::Error::from_raw_os_error(errno as i32),
        }
    }
}

pub trait NixPath {
    fn len(&self) -> usize;

    fn with_nix_path<T, F>(&self, f: F) -> Result<T>
        where F: FnOnce(&CStr) -> T;
}

impl NixPath for str {
    fn len(&self) -> usize {
        NixPath::len(OsStr::new(self))
    }

    fn with_nix_path<T, F>(&self, f: F) -> Result<T>
        where F: FnOnce(&CStr) -> T {
            OsStr::new(self).with_nix_path(f)
        }
}

impl NixPath for OsStr {
    fn len(&self) -> usize {
        self.as_bytes().len()
    }

    fn with_nix_path<T, F>(&self, f: F) -> Result<T>
        where F: FnOnce(&CStr) -> T {
            self.as_bytes().with_nix_path(f)
        }
}

impl NixPath for CStr {
    fn len(&self) -> usize {
        self.to_bytes().len()
    }

    fn with_nix_path<T, F>(&self, f: F) -> Result<T>
            where F: FnOnce(&CStr) -> T {
        // Equivalence with the [u8] impl.
        if self.len() >= PATH_MAX as usize {
            return Err(Error::InvalidPath);
        }

        Ok(f(self))
    }
}

impl NixPath for [u8] {
    fn len(&self) -> usize {
        self.len()
    }

    fn with_nix_path<T, F>(&self, f: F) -> Result<T>
            where F: FnOnce(&CStr) -> T {
        let mut buf = [0u8; PATH_MAX as usize];

        if self.len() >= PATH_MAX as usize {
            return Err(Error::InvalidPath);
        }

        match self.iter().position(|b| *b == 0) {
            Some(_) => Err(Error::InvalidPath),
            None => {
                unsafe {
                    // TODO: Replace with bytes::copy_memory. rust-lang/rust#24028
                    ptr::copy_nonoverlapping(self.as_ptr(), buf.as_mut_ptr(), self.len());
                    Ok(f(CStr::from_ptr(buf.as_ptr() as *const c_char)))
                }

            }
        }
    }
}

impl NixPath for Path {
    fn len(&self) -> usize {
        NixPath::len(self.as_os_str())
    }

    fn with_nix_path<T, F>(&self, f: F) -> Result<T> where F: FnOnce(&CStr) -> T {
        self.as_os_str().with_nix_path(f)
    }
}

impl NixPath for PathBuf {
    fn len(&self) -> usize {
        NixPath::len(self.as_os_str())
    }

    fn with_nix_path<T, F>(&self, f: F) -> Result<T> where F: FnOnce(&CStr) -> T {
        self.as_os_str().with_nix_path(f)
    }
}

/// Treats `None` as an empty string.
impl<'a, NP: ?Sized + NixPath>  NixPath for Option<&'a NP> {
    fn len(&self) -> usize {
        self.map_or(0, NixPath::len)
    }

    fn with_nix_path<T, F>(&self, f: F) -> Result<T> where F: FnOnce(&CStr) -> T {
        if let Some(nix_path) = *self {
            nix_path.with_nix_path(f)
        } else {
            // TODO(#229): avoid extra stack allocation from [u8] impl by
            // replacing with empty CStr.
            b"".with_nix_path(f)
        }
    }
}

#[inline]
pub fn from_ffi(res: libc::c_int) -> Result<()> {
    if res != 0 {
        return Err(Error::Sys(errno::Errno::last()));
    }

    Ok(())
}
<commit_msg>Avoid stack allocation in with_nix_path for Option::None<commit_after>//! Rust friendly bindings to the various *nix system functions.
//!
//! Modules are structured according to the C header file that they would be
//! defined in.
#![crate_name = "nix"]
#![cfg(unix)]
#![allow(non_camel_case_types)]
// latest bitflags triggers a rustc bug with cross-crate macro expansions causing dead_code
// warnings even though the macro expands into something with allow(dead_code)
#![allow(dead_code)]
#![deny(warnings)]

#[macro_use]
extern crate bitflags;

extern crate libc;

#[cfg(test)]
extern crate nix_test as nixtest;

// Re-export some libc constants
pub use libc::{c_int, c_void};

pub mod errno;
pub mod features;
pub mod fcntl;

#[cfg(any(target_os = "linux", target_os = "android"))]
pub mod mount;

#[cfg(any(target_os = "linux"))]
pub mod mqueue;

#[cfg(any(target_os = "linux", target_os = "macos"))]
pub mod poll;

pub mod net;

#[cfg(any(target_os = "linux", target_os = "android"))]
pub mod sched;

pub mod sys;
pub mod unistd;

/*
 *
 * ===== Result / Error =====
 *
 */

use libc::c_char;
use std::{ptr, result};
use std::ffi::{CStr, OsStr};
use std::path::{Path, PathBuf};
use std::os::unix::ffi::OsStrExt;
use std::io;
use std::fmt;
use std::error;
use libc::PATH_MAX;

pub type Result<T> = result::Result<T, Error>;

#[derive(Clone, Copy, Debug, PartialEq)]
pub enum Error {
    Sys(errno::Errno),
    InvalidPath,
}

impl Error {
    pub fn from_errno(errno: errno::Errno) -> Error {
        Error::Sys(errno)
    }

    pub fn last() -> Error {
        Error::Sys(errno::Errno::last())
    }

    pub fn invalid_argument() -> Error {
        Error::Sys(errno::EINVAL)
    }

    pub fn errno(&self) -> errno::Errno {
        match *self {
            Error::Sys(errno) => errno,
            Error::InvalidPath => errno::Errno::EINVAL,
        }
    }
}

impl From<errno::Errno> for Error {
    fn from(errno: errno::Errno) -> Error { Error::from_errno(errno) }
}

impl error::Error for Error {
    fn description(&self) -> &str {
        match self {
            &Error::InvalidPath => "Invalid path",
            &Error::Sys(ref errno) => errno.desc(),
        }
    }
}

impl fmt::Display for Error {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match self {
            &Error::InvalidPath => write!(f, "Invalid path"),
            &Error::Sys(errno) => write!(f, "{:?}: {}", errno, errno.desc()),
        }
    }
}

impl From<Error> for io::Error {
    fn from(err: Error) -> Self {
        match err {
            Error::InvalidPath => io::Error::new(io::ErrorKind::InvalidInput, err),
            Error::Sys(errno) => io::Error::from_raw_os_error(errno as i32),
        }
    }
}

pub trait NixPath {
    fn len(&self) -> usize;

    fn with_nix_path<T, F>(&self, f: F) -> Result<T>
        where F: FnOnce(&CStr) -> T;
}

impl NixPath for str {
    fn len(&self) -> usize {
        NixPath::len(OsStr::new(self))
    }

    fn with_nix_path<T, F>(&self, f: F) -> Result<T>
        where F: FnOnce(&CStr) -> T {
            OsStr::new(self).with_nix_path(f)
        }
}

impl NixPath for OsStr {
    fn len(&self) -> usize {
        self.as_bytes().len()
    }

    fn with_nix_path<T, F>(&self, f: F) -> Result<T>
        where F: FnOnce(&CStr) -> T {
            self.as_bytes().with_nix_path(f)
        }
}

impl NixPath for CStr {
    fn len(&self) -> usize {
        self.to_bytes().len()
    }

    fn with_nix_path<T, F>(&self, f: F) -> Result<T>
            where F: FnOnce(&CStr) -> T {
        // Equivalence with the [u8] impl.
        if self.len() >= PATH_MAX as usize {
            return Err(Error::InvalidPath);
        }

        Ok(f(self))
    }
}

impl NixPath for [u8] {
    fn len(&self) -> usize {
        self.len()
    }

    fn with_nix_path<T, F>(&self, f: F) -> Result<T>
            where F: FnOnce(&CStr) -> T {
        let mut buf = [0u8; PATH_MAX as usize];

        if self.len() >= PATH_MAX as usize {
            return Err(Error::InvalidPath);
        }

        match self.iter().position(|b| *b == 0) {
            Some(_) => Err(Error::InvalidPath),
            None => {
                unsafe {
                    // TODO: Replace with bytes::copy_memory. rust-lang/rust#24028
                    ptr::copy_nonoverlapping(self.as_ptr(), buf.as_mut_ptr(), self.len());
                    Ok(f(CStr::from_ptr(buf.as_ptr() as *const c_char)))
                }

            }
        }
    }
}

impl NixPath for Path {
    fn len(&self) -> usize {
        NixPath::len(self.as_os_str())
    }

    fn with_nix_path<T, F>(&self, f: F) -> Result<T> where F: FnOnce(&CStr) -> T {
        self.as_os_str().with_nix_path(f)
    }
}

impl NixPath for PathBuf {
    fn len(&self) -> usize {
        NixPath::len(self.as_os_str())
    }

    fn with_nix_path<T, F>(&self, f: F) -> Result<T> where F: FnOnce(&CStr) -> T {
        self.as_os_str().with_nix_path(f)
    }
}

/// Treats `None` as an empty string.
impl<'a, NP: ?Sized + NixPath>  NixPath for Option<&'a NP> {
    fn len(&self) -> usize {
        self.map_or(0, NixPath::len)
    }

    fn with_nix_path<T, F>(&self, f: F) -> Result<T> where F: FnOnce(&CStr) -> T {
        if let Some(nix_path) = *self {
            nix_path.with_nix_path(f)
        } else {
            unsafe { CStr::from_ptr("\0".as_ptr() as *const _).with_nix_path(f) }
        }
    }
}

#[inline]
pub fn from_ffi(res: libc::c_int) -> Result<()> {
    if res != 0 {
        return Err(Error::Sys(errno::Errno::last()));
    }

    Ok(())
}
<|endoftext|>