<commit_before><commit_msg>18 - generics<commit_after>// A generic struct
struct Pair<T> {
    first: T,
    second: T,
}

// A generic function
fn swap<T>(pair: Pair<T>) -> Pair<T> {
    let Pair { first, second } = pair;
    Pair { first: second, second: first }
}

// Reimplementing a 2-element tuple as a tuple struct
struct Tuple2<T, U>(T, U);

fn main() {
    // Explicitly specialize `Pair`
    let pair_of_chars: Pair<char> = Pair { first: 'a', second: 'b' };
    // Implicitly specialize `Pair`
    let pair_of_ints = Pair { first: 1i, second: 2 };
    // Explicitly specialize `Tuple2`
    let _tuple: Tuple2<char, int> = Tuple2('R', 2);
    // Explicitly specialize `swap`
    let _swapped_pair_of_chars = swap::<char>(pair_of_chars);
    // Implicitly specialize `swap`
    let _swapped_pair_of_ints = swap(pair_of_ints);
}

<|endoftext|>


<commit_before><commit_msg>Add exampple for using shared memory<commit_after><|endoftext|>


<commit_before><commit_msg>Rollup merge of #89579 - workingjubilee:regression-test-80108, r=Mark-Simulacrum<commit_after>// only-wasm32
// compile-flags: --crate-type=lib -Copt-level=2
// build-pass
#![feature(repr_simd)]

// Regression test for #80108

#[repr(simd)]
pub struct Vector([i32; 4]);

impl Vector {
    pub const fn to_array(self) -> [i32; 4] {
        self.0
    }
}
<|endoftext|>


<commit_before>#![crate_id(name="comm", vers="1.0.0", author="Michael Gehring")]

/*
 * This file is part of the uutils coreutils package.
 *
 * (c) Michael Gehring <mg@ebfe.org>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

extern crate getopts;

use std::cmp::TotalOrd;
use std::io::{BufferedReader, IoResult, print};
use std::io::fs::File;
use std::io::stdio::stdin;
use std::os;
use std::path::Path;

static NAME : &'static str = "comm";
static VERSION : &'static str = "1.0.0";

fn delim(col: int, opts: &getopts::Matches) -> ~str {
    let mut s = StrBuf::new();

    if col > 1 && !opts.opt_present("1") {
        s.push_str("\t");
    }
    if col > 2 && !opts.opt_present("2") {
        s.push_str("\t");
    }

    s.to_owned()
}

fn comm(a: &mut Box<Buffer>, b: &mut Box<Buffer>, opts: &getopts::Matches) {

    let mut ra = a.read_line();
    let mut rb = b.read_line();

    while ra.is_ok() || rb.is_ok() {
        let ord = match (ra.clone(), rb.clone()) {
            (Err(_), Ok(_))  => Greater,
            (Ok(_) , Err(_)) => Less,
            (Ok(s0), Ok(s1)) => s0.cmp(&s1),
            _ => unreachable!(),
        };

        match ord {
            Less => {
                if !opts.opt_present("1") {
                    print!("{}{}", delim(1, opts), ra.unwrap());
                }
                ra = a.read_line();
            }
            Greater => {
                if !opts.opt_present("2") {
                    print!("{}{}", delim(2, opts), rb.unwrap());
                }
                rb = b.read_line();
            }
            Equal => {
                if !opts.opt_present("3") {
                    print!("{}{}", delim(3, opts), ra.unwrap());
                }
                ra = a.read_line();
                rb = b.read_line();
            }
        }
    }
}

fn open_file(name: &str) -> IoResult<Box<Buffer>> {
    match name {
        "-" => Ok(box stdin() as Box<Buffer>),
        _   => {
            let f = try!(File::open(&Path::new(name)));
            Ok(box BufferedReader::new(f) as Box<Buffer>)
        }
    }
}

pub fn main() {
    let args: Vec<StrBuf> = os::args().iter().map(|x| x.to_strbuf()).collect();
    let opts = [
        getopts::optflag("1", "", "suppress column 1 (lines uniq to FILE1)"),
        getopts::optflag("2", "", "suppress column 2 (lines uniq to FILE2)"),
        getopts::optflag("3", "", "suppress column 3 (lines that appear in both files)"),
        getopts::optflag("h", "help", "display this help and exit"),
    ];

    let matches = match getopts::getopts(args.tail(), opts) {
        Ok(m) => m,
        Err(err) => fail!("{}", err.to_err_msg()),
    };

    if matches.opt_present("help") || matches.free.len() != 2 {
        println!("{} {}", NAME, VERSION);
        println!("");
        println!("Usage:");
        println!("  {} [OPTIONS] FILE1 FILE2", NAME);
        println!("");
        print(getopts::usage("Compare sorted files line by line.", opts.as_slice()).as_slice());
        if matches.free.len() != 2 {
            os::set_exit_status(1);
        }
        return;
    }

    let mut f1 = open_file(matches.free.get(0).as_slice()).unwrap();
    let mut f2 = open_file(matches.free.get(1).as_slice()).unwrap();

    comm(&mut f1, &mut f2, &matches)
}
<commit_msg>comm: add --version<commit_after>#![crate_id(name="comm", vers="1.0.0", author="Michael Gehring")]

/*
 * This file is part of the uutils coreutils package.
 *
 * (c) Michael Gehring <mg@ebfe.org>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

extern crate getopts;

use std::cmp::TotalOrd;
use std::io::{BufferedReader, IoResult, print};
use std::io::fs::File;
use std::io::stdio::stdin;
use std::os;
use std::path::Path;

static NAME : &'static str = "comm";
static VERSION : &'static str = "1.0.0";

fn delim(col: int, opts: &getopts::Matches) -> ~str {
    let mut s = StrBuf::new();

    if col > 1 && !opts.opt_present("1") {
        s.push_str("\t");
    }
    if col > 2 && !opts.opt_present("2") {
        s.push_str("\t");
    }

    s.to_owned()
}

fn comm(a: &mut Box<Buffer>, b: &mut Box<Buffer>, opts: &getopts::Matches) {

    let mut ra = a.read_line();
    let mut rb = b.read_line();

    while ra.is_ok() || rb.is_ok() {
        let ord = match (ra.clone(), rb.clone()) {
            (Err(_), Ok(_))  => Greater,
            (Ok(_) , Err(_)) => Less,
            (Ok(s0), Ok(s1)) => s0.cmp(&s1),
            _ => unreachable!(),
        };

        match ord {
            Less => {
                if !opts.opt_present("1") {
                    print!("{}{}", delim(1, opts), ra.unwrap());
                }
                ra = a.read_line();
            }
            Greater => {
                if !opts.opt_present("2") {
                    print!("{}{}", delim(2, opts), rb.unwrap());
                }
                rb = b.read_line();
            }
            Equal => {
                if !opts.opt_present("3") {
                    print!("{}{}", delim(3, opts), ra.unwrap());
                }
                ra = a.read_line();
                rb = b.read_line();
            }
        }
    }
}

fn open_file(name: &str) -> IoResult<Box<Buffer>> {
    match name {
        "-" => Ok(box stdin() as Box<Buffer>),
        _   => {
            let f = try!(File::open(&Path::new(name)));
            Ok(box BufferedReader::new(f) as Box<Buffer>)
        }
    }
}

pub fn main() {
    let args: Vec<StrBuf> = os::args().iter().map(|x| x.to_strbuf()).collect();
    let opts = [
        getopts::optflag("1", "", "suppress column 1 (lines uniq to FILE1)"),
        getopts::optflag("2", "", "suppress column 2 (lines uniq to FILE2)"),
        getopts::optflag("3", "", "suppress column 3 (lines that appear in both files)"),
        getopts::optflag("h", "help", "display this help and exit"),
        getopts::optflag("V", "version", "output version information and exit"),
    ];

    let matches = match getopts::getopts(args.tail(), opts) {
        Ok(m) => m,
        Err(err) => fail!("{}", err.to_err_msg()),
    };

    if matches.opt_present("version") {
        println!("{} {}", NAME, VERSION);
        return;
    }

    if matches.opt_present("help") || matches.free.len() != 2 {
        println!("{} {}", NAME, VERSION);
        println!("");
        println!("Usage:");
        println!("  {} [OPTIONS] FILE1 FILE2", NAME);
        println!("");
        print(getopts::usage("Compare sorted files line by line.", opts.as_slice()).as_slice());
        if matches.free.len() != 2 {
            os::set_exit_status(1);
        }
        return;
    }

    let mut f1 = open_file(matches.free.get(0).as_slice()).unwrap();
    let mut f2 = open_file(matches.free.get(1).as_slice()).unwrap();

    comm(&mut f1, &mut f2, &matches)
}
<|endoftext|>


<commit_before><commit_msg>an empy message<commit_after><|endoftext|>


<commit_before><commit_msg>Make Q and E keys rotate around direction vector<commit_after><|endoftext|>


<commit_before>// Copyright 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.
//
// Original implementation taken from rust-memchr
// Copyright 2015 Andrew Gallant, bluss and Nicolas Koch

/// A safe interface to `memchr`.
///
/// Returns the index corresponding to the first occurrence of `needle` in
/// `haystack`, or `None` if one is not found.
///
/// memchr reduces to super-optimized machine code at around an order of
/// magnitude faster than `haystack.iter().position(|&b| b == needle)`.
/// (See benchmarks.)
///
/// # Example
///
/// This shows how to find the first position of a byte in a byte string.
///
/// ```rust,ignore
/// use memchr::memchr;
///
/// let haystack = b"the quick brown fox";
/// assert_eq!(memchr(b'k', haystack), Some(8));
/// ```
pub fn memchr(needle: u8, haystack: &[u8]) -> Option<usize> {
    // libc memchr
    #[cfg(not(target_os = "windows"))]
    fn memchr_specific(needle: u8, haystack: &[u8]) -> Option<usize> {
        use libc;

        let p = unsafe {
            libc::memchr(
                haystack.as_ptr() as *const libc::c_void,
                needle as libc::c_int,
                haystack.len() as libc::size_t)
        };
        if p.is_null() {
            None
        } else {
            Some(p as usize - (haystack.as_ptr() as usize))
        }
    }

    // use fallback on windows, since it's faster
    #[cfg(target_os = "windows")]
    fn memchr_specific(needle: u8, haystack: &[u8]) -> Option<usize> {
        fallback::memchr(needle, haystack)
    }

    memchr_specific(needle, haystack)
}

/// A safe interface to `memrchr`.
///
/// Returns the index corresponding to the last occurrence of `needle` in
/// `haystack`, or `None` if one is not found.
///
/// # Example
///
/// This shows how to find the last position of a byte in a byte string.
///
/// ```rust,ignore
/// use memchr::memrchr;
///
/// let haystack = b"the quick brown fox";
/// assert_eq!(memrchr(b'o', haystack), Some(17));
/// ```
pub fn memrchr(needle: u8, haystack: &[u8]) -> Option<usize> {

    #[cfg(target_os = "linux")]
    fn memrchr_specific(needle: u8, haystack: &[u8]) -> Option<usize> {
        use libc;

        // GNU's memrchr() will - unlike memchr() - error if haystack is empty.
        if haystack.is_empty() {return None}
        let p = unsafe {
            libc::memrchr(
                haystack.as_ptr() as *const libc::c_void,
                needle as libc::c_int,
                haystack.len() as libc::size_t)
        };
        if p.is_null() {
            None
        } else {
            Some(p as usize - (haystack.as_ptr() as usize))
        }
    }

    #[cfg(not(target_os = "linux"))]
    fn memrchr_specific(needle: u8, haystack: &[u8]) -> Option<usize> {
        fallback::memrchr(needle, haystack)
    }

    memrchr_specific(needle, haystack)
}

#[allow(dead_code)]
mod fallback {
    use cmp;
    use mem;

    const LO_U64: u64 = 0x0101010101010101;
    const HI_U64: u64 = 0x8080808080808080;

    // use truncation
    const LO_USIZE: usize = LO_U64 as usize;
    const HI_USIZE: usize = HI_U64 as usize;

    /// Return `true` if `x` contains any zero byte.
    ///
    /// From *Matters Computational*, J. Arndt
    ///
    /// "The idea is to subtract one from each of the bytes and then look for
    /// bytes where the borrow propagated all the way to the most significant
    /// bit."
    #[inline]
    fn contains_zero_byte(x: usize) -> bool {
        x.wrapping_sub(LO_USIZE) & !x & HI_USIZE != 0
    }

    #[cfg(target_pointer_width = "32")]
    #[inline]
    fn repeat_byte(b: u8) -> usize {
        let mut rep = (b as usize) << 8 | b as usize;
        rep = rep << 16 | rep;
        rep
    }

    #[cfg(target_pointer_width = "64")]
    #[inline]
    fn repeat_byte(b: u8) -> usize {
        let mut rep = (b as usize) << 8 | b as usize;
        rep = rep << 16 | rep;
        rep = rep << 32 | rep;
        rep
    }

    /// Return the first index matching the byte `a` in `text`.
    pub fn memchr(x: u8, text: &[u8]) -> Option<usize> {
        // Scan for a single byte value by reading two `usize` words at a time.
        //
        // Split `text` in three parts
        // - unaligned initial part, before the first word aligned address in text
        // - body, scan by 2 words at a time
        // - the last remaining part, < 2 word size
        let len = text.len();
        let ptr = text.as_ptr();
        let usize_bytes = mem::size_of::<usize>();

        // search up to an aligned boundary
        let align = (ptr as usize) & (usize_bytes- 1);
        let mut offset;
        if align > 0 {
            offset = cmp::min(usize_bytes - align, len);
            if let Some(index) = text[..offset].iter().position(|elt| *elt == x) {
                return Some(index);
            }
        } else {
            offset = 0;
        }

        // search the body of the text
        let repeated_x = repeat_byte(x);

        if len >= 2 * usize_bytes {
            while offset <= len - 2 * usize_bytes {
                unsafe {
                    let u = *(ptr.offset(offset as isize) as *const usize);
                    let v = *(ptr.offset((offset + usize_bytes) as isize) as *const usize);

                    // break if there is a matching byte
                    let zu = contains_zero_byte(u ^ repeated_x);
                    let zv = contains_zero_byte(v ^ repeated_x);
                    if zu || zv {
                        break;
                    }
                }
                offset += usize_bytes * 2;
            }
        }

        // find the byte after the point the body loop stopped
        text[offset..].iter().position(|elt| *elt == x).map(|i| offset + i)
    }

    /// Return the last index matching the byte `a` in `text`.
    pub fn memrchr(x: u8, text: &[u8]) -> Option<usize> {
        // Scan for a single byte value by reading two `usize` words at a time.
        //
        // Split `text` in three parts
        // - unaligned tail, after the last word aligned address in text
        // - body, scan by 2 words at a time
        // - the first remaining bytes, < 2 word size
        let len = text.len();
        let ptr = text.as_ptr();
        let usize_bytes = mem::size_of::<usize>();

        // search to an aligned boundary
        let end_align = (ptr as usize + len) & (usize_bytes - 1);
        let mut offset;
        if end_align > 0 {
            offset = len - cmp::min(usize_bytes - end_align, len);
            if let Some(index) = text[offset..].iter().rposition(|elt| *elt == x) {
                return Some(offset + index);
            }
        } else {
            offset = len;
        }

        // search the body of the text
        let repeated_x = repeat_byte(x);

        while offset >= 2 * usize_bytes {
            unsafe {
                let u = *(ptr.offset(offset as isize - 2 * usize_bytes as isize) as *const usize);
                let v = *(ptr.offset(offset as isize - usize_bytes as isize) as *const usize);

                // break if there is a matching byte
                let zu = contains_zero_byte(u ^ repeated_x);
                let zv = contains_zero_byte(v ^ repeated_x);
                if zu || zv {
                    break;
                }
            }
            offset -= 2 * usize_bytes;
        }

        // find the byte before the point the body loop stopped
        text[..offset].iter().rposition(|elt| *elt == x)
    }

    // test fallback implementations on all platforms
    #[test]
    fn matches_one() {
        assert_eq!(Some(0), memchr(b'a', b"a"));
    }

    #[test]
    fn matches_begin() {
        assert_eq!(Some(0), memchr(b'a', b"aaaa"));
    }

    #[test]
    fn matches_end() {
        assert_eq!(Some(4), memchr(b'z', b"aaaaz"));
    }

    #[test]
    fn matches_nul() {
        assert_eq!(Some(4), memchr(b'\x00', b"aaaa\x00"));
    }

    #[test]
    fn matches_past_nul() {
        assert_eq!(Some(5), memchr(b'z', b"aaaa\x00z"));
    }

    #[test]
    fn no_match_empty() {
        assert_eq!(None, memchr(b'a', b""));
    }

    #[test]
    fn no_match() {
        assert_eq!(None, memchr(b'a', b"xyz"));
    }

    #[test]
    fn matches_one_reversed() {
        assert_eq!(Some(0), memrchr(b'a', b"a"));
    }

    #[test]
    fn matches_begin_reversed() {
        assert_eq!(Some(3), memrchr(b'a', b"aaaa"));
    }

    #[test]
    fn matches_end_reversed() {
        assert_eq!(Some(0), memrchr(b'z', b"zaaaa"));
    }

    #[test]
    fn matches_nul_reversed() {
        assert_eq!(Some(4), memrchr(b'\x00', b"aaaa\x00"));
    }

    #[test]
    fn matches_past_nul_reversed() {
        assert_eq!(Some(0), memrchr(b'z', b"z\x00aaaa"));
    }

    #[test]
    fn no_match_empty_reversed() {
        assert_eq!(None, memrchr(b'a', b""));
    }

    #[test]
    fn no_match_reversed() {
        assert_eq!(None, memrchr(b'a', b"xyz"));
    }
}

#[cfg(test)]
mod tests {
    // test the implementations for the current plattform
    use super::{memchr, memrchr};

    #[test]
    fn matches_one() {
        assert_eq!(Some(0), memchr(b'a', b"a"));
    }

    #[test]
    fn matches_begin() {
        assert_eq!(Some(0), memchr(b'a', b"aaaa"));
    }

    #[test]
    fn matches_end() {
        assert_eq!(Some(4), memchr(b'z', b"aaaaz"));
    }

    #[test]
    fn matches_nul() {
        assert_eq!(Some(4), memchr(b'\x00', b"aaaa\x00"));
    }

    #[test]
    fn matches_past_nul() {
        assert_eq!(Some(5), memchr(b'z', b"aaaa\x00z"));
    }

    #[test]
    fn no_match_empty() {
        assert_eq!(None, memchr(b'a', b""));
    }

    #[test]
    fn no_match() {
        assert_eq!(None, memchr(b'a', b"xyz"));
    }

    #[test]
    fn matches_one_reversed() {
        assert_eq!(Some(0), memrchr(b'a', b"a"));
    }

    #[test]
    fn matches_begin_reversed() {
        assert_eq!(Some(3), memrchr(b'a', b"aaaa"));
    }

    #[test]
    fn matches_end_reversed() {
        assert_eq!(Some(0), memrchr(b'z', b"zaaaa"));
    }

    #[test]
    fn matches_nul_reversed() {
        assert_eq!(Some(4), memrchr(b'\x00', b"aaaa\x00"));
    }

    #[test]
    fn matches_past_nul_reversed() {
        assert_eq!(Some(0), memrchr(b'z', b"z\x00aaaa"));
    }

    #[test]
    fn no_match_empty_reversed() {
        assert_eq!(None, memrchr(b'a', b""));
    }

    #[test]
    fn no_match_reversed() {
        assert_eq!(None, memrchr(b'a', b"xyz"));
    }
}
<commit_msg>Auto merge of #35969 - bluss:memrchr-alignment, r=nagisa<commit_after>// Copyright 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.
//
// Original implementation taken from rust-memchr
// Copyright 2015 Andrew Gallant, bluss and Nicolas Koch

/// A safe interface to `memchr`.
///
/// Returns the index corresponding to the first occurrence of `needle` in
/// `haystack`, or `None` if one is not found.
///
/// memchr reduces to super-optimized machine code at around an order of
/// magnitude faster than `haystack.iter().position(|&b| b == needle)`.
/// (See benchmarks.)
///
/// # Example
///
/// This shows how to find the first position of a byte in a byte string.
///
/// ```rust,ignore
/// use memchr::memchr;
///
/// let haystack = b"the quick brown fox";
/// assert_eq!(memchr(b'k', haystack), Some(8));
/// ```
pub fn memchr(needle: u8, haystack: &[u8]) -> Option<usize> {
    // libc memchr
    #[cfg(not(target_os = "windows"))]
    fn memchr_specific(needle: u8, haystack: &[u8]) -> Option<usize> {
        use libc;

        let p = unsafe {
            libc::memchr(
                haystack.as_ptr() as *const libc::c_void,
                needle as libc::c_int,
                haystack.len() as libc::size_t)
        };
        if p.is_null() {
            None
        } else {
            Some(p as usize - (haystack.as_ptr() as usize))
        }
    }

    // use fallback on windows, since it's faster
    #[cfg(target_os = "windows")]
    fn memchr_specific(needle: u8, haystack: &[u8]) -> Option<usize> {
        fallback::memchr(needle, haystack)
    }

    memchr_specific(needle, haystack)
}

/// A safe interface to `memrchr`.
///
/// Returns the index corresponding to the last occurrence of `needle` in
/// `haystack`, or `None` if one is not found.
///
/// # Example
///
/// This shows how to find the last position of a byte in a byte string.
///
/// ```rust,ignore
/// use memchr::memrchr;
///
/// let haystack = b"the quick brown fox";
/// assert_eq!(memrchr(b'o', haystack), Some(17));
/// ```
pub fn memrchr(needle: u8, haystack: &[u8]) -> Option<usize> {

    #[cfg(target_os = "linux")]
    fn memrchr_specific(needle: u8, haystack: &[u8]) -> Option<usize> {
        use libc;

        // GNU's memrchr() will - unlike memchr() - error if haystack is empty.
        if haystack.is_empty() {return None}
        let p = unsafe {
            libc::memrchr(
                haystack.as_ptr() as *const libc::c_void,
                needle as libc::c_int,
                haystack.len() as libc::size_t)
        };
        if p.is_null() {
            None
        } else {
            Some(p as usize - (haystack.as_ptr() as usize))
        }
    }

    #[cfg(not(target_os = "linux"))]
    fn memrchr_specific(needle: u8, haystack: &[u8]) -> Option<usize> {
        fallback::memrchr(needle, haystack)
    }

    memrchr_specific(needle, haystack)
}

#[allow(dead_code)]
mod fallback {
    use cmp;
    use mem;

    const LO_U64: u64 = 0x0101010101010101;
    const HI_U64: u64 = 0x8080808080808080;

    // use truncation
    const LO_USIZE: usize = LO_U64 as usize;
    const HI_USIZE: usize = HI_U64 as usize;

    /// Return `true` if `x` contains any zero byte.
    ///
    /// From *Matters Computational*, J. Arndt
    ///
    /// "The idea is to subtract one from each of the bytes and then look for
    /// bytes where the borrow propagated all the way to the most significant
    /// bit."
    #[inline]
    fn contains_zero_byte(x: usize) -> bool {
        x.wrapping_sub(LO_USIZE) & !x & HI_USIZE != 0
    }

    #[cfg(target_pointer_width = "32")]
    #[inline]
    fn repeat_byte(b: u8) -> usize {
        let mut rep = (b as usize) << 8 | b as usize;
        rep = rep << 16 | rep;
        rep
    }

    #[cfg(target_pointer_width = "64")]
    #[inline]
    fn repeat_byte(b: u8) -> usize {
        let mut rep = (b as usize) << 8 | b as usize;
        rep = rep << 16 | rep;
        rep = rep << 32 | rep;
        rep
    }

    /// Return the first index matching the byte `a` in `text`.
    pub fn memchr(x: u8, text: &[u8]) -> Option<usize> {
        // Scan for a single byte value by reading two `usize` words at a time.
        //
        // Split `text` in three parts
        // - unaligned initial part, before the first word aligned address in text
        // - body, scan by 2 words at a time
        // - the last remaining part, < 2 word size
        let len = text.len();
        let ptr = text.as_ptr();
        let usize_bytes = mem::size_of::<usize>();

        // search up to an aligned boundary
        let align = (ptr as usize) & (usize_bytes- 1);
        let mut offset;
        if align > 0 {
            offset = cmp::min(usize_bytes - align, len);
            if let Some(index) = text[..offset].iter().position(|elt| *elt == x) {
                return Some(index);
            }
        } else {
            offset = 0;
        }

        // search the body of the text
        let repeated_x = repeat_byte(x);

        if len >= 2 * usize_bytes {
            while offset <= len - 2 * usize_bytes {
                unsafe {
                    let u = *(ptr.offset(offset as isize) as *const usize);
                    let v = *(ptr.offset((offset + usize_bytes) as isize) as *const usize);

                    // break if there is a matching byte
                    let zu = contains_zero_byte(u ^ repeated_x);
                    let zv = contains_zero_byte(v ^ repeated_x);
                    if zu || zv {
                        break;
                    }
                }
                offset += usize_bytes * 2;
            }
        }

        // find the byte after the point the body loop stopped
        text[offset..].iter().position(|elt| *elt == x).map(|i| offset + i)
    }

    /// Return the last index matching the byte `a` in `text`.
    pub fn memrchr(x: u8, text: &[u8]) -> Option<usize> {
        // Scan for a single byte value by reading two `usize` words at a time.
        //
        // Split `text` in three parts
        // - unaligned tail, after the last word aligned address in text
        // - body, scan by 2 words at a time
        // - the first remaining bytes, < 2 word size
        let len = text.len();
        let ptr = text.as_ptr();
        let usize_bytes = mem::size_of::<usize>();

        // search to an aligned boundary
        let end_align = (ptr as usize + len) & (usize_bytes - 1);
        let mut offset;
        if end_align > 0 {
            offset = if end_align >= len { 0 } else { len - end_align };
            if let Some(index) = text[offset..].iter().rposition(|elt| *elt == x) {
                return Some(offset + index);
            }
        } else {
            offset = len;
        }

        // search the body of the text
        let repeated_x = repeat_byte(x);

        while offset >= 2 * usize_bytes {
            unsafe {
                let u = *(ptr.offset(offset as isize - 2 * usize_bytes as isize) as *const usize);
                let v = *(ptr.offset(offset as isize - usize_bytes as isize) as *const usize);

                // break if there is a matching byte
                let zu = contains_zero_byte(u ^ repeated_x);
                let zv = contains_zero_byte(v ^ repeated_x);
                if zu || zv {
                    break;
                }
            }
            offset -= 2 * usize_bytes;
        }

        // find the byte before the point the body loop stopped
        text[..offset].iter().rposition(|elt| *elt == x)
    }

    // test fallback implementations on all platforms
    #[test]
    fn matches_one() {
        assert_eq!(Some(0), memchr(b'a', b"a"));
    }

    #[test]
    fn matches_begin() {
        assert_eq!(Some(0), memchr(b'a', b"aaaa"));
    }

    #[test]
    fn matches_end() {
        assert_eq!(Some(4), memchr(b'z', b"aaaaz"));
    }

    #[test]
    fn matches_nul() {
        assert_eq!(Some(4), memchr(b'\x00', b"aaaa\x00"));
    }

    #[test]
    fn matches_past_nul() {
        assert_eq!(Some(5), memchr(b'z', b"aaaa\x00z"));
    }

    #[test]
    fn no_match_empty() {
        assert_eq!(None, memchr(b'a', b""));
    }

    #[test]
    fn no_match() {
        assert_eq!(None, memchr(b'a', b"xyz"));
    }

    #[test]
    fn matches_one_reversed() {
        assert_eq!(Some(0), memrchr(b'a', b"a"));
    }

    #[test]
    fn matches_begin_reversed() {
        assert_eq!(Some(3), memrchr(b'a', b"aaaa"));
    }

    #[test]
    fn matches_end_reversed() {
        assert_eq!(Some(0), memrchr(b'z', b"zaaaa"));
    }

    #[test]
    fn matches_nul_reversed() {
        assert_eq!(Some(4), memrchr(b'\x00', b"aaaa\x00"));
    }

    #[test]
    fn matches_past_nul_reversed() {
        assert_eq!(Some(0), memrchr(b'z', b"z\x00aaaa"));
    }

    #[test]
    fn no_match_empty_reversed() {
        assert_eq!(None, memrchr(b'a', b""));
    }

    #[test]
    fn no_match_reversed() {
        assert_eq!(None, memrchr(b'a', b"xyz"));
    }

    #[test]
    fn each_alignment_reversed() {
        let mut data = [1u8; 64];
        let needle = 2;
        let pos = 40;
        data[pos] = needle;
        for start in 0..16 {
            assert_eq!(Some(pos - start), memrchr(needle, &data[start..]));
        }
    }
}

#[cfg(test)]
mod tests {
    // test the implementations for the current plattform
    use super::{memchr, memrchr};

    #[test]
    fn matches_one() {
        assert_eq!(Some(0), memchr(b'a', b"a"));
    }

    #[test]
    fn matches_begin() {
        assert_eq!(Some(0), memchr(b'a', b"aaaa"));
    }

    #[test]
    fn matches_end() {
        assert_eq!(Some(4), memchr(b'z', b"aaaaz"));
    }

    #[test]
    fn matches_nul() {
        assert_eq!(Some(4), memchr(b'\x00', b"aaaa\x00"));
    }

    #[test]
    fn matches_past_nul() {
        assert_eq!(Some(5), memchr(b'z', b"aaaa\x00z"));
    }

    #[test]
    fn no_match_empty() {
        assert_eq!(None, memchr(b'a', b""));
    }

    #[test]
    fn no_match() {
        assert_eq!(None, memchr(b'a', b"xyz"));
    }

    #[test]
    fn matches_one_reversed() {
        assert_eq!(Some(0), memrchr(b'a', b"a"));
    }

    #[test]
    fn matches_begin_reversed() {
        assert_eq!(Some(3), memrchr(b'a', b"aaaa"));
    }

    #[test]
    fn matches_end_reversed() {
        assert_eq!(Some(0), memrchr(b'z', b"zaaaa"));
    }

    #[test]
    fn matches_nul_reversed() {
        assert_eq!(Some(4), memrchr(b'\x00', b"aaaa\x00"));
    }

    #[test]
    fn matches_past_nul_reversed() {
        assert_eq!(Some(0), memrchr(b'z', b"z\x00aaaa"));
    }

    #[test]
    fn no_match_empty_reversed() {
        assert_eq!(None, memrchr(b'a', b""));
    }

    #[test]
    fn no_match_reversed() {
        assert_eq!(None, memrchr(b'a', b"xyz"));
    }

    #[test]
    fn each_alignment() {
        let mut data = [1u8; 64];
        let needle = 2;
        let pos = 40;
        data[pos] = needle;
        for start in 0..16 {
            assert_eq!(Some(pos - start), memchr(needle, &data[start..]));
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>Add cfail test arc-rw-state-shouldnt-escape<commit_after>// error-pattern: reference is not valid outside of its lifetime
use std;
import std::arc;
fn main() {
    let x = ~arc::rw_arc(1);
    let mut y = none;
    do x.write |one| {
        y = some(one);
    }
    *option::unwrap(y) = 2;
}
<|endoftext|>


<commit_before><commit_msg>primitive data types can be used due to Copy trait{<commit_after><|endoftext|>


<commit_before><commit_msg>languages/rust/rust-book/3-chapter/25-code/multiple_phrases/src/chinese/mod.rs<commit_after><|endoftext|>


<commit_before><commit_msg>Move dereference out of unsafe block<commit_after><|endoftext|>


<commit_before><commit_msg>Factor set_passwd back into cmd_passwd.<commit_after><|endoftext|>


<commit_before><commit_msg>Remove some dead code.<commit_after><|endoftext|>


<commit_before><commit_msg>Subslice patterns: Test passing static & dynamic semantics.<commit_after>// This test comprehensively checks the passing static and dynamic semantics
// of subslice patterns `..`, `x @ ..`, `ref x @ ..`, and `ref mut @ ..`
// in slice patterns `[$($pat), $(,)?]` .

// run-pass

#![feature(slice_patterns)]

#![allow(unreachable_patterns)]

use std::convert::identity;

#[derive(PartialEq, Debug, Clone)]
struct N(u8);

macro_rules! n {
    ($($e:expr),* $(,)?) => {
        [$(N($e)),*]
    }
}

macro_rules! c {
    ($inp:expr, $typ:ty, $out:expr $(,)?) => {
        assert_eq!($out, identity::<$typ>($inp));
    }
}

macro_rules! m {
    ($e:expr, $p:pat => $b:expr) => {
        match $e {
            $p => $b,
            _ => panic!(),
        }
    }
}

fn main() {
    slices();
    arrays();
}

fn slices() {
    // Matching slices using `ref` patterns:
    let mut v = vec![N(0), N(1), N(2), N(3), N(4)];
    let mut vc = (0..=4).collect::<Vec<u8>>();

    let [..] = v[..]; // Always matches.
    m!(v[..], [N(0), ref sub @ .., N(4)] => c!(sub, &[N], n![1, 2, 3]));
    m!(v[..], [N(0), ref sub @ ..] => c!(sub, &[N], n![1, 2, 3, 4]));
    m!(v[..], [ref sub @ .., N(4)] => c!(sub, &[N], n![0, 1, 2, 3]));
    m!(v[..], [ref sub @ .., _, _, _, _, _] => c!(sub, &[N], &n![] as &[N]));
    m!(v[..], [_, _, _, _, _, ref sub @ ..] => c!(sub, &[N], &n![] as &[N]));
    m!(vc[..], [x, .., y] => c!((x, y), (u8, u8), (0, 4)));

    // Matching slices using `ref mut` patterns:
    let [..] = v[..]; // Always matches.
    m!(v[..], [N(0), ref mut sub @ .., N(4)] => c!(sub, &mut [N], n![1, 2, 3]));
    m!(v[..], [N(0), ref mut sub @ ..] => c!(sub, &mut [N], n![1, 2, 3, 4]));
    m!(v[..], [ref mut sub @ .., N(4)] => c!(sub, &mut [N], n![0, 1, 2, 3]));
    m!(v[..], [ref mut sub @ .., _, _, _, _, _] => c!(sub, &mut [N], &mut n![] as &mut [N]));
    m!(v[..], [_, _, _, _, _, ref mut sub @ ..] => c!(sub, &mut [N], &mut n![] as &mut [N]));
    m!(vc[..], [x, .., y] => c!((x, y), (u8, u8), (0, 4)));

    // Matching slices using default binding modes (&):
    let [..] = &v[..]; // Always matches.
    m!(&v[..], [N(0), sub @ .., N(4)] => c!(sub, &[N], n![1, 2, 3]));
    m!(&v[..], [N(0), sub @ ..] => c!(sub, &[N], n![1, 2, 3, 4]));
    m!(&v[..], [sub @ .., N(4)] => c!(sub, &[N], n![0, 1, 2, 3]));
    m!(&v[..], [sub @ .., _, _, _, _, _] => c!(sub, &[N], &n![] as &[N]));
    m!(&v[..], [_, _, _, _, _, sub @ ..] => c!(sub, &[N], &n![] as &[N]));
    m!(&vc[..], [x, .., y] => c!((x, y), (&u8, &u8), (&0, &4)));

    // Matching slices using default binding modes (&mut):
    let [..] = &mut v[..]; // Always matches.
    m!(&mut v[..], [N(0), sub @ .., N(4)] => c!(sub, &mut [N], n![1, 2, 3]));
    m!(&mut v[..], [N(0), sub @ ..] => c!(sub, &mut [N], n![1, 2, 3, 4]));
    m!(&mut v[..], [sub @ .., N(4)] => c!(sub, &mut [N], n![0, 1, 2, 3]));
    m!(&mut v[..], [sub @ .., _, _, _, _, _] => c!(sub, &mut [N], &mut n![] as &mut [N]));
    m!(&mut v[..], [_, _, _, _, _, sub @ ..] => c!(sub, &mut [N], &mut n![] as &mut [N]));
    m!(&mut vc[..], [x, .., y] => c!((x, y), (&mut u8, &mut u8), (&mut 0, &mut 4)));
}

fn arrays() {
    let mut v = n![0, 1, 2, 3, 4];
    let vc = [0, 1, 2, 3, 4];

    // Matching arrays by value:
    m!(v.clone(), [N(0), sub @ .., N(4)] => c!(sub, [N; 3], n![1, 2, 3]));
    m!(v.clone(), [N(0), sub @ ..] => c!(sub, [N; 4], n![1, 2, 3, 4]));
    m!(v.clone(), [sub @ .., N(4)] => c!(sub, [N; 4], n![0, 1, 2, 3]));
    m!(v.clone(), [sub @ .., _, _, _, _, _] => c!(sub, [N; 0], n![] as [N; 0]));
    m!(v.clone(), [_, _, _, _, _, sub @ ..] => c!(sub, [N; 0], n![] as [N; 0]));
    m!(v.clone(), [x, .., y] => c!((x, y), (N, N), (N(0), N(4))));
    m!(v.clone(), [..] => ());

    // Matching arrays by ref patterns:
    m!(v, [N(0), ref sub @ .., N(4)] => c!(sub, &[N; 3], &n![1, 2, 3]));
    m!(v, [N(0), ref sub @ ..] => c!(sub, &[N; 4], &n![1, 2, 3, 4]));
    m!(v, [ref sub @ .., N(4)] => c!(sub, &[N; 4], &n![0, 1, 2, 3]));
    m!(v, [ref sub @ .., _, _, _, _, _] => c!(sub, &[N; 0], &n![] as &[N; 0]));
    m!(v, [_, _, _, _, _, ref sub @ ..] => c!(sub, &[N; 0], &n![] as &[N; 0]));
    m!(vc, [x, .., y] => c!((x, y), (u8, u8), (0, 4)));

    // Matching arrays by ref mut patterns:
    m!(v, [N(0), ref mut sub @ .., N(4)] => c!(sub, &mut [N; 3], &mut n![1, 2, 3]));
    m!(v, [N(0), ref mut sub @ ..] => c!(sub, &mut [N; 4], &mut n![1, 2, 3, 4]));
    m!(v, [ref mut sub @ .., N(4)] => c!(sub, &mut [N; 4], &mut n![0, 1, 2, 3]));
    m!(v, [ref mut sub @ .., _, _, _, _, _] => c!(sub, &mut [N; 0], &mut n![] as &mut [N; 0]));
    m!(v, [_, _, _, _, _, ref mut sub @ ..] => c!(sub, &mut [N; 0], &mut n![] as &mut [N; 0]));

    // Matching arrays by default binding modes (&):
    m!(&v, [N(0), sub @ .., N(4)] => c!(sub, &[N; 3], &n![1, 2, 3]));
    m!(&v, [N(0), sub @ ..] => c!(sub, &[N; 4], &n![1, 2, 3, 4]));
    m!(&v, [sub @ .., N(4)] => c!(sub, &[N; 4], &n![0, 1, 2, 3]));
    m!(&v, [sub @ .., _, _, _, _, _] => c!(sub, &[N; 0], &n![] as &[N; 0]));
    m!(&v, [_, _, _, _, _, sub @ ..] => c!(sub, &[N; 0], &n![] as &[N; 0]));
    m!(&v, [..] => ());
    m!(&v, [x, .., y] => c!((x, y), (&N, &N), (&N(0), &N(4))));

    // Matching arrays by default binding modes (&mut):
    m!(&mut v, [N(0), sub @ .., N(4)] => c!(sub, &mut [N; 3], &mut n![1, 2, 3]));
    m!(&mut v, [N(0), sub @ ..] => c!(sub, &mut [N; 4], &mut n![1, 2, 3, 4]));
    m!(&mut v, [sub @ .., N(4)] => c!(sub, &mut [N; 4], &mut n![0, 1, 2, 3]));
    m!(&mut v, [sub @ .., _, _, _, _, _] => c!(sub, &mut [N; 0], &mut n![] as &[N; 0]));
    m!(&mut v, [_, _, _, _, _, sub @ ..] => c!(sub, &mut [N; 0], &mut n![] as &[N; 0]));
    m!(&mut v, [..] => ());
    m!(&mut v, [x, .., y] => c!((x, y), (&mut N, &mut N), (&mut N(0), &mut N(4))));
}
<|endoftext|>


<commit_before>// Copyright 2012 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.

// xfail-test

fn is_even(i: int) -> bool { (i%2) == 0 }
fn even(i: int) : is_even(i) -> int { i }

fn test() {
    let v = 4;
    loop {
        check is_even(v);
        break;
    }
    even(v);
}

pub fn main() {
    test();
}
<commit_msg>typestate is not planned for upcoming versions of rust....<commit_after><|endoftext|>


<commit_before><commit_msg>Add Rust solution for bubblesort<commit_after>use std::cmp::PartialOrd;

/// An in-place implementation of bubble sort
fn bubble_sort<T>(arr: &mut [T])
where T: PartialOrd {
  for i in 0..arr.len() {
    for j in i..arr.len() {
      if arr[i] > arr[j] {
        arr.swap(i, j);
      }
    }
  }
}

fn main() {
  let arr = &mut [5,4,1,2,3];
  bubble_sort(arr);
  assert_eq!(&[1,2,3,4,5], arr);
}
<|endoftext|>


<commit_before><commit_msg>Add an example for KEY=value argument as asked in #79<commit_after>#[macro_use]
extern crate structopt;

use structopt::StructOpt;

fn parse_key_val(s: &str) -> Result<(String, String), String> {
    let pos = s.find('=').ok_or_else(|| format!("invalid KEY=value: no `=` found in `{}`", s))?;
    Ok((s[..pos].into(), s[pos + 1..].into()))
}

#[derive(StructOpt, Debug)]
struct Opt {
    #[structopt(short = "D", parse(try_from_str = "parse_key_val"))]
    defines: Vec<(String, String)>,
}

fn main() {
    let opt = Opt::from_args();
    println!("{:?}", opt);
}
<|endoftext|>


<commit_before><commit_msg>Check of options have been revised.<commit_after><|endoftext|>


<commit_before><commit_msg>error solved, lifetime issues persits.<commit_after><|endoftext|>


<commit_before><commit_msg>For channel top emoji users, added # of messages sent<commit_after><|endoftext|>


<commit_before><commit_msg>Add examples for Stack<commit_after><|endoftext|>


<commit_before>// Copyright 2013 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.

use core::prelude::*;

use ast::{meta_item, item, expr};
use codemap::span;
use ext::base::ExtCtxt;
use ext::build::AstBuilder;
use ext::deriving::generic::*;

pub fn expand_deriving_ord(cx: @ExtCtxt,
                           span: span,
                           mitem: @meta_item,
                           in_items: ~[@item]) -> ~[@item] {
    macro_rules! md (
        ($name:expr, $less:expr, $equal:expr) => {
            MethodDef {
                name: $name,
                generics: LifetimeBounds::empty(),
                explicit_self: borrowed_explicit_self(),
                args: ~[borrowed_self()],
                ret_ty: Literal(Path::new(~["bool"])),
                const_nonmatching: false,
                combine_substructure: |cx, span, substr|
                    cs_ord($less, $equal, cx, span, substr)
            }
        }
    );

    let trait_def = TraitDef {
        path: Path::new(~["std", "cmp", "Ord"]),
        // XXX: Ord doesn't imply Eq yet
        additional_bounds: ~[Literal(Path::new(~["std", "cmp", "Eq"]))],
        generics: LifetimeBounds::empty(),
        methods: ~[
            md!("lt", true,  false),
            md!("le", true,  true),
            md!("gt", false, false),
            md!("ge", false, true)
        ]
    };
    trait_def.expand(cx, span, mitem, in_items)
}

/// `less`: is this `lt` or `le`? `equal`: is this `le` or `ge`?
fn cs_ord(less: bool, equal: bool,
          cx: @ExtCtxt, span: span,
          substr: &Substructure) -> @expr {
    let binop = if less {
        cx.ident_of("lt")
    } else {
        cx.ident_of("gt")
    };
    let base = cx.expr_bool(span, equal);

    cs_fold(
        false, // need foldr,
        |cx, span, subexpr, self_f, other_fs| {
            /*

            build up a series of nested ifs from the inside out to get
            lexical ordering (hence foldr), i.e.

            ```
            if self.f1 `binop` other.f1 {
                true
            } else if self.f1 == other.f1 {
                if self.f2 `binop` other.f2 {
                    true
                } else if self.f2 == other.f2 {
                    `equal`
                } else {
                    false
                }
            } else {
                false
            }
            ```

            The inner "`equal`" case is only reached if the two
            items have all fields equal.
            */
            if other_fs.len() != 1 {
                cx.span_bug(span, "Not exactly 2 arguments in `deriving(Ord)`");
            }

            let cmp = cx.expr_method_call(span,
                                          self_f, cx.ident_of("eq"), other_fs.to_owned());
            let elseif = cx.expr_if(span, cmp,
                                    subexpr, Some(cx.expr_bool(span, false)));

            let cmp = cx.expr_method_call(span,
                                          self_f, binop, other_fs.to_owned());
            cx.expr_if(span, cmp,
                        cx.expr_bool(span, true), Some(elseif))
        },
        base,
        |cx, span, args, _| {
            // nonmatching enums, order by the order the variants are
            // written
            match args {
                [(self_var, _, _),
                 (other_var, _, _)] =>
                    cx.expr_bool(span,
                                   if less {
                                       self_var < other_var
                                   } else {
                                       self_var > other_var
                                   }),
                _ => cx.span_bug(span, "Not exactly 2 arguments in `deriving(Ord)`")
            }
        },
        cx, span, substr)
}
<commit_msg>syntax: rewrite deriving(Ord) to not require Eq.<commit_after>// Copyright 2013 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.

use core::prelude::*;

use ast;
use ast::{meta_item, item, expr};
use codemap::span;
use ext::base::ExtCtxt;
use ext::build::AstBuilder;
use ext::deriving::generic::*;

pub fn expand_deriving_ord(cx: @ExtCtxt,
                           span: span,
                           mitem: @meta_item,
                           in_items: ~[@item]) -> ~[@item] {
    macro_rules! md (
        ($name:expr, $func:expr, $op:expr) => {
            MethodDef {
                name: $name,
                generics: LifetimeBounds::empty(),
                explicit_self: borrowed_explicit_self(),
                args: ~[borrowed_self()],
                ret_ty: Literal(Path::new(~["bool"])),
                const_nonmatching: false,
                combine_substructure: |cx, span, substr| $func($op, cx, span, substr)
            }
        }
    );

    let trait_def = TraitDef {
        path: Path::new(~["std", "cmp", "Ord"]),
        additional_bounds: ~[],
        generics: LifetimeBounds::empty(),
        methods: ~[
            md!("lt", cs_strict, true),
            md!("le", cs_nonstrict, true), // inverse operation
            md!("gt", cs_strict, false),
            md!("ge", cs_nonstrict, false)
        ]
    };
    trait_def.expand(cx, span, mitem, in_items)
}

/// Strict inequality.
fn cs_strict(less: bool, cx: @ExtCtxt, span: span, substr: &Substructure) -> @expr {
    let op = if less {ast::lt} else {ast::gt};
    cs_fold(
        false, // need foldr,
        |cx, span, subexpr, self_f, other_fs| {
            /*
            build up a series of chain ||'s and &&'s from the inside
            out (hence foldr) to get lexical ordering, i.e. for op ==
            `ast::lt`

            ```
            self.f1 < other.f1 || (!(other.f1 < self.f1) &&
                (self.f2 < other.f2 || (!(other.f2 < self.f2) &&
                    (false)
                ))
            )
            ```

            The optimiser should remove the redundancy. We explicitly
            get use the binops to avoid auto-deref derefencing too many
            layers of pointers, if the type includes pointers.
            */
            let other_f = match other_fs {
                [o_f] => o_f,
                _ => cx.span_bug(span, "Not exactly 2 arguments in `deriving(Ord)`")
            };

            let cmp = cx.expr_binary(span, op,
                                     cx.expr_deref(span, self_f),
                                     cx.expr_deref(span, other_f));

            let not_cmp = cx.expr_binary(span, op,
                                         cx.expr_deref(span, other_f),
                                         cx.expr_deref(span, self_f));
            let not_cmp = cx.expr_unary(span, ast::not, not_cmp);

            let and = cx.expr_binary(span, ast::and,
                                     not_cmp, subexpr);
            cx.expr_binary(span, ast::or, cmp, and)
        },
        cx.expr_bool(span, false),
        |cx, span, args, _| {
            // nonmatching enums, order by the order the variants are
            // written
            match args {
                [(self_var, _, _),
                 (other_var, _, _)] =>
                    cx.expr_bool(span,
                                 if less {
                                     self_var < other_var
                                 } else {
                                     self_var > other_var
                                 }),
                _ => cx.span_bug(span, "Not exactly 2 arguments in `deriving(Ord)`")
            }
        },
        cx, span, substr)
}

fn cs_nonstrict(less: bool, cx: @ExtCtxt, span: span, substr: &Substructure) -> @expr {
    // Example: ge becomes !(*self < *other), le becomes !(*self > *other)

    let inverse_op = if less {ast::gt} else {ast::lt};
    match substr.self_args {
        [self_, other] => {
            let inverse_cmp = cx.expr_binary(span, inverse_op,
                                             cx.expr_deref(span, self_),
                                             cx.expr_deref(span, other));

            cx.expr_unary(span, ast::not, inverse_cmp)
        }
        _ => cx.span_bug(span, "Not exactly 2 arguments in `deriving(Ord)`")
    }
}
<|endoftext|>


<commit_before>use gtk::widgets;
use rustc_serialize::{Encodable, json};
use std::cell::Cell;
use std::env;
use std::collections::{HashMap, HashSet};
use std::io::{Read, Write};
use std::fs::{self, PathExt};
use std::ops::Deref;
use std::path::{Path, PathBuf};

pub static WINDOW_WIDTH : i32 = 1242;
pub static WINDOW_HEIGHT : i32 = 768;
pub static EDITOR_HEIGHT_PCT : f32 = 0.70;
pub static MIN_FONT_SIZE : i32 = 0;
pub static MAX_FONT_SIZE : i32 = 50;

#[cfg(target_os = "macos")]
pub static META_KEY : u32 = 1 << 28;
#[cfg(not(target_os = "macos"))]
pub static META_KEY : u32 = 1 << 2;

pub static DATA_DIR : &'static str = ".soak";
pub static CONFIG_FILE : &'static str = ".soakrc";
pub static CONFIG_CONTENT : &'static str = include_str!("../resources/soakrc");
pub static PREFS_FILE : &'static str = "prefs.json";
pub static SETTINGS_FILE : &'static str = "settings.json";
pub static NO_WINDOW_FLAG : &'static str = "-nw";

pub struct Resource {
    pub path: &'static [&'static str],
    pub data: &'static str,
    pub always_copy: bool
}
pub static DATA_CONTENT : &'static [Resource] = &[
    Resource{path: &["after", "syntax", "rust.vim"],
             data: include_str!("../resources/soak/after/syntax/rust.vim"),
             always_copy: true},

    Resource{path: &["autoload", "paste.vim"],
             data: include_str!("../resources/soak/autoload/paste.vim"),
             always_copy: false},
    Resource{path: &["autoload", "rust.vim"],
             data: include_str!("../resources/soak/autoload/rust.vim"),
             always_copy: true},

    Resource{path: &["compiler", "rustc.vim"],
             data: include_str!("../resources/soak/compiler/rustc.vim"),
             always_copy: true},
    Resource{path: &["compiler", "cargo.vim"],
             data: include_str!("../resources/soak/compiler/cargo.vim"),
             always_copy: true},

    Resource{path: &["doc", "rust.txt"],
             data: include_str!("../resources/soak/doc/rust.txt"),
             always_copy: true},

    Resource{path: &["ftdetect", "rust.vim"],
             data: include_str!("../resources/soak/ftdetect/rust.vim"),
             always_copy: true},

    Resource{path: &["ftplugin", "rust.vim"],
             data: include_str!("../resources/soak/ftplugin/rust.vim"),
             always_copy: true},
    Resource{path: &["ftplugin", "c.vim"],
             data: include_str!("../resources/soak/ftplugin/c.vim"),
             always_copy: false},

    Resource{path: &["indent", "rust.vim"],
             data: include_str!("../resources/soak/indent/rust.vim"),
             always_copy: true},
    Resource{path: &["indent", "c.vim"],
             data: include_str!("../resources/soak/indent/c.vim"),
             always_copy: false},

    Resource{path: &["plugin", "eunuch.vim"],
             data: include_str!("../resources/soak/plugin/eunuch.vim"),
             always_copy: false},
    Resource{path: &["plugin", "racer.vim"],
             data: include_str!("../resources/soak/plugin/racer.vim"),
             always_copy: true},
    Resource{path: &["plugin", "rust.vim"],
             data: include_str!("../resources/soak/plugin/rust.vim"),
             always_copy: true},

    Resource{path: &["syntax", "c.vim"],
             data: include_str!("../resources/soak/syntax/c.vim"),
             always_copy: false},
    Resource{path: &["syntax", "nosyntax.vim"],
             data: include_str!("../resources/soak/syntax/nosyntax.vim"),
             always_copy: false},
    Resource{path: &["syntax", "rust.vim"],
             data: include_str!("../resources/soak/syntax/rust.vim"),
             always_copy: true},
    Resource{path: &["syntax", "syncolor.vim"],
             data: include_str!("../resources/soak/syntax/syncolor.vim"),
             always_copy: false},
    Resource{path: &["syntax", "synload.vim"],
             data: include_str!("../resources/soak/syntax/synload.vim"),
             always_copy: false},
    Resource{path: &["syntax", "syntax.vim"],
             data: include_str!("../resources/soak/syntax/syntax.vim"),
             always_copy: false},

    Resource{path: &["syntax_checkers", "rust", "rustc.vim"],
             data: include_str!("../resources/soak/syntax_checkers/rust/rustc.vim"),
             always_copy: true},

    Resource{path: &["filetype.vim"],
             data: include_str!("../resources/soak/filetype.vim"),
             always_copy: false}
];

pub struct State<'a> {
    pub projects: HashSet<String>,
    pub expansions: HashSet<String>,
    pub selection: Option<String>,
    pub easy_mode: bool,
    pub font_size: i32,
    pub builders: HashMap<PathBuf, (widgets::VteTerminal, Cell<i32>)>,
    pub window: &'a widgets::Window,
    pub tree_store: &'a widgets::TreeStore,
    pub tree_model: &'a widgets::TreeModel,
    pub tree_selection: &'a widgets::TreeSelection,
    pub rename_button: &'a widgets::Button,
    pub remove_button: &'a widgets::Button,
    pub is_refreshing_tree: bool
}

#[derive(RustcDecodable, RustcEncodable)]
struct Prefs {
    projects: Vec<String>,
    expansions: Vec<String>,
    selection: Option<String>,
    easy_mode: bool,
    font_size: i32
}

#[derive(RustcDecodable, RustcEncodable)]
pub struct KeySettings {
    pub new_project: Option<String>,
    pub import: Option<String>,
    pub rename: Option<String>,
    pub remove: Option<String>,

    pub run: Option<String>,
    pub build: Option<String>,
    pub test: Option<String>,
    pub clean: Option<String>,
    pub stop: Option<String>,

    pub save: Option<String>,
    pub undo: Option<String>,
    pub redo: Option<String>,
    pub font_dec: Option<String>,
    pub font_inc: Option<String>,
    pub close: Option<String>
}

#[derive(RustcDecodable, RustcEncodable)]
pub struct Settings {
    pub keys: KeySettings
}

pub fn get_home_dir() -> PathBuf {
    if let Some(path) = env::home_dir() {
        path
    } else {
        PathBuf::from(".")
    }
}

fn get_prefs(state: &State) -> Prefs {
    Prefs {
        projects: state.projects.clone().into_iter().collect(),
        expansions: state.expansions.clone().into_iter().collect(),
        selection: state.selection.clone(),
        easy_mode: state.easy_mode,
        font_size: state.font_size
    }
}

pub fn is_parent_path(parent_str: &String, child_str: &String) -> bool {
    let parent_ref: &str = parent_str.as_ref();
    child_str.starts_with(parent_ref) &&
    Path::new(parent_str).parent() != Path::new(child_str).parent()
}

pub fn get_selected_path(state: &State) -> Option<String> {
    let mut iter = widgets::TreeIter::new().unwrap();

    if state.tree_selection.get_selected(state.tree_model, &mut iter) {
        state.tree_model.get_value(&iter, 1).get_string()
    } else {
        None
    }
}

fn is_project_path(path: &Path) -> bool {
    path.join("Cargo.toml").exists()
}

fn is_project_root(state: &State, path: &Path) -> bool {
    if let Some(path_str) = path.to_str() {
        state.projects.contains(&path_str.to_string())
    } else {
        false
    }
}

pub fn get_project_path(state: &State, path: &Path) -> Option<PathBuf> {
    if is_project_path(path) || is_project_root(state, path) {
        Some(PathBuf::from(path))
    } else {
        if let Some(parent_path) = path.parent() {
            get_project_path(state, parent_path.deref())
        } else {
            None
        }
    }
}

pub fn get_selected_project_path(state: &State) -> Option<PathBuf> {
    if let Some(path_str) = get_selected_path(state) {
        get_project_path(state, Path::new(&path_str))
    } else {
        None
    }
}

pub fn write_prefs(state: &State) {
    let prefs = get_prefs(state);

    let mut json_str = String::new();
    {
        let mut encoder = json::Encoder::new_pretty(&mut json_str);
        prefs.encode(&mut encoder).ok().expect("Error encoding prefs.");
    }

    let prefs_path = get_home_dir().deref().join(DATA_DIR).join(PREFS_FILE);
    if let Some(mut f) = fs::File::create(&prefs_path).ok() {
        match f.write(json_str.as_bytes()) {
            Ok(_) => {},
            Err(e) => println!("Error writing prefs: {}", e)
        };
    }
}

pub fn read_prefs(state: &mut State) {
    let prefs_path = get_home_dir().deref().join(DATA_DIR).join(PREFS_FILE);
    if let Some(mut f) = fs::File::open(&prefs_path).ok() {
        let mut json_str = String::new();
        let prefs_option : Option<Prefs> = match f.read_to_string(&mut json_str) {
            Ok(_) => {
                match json::decode(json_str.as_ref()) {
                    Ok(object) => Some(object),
                    Err(e) => {
                        println!("Error decoding prefs: {}", e);
                        None
                    }
                }
            },
            Err(_) => None
        };

        if let Some(prefs) = prefs_option {
            state.projects.clear();
            for path_str in prefs.projects.iter() {
                state.projects.insert(path_str.clone());
            }

            state.expansions.clear();
            for path_str in prefs.expansions.iter() {
                state.expansions.insert(path_str.clone());
            }

            state.selection = prefs.selection;
            state.easy_mode = prefs.easy_mode;

            if (prefs.font_size >= MIN_FONT_SIZE) && (prefs.font_size <= MAX_FONT_SIZE) {
                state.font_size = prefs.font_size;
            }
        }
    }
}

fn get_settings() -> Settings {
    Settings {
        keys: ::utils::KeySettings {
            new_project: Some("p".to_string()),
            import: Some("o".to_string()),
            rename: Some("n".to_string()),
            remove: Some("x".to_string()),

            run: Some("a".to_string()),
            build: Some("k".to_string()),
            test: Some("t".to_string()),
            clean: Some("l".to_string()),
            stop: Some("i".to_string()),

            save: Some("s".to_string()),
            undo: Some("z".to_string()),
            redo: Some("r".to_string()),
            font_dec: Some("minus".to_string()),
            font_inc: Some("equal".to_string()),
            close: Some("w".to_string())
        }
    }
}

pub fn write_settings() {
    let settings_path = get_home_dir().deref().join(DATA_DIR).join(SETTINGS_FILE);
    if settings_path.exists() { // don't overwrite existing file, so user can modify it
        return;
    }

    let default_settings = get_settings();

    let mut json_str = String::new();
    {
        let mut encoder = json::Encoder::new_pretty(&mut json_str);
        default_settings.encode(&mut encoder).ok().expect("Error encoding settings.");
    }

    if let Some(mut f) = fs::File::create(&settings_path).ok() {
        match f.write(json_str.as_bytes()) {
            Ok(_) => {},
            Err(e) => println!("Error writing settings: {}", e)
        };
    }
}

pub fn read_settings() -> Settings {
    let default_settings = get_settings();
    let settings_path = get_home_dir().deref().join(DATA_DIR).join(SETTINGS_FILE);

    if let Some(mut f) = fs::File::open(&settings_path).ok() {
        let mut json_str = String::new();
        let settings_opt : Option<Settings> = match f.read_to_string(&mut json_str) {
            Ok(_) => {
                match json::decode(json_str.as_ref()) {
                    Ok(object) => Some(object),
                    Err(e) => {
                        println!("Error decoding settings: {}", e);
                        None
                    }
                }
            },
            Err(_) => None
        };

        if let Some(mut settings) = settings_opt {
            let keys = default_settings.keys;

            if let Some(key) = keys.new_project {
                settings.keys.new_project = Some(settings.keys.new_project.unwrap_or(key));
            }
            if let Some(key) = keys.import {
                settings.keys.import = Some(settings.keys.import.unwrap_or(key));
            }
            if let Some(key) = keys.rename {
                settings.keys.rename = Some(settings.keys.rename.unwrap_or(key));
            }
            if let Some(key) = keys.remove {
                settings.keys.remove = Some(settings.keys.remove.unwrap_or(key));
            }

            if let Some(key) = keys.run {
                settings.keys.run = Some(settings.keys.run.unwrap_or(key));
            }
            if let Some(key) = keys.build {
                settings.keys.build = Some(settings.keys.build.unwrap_or(key));
            }
            if let Some(key) = keys.test {
                settings.keys.test = Some(settings.keys.test.unwrap_or(key));
            }
            if let Some(key) = keys.clean {
                settings.keys.clean = Some(settings.keys.clean.unwrap_or(key));
            }
            if let Some(key) = keys.stop {
                settings.keys.stop = Some(settings.keys.stop.unwrap_or(key))
            }

            if let Some(key) = keys.save {
                settings.keys.save = Some(settings.keys.save.unwrap_or(key));
            }
            if let Some(key) = keys.undo {
                settings.keys.undo = Some(settings.keys.undo.unwrap_or(key));
            }
            if let Some(key) = keys.redo {
                settings.keys.redo = Some(settings.keys.redo.unwrap_or(key));
            }
            if let Some(key) = keys.font_dec {
                settings.keys.font_dec = Some(settings.keys.font_dec.unwrap_or(key));
            }
            if let Some(key) = keys.font_inc {
                settings.keys.font_inc = Some(settings.keys.font_inc.unwrap_or(key));
            }
            if let Some(key) = keys.close {
                settings.keys.close = Some(settings.keys.close.unwrap_or(key));
            }

            return settings;
        }
    }

    default_settings
}
<commit_msg>Don't use x as a shortcut<commit_after>use gtk::widgets;
use rustc_serialize::{Encodable, json};
use std::cell::Cell;
use std::env;
use std::collections::{HashMap, HashSet};
use std::io::{Read, Write};
use std::fs::{self, PathExt};
use std::ops::Deref;
use std::path::{Path, PathBuf};

pub static WINDOW_WIDTH : i32 = 1242;
pub static WINDOW_HEIGHT : i32 = 768;
pub static EDITOR_HEIGHT_PCT : f32 = 0.70;
pub static MIN_FONT_SIZE : i32 = 0;
pub static MAX_FONT_SIZE : i32 = 50;

#[cfg(target_os = "macos")]
pub static META_KEY : u32 = 1 << 28;
#[cfg(not(target_os = "macos"))]
pub static META_KEY : u32 = 1 << 2;

pub static DATA_DIR : &'static str = ".soak";
pub static CONFIG_FILE : &'static str = ".soakrc";
pub static CONFIG_CONTENT : &'static str = include_str!("../resources/soakrc");
pub static PREFS_FILE : &'static str = "prefs.json";
pub static SETTINGS_FILE : &'static str = "settings.json";
pub static NO_WINDOW_FLAG : &'static str = "-nw";

pub struct Resource {
    pub path: &'static [&'static str],
    pub data: &'static str,
    pub always_copy: bool
}
pub static DATA_CONTENT : &'static [Resource] = &[
    Resource{path: &["after", "syntax", "rust.vim"],
             data: include_str!("../resources/soak/after/syntax/rust.vim"),
             always_copy: true},

    Resource{path: &["autoload", "paste.vim"],
             data: include_str!("../resources/soak/autoload/paste.vim"),
             always_copy: false},
    Resource{path: &["autoload", "rust.vim"],
             data: include_str!("../resources/soak/autoload/rust.vim"),
             always_copy: true},

    Resource{path: &["compiler", "rustc.vim"],
             data: include_str!("../resources/soak/compiler/rustc.vim"),
             always_copy: true},
    Resource{path: &["compiler", "cargo.vim"],
             data: include_str!("../resources/soak/compiler/cargo.vim"),
             always_copy: true},

    Resource{path: &["doc", "rust.txt"],
             data: include_str!("../resources/soak/doc/rust.txt"),
             always_copy: true},

    Resource{path: &["ftdetect", "rust.vim"],
             data: include_str!("../resources/soak/ftdetect/rust.vim"),
             always_copy: true},

    Resource{path: &["ftplugin", "rust.vim"],
             data: include_str!("../resources/soak/ftplugin/rust.vim"),
             always_copy: true},
    Resource{path: &["ftplugin", "c.vim"],
             data: include_str!("../resources/soak/ftplugin/c.vim"),
             always_copy: false},

    Resource{path: &["indent", "rust.vim"],
             data: include_str!("../resources/soak/indent/rust.vim"),
             always_copy: true},
    Resource{path: &["indent", "c.vim"],
             data: include_str!("../resources/soak/indent/c.vim"),
             always_copy: false},

    Resource{path: &["plugin", "eunuch.vim"],
             data: include_str!("../resources/soak/plugin/eunuch.vim"),
             always_copy: false},
    Resource{path: &["plugin", "racer.vim"],
             data: include_str!("../resources/soak/plugin/racer.vim"),
             always_copy: true},
    Resource{path: &["plugin", "rust.vim"],
             data: include_str!("../resources/soak/plugin/rust.vim"),
             always_copy: true},

    Resource{path: &["syntax", "c.vim"],
             data: include_str!("../resources/soak/syntax/c.vim"),
             always_copy: false},
    Resource{path: &["syntax", "nosyntax.vim"],
             data: include_str!("../resources/soak/syntax/nosyntax.vim"),
             always_copy: false},
    Resource{path: &["syntax", "rust.vim"],
             data: include_str!("../resources/soak/syntax/rust.vim"),
             always_copy: true},
    Resource{path: &["syntax", "syncolor.vim"],
             data: include_str!("../resources/soak/syntax/syncolor.vim"),
             always_copy: false},
    Resource{path: &["syntax", "synload.vim"],
             data: include_str!("../resources/soak/syntax/synload.vim"),
             always_copy: false},
    Resource{path: &["syntax", "syntax.vim"],
             data: include_str!("../resources/soak/syntax/syntax.vim"),
             always_copy: false},

    Resource{path: &["syntax_checkers", "rust", "rustc.vim"],
             data: include_str!("../resources/soak/syntax_checkers/rust/rustc.vim"),
             always_copy: true},

    Resource{path: &["filetype.vim"],
             data: include_str!("../resources/soak/filetype.vim"),
             always_copy: false}
];

pub struct State<'a> {
    pub projects: HashSet<String>,
    pub expansions: HashSet<String>,
    pub selection: Option<String>,
    pub easy_mode: bool,
    pub font_size: i32,
    pub builders: HashMap<PathBuf, (widgets::VteTerminal, Cell<i32>)>,
    pub window: &'a widgets::Window,
    pub tree_store: &'a widgets::TreeStore,
    pub tree_model: &'a widgets::TreeModel,
    pub tree_selection: &'a widgets::TreeSelection,
    pub rename_button: &'a widgets::Button,
    pub remove_button: &'a widgets::Button,
    pub is_refreshing_tree: bool
}

#[derive(RustcDecodable, RustcEncodable)]
struct Prefs {
    projects: Vec<String>,
    expansions: Vec<String>,
    selection: Option<String>,
    easy_mode: bool,
    font_size: i32
}

#[derive(RustcDecodable, RustcEncodable)]
pub struct KeySettings {
    pub new_project: Option<String>,
    pub import: Option<String>,
    pub rename: Option<String>,
    pub remove: Option<String>,

    pub run: Option<String>,
    pub build: Option<String>,
    pub test: Option<String>,
    pub clean: Option<String>,
    pub stop: Option<String>,

    pub save: Option<String>,
    pub undo: Option<String>,
    pub redo: Option<String>,
    pub font_dec: Option<String>,
    pub font_inc: Option<String>,
    pub close: Option<String>
}

#[derive(RustcDecodable, RustcEncodable)]
pub struct Settings {
    pub keys: KeySettings
}

pub fn get_home_dir() -> PathBuf {
    if let Some(path) = env::home_dir() {
        path
    } else {
        PathBuf::from(".")
    }
}

fn get_prefs(state: &State) -> Prefs {
    Prefs {
        projects: state.projects.clone().into_iter().collect(),
        expansions: state.expansions.clone().into_iter().collect(),
        selection: state.selection.clone(),
        easy_mode: state.easy_mode,
        font_size: state.font_size
    }
}

pub fn is_parent_path(parent_str: &String, child_str: &String) -> bool {
    let parent_ref: &str = parent_str.as_ref();
    child_str.starts_with(parent_ref) &&
    Path::new(parent_str).parent() != Path::new(child_str).parent()
}

pub fn get_selected_path(state: &State) -> Option<String> {
    let mut iter = widgets::TreeIter::new().unwrap();

    if state.tree_selection.get_selected(state.tree_model, &mut iter) {
        state.tree_model.get_value(&iter, 1).get_string()
    } else {
        None
    }
}

fn is_project_path(path: &Path) -> bool {
    path.join("Cargo.toml").exists()
}

fn is_project_root(state: &State, path: &Path) -> bool {
    if let Some(path_str) = path.to_str() {
        state.projects.contains(&path_str.to_string())
    } else {
        false
    }
}

pub fn get_project_path(state: &State, path: &Path) -> Option<PathBuf> {
    if is_project_path(path) || is_project_root(state, path) {
        Some(PathBuf::from(path))
    } else {
        if let Some(parent_path) = path.parent() {
            get_project_path(state, parent_path.deref())
        } else {
            None
        }
    }
}

pub fn get_selected_project_path(state: &State) -> Option<PathBuf> {
    if let Some(path_str) = get_selected_path(state) {
        get_project_path(state, Path::new(&path_str))
    } else {
        None
    }
}

pub fn write_prefs(state: &State) {
    let prefs = get_prefs(state);

    let mut json_str = String::new();
    {
        let mut encoder = json::Encoder::new_pretty(&mut json_str);
        prefs.encode(&mut encoder).ok().expect("Error encoding prefs.");
    }

    let prefs_path = get_home_dir().deref().join(DATA_DIR).join(PREFS_FILE);
    if let Some(mut f) = fs::File::create(&prefs_path).ok() {
        match f.write(json_str.as_bytes()) {
            Ok(_) => {},
            Err(e) => println!("Error writing prefs: {}", e)
        };
    }
}

pub fn read_prefs(state: &mut State) {
    let prefs_path = get_home_dir().deref().join(DATA_DIR).join(PREFS_FILE);
    if let Some(mut f) = fs::File::open(&prefs_path).ok() {
        let mut json_str = String::new();
        let prefs_option : Option<Prefs> = match f.read_to_string(&mut json_str) {
            Ok(_) => {
                match json::decode(json_str.as_ref()) {
                    Ok(object) => Some(object),
                    Err(e) => {
                        println!("Error decoding prefs: {}", e);
                        None
                    }
                }
            },
            Err(_) => None
        };

        if let Some(prefs) = prefs_option {
            state.projects.clear();
            for path_str in prefs.projects.iter() {
                state.projects.insert(path_str.clone());
            }

            state.expansions.clear();
            for path_str in prefs.expansions.iter() {
                state.expansions.insert(path_str.clone());
            }

            state.selection = prefs.selection;
            state.easy_mode = prefs.easy_mode;

            if (prefs.font_size >= MIN_FONT_SIZE) && (prefs.font_size <= MAX_FONT_SIZE) {
                state.font_size = prefs.font_size;
            }
        }
    }
}

fn get_settings() -> Settings {
    Settings {
        keys: ::utils::KeySettings {
            new_project: Some("p".to_string()),
            import: Some("o".to_string()),
            rename: Some("n".to_string()),
            remove: Some("g".to_string()),

            run: Some("a".to_string()),
            build: Some("k".to_string()),
            test: Some("t".to_string()),
            clean: Some("l".to_string()),
            stop: Some("i".to_string()),

            save: Some("s".to_string()),
            undo: Some("z".to_string()),
            redo: Some("r".to_string()),
            font_dec: Some("minus".to_string()),
            font_inc: Some("equal".to_string()),
            close: Some("w".to_string())
        }
    }
}

pub fn write_settings() {
    let settings_path = get_home_dir().deref().join(DATA_DIR).join(SETTINGS_FILE);
    if settings_path.exists() { // don't overwrite existing file, so user can modify it
        return;
    }

    let default_settings = get_settings();

    let mut json_str = String::new();
    {
        let mut encoder = json::Encoder::new_pretty(&mut json_str);
        default_settings.encode(&mut encoder).ok().expect("Error encoding settings.");
    }

    if let Some(mut f) = fs::File::create(&settings_path).ok() {
        match f.write(json_str.as_bytes()) {
            Ok(_) => {},
            Err(e) => println!("Error writing settings: {}", e)
        };
    }
}

pub fn read_settings() -> Settings {
    let default_settings = get_settings();
    let settings_path = get_home_dir().deref().join(DATA_DIR).join(SETTINGS_FILE);

    if let Some(mut f) = fs::File::open(&settings_path).ok() {
        let mut json_str = String::new();
        let settings_opt : Option<Settings> = match f.read_to_string(&mut json_str) {
            Ok(_) => {
                match json::decode(json_str.as_ref()) {
                    Ok(object) => Some(object),
                    Err(e) => {
                        println!("Error decoding settings: {}", e);
                        None
                    }
                }
            },
            Err(_) => None
        };

        if let Some(mut settings) = settings_opt {
            let keys = default_settings.keys;

            if let Some(key) = keys.new_project {
                settings.keys.new_project = Some(settings.keys.new_project.unwrap_or(key));
            }
            if let Some(key) = keys.import {
                settings.keys.import = Some(settings.keys.import.unwrap_or(key));
            }
            if let Some(key) = keys.rename {
                settings.keys.rename = Some(settings.keys.rename.unwrap_or(key));
            }
            if let Some(key) = keys.remove {
                settings.keys.remove = Some(settings.keys.remove.unwrap_or(key));
            }

            if let Some(key) = keys.run {
                settings.keys.run = Some(settings.keys.run.unwrap_or(key));
            }
            if let Some(key) = keys.build {
                settings.keys.build = Some(settings.keys.build.unwrap_or(key));
            }
            if let Some(key) = keys.test {
                settings.keys.test = Some(settings.keys.test.unwrap_or(key));
            }
            if let Some(key) = keys.clean {
                settings.keys.clean = Some(settings.keys.clean.unwrap_or(key));
            }
            if let Some(key) = keys.stop {
                settings.keys.stop = Some(settings.keys.stop.unwrap_or(key))
            }

            if let Some(key) = keys.save {
                settings.keys.save = Some(settings.keys.save.unwrap_or(key));
            }
            if let Some(key) = keys.undo {
                settings.keys.undo = Some(settings.keys.undo.unwrap_or(key));
            }
            if let Some(key) = keys.redo {
                settings.keys.redo = Some(settings.keys.redo.unwrap_or(key));
            }
            if let Some(key) = keys.font_dec {
                settings.keys.font_dec = Some(settings.keys.font_dec.unwrap_or(key));
            }
            if let Some(key) = keys.font_inc {
                settings.keys.font_inc = Some(settings.keys.font_inc.unwrap_or(key));
            }
            if let Some(key) = keys.close {
                settings.keys.close = Some(settings.keys.close.unwrap_or(key));
            }

            return settings;
        }
    }

    default_settings
}
<|endoftext|>


<commit_before><commit_msg>video.reorderVideos method<commit_after><|endoftext|>


<commit_before><commit_msg>Test trying<commit_after>#[test]
fn it_works() {
    assert!(false);
}<|endoftext|>


<commit_before><commit_msg>remove obsolete dead code warning workaround<commit_after><|endoftext|>


<commit_before><commit_msg>Add server header to info<commit_after><|endoftext|>


<commit_before><commit_msg>removed unused code<commit_after><|endoftext|>


<commit_before>use std::env;
use std::fs;
use std::path::Path;
use std::process::Command;

const LINUX_CLANG_DIRS: &'static [&'static str] = &[
    "/usr/lib",
    "/usr/lib/llvm",
    "/usr/lib/llvm-3.8/lib",
    "/usr/lib/llvm-3.7/lib",
    "/usr/lib/llvm-3.6/lib",
    "/usr/lib/llvm-3.5/lib",
    "/usr/lib/llvm-3.4/lib",
    "/usr/lib64/llvm",
    "/usr/lib/x86_64-linux-gnu",
];
const MAC_CLANG_DIR: &'static [&'static str] = &[
    "/usr/local/opt/llvm/lib",
    "/Library/Developer/CommandLineTools/usr/lib",
    "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib",
];
const WIN_CLANG_DIRS: &'static [&'static str] = &["C:\\Program Files\\LLVM\\bin", "C:\\Program Files\\LLVM\\lib"];

mod codegen {
    extern crate quasi_codegen;
    use std::path::Path;
    use std::env;

    pub fn main() {
        let out_dir = env::var_os("OUT_DIR").unwrap();
        let src = Path::new("src/gen.rs");
        let dst = Path::new(&out_dir).join("gen.rs");

        quasi_codegen::expand(&src, &dst).unwrap();
        println!("cargo:rerun-if-changed=src/gen.rs");
    }
}

fn main() {
    codegen::main();
    search_libclang();
}

fn search_libclang() {
    let use_static_lib = env::var_os("LIBCLANG_STATIC").is_some() || cfg!(feature = "static");

    let possible_clang_dirs = if let Ok(dir) = env::var("LIBCLANG_PATH") {
        vec![dir]
    } else if cfg!(any(target_os = "linux", target_os = "freebsd")) {
        LINUX_CLANG_DIRS.iter().map(ToString::to_string).collect()
    } else if cfg!(target_os = "macos") {
        MAC_CLANG_DIR.iter().map(ToString::to_string).collect()
    } else if cfg!(target_os = "windows") {
        WIN_CLANG_DIRS.iter().map(ToString::to_string).collect()
    } else {
        panic!("Platform not supported");
    };

    let clang_lib = if cfg!(target_os = "windows") {
        format!("libclang{}", env::consts::DLL_SUFFIX)
    } else {
        format!("{}clang{}", env::consts::DLL_PREFIX, env::consts::DLL_SUFFIX)
    };

    //may contain path to libclang detected via ldconfig
    let mut libclang_path_string = String::new();

    let mut maybe_clang_dir = possible_clang_dirs.iter().filter_map(|candidate_dir| {
        let clang_dir = Path::new(candidate_dir);
        let clang_path = clang_dir.join(clang_lib.clone());
        if path_exists(&*clang_path) {
            Some(clang_dir)
        } else {
            None
        }
    }).next();

    if maybe_clang_dir.is_none() && cfg!(target_os = "linux") {
        //try to find via lddconfig
        //may return line, like
        //libclang.so.3.7 (libc6,x86-64) => /usr/lib64/libclang.so.3.7
        let lddresult = Command::new("/sbin/ldconfig")
            .arg("-p")
            .output();
        if lddresult.is_ok() {
            let lddresult = lddresult.unwrap();
            let ldd_config_output = String::from_utf8_lossy(&lddresult.stdout).to_string();
            for line in ldd_config_output.lines() {
                let line_trim = line.trim();
                if line_trim.starts_with(&*clang_lib) {
                    let last_word = line_trim.rsplit(" ").next();
                    if let Some(last_word) = last_word {
                        let libclang_path = Path::new(last_word);
                        if path_exists(&libclang_path) {
                            libclang_path_string = last_word.to_owned();
                            maybe_clang_dir = Path::new(&libclang_path_string).parent();
                        }
                    }
                    break;
                }
            }
        }
    }

    macro_rules! qw {
        ($($i:ident)*) => (vec!($(stringify!($i)),*));
    }

    if let Some(clang_dir) = maybe_clang_dir {
        if use_static_lib {
            let libs = qw![
                LLVMAnalysis
                LLVMBitReader
                LLVMCore
                LLVMLTO
                LLVMLinker
                LLVMMC
                LLVMMCParser
                LLVMObjCARCOpts
                LLVMObject
                LLVMOption
                LLVMScalarOpts
                LLVMSupport
                LLVMTarget
                LLVMTransformUtils
                LLVMVectorize
                LLVMipa
                LLVMipo
                clang
                clangARCMigrate
                clangAST
                clangASTMatchers
                clangAnalysis
                clangBasic
                clangDriver
                clangEdit
                clangFormat
                clangFrontend
                clangIndex
                clangLex
                clangParse
                clangRewrite
                clangRewriteFrontend
                clangSema
                clangSerialization
                clangStaticAnalyzerCheckers
                clangStaticAnalyzerCore
                clangStaticAnalyzerFrontend
                clangTooling
            ];

            print!("cargo:rustc-flags=");
            for lib in libs {
                print!("-l static={} ", lib);
            }
            println!("-L {} -l ncursesw -l z -l stdc++", clang_dir.to_str().unwrap());
        } else{
            println!("cargo:rustc-link-search={}", clang_dir.to_str().unwrap());
            if !libclang_path_string.is_empty() {
                let libclang_path = Path::new(&libclang_path_string);
                println!("cargo:rustc-link-lib=dylib=:{}", libclang_path.file_name().unwrap().to_str().unwrap());
            } else {
                println!("cargo:rustc-link-lib=dylib=clang");
            }
        }
        println!("cargo:rerun-if-changed=");
    } else {
        panic!("Unable to find {}", clang_lib);
    }
}

fn path_exists(path: &Path) -> bool {
    fs::metadata(path).is_ok()
}
<commit_msg>Remove clang searching code from build.rs<commit_after>mod codegen {
    extern crate quasi_codegen;
    use std::path::Path;
    use std::env;

    pub fn main() {
        let out_dir = env::var_os("OUT_DIR").unwrap();
        let src = Path::new("src/gen.rs");
        let dst = Path::new(&out_dir).join("gen.rs");

        quasi_codegen::expand(&src, &dst).unwrap();
        println!("cargo:rerun-if-changed=src/gen.rs");
    }
}

fn main() {
    codegen::main();
}
<|endoftext|>


<commit_before><commit_msg>an empy message<commit_after><|endoftext|>