<commit_before>//! Diagnostic reporting support for the codespan crate

use codespan::{FileId, Span};
#[cfg(feature = "serialization")]
use serde::{Deserialize, Serialize};
use std::cmp::Ordering;

/// A severity level for diagnostic messages.
///
/// These are ordered in the following way:
///
/// ```rust
/// use codespan_reporting::Severity;
///
/// assert!(Severity::Bug > Severity::Error);
/// assert!(Severity::Error > Severity::Warning);
/// assert!(Severity::Warning > Severity::Note);
/// assert!(Severity::Note > Severity::Help);
/// ```
#[derive(Copy, Clone, PartialEq, Hash, Debug)]
#[cfg_attr(feature = "memory_usage", derive(heapsize_derive::HeapSizeOf))]
#[cfg_attr(feature = "serialization", derive(Serialize, Deserialize))]
pub enum Severity {
    /// An unexpected bug.
    Bug,
    /// An error.
    Error,
    /// A warning.
    Warning,
    /// A note.
    Note,
    /// A help message.
    Help,
}

impl Severity {
    /// We want bugs to be the maximum severity, errors next, etc...
    fn to_cmp_int(self) -> u8 {
        match self {
            Severity::Bug => 5,
            Severity::Error => 4,
            Severity::Warning => 3,
            Severity::Note => 2,
            Severity::Help => 1,
        }
    }
}

impl PartialOrd for Severity {
    fn partial_cmp(&self, other: &Severity) -> Option<Ordering> {
        u8::partial_cmp(&self.to_cmp_int(), &other.to_cmp_int())
    }
}

/// A label describing an underlined region of code associated with a diagnostic.
#[derive(Clone, Debug)]
#[cfg_attr(feature = "memory_usage", derive(heapsize_derive::HeapSizeOf))]
#[cfg_attr(feature = "serialization", derive(Serialize, Deserialize))]
pub struct Label {
    /// The file that we are labelling.
    pub file_id: FileId,
    /// The span we are going to include in the final snippet.
    pub span: Span,
    /// A message to provide some additional information for the underlined
    /// code. These should not include line breaks.
    pub message: String,
}

impl Label {
    /// Create a new label.
    pub fn new(file_id: FileId, span: impl Into<Span>, message: impl Into<String>) -> Label {
        Label {
            file_id,
            span: span.into(),
            message: message.into(),
        }
    }
}

/// Represents a diagnostic message that can provide information like errors and
/// warnings to the user.
#[derive(Clone, Debug)]
#[cfg_attr(feature = "memory_usage", derive(heapsize_derive::HeapSizeOf))]
#[cfg_attr(feature = "serialization", derive(Serialize, Deserialize))]
pub struct Diagnostic {
    /// The overall severity of the diagnostic
    pub severity: Severity,
    /// An optional code that identifies this diagnostic.
    pub code: Option<String>,
    /// The main message associated with this diagnostic. These should not
    /// include line breaks.
    pub message: String,
    /// A label that describes the primary cause of this diagnostic.
    pub primary_label: Label,
    /// Notes that are associated with the primary cause of the diagnostic.
    /// These can include line breaks for improved formatting.
    pub notes: Vec<String>,
    /// Secondary labels that provide additional context for the diagnostic.
    pub secondary_labels: Vec<Label>,
}

impl Diagnostic {
    /// Create a new diagnostic.
    pub fn new(severity: Severity, message: impl Into<String>, primary_label: Label) -> Diagnostic {
        Diagnostic {
            severity,
            code: None,
            message: message.into(),
            primary_label,
            notes: Vec::new(),
            secondary_labels: Vec::new(),
        }
    }

    /// Create a new diagnostic with a severity of `Severity::Bug`.
    pub fn new_bug(message: impl Into<String>, primary_label: Label) -> Diagnostic {
        Diagnostic::new(Severity::Bug, message, primary_label)
    }

    /// Create a new diagnostic with a severity of `Severity::Error`.
    pub fn new_error(message: impl Into<String>, primary_label: Label) -> Diagnostic {
        Diagnostic::new(Severity::Error, message, primary_label)
    }

    /// Create a new diagnostic with a severity of `Severity::Warning`.
    pub fn new_warning(message: impl Into<String>, primary_label: Label) -> Diagnostic {
        Diagnostic::new(Severity::Warning, message, primary_label)
    }

    /// Create a new diagnostic with a severity of `Severity::Note`.
    pub fn new_note(message: impl Into<String>, primary_label: Label) -> Diagnostic {
        Diagnostic::new(Severity::Note, message, primary_label)
    }

    /// Create a new diagnostic with a severity of `Severity::Help`.
    pub fn new_help(message: impl Into<String>, primary_label: Label) -> Diagnostic {
        Diagnostic::new(Severity::Help, message, primary_label)
    }

    /// Add an error code to the diagnostic.
    pub fn with_code(mut self, code: impl Into<String>) -> Diagnostic {
        self.code = Some(code.into());
        self
    }

    /// Add some notes to the diagnostic.
    pub fn with_notes(mut self, notes: Vec<String>) -> Diagnostic {
        self.notes = notes;
        self
    }

    /// Add some secondary labels to the diagnostic.
    pub fn with_secondary_labels(mut self, labels: impl IntoIterator<Item = Label>) -> Diagnostic {
        self.secondary_labels.extend(labels);
        self
    }
}
<commit_msg>Improve style advice for the diagnostic message<commit_after>//! Diagnostic reporting support for the codespan crate

use codespan::{FileId, Span};
#[cfg(feature = "serialization")]
use serde::{Deserialize, Serialize};
use std::cmp::Ordering;

/// A severity level for diagnostic messages.
///
/// These are ordered in the following way:
///
/// ```rust
/// use codespan_reporting::Severity;
///
/// assert!(Severity::Bug > Severity::Error);
/// assert!(Severity::Error > Severity::Warning);
/// assert!(Severity::Warning > Severity::Note);
/// assert!(Severity::Note > Severity::Help);
/// ```
#[derive(Copy, Clone, PartialEq, Hash, Debug)]
#[cfg_attr(feature = "memory_usage", derive(heapsize_derive::HeapSizeOf))]
#[cfg_attr(feature = "serialization", derive(Serialize, Deserialize))]
pub enum Severity {
    /// An unexpected bug.
    Bug,
    /// An error.
    Error,
    /// A warning.
    Warning,
    /// A note.
    Note,
    /// A help message.
    Help,
}

impl Severity {
    /// We want bugs to be the maximum severity, errors next, etc...
    fn to_cmp_int(self) -> u8 {
        match self {
            Severity::Bug => 5,
            Severity::Error => 4,
            Severity::Warning => 3,
            Severity::Note => 2,
            Severity::Help => 1,
        }
    }
}

impl PartialOrd for Severity {
    fn partial_cmp(&self, other: &Severity) -> Option<Ordering> {
        u8::partial_cmp(&self.to_cmp_int(), &other.to_cmp_int())
    }
}

/// A label describing an underlined region of code associated with a diagnostic.
#[derive(Clone, Debug)]
#[cfg_attr(feature = "memory_usage", derive(heapsize_derive::HeapSizeOf))]
#[cfg_attr(feature = "serialization", derive(Serialize, Deserialize))]
pub struct Label {
    /// The file that we are labelling.
    pub file_id: FileId,
    /// The span we are going to include in the final snippet.
    pub span: Span,
    /// A message to provide some additional information for the underlined
    /// code. These should not include line breaks.
    pub message: String,
}

impl Label {
    /// Create a new label.
    pub fn new(file_id: FileId, span: impl Into<Span>, message: impl Into<String>) -> Label {
        Label {
            file_id,
            span: span.into(),
            message: message.into(),
        }
    }
}

/// Represents a diagnostic message that can provide information like errors and
/// warnings to the user.
#[derive(Clone, Debug)]
#[cfg_attr(feature = "memory_usage", derive(heapsize_derive::HeapSizeOf))]
#[cfg_attr(feature = "serialization", derive(Serialize, Deserialize))]
pub struct Diagnostic {
    /// The overall severity of the diagnostic
    pub severity: Severity,
    /// An optional code that identifies this diagnostic.
    pub code: Option<String>,
    /// The main message associated with this diagnostic.
    ///
    /// These should not include line breaks, and the message should be specific
    /// enough to make sense when paired only with the location given by the
    /// `primary_label`.
    pub message: String,
    /// A label that describes the primary cause of this diagnostic.
    pub primary_label: Label,
    /// Notes that are associated with the primary cause of the diagnostic.
    /// These can include line breaks for improved formatting.
    pub notes: Vec<String>,
    /// Secondary labels that provide additional context for the diagnostic.
    pub secondary_labels: Vec<Label>,
}

impl Diagnostic {
    /// Create a new diagnostic.
    pub fn new(severity: Severity, message: impl Into<String>, primary_label: Label) -> Diagnostic {
        Diagnostic {
            severity,
            code: None,
            message: message.into(),
            primary_label,
            notes: Vec::new(),
            secondary_labels: Vec::new(),
        }
    }

    /// Create a new diagnostic with a severity of `Severity::Bug`.
    pub fn new_bug(message: impl Into<String>, primary_label: Label) -> Diagnostic {
        Diagnostic::new(Severity::Bug, message, primary_label)
    }

    /// Create a new diagnostic with a severity of `Severity::Error`.
    pub fn new_error(message: impl Into<String>, primary_label: Label) -> Diagnostic {
        Diagnostic::new(Severity::Error, message, primary_label)
    }

    /// Create a new diagnostic with a severity of `Severity::Warning`.
    pub fn new_warning(message: impl Into<String>, primary_label: Label) -> Diagnostic {
        Diagnostic::new(Severity::Warning, message, primary_label)
    }

    /// Create a new diagnostic with a severity of `Severity::Note`.
    pub fn new_note(message: impl Into<String>, primary_label: Label) -> Diagnostic {
        Diagnostic::new(Severity::Note, message, primary_label)
    }

    /// Create a new diagnostic with a severity of `Severity::Help`.
    pub fn new_help(message: impl Into<String>, primary_label: Label) -> Diagnostic {
        Diagnostic::new(Severity::Help, message, primary_label)
    }

    /// Add an error code to the diagnostic.
    pub fn with_code(mut self, code: impl Into<String>) -> Diagnostic {
        self.code = Some(code.into());
        self
    }

    /// Add some notes to the diagnostic.
    pub fn with_notes(mut self, notes: Vec<String>) -> Diagnostic {
        self.notes = notes;
        self
    }

    /// Add some secondary labels to the diagnostic.
    pub fn with_secondary_labels(mut self, labels: impl IntoIterator<Item = Label>) -> Diagnostic {
        self.secondary_labels.extend(labels);
        self
    }
}
<|endoftext|>


<commit_before>use std::path::Path;
use std::os::unix::prelude::*;

use nix::fcntl::{O_RDWR, open};
use nix::pty::*;
use nix::sys::stat;
use nix::sys::termios::*;
use nix::unistd::{read, write, close};

/// Test equivalence of `ptsname` and `ptsname_r`
#[test]
#[cfg(any(target_os = "android", target_os = "linux"))]
fn test_ptsname_equivalence() {
    // Open a new PTTY master
    let master_fd = posix_openpt(O_RDWR).unwrap();
    assert!(master_fd.as_raw_fd() > 0);

    // Get the name of the slave
    let slave_name = ptsname(&master_fd).unwrap();
    let slave_name_r = ptsname_r(&master_fd).unwrap();
    assert_eq!(slave_name, slave_name_r);
}

/// Test data copying of `ptsname`
#[test]
#[cfg(any(target_os = "android", target_os = "linux"))]
fn test_ptsname_copy() {
    // Open a new PTTY master
    let master_fd = posix_openpt(O_RDWR).unwrap();
    assert!(master_fd.as_raw_fd() > 0);

    // Get the name of the slave
    let slave_name1 = ptsname(&master_fd).unwrap();
    let slave_name2 = ptsname(&master_fd).unwrap();
    assert!(slave_name1 == slave_name2);
    // Also make sure that the string was actually copied and they point to different parts of
    // memory.
    assert!(slave_name1.as_ptr() != slave_name2.as_ptr());
}

/// Test data copying of `ptsname_r`
#[test]
#[cfg(any(target_os = "android", target_os = "linux"))]
fn test_ptsname_r_copy() {
    // Open a new PTTY master
    let master_fd = posix_openpt(O_RDWR).unwrap();
    assert!(master_fd.as_raw_fd() > 0);

    // Get the name of the slave
    let slave_name1 = ptsname_r(&master_fd).unwrap();
    let slave_name2 = ptsname_r(&master_fd).unwrap();
    assert!(slave_name1 == slave_name2);
    assert!(slave_name1.as_ptr() != slave_name2.as_ptr());
}

/// Test that `ptsname` returns different names for different devices
#[test]
#[cfg(any(target_os = "android", target_os = "linux"))]
fn test_ptsname_unique() {
    // Open a new PTTY master
    let master1_fd = posix_openpt(O_RDWR).unwrap();
    assert!(master1_fd.as_raw_fd() > 0);

    // Open a second PTTY master
    let master2_fd = posix_openpt(O_RDWR).unwrap();
    assert!(master2_fd.as_raw_fd() > 0);

    // Get the name of the slave
    let slave_name1 = ptsname(&master1_fd).unwrap();
    let slave_name2 = ptsname(&master2_fd).unwrap();
    assert!(slave_name1 != slave_name2);
}

/// Test opening a master/slave PTTY pair
///
/// This is a single larger test because much of these functions aren't useful by themselves. So for
/// this test we perform the basic act of getting a file handle for a connect master/slave PTTY
/// pair.
#[test]
fn test_open_ptty_pair() {
    // Open a new PTTY master
    let master_fd = posix_openpt(O_RDWR).unwrap();
    assert!(master_fd.as_raw_fd() > 0);

    // Allow a slave to be generated for it
    grantpt(&master_fd).unwrap();
    unlockpt(&master_fd).unwrap();

    // Get the name of the slave
    let slave_name = ptsname(&master_fd).unwrap();

    // Open the slave device
    let slave_fd = open(Path::new(&slave_name), O_RDWR, stat::Mode::empty()).unwrap();
    assert!(slave_fd > 0);
}

#[test]
fn test_openpty() {
    let pty = openpty(None, None).unwrap();
    assert!(pty.master > 0);
    assert!(pty.slave > 0);

    // Writing to one should be readable on the other one
    let string = "foofoofoo\n";
    let mut buf = [0u8; 16];
    write(pty.master, string.as_bytes()).unwrap();
    let len = read(pty.slave, &mut buf).unwrap();

    assert_eq!(len, string.len());
    assert_eq!(&buf[0..len], string.as_bytes());

    // Read the echo as well
    let echoed_string = "foofoofoo\r\n";
    let len = read(pty.master, &mut buf).unwrap();
    assert_eq!(len, echoed_string.len());
    assert_eq!(&buf[0..len], echoed_string.as_bytes());

    let string2 = "barbarbarbar\n";
    let echoed_string2 = "barbarbarbar\r\n";
    write(pty.slave, string2.as_bytes()).unwrap();
    let len = read(pty.master, &mut buf).unwrap();

    assert_eq!(len, echoed_string2.len());
    assert_eq!(&buf[0..len], echoed_string2.as_bytes());

    close(pty.master).unwrap();
    close(pty.slave).unwrap();
}

#[test]
fn test_openpty_with_termios() {
    // Open one pty to get attributes for the second one
    let mut termios = {
        let pty = openpty(None, None).unwrap();
        assert!(pty.master > 0);
        assert!(pty.slave > 0);
        let termios = tcgetattr(pty.master).unwrap();
        close(pty.master).unwrap();
        close(pty.slave).unwrap();
        termios
    };
    termios.c_oflag &= !ONLCR;

    let pty = openpty(None, &termios).unwrap();
    // Must be valid file descriptors
    assert!(pty.master > 0);
    assert!(pty.slave > 0);

    // Writing to one should be readable on the other one
    let string = "foofoofoo\n";
    let mut buf = [0u8; 16];
    write(pty.master, string.as_bytes()).unwrap();
    let len = read(pty.slave, &mut buf).unwrap();

    assert_eq!(len, string.len());
    assert_eq!(&buf[0..len], string.as_bytes());

    // read the echo as well
    let echoed_string = "foofoofoo\n";
    let len = read(pty.master, &mut buf).unwrap();
    assert_eq!(len, echoed_string.len());
    assert_eq!(&buf[0..len], echoed_string.as_bytes());

    let string2 = "barbarbarbar\n";
    let echoed_string2 = "barbarbarbar\n";
    write(pty.slave, string2.as_bytes()).unwrap();
    let len = read(pty.master, &mut buf).unwrap();

    assert_eq!(len, echoed_string2.len());
    assert_eq!(&buf[0..len], echoed_string2.as_bytes());

    close(pty.master).unwrap();
    close(pty.slave).unwrap();
}
<commit_msg>Handle short reads in pty tests<commit_after>use std::path::Path;
use std::os::unix::prelude::*;

use nix::fcntl::{O_RDWR, open};
use nix::pty::*;
use nix::sys::stat;
use nix::sys::termios::*;
use nix::unistd::{read, write, close};

/// Helper function analogous to std::io::Read::read_exact, but for `RawFD`s
fn read_exact(f: RawFd, buf: &mut  [u8]) {
    let mut len = 0;
    while len < buf.len() {
        // get_mut would be better than split_at_mut, but it requires nightly
        let (_, remaining) = buf.split_at_mut(len);
        len += read(f, remaining).unwrap();
    }
}

/// Test equivalence of `ptsname` and `ptsname_r`
#[test]
#[cfg(any(target_os = "android", target_os = "linux"))]
fn test_ptsname_equivalence() {
    // Open a new PTTY master
    let master_fd = posix_openpt(O_RDWR).unwrap();
    assert!(master_fd.as_raw_fd() > 0);

    // Get the name of the slave
    let slave_name = ptsname(&master_fd).unwrap();
    let slave_name_r = ptsname_r(&master_fd).unwrap();
    assert_eq!(slave_name, slave_name_r);
}

/// Test data copying of `ptsname`
// TODO need to run in a subprocess, since ptsname is non-reentrant
#[test]
#[cfg(any(target_os = "android", target_os = "linux"))]
fn test_ptsname_copy() {
    // Open a new PTTY master
    let master_fd = posix_openpt(O_RDWR).unwrap();
    assert!(master_fd.as_raw_fd() > 0);

    // Get the name of the slave
    let slave_name1 = ptsname(&master_fd).unwrap();
    let slave_name2 = ptsname(&master_fd).unwrap();
    assert!(slave_name1 == slave_name2);
    // Also make sure that the string was actually copied and they point to different parts of
    // memory.
    assert!(slave_name1.as_ptr() != slave_name2.as_ptr());
}

/// Test data copying of `ptsname_r`
#[test]
#[cfg(any(target_os = "android", target_os = "linux"))]
fn test_ptsname_r_copy() {
    // Open a new PTTY master
    let master_fd = posix_openpt(O_RDWR).unwrap();
    assert!(master_fd.as_raw_fd() > 0);

    // Get the name of the slave
    let slave_name1 = ptsname_r(&master_fd).unwrap();
    let slave_name2 = ptsname_r(&master_fd).unwrap();
    assert!(slave_name1 == slave_name2);
    assert!(slave_name1.as_ptr() != slave_name2.as_ptr());
}

/// Test that `ptsname` returns different names for different devices
#[test]
#[cfg(any(target_os = "android", target_os = "linux"))]
fn test_ptsname_unique() {
    // Open a new PTTY master
    let master1_fd = posix_openpt(O_RDWR).unwrap();
    assert!(master1_fd.as_raw_fd() > 0);

    // Open a second PTTY master
    let master2_fd = posix_openpt(O_RDWR).unwrap();
    assert!(master2_fd.as_raw_fd() > 0);

    // Get the name of the slave
    let slave_name1 = ptsname(&master1_fd).unwrap();
    let slave_name2 = ptsname(&master2_fd).unwrap();
    assert!(slave_name1 != slave_name2);
}

/// Test opening a master/slave PTTY pair
///
/// This is a single larger test because much of these functions aren't useful by themselves. So for
/// this test we perform the basic act of getting a file handle for a connect master/slave PTTY
/// pair.
#[test]
fn test_open_ptty_pair() {
    // Open a new PTTY master
    let master_fd = posix_openpt(O_RDWR).unwrap();
    assert!(master_fd.as_raw_fd() > 0);

    // Allow a slave to be generated for it
    grantpt(&master_fd).unwrap();
    unlockpt(&master_fd).unwrap();

    // Get the name of the slave
    let slave_name = ptsname(&master_fd).unwrap();

    // Open the slave device
    let slave_fd = open(Path::new(&slave_name), O_RDWR, stat::Mode::empty()).unwrap();
    assert!(slave_fd > 0);
}

#[test]
fn test_openpty() {
    let pty = openpty(None, None).unwrap();
    assert!(pty.master > 0);
    assert!(pty.slave > 0);

    // Writing to one should be readable on the other one
    let string = "foofoofoo\n";
    let mut buf = [0u8; 10];
    write(pty.master, string.as_bytes()).unwrap();
    read_exact(pty.slave, &mut buf);

    assert_eq!(&buf, string.as_bytes());

    // Read the echo as well
    let echoed_string = "foofoofoo\r\n";
    let mut buf = [0u8; 11];
    read_exact(pty.master, &mut buf);
    assert_eq!(&buf, echoed_string.as_bytes());

    let string2 = "barbarbarbar\n";
    let echoed_string2 = "barbarbarbar\r\n";
    let mut buf = [0u8; 14];
    write(pty.slave, string2.as_bytes()).unwrap();
    read_exact(pty.master, &mut buf);

    assert_eq!(&buf, echoed_string2.as_bytes());

    close(pty.master).unwrap();
    close(pty.slave).unwrap();
}

#[test]
fn test_openpty_with_termios() {
    // Open one pty to get attributes for the second one
    let mut termios = {
        let pty = openpty(None, None).unwrap();
        assert!(pty.master > 0);
        assert!(pty.slave > 0);
        let termios = tcgetattr(pty.master).unwrap();
        close(pty.master).unwrap();
        close(pty.slave).unwrap();
        termios
    };
    termios.c_oflag &= !ONLCR;

    let pty = openpty(None, &termios).unwrap();
    // Must be valid file descriptors
    assert!(pty.master > 0);
    assert!(pty.slave > 0);

    // Writing to one should be readable on the other one
    let string = "foofoofoo\n";
    let mut buf = [0u8; 10];
    write(pty.master, string.as_bytes()).unwrap();
    read_exact(pty.slave, &mut buf);

    assert_eq!(&buf, string.as_bytes());

    // read the echo as well
    let echoed_string = "foofoofoo\n";
    read_exact(pty.master, &mut buf);
    assert_eq!(&buf, echoed_string.as_bytes());

    let string2 = "barbarbarbar\n";
    let echoed_string2 = "barbarbarbar\n";
    let mut buf = [0u8; 13];
    write(pty.slave, string2.as_bytes()).unwrap();
    read_exact(pty.master, &mut buf);

    assert_eq!(&buf, echoed_string2.as_bytes());

    close(pty.master).unwrap();
    close(pty.slave).unwrap();
}
<|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 dom::bindings::callback::CallbackContainer;
use dom::bindings::codegen::Bindings::EventHandlerBinding::EventHandlerNonNull;
use dom::bindings::codegen::Bindings::EventListenerBinding::EventListener;
use dom::bindings::codegen::Bindings::EventTargetBinding::EventTargetMethods;
use dom::bindings::error::{Fallible, InvalidState, report_pending_exception};
use dom::bindings::js::JSRef;
use dom::bindings::utils::{Reflectable, Reflector};
use dom::event::Event;
use dom::eventdispatcher::dispatch_event;
use dom::node::NodeTypeId;
use dom::workerglobalscope::WorkerGlobalScopeId;
use dom::xmlhttprequest::XMLHttpRequestId;
use dom::virtualmethods::VirtualMethods;
use js::jsapi::{JS_CompileUCFunction, JS_GetFunctionObject, JS_CloneFunctionObject};
use js::jsapi::{JSContext, JSObject};
use servo_util::str::DOMString;
use libc::{c_char, size_t};
use std::cell::RefCell;
use std::ptr;
use url::Url;

use std::collections::hashmap::HashMap;

#[deriving(PartialEq)]
#[jstraceable]
pub enum ListenerPhase {
    Capturing,
    Bubbling,
}

#[deriving(PartialEq)]
#[jstraceable]
pub enum EventTargetTypeId {
    NodeTargetTypeId(NodeTypeId),
    WindowTypeId,
    WorkerTypeId,
    WorkerGlobalScopeTypeId(WorkerGlobalScopeId),
    XMLHttpRequestTargetTypeId(XMLHttpRequestId)
}

#[deriving(PartialEq)]
#[jstraceable]
pub enum EventListenerType {
    Additive(EventListener),
    Inline(EventListener),
}

impl EventListenerType {
    fn get_listener(&self) -> EventListener {
        match *self {
            Additive(listener) | Inline(listener) => listener
        }
    }
}

#[deriving(PartialEq)]
#[jstraceable]
#[privatize]
pub struct EventListenerEntry {
    phase: ListenerPhase,
    listener: EventListenerType
}

#[dom_struct]
pub struct EventTarget {
    type_id: EventTargetTypeId,
    reflector_: Reflector,
    handlers: RefCell<HashMap<DOMString, Vec<EventListenerEntry>>>,
}

impl EventTarget {
    pub fn new_inherited(type_id: EventTargetTypeId) -> EventTarget {
        EventTarget {
            type_id: type_id,
            reflector_: Reflector::new(),
            handlers: RefCell::new(HashMap::new()),
        }
    }

    pub fn get_listeners(&self, type_: &str) -> Option<Vec<EventListener>> {
        self.handlers.borrow().find_equiv(&type_).map(|listeners| {
            listeners.iter().map(|entry| entry.listener.get_listener()).collect()
        })
    }

    pub fn get_listeners_for(&self, type_: &str, desired_phase: ListenerPhase)
        -> Option<Vec<EventListener>> {
        self.handlers.borrow().find_equiv(&type_).map(|listeners| {
            let filtered = listeners.iter().filter(|entry| entry.phase == desired_phase);
            filtered.map(|entry| entry.listener.get_listener()).collect()
        })
    }

    #[inline]
    pub fn type_id<'a>(&'a self) -> &'a EventTargetTypeId {
        &self.type_id
    }
}

pub trait EventTargetHelpers {
    fn dispatch_event_with_target(self,
                                  target: Option<JSRef<EventTarget>>,
                                  event: JSRef<Event>) -> Fallible<bool>;
    fn set_inline_event_listener(self,
                                 ty: DOMString,
                                 listener: Option<EventListener>);
    fn get_inline_event_listener(self, ty: DOMString) -> Option<EventListener>;
    fn set_event_handler_uncompiled(self,
                                    cx: *mut JSContext,
                                    url: Url,
                                    scope: *mut JSObject,
                                    ty: &str,
                                    source: DOMString);
    fn set_event_handler_common<T: CallbackContainer>(self, ty: &str,
                                                      listener: Option<T>);
    fn get_event_handler_common<T: CallbackContainer>(self, ty: &str) -> Option<T>;

    fn has_handlers(self) -> bool;
}

impl<'a> EventTargetHelpers for JSRef<'a, EventTarget> {
    fn dispatch_event_with_target(self,
                                  target: Option<JSRef<EventTarget>>,
                                  event: JSRef<Event>) -> Fallible<bool> {
        if event.dispatching() || !event.initialized() {
            return Err(InvalidState);
        }
        Ok(dispatch_event(self, target, event))
    }

    fn set_inline_event_listener(self,
                                 ty: DOMString,
                                 listener: Option<EventListener>) {
        let mut handlers = self.handlers.borrow_mut();
        let entries = handlers.find_or_insert_with(ty, |_| vec!());
        let idx = entries.iter().position(|&entry| {
            match entry.listener {
                Inline(_) => true,
                _ => false,
            }
        });

        match idx {
            Some(idx) => {
                match listener {
                    Some(listener) => entries.get_mut(idx).listener = Inline(listener),
                    None => {
                        entries.remove(idx);
                    }
                }
            }
            None => {
                if listener.is_some() {
                    entries.push(EventListenerEntry {
                        phase: Bubbling,
                        listener: Inline(listener.unwrap()),
                    });
                }
            }
        }
    }

    fn get_inline_event_listener(self, ty: DOMString) -> Option<EventListener> {
        let handlers = self.handlers.borrow();
        let entries = handlers.find(&ty);
        entries.and_then(|entries| entries.iter().find(|entry| {
            match entry.listener {
                Inline(_) => true,
                _ => false,
            }
        }).map(|entry| entry.listener.get_listener()))
    }

    fn set_event_handler_uncompiled(self,
                                    cx: *mut JSContext,
                                    url: Url,
                                    scope: *mut JSObject,
                                    ty: &str,
                                    source: DOMString) {
        let url = url.serialize().to_c_str();
        let name = ty.to_c_str();
        let lineno = 0; //XXXjdm need to get a real number here

        let nargs = 1; //XXXjdm not true for onerror
        static arg_name: [c_char, ..6] =
            ['e' as c_char, 'v' as c_char, 'e' as c_char, 'n' as c_char, 't' as c_char, 0];
        static arg_names: [*const c_char, ..1] = [&arg_name as *const c_char];

        let source: Vec<u16> = source.as_slice().utf16_units().collect();
        let handler = unsafe {
                JS_CompileUCFunction(cx,
                                     ptr::null_mut(),
                                     name.as_ptr(),
                                     nargs,
                                     &arg_names as *const *const i8 as *mut *const i8,
                                     source.as_ptr(),
                                     source.len() as size_t,
                                     url.as_ptr(),
                                     lineno)
        };
        if handler.is_null() {
            report_pending_exception(cx, self.reflector().get_jsobject());
            return;
        }

        let funobj = unsafe {
            JS_CloneFunctionObject(cx, JS_GetFunctionObject(handler), scope)
        };
        assert!(funobj.is_not_null());
        self.set_event_handler_common(ty, Some(EventHandlerNonNull::new(funobj)));
    }

    fn set_event_handler_common<T: CallbackContainer>(
        self, ty: &str, listener: Option<T>)
    {
        let event_listener = listener.map(|listener|
                                          EventListener::new(listener.callback()));
        self.set_inline_event_listener(ty.to_string(), event_listener);
    }

    fn get_event_handler_common<T: CallbackContainer>(self, ty: &str) -> Option<T> {
        let listener = self.get_inline_event_listener(ty.to_string());
        listener.map(|listener| CallbackContainer::new(listener.parent.callback()))
    }

    fn has_handlers(self) -> bool {
        !self.handlers.borrow().is_empty()
    }
}

impl<'a> EventTargetMethods for JSRef<'a, EventTarget> {
    fn AddEventListener(self,
                        ty: DOMString,
                        listener: Option<EventListener>,
                        capture: bool) {
        match listener {
            Some(listener) => {
                let mut handlers = self.handlers.borrow_mut();
                let entry = handlers.find_or_insert_with(ty, |_| vec!());
                let phase = if capture { Capturing } else { Bubbling };
                let new_entry = EventListenerEntry {
                    phase: phase,
                    listener: Additive(listener)
                };
                if entry.as_slice().position_elem(&new_entry).is_none() {
                    entry.push(new_entry);
                }
            },
            _ => (),
        }
    }

    fn RemoveEventListener(self,
                           ty: DOMString,
                           listener: Option<EventListener>,
                           capture: bool) {
        match listener {
            Some(listener) => {
                let mut handlers = self.handlers.borrow_mut();
                let mut entry = handlers.find_mut(&ty);
                for entry in entry.iter_mut() {
                    let phase = if capture { Capturing } else { Bubbling };
                    let old_entry = EventListenerEntry {
                        phase: phase,
                        listener: Additive(listener)
                    };
                    let position = entry.as_slice().position_elem(&old_entry);
                    for &position in position.iter() {
                        entry.remove(position);
                    }
                }
            },
            _ => (),
        }
    }

    fn DispatchEvent(self, event: JSRef<Event>) -> Fallible<bool> {
        self.dispatch_event_with_target(None, event)
    }
}

impl Reflectable for EventTarget {
    fn reflector<'a>(&'a self) -> &'a Reflector {
        &self.reflector_
    }
}

impl<'a> VirtualMethods for JSRef<'a, EventTarget> {
    fn super_type<'a>(&'a self) -> Option<&'a VirtualMethods> {
        None
    }
}
<commit_msg>Use DOMRefCell for EventTarget.<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 dom::bindings::callback::CallbackContainer;
use dom::bindings::cell::DOMRefCell;
use dom::bindings::codegen::Bindings::EventHandlerBinding::EventHandlerNonNull;
use dom::bindings::codegen::Bindings::EventListenerBinding::EventListener;
use dom::bindings::codegen::Bindings::EventTargetBinding::EventTargetMethods;
use dom::bindings::error::{Fallible, InvalidState, report_pending_exception};
use dom::bindings::js::JSRef;
use dom::bindings::utils::{Reflectable, Reflector};
use dom::event::Event;
use dom::eventdispatcher::dispatch_event;
use dom::node::NodeTypeId;
use dom::workerglobalscope::WorkerGlobalScopeId;
use dom::xmlhttprequest::XMLHttpRequestId;
use dom::virtualmethods::VirtualMethods;
use js::jsapi::{JS_CompileUCFunction, JS_GetFunctionObject, JS_CloneFunctionObject};
use js::jsapi::{JSContext, JSObject};
use servo_util::str::DOMString;
use libc::{c_char, size_t};
use std::ptr;
use url::Url;

use std::collections::hashmap::HashMap;

#[deriving(PartialEq)]
#[jstraceable]
pub enum ListenerPhase {
    Capturing,
    Bubbling,
}

#[deriving(PartialEq)]
#[jstraceable]
pub enum EventTargetTypeId {
    NodeTargetTypeId(NodeTypeId),
    WindowTypeId,
    WorkerTypeId,
    WorkerGlobalScopeTypeId(WorkerGlobalScopeId),
    XMLHttpRequestTargetTypeId(XMLHttpRequestId)
}

#[deriving(PartialEq)]
#[jstraceable]
pub enum EventListenerType {
    Additive(EventListener),
    Inline(EventListener),
}

impl EventListenerType {
    fn get_listener(&self) -> EventListener {
        match *self {
            Additive(listener) | Inline(listener) => listener
        }
    }
}

#[deriving(PartialEq)]
#[jstraceable]
#[privatize]
pub struct EventListenerEntry {
    phase: ListenerPhase,
    listener: EventListenerType
}

#[dom_struct]
pub struct EventTarget {
    type_id: EventTargetTypeId,
    reflector_: Reflector,
    handlers: DOMRefCell<HashMap<DOMString, Vec<EventListenerEntry>>>,
}

impl EventTarget {
    pub fn new_inherited(type_id: EventTargetTypeId) -> EventTarget {
        EventTarget {
            type_id: type_id,
            reflector_: Reflector::new(),
            handlers: DOMRefCell::new(HashMap::new()),
        }
    }

    pub fn get_listeners(&self, type_: &str) -> Option<Vec<EventListener>> {
        self.handlers.borrow().find_equiv(&type_).map(|listeners| {
            listeners.iter().map(|entry| entry.listener.get_listener()).collect()
        })
    }

    pub fn get_listeners_for(&self, type_: &str, desired_phase: ListenerPhase)
        -> Option<Vec<EventListener>> {
        self.handlers.borrow().find_equiv(&type_).map(|listeners| {
            let filtered = listeners.iter().filter(|entry| entry.phase == desired_phase);
            filtered.map(|entry| entry.listener.get_listener()).collect()
        })
    }

    #[inline]
    pub fn type_id<'a>(&'a self) -> &'a EventTargetTypeId {
        &self.type_id
    }
}

pub trait EventTargetHelpers {
    fn dispatch_event_with_target(self,
                                  target: Option<JSRef<EventTarget>>,
                                  event: JSRef<Event>) -> Fallible<bool>;
    fn set_inline_event_listener(self,
                                 ty: DOMString,
                                 listener: Option<EventListener>);
    fn get_inline_event_listener(self, ty: DOMString) -> Option<EventListener>;
    fn set_event_handler_uncompiled(self,
                                    cx: *mut JSContext,
                                    url: Url,
                                    scope: *mut JSObject,
                                    ty: &str,
                                    source: DOMString);
    fn set_event_handler_common<T: CallbackContainer>(self, ty: &str,
                                                      listener: Option<T>);
    fn get_event_handler_common<T: CallbackContainer>(self, ty: &str) -> Option<T>;

    fn has_handlers(self) -> bool;
}

impl<'a> EventTargetHelpers for JSRef<'a, EventTarget> {
    fn dispatch_event_with_target(self,
                                  target: Option<JSRef<EventTarget>>,
                                  event: JSRef<Event>) -> Fallible<bool> {
        if event.dispatching() || !event.initialized() {
            return Err(InvalidState);
        }
        Ok(dispatch_event(self, target, event))
    }

    fn set_inline_event_listener(self,
                                 ty: DOMString,
                                 listener: Option<EventListener>) {
        let mut handlers = self.handlers.borrow_mut();
        let entries = handlers.find_or_insert_with(ty, |_| vec!());
        let idx = entries.iter().position(|&entry| {
            match entry.listener {
                Inline(_) => true,
                _ => false,
            }
        });

        match idx {
            Some(idx) => {
                match listener {
                    Some(listener) => entries.get_mut(idx).listener = Inline(listener),
                    None => {
                        entries.remove(idx);
                    }
                }
            }
            None => {
                if listener.is_some() {
                    entries.push(EventListenerEntry {
                        phase: Bubbling,
                        listener: Inline(listener.unwrap()),
                    });
                }
            }
        }
    }

    fn get_inline_event_listener(self, ty: DOMString) -> Option<EventListener> {
        let handlers = self.handlers.borrow();
        let entries = handlers.find(&ty);
        entries.and_then(|entries| entries.iter().find(|entry| {
            match entry.listener {
                Inline(_) => true,
                _ => false,
            }
        }).map(|entry| entry.listener.get_listener()))
    }

    fn set_event_handler_uncompiled(self,
                                    cx: *mut JSContext,
                                    url: Url,
                                    scope: *mut JSObject,
                                    ty: &str,
                                    source: DOMString) {
        let url = url.serialize().to_c_str();
        let name = ty.to_c_str();
        let lineno = 0; //XXXjdm need to get a real number here

        let nargs = 1; //XXXjdm not true for onerror
        static arg_name: [c_char, ..6] =
            ['e' as c_char, 'v' as c_char, 'e' as c_char, 'n' as c_char, 't' as c_char, 0];
        static arg_names: [*const c_char, ..1] = [&arg_name as *const c_char];

        let source: Vec<u16> = source.as_slice().utf16_units().collect();
        let handler = unsafe {
                JS_CompileUCFunction(cx,
                                     ptr::null_mut(),
                                     name.as_ptr(),
                                     nargs,
                                     &arg_names as *const *const i8 as *mut *const i8,
                                     source.as_ptr(),
                                     source.len() as size_t,
                                     url.as_ptr(),
                                     lineno)
        };
        if handler.is_null() {
            report_pending_exception(cx, self.reflector().get_jsobject());
            return;
        }

        let funobj = unsafe {
            JS_CloneFunctionObject(cx, JS_GetFunctionObject(handler), scope)
        };
        assert!(funobj.is_not_null());
        self.set_event_handler_common(ty, Some(EventHandlerNonNull::new(funobj)));
    }

    fn set_event_handler_common<T: CallbackContainer>(
        self, ty: &str, listener: Option<T>)
    {
        let event_listener = listener.map(|listener|
                                          EventListener::new(listener.callback()));
        self.set_inline_event_listener(ty.to_string(), event_listener);
    }

    fn get_event_handler_common<T: CallbackContainer>(self, ty: &str) -> Option<T> {
        let listener = self.get_inline_event_listener(ty.to_string());
        listener.map(|listener| CallbackContainer::new(listener.parent.callback()))
    }

    fn has_handlers(self) -> bool {
        !self.handlers.borrow().is_empty()
    }
}

impl<'a> EventTargetMethods for JSRef<'a, EventTarget> {
    fn AddEventListener(self,
                        ty: DOMString,
                        listener: Option<EventListener>,
                        capture: bool) {
        match listener {
            Some(listener) => {
                let mut handlers = self.handlers.borrow_mut();
                let entry = handlers.find_or_insert_with(ty, |_| vec!());
                let phase = if capture { Capturing } else { Bubbling };
                let new_entry = EventListenerEntry {
                    phase: phase,
                    listener: Additive(listener)
                };
                if entry.as_slice().position_elem(&new_entry).is_none() {
                    entry.push(new_entry);
                }
            },
            _ => (),
        }
    }

    fn RemoveEventListener(self,
                           ty: DOMString,
                           listener: Option<EventListener>,
                           capture: bool) {
        match listener {
            Some(listener) => {
                let mut handlers = self.handlers.borrow_mut();
                let mut entry = handlers.find_mut(&ty);
                for entry in entry.iter_mut() {
                    let phase = if capture { Capturing } else { Bubbling };
                    let old_entry = EventListenerEntry {
                        phase: phase,
                        listener: Additive(listener)
                    };
                    let position = entry.as_slice().position_elem(&old_entry);
                    for &position in position.iter() {
                        entry.remove(position);
                    }
                }
            },
            _ => (),
        }
    }

    fn DispatchEvent(self, event: JSRef<Event>) -> Fallible<bool> {
        self.dispatch_event_with_target(None, event)
    }
}

impl Reflectable for EventTarget {
    fn reflector<'a>(&'a self) -> &'a Reflector {
        &self.reflector_
    }
}

impl<'a> VirtualMethods for JSRef<'a, EventTarget> {
    fn super_type<'a>(&'a self) -> Option<&'a VirtualMethods> {
        None
    }
}
<|endoftext|>


<commit_before>// Copyright:: Copyright (c) 2015-2016 The Habitat Maintainers
//
// The terms of the Evaluation Agreement (Habitat) between Chef Software Inc.
// and the party accessing this file ("Licensee") apply to Licensee's use of
// the Software until such time that the Software is made available under an
// open source license such as the Apache 2.0 License.

use std::io::prelude::*;
use std::io;
use std::process::{Command, Child, Stdio, ExitStatus};
use std::fmt;
use std::error::Error;
use std::result;
use std::thread;
use std::collections::HashMap;

use util;

pub struct Cmd {
    pub child: Option<Child>,
    pub status: Option<ExitStatus>,
    pub stdout: Option<String>,
    pub stderr: Option<String>,
}

impl Cmd {
    pub fn kill(&mut self) -> &Self {
        match self.child {
            Some(ref mut child) => {
                child.kill().unwrap_or_else(|x| panic!("{:?}", x));
            }
            None => {
                panic!("Cannot kill a child that does not exist - you have probably called \
                        wait_with_output already")
            }
        }
        self
    }

    pub fn stdout(&self) -> &str {
        match self.stdout {
            Some(ref stdout) => stdout,
            None => panic!("No stdout available - process needs a wait"),
        }
    }

    pub fn stderr(&self) -> &str {
        match self.stderr {
            Some(ref stderr) => stderr,
            None => panic!("No stderr available - process needs a wait"),
        }
    }

    pub fn status(&self) -> &ExitStatus {
        match self.status {
            Some(ref status) => status,
            None => panic!("No status available - process needs a wait or kill"),
        }
    }

    pub fn wait_with_output(&mut self) -> &Self {
        // The child is unavailable for more calls after this
        let child = self.child.take().unwrap();

        let output = match child.wait_with_output() {
            Ok(output) => output,
            Err(e) => panic!("{:?}", e),
        };
        self.status = Some(output.status);
        let stdout = String::from_utf8(output.stdout).unwrap_or_else(|x| panic!("{:?}", x));
        let stderr = String::from_utf8(output.stderr).unwrap_or_else(|x| panic!("{:?}", x));
        println!("OUT: {}", stdout);
        println!("ERR: {}", stderr);
        self.stdout = Some(stdout);
        self.stderr = Some(stderr);
        self
    }
}

#[derive(Debug)]
pub enum CmdError {
    Io(io::Error),
}

pub type CmdResult<T> = result::Result<T, CmdError>;

impl fmt::Display for CmdError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            CmdError::Io(ref err) => err.fmt(f),
        }
    }
}

impl Error for CmdError {
    fn description(&self) -> &str {
        match *self {
            CmdError::Io(ref err) => err.description(),
        }
    }
}

impl From<io::Error> for CmdError {
    fn from(err: io::Error) -> CmdError {
        CmdError::Io(err)
    }
}

#[derive(Debug)]
pub struct CommandArgs {
    pub cmd: String,
    pub args: Vec<String>,
    pub env: HashMap<String, String>,
    pub cwd: Option<String>,
}

impl CommandArgs {
    fn new<S: Into<String>>(cmd: S) -> CommandArgs {
        CommandArgs {
            cmd: cmd.into(),
            args: Vec::new(),
            env: HashMap::new(),
            cwd: None,
        }
    }

    fn arg<S: Into<String>>(&mut self, arg: S) -> &mut CommandArgs {
        self.args.push(arg.into());
        self
    }

    fn env<S: Into<String>>(&mut self, k: S, v: S) -> &mut CommandArgs {
        self.env.insert(k.into(), v.into());
        self
    }
}

impl fmt::Display for CommandArgs {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f,
               "Command: C: {} A: {:?} E: {:?} CWD: {:?}",
               self.cmd,
               self.args,
               self.env,
               self.cwd)
    }
}

pub fn command(cmd: &str, args: &[&str]) -> Command {
    command_with_env(cmd, args, None)
}

pub fn command_with_env(cmd: &str, args: &[&str], env: Option<&HashMap<&str, &str>>) -> Command {
    let mut cmd_args = CommandArgs::new(cmd);
    for a in args {
        cmd_args.arg(*a);
    }
    if let Some(real_env) = env {
        for (k, v) in real_env {
            cmd_args.env(*k, *v);
        }
    }
    run_command(cmd_args)
}

pub fn run_command(cmd_args: CommandArgs) -> Command {
    println!("{}: {}",
             thread::current().name().unwrap_or("main"),
             cmd_args);

    let mut command = Command::new(&cmd_args.cmd);
    command.args(&cmd_args.args);
    command.stdin(Stdio::null());
    command.stdout(Stdio::piped());
    command.stderr(Stdio::piped());

    for (k, v) in cmd_args.env {
        command.env(k, v);
    }

    command
}

pub fn spawn(mut command: Command) -> CmdResult<Cmd> {
    let child = try!(command.spawn());
    Ok(Cmd {
        child: Some(child),
        status: None,
        stdout: None,
        stderr: None,
    })
}

pub fn studio_run(cmd: &str, args: &[&str]) -> CmdResult<Cmd> {
    let real_cmd = "/src/components/studio/bin/hab-studio.sh";
    let mut real_args = vec!["-r", "/hab/studios/functional-tests", "run", cmd];
    real_args.extend_from_slice(args);
    let mut command = command(real_cmd, &real_args[..]);
    command.current_dir("/src");
    spawn(command)
}

pub fn dockerize(ident_str: &str) {
    let mut install = match studio_run("hab-bpm", &["install", "core/hab-pkg-dockerize"]) {
        Ok(cmd) => cmd,
        Err(e) => panic!("{:?}", e),
    };
    install.wait_with_output();
    if !install.status.unwrap().success() {
        panic!("Failed to install 'core/hab-pkg-dockerize'");
    }
    let mut docker = match studio_run("hab-bpm",
                                      &["exec",
                                        "core/hab-pkg-dockerize",
                                        "hab-pkg-dockerize",
                                        ident_str]) {
        Ok(cmd) => cmd,
        Err(e) => panic!("{:?}", e),
    };
    docker.wait_with_output();
    if !docker.status.unwrap().success() {
        panic!("Failed to dockerize simple service");
    }
}

pub fn run(cmd: &str, args: &[&str]) -> CmdResult<Cmd> {
    let command = command(cmd, args);
    spawn(command)
}

pub fn run_with_env(cmd: &str, args: &[&str], env: &HashMap<&str, &str>) -> CmdResult<Cmd> {
    let command = command_with_env(cmd, args, Some(env));
    spawn(command)
}

pub fn plan_build(to_build: &str) -> CmdResult<Cmd> {
    studio_run("/src/components/plan-build/bin/hab-plan-build.sh",
               &[to_build])
}

pub fn sup(args: &[&str]) -> CmdResult<Cmd> {
    let sup = util::path::sup();
    let command = command(&sup, args);
    spawn(command)
}

pub fn sup_with_env(args: &[&str], env: &HashMap<&str, &str>) -> CmdResult<Cmd> {
    let sup = util::path::sup();
    let command = command_with_env(&sup, args, Some(env));
    spawn(command)
}

/// some days, you just want to specify a directory instead of a hash.
/// This function is for you!
pub fn sup_with_test_key_cache(args: &[&str], cache_dir: &str) -> CmdResult<Cmd> {
    let mut env: HashMap<&str, &str> = HashMap::new();
    env.insert("HAB_CACHE_KEY_PATH", cache_dir);
    sup_with_env(args, &env)
}
<commit_msg>[sup] Update functional tests to call `hab-studio` on PATH.<commit_after>// Copyright:: Copyright (c) 2015-2016 The Habitat Maintainers
//
// The terms of the Evaluation Agreement (Habitat) between Chef Software Inc.
// and the party accessing this file ("Licensee") apply to Licensee's use of
// the Software until such time that the Software is made available under an
// open source license such as the Apache 2.0 License.

use std::io::prelude::*;
use std::io;
use std::process::{Command, Child, Stdio, ExitStatus};
use std::fmt;
use std::error::Error;
use std::result;
use std::thread;
use std::collections::HashMap;

use util;

pub struct Cmd {
    pub child: Option<Child>,
    pub status: Option<ExitStatus>,
    pub stdout: Option<String>,
    pub stderr: Option<String>,
}

impl Cmd {
    pub fn kill(&mut self) -> &Self {
        match self.child {
            Some(ref mut child) => {
                child.kill().unwrap_or_else(|x| panic!("{:?}", x));
            }
            None => {
                panic!("Cannot kill a child that does not exist - you have probably called \
                        wait_with_output already")
            }
        }
        self
    }

    pub fn stdout(&self) -> &str {
        match self.stdout {
            Some(ref stdout) => stdout,
            None => panic!("No stdout available - process needs a wait"),
        }
    }

    pub fn stderr(&self) -> &str {
        match self.stderr {
            Some(ref stderr) => stderr,
            None => panic!("No stderr available - process needs a wait"),
        }
    }

    pub fn status(&self) -> &ExitStatus {
        match self.status {
            Some(ref status) => status,
            None => panic!("No status available - process needs a wait or kill"),
        }
    }

    pub fn wait_with_output(&mut self) -> &Self {
        // The child is unavailable for more calls after this
        let child = self.child.take().unwrap();

        let output = match child.wait_with_output() {
            Ok(output) => output,
            Err(e) => panic!("{:?}", e),
        };
        self.status = Some(output.status);
        let stdout = String::from_utf8(output.stdout).unwrap_or_else(|x| panic!("{:?}", x));
        let stderr = String::from_utf8(output.stderr).unwrap_or_else(|x| panic!("{:?}", x));
        println!("OUT: {}", stdout);
        println!("ERR: {}", stderr);
        self.stdout = Some(stdout);
        self.stderr = Some(stderr);
        self
    }
}

#[derive(Debug)]
pub enum CmdError {
    Io(io::Error),
}

pub type CmdResult<T> = result::Result<T, CmdError>;

impl fmt::Display for CmdError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            CmdError::Io(ref err) => err.fmt(f),
        }
    }
}

impl Error for CmdError {
    fn description(&self) -> &str {
        match *self {
            CmdError::Io(ref err) => err.description(),
        }
    }
}

impl From<io::Error> for CmdError {
    fn from(err: io::Error) -> CmdError {
        CmdError::Io(err)
    }
}

#[derive(Debug)]
pub struct CommandArgs {
    pub cmd: String,
    pub args: Vec<String>,
    pub env: HashMap<String, String>,
    pub cwd: Option<String>,
}

impl CommandArgs {
    fn new<S: Into<String>>(cmd: S) -> CommandArgs {
        CommandArgs {
            cmd: cmd.into(),
            args: Vec::new(),
            env: HashMap::new(),
            cwd: None,
        }
    }

    fn arg<S: Into<String>>(&mut self, arg: S) -> &mut CommandArgs {
        self.args.push(arg.into());
        self
    }

    fn env<S: Into<String>>(&mut self, k: S, v: S) -> &mut CommandArgs {
        self.env.insert(k.into(), v.into());
        self
    }
}

impl fmt::Display for CommandArgs {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f,
               "Command: C: {} A: {:?} E: {:?} CWD: {:?}",
               self.cmd,
               self.args,
               self.env,
               self.cwd)
    }
}

pub fn command(cmd: &str, args: &[&str]) -> Command {
    command_with_env(cmd, args, None)
}

pub fn command_with_env(cmd: &str, args: &[&str], env: Option<&HashMap<&str, &str>>) -> Command {
    let mut cmd_args = CommandArgs::new(cmd);
    for a in args {
        cmd_args.arg(*a);
    }
    if let Some(real_env) = env {
        for (k, v) in real_env {
            cmd_args.env(*k, *v);
        }
    }
    run_command(cmd_args)
}

pub fn run_command(cmd_args: CommandArgs) -> Command {
    println!("{}: {}",
             thread::current().name().unwrap_or("main"),
             cmd_args);

    let mut command = Command::new(&cmd_args.cmd);
    command.args(&cmd_args.args);
    command.stdin(Stdio::null());
    command.stdout(Stdio::piped());
    command.stderr(Stdio::piped());

    for (k, v) in cmd_args.env {
        command.env(k, v);
    }

    command
}

pub fn spawn(mut command: Command) -> CmdResult<Cmd> {
    let child = try!(command.spawn());
    Ok(Cmd {
        child: Some(child),
        status: None,
        stdout: None,
        stderr: None,
    })
}

pub fn studio_run(cmd: &str, args: &[&str]) -> CmdResult<Cmd> {
    let real_cmd = "hab-studio";
    let mut real_args = vec!["-r", "/hab/studios/functional-tests", "run", cmd];
    real_args.extend_from_slice(args);
    let mut command = command(real_cmd, &real_args[..]);
    command.current_dir("/src");
    spawn(command)
}

pub fn dockerize(ident_str: &str) {
    let mut install = match studio_run("hab-bpm", &["install", "core/hab-pkg-dockerize"]) {
        Ok(cmd) => cmd,
        Err(e) => panic!("{:?}", e),
    };
    install.wait_with_output();
    if !install.status.unwrap().success() {
        panic!("Failed to install 'core/hab-pkg-dockerize'");
    }
    let mut docker = match studio_run("hab-bpm",
                                      &["exec",
                                        "core/hab-pkg-dockerize",
                                        "hab-pkg-dockerize",
                                        ident_str]) {
        Ok(cmd) => cmd,
        Err(e) => panic!("{:?}", e),
    };
    docker.wait_with_output();
    if !docker.status.unwrap().success() {
        panic!("Failed to dockerize simple service");
    }
}

pub fn run(cmd: &str, args: &[&str]) -> CmdResult<Cmd> {
    let command = command(cmd, args);
    spawn(command)
}

pub fn run_with_env(cmd: &str, args: &[&str], env: &HashMap<&str, &str>) -> CmdResult<Cmd> {
    let command = command_with_env(cmd, args, Some(env));
    spawn(command)
}

pub fn plan_build(to_build: &str) -> CmdResult<Cmd> {
    studio_run("/src/components/plan-build/bin/hab-plan-build.sh",
               &[to_build])
}

pub fn sup(args: &[&str]) -> CmdResult<Cmd> {
    let sup = util::path::sup();
    let command = command(&sup, args);
    spawn(command)
}

pub fn sup_with_env(args: &[&str], env: &HashMap<&str, &str>) -> CmdResult<Cmd> {
    let sup = util::path::sup();
    let command = command_with_env(&sup, args, Some(env));
    spawn(command)
}

/// some days, you just want to specify a directory instead of a hash.
/// This function is for you!
pub fn sup_with_test_key_cache(args: &[&str], cache_dir: &str) -> CmdResult<Cmd> {
    let mut env: HashMap<&str, &str> = HashMap::new();
    env.insert("HAB_CACHE_KEY_PATH", cache_dir);
    sup_with_env(args, &env)
}
<|endoftext|>


<commit_before>/*
 * The component library for rustfbp
 *
 * Author : Denis Michiels
 * Copyright (C) 2015 Michiels Denis
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of

 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 */

extern crate capnp;
use ports::Ports;
use result::Result;

pub trait Component {
    fn get_ports(&mut self) -> &mut Ports;
    fn is_input_ports(&self) -> bool;
    fn run(&mut self) -> Result<()>;
}

#[macro_export]
macro_rules! component {
    (
       $name:ident, $( contracts( $( $contract:ident ),* ) )*
        inputs($( $input_field_name:ident: $input_contract_name:ident),* ),
        inputs_array($( $input_array_name:ident: $input_contract_array:ident),* ),
        outputs($( $output_field_name:ident: $output_contract_name:ident),* ),
        outputs_array($($output_array_name:ident: $output_contract_array:ident),* ),
        option($($option_contract: ident),*),
        acc($($acc_contract: ident),*),
        fn run(&mut $arg:ident) -> Result<()> $fun:block
    )
        =>
    {
        use rustfbp::component::Component;

        use rustfbp::result;
        use rustfbp::result::Result;
        use rustfbp::ports::IPSender;
        use rustfbp::scheduler::CompMsg;
        use std::error::Error;

        use std::sync::mpsc::Sender;

        use rustfbp::ports::{IP, Ports};

        #[allow(unused_imports)]
        use std::collections::HashMap;

        use capnp::serialize;
        use capnp::message;

        use std::io::{Read, Write};

        $(
        mod contract_capnp {
            $(
                include!(concat!(stringify!($contract), ".rs"));
            )*
        })*

        $( $(
            use contract_capnp::$contract;
        )* )*

        impl $name {
            pub fn recv_option(&mut self) -> IP {
                self.try_recv_option();
                if self.option_ip.is_none() {
                    self.option_ip = self.ports.recv("option").ok();
                }
                match self.option_ip {
                    Some(ref ip) => ip.clone(),
                    None => unreachable!(),
                }
            }

            pub fn try_recv_option(&mut self) -> Option<IP> {
                loop {
                    match self.ports.try_recv("option") {
                        Err(_) => { break; },
                        Ok(ip) => { self.option_ip = Some(ip); }
                    };
                }
                self.option_ip.as_ref().map(|ip|{ ip.clone() })
            }
        }

        // simple and array
        impl Component for $name {

            fn get_ports(&mut self) -> &mut Ports {
                &mut self.ports
            }

            fn is_input_ports(&self) -> bool {
                $(
                    if true || stringify!($input_field_name) == "" { return true; }
                )*
                $(
                    if true || stringify!($input_array_name) == "" { return true; }
                )*
                false
            }

            fn run(&mut $arg) -> Result<()> $fun

        }

        /* Global component */

        #[allow(dead_code)]
        pub struct $name {
            name: String,
            pub ports: Ports,
            pub option_ip: Option<IP>,
        }

        #[allow(dead_code)]
        pub fn new(name: String, sched: Sender<CompMsg>) -> Result<(Box<Component + Send>, HashMap<String, IPSender>)> {
            let (ports, senders) = try!(Ports::new(name.clone(), sched,
                                   vec!["option".into(), "acc".into(), $( stringify!($input_field_name).to_string() ),*],
                                   vec![$( stringify!($input_array_name).to_string() ),*],
                                   vec!["acc".into(), $( stringify!($output_field_name).to_string() ),*],
                                   vec![$( stringify!($output_array_name).to_string() ),*],));

            // Put it together
            let comp = $name{
                name: name,
                ports: ports,
                option_ip: None,
            };
            Ok((Box::new(comp) as Box<Component + Send>, senders))
        }

        #[no_mangle]
        pub extern fn create_component(name: String, sched: Sender<CompMsg>) -> Result<(Box<Component + Send>, HashMap<String, IPSender>)> {
            new(name, sched)
        }

        #[no_mangle]
        pub extern fn get_contract_input(port: &str) -> Result<String> {
            match port {
                $(
                    stringify!($input_field_name)=> Ok(stringify!($input_contract_name).into()),
                )*
                _ => { Err(result::Error::PortNotFound) }
            }
        }

        #[no_mangle]
        pub extern fn get_contract_input_array(port: &str) -> Result<String> {
            match port {
                $(
                    stringify!($input_array_name) => Ok(stringify!($input_contract_array).into()),
                )*
                _ => { Err(result::Error::PortNotFound) }
            }
        }

        #[no_mangle]
        pub extern fn get_contract_output(port: &str) -> Result<String> {
            match port {
                $(
                    stringify!($output_field_name)=> Ok(stringify!($output_contract_name).into()),
                )*
                _ => { Err(result::Error::PortNotFound) }
            }
        }

        #[no_mangle]
        pub extern fn get_contract_output_array(port: &str) -> Result<String> {
            match port {
                $(
                    stringify!($output_array_name) => Ok(stringify!($output_contract_array).into()),
                )*
                _ => { Err(result::Error::PortNotFound) }
            }
        }
    }
}
<commit_msg>Problem : Cannot send Rust object by the acc port<commit_after>/*
 * The component library for rustfbp
 *
 * Author : Denis Michiels
 * Copyright (C) 2015 Michiels Denis
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of

 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 */

extern crate capnp;
use ports::Ports;
use result::Result;

pub trait Component {
    fn get_ports(&mut self) -> &mut Ports;
    fn is_input_ports(&self) -> bool;
    fn run(&mut self) -> Result<()>;
}

#[macro_export]
macro_rules! component {
    (
       $name:ident, $( contracts( $( $contract:ident ),* ) )*
        inputs($( $input_field_name:ident: $input_contract_name:ident),* ),
        inputs_array($( $input_array_name:ident: $input_contract_array:ident),* ),
        outputs($( $output_field_name:ident: $output_contract_name:ident),* ),
        outputs_array($($output_array_name:ident: $output_contract_array:ident),* ),
        option($($option_contract: ident),*),
        acc($($acc_contract: ident),*), $( portal($portal_type:ty => $portal_value:expr))*
        fn run(&mut $arg:ident) -> Result<()> $fun:block
    )
        =>
    {
        use rustfbp::component::Component;

        use rustfbp::result;
        use rustfbp::result::Result;
        use rustfbp::ports::IPSender;
        use rustfbp::scheduler::CompMsg;
        use std::error::Error;

        use std::sync::mpsc::Sender;

        use rustfbp::ports::{IP, Ports};

        #[allow(unused_imports)]
        use std::collections::HashMap;

        use capnp::serialize;
        use capnp::message;

        use std::io::{Read, Write};

        $(
        mod contract_capnp {
            $(
                include!(concat!(stringify!($contract), ".rs"));
            )*
        })*

        $( $(
            use contract_capnp::$contract;
        )* )*

        impl $name {
            pub fn recv_option(&mut self) -> IP {
                self.try_recv_option();
                if self.option_ip.is_none() {
                    self.option_ip = self.ports.recv("option").ok();
                }
                match self.option_ip {
                    Some(ref ip) => ip.clone(),
                    None => unreachable!(),
                }
            }

            pub fn try_recv_option(&mut self) -> Option<IP> {
                loop {
                    match self.ports.try_recv("option") {
                        Err(_) => { break; },
                        Ok(ip) => { self.option_ip = Some(ip); }
                    };
                }
                self.option_ip.as_ref().map(|ip|{ ip.clone() })
            }
        }

        // simple and array
        impl Component for $name {

            fn get_ports(&mut self) -> &mut Ports {
                &mut self.ports
            }

            fn is_input_ports(&self) -> bool {
                $(
                    if true || stringify!($input_field_name) == "" { return true; }
                )*
                $(
                    if true || stringify!($input_array_name) == "" { return true; }
                )*
                false
            }

            fn run(&mut $arg) -> Result<()> $fun

        }

        /* Global component */

        #[allow(dead_code)]
        pub struct $name {
            name: String,
            pub ports: Ports,
            pub option_ip: Option<IP>,
            $(
            pub portal: $portal_type ,
            )*
        }

        #[allow(dead_code)]
        pub fn new(name: String, sched: Sender<CompMsg>) -> Result<(Box<Component + Send>, HashMap<String, IPSender>)> {
            let (ports, senders) = try!(Ports::new(name.clone(), sched,
                                   vec!["option".into(), "acc".into(), $( stringify!($input_field_name).to_string() ),*],
                                   vec![$( stringify!($input_array_name).to_string() ),*],
                                   vec!["acc".into(), $( stringify!($output_field_name).to_string() ),*],
                                   vec![$( stringify!($output_array_name).to_string() ),*],));

            // Put it together
            let comp = $name{
                name: name,
                ports: ports,
                option_ip: None,
                $(
                    portal: $portal_value,
                )*
            };
            Ok((Box::new(comp) as Box<Component + Send>, senders))
        }

        #[no_mangle]
        pub extern fn create_component(name: String, sched: Sender<CompMsg>) -> Result<(Box<Component + Send>, HashMap<String, IPSender>)> {
            new(name, sched)
        }

        #[no_mangle]
        pub extern fn get_contract_input(port: &str) -> Result<String> {
            match port {
                $(
                    stringify!($input_field_name)=> Ok(stringify!($input_contract_name).into()),
                )*
                _ => { Err(result::Error::PortNotFound) }
            }
        }

        #[no_mangle]
        pub extern fn get_contract_input_array(port: &str) -> Result<String> {
            match port {
                $(
                    stringify!($input_array_name) => Ok(stringify!($input_contract_array).into()),
                )*
                _ => { Err(result::Error::PortNotFound) }
            }
        }

        #[no_mangle]
        pub extern fn get_contract_output(port: &str) -> Result<String> {
            match port {
                $(
                    stringify!($output_field_name)=> Ok(stringify!($output_contract_name).into()),
                )*
                _ => { Err(result::Error::PortNotFound) }
            }
        }

        #[no_mangle]
        pub extern fn get_contract_output_array(port: &str) -> Result<String> {
            match port {
                $(
                    stringify!($output_array_name) => Ok(stringify!($output_contract_array).into()),
                )*
                _ => { Err(result::Error::PortNotFound) }
            }
        }
    }
}
<|endoftext|>


<commit_before>/*use std::env;
use std::fs::File;
use std::io::Write;
use std::path::Path;*/

fn main() -> () {
    println!("cargo:rustc-link-search=native={}/blis/lib", std::env::home_dir().unwrap().to_str().unwrap() );
    println!("cargo:rustc-link-search=native=/usr/local/lib");
    println!("cargo:rustc-link-lib=static=blis");

    //Stuff for richard/s kernel
//    println!("cargo:rustc-link-search=native={}/hsw_kernel", std::env::home_dir().unwrap().to_str().unwrap() );
//    println!("cargo:rustc-link-lib=static=kern");

//    println!("cargo:rustc-link-lib=static=irc");
}
<commit_msg>Needed to recommit build.rs<commit_after>/*use std::env;
use std::fs::File;
use std::io::Write;
use std::path::Path;*/

fn main() -> () {
    println!("cargo:rustc-link-search=native={}/blis/lib", std::env::home_dir().unwrap().to_str().unwrap() );
    println!("cargo:rustc-link-search=native=/usr/local/lib");
    println!("cargo:rustc-link-lib=static=blis");

//  The following is needed for compiling with mkl
//    println!("cargo:rustc-link-lib=static=irc");
}
<|endoftext|>


<commit_before>extern crate capnpc;

fn main() {
    ::capnpc::CompilerCommand::new()
        .src_prefix("schema")
        .file("schema/root.capnp")
        .run().expect("capnp schema compiler failed");
}
<commit_msg>Formatting<commit_after>extern crate capnpc;

fn main() {
    ::capnpc::CompilerCommand::new()
        .src_prefix("schema")
        .file("schema/root.capnp")
        .run()
        .expect("capnp schema compiler failed");
}
<|endoftext|>


<commit_before>#[macro_use]
extern crate clap;
#[macro_use]
extern crate lazy_static;

use std::env;
use std::fs::{self, File};
use std::io::{self, Read, Write};
use std::path::Path;
use std::process;

use clap::Shell;

use app::{RGArg, RGArgKind};

#[allow(dead_code)]
#[path = "src/app.rs"]
mod app;

fn main() {
    // OUT_DIR is set by Cargo and it's where any additional build artifacts
    // are written.
    let outdir = match env::var_os("OUT_DIR") {
        Some(outdir) => outdir,
        None => {
            eprintln!(
                "OUT_DIR environment variable not defined. \
                 Please file a bug: \
                 https://github.com/BurntSushi/ripgrep/issues/new");
            process::exit(1);
        }
    };
    fs::create_dir_all(&outdir).unwrap();

    let stamp_path = Path::new(&outdir).join("ripgrep-stamp");
    if let Err(err) = File::create(&stamp_path) {
        panic!("failed to write {}: {}", stamp_path.display(), err);
    }
    if let Err(err) = generate_man_page(&outdir) {
        eprintln!("failed to generate man page: {}", err);
    }

    // Use clap to build completion files.
    let mut app = app::app();
    app.gen_completions("rg", Shell::Bash, &outdir);
    app.gen_completions("rg", Shell::Fish, &outdir);
    app.gen_completions("rg", Shell::PowerShell, &outdir);
    // Note that we do not use clap's support for zsh. Instead, zsh completions
    // are manually maintained in `complete/_rg`.

    // Make the current git hash available to the build.
    if let Some(rev) = git_revision_hash() {
        println!("cargo:rustc-env=RIPGREP_BUILD_GIT_HASH={}", rev);
    }
}

fn git_revision_hash() -> Option<String> {
    let result = process::Command::new("git")
        .args(&["rev-parse", "--short=10", "HEAD"])
        .output();
    result.ok().and_then(|output| {
        let v = String::from_utf8_lossy(&output.stdout).trim().to_string();
        if v.is_empty() {
            None
        } else {
            Some(v)
        }
    })
}

fn generate_man_page<P: AsRef<Path>>(outdir: P) -> io::Result<()> {
    // If asciidoc isn't installed, then don't do anything.
    if let Err(err) = process::Command::new("a2x").output() {
        eprintln!("Could not run 'a2x' binary, skipping man page generation.");
        eprintln!("Error from running 'a2x': {}", err);
        return Ok(());
    }
    // 1. Read asciidoc template.
    // 2. Interpolate template with auto-generated docs.
    // 3. Save interpolation to disk.
    // 4. Use a2x (part of asciidoc) to convert to man page.
    let outdir = outdir.as_ref();
    let cwd = env::current_dir()?;
    let tpl_path = cwd.join("doc").join("rg.1.txt.tpl");
    let txt_path = outdir.join("rg.1.txt");

    let mut tpl = String::new();
    File::open(&tpl_path)?.read_to_string(&mut tpl)?;
    tpl = tpl.replace("{OPTIONS}", &formatted_options()?);

    let githash = git_revision_hash();
    let githash = githash.as_ref().map(|x| &**x);
    tpl = tpl.replace("{VERSION}", &app::long_version(githash));

    File::create(&txt_path)?.write_all(tpl.as_bytes())?;
    let result = process::Command::new("a2x")
        .arg("--no-xmllint")
        .arg("--doctype").arg("manpage")
        .arg("--format").arg("manpage")
        .arg(&txt_path)
        .spawn()?
        .wait()?;
    if !result.success() {
        let msg = format!("'a2x' failed with exit code {:?}", result.code());
        return Err(ioerr(msg));
    }
    Ok(())
}

fn formatted_options() -> io::Result<String> {
    let mut args = app::all_args_and_flags();
    args.sort_by(|x1, x2| x1.name.cmp(&x2.name));

    let mut formatted = vec![];
    for arg in args {
        if arg.hidden {
            continue;
        }
        // ripgrep only has two positional arguments, and probably will only
        // ever have two positional arguments, so we just hardcode them into
        // the template.
        if let app::RGArgKind::Positional{..} = arg.kind {
            continue;
        }
        formatted.push(formatted_arg(&arg)?);
    }
    Ok(formatted.join("\n\n"))
}

fn formatted_arg(arg: &RGArg) -> io::Result<String> {
    match arg.kind {
        RGArgKind::Positional{..} => panic!("unexpected positional argument"),
        RGArgKind::Switch { long, short, multiple } => {
            let mut out = vec![];

            let mut header = format!("--{}", long);
            if let Some(short) = short {
                header = format!("-{}, {}", short, header);
            }
            if multiple {
                header = format!("*{}* ...::", header);
            } else {
                header = format!("*{}*::", header);
            }
            writeln!(out, "{}", header)?;
            writeln!(out, "{}", formatted_doc_txt(arg)?)?;

            Ok(String::from_utf8(out).unwrap())
        }
        RGArgKind::Flag { long, short, value_name, multiple, .. } => {
            let mut out = vec![];

            let mut header = format!("--{}", long);
            if let Some(short) = short {
                header = format!("-{}, {}", short, header);
            }
            if multiple {
                header = format!("*{}* _{}_ ...::", header, value_name);
            } else {
                header = format!("*{}* _{}_::", header, value_name);
            }
            writeln!(out, "{}", header)?;
            writeln!(out, "{}", formatted_doc_txt(arg)?)?;

            Ok(String::from_utf8(out).unwrap())
        }
    }
}

fn formatted_doc_txt(arg: &RGArg) -> io::Result<String> {
    let paragraphs: Vec<String> = arg.doc_long
        .replace("{", "{")
        .replace("}", r"}")
        .split("\n\n")
        .map(|s| s.to_string())
        .collect();
    if paragraphs.is_empty() {
        return Err(ioerr(format!("missing docs for --{}", arg.name)));
    }
    let first = format!("  {}", paragraphs[0].replace("\n", "\n  "));
    if paragraphs.len() == 1 {
        return Ok(first);
    }
    Ok(format!("{}\n+\n{}", first, paragraphs[1..].join("\n+\n")))
}

fn ioerr(msg: String) -> io::Error {
    io::Error::new(io::ErrorKind::Other, msg)
}
<commit_msg>edition: fix build.rs<commit_after>use std::env;
use std::fs::{self, File};
use std::io::{self, Read, Write};
use std::path::Path;
use std::process;

use clap::Shell;

use app::{RGArg, RGArgKind};

#[allow(dead_code)]
#[path = "src/app.rs"]
mod app;

fn main() {
    // OUT_DIR is set by Cargo and it's where any additional build artifacts
    // are written.
    let outdir = match env::var_os("OUT_DIR") {
        Some(outdir) => outdir,
        None => {
            eprintln!(
                "OUT_DIR environment variable not defined. \
                 Please file a bug: \
                 https://github.com/BurntSushi/ripgrep/issues/new");
            process::exit(1);
        }
    };
    fs::create_dir_all(&outdir).unwrap();

    let stamp_path = Path::new(&outdir).join("ripgrep-stamp");
    if let Err(err) = File::create(&stamp_path) {
        panic!("failed to write {}: {}", stamp_path.display(), err);
    }
    if let Err(err) = generate_man_page(&outdir) {
        eprintln!("failed to generate man page: {}", err);
    }

    // Use clap to build completion files.
    let mut app = app::app();
    app.gen_completions("rg", Shell::Bash, &outdir);
    app.gen_completions("rg", Shell::Fish, &outdir);
    app.gen_completions("rg", Shell::PowerShell, &outdir);
    // Note that we do not use clap's support for zsh. Instead, zsh completions
    // are manually maintained in `complete/_rg`.

    // Make the current git hash available to the build.
    if let Some(rev) = git_revision_hash() {
        println!("cargo:rustc-env=RIPGREP_BUILD_GIT_HASH={}", rev);
    }
}

fn git_revision_hash() -> Option<String> {
    let result = process::Command::new("git")
        .args(&["rev-parse", "--short=10", "HEAD"])
        .output();
    result.ok().and_then(|output| {
        let v = String::from_utf8_lossy(&output.stdout).trim().to_string();
        if v.is_empty() {
            None
        } else {
            Some(v)
        }
    })
}

fn generate_man_page<P: AsRef<Path>>(outdir: P) -> io::Result<()> {
    // If asciidoc isn't installed, then don't do anything.
    if let Err(err) = process::Command::new("a2x").output() {
        eprintln!("Could not run 'a2x' binary, skipping man page generation.");
        eprintln!("Error from running 'a2x': {}", err);
        return Ok(());
    }
    // 1. Read asciidoc template.
    // 2. Interpolate template with auto-generated docs.
    // 3. Save interpolation to disk.
    // 4. Use a2x (part of asciidoc) to convert to man page.
    let outdir = outdir.as_ref();
    let cwd = env::current_dir()?;
    let tpl_path = cwd.join("doc").join("rg.1.txt.tpl");
    let txt_path = outdir.join("rg.1.txt");

    let mut tpl = String::new();
    File::open(&tpl_path)?.read_to_string(&mut tpl)?;
    tpl = tpl.replace("{OPTIONS}", &formatted_options()?);

    let githash = git_revision_hash();
    let githash = githash.as_ref().map(|x| &**x);
    tpl = tpl.replace("{VERSION}", &app::long_version(githash));

    File::create(&txt_path)?.write_all(tpl.as_bytes())?;
    let result = process::Command::new("a2x")
        .arg("--no-xmllint")
        .arg("--doctype").arg("manpage")
        .arg("--format").arg("manpage")
        .arg(&txt_path)
        .spawn()?
        .wait()?;
    if !result.success() {
        let msg = format!("'a2x' failed with exit code {:?}", result.code());
        return Err(ioerr(msg));
    }
    Ok(())
}

fn formatted_options() -> io::Result<String> {
    let mut args = app::all_args_and_flags();
    args.sort_by(|x1, x2| x1.name.cmp(&x2.name));

    let mut formatted = vec![];
    for arg in args {
        if arg.hidden {
            continue;
        }
        // ripgrep only has two positional arguments, and probably will only
        // ever have two positional arguments, so we just hardcode them into
        // the template.
        if let app::RGArgKind::Positional{..} = arg.kind {
            continue;
        }
        formatted.push(formatted_arg(&arg)?);
    }
    Ok(formatted.join("\n\n"))
}

fn formatted_arg(arg: &RGArg) -> io::Result<String> {
    match arg.kind {
        RGArgKind::Positional{..} => panic!("unexpected positional argument"),
        RGArgKind::Switch { long, short, multiple } => {
            let mut out = vec![];

            let mut header = format!("--{}", long);
            if let Some(short) = short {
                header = format!("-{}, {}", short, header);
            }
            if multiple {
                header = format!("*{}* ...::", header);
            } else {
                header = format!("*{}*::", header);
            }
            writeln!(out, "{}", header)?;
            writeln!(out, "{}", formatted_doc_txt(arg)?)?;

            Ok(String::from_utf8(out).unwrap())
        }
        RGArgKind::Flag { long, short, value_name, multiple, .. } => {
            let mut out = vec![];

            let mut header = format!("--{}", long);
            if let Some(short) = short {
                header = format!("-{}, {}", short, header);
            }
            if multiple {
                header = format!("*{}* _{}_ ...::", header, value_name);
            } else {
                header = format!("*{}* _{}_::", header, value_name);
            }
            writeln!(out, "{}", header)?;
            writeln!(out, "{}", formatted_doc_txt(arg)?)?;

            Ok(String::from_utf8(out).unwrap())
        }
    }
}

fn formatted_doc_txt(arg: &RGArg) -> io::Result<String> {
    let paragraphs: Vec<String> = arg.doc_long
        .replace("{", "{")
        .replace("}", r"}")
        .split("\n\n")
        .map(|s| s.to_string())
        .collect();
    if paragraphs.is_empty() {
        return Err(ioerr(format!("missing docs for --{}", arg.name)));
    }
    let first = format!("  {}", paragraphs[0].replace("\n", "\n  "));
    if paragraphs.len() == 1 {
        return Ok(first);
    }
    Ok(format!("{}\n+\n{}", first, paragraphs[1..].join("\n+\n")))
}

fn ioerr(msg: String) -> io::Error {
    io::Error::new(io::ErrorKind::Other, msg)
}
<|endoftext|>


<commit_before>#[test]
fn dogfood() {
    if option_env!("RUSTC_TEST_SUITE").is_some() {
        return;
    }
    let root_dir = std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR"));
    let clippy_cmd = std::path::Path::new(&root_dir)
        .join("target")
        .join(env!("PROFILE"))
        .join("cargo-clippy");

    let output = std::process::Command::new(clippy_cmd)
        .current_dir(root_dir)
        .env("CLIPPY_DOGFOOD", "1")
        .arg("clippy-preview")
        .arg("--all-targets")
        .arg("--all-features")
        .arg("--")
        .args(&["-D", "clippy::all"])
        .args(&["-D", "clippy::internal"])
        .args(&["-D", "clippy::pedantic"])
        .output()
        .unwrap();
    println!("status: {}", output.status);
    println!("stdout: {}", String::from_utf8_lossy(&output.stdout));
    println!("stderr: {}", String::from_utf8_lossy(&output.stderr));

    assert!(output.status.success());
}

#[test]
fn dogfood_tests() {
    if option_env!("RUSTC_TEST_SUITE").is_some() {
        return;
    }
    let root_dir = std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR"));
    let clippy_cmd = std::path::Path::new(&root_dir)
        .join("target")
        .join(env!("PROFILE"))
        .join("cargo-clippy");

    for d in &[
        "clippy_workspace_tests",
        "clippy_workspace_tests/src",
        "clippy_workspace_tests/subcrate",
        "clippy_workspace_tests/subcrate/src",
        "clippy_dev",
        "rustc_tools_util",
    ] {
        let output = std::process::Command::new(&clippy_cmd)
            .current_dir(root_dir.join(d))
            .env("CLIPPY_DOGFOOD", "1")
            .arg("clippy")
            .arg("--")
            .args(&["-D", "clippy::all"])
            .args(&["-D", "clippy::pedantic"])
            .output()
            .unwrap();
        println!("status: {}", output.status);
        println!("stdout: {}", String::from_utf8_lossy(&output.stdout));
        println!("stderr: {}", String::from_utf8_lossy(&output.stderr));

        assert!(output.status.success());
    }
}
<commit_msg>Disable dogfood on windows for faster build time on travis<commit_after>#[test]
fn dogfood() {
    if option_env!("RUSTC_TEST_SUITE").is_some() || cfg!(windows) {
        return;
    }
    let root_dir = std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR"));
    let clippy_cmd = std::path::Path::new(&root_dir)
        .join("target")
        .join(env!("PROFILE"))
        .join("cargo-clippy");

    let output = std::process::Command::new(clippy_cmd)
        .current_dir(root_dir)
        .env("CLIPPY_DOGFOOD", "1")
        .arg("clippy-preview")
        .arg("--all-targets")
        .arg("--all-features")
        .arg("--")
        .args(&["-D", "clippy::all"])
        .args(&["-D", "clippy::internal"])
        .args(&["-D", "clippy::pedantic"])
        .output()
        .unwrap();
    println!("status: {}", output.status);
    println!("stdout: {}", String::from_utf8_lossy(&output.stdout));
    println!("stderr: {}", String::from_utf8_lossy(&output.stderr));

    assert!(output.status.success());
}

#[test]
fn dogfood_tests() {
    if option_env!("RUSTC_TEST_SUITE").is_some() || cfg!(windows) {
        return;
    }
    let root_dir = std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR"));
    let clippy_cmd = std::path::Path::new(&root_dir)
        .join("target")
        .join(env!("PROFILE"))
        .join("cargo-clippy");

    for d in &[
        "clippy_workspace_tests",
        "clippy_workspace_tests/src",
        "clippy_workspace_tests/subcrate",
        "clippy_workspace_tests/subcrate/src",
        "clippy_dev",
        "rustc_tools_util",
    ] {
        let output = std::process::Command::new(&clippy_cmd)
            .current_dir(root_dir.join(d))
            .env("CLIPPY_DOGFOOD", "1")
            .arg("clippy")
            .arg("--")
            .args(&["-D", "clippy::all"])
            .args(&["-D", "clippy::pedantic"])
            .output()
            .unwrap();
        println!("status: {}", output.status);
        println!("stdout: {}", String::from_utf8_lossy(&output.stdout));
        println!("stderr: {}", String::from_utf8_lossy(&output.stderr));

        assert!(output.status.success());
    }
}
<|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/. */

#![cfg(feature = "debugmozjs")]

#[macro_use]
extern crate mozjs;
extern crate libc;

use mozjs::jsapi::CompartmentOptions;
use mozjs::jsapi::JSAutoCompartment;
use mozjs::jsapi::JSClass;
use mozjs::jsapi::JSContext;
use mozjs::jsapi::JSFunctionSpec;
use mozjs::jsapi::JS_GetObjectPrototype;
use mozjs::jsapi::JSNativeWrapper;
use mozjs::jsapi::JS_NewGlobalObject;
use mozjs::jsapi::JS_NewObjectWithUniqueType;
use mozjs::jsapi::JSPROP_ENUMERATE;
use mozjs::jsapi::JS_SetGCZeal;
use mozjs::jsapi::OnNewGlobalHookOption;
use mozjs::jsapi::Value;
use mozjs::jsapi::{JSObject, JSString, JSFunction};
use mozjs::jsval::JSVal;
use mozjs::rust::{Runtime, SIMPLE_GLOBAL_CLASS, define_methods};
use std::ptr;

#[test]
fn rooting() {
    unsafe {
        let runtime = Runtime::new().unwrap();
        let cx = runtime.cx();
        JS_SetGCZeal(cx, 2, 1);

        let h_option = OnNewGlobalHookOption::FireOnNewGlobalHook;
        let c_option = CompartmentOptions::default();

        rooted!(in(cx) let global = JS_NewGlobalObject(cx,
                                                       &SIMPLE_GLOBAL_CLASS,
                                                       ptr::null_mut(),
                                                       h_option,
                                                       &c_option));
        let _ac = JSAutoCompartment::new(cx, global.get());
        rooted!(in(cx) let prototype_proto = JS_GetObjectPrototype(cx, global.handle().into()));
        rooted!(in(cx) let proto = JS_NewObjectWithUniqueType(cx,
                                                              &CLASS as *const _,
                                                              prototype_proto.handle().into()));
        define_methods(cx, proto.handle(), METHODS).unwrap();
    }
}

#[test]
fn type_rooting() {
    let runtime = Runtime::new().unwrap();
    let cx = runtime.cx();

    unsafe{
        rooted!(in(cx) let root : JSVal);
        assert_eq!(root.get().is_undefined(), true);

        rooted!(in(cx) let root : *mut JSObject);
        assert_eq!(root.get().is_null(), true);

        rooted!(in(cx) let root : *mut JSString);
        assert_eq!(root.get().is_null(), true);

        rooted!(in(cx) let root : *mut JSFunction);
        assert_eq!(root.get().is_null(), true);
    }
}

unsafe extern "C" fn generic_method(_: *mut JSContext, _: u32, _: *mut Value) -> bool {
    true
}

const METHODS: &'static [JSFunctionSpec] = &[
    JSFunctionSpec {
        name: b"addEventListener\0" as *const u8 as *const libc::c_char,
        call: JSNativeWrapper { op: Some(generic_method), info: 0 as *const _ },
        nargs: 2,
        flags: JSPROP_ENUMERATE as u16,
        selfHostedName: 0 as *const libc::c_char
    },
    JSFunctionSpec {
        name: b"removeEventListener\0" as *const u8 as *const libc::c_char,
        call: JSNativeWrapper { op: Some(generic_method), info: 0 as *const _  },
        nargs: 2,
        flags: JSPROP_ENUMERATE as u16,
        selfHostedName: 0 as *const libc::c_char
    },
    JSFunctionSpec {
        name: b"dispatchEvent\0" as *const u8 as *const libc::c_char,
        call: JSNativeWrapper { op: Some(generic_method), info: 0 as *const _  },
        nargs: 1,
        flags: JSPROP_ENUMERATE as u16,
        selfHostedName: 0 as *const libc::c_char
    },
    JSFunctionSpec::ZERO,
];

static CLASS: JSClass = JSClass {
    name: b"EventTargetPrototype\0" as *const u8 as *const libc::c_char,
    flags: 0,
    cOps: 0 as *const _,
    reserved: [0 as *mut _; 3]
};
<commit_msg>[#411] merge test functions<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/. */

#![cfg(feature = "debugmozjs")]

#[macro_use]
extern crate mozjs;
extern crate libc;

use mozjs::jsapi::CompartmentOptions;
use mozjs::jsapi::JSAutoCompartment;
use mozjs::jsapi::JSClass;
use mozjs::jsapi::JSContext;
use mozjs::jsapi::JSFunctionSpec;
use mozjs::jsapi::JS_GetObjectPrototype;
use mozjs::jsapi::JSNativeWrapper;
use mozjs::jsapi::JS_NewGlobalObject;
use mozjs::jsapi::JS_NewObjectWithUniqueType;
use mozjs::jsapi::JSPROP_ENUMERATE;
use mozjs::jsapi::JS_SetGCZeal;
use mozjs::jsapi::OnNewGlobalHookOption;
use mozjs::jsapi::Value;
use mozjs::jsapi::{JSObject, JSString, JSFunction};
use mozjs::jsval::JSVal;
use mozjs::rust::{Runtime, SIMPLE_GLOBAL_CLASS, define_methods};
use std::ptr;

#[test]
fn rooting() {
    unsafe {
        let runtime = Runtime::new().unwrap();
        let cx = runtime.cx();
        JS_SetGCZeal(cx, 2, 1);

        let h_option = OnNewGlobalHookOption::FireOnNewGlobalHook;
        let c_option = CompartmentOptions::default();

        rooted!(in(cx) let global = JS_NewGlobalObject(cx,
                                                       &SIMPLE_GLOBAL_CLASS,
                                                       ptr::null_mut(),
                                                       h_option,
                                                       &c_option));
        let _ac = JSAutoCompartment::new(cx, global.get());
        rooted!(in(cx) let prototype_proto = JS_GetObjectPrototype(cx, global.handle().into()));
        rooted!(in(cx) let proto = JS_NewObjectWithUniqueType(cx,
                                                              &CLASS as *const _,
                                                              prototype_proto.handle().into()));
        define_methods(cx, proto.handle(), METHODS).unwrap();

        rooted!(in(cx) let root : JSVal);
        assert_eq!(root.get().is_undefined(), true);

        rooted!(in(cx) let root : *mut JSObject);
        assert_eq!(root.get().is_null(), true);

        rooted!(in(cx) let root : *mut JSString);
        assert_eq!(root.get().is_null(), true);

        rooted!(in(cx) let root : *mut JSFunction);
        assert_eq!(root.get().is_null(), true);
    }
}

unsafe extern "C" fn generic_method(_: *mut JSContext, _: u32, _: *mut Value) -> bool {
    true
}

const METHODS: &'static [JSFunctionSpec] = &[
    JSFunctionSpec {
        name: b"addEventListener\0" as *const u8 as *const libc::c_char,
        call: JSNativeWrapper { op: Some(generic_method), info: 0 as *const _ },
        nargs: 2,
        flags: JSPROP_ENUMERATE as u16,
        selfHostedName: 0 as *const libc::c_char
    },
    JSFunctionSpec {
        name: b"removeEventListener\0" as *const u8 as *const libc::c_char,
        call: JSNativeWrapper { op: Some(generic_method), info: 0 as *const _  },
        nargs: 2,
        flags: JSPROP_ENUMERATE as u16,
        selfHostedName: 0 as *const libc::c_char
    },
    JSFunctionSpec {
        name: b"dispatchEvent\0" as *const u8 as *const libc::c_char,
        call: JSNativeWrapper { op: Some(generic_method), info: 0 as *const _  },
        nargs: 1,
        flags: JSPROP_ENUMERATE as u16,
        selfHostedName: 0 as *const libc::c_char
    },
    JSFunctionSpec::ZERO,
];

static CLASS: JSClass = JSClass {
    name: b"EventTargetPrototype\0" as *const u8 as *const libc::c_char,
    flags: 0,
    cOps: 0 as *const _,
    reserved: [0 as *mut _; 3]
};
<|endoftext|>