<commit_before>extern crate ansi_term;
extern crate getopts;
extern crate isatty;
extern crate regex;
extern crate ignore;

pub mod lscolors;
pub mod fshelper;

use std::env;
use std::error::Error;
use std::ffi::OsStr;
use std::fs;
use std::io::Write;
use std::path::{Path, Component};
use std::process;

use getopts::Options;
use isatty::stdout_isatty;
use regex::{Regex, RegexBuilder};
use ignore::WalkBuilder;

use lscolors::LsColors;

/// Configuration options for *fd*.
struct FdOptions {
    /// Determines whether the regex search is case-sensitive or case-insensitive.
    case_sensitive: bool,

    /// Whether to search within the full file path or just the base name (filename or directory
    /// name).
    search_full_path: bool,

    /// Whether to ignore hidden files and directories (or not).
    ignore_hidden: bool,

    /// Whether to respect VCS ignore files (`.gitignore`, `.ignore`, ..) or not.
    read_ignore: bool,

    /// Whether to follow symlinks or not.
    follow_links: bool,

    /// The maximum search depth, or `None` if no maximum search depth should be set.
    ///
    /// A depth of `1` includes all files under the current directory, a depth of `2` also includes
    /// all files under subdirectories of the current directory, etc.
    max_depth: Option<usize>,

    /// `None` if the output should not be colorized. Otherwise, a `LsColors` instance that defines
    /// how to style different filetypes.
    ls_colors: Option<LsColors>
}

/// Print a search result to the console.
fn print_entry(path_root: &Path, path_entry: &Path, config: &FdOptions) {
    let path_full = path_root.join(path_entry);

    let path_str = match path_entry.to_str() {
        Some(p) => p,
        None    => return
    };

    if let Some(ref ls_colors) = config.ls_colors {
        let mut component_path = path_root.to_path_buf();

        // Traverse the path and colorize each component
        for component in path_entry.components() {
            let comp_str = match component {
                Component::Normal(p) => p.to_str().unwrap(),
                Component::ParentDir => "..",
                _                    => error("Unexpected path component")
            };

            component_path.push(Path::new(comp_str));

            let style =
                if component_path.symlink_metadata()
                                 .map(|md| md.file_type().is_symlink())
                                 .unwrap_or(false) {
                    ls_colors.symlink
                } else if component_path.is_dir() {
                    ls_colors.directory
                } else {
                    // Look up file name
                    let o_style =
                        component_path.file_name()
                                      .and_then(|n| n.to_str())
                                      .and_then(|n| ls_colors.filenames.get(n));

                    match o_style {
                        Some(s) => *s,
                        None =>
                            // Look up file extension
                            component_path.extension()
                                          .and_then(|e| e.to_str())
                                          .and_then(|e| ls_colors.extensions.get(e))
                                          .cloned()
                                          .unwrap_or_default()
                    }
                };

            print!("{}", style.paint(comp_str));

            if component_path.is_dir() && component_path != path_full {
                let sep = std::path::MAIN_SEPARATOR.to_string();
                print!("{}", style.paint(sep));
            }
        }
        println!();
    } else {
        // Uncolored output:
        println!("{}", path_str);
    }
}

/// Recursively scan the given root path and search for files / pathnames matching the pattern.
fn scan(cwd: &Path, root: &Path, pattern: &Regex, config: &FdOptions) {
    let walker = WalkBuilder::new(root)
                     .hidden(config.ignore_hidden)
                     .ignore(config.read_ignore)
                     .git_ignore(config.read_ignore)
                     .parents(config.read_ignore)
                     .git_global(config.read_ignore)
                     .git_exclude(config.read_ignore)
                     .follow_links(config.follow_links)
                     .max_depth(config.max_depth)
                     .build()
                     .into_iter()
                     .filter_map(|e| e.ok())
                     .filter(|e| e.path() != root);

    for entry in walker {
        let path_rel_buf = match fshelper::path_relative_from(entry.path(), cwd) {
            Some(p) => p,
            None => error("Could not get relative path for directory entry.")
        };
        let path_rel = path_rel_buf.as_path();

        let search_str =
            if config.search_full_path {
                path_rel.to_str()
            } else {
                path_rel.file_name()
                        .and_then(OsStr::to_str)
            };

        search_str.and_then(|s| pattern.find(s))
                  .map(|_| print_entry(cwd, path_rel, config));
    }
}

/// Print error message to stderr and exit with status `1`.
fn error(message: &str) -> ! {
    writeln!(&mut std::io::stderr(), "{}", message)
        .expect("Failed writing to stderr");
    process::exit(1);
}

fn main() {
    let args: Vec<String> = env::args().collect();

    let mut opts = Options::new();
    opts.optflag("h", "help",
                      "print this help message");
    opts.optflag("s", "sensitive",
                      "case-sensitive search (default: smart case)");
    opts.optflag("p", "full-path",
                      "search full path (default: file-/dirname only)");
    opts.optflag("H", "hidden",
                      "search hidden files/directories");
    opts.optflag("I", "no-ignore",
                      "do not respect .(git)ignore files");
    opts.optflag("f", "follow",
                      "follow symlinks");
    opts.optflag("n", "no-color",
                      "do not colorize output");
    opts.optopt("d", "max-depth",
                     "maximum search depth (default: none)", "D");

    let matches = match opts.parse(&args[1..]) {
        Ok(m)  => m,
        Err(e) => error(e.description())
    };

    if matches.opt_present("h") {
        let brief = "Usage: fd [options] [PATTERN] [PATH]";
        print!("{}", opts.usage(brief));
        process::exit(1);
    }

    // Get the search pattern
    let empty_pattern = String::new();
    let pattern = matches.free.get(0).unwrap_or(&empty_pattern);

    // Get the current working directory
    let current_dir_buf = match env::current_dir() {
        Ok(cd) => cd,
        Err(_) => error("Could not get current directory!")
    };
    let current_dir = current_dir_buf.as_path();

    // Get the root directory for the search
    let root_dir_buf = matches.free.get(1)
                                   .and_then(|r| fs::canonicalize(r).ok())
                                   .unwrap_or(current_dir_buf.clone());
    let root_dir = root_dir_buf.as_path();

    // The search will be case-sensitive if the command line flag is set or
    // if the pattern has an uppercase character (smart case).
    let case_sensitive = matches.opt_present("sensitive") ||
                         pattern.chars().any(char::is_uppercase);

    let colored_output = !matches.opt_present("no-color") &&
                         stdout_isatty();

    let ls_colors =
        if colored_output {
            Some(
                env::var("LS_COLORS")
                    .ok()
                    .map(|val| LsColors::from_string(&val))
                    .unwrap_or_default()
            )
        } else {
            None
        };

    let config = FdOptions {
        case_sensitive:    case_sensitive,
        search_full_path:  matches.opt_present("full-path"),
        ignore_hidden:     !matches.opt_present("hidden"),
        read_ignore:       !matches.opt_present("no-ignore"),
        follow_links:      matches.opt_present("follow"),
        max_depth:         matches.opt_str("max-depth")
                                   .and_then(|ds| usize::from_str_radix(&ds, 10).ok()),
        ls_colors:         ls_colors
    };

    match RegexBuilder::new(pattern)
              .case_insensitive(!config.case_sensitive)
              .build() {
        Ok(re)   => scan(current_dir, root_dir, &re, &config),
        Err(err) => error(err.description())
    }
}
<commit_msg>Fix clippy warning<commit_after>extern crate ansi_term;
extern crate getopts;
extern crate isatty;
extern crate regex;
extern crate ignore;

pub mod lscolors;
pub mod fshelper;

use std::env;
use std::error::Error;
use std::ffi::OsStr;
use std::fs;
use std::io::Write;
use std::path::{Path, Component};
use std::process;

use getopts::Options;
use isatty::stdout_isatty;
use regex::{Regex, RegexBuilder};
use ignore::WalkBuilder;

use lscolors::LsColors;

/// Configuration options for *fd*.
struct FdOptions {
    /// Determines whether the regex search is case-sensitive or case-insensitive.
    case_sensitive: bool,

    /// Whether to search within the full file path or just the base name (filename or directory
    /// name).
    search_full_path: bool,

    /// Whether to ignore hidden files and directories (or not).
    ignore_hidden: bool,

    /// Whether to respect VCS ignore files (`.gitignore`, `.ignore`, ..) or not.
    read_ignore: bool,

    /// Whether to follow symlinks or not.
    follow_links: bool,

    /// The maximum search depth, or `None` if no maximum search depth should be set.
    ///
    /// A depth of `1` includes all files under the current directory, a depth of `2` also includes
    /// all files under subdirectories of the current directory, etc.
    max_depth: Option<usize>,

    /// `None` if the output should not be colorized. Otherwise, a `LsColors` instance that defines
    /// how to style different filetypes.
    ls_colors: Option<LsColors>
}

/// Print a search result to the console.
fn print_entry(path_root: &Path, path_entry: &Path, config: &FdOptions) {
    let path_full = path_root.join(path_entry);

    let path_str = match path_entry.to_str() {
        Some(p) => p,
        None    => return
    };

    if let Some(ref ls_colors) = config.ls_colors {
        let mut component_path = path_root.to_path_buf();

        // Traverse the path and colorize each component
        for component in path_entry.components() {
            let comp_str = match component {
                Component::Normal(p) => p.to_str().unwrap(),
                Component::ParentDir => "..",
                _                    => error("Unexpected path component")
            };

            component_path.push(Path::new(comp_str));

            let style =
                if component_path.symlink_metadata()
                                 .map(|md| md.file_type().is_symlink())
                                 .unwrap_or(false) {
                    ls_colors.symlink
                } else if component_path.is_dir() {
                    ls_colors.directory
                } else {
                    // Look up file name
                    let o_style =
                        component_path.file_name()
                                      .and_then(|n| n.to_str())
                                      .and_then(|n| ls_colors.filenames.get(n));

                    match o_style {
                        Some(s) => *s,
                        None =>
                            // Look up file extension
                            component_path.extension()
                                          .and_then(|e| e.to_str())
                                          .and_then(|e| ls_colors.extensions.get(e))
                                          .cloned()
                                          .unwrap_or_default()
                    }
                };

            print!("{}", style.paint(comp_str));

            if component_path.is_dir() && component_path != path_full {
                let sep = std::path::MAIN_SEPARATOR.to_string();
                print!("{}", style.paint(sep));
            }
        }
        println!();
    } else {
        // Uncolored output:
        println!("{}", path_str);
    }
}

/// Recursively scan the given root path and search for files / pathnames matching the pattern.
fn scan(cwd: &Path, root: &Path, pattern: &Regex, config: &FdOptions) {
    let walker = WalkBuilder::new(root)
                     .hidden(config.ignore_hidden)
                     .ignore(config.read_ignore)
                     .git_ignore(config.read_ignore)
                     .parents(config.read_ignore)
                     .git_global(config.read_ignore)
                     .git_exclude(config.read_ignore)
                     .follow_links(config.follow_links)
                     .max_depth(config.max_depth)
                     .build()
                     .into_iter()
                     .filter_map(|e| e.ok())
                     .filter(|e| e.path() != root);

    for entry in walker {
        let path_rel_buf = match fshelper::path_relative_from(entry.path(), cwd) {
            Some(p) => p,
            None => error("Could not get relative path for directory entry.")
        };
        let path_rel = path_rel_buf.as_path();

        let search_str =
            if config.search_full_path {
                path_rel.to_str()
            } else {
                path_rel.file_name()
                        .and_then(OsStr::to_str)
            };

        search_str.and_then(|s| pattern.find(s))
                  .map(|_| print_entry(cwd, path_rel, config));
    }
}

/// Print error message to stderr and exit with status `1`.
fn error(message: &str) -> ! {
    writeln!(&mut std::io::stderr(), "{}", message)
        .expect("Failed writing to stderr");
    process::exit(1);
}

fn main() {
    let args: Vec<String> = env::args().collect();

    let mut opts = Options::new();
    opts.optflag("h", "help",
                      "print this help message");
    opts.optflag("s", "sensitive",
                      "case-sensitive search (default: smart case)");
    opts.optflag("p", "full-path",
                      "search full path (default: file-/dirname only)");
    opts.optflag("H", "hidden",
                      "search hidden files/directories");
    opts.optflag("I", "no-ignore",
                      "do not respect .(git)ignore files");
    opts.optflag("f", "follow",
                      "follow symlinks");
    opts.optflag("n", "no-color",
                      "do not colorize output");
    opts.optopt("d", "max-depth",
                     "maximum search depth (default: none)", "D");

    let matches = match opts.parse(&args[1..]) {
        Ok(m)  => m,
        Err(e) => error(e.description())
    };

    if matches.opt_present("h") {
        let brief = "Usage: fd [options] [PATTERN] [PATH]";
        print!("{}", opts.usage(brief));
        process::exit(1);
    }

    // Get the search pattern
    let empty_pattern = String::new();
    let pattern = matches.free.get(0).unwrap_or(&empty_pattern);

    // Get the current working directory
    let current_dir_buf = match env::current_dir() {
        Ok(cd) => cd,
        Err(_) => error("Could not get current directory!")
    };
    let current_dir = current_dir_buf.as_path();

    // Get the root directory for the search
    let root_dir_buf = matches.free.get(1)
                                   .and_then(|r| fs::canonicalize(r).ok())
                                   .unwrap_or_else(|| current_dir_buf.clone());
    let root_dir = root_dir_buf.as_path();

    // The search will be case-sensitive if the command line flag is set or
    // if the pattern has an uppercase character (smart case).
    let case_sensitive = matches.opt_present("sensitive") ||
                         pattern.chars().any(char::is_uppercase);

    let colored_output = !matches.opt_present("no-color") &&
                         stdout_isatty();

    let ls_colors =
        if colored_output {
            Some(
                env::var("LS_COLORS")
                    .ok()
                    .map(|val| LsColors::from_string(&val))
                    .unwrap_or_default()
            )
        } else {
            None
        };

    let config = FdOptions {
        case_sensitive:    case_sensitive,
        search_full_path:  matches.opt_present("full-path"),
        ignore_hidden:     !matches.opt_present("hidden"),
        read_ignore:       !matches.opt_present("no-ignore"),
        follow_links:      matches.opt_present("follow"),
        max_depth:         matches.opt_str("max-depth")
                                   .and_then(|ds| usize::from_str_radix(&ds, 10).ok()),
        ls_colors:         ls_colors
    };

    match RegexBuilder::new(pattern)
              .case_insensitive(!config.case_sensitive)
              .build() {
        Ok(re)   => scan(current_dir, root_dir, &re, &config),
        Err(err) => error(err.description())
    }
}
<|endoftext|>


<commit_before>#[allow(dead_code)]
#[path = "../libm/src/math/mod.rs"]
mod libm;

macro_rules! no_mangle {
    ($(fn $fun:ident($($iid:ident : $ity:ty),+) -> $oty:ty;)+) => {
        intrinsics! {
            $(
                pub extern "C" fn $fun($($iid: $ity),+) -> $oty {
                    self::libm::$fun($($iid),+)
                }
            )+
        }
    }
}

#[cfg(any(
    all(
        target_arch = "wasm32",
        target_os = "unknown",
        not(target_env = "wasi")
    ),
    all(target_vendor = "fortanix", target_env = "sgx")
))]
no_mangle! {
    fn acos(x: f64) -> f64;
    fn asin(x: f64) -> f64;
    fn atan(x: f64) -> f64;
    fn atan2(x: f64, y: f64) -> f64;
    fn cbrt(x: f64) -> f64;
    fn cosh(x: f64) -> f64;
    fn expm1(x: f64) -> f64;
    fn hypot(x: f64, y: f64) -> f64;
    fn log1p(x: f64) -> f64;
    fn sinh(x: f64) -> f64;
    fn tan(x: f64) -> f64;
    fn tanh(x: f64) -> f64;
    fn cos(x: f64) -> f64;
    fn cosf(x: f32) -> f32;
    fn exp(x: f64) -> f64;
    fn expf(x: f32) -> f32;
    fn log2(x: f64) -> f64;
    fn log2f(x: f32) -> f32;
    fn log10(x: f64) -> f64;
    fn log10f(x: f32) -> f32;
    fn log(x: f64) -> f64;
    fn logf(x: f32) -> f32;
    fn round(x: f64) -> f64;
    fn roundf(x: f32) -> f32;
    fn sin(x: f64) -> f64;
    fn sinf(x: f32) -> f32;
    fn pow(x: f64, y: f64) -> f64;
    fn powf(x: f32, y: f32) -> f32;
    fn exp2(x: f64) -> f64;
    fn exp2f(x: f32) -> f32;
    fn fmod(x: f64, y: f64) -> f64;
    fn fmodf(x: f32, y: f32) -> f32;
    fn fma(x: f64, y: f64, z: f64) -> f64;
    fn fmaf(x: f32, y: f32, z: f32) -> f32;
    fn acosf(n: f32) -> f32;
    fn asinf(n: f32) -> f32;
    fn atan2f(a: f32, b: f32) -> f32;
    fn atanf(n: f32) -> f32;
    fn cbrtf(n: f32) -> f32;
    fn coshf(n: f32) -> f32;
    fn expm1f(n: f32) -> f32;
    fn fdimf(a: f32, b: f32) -> f32;
    fn hypotf(x: f32, y: f32) -> f32;
    fn log1pf(n: f32) -> f32;
    fn sinhf(n: f32) -> f32;
    fn tanf(n: f32) -> f32;
    fn tanhf(n: f32) -> f32;
}

#[cfg(all(target_vendor = "fortanix", target_env = "sgx"))]
no_mangle! {
    fn ceil(x: f64) -> f64;
    fn ceilf(x: f32) -> f32;
    fn floor(x: f64) -> f64;
    fn floorf(x: f32) -> f32;
    fn trunc(x: f64) -> f64;
    fn truncf(x: f32) -> f32;
}

// only for the thumb*-none-eabi* targets
#[cfg(all(target_arch = "arm", target_os = "none"))]
no_mangle! {
    // `f64 % f64`
    fn fmod(x: f64, y: f64) -> f64;
    // `f32 % f32`
    fn fmodf(x: f32, y: f32) -> f32;
}
<commit_msg>Added missing fdim signature<commit_after>#[allow(dead_code)]
#[path = "../libm/src/math/mod.rs"]
mod libm;

macro_rules! no_mangle {
    ($(fn $fun:ident($($iid:ident : $ity:ty),+) -> $oty:ty;)+) => {
        intrinsics! {
            $(
                pub extern "C" fn $fun($($iid: $ity),+) -> $oty {
                    self::libm::$fun($($iid),+)
                }
            )+
        }
    }
}

#[cfg(any(
    all(
        target_arch = "wasm32",
        target_os = "unknown",
        not(target_env = "wasi")
    ),
    all(target_vendor = "fortanix", target_env = "sgx")
))]
no_mangle! {
    fn acos(x: f64) -> f64;
    fn asin(x: f64) -> f64;
    fn atan(x: f64) -> f64;
    fn atan2(x: f64, y: f64) -> f64;
    fn cbrt(x: f64) -> f64;
    fn cosh(x: f64) -> f64;
    fn expm1(x: f64) -> f64;
    fn hypot(x: f64, y: f64) -> f64;
    fn log1p(x: f64) -> f64;
    fn sinh(x: f64) -> f64;
    fn tan(x: f64) -> f64;
    fn tanh(x: f64) -> f64;
    fn cos(x: f64) -> f64;
    fn cosf(x: f32) -> f32;
    fn exp(x: f64) -> f64;
    fn expf(x: f32) -> f32;
    fn log2(x: f64) -> f64;
    fn log2f(x: f32) -> f32;
    fn log10(x: f64) -> f64;
    fn log10f(x: f32) -> f32;
    fn log(x: f64) -> f64;
    fn logf(x: f32) -> f32;
    fn round(x: f64) -> f64;
    fn roundf(x: f32) -> f32;
    fn sin(x: f64) -> f64;
    fn sinf(x: f32) -> f32;
    fn pow(x: f64, y: f64) -> f64;
    fn powf(x: f32, y: f32) -> f32;
    fn exp2(x: f64) -> f64;
    fn exp2f(x: f32) -> f32;
    fn fmod(x: f64, y: f64) -> f64;
    fn fmodf(x: f32, y: f32) -> f32;
    fn fma(x: f64, y: f64, z: f64) -> f64;
    fn fmaf(x: f32, y: f32, z: f32) -> f32;
    fn acosf(n: f32) -> f32;
    fn asinf(n: f32) -> f32;
    fn atan2f(a: f32, b: f32) -> f32;
    fn atanf(n: f32) -> f32;
    fn cbrtf(n: f32) -> f32;
    fn coshf(n: f32) -> f32;
    fn expm1f(n: f32) -> f32;
    fn fdim(a: f64, b: f64) -> f64;
    fn fdimf(a: f32, b: f32) -> f32;
    fn hypotf(x: f32, y: f32) -> f32;
    fn log1pf(n: f32) -> f32;
    fn sinhf(n: f32) -> f32;
    fn tanf(n: f32) -> f32;
    fn tanhf(n: f32) -> f32;
}

#[cfg(all(target_vendor = "fortanix", target_env = "sgx"))]
no_mangle! {
    fn ceil(x: f64) -> f64;
    fn ceilf(x: f32) -> f32;
    fn floor(x: f64) -> f64;
    fn floorf(x: f32) -> f32;
    fn trunc(x: f64) -> f64;
    fn truncf(x: f32) -> f32;
}

// only for the thumb*-none-eabi* targets
#[cfg(all(target_arch = "arm", target_os = "none"))]
no_mangle! {
    // `f64 % f64`
    fn fmod(x: f64, y: f64) -> f64;
    // `f32 % f32`
    fn fmodf(x: f32, y: f32) -> f32;
}
<|endoftext|>


<commit_before>extern crate libc;
extern crate log;

use std::fmt;
use std::io;
use std::io::{Read, Write};
use std::sync::mpsc::{Receiver, RecvTimeoutError};
use std::time::Duration;

use consts::HID_RPT_SIZE;
use core_foundation_sys::base::*;
use u2fprotocol::U2FDevice;

use super::iokit::*;

const READ_TIMEOUT: u64 = 15;

pub struct Report {
    pub data: [u8; HID_RPT_SIZE],
}

unsafe impl Send for Report {}
unsafe impl Sync for Report {}

pub struct Device {
    pub device_ref: IOHIDDeviceRef,
    // Channel ID for U2F HID communication. Needed to implement U2FDevice
    // trait.
    pub cid: [u8; 4],
    pub report_recv: Receiver<Report>,
    pub report_send_void: *mut libc::c_void,
}

impl fmt::Display for Device {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "InternalDevice(ref:{:?}, cid: {:02x}{:02x}{:02x}{:02x})",
               self.device_ref, self.cid[0], self.cid[1], self.cid[2], self.cid[3])
    }
}

impl PartialEq for Device {
    fn eq(&self, other_device: &Device) -> bool {
        self.device_ref == other_device.device_ref
    }
}

impl Read for Device {
    fn read(&mut self, mut bytes: &mut [u8]) -> io::Result<usize> {
        let timeout = Duration::from_secs(READ_TIMEOUT);
        let report_data = match self.report_recv.recv_timeout(timeout) {
            Ok(v) => v,
            Err(e) => {
                if e == RecvTimeoutError::Timeout {
                    return Err(io::Error::new(io::ErrorKind::TimedOut, e));
                }
                return Err(io::Error::new(io::ErrorKind::UnexpectedEof, e));
            },
        };
        let len = bytes.write(&report_data.data).unwrap();
        Ok(len)
    }
}

impl Write for Device {
    fn write(&mut self, bytes: &[u8]) -> io::Result<usize> {
        unsafe { set_report(self.device_ref, kIOHIDReportTypeOutput, bytes) }
    }

    // USB HID writes don't buffer, so this will be a nop.
    fn flush(&mut self) -> io::Result<()> {
        Ok(())
    }
}

impl U2FDevice for Device {
    fn get_cid(&self) -> [u8; 4] {
        return self.cid.clone();
    }
    fn set_cid(&mut self, cid: &[u8; 4]) {
        self.cid.clone_from(cid);
    }
}

unsafe fn set_report(device_ref: IOHIDDeviceRef,
                     report_type: IOHIDReportType,
                     bytes: &[u8])
                     -> io::Result<usize> {
    let report_id = bytes[0] as i64;
    let mut data = bytes.as_ptr();
    let mut length = bytes.len() as CFIndex;

    if report_id == 0x0 {
        // Not using numbered reports, so don't send the report number
        length = length - 1;
        data = data.offset(1);
    }

    let result = IOHIDDeviceSetReport(device_ref, report_type, report_id, data, length);
    if result != 0 {
        warn!("set_report sending failure = {0:X}", result);

        return Err(io::Error::from_raw_os_error(result));
    }
    trace!("set_report sending success = {0:X}", result);

    Ok(length as usize)
}
<commit_msg>Small cleanup in macos::Device::read()<commit_after>extern crate libc;
extern crate log;

use std::fmt;
use std::io;
use std::io::{Read, Write};
use std::sync::mpsc::{Receiver, RecvTimeoutError};
use std::time::Duration;

use consts::HID_RPT_SIZE;
use core_foundation_sys::base::*;
use u2fprotocol::U2FDevice;

use super::iokit::*;

const READ_TIMEOUT: u64 = 15;

pub struct Report {
    pub data: [u8; HID_RPT_SIZE],
}

unsafe impl Send for Report {}
unsafe impl Sync for Report {}

pub struct Device {
    pub device_ref: IOHIDDeviceRef,
    // Channel ID for U2F HID communication. Needed to implement U2FDevice
    // trait.
    pub cid: [u8; 4],
    pub report_recv: Receiver<Report>,
    pub report_send_void: *mut libc::c_void,
}

impl fmt::Display for Device {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "InternalDevice(ref:{:?}, cid: {:02x}{:02x}{:02x}{:02x})",
               self.device_ref, self.cid[0], self.cid[1], self.cid[2], self.cid[3])
    }
}

impl PartialEq for Device {
    fn eq(&self, other_device: &Device) -> bool {
        self.device_ref == other_device.device_ref
    }
}

impl Read for Device {
    fn read(&mut self, mut bytes: &mut [u8]) -> io::Result<usize> {
        let timeout = Duration::from_secs(READ_TIMEOUT);
        let report_data = match self.report_recv.recv_timeout(timeout) {
            Ok(v) => v,
            Err(e) if e == RecvTimeoutError::Timeout => {
                return Err(io::Error::new(io::ErrorKind::TimedOut, e));
            }
            Err(e) => {
                return Err(io::Error::new(io::ErrorKind::UnexpectedEof, e));
            }
        };
        bytes.write(&report_data.data)
    }
}

impl Write for Device {
    fn write(&mut self, bytes: &[u8]) -> io::Result<usize> {
        unsafe { set_report(self.device_ref, kIOHIDReportTypeOutput, bytes) }
    }

    // USB HID writes don't buffer, so this will be a nop.
    fn flush(&mut self) -> io::Result<()> {
        Ok(())
    }
}

impl U2FDevice for Device {
    fn get_cid(&self) -> [u8; 4] {
        return self.cid.clone();
    }

    fn set_cid(&mut self, cid: &[u8; 4]) {
        self.cid.clone_from(cid);
    }
}

unsafe fn set_report(device_ref: IOHIDDeviceRef,
                     report_type: IOHIDReportType,
                     bytes: &[u8])
                     -> io::Result<usize> {
    let report_id = bytes[0] as i64;
    let mut data = bytes.as_ptr();
    let mut length = bytes.len() as CFIndex;

    if report_id == 0x0 {
        // Not using numbered reports, so don't send the report number
        length = length - 1;
        data = data.offset(1);
    }

    let result = IOHIDDeviceSetReport(device_ref, report_type, report_id, data, length);
    if result != 0 {
        warn!("set_report sending failure = {0:X}", result);

        return Err(io::Error::from_raw_os_error(result));
    }
    trace!("set_report sending success = {0:X}", result);

    Ok(length as usize)
}
<|endoftext|>


<commit_before>#[deriving(Clone,Show,Hash)]
pub enum Name {
    Symbol (Box<String>),
    ForkL (Box<Name>),
    ForkR (Box<Name>),
    Pair (Box<Name>,Box<Name>),
}
#[allow(dead_code)]
pub fn symbol (s:String) -> Name {
    Name::Symbol(box s)
}
#[allow(dead_code)]
pub fn fork (n:Name) -> (Name,Name) {
    let m = n.clone () ;
    (Name::ForkL(box n), Name::ForkR(box m))
}
#[allow(dead_code)]
pub fn pair (n:Name, m:Name) -> Name {
    Name::Pair(box n, box m)
}
#[allow(dead_code)]
pub fn printstuff () {
    let n = symbol (format!("one")) ;
    let m = symbol (format!("two")) ;
    println!("Adapton: {}, {}", n, m);
    println!("Adapton: {}, {}", fork(n), m);
}
#[test]
fn test_printstuff () {
    printstuff();
}
<commit_msg>encapsulation<commit_after>#[deriving(Clone,Show,Hash)]
enum NameS {
    Symbol (Box<String>),
    ForkL (Box<Name>),
    ForkR (Box<Name>),
    Pair (Box<Name>,Box<Name>),
}
pub type Name = NameS;
#[allow(dead_code)]
pub fn symbol (s:String) -> Name {
    NameS::Symbol(box s)
}
#[allow(dead_code)]
pub fn fork (n:Name) -> (Name,Name) {
    let m = n.clone () ;
    (NameS::ForkL(box n), NameS::ForkR(box m))
}
#[allow(dead_code)]
pub fn pair (n:Name, m:Name) -> Name {
    NameS::Pair(box n, box m)
}
#[allow(dead_code)]
pub fn printstuff () {
    let n = symbol (format!("one")) ;
    let m = symbol (format!("two")) ;
    println!("Adapton: {}, {}", n, m);
    println!("Adapton: {}, {}", fork(n), m);
}
#[test]
fn test_printstuff () {
    printstuff();
}
<|endoftext|>


<commit_before>

use sound_stream_settings::SoundStreamSettings;

/// The DSP Node contains a vector of children
/// nodes (within the `MixerInput`s), from which
/// audio can be requested as well as the current
/// SoundStream settings.
#[deriving(Show, Clone, Encodable, Decodable)]
pub struct Data {
    /// SoundStreamSettings for buffer calculations.
    pub settings: SoundStreamSettings,
    /// Master volume for DSP node.
    pub vol: f32,
    /// Panning for DSP node.
    /// -1.0 = Left.
    ///  0.0 = Center.
    ///  1.0 = Right.
    pub pan: f32
}

impl Data {
    /// Default constructor for a Data struct.
    pub fn new(settings: SoundStreamSettings) -> Data {
        Data {
            settings: settings,
            vol: 1f32,
            pan: 0.0f32,
        }
    }
}

/// DSP Node trait. Implement this for any audio
/// instrument or effects types. Be sure to add
/// the `Node` struct to a field as well, and
/// override the `get_node` and `get_node_mut`
/// methods by returning a ref (/mut) to it.
pub trait Node {

    /// Return a reference a Data struct owned by the Node.
    fn get_node_data<'a>(&'a mut self) -> &'a mut Data;
    /// Return a reference to the inputs for the Node.
    fn get_inputs<'a>(&'a self) -> Vec<&'a Node> { Vec::new() }
    /// Return a mutable reference to the inputs for the Node.
    fn get_inputs_mut<'a>(&'a mut self) -> Vec<&'a mut Node> { Vec::new() }

    /// Apply settings to self and all inputs.
    fn apply_settings(&mut self, settings: SoundStreamSettings) {
        for input in self.get_inputs_mut().into_iter() {
            input.apply_settings(settings);
        }
        self.get_node_data().settings = settings;
    }

    /// Receive incoming audio (override this
    /// to do something with the input).
    fn audio_received(&mut self, _input: &Vec<f32>) {}

    /// Request audio from inputs, process and
    /// pass back to the output! Override this
    /// method for any synthesis or generative
    /// types.
    fn audio_requested<'a>(&'a mut self, output: &mut Vec<f32>) {
        let frames = self.get_node_data().settings.frames as uint;
        let channels = self.get_node_data().settings.channels as uint;
        {
            let mut vol_per_channel: Vec<f32> = Vec::from_elem(channels, 1f32);
            for input in self.get_inputs_mut().into_iter() {
                let input_vol = input.get_node_data().vol;
                let input_pan = input.get_node_data().pan;
                let mut working: Vec<f32> = Vec::from_elem(frames * channels, 0f32);
                // Call audio_requested for each input.
                input.audio_requested(&mut working);
                // Construct precalculated volume and
                // pan array (for efficiency).
                let (mut vol_l, mut vol_r) = (input_vol, input_vol);
                if input_pan >= 0.0 {
                    vol_l *= (input_pan - 1.0) + 1.0;
                }
                else {
                    vol_r *= input_pan + 1.0;
                }
                for i in range(0, channels) {
                    *vol_per_channel.get_mut(i) = if i == 0 { vol_l } else { vol_r };
                }
                // Sum all input nodes to output (considering
                // pan, vol and interleaving).
                for i in range(0, frames) {
                    for j in range(0, channels) {
                        *output.get_mut(i * channels + j) +=
                            working[i * channels + j] * vol_per_channel[j];
                    }
                }
            }
        }
        // Custom buffer processing.
        self.process_buffer(output);
    }

    /// Override for custom processing of audio per
    /// buffer. This is mainly for audio effects. Get's
    /// called at the end of audio_requested.
    fn process_buffer(&mut self, _output: &mut Vec<f32>) {}

}

<commit_msg>Fixed error in panning.<commit_after>

use sound_stream_settings::SoundStreamSettings;

/// The DSP Node contains a vector of children
/// nodes (within the `MixerInput`s), from which
/// audio can be requested as well as the current
/// SoundStream settings.
#[deriving(Show, Clone, Encodable, Decodable)]
pub struct Data {
    /// SoundStreamSettings for buffer calculations.
    pub settings: SoundStreamSettings,
    /// Master volume for DSP node.
    pub vol: f32,
    /// Panning for DSP node.
    /// -1.0 = Left.
    ///  0.0 = Center.
    ///  1.0 = Right.
    pub pan: f32
}

impl Data {
    /// Default constructor for a Data struct.
    pub fn new(settings: SoundStreamSettings) -> Data {
        Data {
            settings: settings,
            vol: 1f32,
            pan: 0.0f32,
        }
    }
}

/// DSP Node trait. Implement this for any audio
/// instrument or effects types. Be sure to add
/// the `Node` struct to a field as well, and
/// override the `get_node` and `get_node_mut`
/// methods by returning a ref (/mut) to it.
pub trait Node {

    /// Return a reference a Data struct owned by the Node.
    fn get_node_data<'a>(&'a mut self) -> &'a mut Data;
    /// Return a reference to the inputs for the Node.
    fn get_inputs<'a>(&'a self) -> Vec<&'a Node> { Vec::new() }
    /// Return a mutable reference to the inputs for the Node.
    fn get_inputs_mut<'a>(&'a mut self) -> Vec<&'a mut Node> { Vec::new() }

    /// Apply settings to self and all inputs.
    fn apply_settings(&mut self, settings: SoundStreamSettings) {
        for input in self.get_inputs_mut().into_iter() {
            input.apply_settings(settings);
        }
        self.get_node_data().settings = settings;
    }

    /// Receive incoming audio (override this
    /// to do something with the input).
    fn audio_received(&mut self, _input: &Vec<f32>) {}

    /// Request audio from inputs, process and
    /// pass back to the output! Override this
    /// method for any synthesis or generative
    /// types.
    fn audio_requested<'a>(&'a mut self, output: &mut Vec<f32>) {
        let frames = self.get_node_data().settings.frames as uint;
        let channels = self.get_node_data().settings.channels as uint;
        {
            let mut vol_per_channel: Vec<f32> = Vec::from_elem(channels, 1f32);
            for input in self.get_inputs_mut().into_iter() {
                let input_vol = input.get_node_data().vol;
                let input_pan = input.get_node_data().pan;
                let mut working: Vec<f32> = Vec::from_elem(frames * channels, 0f32);
                // Call audio_requested for each input.
                input.audio_requested(&mut working);
                // Construct precalculated volume and
                // pan array (for efficiency).
                let (mut vol_l, mut vol_r) = (input_vol, input_vol);
                if input_pan >= 0.0 { vol_l *= ::std::num::abs(input_pan - 1.0); }
                else                { vol_r *= input_pan + 1.0; }
                for i in range(0, channels) {
                    *vol_per_channel.get_mut(i) = if i == 0 { vol_l } else { vol_r };
                }
                // Sum all input nodes to output (considering
                // pan, vol and interleaving).
                for i in range(0, frames) {
                    for j in range(0, channels) {
                        *output.get_mut(i * channels + j) +=
                            working[i * channels + j] * vol_per_channel[j];
                    }
                }
            }
        }
        // Custom buffer processing.
        self.process_buffer(output);
    }

    /// Override for custom processing of audio per
    /// buffer. This is mainly for audio effects. Get's
    /// called at the end of audio_requested.
    fn process_buffer(&mut self, _output: &mut Vec<f32>) {}

}

<|endoftext|>


<commit_before>#![deny(
    non_camel_case_types,
    non_snake_case,
    path_statements,
    trivial_numeric_casts,
    unstable_features,
    unused_allocation,
    unused_import_braces,
    unused_imports,
    unused_must_use,
    unused_mut,
    unused_qualifications,
    while_true,
)]

extern crate clap;
#[macro_use] extern crate log;
extern crate semver;
extern crate toml;
#[macro_use] extern crate version;

extern crate libimagrt;
extern crate libimagstore;
extern crate libimagentryview;
#[macro_use] extern crate libimagerror;

use std::process::exit;
use std::path::PathBuf;

use libimagrt::setup::generate_runtime_setup;
use libimagerror::trace::trace_error;
use libimagentryview::builtin::stdout::StdoutViewer;
use libimagentryview::builtin::versions::VersionsViewer;
use libimagentryview::viewer::Viewer;

mod ui;

use ui::build_ui;

fn main() {
    let rt = generate_runtime_setup( "imag-view",
                                     &version!()[..],
                                     "View entries (readonly)",
                                     build_ui);

    let entry_id     = rt.cli().value_of("id").unwrap(); // enforced by clap
    let view_header  = rt.cli().is_present("view-header");
    let view_content = rt.cli().is_present("view-content");

    let scmd = match rt.cli().subcommand_matches("view-in") {
        None => {
            debug!("No commandline call");
            exit(1); // we can afford not-executing destructors here
        }
        Some(s) => s,
    };

    let entry = match rt.store().retrieve(PathBuf::from(entry_id)) {
        Ok(fle) => fle,
        Err(e) => {
            trace_error(&e);
            exit(1); // we can afford not-executing destructors here
        }
    };

    let res = if rt.cli().is_present("versions") {
        VersionsViewer::new(rt.store()).view_entry(&entry)
    } else {
        if scmd.is_present("view-in-stdout") {
        } else if scmd.is_present("view-in-ui") {
            warn!("Viewing in UI is currently not supported, switch to stdout");
        } else if scmd.is_present("view-in-browser") {
            warn!("Viewing in browser is currently not supported, switch to stdout");
        } else if scmd.is_present("view-in-texteditor") {
            warn!("Viewing in texteditor is currently not supported, switch to stdout");
        } else if scmd.is_present("view-in-custom") {
            warn!("Viewing in custom is currently not supported, switch to stdout");
        }

        StdoutViewer::new(view_header, view_content).view_entry(&entry)
    };

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

<commit_msg>Replace Store::retrieve() with Store::get()<commit_after>#![deny(
    non_camel_case_types,
    non_snake_case,
    path_statements,
    trivial_numeric_casts,
    unstable_features,
    unused_allocation,
    unused_import_braces,
    unused_imports,
    unused_must_use,
    unused_mut,
    unused_qualifications,
    while_true,
)]

extern crate clap;
#[macro_use] extern crate log;
extern crate semver;
extern crate toml;
#[macro_use] extern crate version;

extern crate libimagrt;
extern crate libimagstore;
extern crate libimagentryview;
#[macro_use] extern crate libimagerror;

use std::process::exit;
use std::path::PathBuf;

use libimagrt::setup::generate_runtime_setup;
use libimagerror::trace::trace_error;
use libimagentryview::builtin::stdout::StdoutViewer;
use libimagentryview::builtin::versions::VersionsViewer;
use libimagentryview::viewer::Viewer;

mod ui;

use ui::build_ui;

fn main() {
    let rt = generate_runtime_setup( "imag-view",
                                     &version!()[..],
                                     "View entries (readonly)",
                                     build_ui);

    let entry_id     = rt.cli().value_of("id").unwrap(); // enforced by clap
    let view_header  = rt.cli().is_present("view-header");
    let view_content = rt.cli().is_present("view-content");

    let scmd = match rt.cli().subcommand_matches("view-in") {
        None => {
            debug!("No commandline call");
            exit(1); // we can afford not-executing destructors here
        }
        Some(s) => s,
    };

    let entry = match rt.store().get(PathBuf::from(entry_id)) {
        Ok(Some(fle)) => fle,
        Ok(None) => {
            error!("Cannot get {}, there is no such id in the store", entry_id);
            exit(1);
        }
        Err(e) => {
            trace_error(&e);
            exit(1); // we can afford not-executing destructors here
        }
    };

    let res = if rt.cli().is_present("versions") {
        VersionsViewer::new(rt.store()).view_entry(&entry)
    } else {
        if scmd.is_present("view-in-stdout") {
        } else if scmd.is_present("view-in-ui") {
            warn!("Viewing in UI is currently not supported, switch to stdout");
        } else if scmd.is_present("view-in-browser") {
            warn!("Viewing in browser is currently not supported, switch to stdout");
        } else if scmd.is_present("view-in-texteditor") {
            warn!("Viewing in texteditor is currently not supported, switch to stdout");
        } else if scmd.is_present("view-in-custom") {
            warn!("Viewing in custom is currently not supported, switch to stdout");
        }

        StdoutViewer::new(view_header, view_content).view_entry(&entry)
    };

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

<|endoftext|>


<commit_before>///! Selected intrusive types, including intrusive references.
///!
///! Use of intrusively-reference-counted objects allows easy creation of sharable reference
///! allows creation of references to e.g. self:
///!
///! ```rust
///! use relemon::util::intrusive
///! struct Quaternion { w: f64, x: f64, y: f64, z: f64 }
///! impl MyType {
///! fn new_on_heap(w: f64, x: f64, y: f64, z: f64) -> Ref<Quaternion>
///! }
///! ```
///!

extern crate core;
use std;
use std::fmt;
use std::mem;
use std::ptr::PtrExt;
use std::ops::Deref;
use std::hash::{Hash, Hasher};

/// Interface for types that can be used with intrusive references.
pub trait RefCounted {
    // Create a reference to the current object.
    fn ref_to_self<T: RefCounted + ExplicitlySized>(&self) -> Ref<T> {
        ref_to_raw(unsafe{std::mem::transmute(&self)})
    }

    /// Fetch the object's current reference count.
    fn get_refcount(&self) -> usize;

    /// Increment the object's reference count, returning the new value.
    fn add_ref(&mut self) -> usize;

    /// Decrement the object's reference count, returning the new value.
    fn remove_ref(&mut self) -> usize;
}

/// Interface required of unsized types used with intrusive references.
pub trait ExplicitlySized {
    /// Get the underlying type's allocation size.
    fn get_type_size(&self) -> usize;

    /// Get the underlying type's allocation alignment.
    fn get_type_align(&self) -> usize;
}

/// Create a simple implementation of util::intrusive::RefCounted for a type.
#[macro_export]
macro_rules! default_refcounted_impl {
    ($target:ident, $($mbr:ident).*) => (
        impl RefCounted for $target {
            fn get_refcount(&self) -> usize { self.$($mbr).* }
            fn add_ref(&mut self) -> usize { self.$($mbr).* += 1; self.$($mbr).* }
            fn remove_ref(&mut self) -> usize { self.$($mbr).* -= 1; self.$($mbr).* }
        });
    ($target:ident<'a>, $($mbr:ident).*) => (
        impl<'a> RefCounted for $target<'a> {
            fn get_refcount(&self) -> usize { self.$($mbr).* }
            fn add_ref(&mut self) -> usize { self.$($mbr).* += 1; self.$($mbr).* }
            fn remove_ref(&mut self) -> usize { self.$($mbr).* -= 1; self.$($mbr).* }
        });
    (<$typ:ident>, $($mbr:ident).*) => (
        impl<$typ> RefCounted for $typ {
            fn get_refcount(&self) -> usize { self.$($mbr).* }
            fn add_ref(&mut self) -> usize { self.$($mbr).* += 1; self.$($mbr).* }
            fn remove_ref(&mut self) -> usize { self.$($mbr).* -= 1; self.$($mbr).* }
        });
}

/// Immutable reference to an intrusively-refcounted object.
pub struct Ref<T: RefCounted + ?Sized>(*const T);

/// Create an intrusive reference via raw pointer.
/// This method is all *kinds* of unsafe, and should **not** be used from
/// user code!
fn ref_to_raw<T: RefCounted + ExplicitlySized>(ptr: *mut T) -> Ref<T> {
    // Transmute into a mutable reference so we can increment the refcount.
    let mut_ref: &mut T = unsafe { &mut *ptr };
    panic_unless!(1 == mut_ref.add_ref(), "unexpected nonzero refcount on unowned raw pointer");
    Ref(ptr)
}

/// Move the given value into the heap, and return a Ref to it.  The value
/// should have a refcount of zero prior to this function.
///
/// # Examples
///
/// ```rust
/// #[macro_use]
/// use cripes::util::intrusive;
///
/// #[derive(Debug)]
/// struct Dog { refcount: usize }
/// default_refcounted_impl!(Dog);
/// let x = intrusive::ref_to_new(Dog{refcount: 0});   // x is an intrusive reference to the heap
/// println!("{:?}", x);
/// drop(x);                  // dropping the sole reference to that location
///                           // will free the memory.
/// ```
pub fn ref_to_new<U: RefCounted + ExplicitlySized, T: ?Sized + RefCounted + ExplicitlySized>(obj: U) -> Ref<T> {
    let mem = unsafe { mem::transmute::<_,*mut T>(std::boxed::into_raw(Box::new(obj))) };
    ref_to_raw(mem)
}

/* **************************************************************** */
impl<T: RefCounted + ExplicitlySized + ?Sized> Ref<T> {
    /// Create a null Ref.  This is probably not very safe.
    pub fn null() -> Ref<T> {
        Ref(std::mem::transmute::<_,*const T>(0))
    }

    /// Check if the ref's internal pointer is NULL.
    pub fn is_null(&self) -> bool { match *self { Ref(x) => (x == 0 as *const T) } }

    /// Get the reference count from the underlying object.
    pub fn get_refcount(&self) -> usize {
        self.deref().get_refcount()
    }

    /// Check if this refers to the same object as another Ref.
    pub fn is_same(&self, other: &Ref<T>) -> bool {
        match *self { Ref(x) => match *other { Ref(y) => (x as usize) == (y as usize) } }
    }
}

/* ================================================================
 * impl std::borrow::Borrow
 */
impl<T: RefCounted + ?Sized>  std::borrow::Borrow<T> for Ref<T> {
    fn borrow(&self) -> &T {
        self.deref()
    }
}

/* ================================================================
 * impl fmt::Display
 */
impl<T: RefCounted + fmt::Display + ?Sized> fmt::Display for Ref<T>  {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            Ref(p) => { assert!(! (p == 0 as *const T));
                        self.deref().fmt(f) } }
    }
}

/* ================================================================
 * impl fmt::Debug
 */
impl<T: RefCounted + fmt::Debug + ?Sized> fmt::Debug for Ref<T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            Ref(value) => {
                write!(f, "Ref {{ 0x{:X}=>", (value as usize));
                self.deref().fmt(f) }
        }
    }
}

/* ================================================================
 * impl Clone
 */
impl<T: RefCounted + ?Sized> Clone for Ref<T> {
    fn clone(&self) -> Self {
        ref_to_raw(self.deref())
    }
}

/* ================================================================
 * impl Deref
 */
impl<T: RefCounted + ?Sized> Deref for Ref<T> {
    type Target = T;
    fn deref(&self) -> &T {
        if self.is_null() { panic!("tried to deref a null pointer") }
        match *self { Ref(p) =>  { &*p }
        }
    }
}

/* ================================================================
 * impl Drop
 */
#[unsafe_destructor]
impl<T: RefCounted + ExplicitlySized + ?Sized> Drop for Ref<T> {
    fn drop(&mut self) {
        match *self {
            Ref(x) => { assert!((x as usize) != 0);
                        let _ref: &mut T = unsafe { &mut *x };
                        if _ref.remove_ref() == 0 {
                            let boxed = unsafe { Box::from_raw(mem::transmute::<_,*mut T>(x)) };
                            drop(boxed); } }
        }
    }
}

/* ================================================================
 * impl PartialEq<T>, Eq<T>
 */
impl<T: Eq + RefCounted + ExplicitlySized + ?Sized> Eq for Ref<T> {}

impl<T: PartialEq<T> + RefCounted + ExplicitlySized + ?Sized> PartialEq<Ref<T>> for Ref<T> {
    fn eq(&self, other: &Ref<T>) -> bool {
        *(*self) == *(*other)
    }
}
impl<T: PartialEq<T> + RefCounted + ExplicitlySized + ?Sized> PartialEq<T> for Ref<T> {
    fn eq(&self, other: &T) -> bool {
        *self == *other
    }
}

/* ================================================================
 * impl Hash<H>
 */
impl<T: ?Sized + ExplicitlySized + RefCounted + Hash> Hash for Ref<T> {
    fn hash<H: Hasher>(&self, state: &mut H) {
        match *self { Ref(..) => self.deref().hash(state) }
    }
}
<commit_msg>util::intrusive: specify `intrusive::` prefix on default_refcounted_impl<commit_after>///! Selected intrusive types, including intrusive references.
///!
///! Use of intrusively-reference-counted objects allows easy creation of sharable reference
///! allows creation of references to e.g. self:
///!
///! ```rust
///! use relemon::util::intrusive
///! struct Quaternion { w: f64, x: f64, y: f64, z: f64 }
///! impl MyType {
///! fn new_on_heap(w: f64, x: f64, y: f64, z: f64) -> Ref<Quaternion>
///! }
///! ```
///!

extern crate core;
use std;
use std::fmt;
use std::mem;
use std::ptr::PtrExt;
use std::ops::Deref;
use std::hash::{Hash, Hasher};

/// Interface for types that can be used with intrusive references.
pub trait RefCounted {
    // Create a reference to the current object.
    fn ref_to_self<T: RefCounted + ExplicitlySized>(&self) -> Ref<T> {
        ref_to_raw(unsafe{std::mem::transmute(&self)})
    }

    /// Fetch the object's current reference count.
    fn get_refcount(&self) -> usize;

    /// Increment the object's reference count, returning the new value.
    fn add_ref(&mut self) -> usize;

    /// Decrement the object's reference count, returning the new value.
    fn remove_ref(&mut self) -> usize;
}

/// Interface required of unsized types used with intrusive references.
pub trait ExplicitlySized {
    /// Get the underlying type's allocation size.
    fn get_type_size(&self) -> usize;

    /// Get the underlying type's allocation alignment.
    fn get_type_align(&self) -> usize;
}

/// Create a simple implementation of util::intrusive::RefCounted for a type.
#[macro_export]
macro_rules! default_refcounted_impl {
    ($target:ident, $($mbr:ident).*) => (
        impl intrusive::RefCounted for $target {
            fn get_refcount(&self) -> usize { self.$($mbr).* }
            fn add_ref(&mut self) -> usize { self.$($mbr).* += 1; self.$($mbr).* }
            fn remove_ref(&mut self) -> usize { self.$($mbr).* -= 1; self.$($mbr).* }
        });
    ($target:ident<'a>, $($mbr:ident).*) => (
        impl<'a> intrusive::RefCounted for $target<'a> {
            fn get_refcount(&self) -> usize { self.$($mbr).* }
            fn add_ref(&mut self) -> usize { self.$($mbr).* += 1; self.$($mbr).* }
            fn remove_ref(&mut self) -> usize { self.$($mbr).* -= 1; self.$($mbr).* }
        });
    (<$typ:ident>, $($mbr:ident).*) => (
        impl<$typ> intrusive::RefCounted for $typ {
            fn get_refcount(&self) -> usize { self.$($mbr).* }
            fn add_ref(&mut self) -> usize { self.$($mbr).* += 1; self.$($mbr).* }
            fn remove_ref(&mut self) -> usize { self.$($mbr).* -= 1; self.$($mbr).* }
        });
}

/// Immutable reference to an intrusively-refcounted object.
pub struct Ref<T: RefCounted + ?Sized>(*const T);

/// Create an intrusive reference via raw pointer.
/// This method is all *kinds* of unsafe, and should **not** be used from
/// user code!
fn ref_to_raw<T: RefCounted + ExplicitlySized>(ptr: *mut T) -> Ref<T> {
    // Transmute into a mutable reference so we can increment the refcount.
    let mut_ref: &mut T = unsafe { &mut *ptr };
    panic_unless!(1 == mut_ref.add_ref(), "unexpected nonzero refcount on unowned raw pointer");
    Ref(ptr)
}

/// Move the given value into the heap, and return a Ref to it.  The value
/// should have a refcount of zero prior to this function.
///
/// # Examples
///
/// ```rust
/// #[macro_use]
/// use cripes::util::intrusive;
///
/// #[derive(Debug)]
/// struct Dog { refcount: usize }
/// default_refcounted_impl!(Dog);
/// let x = intrusive::ref_to_new(Dog{refcount: 0});   // x is an intrusive reference to the heap
/// println!("{:?}", x);
/// drop(x);                  // dropping the sole reference to that location
///                           // will free the memory.
/// ```
pub fn ref_to_new<U: RefCounted + ExplicitlySized, T: ?Sized + RefCounted + ExplicitlySized>(obj: U) -> Ref<T> {
    let mem = unsafe { mem::transmute::<_,*mut T>(std::boxed::into_raw(Box::new(obj))) };
    ref_to_raw(mem)
}

/* **************************************************************** */
impl<T: RefCounted + ExplicitlySized + ?Sized> Ref<T> {
    /// Create a null Ref.  This is probably not very safe.
    pub fn null() -> Ref<T> {
        Ref(std::mem::transmute::<_,*const T>(0))
    }

    /// Check if the ref's internal pointer is NULL.
    pub fn is_null(&self) -> bool { match *self { Ref(x) => (x == 0 as *const T) } }

    /// Get the reference count from the underlying object.
    pub fn get_refcount(&self) -> usize {
        self.deref().get_refcount()
    }

    /// Check if this refers to the same object as another Ref.
    pub fn is_same(&self, other: &Ref<T>) -> bool {
        match *self { Ref(x) => match *other { Ref(y) => (x as usize) == (y as usize) } }
    }
}

/* ================================================================
 * impl std::borrow::Borrow
 */
impl<T: RefCounted + ?Sized>  std::borrow::Borrow<T> for Ref<T> {
    fn borrow(&self) -> &T {
        self.deref()
    }
}

/* ================================================================
 * impl fmt::Display
 */
impl<T: RefCounted + fmt::Display + ?Sized> fmt::Display for Ref<T>  {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            Ref(p) => { assert!(! (p == 0 as *const T));
                        self.deref().fmt(f) } }
    }
}

/* ================================================================
 * impl fmt::Debug
 */
impl<T: RefCounted + fmt::Debug + ?Sized> fmt::Debug for Ref<T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            Ref(value) => {
                write!(f, "Ref {{ 0x{:X}=>", (value as usize));
                self.deref().fmt(f) }
        }
    }
}

/* ================================================================
 * impl Clone
 */
impl<T: RefCounted + ?Sized> Clone for Ref<T> {
    fn clone(&self) -> Self {
        ref_to_raw(self.deref())
    }
}

/* ================================================================
 * impl Deref
 */
impl<T: RefCounted + ?Sized> Deref for Ref<T> {
    type Target = T;
    fn deref(&self) -> &T {
        if self.is_null() { panic!("tried to deref a null pointer") }
        match *self { Ref(p) =>  { &*p }
        }
    }
}

/* ================================================================
 * impl Drop
 */
#[unsafe_destructor]
impl<T: RefCounted + ExplicitlySized + ?Sized> Drop for Ref<T> {
    fn drop(&mut self) {
        match *self {
            Ref(x) => { assert!((x as usize) != 0);
                        let _ref: &mut T = unsafe { &mut *x };
                        if _ref.remove_ref() == 0 {
                            let boxed = unsafe { Box::from_raw(mem::transmute::<_,*mut T>(x)) };
                            drop(boxed); } }
        }
    }
}

/* ================================================================
 * impl PartialEq<T>, Eq<T>
 */
impl<T: Eq + RefCounted + ExplicitlySized + ?Sized> Eq for Ref<T> {}

impl<T: PartialEq<T> + RefCounted + ExplicitlySized + ?Sized> PartialEq<Ref<T>> for Ref<T> {
    fn eq(&self, other: &Ref<T>) -> bool {
        *(*self) == *(*other)
    }
}
impl<T: PartialEq<T> + RefCounted + ExplicitlySized + ?Sized> PartialEq<T> for Ref<T> {
    fn eq(&self, other: &T) -> bool {
        *self == *other
    }
}

/* ================================================================
 * impl Hash<H>
 */
impl<T: ?Sized + ExplicitlySized + RefCounted + Hash> Hash for Ref<T> {
    fn hash<H: Hasher>(&self, state: &mut H) {
        match *self { Ref(..) => self.deref().hash(state) }
    }
}
<|endoftext|>


<commit_before>use std::fs;
use std::io::Read;
use std::str;
use std::process;

use serde_json;
use console::strip_ansi_codes;
use glob::{glob, glob_with, MatchOptions};
use regex::Regex;

use prelude::*;
use utils::xcode::XcodeProjectInfo;

#[derive(Debug, Deserialize)]
pub struct CodePushPackage {
    pub label: String,
}

#[derive(Debug, Deserialize)]
pub struct CodePushDeployment {
    pub name: String,
    pub package: Option<CodePushPackage>,
}

pub fn get_codepush_deployments(app: &str)
    -> Result<Vec<CodePushDeployment>>
{
    let p = process::Command::new("code-push")
        .arg("deployment")
        .arg("ls")
        .arg(app)
        .arg("--format")
        .arg("json")
        .output()?;
    if !p.status.success() {
        let msgstr;
        let detail = if let Ok(msg) = str::from_utf8(&p.stderr) {
            msgstr = strip_ansi_codes(msg);
            if &msgstr[..9] == "[Error]  " {
                &msgstr[9..]
            } else if &msgstr[..8] == "[Error] " {
                &msgstr[8..]
            } else {
                &msgstr
            }
        } else {
            "Unknown Error"
        };
        return Err(format!("Failed to get codepush deployments ({})", detail).into());
    }
    Ok(serde_json::from_slice(&p.stdout)?)
}

pub fn get_codepush_package(app: &str, deployment: &str)
    -> Result<CodePushPackage>
{
    let deployments = get_codepush_deployments(app)?;
    for dep in deployments {
        if_chain! {
            if &dep.name == deployment;
            if let Some(pkg) = dep.package;
            then {
                return Ok(pkg);
            }
        }
    }

    Err(format!("could not find deployment {} for {}", deployment, app).into())
}

pub fn get_codepush_release(package: &CodePushPackage, platform: &str,
                            bundle_id_override: Option<&str>)
    -> Result<String>
{
    lazy_static! {
        static ref APP_ID_RE: Regex = Regex::new(
            r#"applicationId\s+["']([^"']*)["']"#).unwrap();
    }

    if let Some(bundle_id) = bundle_id_override {
        return Ok(format!("{}-codepush:{}", bundle_id, package.label));
    }

    if platform == "ios" {
        if !cfg!(target_os="macos") {
            return Err("Codepush releases for iOS require OS X if no \
                        bundle ID is specified".into());
        }
        let mut opts = MatchOptions::new();
        opts.case_sensitive = false;
        for entry_rv in glob_with("ios/*.xcodeproj", &opts)? {
            if let Ok(entry) = entry_rv {
                let pi = XcodeProjectInfo::from_path(&entry)?;
                if_chain! {
                    if let Some(config) = pi.get_configuration("release")
                        .or_else(|| pi.get_configuration("debug"));
                    if let Some(target) = pi.get_first_target();
                    then {
                        return Ok(pi.get_release_name(
                            target, config,
                            Some(&format!("codepush:{}", package.label)))?);
                    }
                }
            }
        }
        return Err("Could not find plist".into());
    } else if platform == "android" {
        for entry_rv in glob("android/app/build.gradle")? {
            let mut s = String::new();
            if_chain! {
                if let Ok(entry) = entry_rv;
                if let Ok(md) = entry.metadata();
                if md.is_file();
                if let Ok(mut f) = fs::File::open(entry);
                if f.read_to_string(&mut s).is_ok();
                then {
                    return if let Some(app_id_caps) = APP_ID_RE.captures(&s) {
                        Ok(format!("{}-codepush:{}", &app_id_caps[1], package.label))
                    } else {
                        Err("Could not parse app id from build.gradle".into())
                    };
                }
            }
        }
        return Err("Could not find AndroidManifest.xml".into());
    }
    return Err(format!("Unsupported platform '{}'", platform).into());
}
<commit_msg>Refer to releases in codepush code<commit_after>use std::fs;
use std::io::Read;
use std::str;
use std::process;

use serde_json;
use console::strip_ansi_codes;
use glob::{glob, glob_with, MatchOptions};
use regex::Regex;

use prelude::*;
use utils::xcode::XcodeProjectInfo;

#[derive(Debug, Deserialize)]
pub struct CodePushPackage {
    pub label: String,
}

#[derive(Debug, Deserialize)]
pub struct CodePushDeployment {
    pub name: String,
    pub package: Option<CodePushPackage>,
}

pub fn get_codepush_deployments(app: &str)
    -> Result<Vec<CodePushDeployment>>
{
    let p = process::Command::new("code-push")
        .arg("deployment")
        .arg("ls")
        .arg(app)
        .arg("--format")
        .arg("json")
        .output()?;
    if !p.status.success() {
        let msgstr;
        let detail = if let Ok(msg) = str::from_utf8(&p.stderr) {
            msgstr = strip_ansi_codes(msg);
            if &msgstr[..9] == "[Error]  " {
                &msgstr[9..]
            } else if &msgstr[..8] == "[Error] " {
                &msgstr[8..]
            } else {
                &msgstr
            }
        } else {
            "Unknown Error"
        };
        return Err(format!("Failed to get codepush deployments ({})", detail).into());
    }
    Ok(serde_json::from_slice(&p.stdout)?)
}

pub fn get_codepush_package(app: &str, deployment: &str)
    -> Result<CodePushPackage>
{
    let deployments = get_codepush_deployments(app)?;
    for dep in deployments {
        if_chain! {
            if &dep.name == deployment;
            if let Some(pkg) = dep.package;
            then {
                return Ok(pkg);
            }
        }
    }

    Err(format!("could not find deployment {} for {}", deployment, app).into())
}

pub fn get_codepush_release(package: &CodePushPackage, platform: &str,
                            bundle_id_override: Option<&str>)
    -> Result<String>
{
    // this is similar to utils::releases::infer_gradle_release_name
    lazy_static! {
        static ref APP_ID_RE: Regex = Regex::new(
            r#"applicationId\s+["']([^"']*)["']"#).unwrap();
    }

    if let Some(bundle_id) = bundle_id_override {
        return Ok(format!("{}-codepush:{}", bundle_id, package.label));
    }

    if platform == "ios" {
        if !cfg!(target_os="macos") {
            return Err("Codepush releases for iOS require OS X if no \
                        bundle ID is specified".into());
        }
        let mut opts = MatchOptions::new();
        opts.case_sensitive = false;
        for entry_rv in glob_with("ios/*.xcodeproj", &opts)? {
            if let Ok(entry) = entry_rv {
                let pi = XcodeProjectInfo::from_path(&entry)?;
                if_chain! {
                    if let Some(config) = pi.get_configuration("release")
                        .or_else(|| pi.get_configuration("debug"));
                    if let Some(target) = pi.get_first_target();
                    then {
                        return Ok(pi.get_release_name(
                            target, config,
                            Some(&format!("codepush:{}", package.label)))?);
                    }
                }
            }
        }
        return Err("Could not find plist".into());
    } else if platform == "android" {
        for entry_rv in glob("android/app/build.gradle")? {
            let mut s = String::new();
            if_chain! {
                if let Ok(entry) = entry_rv;
                if let Ok(md) = entry.metadata();
                if md.is_file();
                if let Ok(mut f) = fs::File::open(entry);
                if f.read_to_string(&mut s).is_ok();
                then {
                    return if let Some(app_id_caps) = APP_ID_RE.captures(&s) {
                        Ok(format!("{}-codepush:{}", &app_id_caps[1], package.label))
                    } else {
                        Err("Could not parse app id from build.gradle".into())
                    };
                }
            }
        }
        return Err("Could not find AndroidManifest.xml".into());
    }
    return Err(format!("Unsupported platform '{}'", platform).into());
}
<|endoftext|>


<commit_before>
export t;
export create;
export union;
export intersect;
export copy;
export clone;
export get;
export equal;
export clear;
export set_all;
export invert;
export difference;
export set;
export is_true;
export is_false;
export to_vec;
export to_str;
export eq_vec;

// FIXME: With recursive object types, we could implement binary methods like
//        union, intersection, and difference. At that point, we could write
//        an optimizing version of this module that produces a different obj
//        for the case where nbits <= 32.

// FIXME: Almost all the functions in this module should be state fns, but the
//        effect system isn't currently working correctly.
type t = rec(vec[mutable uint] storage, uint nbits);

// FIXME: this should be a constant once they work
fn uint_bits() -> uint { ret 32u + (1u << 32u >> 27u); }

fn create(uint nbits, bool init) -> t {
    auto elt = if (init) { !0u } else { 0u };
    auto storage = vec::init_elt_mut[uint](elt, nbits / uint_bits() + 1u);
    ret rec(storage=storage, nbits=nbits);
}

fn process(&fn(uint, uint) -> uint  op, &t v0, &t v1) -> bool {
    auto len = vec::len(v1.storage);
    assert (vec::len(v0.storage) == len);
    assert (v0.nbits == v1.nbits);
    auto changed = false;
    for each (uint i in uint::range(0u, len)) {
        auto w0 = v0.storage.(i);
        auto w1 = v1.storage.(i);
        auto w = op(w0, w1);
        if (w0 != w) { changed = true; v0.storage.(i) = w; }
    }
    ret changed;
}

fn lor(uint w0, uint w1) -> uint { ret w0 | w1; }

fn union(&t v0, &t v1) -> bool { auto sub = lor; ret process(sub, v0, v1); }

fn land(uint w0, uint w1) -> uint { ret w0 & w1; }

fn intersect(&t v0, &t v1) -> bool {
    auto sub = land;
    ret process(sub, v0, v1);
}

fn right(uint w0, uint w1) -> uint { ret w1; }

fn copy(&t v0, t v1) -> bool { auto sub = right; ret process(sub, v0, v1); }

fn clone(t v) -> t {
    auto storage = vec::init_elt_mut[uint](0u, v.nbits / uint_bits() + 1u);
    auto len = vec::len(v.storage);
    for each (uint i in uint::range(0u, len)) { storage.(i) = v.storage.(i); }
    ret rec(storage=storage, nbits=v.nbits);
}

fn get(&t v, uint i) -> bool {
    assert (i < v.nbits);
    auto bits = uint_bits();
    auto w = i / bits;
    auto b = i % bits;
    auto x = 1u & v.storage.(w) >> b;
    ret x == 1u;
}

fn equal(&t v0, &t v1) -> bool {
    // FIXME: when we can break or return from inside an iterator loop,
    //        we can eliminate this painful while-loop

    auto len = vec::len(v1.storage);
    auto i = 0u;
    while (i < len) {
        if (v0.storage.(i) != v1.storage.(i)) { ret false; }
        i = i + 1u;
    }
    ret true;
}

fn clear(&t v) {
    for each (uint i in uint::range(0u, vec::len(v.storage))) {
        v.storage.(i) = 0u;
    }
}

fn set_all(&t v) {
    for each (uint i in uint::range(0u, v.nbits)) { set(v, i, true); }
}

fn invert(&t v) {
    for each (uint i in uint::range(0u, vec::len(v.storage))) {
        v.storage.(i) = !v.storage.(i);
    }
}

/* v0 = v0 - v1 */
fn difference(&t v0, &t v1) -> bool {
    invert(v1);
    auto b = intersect(v0, v1);
    invert(v1);
    ret b;
}

fn set(&t v, uint i, bool x) {
    assert (i < v.nbits);
    auto bits = uint_bits();
    auto w = i / bits;
    auto b = i % bits;
    auto w0 = v.storage.(w);
    auto flag = 1u << b;
    v.storage.(w) =
        if (x) { v.storage.(w) | flag } else { v.storage.(w) & !flag };
}

/* true if all bits are 1 */
fn is_true(&t v) -> bool {
    for (uint i in to_vec(v)) { if (i != 1u) { ret false; } }
    ret true;
}

/* true if all bits are non-1 */
fn is_false(&t v) -> bool {
    for (uint i in to_vec(v)) { if (i == 1u) { ret false; } }
    ret true;
}

fn init_to_vec(t v, uint i) -> uint { ret if (get(v, i)) { 1u } else { 0u }; }

fn to_vec(&t v) -> vec[uint] {
    auto sub = bind init_to_vec(v, _);
    ret vec::init_fn[uint](sub, v.nbits);
}

fn to_str(&t v) -> str {
    auto rs = "";
    for (uint i in bitv::to_vec(v)) {
        if (i == 1u) { rs += "1"; } else { rs += "0"; }
    }
    ret rs;
}

// FIXME: can we just use structural equality on to_vec?
fn eq_vec(&t v0, &vec[uint] v1) -> bool {
    assert (v0.nbits == vec::len[uint](v1));
    auto len = v0.nbits;
    auto i = 0u;
    while (i < len) {
        auto w0 = get(v0, i);
        auto w1 = v1.(i);
        if (!w0 && w1 != 0u || w0 && w1 == 0u) { ret false; }
        i = i + 1u;
    }
    ret true;
}
//
// Local Variables:
// mode: rust
// fill-column: 78;
// indent-tabs-mode: nil
// c-basic-offset: 4
// buffer-file-coding-system: utf-8-unix
// compile-command: "make -k -C $RBUILD 2>&1 | sed -e 's/\\/x\\//x:\\//g'";
// End:
//
<commit_msg>Get rid of an unused variable<commit_after>
export t;
export create;
export union;
export intersect;
export copy;
export clone;
export get;
export equal;
export clear;
export set_all;
export invert;
export difference;
export set;
export is_true;
export is_false;
export to_vec;
export to_str;
export eq_vec;

// FIXME: With recursive object types, we could implement binary methods like
//        union, intersection, and difference. At that point, we could write
//        an optimizing version of this module that produces a different obj
//        for the case where nbits <= 32.

// FIXME: Almost all the functions in this module should be state fns, but the
//        effect system isn't currently working correctly.
type t = rec(vec[mutable uint] storage, uint nbits);

// FIXME: this should be a constant once they work
fn uint_bits() -> uint { ret 32u + (1u << 32u >> 27u); }

fn create(uint nbits, bool init) -> t {
    auto elt = if (init) { !0u } else { 0u };
    auto storage = vec::init_elt_mut[uint](elt, nbits / uint_bits() + 1u);
    ret rec(storage=storage, nbits=nbits);
}

fn process(&fn(uint, uint) -> uint  op, &t v0, &t v1) -> bool {
    auto len = vec::len(v1.storage);
    assert (vec::len(v0.storage) == len);
    assert (v0.nbits == v1.nbits);
    auto changed = false;
    for each (uint i in uint::range(0u, len)) {
        auto w0 = v0.storage.(i);
        auto w1 = v1.storage.(i);
        auto w = op(w0, w1);
        if (w0 != w) { changed = true; v0.storage.(i) = w; }
    }
    ret changed;
}

fn lor(uint w0, uint w1) -> uint { ret w0 | w1; }

fn union(&t v0, &t v1) -> bool { auto sub = lor; ret process(sub, v0, v1); }

fn land(uint w0, uint w1) -> uint { ret w0 & w1; }

fn intersect(&t v0, &t v1) -> bool {
    auto sub = land;
    ret process(sub, v0, v1);
}

fn right(uint w0, uint w1) -> uint { ret w1; }

fn copy(&t v0, t v1) -> bool { auto sub = right; ret process(sub, v0, v1); }

fn clone(t v) -> t {
    auto storage = vec::init_elt_mut[uint](0u, v.nbits / uint_bits() + 1u);
    auto len = vec::len(v.storage);
    for each (uint i in uint::range(0u, len)) { storage.(i) = v.storage.(i); }
    ret rec(storage=storage, nbits=v.nbits);
}

fn get(&t v, uint i) -> bool {
    assert (i < v.nbits);
    auto bits = uint_bits();
    auto w = i / bits;
    auto b = i % bits;
    auto x = 1u & v.storage.(w) >> b;
    ret x == 1u;
}

fn equal(&t v0, &t v1) -> bool {
    // FIXME: when we can break or return from inside an iterator loop,
    //        we can eliminate this painful while-loop

    auto len = vec::len(v1.storage);
    auto i = 0u;
    while (i < len) {
        if (v0.storage.(i) != v1.storage.(i)) { ret false; }
        i = i + 1u;
    }
    ret true;
}

fn clear(&t v) {
    for each (uint i in uint::range(0u, vec::len(v.storage))) {
        v.storage.(i) = 0u;
    }
}

fn set_all(&t v) {
    for each (uint i in uint::range(0u, v.nbits)) { set(v, i, true); }
}

fn invert(&t v) {
    for each (uint i in uint::range(0u, vec::len(v.storage))) {
        v.storage.(i) = !v.storage.(i);
    }
}

/* v0 = v0 - v1 */
fn difference(&t v0, &t v1) -> bool {
    invert(v1);
    auto b = intersect(v0, v1);
    invert(v1);
    ret b;
}

fn set(&t v, uint i, bool x) {
    assert (i < v.nbits);
    auto bits = uint_bits();
    auto w = i / bits;
    auto b = i % bits;
    auto flag = 1u << b;
    v.storage.(w) =
        if (x) { v.storage.(w) | flag } else { v.storage.(w) & !flag };
}

/* true if all bits are 1 */
fn is_true(&t v) -> bool {
    for (uint i in to_vec(v)) { if (i != 1u) { ret false; } }
    ret true;
}

/* true if all bits are non-1 */
fn is_false(&t v) -> bool {
    for (uint i in to_vec(v)) { if (i == 1u) { ret false; } }
    ret true;
}

fn init_to_vec(t v, uint i) -> uint { ret if (get(v, i)) { 1u } else { 0u }; }

fn to_vec(&t v) -> vec[uint] {
    auto sub = bind init_to_vec(v, _);
    ret vec::init_fn[uint](sub, v.nbits);
}

fn to_str(&t v) -> str {
    auto rs = "";
    for (uint i in bitv::to_vec(v)) {
        if (i == 1u) { rs += "1"; } else { rs += "0"; }
    }
    ret rs;
}

// FIXME: can we just use structural equality on to_vec?
fn eq_vec(&t v0, &vec[uint] v1) -> bool {
    assert (v0.nbits == vec::len[uint](v1));
    auto len = v0.nbits;
    auto i = 0u;
    while (i < len) {
        auto w0 = get(v0, i);
        auto w1 = v1.(i);
        if (!w0 && w1 != 0u || w0 && w1 == 0u) { ret false; }
        i = i + 1u;
    }
    ret true;
}
//
// Local Variables:
// mode: rust
// fill-column: 78;
// indent-tabs-mode: nil
// c-basic-offset: 4
// buffer-file-coding-system: utf-8-unix
// compile-command: "make -k -C $RBUILD 2>&1 | sed -e 's/\\/x\\//x:\\//g'";
// End:
//
<|endoftext|>


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

use eutil::slice_to_str;
use libc::c_int;
use std::boxed;
use std::collections::BTreeMap;
use string::{cef_string_userfree_utf16_alloc, cef_string_userfree_utf16_free};
use string::{cef_string_utf16_set};
use types::{cef_string_multimap_t,cef_string_t};

//cef_string_multimap

#[no_mangle]
pub extern "C" fn cef_string_multimap_alloc() -> *mut cef_string_multimap_t {
    boxed::into_raw(box BTreeMap::new())
}

#[no_mangle]
pub extern "C" fn cef_string_multimap_size(smm: *mut cef_string_multimap_t) -> c_int {
    unsafe {
        if smm.is_null() { return 0; }
        // t1 : collections::btree::map::Values<'_, collections::string::String, collections::vec::Vec<*mut types::cef_string_utf16>>`
        let t1 = (*smm).values();
        // t2 : collections::btree::map::BTreeMap<collections::string::String, collections::vec::Vec<*mut types::cef_string_utf16>>
        let t2 : usize = t1.map(|val| (*val).len()).sum();
        t2 as c_int
    }
}

#[no_mangle]
pub extern "C" fn cef_string_multimap_find_count(smm: *mut cef_string_multimap_t, key: *const cef_string_t) -> c_int {
    unsafe {
        if smm.is_null() { return 0; }
        slice_to_str((*key).str as *const u8, (*key).length as usize, |result| {
            match (*smm).get(result) {
                Some(s) =>  s.len() as c_int,
                None => 0
            }
        })
    }
}

#[no_mangle]
pub extern "C" fn cef_string_multimap_append(smm: *mut cef_string_multimap_t, key: *const cef_string_t, value: *const cef_string_t) -> c_int {
    unsafe {
        if smm.is_null() { return 0; }
        slice_to_str((*key).str as *const u8, (*key).length as usize, |result| {
            let csv = cef_string_userfree_utf16_alloc();
            cef_string_utf16_set((*value).str as *const u16, (*value).length, csv, 1);
            match (*smm).get_mut(result) {
                Some(vc) => (*vc).push(csv),
                None => { (*smm).insert(result.to_owned(), vec!(csv)); }
            }
            1
        })
    }
}

#[no_mangle]
pub extern "C" fn cef_string_multimap_enumerate(smm: *mut cef_string_multimap_t, key: *const cef_string_t, index: c_int, value: *mut cef_string_t) -> c_int {
    unsafe {
        if smm.is_null() { return 0; }
        slice_to_str((*key).str as *const u8, (*key).length as usize, |result| {
            match (*smm).get(result) {
                Some(s) => {
                    if (*s).len() <= index as usize {
                        return 0;
                    }
                    let cs = (*s)[index as usize];
                    cef_string_utf16_set((*cs).str as *const u16, (*cs).length, value, 1)
                }
                None => 0
            }
        })
    }
}

#[no_mangle]
pub extern "C" fn cef_string_multimap_key(smm: *mut cef_string_multimap_t, index: c_int, value: *mut cef_string_t) -> c_int {
    unsafe {
        if index < 0 || smm.is_null() { return 0; }
        let mut rem = index as usize;

        for (key, val) in (*smm).iter() {
            if rem < (*val).len() {
                return cef_string_utf16_set((*key).as_bytes().as_ptr() as *const u16,
                                            (*key).len() as u64,
                                            value,
                                            1);
            } else {
                rem -= (*val).len();
            }
        }
    }
    0
}

#[no_mangle]
pub extern "C" fn cef_string_multimap_value(smm: *mut cef_string_multimap_t, index: c_int, value: *mut cef_string_t) -> c_int {
    unsafe {
        if index < 0 || smm.is_null() { return 0; }
        let mut rem = index as usize;

        for val in (*smm).values() {
            if rem < (*val).len() {
                let cs = (*val)[rem as usize];
                return cef_string_utf16_set((*cs).str as *const u16, (*cs).length, value, 1);
            } else {
                rem -= (*val).len();
            }
        }
    }
    0
}

#[no_mangle]
pub extern "C" fn cef_string_multimap_clear(smm: *mut cef_string_multimap_t) {
    unsafe {
        if smm.is_null() { return; }
        if (*smm).len() == 0 { return; }
        for (_, val) in (*smm).iter_mut() {
            while (*val).len() != 0 {
                let cs = (*val).pop();
                cef_string_userfree_utf16_free(cs.unwrap());
            }
        }
        (*smm).clear();
    }
}

#[no_mangle]
pub extern "C" fn cef_string_multimap_free(smm: *mut cef_string_multimap_t) {
    unsafe {
        if smm.is_null() { return; }
        cef_string_multimap_clear(smm);
        drop(Box::from_raw(smm));
    }
}
<commit_msg>Use pop() better in cef_string_multimap_clear.<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use eutil::slice_to_str;
use libc::c_int;
use std::boxed;
use std::collections::BTreeMap;
use string::{cef_string_userfree_utf16_alloc, cef_string_userfree_utf16_free};
use string::{cef_string_utf16_set};
use types::{cef_string_multimap_t,cef_string_t};

//cef_string_multimap

#[no_mangle]
pub extern "C" fn cef_string_multimap_alloc() -> *mut cef_string_multimap_t {
    boxed::into_raw(box BTreeMap::new())
}

#[no_mangle]
pub extern "C" fn cef_string_multimap_size(smm: *mut cef_string_multimap_t) -> c_int {
    unsafe {
        if smm.is_null() { return 0; }
        // t1 : collections::btree::map::Values<'_, collections::string::String, collections::vec::Vec<*mut types::cef_string_utf16>>`
        let t1 = (*smm).values();
        // t2 : collections::btree::map::BTreeMap<collections::string::String, collections::vec::Vec<*mut types::cef_string_utf16>>
        let t2 : usize = t1.map(|val| (*val).len()).sum();
        t2 as c_int
    }
}

#[no_mangle]
pub extern "C" fn cef_string_multimap_find_count(smm: *mut cef_string_multimap_t, key: *const cef_string_t) -> c_int {
    unsafe {
        if smm.is_null() { return 0; }
        slice_to_str((*key).str as *const u8, (*key).length as usize, |result| {
            match (*smm).get(result) {
                Some(s) =>  s.len() as c_int,
                None => 0
            }
        })
    }
}

#[no_mangle]
pub extern "C" fn cef_string_multimap_append(smm: *mut cef_string_multimap_t, key: *const cef_string_t, value: *const cef_string_t) -> c_int {
    unsafe {
        if smm.is_null() { return 0; }
        slice_to_str((*key).str as *const u8, (*key).length as usize, |result| {
            let csv = cef_string_userfree_utf16_alloc();
            cef_string_utf16_set((*value).str as *const u16, (*value).length, csv, 1);
            match (*smm).get_mut(result) {
                Some(vc) => (*vc).push(csv),
                None => { (*smm).insert(result.to_owned(), vec!(csv)); }
            }
            1
        })
    }
}

#[no_mangle]
pub extern "C" fn cef_string_multimap_enumerate(smm: *mut cef_string_multimap_t, key: *const cef_string_t, index: c_int, value: *mut cef_string_t) -> c_int {
    unsafe {
        if smm.is_null() { return 0; }
        slice_to_str((*key).str as *const u8, (*key).length as usize, |result| {
            match (*smm).get(result) {
                Some(s) => {
                    if (*s).len() <= index as usize {
                        return 0;
                    }
                    let cs = (*s)[index as usize];
                    cef_string_utf16_set((*cs).str as *const u16, (*cs).length, value, 1)
                }
                None => 0
            }
        })
    }
}

#[no_mangle]
pub extern "C" fn cef_string_multimap_key(smm: *mut cef_string_multimap_t, index: c_int, value: *mut cef_string_t) -> c_int {
    unsafe {
        if index < 0 || smm.is_null() { return 0; }
        let mut rem = index as usize;

        for (key, val) in (*smm).iter() {
            if rem < (*val).len() {
                return cef_string_utf16_set((*key).as_bytes().as_ptr() as *const u16,
                                            (*key).len() as u64,
                                            value,
                                            1);
            } else {
                rem -= (*val).len();
            }
        }
    }
    0
}

#[no_mangle]
pub extern "C" fn cef_string_multimap_value(smm: *mut cef_string_multimap_t, index: c_int, value: *mut cef_string_t) -> c_int {
    unsafe {
        if index < 0 || smm.is_null() { return 0; }
        let mut rem = index as usize;

        for val in (*smm).values() {
            if rem < (*val).len() {
                let cs = (*val)[rem as usize];
                return cef_string_utf16_set((*cs).str as *const u16, (*cs).length, value, 1);
            } else {
                rem -= (*val).len();
            }
        }
    }
    0
}

#[no_mangle]
pub extern "C" fn cef_string_multimap_clear(smm: *mut cef_string_multimap_t) {
    unsafe {
        if smm.is_null() { return; }
        if (*smm).len() == 0 { return; }
        for (_, val) in (*smm).iter_mut() {
            while let Some(cs) = (*val).pop() {
                cef_string_userfree_utf16_free(cs);
            }
        }
        (*smm).clear();
    }
}

#[no_mangle]
pub extern "C" fn cef_string_multimap_free(smm: *mut cef_string_multimap_t) {
    unsafe {
        if smm.is_null() { return; }
        cef_string_multimap_clear(smm);
        drop(Box::from_raw(smm));
    }
}
<|endoftext|>