<commit_before>// Code for creating styled buffers

use crate::snippet::{Style, StyledString};

#[derive(Debug)]
pub struct StyledBuffer {
    text: Vec<Vec<char>>,
    styles: Vec<Vec<Style>>,
}

impl StyledBuffer {
    pub fn new() -> StyledBuffer {
        StyledBuffer {
            text: vec![],
            styles: vec![],
        }
    }

    fn replace_tabs(&mut self) {
        for (line_pos, line) in self.text.iter_mut().enumerate() {
            let mut tab_pos = vec![];
            for (pos, c) in line.iter().enumerate() {
                if *c == '\t' {
                    tab_pos.push(pos);
                }
            }
            // start with the tabs at the end of the line to replace them with 4 space chars
            for pos in tab_pos.iter().rev() {
                assert_eq!(line.remove(*pos), '\t');
                // fix the position of the style to match up after replacing the tabs
                let s = self.styles[line_pos].remove(*pos);
                for _ in 0..4 {
                    line.insert(*pos, ' ');
                    self.styles[line_pos].insert(*pos, s);
                }
            }
        }
    }

    pub fn render(&mut self) -> Vec<Vec<StyledString>> {
        let mut output: Vec<Vec<StyledString>> = vec![];
        let mut styled_vec: Vec<StyledString> = vec![];

        // before we render, replace tabs with spaces
        self.replace_tabs();

        for (row, row_style) in self.text.iter().zip(&self.styles) {
            let mut current_style = Style::NoStyle;
            let mut current_text = String::new();

            for (&c, &s) in row.iter().zip(row_style) {
                if s != current_style {
                    if !current_text.is_empty() {
                        styled_vec.push(StyledString {
                            text: current_text,
                            style: current_style,
                        });
                    }
                    current_style = s;
                    current_text = String::new();
                }
                current_text.push(c);
            }
            if !current_text.is_empty() {
                styled_vec.push(StyledString {
                    text: current_text,
                    style: current_style,
                });
            }

            // We're done with the row, push and keep going
            output.push(styled_vec);

            styled_vec = vec![];
        }

        output
    }

    fn ensure_lines(&mut self, line: usize) {
        while line >= self.text.len() {
            self.text.push(vec![]);
            self.styles.push(vec![]);
        }
    }

    pub fn putc(&mut self, line: usize, col: usize, chr: char, style: Style) {
        self.ensure_lines(line);
        if col < self.text[line].len() {
            self.text[line][col] = chr;
            self.styles[line][col] = style;
        } else {
            let mut i = self.text[line].len();
            while i < col {
                self.text[line].push(' ');
                self.styles[line].push(Style::NoStyle);
                i += 1;
            }
            self.text[line].push(chr);
            self.styles[line].push(style);
        }
    }

    pub fn puts(&mut self, line: usize, col: usize, string: &str, style: Style) {
        let mut n = col;
        for c in string.chars() {
            self.putc(line, n, c, style);
            n += 1;
        }
    }

    pub fn prepend(&mut self, line: usize, string: &str, style: Style) {
        self.ensure_lines(line);
        let string_len = string.len();

        // Push the old content over to make room for new content
        for _ in 0..string_len {
            self.styles[line].insert(0, Style::NoStyle);
            self.text[line].insert(0, ' ');
        }

        self.puts(line, 0, string, style);
    }

    pub fn append(&mut self, line: usize, string: &str, style: Style) {
        if line >= self.text.len() {
            self.puts(line, 0, string, style);
        } else {
            let col = self.text[line].len();
            self.puts(line, col, string, style);
        }
    }

    pub fn num_lines(&self) -> usize {
        self.text.len()
    }

    pub fn set_style_range(&mut self,
                           line: usize,
                           col_start: usize,
                           col_end: usize,
                           style: Style,
                           overwrite: bool) {
        for col in col_start..col_end {
            self.set_style(line, col, style, overwrite);
        }
    }

    pub fn set_style(&mut self, line: usize, col: usize, style: Style, overwrite: bool) {
        if let Some(ref mut line) = self.styles.get_mut(line) {
            if let Some(s) = line.get_mut(col) {
                if *s == Style::NoStyle || *s == Style::Quotation || overwrite {
                    *s = style;
                }
            }
        }
    }
}
<commit_msg>Correctly estimate required space for string<commit_after>// Code for creating styled buffers

use crate::snippet::{Style, StyledString};

#[derive(Debug)]
pub struct StyledBuffer {
    text: Vec<Vec<char>>,
    styles: Vec<Vec<Style>>,
}

impl StyledBuffer {
    pub fn new() -> StyledBuffer {
        StyledBuffer {
            text: vec![],
            styles: vec![],
        }
    }

    fn replace_tabs(&mut self) {
        for (line_pos, line) in self.text.iter_mut().enumerate() {
            let mut tab_pos = vec![];
            for (pos, c) in line.iter().enumerate() {
                if *c == '\t' {
                    tab_pos.push(pos);
                }
            }
            // start with the tabs at the end of the line to replace them with 4 space chars
            for pos in tab_pos.iter().rev() {
                assert_eq!(line.remove(*pos), '\t');
                // fix the position of the style to match up after replacing the tabs
                let s = self.styles[line_pos].remove(*pos);
                for _ in 0..4 {
                    line.insert(*pos, ' ');
                    self.styles[line_pos].insert(*pos, s);
                }
            }
        }
    }

    pub fn render(&mut self) -> Vec<Vec<StyledString>> {
        let mut output: Vec<Vec<StyledString>> = vec![];
        let mut styled_vec: Vec<StyledString> = vec![];

        // before we render, replace tabs with spaces
        self.replace_tabs();

        for (row, row_style) in self.text.iter().zip(&self.styles) {
            let mut current_style = Style::NoStyle;
            let mut current_text = String::new();

            for (&c, &s) in row.iter().zip(row_style) {
                if s != current_style {
                    if !current_text.is_empty() {
                        styled_vec.push(StyledString {
                            text: current_text,
                            style: current_style,
                        });
                    }
                    current_style = s;
                    current_text = String::new();
                }
                current_text.push(c);
            }
            if !current_text.is_empty() {
                styled_vec.push(StyledString {
                    text: current_text,
                    style: current_style,
                });
            }

            // We're done with the row, push and keep going
            output.push(styled_vec);

            styled_vec = vec![];
        }

        output
    }

    fn ensure_lines(&mut self, line: usize) {
        while line >= self.text.len() {
            self.text.push(vec![]);
            self.styles.push(vec![]);
        }
    }

    pub fn putc(&mut self, line: usize, col: usize, chr: char, style: Style) {
        self.ensure_lines(line);
        if col < self.text[line].len() {
            self.text[line][col] = chr;
            self.styles[line][col] = style;
        } else {
            let mut i = self.text[line].len();
            while i < col {
                self.text[line].push(' ');
                self.styles[line].push(Style::NoStyle);
                i += 1;
            }
            self.text[line].push(chr);
            self.styles[line].push(style);
        }
    }

    pub fn puts(&mut self, line: usize, col: usize, string: &str, style: Style) {
        let mut n = col;
        for c in string.chars() {
            self.putc(line, n, c, style);
            n += 1;
        }
    }

    pub fn prepend(&mut self, line: usize, string: &str, style: Style) {
        self.ensure_lines(line);
        let string_len = string.chars().count();

        // Push the old content over to make room for new content
        for _ in 0..string_len {
            self.styles[line].insert(0, Style::NoStyle);
            self.text[line].insert(0, ' ');
        }

        self.puts(line, 0, string, style);
    }

    pub fn append(&mut self, line: usize, string: &str, style: Style) {
        if line >= self.text.len() {
            self.puts(line, 0, string, style);
        } else {
            let col = self.text[line].len();
            self.puts(line, col, string, style);
        }
    }

    pub fn num_lines(&self) -> usize {
        self.text.len()
    }

    pub fn set_style_range(&mut self,
                           line: usize,
                           col_start: usize,
                           col_end: usize,
                           style: Style,
                           overwrite: bool) {
        for col in col_start..col_end {
            self.set_style(line, col, style, overwrite);
        }
    }

    pub fn set_style(&mut self, line: usize, col: usize, style: Style, overwrite: bool) {
        if let Some(ref mut line) = self.styles.get_mut(line) {
            if let Some(s) = line.get_mut(col) {
                if *s == Style::NoStyle || *s == Style::Quotation || overwrite {
                    *s = style;
                }
            }
        }
    }
}
<|endoftext|>


<commit_before>// Copyright 2013-2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! Dynamic library facilities.
//!
//! A simple wrapper over the platform's dynamic library facilities

use std::ffi::CString;
use std::path::Path;

pub struct DynamicLibrary {
    handle: *mut u8
}

impl Drop for DynamicLibrary {
    fn drop(&mut self) {
        unsafe {
            dl::close(self.handle)
        }
    }
}

impl DynamicLibrary {
    /// Lazily open a dynamic library. When passed None it gives a
    /// handle to the calling process
    pub fn open(filename: Option<&Path>) -> Result<DynamicLibrary, String> {
        let maybe_library = dl::open(filename.map(|path| path.as_os_str()));

        // The dynamic library must not be constructed if there is
        // an error opening the library so the destructor does not
        // run.
        match maybe_library {
            Err(err) => Err(err),
            Ok(handle) => Ok(DynamicLibrary { handle })
        }
    }

    /// Load a dynamic library into the global namespace (RTLD_GLOBAL on Unix)
    /// and do it now (don't use RTLD_LAZY on Unix).
    pub fn open_global_now(filename: &Path) -> Result<DynamicLibrary, String> {
        let maybe_library = dl::open_global_now(filename.as_os_str());
        match maybe_library {
            Err(err) => Err(err),
            Ok(handle) => Ok(DynamicLibrary { handle })
        }
    }

    /// Returns the environment variable for this process's dynamic library
    /// search path
    pub fn envvar() -> &'static str {
        if cfg!(windows) {
            "PATH"
        } else if cfg!(target_os = "macos") {
            "DYLD_LIBRARY_PATH"
        } else if cfg!(target_os = "haiku") {
            "LIBRARY_PATH"
        } else {
            "LD_LIBRARY_PATH"
        }
    }

    /// Accesses the value at the symbol of the dynamic library.
    pub unsafe fn symbol<T>(&self, symbol: &str) -> Result<*mut T, String> {
        // This function should have a lifetime constraint of 'a on
        // T but that feature is still unimplemented

        let raw_string = CString::new(symbol).unwrap();
        let maybe_symbol_value = dl::symbol(self.handle, raw_string.as_ptr());

        // The value must not be constructed if there is an error so
        // the destructor does not run.
        match maybe_symbol_value {
            Err(err) => Err(err),
            Ok(symbol_value) => Ok(symbol_value as *mut T)
        }
    }
}

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

    #[test]
    fn test_loading_cosine() {
        if cfg!(windows) {
            return
        }

        // The math library does not need to be loaded since it is already
        // statically linked in
        let libm = match DynamicLibrary::open(None) {
            Err(error) => panic!("Could not load self as module: {}", error),
            Ok(libm) => libm
        };

        let cosine: extern fn(libc::c_double) -> libc::c_double = unsafe {
            match libm.symbol("cos") {
                Err(error) => panic!("Could not load function cos: {}", error),
                Ok(cosine) => mem::transmute::<*mut u8, _>(cosine)
            }
        };

        let argument = 0.0;
        let expected_result = 1.0;
        let result = cosine(argument);
        if result != expected_result {
            panic!("cos({}) != {} but equaled {} instead", argument,
                   expected_result, result)
        }
    }

    #[test]
    fn test_errors_do_not_crash() {
        use std::path::Path;

        if !cfg!(unix) {
            return
        }

        // Open /dev/null as a library to get an error, and make sure
        // that only causes an error, and not a crash.
        let path = Path::new("/dev/null");
        match DynamicLibrary::open(Some(&path)) {
            Err(_) => {}
            Ok(_) => panic!("Successfully opened the empty library.")
        }
    }
}

#[cfg(unix)]
mod dl {
    use libc;
    use std::ffi::{CStr, OsStr, CString};
    use std::os::unix::prelude::*;
    use std::ptr;
    use std::str;

    pub fn open(filename: Option<&OsStr>) -> Result<*mut u8, String> {
        check_for_errors_in(|| {
            unsafe {
                match filename {
                    Some(filename) => open_external(filename),
                    None => open_internal(),
                }
            }
        })
    }

    pub fn open_global_now(filename: &OsStr) -> Result<*mut u8, String> {
        check_for_errors_in(|| unsafe {
            let s = CString::new(filename.as_bytes()).unwrap();
            libc::dlopen(s.as_ptr(), libc::RTLD_GLOBAL | libc::RTLD_NOW) as *mut u8
        })
    }

    unsafe fn open_external(filename: &OsStr) -> *mut u8 {
        let s = CString::new(filename.as_bytes()).unwrap();
        libc::dlopen(s.as_ptr(), libc::RTLD_LAZY) as *mut u8
    }

    unsafe fn open_internal() -> *mut u8 {
        libc::dlopen(ptr::null(), libc::RTLD_LAZY) as *mut u8
    }

    pub fn check_for_errors_in<T, F>(f: F) -> Result<T, String> where
        F: FnOnce() -> T,
    {
        use std::sync::{Mutex, Once, ONCE_INIT};
        static INIT: Once = ONCE_INIT;
        static mut LOCK: *mut Mutex<()> = 0 as *mut _;
        unsafe {
            INIT.call_once(|| {
                LOCK = Box::into_raw(Box::new(Mutex::new(())));
            });
            // dlerror isn't thread safe, so we need to lock around this entire
            // sequence
            let _guard = (*LOCK).lock();
            let _old_error = libc::dlerror();

            let result = f();

            let last_error = libc::dlerror() as *const _;
            let ret = if ptr::null() == last_error {
                Ok(result)
            } else {
                let s = CStr::from_ptr(last_error).to_bytes();
                Err(str::from_utf8(s).unwrap().to_owned())
            };

            ret
        }
    }

    pub unsafe fn symbol(handle: *mut u8,
                         symbol: *const libc::c_char)
                         -> Result<*mut u8, String> {
        check_for_errors_in(|| {
            libc::dlsym(handle as *mut libc::c_void, symbol) as *mut u8
        })
    }
    pub unsafe fn close(handle: *mut u8) {
        libc::dlclose(handle as *mut libc::c_void); ()
    }
}

#[cfg(windows)]
mod dl {
    use std::ffi::OsStr;
    use std::io;
    use std::os::windows::prelude::*;
    use std::ptr;

    use libc::{c_uint, c_void, c_char};

    type DWORD = u32;
    type HMODULE = *mut u8;
    type BOOL = i32;
    type LPCWSTR = *const u16;
    type LPCSTR = *const i8;

    extern "system" {
        fn SetThreadErrorMode(dwNewMode: DWORD,
                              lpOldMode: *mut DWORD) -> c_uint;
        fn LoadLibraryW(name: LPCWSTR) -> HMODULE;
        fn GetModuleHandleExW(dwFlags: DWORD,
                              name: LPCWSTR,
                              handle: *mut HMODULE) -> BOOL;
        fn GetProcAddress(handle: HMODULE,
                          name: LPCSTR) -> *mut c_void;
        fn FreeLibrary(handle: HMODULE) -> BOOL;
    }

    pub fn open_global_now(filename: &OsStr) -> Result<*mut u8, String> {
        open(Some(filename))
    }

    pub fn open(filename: Option<&OsStr>) -> Result<*mut u8, String> {
        // disable "dll load failed" error dialog.
        let prev_error_mode = unsafe {
            // SEM_FAILCRITICALERRORS 0x01
            let new_error_mode = 1;
            let mut prev_error_mode = 0;
            let result = SetThreadErrorMode(new_error_mode,
                                            &mut prev_error_mode);
            if result == 0 {
                return Err(io::Error::last_os_error().to_string())
            }
            prev_error_mode
        };

        let result = match filename {
            Some(filename) => {
                let filename_str: Vec<_> =
                    filename.encode_wide().chain(Some(0)).collect();
                let result = unsafe {
                    LoadLibraryW(filename_str.as_ptr())
                };
                ptr_result(result)
            }
            None => {
                let mut handle = ptr::null_mut();
                let succeeded = unsafe {
                    GetModuleHandleExW(0 as DWORD, ptr::null(), &mut handle)
                };
                if succeeded == 0 {
                    Err(io::Error::last_os_error().to_string())
                } else {
                    Ok(handle as *mut u8)
                }
            }
        };

        unsafe {
            SetThreadErrorMode(prev_error_mode, ptr::null_mut());
        }

        result
    }

    pub unsafe fn symbol(handle: *mut u8,
                         symbol: *const c_char)
                         -> Result<*mut u8, String> {
        let ptr = GetProcAddress(handle as HMODULE, symbol) as *mut u8;
        ptr_result(ptr)
    }

    pub unsafe fn close(handle: *mut u8) {
        FreeLibrary(handle as HMODULE);
    }

    fn ptr_result<T>(ptr: *mut T) -> Result<*mut T, String> {
        if ptr.is_null() {
            Err(io::Error::last_os_error().to_string())
        } else {
            Ok(ptr)
        }
    }
}
<commit_msg>rustc_metadata: test loading atoi instead of cos<commit_after>// Copyright 2013-2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! Dynamic library facilities.
//!
//! A simple wrapper over the platform's dynamic library facilities

use std::ffi::CString;
use std::path::Path;

pub struct DynamicLibrary {
    handle: *mut u8
}

impl Drop for DynamicLibrary {
    fn drop(&mut self) {
        unsafe {
            dl::close(self.handle)
        }
    }
}

impl DynamicLibrary {
    /// Lazily open a dynamic library. When passed None it gives a
    /// handle to the calling process
    pub fn open(filename: Option<&Path>) -> Result<DynamicLibrary, String> {
        let maybe_library = dl::open(filename.map(|path| path.as_os_str()));

        // The dynamic library must not be constructed if there is
        // an error opening the library so the destructor does not
        // run.
        match maybe_library {
            Err(err) => Err(err),
            Ok(handle) => Ok(DynamicLibrary { handle })
        }
    }

    /// Load a dynamic library into the global namespace (RTLD_GLOBAL on Unix)
    /// and do it now (don't use RTLD_LAZY on Unix).
    pub fn open_global_now(filename: &Path) -> Result<DynamicLibrary, String> {
        let maybe_library = dl::open_global_now(filename.as_os_str());
        match maybe_library {
            Err(err) => Err(err),
            Ok(handle) => Ok(DynamicLibrary { handle })
        }
    }

    /// Returns the environment variable for this process's dynamic library
    /// search path
    pub fn envvar() -> &'static str {
        if cfg!(windows) {
            "PATH"
        } else if cfg!(target_os = "macos") {
            "DYLD_LIBRARY_PATH"
        } else if cfg!(target_os = "haiku") {
            "LIBRARY_PATH"
        } else {
            "LD_LIBRARY_PATH"
        }
    }

    /// Accesses the value at the symbol of the dynamic library.
    pub unsafe fn symbol<T>(&self, symbol: &str) -> Result<*mut T, String> {
        // This function should have a lifetime constraint of 'a on
        // T but that feature is still unimplemented

        let raw_string = CString::new(symbol).unwrap();
        let maybe_symbol_value = dl::symbol(self.handle, raw_string.as_ptr());

        // The value must not be constructed if there is an error so
        // the destructor does not run.
        match maybe_symbol_value {
            Err(err) => Err(err),
            Ok(symbol_value) => Ok(symbol_value as *mut T)
        }
    }
}

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

    #[test]
    fn test_loading_atoi() {
        if cfg!(windows) {
            return
        }

        // The C library does not need to be loaded since it is already linked in
        let lib = match DynamicLibrary::open(None) {
            Err(error) => panic!("Could not load self as module: {}", error),
            Ok(lib) => lib
        };

        let atoi: extern fn(*const libc::c_char) -> libc::c_int = unsafe {
            match lib.symbol("atoi") {
                Err(error) => panic!("Could not load function atoi: {}", error),
                Ok(atoi) => mem::transmute::<*mut u8, _>(atoi)
            }
        };

        let argument = CString::new("1383428980").unwrap();
        let expected_result = 0x52757374;
        let result = atoi(argument.as_ptr());
        if result != expected_result {
            panic!("atoi({:?}) != {} but equaled {} instead", argument,
                   expected_result, result)
        }
    }

    #[test]
    fn test_errors_do_not_crash() {
        use std::path::Path;

        if !cfg!(unix) {
            return
        }

        // Open /dev/null as a library to get an error, and make sure
        // that only causes an error, and not a crash.
        let path = Path::new("/dev/null");
        match DynamicLibrary::open(Some(&path)) {
            Err(_) => {}
            Ok(_) => panic!("Successfully opened the empty library.")
        }
    }
}

#[cfg(unix)]
mod dl {
    use libc;
    use std::ffi::{CStr, OsStr, CString};
    use std::os::unix::prelude::*;
    use std::ptr;
    use std::str;

    pub fn open(filename: Option<&OsStr>) -> Result<*mut u8, String> {
        check_for_errors_in(|| {
            unsafe {
                match filename {
                    Some(filename) => open_external(filename),
                    None => open_internal(),
                }
            }
        })
    }

    pub fn open_global_now(filename: &OsStr) -> Result<*mut u8, String> {
        check_for_errors_in(|| unsafe {
            let s = CString::new(filename.as_bytes()).unwrap();
            libc::dlopen(s.as_ptr(), libc::RTLD_GLOBAL | libc::RTLD_NOW) as *mut u8
        })
    }

    unsafe fn open_external(filename: &OsStr) -> *mut u8 {
        let s = CString::new(filename.as_bytes()).unwrap();
        libc::dlopen(s.as_ptr(), libc::RTLD_LAZY) as *mut u8
    }

    unsafe fn open_internal() -> *mut u8 {
        libc::dlopen(ptr::null(), libc::RTLD_LAZY) as *mut u8
    }

    pub fn check_for_errors_in<T, F>(f: F) -> Result<T, String> where
        F: FnOnce() -> T,
    {
        use std::sync::{Mutex, Once, ONCE_INIT};
        static INIT: Once = ONCE_INIT;
        static mut LOCK: *mut Mutex<()> = 0 as *mut _;
        unsafe {
            INIT.call_once(|| {
                LOCK = Box::into_raw(Box::new(Mutex::new(())));
            });
            // dlerror isn't thread safe, so we need to lock around this entire
            // sequence
            let _guard = (*LOCK).lock();
            let _old_error = libc::dlerror();

            let result = f();

            let last_error = libc::dlerror() as *const _;
            let ret = if ptr::null() == last_error {
                Ok(result)
            } else {
                let s = CStr::from_ptr(last_error).to_bytes();
                Err(str::from_utf8(s).unwrap().to_owned())
            };

            ret
        }
    }

    pub unsafe fn symbol(handle: *mut u8,
                         symbol: *const libc::c_char)
                         -> Result<*mut u8, String> {
        check_for_errors_in(|| {
            libc::dlsym(handle as *mut libc::c_void, symbol) as *mut u8
        })
    }
    pub unsafe fn close(handle: *mut u8) {
        libc::dlclose(handle as *mut libc::c_void); ()
    }
}

#[cfg(windows)]
mod dl {
    use std::ffi::OsStr;
    use std::io;
    use std::os::windows::prelude::*;
    use std::ptr;

    use libc::{c_uint, c_void, c_char};

    type DWORD = u32;
    type HMODULE = *mut u8;
    type BOOL = i32;
    type LPCWSTR = *const u16;
    type LPCSTR = *const i8;

    extern "system" {
        fn SetThreadErrorMode(dwNewMode: DWORD,
                              lpOldMode: *mut DWORD) -> c_uint;
        fn LoadLibraryW(name: LPCWSTR) -> HMODULE;
        fn GetModuleHandleExW(dwFlags: DWORD,
                              name: LPCWSTR,
                              handle: *mut HMODULE) -> BOOL;
        fn GetProcAddress(handle: HMODULE,
                          name: LPCSTR) -> *mut c_void;
        fn FreeLibrary(handle: HMODULE) -> BOOL;
    }

    pub fn open_global_now(filename: &OsStr) -> Result<*mut u8, String> {
        open(Some(filename))
    }

    pub fn open(filename: Option<&OsStr>) -> Result<*mut u8, String> {
        // disable "dll load failed" error dialog.
        let prev_error_mode = unsafe {
            // SEM_FAILCRITICALERRORS 0x01
            let new_error_mode = 1;
            let mut prev_error_mode = 0;
            let result = SetThreadErrorMode(new_error_mode,
                                            &mut prev_error_mode);
            if result == 0 {
                return Err(io::Error::last_os_error().to_string())
            }
            prev_error_mode
        };

        let result = match filename {
            Some(filename) => {
                let filename_str: Vec<_> =
                    filename.encode_wide().chain(Some(0)).collect();
                let result = unsafe {
                    LoadLibraryW(filename_str.as_ptr())
                };
                ptr_result(result)
            }
            None => {
                let mut handle = ptr::null_mut();
                let succeeded = unsafe {
                    GetModuleHandleExW(0 as DWORD, ptr::null(), &mut handle)
                };
                if succeeded == 0 {
                    Err(io::Error::last_os_error().to_string())
                } else {
                    Ok(handle as *mut u8)
                }
            }
        };

        unsafe {
            SetThreadErrorMode(prev_error_mode, ptr::null_mut());
        }

        result
    }

    pub unsafe fn symbol(handle: *mut u8,
                         symbol: *const c_char)
                         -> Result<*mut u8, String> {
        let ptr = GetProcAddress(handle as HMODULE, symbol) as *mut u8;
        ptr_result(ptr)
    }

    pub unsafe fn close(handle: *mut u8) {
        FreeLibrary(handle as HMODULE);
    }

    fn ptr_result<T>(ptr: *mut T) -> Result<*mut T, String> {
        if ptr.is_null() {
            Err(io::Error::last_os_error().to_string())
        } else {
            Ok(ptr)
        }
    }
}
<|endoftext|>


<commit_before>use crate::ast::{self, Ident};
use crate::source_map::FilePathMapping;
use crate::parse::{ParseSess, PResult, source_file_to_stream};
use crate::parse::{lexer, new_parser_from_source_str};
use crate::parse::parser::Parser;
use crate::ptr::P;
use crate::tokenstream::TokenStream;

use std::iter::Peekable;
use std::path::PathBuf;

/// Map a string to tts, using a made-up filename:
pub fn string_to_stream(source_str: String) -> TokenStream {
    let ps = ParseSess::new(FilePathMapping::empty());
    source_file_to_stream(
        &ps,
        ps.source_map().new_source_file(PathBuf::from("bogofile").into(),
        source_str,
    ), None).0
}

/// Map string to parser (via tts)
pub fn string_to_parser(ps: &ParseSess, source_str: String) -> Parser {
    new_parser_from_source_str(ps, PathBuf::from("bogofile").into(), source_str)
}

fn with_error_checking_parse<'a, T, F>(s: String, ps: &'a ParseSess, f: F) -> T where
    F: FnOnce(&mut Parser<'a>) -> PResult<'a, T>,
{
    let mut p = string_to_parser(&ps, s);
    let x = panictry!(f(&mut p));
    p.sess.span_diagnostic.abort_if_errors();
    x
}

/// Parse a string, return a crate.
pub fn string_to_crate (source_str : String) -> ast::Crate {
    let ps = ParseSess::new(FilePathMapping::empty());
    with_error_checking_parse(source_str, &ps, |p| {
        p.parse_crate_mod()
    })
}

/// Parse a string, return an expr
pub fn string_to_expr (source_str : String) -> P<ast::Expr> {
    let ps = ParseSess::new(FilePathMapping::empty());
    with_error_checking_parse(source_str, &ps, |p| {
        p.parse_expr()
    })
}

/// Parse a string, return an item
pub fn string_to_item (source_str : String) -> Option<P<ast::Item>> {
    let ps = ParseSess::new(FilePathMapping::empty());
    with_error_checking_parse(source_str, &ps, |p| {
        p.parse_item()
    })
}

/// Parse a string, return a pat. Uses "irrefutable"... which doesn't
/// (currently) affect parsing.
pub fn string_to_pat(source_str: String) -> P<ast::Pat> {
    let ps = ParseSess::new(FilePathMapping::empty());
    with_error_checking_parse(source_str, &ps, |p| {
        p.parse_pat(None)
    })
}

/// Converts a vector of strings to a vector of Ident's
pub fn strs_to_idents(ids: Vec<&str> ) -> Vec<Ident> {
    ids.iter().map(|u| Ident::from_str(*u)).collect()
}

/// Does the given string match the pattern? whitespace in the first string
/// may be deleted or replaced with other whitespace to match the pattern.
/// This function is relatively Unicode-ignorant; fortunately, the careful design
/// of UTF-8 mitigates this ignorance. It doesn't do NKF-normalization(?).
pub fn matches_codepattern(a : &str, b : &str) -> bool {
    let mut a_iter = a.chars().peekable();
    let mut b_iter = b.chars().peekable();

    loop {
        let (a, b) = match (a_iter.peek(), b_iter.peek()) {
            (None, None) => return true,
            (None, _) => return false,
            (Some(&a), None) => {
                if is_pattern_whitespace(a) {
                    break // trailing whitespace check is out of loop for borrowck
                } else {
                    return false
                }
            }
            (Some(&a), Some(&b)) => (a, b)
        };

        if is_pattern_whitespace(a) && is_pattern_whitespace(b) {
            // skip whitespace for a and b
            scan_for_non_ws_or_end(&mut a_iter);
            scan_for_non_ws_or_end(&mut b_iter);
        } else if is_pattern_whitespace(a) {
            // skip whitespace for a
            scan_for_non_ws_or_end(&mut a_iter);
        } else if a == b {
            a_iter.next();
            b_iter.next();
        } else {
            return false
        }
    }

    // check if a has *only* trailing whitespace
    a_iter.all(is_pattern_whitespace)
}

/// Advances the given peekable `Iterator` until it reaches a non-whitespace character
fn scan_for_non_ws_or_end<I: Iterator<Item= char>>(iter: &mut Peekable<I>) {
    while lexer::is_pattern_whitespace(iter.peek().cloned()) {
        iter.next();
    }
}

pub fn is_pattern_whitespace(c: char) -> bool {
    lexer::is_pattern_whitespace(Some(c))
}

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

    #[test]
    fn eqmodws() {
        assert_eq!(matches_codepattern("",""),true);
        assert_eq!(matches_codepattern("","a"),false);
        assert_eq!(matches_codepattern("a",""),false);
        assert_eq!(matches_codepattern("a","a"),true);
        assert_eq!(matches_codepattern("a b","a   \n\t\r  b"),true);
        assert_eq!(matches_codepattern("a b ","a   \n\t\r  b"),true);
        assert_eq!(matches_codepattern("a b","a   \n\t\r  b "),false);
        assert_eq!(matches_codepattern("a   b","a b"),true);
        assert_eq!(matches_codepattern("ab","a b"),false);
        assert_eq!(matches_codepattern("a   b","ab"),true);
        assert_eq!(matches_codepattern(" a   b","ab"),true);
    }

    #[test]
    fn pattern_whitespace() {
        assert_eq!(matches_codepattern("","\x0C"), false);
        assert_eq!(matches_codepattern("a b ","a   \u{0085}\n\t\r  b"),true);
        assert_eq!(matches_codepattern("a b","a   \u{0085}\n\t\r  b "),false);
    }

    #[test]
    fn non_pattern_whitespace() {
        // These have the property 'White_Space' but not 'Pattern_White_Space'
        assert_eq!(matches_codepattern("a b","a\u{2002}b"), false);
        assert_eq!(matches_codepattern("a   b","a\u{2002}b"), false);
        assert_eq!(matches_codepattern("\u{205F}a   b","ab"), false);
        assert_eq!(matches_codepattern("a  \u{3000}b","ab"), false);
    }
}
<commit_msg>Add missing lifetime specifier<commit_after>use crate::ast::{self, Ident};
use crate::source_map::FilePathMapping;
use crate::parse::{ParseSess, PResult, source_file_to_stream};
use crate::parse::{lexer, new_parser_from_source_str};
use crate::parse::parser::Parser;
use crate::ptr::P;
use crate::tokenstream::TokenStream;

use std::iter::Peekable;
use std::path::PathBuf;

/// Map a string to tts, using a made-up filename:
pub fn string_to_stream(source_str: String) -> TokenStream {
    let ps = ParseSess::new(FilePathMapping::empty());
    source_file_to_stream(
        &ps,
        ps.source_map().new_source_file(PathBuf::from("bogofile").into(),
        source_str,
    ), None).0
}

/// Map string to parser (via tts)
pub fn string_to_parser(ps: &ParseSess, source_str: String) -> Parser<'_> {
    new_parser_from_source_str(ps, PathBuf::from("bogofile").into(), source_str)
}

fn with_error_checking_parse<'a, T, F>(s: String, ps: &'a ParseSess, f: F) -> T where
    F: FnOnce(&mut Parser<'a>) -> PResult<'a, T>,
{
    let mut p = string_to_parser(&ps, s);
    let x = panictry!(f(&mut p));
    p.sess.span_diagnostic.abort_if_errors();
    x
}

/// Parse a string, return a crate.
pub fn string_to_crate (source_str : String) -> ast::Crate {
    let ps = ParseSess::new(FilePathMapping::empty());
    with_error_checking_parse(source_str, &ps, |p| {
        p.parse_crate_mod()
    })
}

/// Parse a string, return an expr
pub fn string_to_expr (source_str : String) -> P<ast::Expr> {
    let ps = ParseSess::new(FilePathMapping::empty());
    with_error_checking_parse(source_str, &ps, |p| {
        p.parse_expr()
    })
}

/// Parse a string, return an item
pub fn string_to_item (source_str : String) -> Option<P<ast::Item>> {
    let ps = ParseSess::new(FilePathMapping::empty());
    with_error_checking_parse(source_str, &ps, |p| {
        p.parse_item()
    })
}

/// Parse a string, return a pat. Uses "irrefutable"... which doesn't
/// (currently) affect parsing.
pub fn string_to_pat(source_str: String) -> P<ast::Pat> {
    let ps = ParseSess::new(FilePathMapping::empty());
    with_error_checking_parse(source_str, &ps, |p| {
        p.parse_pat(None)
    })
}

/// Converts a vector of strings to a vector of Ident's
pub fn strs_to_idents(ids: Vec<&str> ) -> Vec<Ident> {
    ids.iter().map(|u| Ident::from_str(*u)).collect()
}

/// Does the given string match the pattern? whitespace in the first string
/// may be deleted or replaced with other whitespace to match the pattern.
/// This function is relatively Unicode-ignorant; fortunately, the careful design
/// of UTF-8 mitigates this ignorance. It doesn't do NKF-normalization(?).
pub fn matches_codepattern(a : &str, b : &str) -> bool {
    let mut a_iter = a.chars().peekable();
    let mut b_iter = b.chars().peekable();

    loop {
        let (a, b) = match (a_iter.peek(), b_iter.peek()) {
            (None, None) => return true,
            (None, _) => return false,
            (Some(&a), None) => {
                if is_pattern_whitespace(a) {
                    break // trailing whitespace check is out of loop for borrowck
                } else {
                    return false
                }
            }
            (Some(&a), Some(&b)) => (a, b)
        };

        if is_pattern_whitespace(a) && is_pattern_whitespace(b) {
            // skip whitespace for a and b
            scan_for_non_ws_or_end(&mut a_iter);
            scan_for_non_ws_or_end(&mut b_iter);
        } else if is_pattern_whitespace(a) {
            // skip whitespace for a
            scan_for_non_ws_or_end(&mut a_iter);
        } else if a == b {
            a_iter.next();
            b_iter.next();
        } else {
            return false
        }
    }

    // check if a has *only* trailing whitespace
    a_iter.all(is_pattern_whitespace)
}

/// Advances the given peekable `Iterator` until it reaches a non-whitespace character
fn scan_for_non_ws_or_end<I: Iterator<Item= char>>(iter: &mut Peekable<I>) {
    while lexer::is_pattern_whitespace(iter.peek().cloned()) {
        iter.next();
    }
}

pub fn is_pattern_whitespace(c: char) -> bool {
    lexer::is_pattern_whitespace(Some(c))
}

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

    #[test]
    fn eqmodws() {
        assert_eq!(matches_codepattern("",""),true);
        assert_eq!(matches_codepattern("","a"),false);
        assert_eq!(matches_codepattern("a",""),false);
        assert_eq!(matches_codepattern("a","a"),true);
        assert_eq!(matches_codepattern("a b","a   \n\t\r  b"),true);
        assert_eq!(matches_codepattern("a b ","a   \n\t\r  b"),true);
        assert_eq!(matches_codepattern("a b","a   \n\t\r  b "),false);
        assert_eq!(matches_codepattern("a   b","a b"),true);
        assert_eq!(matches_codepattern("ab","a b"),false);
        assert_eq!(matches_codepattern("a   b","ab"),true);
        assert_eq!(matches_codepattern(" a   b","ab"),true);
    }

    #[test]
    fn pattern_whitespace() {
        assert_eq!(matches_codepattern("","\x0C"), false);
        assert_eq!(matches_codepattern("a b ","a   \u{0085}\n\t\r  b"),true);
        assert_eq!(matches_codepattern("a b","a   \u{0085}\n\t\r  b "),false);
    }

    #[test]
    fn non_pattern_whitespace() {
        // These have the property 'White_Space' but not 'Pattern_White_Space'
        assert_eq!(matches_codepattern("a b","a\u{2002}b"), false);
        assert_eq!(matches_codepattern("a   b","a\u{2002}b"), false);
        assert_eq!(matches_codepattern("\u{205F}a   b","ab"), false);
        assert_eq!(matches_codepattern("a  \u{3000}b","ab"), false);
    }
}
<|endoftext|>


<commit_before>pub mod context;
#[cfg_attr(rustfmt, rustfmt_skip)]
mod_path! parser (concat!(env!("OUT_DIR"), "/query/parser.rs"));

use value;
pub use self::context::Context;

#[derive(Clone, Debug, Eq, PartialEq)]
pub enum Query {
    Chain(Vec<Query>),
    Function(String, Vec<Expression>),
}

#[derive(Clone, Debug, Eq, PartialEq)]
pub enum Expression {
    String(String),
    Integer(i64),
}

impl Query {
    pub fn parse(raw: &str) -> Query {
        parser::parse_query(raw).unwrap()
    }

    pub fn evaluate(&self, context: &context::Context, input: value::Value) -> value::Value {
        match *self {
            Query::Chain(ref queries) => apply_chain(context, input, queries),
            Query::Function(ref name, ref args) => apply_function(context, input, name, args),
        }
    }
}

impl Expression {
    fn to_value(&self) -> value::Value {
        match *self {
            Expression::String(ref s) => value::Value::String(s.clone()),
            Expression::Integer(i) => value::Value::I64(i),
        }
    }
}

fn apply_chain(context: &context::Context, input: value::Value, queries: &[Query]) -> value::Value{
    let mut result = input;

    for query in queries {
        result = query.evaluate(context, result);
    }

    result
}

fn apply_function(context: &context::Context, input: value::Value, name: &str, args: &[Expression]) -> value::Value {
    match context.function(name) {
        Some(func) => {
            let mut vals = Vec::with_capacity(args.len() + 1);
            vals.push(input);
            for arg in args {
                vals.push(arg.to_value())
            }
            func(&vals)
        },
        None => value::Value::Unit,
    }
}

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

    #[test]
    fn parse_bare_function() {
        let expected = Query::Function("select".to_owned(), vec![]);
        let actual = Query::parse("select");

        assert_eq!(expected, actual);
    }

    #[test]
    fn parse_function_one_arg() {
        let expected =
            Query::Function("select".to_owned(),
                            vec![Expression::String("a".to_owned())]);
        let actual = Query::parse("select a");

        assert_eq!(expected, actual);
    }

    #[test]
    fn parse_function_one_arg_ident_numbers() {
        let expected =
            Query::Function("select".to_owned(),
                            vec![Expression::String("abc123".to_owned())]);
        let actual = Query::parse("select abc123");

        assert_eq!(expected, actual);
    }

    #[test]
    fn parse_function_one_arg_integer() {
        let expected =
            Query::Function("select".to_owned(),
                            vec![Expression::Integer(52)]);
        let actual = Query::parse("select 52");

        assert_eq!(expected, actual);
    }

    #[test]
    fn parse_function_one_arg_negative_integer() {
        let expected =
            Query::Function("select".to_owned(),
                            vec![Expression::Integer(-52)]);
        let actual = Query::parse("select -52");

        assert_eq!(expected, actual);
    }

    #[test]
    fn parse_function_one_arg_negative_integer_spaced() {
        let expected =
            Query::Function("select".to_owned(),
                            vec![Expression::Integer(-52)]);
        let actual = Query::parse("select - 52");

        assert_eq!(expected, actual);
    }

    #[test]
    fn parse_function_one_arg_underscore() {
        let expected =
            Query::Function("select".to_owned(),
                            vec![Expression::String("abc_def".to_owned())]);
        let actual = Query::parse("select abc_def");

        assert_eq!(expected, actual);
    }

    #[test]
    fn parse_function_one_arg_dash() {
        let expected =
            Query::Function("select".to_owned(),
                            vec![Expression::String("abc-def".to_owned())]);
        let actual = Query::parse("select abc-def");

        assert_eq!(expected, actual);
    }

    #[test]
    fn parse_function_two_args() {
        let expected =
            Query::Function("select".to_owned(), vec![
                Expression::String("abc-def".to_owned()),
                Expression::String("ghi_123".to_owned()),
            ]);
        let actual = Query::parse("select abc-def ghi_123");

        assert_eq!(expected, actual);
    }
}
<commit_msg>Hide query::context module<commit_after>mod context;
#[cfg_attr(rustfmt, rustfmt_skip)]
mod_path! parser (concat!(env!("OUT_DIR"), "/query/parser.rs"));

use value;
pub use self::context::Context;

#[derive(Clone, Debug, Eq, PartialEq)]
pub enum Query {
    Chain(Vec<Query>),
    Function(String, Vec<Expression>),
}

#[derive(Clone, Debug, Eq, PartialEq)]
pub enum Expression {
    String(String),
    Integer(i64),
}

impl Query {
    pub fn parse(raw: &str) -> Query {
        parser::parse_query(raw).unwrap()
    }

    pub fn evaluate(&self, context: &context::Context, input: value::Value) -> value::Value {
        match *self {
            Query::Chain(ref queries) => apply_chain(context, input, queries),
            Query::Function(ref name, ref args) => apply_function(context, input, name, args),
        }
    }
}

impl Expression {
    fn to_value(&self) -> value::Value {
        match *self {
            Expression::String(ref s) => value::Value::String(s.clone()),
            Expression::Integer(i) => value::Value::I64(i),
        }
    }
}

fn apply_chain(context: &context::Context, input: value::Value, queries: &[Query]) -> value::Value{
    let mut result = input;

    for query in queries {
        result = query.evaluate(context, result);
    }

    result
}

fn apply_function(context: &context::Context, input: value::Value, name: &str, args: &[Expression]) -> value::Value {
    match context.function(name) {
        Some(func) => {
            let mut vals = Vec::with_capacity(args.len() + 1);
            vals.push(input);
            for arg in args {
                vals.push(arg.to_value())
            }
            func(&vals)
        },
        None => value::Value::Unit,
    }
}

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

    #[test]
    fn parse_bare_function() {
        let expected = Query::Function("select".to_owned(), vec![]);
        let actual = Query::parse("select");

        assert_eq!(expected, actual);
    }

    #[test]
    fn parse_function_one_arg() {
        let expected =
            Query::Function("select".to_owned(),
                            vec![Expression::String("a".to_owned())]);
        let actual = Query::parse("select a");

        assert_eq!(expected, actual);
    }

    #[test]
    fn parse_function_one_arg_ident_numbers() {
        let expected =
            Query::Function("select".to_owned(),
                            vec![Expression::String("abc123".to_owned())]);
        let actual = Query::parse("select abc123");

        assert_eq!(expected, actual);
    }

    #[test]
    fn parse_function_one_arg_integer() {
        let expected =
            Query::Function("select".to_owned(),
                            vec![Expression::Integer(52)]);
        let actual = Query::parse("select 52");

        assert_eq!(expected, actual);
    }

    #[test]
    fn parse_function_one_arg_negative_integer() {
        let expected =
            Query::Function("select".to_owned(),
                            vec![Expression::Integer(-52)]);
        let actual = Query::parse("select -52");

        assert_eq!(expected, actual);
    }

    #[test]
    fn parse_function_one_arg_negative_integer_spaced() {
        let expected =
            Query::Function("select".to_owned(),
                            vec![Expression::Integer(-52)]);
        let actual = Query::parse("select - 52");

        assert_eq!(expected, actual);
    }

    #[test]
    fn parse_function_one_arg_underscore() {
        let expected =
            Query::Function("select".to_owned(),
                            vec![Expression::String("abc_def".to_owned())]);
        let actual = Query::parse("select abc_def");

        assert_eq!(expected, actual);
    }

    #[test]
    fn parse_function_one_arg_dash() {
        let expected =
            Query::Function("select".to_owned(),
                            vec![Expression::String("abc-def".to_owned())]);
        let actual = Query::parse("select abc-def");

        assert_eq!(expected, actual);
    }

    #[test]
    fn parse_function_two_args() {
        let expected =
            Query::Function("select".to_owned(), vec![
                Expression::String("abc-def".to_owned()),
                Expression::String("ghi_123".to_owned()),
            ]);
        let actual = Query::parse("select abc-def ghi_123");

        assert_eq!(expected, actual);
    }
}
<|endoftext|>


<commit_before>// The Computer Language Benchmarks Game
// http://benchmarksgame.alioth.debian.org/
//
// contributed by the Rust Project Developers
// contributed by BurntSushi
// contributed by TeXitoi

// Copyright (c) 2014 The Rust Project Developers
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// - Redistributions of source code must retain the above copyright
//   notice, this list of conditions and the following disclaimer.
//
// - Redistributions in binary form must reproduce the above copyright
//   notice, this list of conditions and the following disclaimer in
//   the documentation and/or other materials provided with the
//   distribution.
//
// - Neither the name of "The Computer Language Benchmarks Game" nor
//   the name of "The Computer Language Shootout Benchmarks" nor the
//   names of its contributors may be used to endorse or promote
//   products derived from this software without specific prior
//   written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
// OF THE POSSIBILITY OF SUCH DAMAGE.

extern crate regex;

use std::io::{self, Read};
use std::sync::Arc;
use std::thread;
use regex::NoExpand;

macro_rules! regex { ($re:expr) => (::regex::Regex::new($re).unwrap()); }

fn main() {
    let mut seq = String::new();
    io::stdin().read_to_string(&mut seq).unwrap();
    let ilen = seq.len();

    seq = regex!(">[^\n]*\n|\n").replace_all(&seq, NoExpand(""));
    let seq_arc = Arc::new(seq.clone()); // copy before it moves
    let clen = seq.len();

    let seqlen = thread::scoped(move|| {
        let substs = vec![
            (regex!("B"), "(c|g|t)"),
            (regex!("D"), "(a|g|t)"),
            (regex!("H"), "(a|c|t)"),
            (regex!("K"), "(g|t)"),
            (regex!("M"), "(a|c)"),
            (regex!("N"), "(a|c|g|t)"),
            (regex!("R"), "(a|g)"),
            (regex!("S"), "(c|g)"),
            (regex!("V"), "(a|c|g)"),
            (regex!("W"), "(a|t)"),
            (regex!("Y"), "(c|t)"),
        ];
        let mut seq = seq;
        for (re, replacement) in substs.into_iter() {
            seq = re.replace_all(&seq, NoExpand(replacement));
        }
        seq.len()
    });

    let variants = vec![
        regex!("agggtaaa|tttaccct"),
        regex!("[cgt]gggtaaa|tttaccc[acg]"),
        regex!("a[act]ggtaaa|tttacc[agt]t"),
        regex!("ag[act]gtaaa|tttac[agt]ct"),
        regex!("agg[act]taaa|ttta[agt]cct"),
        regex!("aggg[acg]aaa|ttt[cgt]ccct"),
        regex!("agggt[cgt]aa|tt[acg]accct"),
        regex!("agggta[cgt]a|t[acg]taccct"),
        regex!("agggtaa[cgt]|[acg]ttaccct"),
    ];
    let (mut variant_strs, mut counts) = (vec!(), vec!());
    for variant in variants.into_iter() {
        let seq_arc_copy = seq_arc.clone();
        variant_strs.push(variant.to_string());
        counts.push(thread::scoped(move|| {
            variant.find_iter(&seq_arc_copy).count()
        }));
    }

    let mut olines = Vec::new();
    for (variant, count) in variant_strs.iter().zip(counts.into_iter()) {
        olines.push(format!("{} {}", variant, count.join()));
    }
    olines.push("".to_string());
    olines.push(format!("{}", ilen));
    olines.push(format!("{}", clen));
    olines.push(format!("{}", seqlen.join()));
    println!("{}", olines.connect("\n"));
}
<commit_msg>Remove license header.<commit_after>// The Computer Language Benchmarks Game
// http://benchmarksgame.alioth.debian.org/
//
// contributed by the Rust Project Developers
// contributed by BurntSushi
// contributed by TeXitoi

extern crate regex;

use std::io::{self, Read};
use std::sync::Arc;
use std::thread;
use regex::NoExpand;

macro_rules! regex { ($re:expr) => (::regex::Regex::new($re).unwrap()); }

fn main() {
    let mut seq = String::new();
    io::stdin().read_to_string(&mut seq).unwrap();
    let ilen = seq.len();

    seq = regex!(">[^\n]*\n|\n").replace_all(&seq, NoExpand(""));
    let seq_arc = Arc::new(seq.clone()); // copy before it moves
    let clen = seq.len();

    let seqlen = thread::scoped(move|| {
        let substs = vec![
            (regex!("B"), "(c|g|t)"),
            (regex!("D"), "(a|g|t)"),
            (regex!("H"), "(a|c|t)"),
            (regex!("K"), "(g|t)"),
            (regex!("M"), "(a|c)"),
            (regex!("N"), "(a|c|g|t)"),
            (regex!("R"), "(a|g)"),
            (regex!("S"), "(c|g)"),
            (regex!("V"), "(a|c|g)"),
            (regex!("W"), "(a|t)"),
            (regex!("Y"), "(c|t)"),
        ];
        let mut seq = seq;
        for (re, replacement) in substs.into_iter() {
            seq = re.replace_all(&seq, NoExpand(replacement));
        }
        seq.len()
    });

    let variants = vec![
        regex!("agggtaaa|tttaccct"),
        regex!("[cgt]gggtaaa|tttaccc[acg]"),
        regex!("a[act]ggtaaa|tttacc[agt]t"),
        regex!("ag[act]gtaaa|tttac[agt]ct"),
        regex!("agg[act]taaa|ttta[agt]cct"),
        regex!("aggg[acg]aaa|ttt[cgt]ccct"),
        regex!("agggt[cgt]aa|tt[acg]accct"),
        regex!("agggta[cgt]a|t[acg]taccct"),
        regex!("agggtaa[cgt]|[acg]ttaccct"),
    ];
    let (mut variant_strs, mut counts) = (vec!(), vec!());
    for variant in variants.into_iter() {
        let seq_arc_copy = seq_arc.clone();
        variant_strs.push(variant.to_string());
        counts.push(thread::scoped(move|| {
            variant.find_iter(&seq_arc_copy).count()
        }));
    }

    let mut olines = Vec::new();
    for (variant, count) in variant_strs.iter().zip(counts.into_iter()) {
        olines.push(format!("{} {}", variant, count.join()));
    }
    olines.push("".to_string());
    olines.push(format!("{}", ilen));
    olines.push(format!("{}", clen));
    olines.push(format!("{}", seqlen.join()));
    println!("{}", olines.connect("\n"));
}
<|endoftext|>


<commit_before>use std::ops::Not;

use types::chat::*;
use types::primitive::*;
use types::message::*;
use requests::_base::*;

#[derive(Debug, Clone, PartialEq, PartialOrd, Serialize)]
pub struct SendMessage<'c, 's> {
    pub chat_id: ChatId<'c>,
    pub text: &'s str,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub parse_mode: Option<ParseMode>,
    #[serde(skip_serializing_if = "Not::not")]
    pub disable_web_page_preview: bool,
    #[serde(skip_serializing_if = "Not::not")]
    pub disable_notification: bool,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub reply_to_message_id: Option<Integer>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub reply_markup: Option<ReplyMarkup>,
}

impl<'c, 's> SendMessage<'c, 's> {
    pub fn new<C>(chat: C, text: &'s str) -> Self where C: Into<ChatId<'c>> {
        SendMessage {
            chat_id: chat.into(),
            text: text,
            parse_mode: None,
            disable_web_page_preview: false,
            disable_notification: false,
            reply_to_message_id: None,
            reply_markup: None,
        }
    }

    pub fn parse_mode(mut self, parse_mode: ParseMode) -> Self {
        self.parse_mode = Some(parse_mode);
        self
    }

    pub fn disable_web_page_preview(mut self) -> Self { // TODO(knsd): Rename to disable_preview?
        self.disable_web_page_preview = true;
        self
    }

    pub fn disable_notification(mut self) -> Self {
        self.disable_notification = true;
        self
    }

    pub fn reply_to<R>(mut self, to: R) -> Self where R: Into<ReplyTo> {
        self.reply_to_message_id = Some(to.into().0);
        self
    }

    pub fn reply_markup(mut self, reply_markup: ReplyMarkup) -> Self { // TODO(knsd): nice builder?
        self.reply_markup = Some(reply_markup);
        self
    }
}

impl Chat {
    pub fn text<'c, 's>(&'c self, text: &'s str) -> SendMessage<'c, 's> {
        SendMessage::new(self, text)
    }
}

macro_rules! send_chat_type {
    ($chat: ident) => {
        impl $chat {
            pub fn text<'c, 's>(&'c self, text: &'s str) -> SendMessage<'c, 's> {
                SendMessage::new(self, text)
            }
        }
    };
}

send_chat_type!(User);
send_chat_type!(Group);
send_chat_type!(Supergroup);
send_chat_type!(Channel);

impl ForwardFrom {
    pub fn text<'c, 's>(&'c self, text: &'s str) -> SendMessage<'c, 's> {
        let id = match *self {
            ForwardFrom::User {ref user, ..} => user.id,
            ForwardFrom::Channel {ref channel, ..} => channel.id,
        };

        SendMessage::new(id, text)
    }
}

impl Message {
    pub fn text_reply<'c, 's>(&'c self, text: &'s str) -> SendMessage<'c, 's> {
        self.chat.text(text).reply_to(self)
    }
}
<commit_msg>feat: implement Request for SendMessage<commit_after>use std::ops::Not;

use types::chat::*;
use types::primitive::*;
use types::message::*;
use requests::_base::*;

#[derive(Debug, Clone, PartialEq, PartialOrd, Serialize)]
pub struct SendMessage<'c, 's> {
    pub chat_id: ChatId<'c>,
    pub text: &'s str,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub parse_mode: Option<ParseMode>,
    #[serde(skip_serializing_if = "Not::not")]
    pub disable_web_page_preview: bool,
    #[serde(skip_serializing_if = "Not::not")]
    pub disable_notification: bool,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub reply_to_message_id: Option<Integer>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub reply_markup: Option<ReplyMarkup>,
}

impl<'c, 's> Request for SendMessage<'c, 's> {
    type Response = Message;
}

impl<'c, 's> SendMessage<'c, 's> {
    pub fn new<C>(chat: C, text: &'s str) -> Self where C: Into<ChatId<'c>> {
        SendMessage {
            chat_id: chat.into(),
            text: text,
            parse_mode: None,
            disable_web_page_preview: false,
            disable_notification: false,
            reply_to_message_id: None,
            reply_markup: None,
        }
    }

    pub fn parse_mode(mut self, parse_mode: ParseMode) -> Self {
        self.parse_mode = Some(parse_mode);
        self
    }

    pub fn disable_web_page_preview(mut self) -> Self { // TODO(knsd): Rename to disable_preview?
        self.disable_web_page_preview = true;
        self
    }

    pub fn disable_notification(mut self) -> Self {
        self.disable_notification = true;
        self
    }

    pub fn reply_to<R>(mut self, to: R) -> Self where R: Into<ReplyTo> {
        self.reply_to_message_id = Some(to.into().0);
        self
    }

    pub fn reply_markup(mut self, reply_markup: ReplyMarkup) -> Self { // TODO(knsd): nice builder?
        self.reply_markup = Some(reply_markup);
        self
    }
}

impl Chat {
    pub fn text<'c, 's>(&'c self, text: &'s str) -> SendMessage<'c, 's> {
        SendMessage::new(self, text)
    }
}

macro_rules! send_chat_type {
    ($chat: ident) => {
        impl $chat {
            pub fn text<'c, 's>(&'c self, text: &'s str) -> SendMessage<'c, 's> {
                SendMessage::new(self, text)
            }
        }
    };
}

send_chat_type!(User);
send_chat_type!(Group);
send_chat_type!(Supergroup);
send_chat_type!(Channel);

impl ForwardFrom {
    pub fn text<'c, 's>(&'c self, text: &'s str) -> SendMessage<'c, 's> {
        let id = match *self {
            ForwardFrom::User {ref user, ..} => user.id,
            ForwardFrom::Channel {ref channel, ..} => channel.id,
        };

        SendMessage::new(id, text)
    }
}

impl Message {
    pub fn text_reply<'c, 's>(&'c self, text: &'s str) -> SendMessage<'c, 's> {
        self.chat.text(text).reply_to(self)
    }
}
<|endoftext|>


<commit_before>#![cfg(feature = "dynamodb")]

extern crate rusoto_core;
extern crate rusoto_dynamodb;

use rusoto_dynamodb::{DynamoDb, DynamoDbClient, ListTablesInput, ListTablesError};
use rusoto_core::{DefaultCredentialsProvider, Region};
use rusoto_core::default_tls_client;

#[test]
fn should_parse_error_type() {
    let credentials = DefaultCredentialsProvider::new().unwrap();
    let a_region = Region::Custom("http://localhost:8000".to_owned());
    let client = DynamoDbClient::new(default_tls_client().unwrap(), credentials, a_region);

    // limit of -1 should generate a validation error
    let request = ListTablesInput { limit: Some(-1), ..Default::default() };

    let response = client.list_tables(&request);
    match response {
        Err(ListTablesError::Validation(msg)) => {
            // local dynamodb gives a different error, this matches both:
            assert!(msg.contains("greater than or equal to 1"))
        }
        _ => panic!("Should have been a Validation error"),
    };
}

#[test]
fn should_list_tables() {
    let credentials = DefaultCredentialsProvider::new().unwrap();
    let a_region = Region::Custom("http://localhost:8000".to_owned());
    let client = DynamoDbClient::new(default_tls_client().unwrap(), credentials, a_region);
    let request = ListTablesInput::default();

    client.list_tables(&request).unwrap();
}
<commit_msg>Reset dynamodb integration tests to use AWS.<commit_after>#![cfg(feature = "dynamodb")]

extern crate rusoto_core;
extern crate rusoto_dynamodb;

use rusoto_dynamodb::{DynamoDb, DynamoDbClient, ListTablesInput, ListTablesError};
use rusoto_core::{DefaultCredentialsProvider, Region};
use rusoto_core::default_tls_client;

#[test]
fn should_parse_error_type() {
    let credentials = DefaultCredentialsProvider::new().unwrap();
    let client = DynamoDbClient::new(default_tls_client().unwrap(), credentials, Region::UsEast1);

    // limit of -1 should generate a validation error
    let request = ListTablesInput { limit: Some(-1), ..Default::default() };

    let response = client.list_tables(&request);
    match response {
        Err(ListTablesError::Validation(msg)) => {
            // local dynamodb gives a different error, this matches both:
            assert!(msg.contains("greater than or equal to 1"))
        }
        _ => panic!("Should have been a Validation error"),
    };
}

#[test]
fn should_list_tables() {
    let credentials = DefaultCredentialsProvider::new().unwrap();
    let client = DynamoDbClient::new(default_tls_client().unwrap(), credentials, Region::UsEast1);
    let request = ListTablesInput::default();

    client.list_tables(&request).unwrap();
}
<|endoftext|>


<commit_before>use backend::obj::*;
use std::f32::consts;
use num::Integer;
use core::color;
use core::color::ToRgb;
use core::geometry::*;
use backend::world::segment;
use backend::world::segment::*;
use backend::world::agent;
use backend::world::agent::Agent;
use backend::world::gen::*;
use cgmath;
use cgmath::EuclideanVector;

pub trait Phenotype {
	fn develop(gen: &mut Genome, id: Id, transform: Transform, motion: Option<Motion>, charge: f32) -> agent::Agent;
}

pub struct Resource {}
pub struct Minion {}
pub struct Spore {}

impl Phenotype for Resource {
	fn develop(gen: &mut Genome, id: Id, transform: Transform, motion: Option<Motion>, charge: f32) -> agent::Agent {

		let albedo = color::YPbPr::new(0.5, gen.next_float(-0.5, 0.5), gen.next_float(-0.5, 0.5));
		let body = gen.eq_triangle();
		let mut builder = AgentBuilder::new(id,
		                                    Material { density: 1.0, ..Default::default() },
		                                    Livery { albedo: albedo.to_rgba(), ..Default::default() },
		                                    gen.dna(),
		                                    segment::State::with_charge(charge, 0., charge));
		builder.start(transform, motion, &body).build()
	}
}

impl Phenotype for Minion {
	fn develop(gen: &mut Genome, id: Id, transform: Transform, motion: Option<Motion>, charge: f32) -> agent::Agent {
		let albedo = color::Hsl::new(gen.next_float(0., 1.), 0.5, 0.5);
		let mut builder = AgentBuilder::new(id,
		                                    Material { density: 0.2, ..Default::default() },
		                                    Livery { albedo: albedo.to_rgba(), ..Default::default() },
		                                    gen.dna(),
		                                    segment::State::with_charge(0., charge, charge));
		let torso_shape = gen.any_poly();
		let torso = builder.start(transform, motion, &torso_shape).index();
		let arm_shape = gen.star();
		let leg_shape = gen.star();
		let head_shape = gen.iso_triangle();
		let antenna_shape = gen.triangle();
		let tail_shape = gen.vbar();
		let i = ::std::cmp::max((torso_shape.length() as isize / 5), 1);
		builder.addr(torso, i, &arm_shape, ARM | JOINT | ACTUATOR | RUDDER)
			.addl(torso, -i, &arm_shape, ARM | JOINT | ACTUATOR | RUDDER);

		let head = builder.add(torso, 0, &head_shape, HEAD | MOUTH | SENSOR).index();
		builder.addr(head, 1, &antenna_shape, HEAD | MOUTH | ACTUATOR | RUDDER)
			.addl(head, 2, &antenna_shape, HEAD | MOUTH | ACTUATOR | RUDDER);

		let mut belly = torso;
		let mut belly_mid = torso_shape.mid();
		while gen.next_integer(0, 4) == 0 {
			let belly_shape = gen.poly(true);

			belly = builder.add(belly, belly_mid, &belly_shape, STORAGE | JOINT).index();
			belly_mid = belly_shape.mid();
			if gen.next_integer(0, 4) == 0 {
				builder.addr(belly, 2, &arm_shape, ARM | ACTUATOR | RUDDER)
					.addl(belly, -2, &arm_shape, ARM | ACTUATOR | RUDDER);
			}
		}

		builder.addr(belly, belly_mid - 1, &leg_shape, LEG | ACTUATOR | THRUSTER)
			.addl(belly,
			      -(belly_mid - 1),
			      &leg_shape,
			      LEG | ACTUATOR | THRUSTER)
			.add(belly, belly_mid, &tail_shape, TAIL | ACTUATOR | BRAKE)
			.build()
	}
}

impl Phenotype for Spore {
	fn develop(gen: &mut Genome, id: Id, transform: Transform, motion: Option<Motion>, charge: f32) -> agent::Agent {
		let albedo = color::Hsl::new(gen.next_float(0., 1.), 0.5, 0.5);
		let mut builder = AgentBuilder::new(id,
		                                    Material { density: 0.5, ..Default::default() },
		                                    Livery { albedo: albedo.to_rgba(), ..Default::default() },
		                                    gen.dna(),
		                                    segment::State::with_charge(0., charge, charge));
		builder.start(transform, motion, &gen.ball()).build()
	}
}

pub struct AgentBuilder {
	id: Id,
	material: Material,
	livery: Livery,
	dna: Dna,
	state: segment::State,
	segments: Vec<Segment>,
}

impl AgentBuilder {
	pub fn new(id: Id, material: Material, livery: Livery, dna: &Dna, state: segment::State) -> Self {
		AgentBuilder {
			id: id,
			material: material,
			livery: livery,
			state: state,
			dna: dna.clone(),
			segments: Vec::new(),
		}
	}

	pub fn start(&mut self, transform: Transform, initial_vel: Option<Motion>, shape: &Shape) -> &mut Self {
		let segment = self.new_segment(shape,
		                               Winding::CW,
		                               transform,
		                               initial_vel,
		                               None,
		                               segment::CORE | segment::STORAGE | segment::MIDDLE);
		self.segments.clear();
		self.segments.push(segment);
		self
	}

	#[inline]
	pub fn add(&mut self,
	           parent_index: SegmentIndex,
	           attachment_index_offset: isize,
	           shape: &Shape,
	           flags: segment::Flags)
	           -> &mut Self {
		self.addw(parent_index,
		          attachment_index_offset,
		          shape,
		          Winding::CW,
		          flags | segment::MIDDLE)
	}
	#[inline]
	pub fn addl(&mut self,
	            parent_index: SegmentIndex,
	            attachment_index_offset: isize,
	            shape: &Shape,
	            flags: segment::Flags)
	            -> &mut Self {
		self.addw(parent_index,
		          attachment_index_offset,
		          shape,
		          Winding::CCW,
		          flags | segment::LEFT)
	}
	#[inline]
	pub fn addr(&mut self,
	            parent_index: SegmentIndex,
	            attachment_index_offset: isize,
	            shape: &Shape,
	            flags: segment::Flags)
	            -> &mut Self {
		self.addw(parent_index,
		          attachment_index_offset,
		          shape,
		          Winding::CW,
		          flags | segment::RIGHT)
	}

	pub fn addw(&mut self,
	            parent_index: SegmentIndex,
	            attachment_index_offset: isize,
	            shape: &Shape,
	            winding: Winding,
	            flags: segment::Flags)
	            -> &mut Self {
		let parent = self.segments[parent_index as usize].clone();//urgh!;
		let parent_pos = parent.transform.position;
		let parent_angle = parent.transform.angle;
		let parent_length = parent.mesh.shape.length() as isize;
		let attachment_index = ((attachment_index_offset + parent_length) % parent_length) as usize;
		let p0 = cgmath::Matrix2::from_angle(cgmath::rad(parent_angle)) * parent.mesh.vertices[attachment_index];
		let angle = f32::atan2(p0.y, p0.x);
		let r0 = p0.length() * parent.mesh.shape.radius();
		let r1 = shape.radius();
		let segment = self.new_segment(shape,
		                               winding,
		                               Transform::new(parent_pos + (p0 * (r0 + r1)), consts::PI / 2. + angle),
		                               None,
		                               parent.new_attachment(attachment_index as AttachmentIndex),
		                               flags);
		self.segments.push(segment);
		self
	}

	pub fn index(&self) -> SegmentIndex {
		match self.segments.len() {
			0 => 0,
			n => (n - 1) as SegmentIndex,
		}
	}

	fn new_segment(&mut self,
	               shape: &Shape,
	               winding: Winding,
	               transform: Transform,
	               motion: Option<Motion>,
	               attachment: Option<segment::Attachment>,
	               flags: segment::Flags)
	               -> segment::Segment {
		segment::Segment {
			index: self.segments.len() as SegmentIndex,
			transform: transform,
			motion: motion,
			mesh: Mesh::from_shape(shape.clone(), winding),
			material: self.material.clone(),
			livery: self.livery.clone(),
			state: self.state.clone(),
			attached_to: attachment,
			flags: flags,
		}
	}

	pub fn build(&self) -> Agent {
		Agent::new(self.id, &self.dna, self.segments.clone().into_boxed_slice())
	}
}
<commit_msg>Cleanup<commit_after>use backend::obj::*;
use std::f32::consts;
use core::color;
use core::color::ToRgb;
use core::geometry::*;
use backend::world::segment;
use backend::world::segment::*;
use backend::world::agent;
use backend::world::agent::Agent;
use backend::world::gen::*;
use cgmath;
use cgmath::EuclideanVector;

pub trait Phenotype {
	fn develop(gen: &mut Genome, id: Id, transform: Transform, motion: Option<Motion>, charge: f32) -> agent::Agent;
}

pub struct Resource {}
pub struct Minion {}
pub struct Spore {}

impl Phenotype for Resource {
	fn develop(gen: &mut Genome, id: Id, transform: Transform, motion: Option<Motion>, charge: f32) -> agent::Agent {

		let albedo = color::YPbPr::new(0.5, gen.next_float(-0.5, 0.5), gen.next_float(-0.5, 0.5));
		let body = gen.eq_triangle();
		let mut builder = AgentBuilder::new(id,
		                                    Material { density: 1.0, ..Default::default() },
		                                    Livery { albedo: albedo.to_rgba(), ..Default::default() },
		                                    gen.dna(),
		                                    segment::State::with_charge(charge, 0., charge));
		builder.start(transform, motion, &body).build()
	}
}

impl Phenotype for Minion {
	fn develop(gen: &mut Genome, id: Id, transform: Transform, motion: Option<Motion>, charge: f32) -> agent::Agent {
		let albedo = color::Hsl::new(gen.next_float(0., 1.), 0.5, 0.5);
		let mut builder = AgentBuilder::new(id,
		                                    Material { density: 0.2, ..Default::default() },
		                                    Livery { albedo: albedo.to_rgba(), ..Default::default() },
		                                    gen.dna(),
		                                    segment::State::with_charge(0., charge, charge));
		let torso_shape = gen.any_poly();
		let torso = builder.start(transform, motion, &torso_shape).index();
		let arm_shape = gen.star();
		let leg_shape = gen.star();
		let head_shape = gen.iso_triangle();
		let antenna_shape = gen.triangle();
		let tail_shape = gen.vbar();
		let i = ::std::cmp::max((torso_shape.length() as isize / 5), 1);
		builder.addr(torso, i, &arm_shape, ARM | JOINT | ACTUATOR | RUDDER)
			.addl(torso, -i, &arm_shape, ARM | JOINT | ACTUATOR | RUDDER);

		let head = builder.add(torso, 0, &head_shape, HEAD | MOUTH | SENSOR).index();
		builder.addr(head, 1, &antenna_shape, HEAD | MOUTH | ACTUATOR | RUDDER)
			.addl(head, 2, &antenna_shape, HEAD | MOUTH | ACTUATOR | RUDDER);

		let mut belly = torso;
		let mut belly_mid = torso_shape.mid();
		while gen.next_integer(0, 4) == 0 {
			let belly_shape = gen.poly(true);

			belly = builder.add(belly, belly_mid, &belly_shape, STORAGE | JOINT).index();
			belly_mid = belly_shape.mid();
			if gen.next_integer(0, 4) == 0 {
				builder.addr(belly, 2, &arm_shape, ARM | ACTUATOR | RUDDER)
					.addl(belly, -2, &arm_shape, ARM | ACTUATOR | RUDDER);
			}
		}

		builder.addr(belly, belly_mid - 1, &leg_shape, LEG | ACTUATOR | THRUSTER)
			.addl(belly,
			      -(belly_mid - 1),
			      &leg_shape,
			      LEG | ACTUATOR | THRUSTER)
			.add(belly, belly_mid, &tail_shape, TAIL | ACTUATOR | BRAKE)
			.build()
	}
}

impl Phenotype for Spore {
	fn develop(gen: &mut Genome, id: Id, transform: Transform, motion: Option<Motion>, charge: f32) -> agent::Agent {
		let albedo = color::Hsl::new(gen.next_float(0., 1.), 0.5, 0.5);
		let mut builder = AgentBuilder::new(id,
		                                    Material { density: 0.5, ..Default::default() },
		                                    Livery { albedo: albedo.to_rgba(), ..Default::default() },
		                                    gen.dna(),
		                                    segment::State::with_charge(0., charge, charge));
		builder.start(transform, motion, &gen.ball()).build()
	}
}

pub struct AgentBuilder {
	id: Id,
	material: Material,
	livery: Livery,
	dna: Dna,
	state: segment::State,
	segments: Vec<Segment>,
}

impl AgentBuilder {
	pub fn new(id: Id, material: Material, livery: Livery, dna: &Dna, state: segment::State) -> Self {
		AgentBuilder {
			id: id,
			material: material,
			livery: livery,
			state: state,
			dna: dna.clone(),
			segments: Vec::new(),
		}
	}

	pub fn start(&mut self, transform: Transform, initial_vel: Option<Motion>, shape: &Shape) -> &mut Self {
		let segment = self.new_segment(shape,
		                               Winding::CW,
		                               transform,
		                               initial_vel,
		                               None,
		                               segment::CORE | segment::STORAGE | segment::MIDDLE);
		self.segments.clear();
		self.segments.push(segment);
		self
	}

	#[inline]
	pub fn add(&mut self,
	           parent_index: SegmentIndex,
	           attachment_index_offset: isize,
	           shape: &Shape,
	           flags: segment::Flags)
	           -> &mut Self {
		self.addw(parent_index,
		          attachment_index_offset,
		          shape,
		          Winding::CW,
		          flags | segment::MIDDLE)
	}
	#[inline]
	pub fn addl(&mut self,
	            parent_index: SegmentIndex,
	            attachment_index_offset: isize,
	            shape: &Shape,
	            flags: segment::Flags)
	            -> &mut Self {
		self.addw(parent_index,
		          attachment_index_offset,
		          shape,
		          Winding::CCW,
		          flags | segment::LEFT)
	}
	#[inline]
	pub fn addr(&mut self,
	            parent_index: SegmentIndex,
	            attachment_index_offset: isize,
	            shape: &Shape,
	            flags: segment::Flags)
	            -> &mut Self {
		self.addw(parent_index,
		          attachment_index_offset,
		          shape,
		          Winding::CW,
		          flags | segment::RIGHT)
	}

	pub fn addw(&mut self,
	            parent_index: SegmentIndex,
	            attachment_index_offset: isize,
	            shape: &Shape,
	            winding: Winding,
	            flags: segment::Flags)
	            -> &mut Self {
		let parent = self.segments[parent_index as usize].clone();//urgh!;
		let parent_pos = parent.transform.position;
		let parent_angle = parent.transform.angle;
		let parent_length = parent.mesh.shape.length() as isize;
		let attachment_index = ((attachment_index_offset + parent_length) % parent_length) as usize;
		let p0 = cgmath::Matrix2::from_angle(cgmath::rad(parent_angle)) * parent.mesh.vertices[attachment_index];
		let angle = f32::atan2(p0.y, p0.x);
		let r0 = p0.length() * parent.mesh.shape.radius();
		let r1 = shape.radius();
		let segment = self.new_segment(shape,
		                               winding,
		                               Transform::new(parent_pos + (p0 * (r0 + r1)), consts::PI / 2. + angle),
		                               None,
		                               parent.new_attachment(attachment_index as AttachmentIndex),
		                               flags);
		self.segments.push(segment);
		self
	}

	pub fn index(&self) -> SegmentIndex {
		match self.segments.len() {
			0 => 0,
			n => (n - 1) as SegmentIndex,
		}
	}

	fn new_segment(&mut self,
	               shape: &Shape,
	               winding: Winding,
	               transform: Transform,
	               motion: Option<Motion>,
	               attachment: Option<segment::Attachment>,
	               flags: segment::Flags)
	               -> segment::Segment {
		segment::Segment {
			index: self.segments.len() as SegmentIndex,
			transform: transform,
			motion: motion,
			mesh: Mesh::from_shape(shape.clone(), winding),
			material: self.material.clone(),
			livery: self.livery.clone(),
			state: self.state.clone(),
			attached_to: attachment,
			flags: flags,
		}
	}

	pub fn build(&self) -> Agent {
		Agent::new(self.id, &self.dna, self.segments.clone().into_boxed_slice())
	}
}
<|endoftext|>


<commit_before>// run-pass
// We disable tail merging here because it can't preserve debuginfo and thus
// potentially breaks the backtraces. Also, subtle changes can decide whether
// tail merging succeeds, so the test might work today but fail tomorrow due to a
// seemingly completely unrelated change.
// Unfortunately, LLVM has no "disable" option for this, so we have to set
// "enable" to 0 instead.

// compile-flags:-g -Cllvm-args=-enable-tail-merge=0 -Cllvm-args=-opt-bisect-limit=0
// compile-flags:-Cforce-frame-pointers=yes
// ignore-pretty issue #37195
// ignore-emscripten spawning processes is not supported
// ignore-sgx no processes
// normalize-stderr-test ".*\n" -> ""

// Note that above `-opt-bisect-limit=0` is used to basically disable
// optimizations. It creates tons of output on stderr, hence we normalize
// that away entirely.

use std::env;

#[path = "backtrace-debuginfo-aux.rs"] mod aux;

macro_rules! pos {
    () => ((file!(), line!()))
}

macro_rules! dump_and_die {
    ($($pos:expr),*) => ({
        // FIXME(#18285): we cannot include the current position because
        // the macro span takes over the last frame's file/line.
        //
        // You might also be wondering why a major platform,
        // i686-pc-windows-msvc, is located in here. Some of the saga can be
        // found on #62897, but the tl;dr; is that it appears that if the
        // standard library doesn't have debug information or frame pointers,
        // which it doesn't by default on the test builders, then the stack
        // walking routines in dbghelp will randomly terminate the stack trace
        // in libstd without going further. Presumably the addition of frame
        // pointers and/or debuginfo fixes this since tests always work with
        // nightly compilers (which have debuginfo). In general though this test
        // is replicated in rust-lang/backtrace-rs and has extensive coverage
        // there, even on i686-pc-windows-msvc. We do the best we can in
        // rust-lang/rust to test it as well, but sometimes we just gotta keep
        // landing PRs.
        if cfg!(any(target_os = "android",
                    all(target_os = "linux", target_arch = "arm"),
                    all(target_env = "msvc", target_arch = "x86"),
                    target_os = "freebsd",
                    target_os = "dragonfly",
                    target_os = "openbsd")) {
            // skip these platforms as this support isn't implemented yet.
        } else {
            dump_filelines(&[$($pos),*]);
            panic!();
        }
    })
}

// we can't use a function as it will alter the backtrace
macro_rules! check {
    ($counter:expr; $($pos:expr),*) => ({
        if *$counter == 0 {
            dump_and_die!($($pos),*)
        } else {
            *$counter -= 1;
        }
    })
}

type Pos = (&'static str, u32);

// this goes to stdout and each line has to be occurred
// in the following backtrace to stderr with a correct order.
fn dump_filelines(filelines: &[Pos]) {
    for &(file, line) in filelines.iter().rev() {
        // extract a basename
        let basename = file.split(&['/', '\\'][..]).last().unwrap();
        println!("{}:{}", basename, line);
    }
}

#[inline(never)]
fn inner(counter: &mut i32, main_pos: Pos, outer_pos: Pos) {
    check!(counter; main_pos, outer_pos);
    check!(counter; main_pos, outer_pos);
    let inner_pos = pos!(); aux::callback(|aux_pos| {
        check!(counter; main_pos, outer_pos, inner_pos, aux_pos);
    });
    let inner_pos = pos!(); aux::callback_inlined(|aux_pos| {
        check!(counter; main_pos, outer_pos, inner_pos, aux_pos);
    });
}

// We emit the wrong location for the caller here when inlined on MSVC
#[cfg_attr(not(target_env = "msvc"), inline(always))]
#[cfg_attr(target_env = "msvc", inline(never))]
fn inner_inlined(counter: &mut i32, main_pos: Pos, outer_pos: Pos) {
    check!(counter; main_pos, outer_pos);
    check!(counter; main_pos, outer_pos);

    // Again, disable inlining for MSVC.
    #[cfg_attr(not(target_env = "msvc"), inline(always))]
    #[cfg_attr(target_env = "msvc", inline(never))]
    fn inner_further_inlined(counter: &mut i32, main_pos: Pos, outer_pos: Pos, inner_pos: Pos) {
        check!(counter; main_pos, outer_pos, inner_pos);
    }
    inner_further_inlined(counter, main_pos, outer_pos, pos!());

    let inner_pos = pos!(); aux::callback(|aux_pos| {
        check!(counter; main_pos, outer_pos, inner_pos, aux_pos);
    });
    let inner_pos = pos!(); aux::callback_inlined(|aux_pos| {
        check!(counter; main_pos, outer_pos, inner_pos, aux_pos);
    });

    // this tests a distinction between two independent calls to the inlined function.
    // (un)fortunately, LLVM somehow merges two consecutive such calls into one node.
    inner_further_inlined(counter, main_pos, outer_pos, pos!());
}

#[inline(never)]
fn outer(mut counter: i32, main_pos: Pos) {
    inner(&mut counter, main_pos, pos!());
    inner_inlined(&mut counter, main_pos, pos!());
}

fn check_trace(output: &str, error: &str) -> Result<(), String> {
    // reverse the position list so we can start with the last item (which was the first line)
    let mut remaining: Vec<&str> = output.lines().map(|s| s.trim()).rev().collect();

    if !error.contains("stack backtrace") {
        return Err(format!("no backtrace found in stderr:\n{}", error))
    }
    for line in error.lines() {
        if !remaining.is_empty() && line.contains(remaining.last().unwrap()) {
            remaining.pop();
        }
    }
    if !remaining.is_empty() {
        return Err(format!("trace does not match position list\n\
            still need to find {:?}\n\n\
            --- stdout\n{}\n\
            --- stderr\n{}",
            remaining, output, error))
    }
    Ok(())
}

fn run_test(me: &str) {
    use std::str;
    use std::process::Command;

    let mut i = 0;
    let mut errors = Vec::new();
    loop {
        let out = Command::new(me)
                          .env("RUST_BACKTRACE", "full")
                          .arg(i.to_string()).output().unwrap();
        let output = str::from_utf8(&out.stdout).unwrap();
        let error = str::from_utf8(&out.stderr).unwrap();
        if out.status.success() {
            assert!(output.contains("done."), "bad output for successful run: {}", output);
            break;
        } else {
            if let Err(e) = check_trace(output, error) {
                errors.push(e);
            }
        }
        i += 1;
    }
    if errors.len() > 0 {
        for error in errors {
            println!("---------------------------------------");
            println!("{}", error);
        }

        panic!("found some errors");
    }
}

#[inline(never)]
fn main() {
    let args: Vec<String> = env::args().collect();
    if args.len() >= 2 {
        let case = args[1].parse().unwrap();
        eprintln!("test case {}", case);
        outer(case, pos!());
        println!("done.");
    } else {
        run_test(&args[0]);
    }
}
<commit_msg>Drop -opt-bisect-limit=0 flag from test<commit_after>// run-pass
// We disable tail merging here because it can't preserve debuginfo and thus
// potentially breaks the backtraces. Also, subtle changes can decide whether
// tail merging succeeds, so the test might work today but fail tomorrow due to a
// seemingly completely unrelated change.
// Unfortunately, LLVM has no "disable" option for this, so we have to set
// "enable" to 0 instead.

// compile-flags:-g -Copt-level=0 -Cllvm-args=-enable-tail-merge=0
// compile-flags:-Cforce-frame-pointers=yes
// ignore-pretty issue #37195
// ignore-emscripten spawning processes is not supported
// ignore-sgx no processes

use std::env;

#[path = "backtrace-debuginfo-aux.rs"] mod aux;

macro_rules! pos {
    () => ((file!(), line!()))
}

macro_rules! dump_and_die {
    ($($pos:expr),*) => ({
        // FIXME(#18285): we cannot include the current position because
        // the macro span takes over the last frame's file/line.
        //
        // You might also be wondering why a major platform,
        // i686-pc-windows-msvc, is located in here. Some of the saga can be
        // found on #62897, but the tl;dr; is that it appears that if the
        // standard library doesn't have debug information or frame pointers,
        // which it doesn't by default on the test builders, then the stack
        // walking routines in dbghelp will randomly terminate the stack trace
        // in libstd without going further. Presumably the addition of frame
        // pointers and/or debuginfo fixes this since tests always work with
        // nightly compilers (which have debuginfo). In general though this test
        // is replicated in rust-lang/backtrace-rs and has extensive coverage
        // there, even on i686-pc-windows-msvc. We do the best we can in
        // rust-lang/rust to test it as well, but sometimes we just gotta keep
        // landing PRs.
        if cfg!(any(target_os = "android",
                    all(target_os = "linux", target_arch = "arm"),
                    all(target_env = "msvc", target_arch = "x86"),
                    target_os = "freebsd",
                    target_os = "dragonfly",
                    target_os = "openbsd")) {
            // skip these platforms as this support isn't implemented yet.
        } else {
            dump_filelines(&[$($pos),*]);
            panic!();
        }
    })
}

// we can't use a function as it will alter the backtrace
macro_rules! check {
    ($counter:expr; $($pos:expr),*) => ({
        if *$counter == 0 {
            dump_and_die!($($pos),*)
        } else {
            *$counter -= 1;
        }
    })
}

type Pos = (&'static str, u32);

// this goes to stdout and each line has to be occurred
// in the following backtrace to stderr with a correct order.
fn dump_filelines(filelines: &[Pos]) {
    for &(file, line) in filelines.iter().rev() {
        // extract a basename
        let basename = file.split(&['/', '\\'][..]).last().unwrap();
        println!("{}:{}", basename, line);
    }
}

#[inline(never)]
fn inner(counter: &mut i32, main_pos: Pos, outer_pos: Pos) {
    check!(counter; main_pos, outer_pos);
    check!(counter; main_pos, outer_pos);
    let inner_pos = pos!(); aux::callback(|aux_pos| {
        check!(counter; main_pos, outer_pos, inner_pos, aux_pos);
    });
    let inner_pos = pos!(); aux::callback_inlined(|aux_pos| {
        check!(counter; main_pos, outer_pos, inner_pos, aux_pos);
    });
}

// We emit the wrong location for the caller here when inlined on MSVC
#[cfg_attr(not(target_env = "msvc"), inline(always))]
#[cfg_attr(target_env = "msvc", inline(never))]
fn inner_inlined(counter: &mut i32, main_pos: Pos, outer_pos: Pos) {
    check!(counter; main_pos, outer_pos);
    check!(counter; main_pos, outer_pos);

    // Again, disable inlining for MSVC.
    #[cfg_attr(not(target_env = "msvc"), inline(always))]
    #[cfg_attr(target_env = "msvc", inline(never))]
    fn inner_further_inlined(counter: &mut i32, main_pos: Pos, outer_pos: Pos, inner_pos: Pos) {
        check!(counter; main_pos, outer_pos, inner_pos);
    }
    inner_further_inlined(counter, main_pos, outer_pos, pos!());

    let inner_pos = pos!(); aux::callback(|aux_pos| {
        check!(counter; main_pos, outer_pos, inner_pos, aux_pos);
    });
    let inner_pos = pos!(); aux::callback_inlined(|aux_pos| {
        check!(counter; main_pos, outer_pos, inner_pos, aux_pos);
    });

    // this tests a distinction between two independent calls to the inlined function.
    // (un)fortunately, LLVM somehow merges two consecutive such calls into one node.
    inner_further_inlined(counter, main_pos, outer_pos, pos!());
}

#[inline(never)]
fn outer(mut counter: i32, main_pos: Pos) {
    inner(&mut counter, main_pos, pos!());
    inner_inlined(&mut counter, main_pos, pos!());
}

fn check_trace(output: &str, error: &str) -> Result<(), String> {
    // reverse the position list so we can start with the last item (which was the first line)
    let mut remaining: Vec<&str> = output.lines().map(|s| s.trim()).rev().collect();

    if !error.contains("stack backtrace") {
        return Err(format!("no backtrace found in stderr:\n{}", error))
    }
    for line in error.lines() {
        if !remaining.is_empty() && line.contains(remaining.last().unwrap()) {
            remaining.pop();
        }
    }
    if !remaining.is_empty() {
        return Err(format!("trace does not match position list\n\
            still need to find {:?}\n\n\
            --- stdout\n{}\n\
            --- stderr\n{}",
            remaining, output, error))
    }
    Ok(())
}

fn run_test(me: &str) {
    use std::str;
    use std::process::Command;

    let mut i = 0;
    let mut errors = Vec::new();
    loop {
        let out = Command::new(me)
                          .env("RUST_BACKTRACE", "full")
                          .arg(i.to_string()).output().unwrap();
        let output = str::from_utf8(&out.stdout).unwrap();
        let error = str::from_utf8(&out.stderr).unwrap();
        if out.status.success() {
            assert!(output.contains("done."), "bad output for successful run: {}", output);
            break;
        } else {
            if let Err(e) = check_trace(output, error) {
                errors.push(e);
            }
        }
        i += 1;
    }
    if errors.len() > 0 {
        for error in errors {
            println!("---------------------------------------");
            println!("{}", error);
        }

        panic!("found some errors");
    }
}

#[inline(never)]
fn main() {
    let args: Vec<String> = env::args().collect();
    if args.len() >= 2 {
        let case = args[1].parse().unwrap();
        eprintln!("test case {}", case);
        outer(case, pos!());
        println!("done.");
    } else {
        run_test(&args[0]);
    }
}
<|endoftext|>