<commit_before>use std::collections::BTreeMap;

#[derive(Copy, Clone, PartialEq, Eq)]
pub enum Token {
    Output,
    Input,
    Loop,
    EndLoop,
    Move(i32),
    Add(i32, i32),
    Set(i32, i32),
    MulCopy(i32, i32, i32),
    Scan(i32),
    LoadOut(i32, i32),
    LoadOutSet(i32),
    If(i32),
    EndIf,
}
use Token::*;

pub fn parse(code: &str) -> Vec<Token> {
    let mut tokens = Vec::new();
    for i in code.chars() {
        match i {
            '+' => tokens.push(Add(0, 1)),
            '-' => tokens.push(Add(0, -1)),
            '>' => tokens.push(Move(1)),
            '<' => tokens.push(Move(-1)),
            '[' => tokens.push(Loop),
            ']' => tokens.push(EndLoop),
            ',' => tokens.push(Input),
            '.' => {
                tokens.push(LoadOut(0, 0));
                tokens.push(Output);
            },
            _ => ()
        };
    }

    tokens
    }

pub fn optimize(tokens: Vec<Token>) -> Vec<Token> {
    let mut newtokens: Vec<Token> = Vec::new();
    let mut shift = 0;
    let mut do_output = false;
    // With HashMap, the order sometimes switches
    // in recursion, and the optimizer never exits.
    let mut adds: BTreeMap<i32, i32> = BTreeMap::new();
    let mut sets: BTreeMap<i32, i32> = BTreeMap::new();
    let mut pre_loop_sets: BTreeMap<i32, i32> = BTreeMap::new();

    for token in tokens.iter() {
        let mut prev_token = match newtokens.last() {
            Some(tok) => Some(*tok),
            None => None
        };
        if *token == EndLoop && prev_token == Some(Loop) && shift == 0 && adds.contains_key(&0) {
            if adds.len() == 1 {
                newtokens.pop(); // Remove Loop
                if !sets.is_empty() {
                    newtokens.push(If(0));
                    for (offset, value) in sets.iter() {
                        newtokens.push(Set(*offset, *value));
                    }
                    sets.clear();
                    newtokens.push(Set(0, 0));
                    newtokens.push(EndIf);
                } else {
                    sets.insert(0, 0);
                }
                pre_loop_sets.clear();
                adds.clear();
                continue
            } else if adds.get(&0) == Some(&-1) {
                newtokens.pop(); // Remove Loop
                if !sets.is_empty() {
                    newtokens.push(If(0));
                    for (offset, value) in sets.iter() {
                        newtokens.push(Set(*offset, *value));
                    }
                }
                for (offset, value) in adds.iter() {
                    if *offset != 0 {
                        let src = 0;
                        let dest = *offset;
                        let mul = *value;
                        if pre_loop_sets.contains_key(&src) {
                            let val = pre_loop_sets.get(&src).unwrap() * mul;
                            newtokens.push(Add(dest, val));
                        } else {
                            newtokens.push(MulCopy(src, dest, mul));
                        }
                    }
                }
                if !sets.is_empty() {
                    newtokens.push(EndIf);
                }
                pre_loop_sets.clear();
                adds.clear();
                sets.clear();
                sets.insert(0, 0);
                continue
            }
        }

        match *token {
            Loop =>
                for (offset, value) in sets.iter() {
                    pre_loop_sets.insert(*offset+shift, *value);
                },
            Set(_, _) | Add(_, _) | Move(_) => {},
            _ => pre_loop_sets.clear()
        }

        match *token {
            Set(_, _) | Add(_, _) | Move(_) | LoadOut(_, _) | LoadOutSet(_) | Output => {},
            _ => {
               if do_output {
                   newtokens.push(Output);
                   do_output = false;
               }

               for (offset, value) in sets.iter() {
                  newtokens.push(Set(*offset, *value));
               }
               for (offset, value) in adds.iter() {
                  newtokens.push(Add(*offset, *value));
               }
               sets.clear();
               adds.clear();
            }
        }

        if shift != 0 {
           match *token {
               Loop | Input | Scan(_) => {
                   newtokens.push(Move(shift));
                   shift = 0;
               },
               _ => {}
           }
        }

        match *token {
            Set(mut offset, val) => {
                offset += shift;
                // Add before Set does nothing; remove it
                if adds.contains_key(&offset) {
                    adds.remove(&offset);
                }
                sets.insert(offset, val);
            },
            Add(mut offset, mut val) => {
                offset += shift;
                if sets.contains_key(&offset) {
                    val = sets.get(&offset).unwrap() + val;
                    sets.insert(offset, val);
                } else {
                    val = adds.get(&offset).unwrap_or(&0) + val;
                    adds.insert(offset, val);
                }
            },
            MulCopy(src, dest, mul) =>
                newtokens.push(MulCopy(src+shift, dest+shift, mul)),
            // XXX Deal with shift in if, if those are ever generated
            If(offset) =>
                newtokens.push(If(offset+shift)),
            Move(offset) =>
                shift += offset,
            Output =>
                do_output = true,
            LoadOut(mut offset, add) => {
                offset += shift;
                if sets.contains_key(&offset) {
                    newtokens.push(LoadOutSet(sets.get(&offset).unwrap() + add));
                } else {
                    newtokens.push(LoadOut(offset, adds.get(&offset).unwrap_or(&0) + add));
                }
            },
            EndLoop => {
                prev_token = match newtokens.last() {
                            Some(tok) => Some(*tok),
                            None => None
                        };
                if prev_token == Some(Loop) && shift != 0 && sets.is_empty() && adds.is_empty() {
                    newtokens.pop(); // Remove StartLoop
                    newtokens.push(Scan(shift));
                } else {
                    if shift != 0 {
                        newtokens.push(Move(shift));
                    }
                    newtokens.push(EndLoop);
                }
                shift = 0;
            },
            EndIf | LoadOutSet(_) | Loop | Input | Scan(_) =>
                newtokens.push(*token),
        }
    }

    // Any remaining add/set/shift is ignored, as it would have no effect
    if do_output {
        newtokens.push(Output);
    }

    // Optimize recursively
    if newtokens != tokens {
        optimize(newtokens)
    } else {
        newtokens
    }
}
<commit_msg>Simplification by replacing match with .map()<commit_after>use std::collections::BTreeMap;

#[derive(Copy, Clone, PartialEq, Eq)]
pub enum Token {
    Output,
    Input,
    Loop,
    EndLoop,
    Move(i32),
    Add(i32, i32),
    Set(i32, i32),
    MulCopy(i32, i32, i32),
    Scan(i32),
    LoadOut(i32, i32),
    LoadOutSet(i32),
    If(i32),
    EndIf,
}
use Token::*;

pub fn parse(code: &str) -> Vec<Token> {
    let mut tokens = Vec::new();
    for i in code.chars() {
        match i {
            '+' => tokens.push(Add(0, 1)),
            '-' => tokens.push(Add(0, -1)),
            '>' => tokens.push(Move(1)),
            '<' => tokens.push(Move(-1)),
            '[' => tokens.push(Loop),
            ']' => tokens.push(EndLoop),
            ',' => tokens.push(Input),
            '.' => {
                tokens.push(LoadOut(0, 0));
                tokens.push(Output);
            },
            _ => ()
        };
    }

    tokens
    }

pub fn optimize(tokens: Vec<Token>) -> Vec<Token> {
    let mut newtokens: Vec<Token> = Vec::new();
    let mut shift = 0;
    let mut do_output = false;
    // With HashMap, the order sometimes switches
    // in recursion, and the optimizer never exits.
    let mut adds: BTreeMap<i32, i32> = BTreeMap::new();
    let mut sets: BTreeMap<i32, i32> = BTreeMap::new();
    let mut pre_loop_sets: BTreeMap<i32, i32> = BTreeMap::new();

    for token in tokens.iter() {
        let mut prev_token = newtokens.last().map(|t| *t);
        if *token == EndLoop && prev_token == Some(Loop) && shift == 0 && adds.contains_key(&0) {
            if adds.len() == 1 {
                newtokens.pop(); // Remove Loop
                if !sets.is_empty() {
                    newtokens.push(If(0));
                    for (offset, value) in sets.iter() {
                        newtokens.push(Set(*offset, *value));
                    }
                    sets.clear();
                    newtokens.push(Set(0, 0));
                    newtokens.push(EndIf);
                } else {
                    sets.insert(0, 0);
                }
                pre_loop_sets.clear();
                adds.clear();
                continue
            } else if adds.get(&0) == Some(&-1) {
                newtokens.pop(); // Remove Loop
                if !sets.is_empty() {
                    newtokens.push(If(0));
                    for (offset, value) in sets.iter() {
                        newtokens.push(Set(*offset, *value));
                    }
                }
                for (offset, value) in adds.iter() {
                    if *offset != 0 {
                        let src = 0;
                        let dest = *offset;
                        let mul = *value;
                        if pre_loop_sets.contains_key(&src) {
                            let val = pre_loop_sets.get(&src).unwrap() * mul;
                            newtokens.push(Add(dest, val));
                        } else {
                            newtokens.push(MulCopy(src, dest, mul));
                        }
                    }
                }
                if !sets.is_empty() {
                    newtokens.push(EndIf);
                }
                pre_loop_sets.clear();
                adds.clear();
                sets.clear();
                sets.insert(0, 0);
                continue
            }
        }

        match *token {
            Loop =>
                for (offset, value) in sets.iter() {
                    pre_loop_sets.insert(*offset+shift, *value);
                },
            Set(_, _) | Add(_, _) | Move(_) => {},
            _ => pre_loop_sets.clear()
        }

        match *token {
            Set(_, _) | Add(_, _) | Move(_) | LoadOut(_, _) | LoadOutSet(_) | Output => {},
            _ => {
               if do_output {
                   newtokens.push(Output);
                   do_output = false;
               }

               for (offset, value) in sets.iter() {
                  newtokens.push(Set(*offset, *value));
               }
               for (offset, value) in adds.iter() {
                  newtokens.push(Add(*offset, *value));
               }
               sets.clear();
               adds.clear();
            }
        }

        if shift != 0 {
           match *token {
               Loop | Input | Scan(_) => {
                   newtokens.push(Move(shift));
                   shift = 0;
               },
               _ => {}
           }
        }

        match *token {
            Set(mut offset, val) => {
                offset += shift;
                // Add before Set does nothing; remove it
                if adds.contains_key(&offset) {
                    adds.remove(&offset);
                }
                sets.insert(offset, val);
            },
            Add(mut offset, mut val) => {
                offset += shift;
                if sets.contains_key(&offset) {
                    val = sets.get(&offset).unwrap() + val;
                    sets.insert(offset, val);
                } else {
                    val = adds.get(&offset).unwrap_or(&0) + val;
                    adds.insert(offset, val);
                }
            },
            MulCopy(src, dest, mul) =>
                newtokens.push(MulCopy(src+shift, dest+shift, mul)),
            // XXX Deal with shift in if, if those are ever generated
            If(offset) =>
                newtokens.push(If(offset+shift)),
            Move(offset) =>
                shift += offset,
            Output =>
                do_output = true,
            LoadOut(mut offset, add) => {
                offset += shift;
                if sets.contains_key(&offset) {
                    newtokens.push(LoadOutSet(sets.get(&offset).unwrap() + add));
                } else {
                    newtokens.push(LoadOut(offset, adds.get(&offset).unwrap_or(&0) + add));
                }
            },
            EndLoop => {
                prev_token = newtokens.last().map(|t| *t);
                if prev_token == Some(Loop) && shift != 0 && sets.is_empty() && adds.is_empty() {
                    newtokens.pop(); // Remove StartLoop
                    newtokens.push(Scan(shift));
                } else {
                    if shift != 0 {
                        newtokens.push(Move(shift));
                    }
                    newtokens.push(EndLoop);
                }
                shift = 0;
            },
            EndIf | LoadOutSet(_) | Loop | Input | Scan(_) =>
                newtokens.push(*token),
        }
    }

    // Any remaining add/set/shift is ignored, as it would have no effect
    if do_output {
        newtokens.push(Output);
    }

    // Optimize recursively
    if newtokens != tokens {
        optimize(newtokens)
    } else {
        newtokens
    }
}
<|endoftext|>


<commit_before>extern crate serde_json;
extern crate gossyp_base;
extern crate gossyp_toolkit;
extern crate gossyp_lang;

pub use gossyp_base::*;
pub use gossyp_toolkit::*;
pub use gossyp_lang::*;
<commit_msg>This might be a better way of publishing the crates?<commit_after>extern crate serde_json;
pub extern crate gossyp_base as _gossyp_base;
pub extern crate gossyp_toolkit as _gossyp_toolkit;
pub extern crate gossyp_lang as _gossyp_lang;

pub use _gossyp_base as gossyp_base;
pub use _gossyp_toolkit as gossyp_toolkit;
pub use _gossyp_lang as gossyp_lang;
<|endoftext|>


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

use std::fmt;
use std::io::Read;

const LF: u8 = b'\n';
const CR: u8 = b'\r';
const QUOTE: u8 = b'"';
const COMMA: u8 = b',';

// Error messages
const UNEXPECTED_EOL: &str = "Unexpected end of line";
const UNEXPECTED_CHAR: &str = "Unexpected character after quote";
const EXPECTED_LF: &str = "Expected linefeed after carriage return";

enum CSVState {
    Start,
    NonQuotedValue,
    QuotedValue,
    QuoteQuote,
    ExpectLF,
    Error,
}

type CSVResult = Result<CSVState, &'static str>;

impl CSVState {
    fn parse_byte(&self, byte: u8) -> CSVResult {
        match (self, byte) {
            (CSVState::Start, QUOTE) => Ok(CSVState::QuotedValue),
            (CSVState::Start, COMMA) => Ok(CSVState::Start),
            (CSVState::Start, _) => Ok(CSVState::NonQuotedValue),

            (CSVState::NonQuotedValue, COMMA) => Ok(CSVState::Start),
            (CSVState::NonQuotedValue, LF) => Ok(CSVState::Start),
            (CSVState::NonQuotedValue, CR) => Ok(CSVState::ExpectLF),
            (CSVState::NonQuotedValue, _) => Ok(CSVState::NonQuotedValue),

            (CSVState::QuotedValue, QUOTE) => Ok(CSVState::QuoteQuote),
            (CSVState::QuotedValue, CR) => Err(UNEXPECTED_EOL),
            (CSVState::QuotedValue, LF) => Err(UNEXPECTED_EOL),
            (CSVState::QuotedValue, _) => Ok(CSVState::QuotedValue),

            (CSVState::QuoteQuote, QUOTE) => Ok(CSVState::QuotedValue),
            (CSVState::QuoteQuote, COMMA) => Ok(CSVState::Start),
            (CSVState::QuoteQuote, LF) => Ok(CSVState::Start),
            (CSVState::QuoteQuote, CR) => Ok(CSVState::ExpectLF),
            (CSVState::QuoteQuote, _) => Err(UNEXPECTED_CHAR),

            (CSVState::ExpectLF, LF) => Ok(CSVState::Start),
            (CSVState::ExpectLF, _) => Err(EXPECTED_LF),

            (CSVState::Error, LF) => Ok(CSVState::Start),
            (CSVState::Error, _) => Ok(CSVState::Error),
        }
    }
}

#[cfg_attr(test, derive(Debug, PartialEq))]
pub struct CSVError {
    pub line: u32,
    pub col: u32,
    pub text: &'static str,
}

impl fmt::Display for CSVError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}:{} {}", self.line, self.col, self.text)
    }
}

pub fn csv_report(reader: impl Read) -> impl Iterator<Item = CSVError> {
    let mut line = 1;
    let mut col = 0;
    let mut state = CSVState::Start;

    reader.bytes().filter_map(move |b| {
        let byte = b.unwrap();

        match state.parse_byte(byte) {
            Ok(new_state) => {
                state = new_state;
                if byte == LF {
                    line += 1;
                    col = 0;
                } else {
                    col += 1;
                }
                None
            }
            Err(error) => {
                let err = CSVError {
                    line: line,
                    col: col,
                    text: error,
                };
                if byte == LF {
                    line += 1;
                    col = 0;
                } else {
                    col += 1;
                };
                state = match error {
                    UNEXPECTED_EOL => CSVState::Start,
                    _ => CSVState::Error,
                };
                Some(err)
            }
        }
    })
}

#[cfg(test)]
mod tests {
    use super::{csv_report, CSVError, UNEXPECTED_CHAR, UNEXPECTED_EOL};

    #[test]
    fn finds_errors_in_csv() {
        use std::fs::File;

        let mut file = File::open("tests/test.csv").unwrap();

        let mut report = csv_report(&mut file);

        assert_eq!(
            report.next(),
            Some(CSVError {
                line: 2,
                col: 13,
                text: UNEXPECTED_CHAR,
            })
        );
        assert_eq!(
            report.next(),
            Some(CSVError {
                line: 3,
                col: 28,
                text: UNEXPECTED_EOL,
            })
        );
        assert_eq!(
            report.next(),
            Some(CSVError {
                line: 5,
                col: 31,
                text: UNEXPECTED_EOL,
            })
        );
        assert_eq!(
            report.next(),
            Some(CSVError {
                line: 8,
                col: 14,
                text: UNEXPECTED_CHAR,
            })
        );
        assert_eq!(
            report.next(),
            Some(CSVError {
                line: 11,
                col: 39,
                text: UNEXPECTED_EOL,
            })
        );
        assert_eq!(
            report.next(),
            Some(CSVError {
                line: 12,
                col: 28,
                text: UNEXPECTED_EOL,
            })
        );
        assert_eq!(report.next(), None);
    }
}
<commit_msg>Use a shorthand for creating CSVError<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use std::fmt;
use std::io::Read;

const LF: u8 = b'\n';
const CR: u8 = b'\r';
const QUOTE: u8 = b'"';
const COMMA: u8 = b',';

// Error messages
const UNEXPECTED_EOL: &str = "Unexpected end of line";
const UNEXPECTED_CHAR: &str = "Unexpected character after quote";
const EXPECTED_LF: &str = "Expected linefeed after carriage return";

enum CSVState {
    Start,
    NonQuotedValue,
    QuotedValue,
    QuoteQuote,
    ExpectLF,
    Error,
}

type CSVResult = Result<CSVState, &'static str>;

impl CSVState {
    fn parse_byte(&self, byte: u8) -> CSVResult {
        match (self, byte) {
            (CSVState::Start, QUOTE) => Ok(CSVState::QuotedValue),
            (CSVState::Start, COMMA) => Ok(CSVState::Start),
            (CSVState::Start, _) => Ok(CSVState::NonQuotedValue),

            (CSVState::NonQuotedValue, COMMA) => Ok(CSVState::Start),
            (CSVState::NonQuotedValue, LF) => Ok(CSVState::Start),
            (CSVState::NonQuotedValue, CR) => Ok(CSVState::ExpectLF),
            (CSVState::NonQuotedValue, _) => Ok(CSVState::NonQuotedValue),

            (CSVState::QuotedValue, QUOTE) => Ok(CSVState::QuoteQuote),
            (CSVState::QuotedValue, CR) => Err(UNEXPECTED_EOL),
            (CSVState::QuotedValue, LF) => Err(UNEXPECTED_EOL),
            (CSVState::QuotedValue, _) => Ok(CSVState::QuotedValue),

            (CSVState::QuoteQuote, QUOTE) => Ok(CSVState::QuotedValue),
            (CSVState::QuoteQuote, COMMA) => Ok(CSVState::Start),
            (CSVState::QuoteQuote, LF) => Ok(CSVState::Start),
            (CSVState::QuoteQuote, CR) => Ok(CSVState::ExpectLF),
            (CSVState::QuoteQuote, _) => Err(UNEXPECTED_CHAR),

            (CSVState::ExpectLF, LF) => Ok(CSVState::Start),
            (CSVState::ExpectLF, _) => Err(EXPECTED_LF),

            (CSVState::Error, LF) => Ok(CSVState::Start),
            (CSVState::Error, _) => Ok(CSVState::Error),
        }
    }
}

#[cfg_attr(test, derive(Debug, PartialEq))]
pub struct CSVError {
    pub line: u32,
    pub col: u32,
    pub text: &'static str,
}

impl fmt::Display for CSVError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}:{} {}", self.line, self.col, self.text)
    }
}

pub fn csv_report(reader: impl Read) -> impl Iterator<Item = CSVError> {
    let mut line = 1;
    let mut col = 0;
    let mut state = CSVState::Start;

    reader.bytes().filter_map(move |b| {
        let byte = b.unwrap();

        match state.parse_byte(byte) {
            Ok(new_state) => {
                state = new_state;
                if byte == LF {
                    line += 1;
                    col = 0;
                } else {
                    col += 1;
                }
                None
            }
            Err(text) => {
                let err = CSVError {line, col, text};
                if byte == LF {
                    line += 1;
                    col = 0;
                } else {
                    col += 1;
                };
                state = match text {
                    UNEXPECTED_EOL => CSVState::Start,
                    _ => CSVState::Error,
                };
                Some(err)
            }
        }
    })
}

#[cfg(test)]
mod tests {
    use super::{csv_report, CSVError, UNEXPECTED_CHAR, UNEXPECTED_EOL};

    #[test]
    fn finds_errors_in_csv() {
        use std::fs::File;

        let mut file = File::open("tests/test.csv").unwrap();

        let mut report = csv_report(&mut file);

        assert_eq!(
            report.next(),
            Some(CSVError {
                line: 2,
                col: 13,
                text: UNEXPECTED_CHAR,
            })
        );
        assert_eq!(
            report.next(),
            Some(CSVError {
                line: 3,
                col: 28,
                text: UNEXPECTED_EOL,
            })
        );
        assert_eq!(
            report.next(),
            Some(CSVError {
                line: 5,
                col: 31,
                text: UNEXPECTED_EOL,
            })
        );
        assert_eq!(
            report.next(),
            Some(CSVError {
                line: 8,
                col: 14,
                text: UNEXPECTED_CHAR,
            })
        );
        assert_eq!(
            report.next(),
            Some(CSVError {
                line: 11,
                col: 39,
                text: UNEXPECTED_EOL,
            })
        );
        assert_eq!(
            report.next(),
            Some(CSVError {
                line: 12,
                col: 28,
                text: UNEXPECTED_EOL,
            })
        );
        assert_eq!(report.next(), None);
    }
}
<|endoftext|>


<commit_before>extern crate time;
extern crate num;
extern crate byteorder;
use num::BigUint;
use num::bigint::{ToBigInt};
use time::Timespec;
use time::Tm;
use std::error;
use byteorder::{LittleEndian, WriteBytesExt};

struct Flaker {
    identifier: Vec<u8>,
    epoch: u64,
    last_oxidized_in_ms: u64,
    counter: u32,
}

impl Flaker {
	pub fn new_from_identifier(identifier: Vec<u8>) -> Flaker {
		let default_epoch_ts = Timespec::new(0, 0);
		let default_epoch_ms = default_epoch_ts.sec as u64 + default_epoch_ts.nsec as u64 / 1000 / 1000;

		Flaker::new(identifier, default_epoch_ms, false)
	}

	pub fn new(identifier: Vec<u8>, epoch: u64, littleEndian: bool) -> Flaker {
		// TODO : check that identifier has a length of 6
		let mut l_identifier = identifier.clone();

		if !littleEndian {
			l_identifier.reverse();
		}

		Flaker { identifier: l_identifier,
				 epoch: epoch,
				 last_oxidized_in_ms: Flaker::current_time_in_ms(),
				 counter: 0
			   }
	}

	fn update(&mut self) -> Result<(), String> {
		let current_time_in_ms = Flaker::current_time_in_ms();

		if self.last_oxidized_in_ms > current_time_in_ms {
			return Result::Err("The clock is running backwards".to_owned());
		}

		if self.last_oxidized_in_ms < current_time_in_ms {
			self.counter = 0;
		}
		else {
			self.counter += 1;
		}

		self.last_oxidized_in_ms = current_time_in_ms;

		Ok(())
	}

	pub fn get_id(&mut self) -> BigUint {
		self.update();

		let mut bytes = Vec::new();

		bytes.push(self.counter as u8);
		bytes.push((self.counter >> 8) as u8);

		// next 6 bytes are the worker id
		for i in &self.identifier {
			bytes.push(*i);
		}

		let mut wtr = vec![];

		wtr.write_u64::<LittleEndian>(self.last_oxidized_in_ms).unwrap();

		for w in wtr {
			bytes.push(w);
		}

		BigUint::from_bytes_le(&bytes)
	}

	fn current_time_in_ms() -> u64 {
		let now = time::now();
		let now_ts = now.to_timespec();

		now_ts.sec as u64 + now_ts.nsec as u64 / 1000 / 1000
	}
}

#[test]
fn ids_change_over_time() {
	let mut f1 = Flaker::new_from_identifier(vec![0, 1, 2, 3, 4, 5]);
	let id1 = f1.get_id();
	std::thread::sleep_ms(50);
	let id2 = f1.get_id();

	println!("{} < {}", id1, id2);

	assert!(id1 < id2);
}

#[test]
fn ids_change_quickly() {
	let mut f1 = Flaker::new_from_identifier(vec![0, 1, 2, 3, 4, 5]);

	let id3 = f1.get_id();
	let id4 = f1.get_id();

	assert!(id3 < id4);
}
<commit_msg>Correcting variable name to snake case.<commit_after>extern crate time;
extern crate num;
extern crate byteorder;
use num::BigUint;
use num::bigint::{ToBigInt};
use time::Timespec;
use time::Tm;
use std::error;
use byteorder::{LittleEndian, WriteBytesExt};

struct Flaker {
    identifier: Vec<u8>,
    epoch: u64,
    last_oxidized_in_ms: u64,
    counter: u32,
}

impl Flaker {
	pub fn new_from_identifier(identifier: Vec<u8>) -> Flaker {
		let default_epoch_ts = Timespec::new(0, 0);
		let default_epoch_ms = default_epoch_ts.sec as u64 + default_epoch_ts.nsec as u64 / 1000 / 1000;

		Flaker::new(identifier, default_epoch_ms, false)
	}

	pub fn new(identifier: Vec<u8>, epoch: u64, little_endian: bool) -> Flaker {
		// TODO : check that identifier has a length of 6
		let mut l_identifier = identifier.clone();

		if !little_endian {
			l_identifier.reverse();
		}

		Flaker { identifier: l_identifier,
				 epoch: epoch,
				 last_oxidized_in_ms: Flaker::current_time_in_ms(),
				 counter: 0
			   }
	}

	fn update(&mut self) -> Result<(), String> {
		let current_time_in_ms = Flaker::current_time_in_ms();

		if self.last_oxidized_in_ms > current_time_in_ms {
			return Result::Err("The clock is running backwards".to_owned());
		}

		if self.last_oxidized_in_ms < current_time_in_ms {
			self.counter = 0;
		}
		else {
			self.counter += 1;
		}

		self.last_oxidized_in_ms = current_time_in_ms;

		Ok(())
	}

	pub fn get_id(&mut self) -> BigUint {
		self.update();

		let mut bytes = Vec::new();

		bytes.push(self.counter as u8);
		bytes.push((self.counter >> 8) as u8);

		// next 6 bytes are the worker id
		for i in &self.identifier {
			bytes.push(*i);
		}

		let mut wtr = vec![];

		wtr.write_u64::<LittleEndian>(self.last_oxidized_in_ms).unwrap();

		for w in wtr {
			bytes.push(w);
		}

		BigUint::from_bytes_le(&bytes)
	}

	fn current_time_in_ms() -> u64 {
		let now = time::now();
		let now_ts = now.to_timespec();

		now_ts.sec as u64 + now_ts.nsec as u64 / 1000 / 1000
	}
}

#[test]
fn ids_change_over_time() {
	let mut f1 = Flaker::new_from_identifier(vec![0, 1, 2, 3, 4, 5]);
	let id1 = f1.get_id();
	std::thread::sleep_ms(50);
	let id2 = f1.get_id();

	println!("{} < {}", id1, id2);

	assert!(id1 < id2);
}

#[test]
fn ids_change_quickly() {
	let mut f1 = Flaker::new_from_identifier(vec![0, 1, 2, 3, 4, 5]);

	let id3 = f1.get_id();
	let id4 = f1.get_id();

	assert!(id3 < id4);
}
<|endoftext|>


<commit_before>#![feature(
    rustc_private,
    decl_macro,
    type_alias_impl_trait,
    associated_type_bounds,
    never_type,
    try_blocks,
    box_patterns,
    hash_drain_filter
)]
#![warn(rust_2018_idioms)]
#![warn(unused_lifetimes)]
#![warn(unreachable_pub)]
#![feature(box_patterns)]

extern crate snap;
#[macro_use]
extern crate rustc_middle;
extern crate rustc_ast;
extern crate rustc_codegen_ssa;
extern crate rustc_data_structures;
extern crate rustc_errors;
extern crate rustc_fs_util;
extern crate rustc_hir;
extern crate rustc_incremental;
extern crate rustc_index;
extern crate rustc_session;
extern crate rustc_span;
extern crate rustc_target;

// This prevents duplicating functions and statics that are already part of the host rustc process.
#[allow(unused_extern_crates)]
extern crate rustc_driver;

use std::any::Any;
use std::str::FromStr;

use rustc_codegen_ssa::traits::CodegenBackend;
use rustc_codegen_ssa::CodegenResults;
use rustc_errors::ErrorReported;
use rustc_middle::dep_graph::{WorkProduct, WorkProductId};
use rustc_middle::middle::cstore::{EncodedMetadata, MetadataLoader};
use rustc_middle::ty::query::Providers;
use rustc_session::config::OutputFilenames;
use rustc_session::Session;

use cranelift_codegen::settings::{self, Configurable};

use crate::constant::ConstantCx;
use crate::prelude::*;

mod abi;
mod allocator;
mod analyze;
mod archive;
mod backend;
mod base;
mod cast;
mod codegen_i128;
mod common;
mod constant;
mod debuginfo;
mod discriminant;
mod driver;
mod inline_asm;
mod intrinsics;
mod linkage;
mod main_shim;
mod metadata;
mod num;
mod optimize;
mod pointer;
mod pretty_clif;
mod toolchain;
mod trap;
mod unsize;
mod value_and_place;
mod vtable;

mod prelude {
    pub(crate) use std::convert::{TryFrom, TryInto};

    pub(crate) use rustc_span::Span;

    pub(crate) use rustc_hir::def_id::{DefId, LOCAL_CRATE};
    pub(crate) use rustc_middle::bug;
    pub(crate) use rustc_middle::mir::{self, *};
    pub(crate) use rustc_middle::ty::layout::{self, TyAndLayout};
    pub(crate) use rustc_middle::ty::{
        self, FloatTy, Instance, InstanceDef, IntTy, ParamEnv, Ty, TyCtxt, TypeAndMut,
        TypeFoldable, UintTy,
    };
    pub(crate) use rustc_target::abi::{Abi, LayoutOf, Scalar, Size, VariantIdx};

    pub(crate) use rustc_data_structures::fx::FxHashMap;

    pub(crate) use rustc_index::vec::Idx;

    pub(crate) use cranelift_codegen::entity::EntitySet;
    pub(crate) use cranelift_codegen::ir::condcodes::{FloatCC, IntCC};
    pub(crate) use cranelift_codegen::ir::function::Function;
    pub(crate) use cranelift_codegen::ir::types;
    pub(crate) use cranelift_codegen::ir::{
        AbiParam, Block, ExternalName, FuncRef, Inst, InstBuilder, MemFlags, Signature, SourceLoc,
        StackSlot, StackSlotData, StackSlotKind, TrapCode, Type, Value,
    };
    pub(crate) use cranelift_codegen::isa::{self, CallConv};
    pub(crate) use cranelift_codegen::Context;
    pub(crate) use cranelift_frontend::{FunctionBuilder, FunctionBuilderContext, Variable};
    pub(crate) use cranelift_module::{self, DataContext, DataId, FuncId, Linkage, Module};

    pub(crate) use crate::abi::*;
    pub(crate) use crate::base::{codegen_operand, codegen_place};
    pub(crate) use crate::cast::*;
    pub(crate) use crate::common::*;
    pub(crate) use crate::debuginfo::{DebugContext, UnwindContext};
    pub(crate) use crate::pointer::Pointer;
    pub(crate) use crate::trap::*;
    pub(crate) use crate::value_and_place::{CPlace, CPlaceInner, CValue};
}

struct PrintOnPanic<F: Fn() -> String>(F);
impl<F: Fn() -> String> Drop for PrintOnPanic<F> {
    fn drop(&mut self) {
        if ::std::thread::panicking() {
            println!("{}", (self.0)());
        }
    }
}

struct CodegenCx<'m, 'tcx: 'm> {
    tcx: TyCtxt<'tcx>,
    module: &'m mut dyn Module,
    global_asm: String,
    constants_cx: ConstantCx,
    cached_context: Context,
    vtables: FxHashMap<(Ty<'tcx>, Option<ty::PolyExistentialTraitRef<'tcx>>), DataId>,
    debug_context: Option<DebugContext<'tcx>>,
    unwind_context: UnwindContext<'tcx>,
}

impl<'m, 'tcx> CodegenCx<'m, 'tcx> {
    fn new(
        tcx: TyCtxt<'tcx>,
        backend_config: BackendConfig,
        module: &'m mut dyn Module,
        debug_info: bool,
    ) -> Self {
        let unwind_context = UnwindContext::new(
            tcx,
            module.isa(),
            matches!(backend_config.codegen_mode, CodegenMode::Aot),
        );
        let debug_context =
            if debug_info { Some(DebugContext::new(tcx, module.isa())) } else { None };
        CodegenCx {
            tcx,
            module,
            global_asm: String::new(),
            constants_cx: ConstantCx::default(),
            cached_context: Context::new(),
            vtables: FxHashMap::default(),
            debug_context,
            unwind_context,
        }
    }

    fn finalize(self) -> (String, Option<DebugContext<'tcx>>, UnwindContext<'tcx>) {
        self.constants_cx.finalize(self.tcx, self.module);
        (self.global_asm, self.debug_context, self.unwind_context)
    }
}

#[derive(Copy, Clone, Debug)]
pub enum CodegenMode {
    Aot,
    Jit,
    JitLazy,
}

impl Default for CodegenMode {
    fn default() -> Self {
        CodegenMode::Aot
    }
}

impl FromStr for CodegenMode {
    type Err = String;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        match s {
            "aot" => Ok(CodegenMode::Aot),
            "jit" => Ok(CodegenMode::Jit),
            "jit-lazy" => Ok(CodegenMode::JitLazy),
            _ => Err(format!("Unknown codegen mode `{}`", s)),
        }
    }
}

#[derive(Copy, Clone, Debug, Default)]
pub struct BackendConfig {
    pub codegen_mode: CodegenMode,
}

impl BackendConfig {
    fn from_opts(opts: &[String]) -> Result<Self, String> {
        let mut config = BackendConfig::default();
        for opt in opts {
            if let Some((name, value)) = opt.split_once('=') {
                match name {
                    "mode" => config.codegen_mode = value.parse()?,
                    _ => return Err(format!("Unknown option `{}`", name)),
                }
            } else {
                return Err(format!("Invalid option `{}`", opt));
            }
        }
        Ok(config)
    }
}

pub struct CraneliftCodegenBackend {
    pub config: Option<BackendConfig>,
}

impl CodegenBackend for CraneliftCodegenBackend {
    fn init(&self, sess: &Session) {
        if sess.lto() != rustc_session::config::Lto::No && sess.opts.cg.embed_bitcode {
            sess.warn("LTO is not supported. You may get a linker error.");
        }
    }

    fn metadata_loader(&self) -> Box<dyn MetadataLoader + Sync> {
        Box::new(crate::metadata::CraneliftMetadataLoader)
    }

    fn provide(&self, _providers: &mut Providers) {}
    fn provide_extern(&self, _providers: &mut Providers) {}

    fn target_features(&self, _sess: &Session) -> Vec<rustc_span::Symbol> {
        vec![]
    }

    fn codegen_crate<'tcx>(
        &self,
        tcx: TyCtxt<'tcx>,
        metadata: EncodedMetadata,
        need_metadata_module: bool,
    ) -> Box<dyn Any> {
        let config = if let Some(config) = self.config {
            config
        } else {
            BackendConfig::from_opts(&tcx.sess.opts.cg.llvm_args)
                .unwrap_or_else(|err| tcx.sess.fatal(&err))
        };
        let res = driver::codegen_crate(tcx, metadata, need_metadata_module, config);

        res
    }

    fn join_codegen(
        &self,
        ongoing_codegen: Box<dyn Any>,
        _sess: &Session,
    ) -> Result<(CodegenResults, FxHashMap<WorkProductId, WorkProduct>), ErrorReported> {
        Ok(*ongoing_codegen
            .downcast::<(CodegenResults, FxHashMap<WorkProductId, WorkProduct>)>()
            .unwrap())
    }

    fn link(
        &self,
        sess: &Session,
        codegen_results: CodegenResults,
        outputs: &OutputFilenames,
    ) -> Result<(), ErrorReported> {
        use rustc_codegen_ssa::back::link::link_binary;

        let target_cpu = crate::target_triple(sess).to_string();
        link_binary::<crate::archive::ArArchiveBuilder<'_>>(
            sess,
            &codegen_results,
            outputs,
            &codegen_results.crate_name.as_str(),
            &target_cpu,
        );

        Ok(())
    }
}

fn target_triple(sess: &Session) -> target_lexicon::Triple {
    sess.target.llvm_target.parse().unwrap()
}

fn build_isa(sess: &Session) -> Box<dyn isa::TargetIsa + 'static> {
    use target_lexicon::BinaryFormat;

    let target_triple = crate::target_triple(sess);

    let mut flags_builder = settings::builder();
    flags_builder.enable("is_pic").unwrap();
    flags_builder.set("enable_probestack", "false").unwrap(); // __cranelift_probestack is not provided
    flags_builder
        .set("enable_verifier", if cfg!(debug_assertions) { "true" } else { "false" })
        .unwrap();

    let tls_model = match target_triple.binary_format {
        BinaryFormat::Elf => "elf_gd",
        BinaryFormat::Macho => "macho",
        BinaryFormat::Coff => "coff",
        _ => "none",
    };
    flags_builder.set("tls_model", tls_model).unwrap();

    flags_builder.set("enable_simd", "true").unwrap();

    use rustc_session::config::OptLevel;
    match sess.opts.optimize {
        OptLevel::No => {
            flags_builder.set("opt_level", "none").unwrap();
        }
        OptLevel::Less | OptLevel::Default => {}
        OptLevel::Aggressive => {
            flags_builder.set("opt_level", "speed_and_size").unwrap();
        }
        OptLevel::Size | OptLevel::SizeMin => {
            sess.warn("Optimizing for size is not supported. Just ignoring the request");
        }
    }

    let flags = settings::Flags::new(flags_builder);

    let variant = cranelift_codegen::isa::BackendVariant::MachInst;
    let mut isa_builder = cranelift_codegen::isa::lookup_variant(target_triple, variant).unwrap();
    // Don't use "haswell", as it implies `has_lzcnt`.macOS CI is still at Ivy Bridge EP, so `lzcnt`
    // is interpreted as `bsr`.
    isa_builder.enable("nehalem").unwrap();
    isa_builder.finish(flags)
}

/// This is the entrypoint for a hot plugged rustc_codegen_cranelift
#[no_mangle]
pub fn __rustc_codegen_backend() -> Box<dyn CodegenBackend> {
    Box::new(CraneliftCodegenBackend { config: None })
}
<commit_msg>Clean up todos<commit_after>#![feature(
    rustc_private,
    decl_macro,
    type_alias_impl_trait,
    associated_type_bounds,
    never_type,
    try_blocks,
    box_patterns,
    hash_drain_filter
)]
#![warn(rust_2018_idioms)]
#![warn(unused_lifetimes)]
#![warn(unreachable_pub)]

extern crate snap;
#[macro_use]
extern crate rustc_middle;
extern crate rustc_ast;
extern crate rustc_codegen_ssa;
extern crate rustc_data_structures;
extern crate rustc_errors;
extern crate rustc_fs_util;
extern crate rustc_hir;
extern crate rustc_incremental;
extern crate rustc_index;
extern crate rustc_session;
extern crate rustc_span;
extern crate rustc_target;

// This prevents duplicating functions and statics that are already part of the host rustc process.
#[allow(unused_extern_crates)]
extern crate rustc_driver;

use std::any::Any;
use std::str::FromStr;

use rustc_codegen_ssa::traits::CodegenBackend;
use rustc_codegen_ssa::CodegenResults;
use rustc_errors::ErrorReported;
use rustc_middle::dep_graph::{WorkProduct, WorkProductId};
use rustc_middle::middle::cstore::{EncodedMetadata, MetadataLoader};
use rustc_middle::ty::query::Providers;
use rustc_session::config::OutputFilenames;
use rustc_session::Session;

use cranelift_codegen::settings::{self, Configurable};

use crate::constant::ConstantCx;
use crate::prelude::*;

mod abi;
mod allocator;
mod analyze;
mod archive;
mod backend;
mod base;
mod cast;
mod codegen_i128;
mod common;
mod constant;
mod debuginfo;
mod discriminant;
mod driver;
mod inline_asm;
mod intrinsics;
mod linkage;
mod main_shim;
mod metadata;
mod num;
mod optimize;
mod pointer;
mod pretty_clif;
mod toolchain;
mod trap;
mod unsize;
mod value_and_place;
mod vtable;

mod prelude {
    pub(crate) use std::convert::{TryFrom, TryInto};

    pub(crate) use rustc_span::Span;

    pub(crate) use rustc_hir::def_id::{DefId, LOCAL_CRATE};
    pub(crate) use rustc_middle::bug;
    pub(crate) use rustc_middle::mir::{self, *};
    pub(crate) use rustc_middle::ty::layout::{self, TyAndLayout};
    pub(crate) use rustc_middle::ty::{
        self, FloatTy, Instance, InstanceDef, IntTy, ParamEnv, Ty, TyCtxt, TypeAndMut,
        TypeFoldable, UintTy,
    };
    pub(crate) use rustc_target::abi::{Abi, LayoutOf, Scalar, Size, VariantIdx};

    pub(crate) use rustc_data_structures::fx::FxHashMap;

    pub(crate) use rustc_index::vec::Idx;

    pub(crate) use cranelift_codegen::entity::EntitySet;
    pub(crate) use cranelift_codegen::ir::condcodes::{FloatCC, IntCC};
    pub(crate) use cranelift_codegen::ir::function::Function;
    pub(crate) use cranelift_codegen::ir::types;
    pub(crate) use cranelift_codegen::ir::{
        AbiParam, Block, ExternalName, FuncRef, Inst, InstBuilder, MemFlags, Signature, SourceLoc,
        StackSlot, StackSlotData, StackSlotKind, TrapCode, Type, Value,
    };
    pub(crate) use cranelift_codegen::isa::{self, CallConv};
    pub(crate) use cranelift_codegen::Context;
    pub(crate) use cranelift_frontend::{FunctionBuilder, FunctionBuilderContext, Variable};
    pub(crate) use cranelift_module::{self, DataContext, DataId, FuncId, Linkage, Module};

    pub(crate) use crate::abi::*;
    pub(crate) use crate::base::{codegen_operand, codegen_place};
    pub(crate) use crate::cast::*;
    pub(crate) use crate::common::*;
    pub(crate) use crate::debuginfo::{DebugContext, UnwindContext};
    pub(crate) use crate::pointer::Pointer;
    pub(crate) use crate::trap::*;
    pub(crate) use crate::value_and_place::{CPlace, CPlaceInner, CValue};
}

struct PrintOnPanic<F: Fn() -> String>(F);
impl<F: Fn() -> String> Drop for PrintOnPanic<F> {
    fn drop(&mut self) {
        if ::std::thread::panicking() {
            println!("{}", (self.0)());
        }
    }
}

struct CodegenCx<'m, 'tcx: 'm> {
    tcx: TyCtxt<'tcx>,
    module: &'m mut dyn Module,
    global_asm: String,
    constants_cx: ConstantCx,
    cached_context: Context,
    vtables: FxHashMap<(Ty<'tcx>, Option<ty::PolyExistentialTraitRef<'tcx>>), DataId>,
    debug_context: Option<DebugContext<'tcx>>,
    unwind_context: UnwindContext<'tcx>,
}

impl<'m, 'tcx> CodegenCx<'m, 'tcx> {
    fn new(
        tcx: TyCtxt<'tcx>,
        backend_config: BackendConfig,
        module: &'m mut dyn Module,
        debug_info: bool,
    ) -> Self {
        let unwind_context = UnwindContext::new(
            tcx,
            module.isa(),
            matches!(backend_config.codegen_mode, CodegenMode::Aot),
        );
        let debug_context =
            if debug_info { Some(DebugContext::new(tcx, module.isa())) } else { None };
        CodegenCx {
            tcx,
            module,
            global_asm: String::new(),
            constants_cx: ConstantCx::default(),
            cached_context: Context::new(),
            vtables: FxHashMap::default(),
            debug_context,
            unwind_context,
        }
    }

    fn finalize(self) -> (String, Option<DebugContext<'tcx>>, UnwindContext<'tcx>) {
        self.constants_cx.finalize(self.tcx, self.module);
        (self.global_asm, self.debug_context, self.unwind_context)
    }
}

#[derive(Copy, Clone, Debug)]
pub enum CodegenMode {
    Aot,
    Jit,
    JitLazy,
}

impl Default for CodegenMode {
    fn default() -> Self {
        CodegenMode::Aot
    }
}

impl FromStr for CodegenMode {
    type Err = String;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        match s {
            "aot" => Ok(CodegenMode::Aot),
            "jit" => Ok(CodegenMode::Jit),
            "jit-lazy" => Ok(CodegenMode::JitLazy),
            _ => Err(format!("Unknown codegen mode `{}`", s)),
        }
    }
}

#[derive(Copy, Clone, Debug, Default)]
pub struct BackendConfig {
    pub codegen_mode: CodegenMode,
}

impl BackendConfig {
    fn from_opts(opts: &[String]) -> Result<Self, String> {
        let mut config = BackendConfig::default();
        for opt in opts {
            if let Some((name, value)) = opt.split_once('=') {
                match name {
                    "mode" => config.codegen_mode = value.parse()?,
                    _ => return Err(format!("Unknown option `{}`", name)),
                }
            } else {
                return Err(format!("Invalid option `{}`", opt));
            }
        }
        Ok(config)
    }
}

pub struct CraneliftCodegenBackend {
    pub config: Option<BackendConfig>,
}

impl CodegenBackend for CraneliftCodegenBackend {
    fn init(&self, sess: &Session) {
        if sess.lto() != rustc_session::config::Lto::No && sess.opts.cg.embed_bitcode {
            sess.warn("LTO is not supported. You may get a linker error.");
        }
    }

    fn metadata_loader(&self) -> Box<dyn MetadataLoader + Sync> {
        Box::new(crate::metadata::CraneliftMetadataLoader)
    }

    fn provide(&self, _providers: &mut Providers) {}
    fn provide_extern(&self, _providers: &mut Providers) {}

    fn target_features(&self, _sess: &Session) -> Vec<rustc_span::Symbol> {
        vec![]
    }

    fn codegen_crate<'tcx>(
        &self,
        tcx: TyCtxt<'tcx>,
        metadata: EncodedMetadata,
        need_metadata_module: bool,
    ) -> Box<dyn Any> {
        let config = if let Some(config) = self.config {
            config
        } else {
            BackendConfig::from_opts(&tcx.sess.opts.cg.llvm_args)
                .unwrap_or_else(|err| tcx.sess.fatal(&err))
        };
        let res = driver::codegen_crate(tcx, metadata, need_metadata_module, config);

        res
    }

    fn join_codegen(
        &self,
        ongoing_codegen: Box<dyn Any>,
        _sess: &Session,
    ) -> Result<(CodegenResults, FxHashMap<WorkProductId, WorkProduct>), ErrorReported> {
        Ok(*ongoing_codegen
            .downcast::<(CodegenResults, FxHashMap<WorkProductId, WorkProduct>)>()
            .unwrap())
    }

    fn link(
        &self,
        sess: &Session,
        codegen_results: CodegenResults,
        outputs: &OutputFilenames,
    ) -> Result<(), ErrorReported> {
        use rustc_codegen_ssa::back::link::link_binary;

        let target_cpu = crate::target_triple(sess).to_string();
        link_binary::<crate::archive::ArArchiveBuilder<'_>>(
            sess,
            &codegen_results,
            outputs,
            &codegen_results.crate_name.as_str(),
            &target_cpu,
        );

        Ok(())
    }
}

fn target_triple(sess: &Session) -> target_lexicon::Triple {
    sess.target.llvm_target.parse().unwrap()
}

fn build_isa(sess: &Session) -> Box<dyn isa::TargetIsa + 'static> {
    use target_lexicon::BinaryFormat;

    let target_triple = crate::target_triple(sess);

    let mut flags_builder = settings::builder();
    flags_builder.enable("is_pic").unwrap();
    flags_builder.set("enable_probestack", "false").unwrap(); // __cranelift_probestack is not provided
    flags_builder
        .set("enable_verifier", if cfg!(debug_assertions) { "true" } else { "false" })
        .unwrap();

    let tls_model = match target_triple.binary_format {
        BinaryFormat::Elf => "elf_gd",
        BinaryFormat::Macho => "macho",
        BinaryFormat::Coff => "coff",
        _ => "none",
    };
    flags_builder.set("tls_model", tls_model).unwrap();

    flags_builder.set("enable_simd", "true").unwrap();

    use rustc_session::config::OptLevel;
    match sess.opts.optimize {
        OptLevel::No => {
            flags_builder.set("opt_level", "none").unwrap();
        }
        OptLevel::Less | OptLevel::Default => {}
        OptLevel::Aggressive => {
            flags_builder.set("opt_level", "speed_and_size").unwrap();
        }
        OptLevel::Size | OptLevel::SizeMin => {
            sess.warn("Optimizing for size is not supported. Just ignoring the request");
        }
    }

    let flags = settings::Flags::new(flags_builder);

    let variant = cranelift_codegen::isa::BackendVariant::MachInst;
    let mut isa_builder = cranelift_codegen::isa::lookup_variant(target_triple, variant).unwrap();
    // Don't use "haswell", as it implies `has_lzcnt`.macOS CI is still at Ivy Bridge EP, so `lzcnt`
    // is interpreted as `bsr`.
    isa_builder.enable("nehalem").unwrap();
    isa_builder.finish(flags)
}

/// This is the entrypoint for a hot plugged rustc_codegen_cranelift
#[no_mangle]
pub fn __rustc_codegen_backend() -> Box<dyn CodegenBackend> {
    Box::new(CraneliftCodegenBackend { config: None })
}
<|endoftext|>


<commit_before>#[cfg(test)]
mod tests {
    #[test]
    fn it_works() {
    }
}
<commit_msg>remove placeholder test for now<commit_after><|endoftext|>


<commit_before>#![feature(collections)]

#[macro_use] mod macros;
mod std_impls;

pub trait Collection {
    /// Removes all items from the collection.
    fn clear(&mut self);

    /// Checks if the collection is empty.
    fn is_empty(&self) -> bool { self.len() == 0 }

    /// Returns the number of items in the collection.
    fn len(&self) -> usize;
}

pub trait Map: Collection + MapLookup<<Self as Map>::Key, MapValue=<Self as Map>::Value> {
    /// The map's key type.
    type Key;
    /// The map's value type.
    type Value;

    /// Inserts the given key and value into the map, returning the previous value associated with
    /// the key, or `None` if the map did not already contain the key.
    fn insert(&mut self, key: Self::Key, value: Self::Value) -> Option<Self::Value>;
}

pub trait MapLookup<Q: ?Sized> {
    type MapValue;

    /// Checks if the map contains the given key.
    fn contains_key(&self, key: &Q) -> bool { self.get(key).is_some() }

    /// Returns a reference to the value associated with the given key in the map, or `None` if
    /// the map does not contain the key.
    fn get(&self, key: &Q) -> Option<&Self::MapValue>;

    /// Returns a mutable reference to the value associated with the given key in the map, or
    /// `None` if the map does not contain the key.
    fn get_mut(&mut self, key: &Q) -> Option<&mut Self::MapValue>;

    /// Removes the given key from the map, returning the value associated with it, or `None` if
    /// the map did not contain the key.
    fn remove(&mut self, key: &Q) -> Option<Self::MapValue>;
}

pub trait EntryMap<'a>: Map {
    type Occupied: OccupiedEntry<'a, Value=Self::Value>;
    type Vacant: VacantEntry<'a, Value=Self::Value>;

    /// Returns the given key's corresponding entry in the map for in-place manipulation.
    fn entry(&'a mut self, key: Self::Key) -> Entry<Self::Occupied, Self::Vacant>;
}

pub enum Entry<O, V> {
    Occupied(O),
    Vacant(V),
}

impl<'a, O, V> Entry<O, V> where O: OccupiedEntry<'a>, V: VacantEntry<'a, Value=O::Value> {
    /// Returns a mutable reference to the entry's value if it is occupied, or the vacant entry if
    /// it is vacant.
    pub fn get(self) -> Result<&'a mut O::Value, V> {
        match self {
            Entry::Occupied(e) => Ok(e.into_mut()),
            Entry::Vacant(e) => Err(e),
        }
    }
}

pub trait OccupiedEntry<'a> {
    type Value: 'a;

    /// Returns a reference to the entry's value.
    fn get(&self) -> &Self::Value;

    /// Returns a mutable reference to the entry's value.
    fn get_mut(&mut self) -> &mut Self::Value;

    /// Sets the entry's value to the given one, returning the old value.
    fn insert(&mut self, value: Self::Value) -> Self::Value;

    /// Returns a mutable reference to the entry's value with the lifetime of the map.
    fn into_mut(self) -> &'a mut Self::Value;

    /// Removes the entry, returning its value.
    fn remove(self) -> Self::Value;
}

pub trait VacantEntry<'a> {
    type Value: 'a;

    /// Sets the entry's value to the given one, returning a mutable reference to the value with
    /// the lifetime of the map.
    fn insert(self, value: Self::Value) -> &'a mut Self::Value;
}

pub trait Set: Collection + SetLookup<<Self as Set>::Item> {
    type Item;

    /// Inserts the given item into the set, returning `true` if the set did not already contain
    /// the item.
    fn insert(&mut self, item: Self::Item) -> bool;
}

pub trait SetLookup<Q: ?Sized> {
    /// Checks if the set contains the given item.
    fn contains(&self, item: &Q) -> bool;

    /// Removes the given item from the set, returning `true` if the set contained the item.
    fn remove(&mut self, item: &Q) -> bool;
}
<commit_msg>add entry API v3<commit_after>#![feature(collections)]

#[macro_use] mod macros;
mod std_impls;

pub trait Collection {
    /// Removes all items from the collection.
    fn clear(&mut self);

    /// Checks if the collection is empty.
    fn is_empty(&self) -> bool { self.len() == 0 }

    /// Returns the number of items in the collection.
    fn len(&self) -> usize;
}

pub trait Map: Collection + MapLookup<<Self as Map>::Key, MapValue=<Self as Map>::Value> {
    /// The map's key type.
    type Key;
    /// The map's value type.
    type Value;

    /// Inserts the given key and value into the map, returning the previous value associated with
    /// the key, or `None` if the map did not already contain the key.
    fn insert(&mut self, key: Self::Key, value: Self::Value) -> Option<Self::Value>;
}

pub trait MapLookup<Q: ?Sized> {
    type MapValue;

    /// Checks if the map contains the given key.
    fn contains_key(&self, key: &Q) -> bool { self.get(key).is_some() }

    /// Returns a reference to the value associated with the given key in the map, or `None` if
    /// the map does not contain the key.
    fn get(&self, key: &Q) -> Option<&Self::MapValue>;

    /// Returns a mutable reference to the value associated with the given key in the map, or
    /// `None` if the map does not contain the key.
    fn get_mut(&mut self, key: &Q) -> Option<&mut Self::MapValue>;

    /// Removes the given key from the map, returning the value associated with it, or `None` if
    /// the map did not contain the key.
    fn remove(&mut self, key: &Q) -> Option<Self::MapValue>;
}

pub trait EntryMap<'a>: Map {
    type Occupied: OccupiedEntry<'a, Value=Self::Value>;
    type Vacant: VacantEntry<'a, Value=Self::Value>;

    /// Returns the given key's corresponding entry in the map for in-place manipulation.
    fn entry(&'a mut self, key: Self::Key) -> Entry<Self::Occupied, Self::Vacant>;
}

pub enum Entry<O, V> {
    Occupied(O),
    Vacant(V),
}

impl<'a, O, V> Entry<O, V> where O: OccupiedEntry<'a>, V: VacantEntry<'a, Value=O::Value> {
    /// Returns a mutable reference to the entry's value if it is occupied, or the vacant entry if
    /// it is vacant.
    pub fn get(self) -> Result<&'a mut O::Value, V> {
        match self {
            Entry::Occupied(e) => Ok(e.into_mut()),
            Entry::Vacant(e) => Err(e),
        }
    }

    /// Ensures that a value is in the entry by inserting the default if it is empty, and returns a
    /// mutable reference to the value.
    pub fn or_insert(self, default: O::Value) -> &'a mut O::Value {
        match self {
            Entry::Occupied(e) => e.into_mut(),
            Entry::Vacant(e) => e.insert(default),
        }
    }

    /// Ensures that a value is in the entry by inserting the result of the default function if it
    /// is empty, and returns a mutable reference to the value.
    pub fn or_insert_with<F>(self, default: F) -> &'a mut O::Value where F: FnOnce() -> O::Value {
        match self {
            Entry::Occupied(e) => e.into_mut(),
            Entry::Vacant(e) => e.insert(default()),
        }
    }
}

pub trait OccupiedEntry<'a> {
    type Value: 'a;

    /// Returns a reference to the entry's value.
    fn get(&self) -> &Self::Value;

    /// Returns a mutable reference to the entry's value.
    fn get_mut(&mut self) -> &mut Self::Value;

    /// Sets the entry's value to the given one, returning the old value.
    fn insert(&mut self, value: Self::Value) -> Self::Value;

    /// Returns a mutable reference to the entry's value with the lifetime of the map.
    fn into_mut(self) -> &'a mut Self::Value;

    /// Removes the entry, returning its value.
    fn remove(self) -> Self::Value;
}

pub trait VacantEntry<'a> {
    type Value: 'a;

    /// Sets the entry's value to the given one, returning a mutable reference to the value with
    /// the lifetime of the map.
    fn insert(self, value: Self::Value) -> &'a mut Self::Value;
}

pub trait Set: Collection + SetLookup<<Self as Set>::Item> {
    type Item;

    /// Inserts the given item into the set, returning `true` if the set did not already contain
    /// the item.
    fn insert(&mut self, item: Self::Item) -> bool;
}

pub trait SetLookup<Q: ?Sized> {
    /// Checks if the set contains the given item.
    fn contains(&self, item: &Q) -> bool;

    /// Removes the given item from the set, returning `true` if the set contained the item.
    fn remove(&mut self, item: &Q) -> bool;
}
<|endoftext|>


<commit_before>#![crate_type = "rlib"]
#![crate_name = "cripes"]

#![feature(alloc)]
#![feature(core)]
#![feature(hash)]

use std::slice::bytes;

/// Utility wrapper for `std::slice::bytes::copy_memory` that retains C's
/// `memcpy` argument-order semantics.
#[inline(always)]
fn memcpy(dest: &mut [u8], src: &[u8]) {
    bytes::copy_memory(src, dest)
}

#[macro_use]
pub mod util;

#[macro_use]
pub mod symbol;
pub mod pattern;
<commit_msg>src/lib.rs: use `#![feature(unstable)]`<commit_after>#![feature(unstable)]
#![crate_type = "rlib"]
#![crate_name = "cripes"]

#![feature(alloc)]
#![feature(core)]
#![feature(hash)]

use std::slice::bytes;

/// Utility wrapper for `std::slice::bytes::copy_memory` that retains C's
/// `memcpy` argument-order semantics.
#[inline(always)]
fn memcpy(dest: &mut [u8], src: &[u8]) {
    bytes::copy_memory(src, dest)
}

#[macro_use]
pub mod util;

#[macro_use]
pub mod symbol;
pub mod pattern;
<|endoftext|>


<commit_before>#![allow(non_upper_case_globals)]

extern crate libc;

pub use array::*;
pub use base::*;
pub use character_set::*;
pub use data::*;
pub use dictionary::*;
pub use locale::*;
pub use number::*;
pub use string::*;

pub mod array;
pub mod base;
pub mod character_set;
pub mod data;
pub mod dictionary;
pub mod locale;
pub mod number;
pub mod string;
<commit_msg>suppresses warning about crate name<commit_after>#![allow(non_upper_case_globals,non_snake_case)]

extern crate libc;

pub use array::*;
pub use base::*;
pub use character_set::*;
pub use data::*;
pub use dictionary::*;
pub use locale::*;
pub use number::*;
pub use string::*;

pub mod array;
pub mod base;
pub mod character_set;
pub mod data;
pub mod dictionary;
pub mod locale;
pub mod number;
pub mod string;
<|endoftext|>


<commit_before>//! Iterator zippers
//!
//! This crate provides "zippers" as tuple structs: `Zip2`, `Zip3`, etc. These structs accept
//! iterators as fields, and provides iteration over the "zipped" elements.
//!
//! The functionality is similar to the `Iterator::zip` method. The difference is that the `zip`
//! method always produces an iterator that yields *two-element* tuples. If you want to zip 3
//! iterators, you'll write `xs.zip(ys).zip(zs)` which returns an iterator that yields elements of
//! type `((X, Y), Z)`. On the other hand, with this library you can write `Zip3(xs, ys, zs)` which
//! is an iterator that yields elements of type `(X, Y, Z)`.
//!
//! ```
//! use zip::Zip3;
//!
//! let chars = &['a', 'b', 'c'];
//! let mut v = vec![0u, 1, 2];
//! for (&c, i, &mut j) in Zip3(chars.iter(), range(0u, 5), v.iter_mut()) {
//!     assert!(i < 3);
//!     assert_eq!(i, j);
//! }
//! ```

#![deny(missing_docs, warnings)]

/// This macro emulates an "any-arity" free function that zips iterators
///
/// **Note** This macro calls `into_iter()` on the inputs. For this reason, this macro won't work
/// until `IntoIterator` lands in stdlib, or unless you provide your own `IntoIterator` trait.
///
/// # Examples
///
/// ```
/// #[macro_use]
/// extern crate zip;
///
/// # use std::slice;
/// # trait IntoIterator {
/// #     type Iter: Iterator;
/// #     fn into_iter(self) -> Self::Iter;
/// # }
/// # impl<I> IntoIterator for I where I: Iterator {
/// #     type Iter = I;
/// #     fn into_iter(self) -> I { self }
/// # }
/// # impl<'a, T> IntoIterator for &'a [T] {
/// #     type Iter = slice::Iter<'a, T>;
/// #     fn into_iter(self) -> slice::Iter<'a, T> { self.iter() }
/// # }
/// # impl<'a, T> IntoIterator for &'a mut Vec<T> {
/// #     type Iter = slice::IterMut<'a, T>;
/// #     fn into_iter(self) -> slice::IterMut<'a, T> { self.iter_mut() }
/// # }
/// # fn main() {
/// let chars = &['a', 'b', 'c'];
/// let mut v = vec![0u, 1, 2];
///
/// for (&c, i, &mut j) in zip!(chars, range(0u, 5), &mut v) {
///     assert!(i < 3);
///     assert_eq!(i, j);
/// }
/// # }
/// ```
#[macro_export]
macro_rules! zip {
    ($a:expr, $b:expr) => {
        ::zip::Zip2(($a).into_iter(), ($b).into_iter())
    };
    ($a:expr, $b:expr, $c:expr) => {
        ::zip::Zip3(($a).into_iter(), ($b).into_iter(), ($c).into_iter())
    };
    ($a:expr, $b:expr, $c:expr, $d:expr) => {
        ::zip::Zip4(($a).into_iter(), ($b).into_iter(), ($c).into_iter(), ($d).into_iter())
    };
    ($a:expr, $b:expr, $c:expr, $d:expr, $e:expr) => {
        ::zip::Zip5(
            ($a).into_iter(),
            ($b).into_iter(),
            ($c).into_iter(),
            ($d).into_iter(),
            ($e).into_iter(),
        )
    };
    ($($x:expr),+,) => { zip!($($x),+) }
}

macro_rules! min {
    ($x:expr) => { $x };
    ($x:expr, $($y:expr),+) => { ::std::cmp::min($x, min!($($y),+)) };
    ($($x:expr),+,) => { min!($($x),+) };
}

/// Two-iterator zipper
pub struct Zip2<A, B>(pub A, pub B);

impl<A, B, AI, BI> Iterator for Zip2<AI, BI> where
    AI: Iterator<Item=A>,
    BI: Iterator<Item=B>,
{
    type Item = (A, B);

    fn next(&mut self) -> Option<(A, B)> {
        if let Some(a) = self.0.next() {
            if let Some(b) = self.1.next() {
                return Some((a, b));
            }
        }

        None
    }

    fn size_hint(&self) -> (uint, Option<uint>) {
        (min!{
            self.0.size_hint().0,
            self.1.size_hint().0,
        }, None)
    }
}

/// Three-iterator zipper
pub struct Zip3<A, B, C>(pub A, pub B, pub C);

impl<A, B, C, AI, BI, CI> Iterator for Zip3<AI, BI, CI> where
    AI: Iterator<Item=A>,
    BI: Iterator<Item=B>,
    CI: Iterator<Item=C>,
{
    type Item = (A, B, C);

    fn next(&mut self) -> Option<(A, B, C)> {
        if let Some(a) = self.0.next() {
            if let Some(b) = self.1.next() {
                if let Some(c) = self.2.next() {
                    return Some((a, b, c));
                }
            }
        }

        None
    }

    fn size_hint(&self) -> (uint, Option<uint>) {
        (min!{
            self.0.size_hint().0,
            self.1.size_hint().0,
            self.2.size_hint().0,
        }, None)
    }
}

/// Four-iterator zipper
pub struct Zip4<A, B, C, D>(pub A, pub B, pub C, pub D);

impl<A, B, C, D, AI, BI, CI, DI> Iterator for Zip4<AI, BI, CI, DI> where
    AI: Iterator<Item=A>,
    BI: Iterator<Item=B>,
    CI: Iterator<Item=C>,
    DI: Iterator<Item=D>,
{
    type Item = (A, B, C, D);

    fn next(&mut self) -> Option<(A, B, C, D)> {
        if let Some(a) = self.0.next() {
            if let Some(b) = self.1.next() {
                if let Some(c) = self.2.next() {
                    if let Some(d) = self.3.next() {
                        return Some((a, b, c, d))
                    }
                }
            }
        }

        None
    }

    fn size_hint(&self) -> (uint, Option<uint>) {
        (min!{
            self.0.size_hint().0,
            self.1.size_hint().0,
            self.2.size_hint().0,
            self.3.size_hint().0,
        }, None)
    }
}

/// Five-iterator zipper
pub struct Zip5<A, B, C, D, E>(pub A, pub B, pub C, pub D, pub E);

impl<A, B, C, D, E, AI, BI, CI, DI, EI> Iterator for Zip5<AI, BI, CI, DI, EI> where
    AI: Iterator<Item=A>,
    BI: Iterator<Item=B>,
    CI: Iterator<Item=C>,
    DI: Iterator<Item=D>,
    EI: Iterator<Item=E>,
{
    type Item = (A, B, C, D, E);

    fn next(&mut self) -> Option<(A, B, C, D, E)> {
        if let Some(a) = self.0.next() {
            if let Some(b) = self.1.next() {
                if let Some(c) = self.2.next() {
                    if let Some(d) = self.3.next() {
                        if let Some(e) = self.4.next() {
                            return Some((a, b, c, d, e))
                        }
                    }
                }
            }
        }

        None
    }

    fn size_hint(&self) -> (uint, Option<uint>) {
        (min!{
            self.0.size_hint().0,
            self.1.size_hint().0,
            self.2.size_hint().0,
            self.3.size_hint().0,
            self.4.size_hint().0,
        }, None)
    }
}

#[cfg(test)]
mod bench {
    extern crate test;

    use self::test::Bencher;

    const SIZE: uint = 1024;

    #[bench]
    fn collect2(z: &mut Bencher) {
        let a = [0u8; SIZE];
        let b = a;

        z.iter(|| {
            ::Zip2(a.iter(), b.iter()).collect::<Vec<_>>()
        })
    }

    #[bench]
    fn collect2_(z: &mut Bencher) {
        let a = [0u8; SIZE];
        let b = a;

        z.iter(|| {
            a.iter().zip(b.iter()).collect::<Vec<_>>()
        })
    }

    #[bench]
    fn count2(z: &mut Bencher) {
        let a = [0u8; SIZE];
        let b = a;

        z.iter(|| {
            ::Zip2(a.iter(), b.iter()).count()
        })
    }

    #[bench]
    fn count2_(z: &mut Bencher) {
        let a = [0u8; SIZE];
        let b = a;

        z.iter(|| {
            a.iter().zip(b.iter()).count()
        })
    }

    #[bench]
    fn collect3(z: &mut Bencher) {
        let a = [0u8; SIZE];
        let (b, c) = (a, a);

        z.iter(|| {
            ::Zip3(a.iter(), b.iter(), c.iter()).collect::<Vec<_>>()
        })
    }

    #[bench]
    fn collect3_(z: &mut Bencher) {
        let a = [0u8; SIZE];
        let (b, c) = (a, a);

        z.iter(|| {
            a.iter().zip(b.iter()).zip(c.iter()).collect::<Vec<_>>()
        })
    }

    #[bench]
    fn count3(z: &mut Bencher) {
        let a = [0u8; SIZE];
        let (b, c) = (a, a);

        z.iter(|| {
            ::Zip3(a.iter(), b.iter(), c.iter()).count()
        })
    }

    #[bench]
    fn count3_(z: &mut Bencher) {
        let a = [0u8; SIZE];
        let (b, c) = (a, a);

        z.iter(|| {
            a.iter().zip(b.iter()).zip(c.iter()).count()
        })
    }

    #[bench]
    fn collect4(z: &mut Bencher) {
        let a = [0u8; SIZE];
        let (b, c, d) = (a, a, a);

        z.iter(|| {
            ::Zip4(a.iter(), b.iter(), c.iter(), d.iter()).collect::<Vec<_>>()
        })
    }

    #[bench]
    fn collect4_(z: &mut Bencher) {
        let a = [0u8; SIZE];
        let (b, c, d) = (a, a, a);

        z.iter(|| {
            a.iter().zip(b.iter()).zip(c.iter()).zip(d.iter()).collect::<Vec<_>>()
        })
    }

    #[bench]
    fn count4(z: &mut Bencher) {
        let a = [0u8; SIZE];
        let (b, c, d) = (a, a, a);

        z.iter(|| {
            ::Zip4(a.iter(), b.iter(), c.iter(), d.iter()).count()
        })
    }

    #[bench]
    fn count4_(z: &mut Bencher) {
        let a = [0u8; SIZE];
        let (b, c, d) = (a, a, a);

        z.iter(|| {
            a.iter().zip(b.iter()).zip(c.iter()).zip(d.iter()).count()
        })
    }

    #[bench]
    fn collect5(z: &mut Bencher) {
        let a = [0u8; SIZE];
        let (b, c, d, e) = (a, a, a, a);

        z.iter(|| {
            ::Zip5(a.iter(), b.iter(), c.iter(), d.iter(), e.iter()).collect::<Vec<_>>()
        })
    }

    #[bench]
    fn collect5_(z: &mut Bencher) {
        let a = [0u8; SIZE];
        let (b, c, d, e) = (a, a, a, a);

        z.iter(|| {
            a.iter().zip(b.iter()).zip(c.iter()).zip(d.iter()).zip(e.iter()).collect::<Vec<_>>()
        })
    }

    #[bench]
    fn count5(z: &mut Bencher) {
        let a = [0u8; SIZE];
        let (b, c, d, e) = (a, a, a, a);

        z.iter(|| {
            ::Zip5(a.iter(), b.iter(), c.iter(), d.iter(), e.iter()).count()
        })
    }

    #[bench]
    fn count5_(z: &mut Bencher) {
        let a = [0u8; SIZE];
        let (b, c, d, e) = (a, a, a, a);

        z.iter(|| {
            a.iter().zip(b.iter()).zip(c.iter()).zip(d.iter()).zip(e.iter()).count()
        })
    }
}
<commit_msg>fix(zip!): use the `$crate` variable instead of hardcoding `::zip`<commit_after>//! Iterator zippers
//!
//! This crate provides "zippers" as tuple structs: `Zip2`, `Zip3`, etc. These structs accept
//! iterators as fields, and provides iteration over the "zipped" elements.
//!
//! The functionality is similar to the `Iterator::zip` method. The difference is that the `zip`
//! method always produces an iterator that yields *two-element* tuples. If you want to zip 3
//! iterators, you'll write `xs.zip(ys).zip(zs)` which returns an iterator that yields elements of
//! type `((X, Y), Z)`. On the other hand, with this library you can write `Zip3(xs, ys, zs)` which
//! is an iterator that yields elements of type `(X, Y, Z)`.
//!
//! ```
//! use zip::Zip3;
//!
//! let chars = &['a', 'b', 'c'];
//! let mut v = vec![0u, 1, 2];
//! for (&c, i, &mut j) in Zip3(chars.iter(), range(0u, 5), v.iter_mut()) {
//!     assert!(i < 3);
//!     assert_eq!(i, j);
//! }
//! ```

#![deny(missing_docs, warnings)]

/// This macro emulates an "any-arity" free function that zips iterators
///
/// **Note** This macro calls `into_iter()` on the inputs. For this reason, this macro won't work
/// until `IntoIterator` lands in stdlib, or unless you provide your own `IntoIterator` trait.
///
/// # Examples
///
/// ```
/// #[macro_use]
/// extern crate zip;
///
/// # use std::slice;
/// # trait IntoIterator {
/// #     type Iter: Iterator;
/// #     fn into_iter(self) -> Self::Iter;
/// # }
/// # impl<I> IntoIterator for I where I: Iterator {
/// #     type Iter = I;
/// #     fn into_iter(self) -> I { self }
/// # }
/// # impl<'a, T> IntoIterator for &'a [T] {
/// #     type Iter = slice::Iter<'a, T>;
/// #     fn into_iter(self) -> slice::Iter<'a, T> { self.iter() }
/// # }
/// # impl<'a, T> IntoIterator for &'a mut Vec<T> {
/// #     type Iter = slice::IterMut<'a, T>;
/// #     fn into_iter(self) -> slice::IterMut<'a, T> { self.iter_mut() }
/// # }
/// # fn main() {
/// let chars = &['a', 'b', 'c'];
/// let mut v = vec![0u, 1, 2];
///
/// for (&c, i, &mut j) in zip!(chars, range(0u, 5), &mut v) {
///     assert!(i < 3);
///     assert_eq!(i, j);
/// }
/// # }
/// ```
#[macro_export]
macro_rules! zip {
    ($a:expr, $b:expr) => {
        $crate::Zip2(($a).into_iter(), ($b).into_iter())
    };
    ($a:expr, $b:expr, $c:expr) => {
        $crate::Zip3(($a).into_iter(), ($b).into_iter(), ($c).into_iter())
    };
    ($a:expr, $b:expr, $c:expr, $d:expr) => {
        $crate::Zip4(($a).into_iter(), ($b).into_iter(), ($c).into_iter(), ($d).into_iter())
    };
    ($a:expr, $b:expr, $c:expr, $d:expr, $e:expr) => {
        $crate::Zip5(
            ($a).into_iter(),
            ($b).into_iter(),
            ($c).into_iter(),
            ($d).into_iter(),
            ($e).into_iter(),
        )
    };
    ($($x:expr),+,) => { zip!($($x),+) }
}

macro_rules! min {
    ($x:expr) => { $x };
    ($x:expr, $($y:expr),+) => { ::std::cmp::min($x, min!($($y),+)) };
    ($($x:expr),+,) => { min!($($x),+) };
}

/// Two-iterator zipper
pub struct Zip2<A, B>(pub A, pub B);

impl<A, B, AI, BI> Iterator for Zip2<AI, BI> where
    AI: Iterator<Item=A>,
    BI: Iterator<Item=B>,
{
    type Item = (A, B);

    fn next(&mut self) -> Option<(A, B)> {
        if let Some(a) = self.0.next() {
            if let Some(b) = self.1.next() {
                return Some((a, b));
            }
        }

        None
    }

    fn size_hint(&self) -> (uint, Option<uint>) {
        (min!{
            self.0.size_hint().0,
            self.1.size_hint().0,
        }, None)
    }
}

/// Three-iterator zipper
pub struct Zip3<A, B, C>(pub A, pub B, pub C);

impl<A, B, C, AI, BI, CI> Iterator for Zip3<AI, BI, CI> where
    AI: Iterator<Item=A>,
    BI: Iterator<Item=B>,
    CI: Iterator<Item=C>,
{
    type Item = (A, B, C);

    fn next(&mut self) -> Option<(A, B, C)> {
        if let Some(a) = self.0.next() {
            if let Some(b) = self.1.next() {
                if let Some(c) = self.2.next() {
                    return Some((a, b, c));
                }
            }
        }

        None
    }

    fn size_hint(&self) -> (uint, Option<uint>) {
        (min!{
            self.0.size_hint().0,
            self.1.size_hint().0,
            self.2.size_hint().0,
        }, None)
    }
}

/// Four-iterator zipper
pub struct Zip4<A, B, C, D>(pub A, pub B, pub C, pub D);

impl<A, B, C, D, AI, BI, CI, DI> Iterator for Zip4<AI, BI, CI, DI> where
    AI: Iterator<Item=A>,
    BI: Iterator<Item=B>,
    CI: Iterator<Item=C>,
    DI: Iterator<Item=D>,
{
    type Item = (A, B, C, D);

    fn next(&mut self) -> Option<(A, B, C, D)> {
        if let Some(a) = self.0.next() {
            if let Some(b) = self.1.next() {
                if let Some(c) = self.2.next() {
                    if let Some(d) = self.3.next() {
                        return Some((a, b, c, d))
                    }
                }
            }
        }

        None
    }

    fn size_hint(&self) -> (uint, Option<uint>) {
        (min!{
            self.0.size_hint().0,
            self.1.size_hint().0,
            self.2.size_hint().0,
            self.3.size_hint().0,
        }, None)
    }
}

/// Five-iterator zipper
pub struct Zip5<A, B, C, D, E>(pub A, pub B, pub C, pub D, pub E);

impl<A, B, C, D, E, AI, BI, CI, DI, EI> Iterator for Zip5<AI, BI, CI, DI, EI> where
    AI: Iterator<Item=A>,
    BI: Iterator<Item=B>,
    CI: Iterator<Item=C>,
    DI: Iterator<Item=D>,
    EI: Iterator<Item=E>,
{
    type Item = (A, B, C, D, E);

    fn next(&mut self) -> Option<(A, B, C, D, E)> {
        if let Some(a) = self.0.next() {
            if let Some(b) = self.1.next() {
                if let Some(c) = self.2.next() {
                    if let Some(d) = self.3.next() {
                        if let Some(e) = self.4.next() {
                            return Some((a, b, c, d, e))
                        }
                    }
                }
            }
        }

        None
    }

    fn size_hint(&self) -> (uint, Option<uint>) {
        (min!{
            self.0.size_hint().0,
            self.1.size_hint().0,
            self.2.size_hint().0,
            self.3.size_hint().0,
            self.4.size_hint().0,
        }, None)
    }
}

#[cfg(test)]
mod bench {
    extern crate test;

    use self::test::Bencher;

    const SIZE: uint = 1024;

    #[bench]
    fn collect2(z: &mut Bencher) {
        let a = [0u8; SIZE];
        let b = a;

        z.iter(|| {
            ::Zip2(a.iter(), b.iter()).collect::<Vec<_>>()
        })
    }

    #[bench]
    fn collect2_(z: &mut Bencher) {
        let a = [0u8; SIZE];
        let b = a;

        z.iter(|| {
            a.iter().zip(b.iter()).collect::<Vec<_>>()
        })
    }

    #[bench]
    fn count2(z: &mut Bencher) {
        let a = [0u8; SIZE];
        let b = a;

        z.iter(|| {
            ::Zip2(a.iter(), b.iter()).count()
        })
    }

    #[bench]
    fn count2_(z: &mut Bencher) {
        let a = [0u8; SIZE];
        let b = a;

        z.iter(|| {
            a.iter().zip(b.iter()).count()
        })
    }

    #[bench]
    fn collect3(z: &mut Bencher) {
        let a = [0u8; SIZE];
        let (b, c) = (a, a);

        z.iter(|| {
            ::Zip3(a.iter(), b.iter(), c.iter()).collect::<Vec<_>>()
        })
    }

    #[bench]
    fn collect3_(z: &mut Bencher) {
        let a = [0u8; SIZE];
        let (b, c) = (a, a);

        z.iter(|| {
            a.iter().zip(b.iter()).zip(c.iter()).collect::<Vec<_>>()
        })
    }

    #[bench]
    fn count3(z: &mut Bencher) {
        let a = [0u8; SIZE];
        let (b, c) = (a, a);

        z.iter(|| {
            ::Zip3(a.iter(), b.iter(), c.iter()).count()
        })
    }

    #[bench]
    fn count3_(z: &mut Bencher) {
        let a = [0u8; SIZE];
        let (b, c) = (a, a);

        z.iter(|| {
            a.iter().zip(b.iter()).zip(c.iter()).count()
        })
    }

    #[bench]
    fn collect4(z: &mut Bencher) {
        let a = [0u8; SIZE];
        let (b, c, d) = (a, a, a);

        z.iter(|| {
            ::Zip4(a.iter(), b.iter(), c.iter(), d.iter()).collect::<Vec<_>>()
        })
    }

    #[bench]
    fn collect4_(z: &mut Bencher) {
        let a = [0u8; SIZE];
        let (b, c, d) = (a, a, a);

        z.iter(|| {
            a.iter().zip(b.iter()).zip(c.iter()).zip(d.iter()).collect::<Vec<_>>()
        })
    }

    #[bench]
    fn count4(z: &mut Bencher) {
        let a = [0u8; SIZE];
        let (b, c, d) = (a, a, a);

        z.iter(|| {
            ::Zip4(a.iter(), b.iter(), c.iter(), d.iter()).count()
        })
    }

    #[bench]
    fn count4_(z: &mut Bencher) {
        let a = [0u8; SIZE];
        let (b, c, d) = (a, a, a);

        z.iter(|| {
            a.iter().zip(b.iter()).zip(c.iter()).zip(d.iter()).count()
        })
    }

    #[bench]
    fn collect5(z: &mut Bencher) {
        let a = [0u8; SIZE];
        let (b, c, d, e) = (a, a, a, a);

        z.iter(|| {
            ::Zip5(a.iter(), b.iter(), c.iter(), d.iter(), e.iter()).collect::<Vec<_>>()
        })
    }

    #[bench]
    fn collect5_(z: &mut Bencher) {
        let a = [0u8; SIZE];
        let (b, c, d, e) = (a, a, a, a);

        z.iter(|| {
            a.iter().zip(b.iter()).zip(c.iter()).zip(d.iter()).zip(e.iter()).collect::<Vec<_>>()
        })
    }

    #[bench]
    fn count5(z: &mut Bencher) {
        let a = [0u8; SIZE];
        let (b, c, d, e) = (a, a, a, a);

        z.iter(|| {
            ::Zip5(a.iter(), b.iter(), c.iter(), d.iter(), e.iter()).count()
        })
    }

    #[bench]
    fn count5_(z: &mut Bencher) {
        let a = [0u8; SIZE];
        let (b, c, d, e) = (a, a, a, a);

        z.iter(|| {
            a.iter().zip(b.iter()).zip(c.iter()).zip(d.iter()).zip(e.iter()).count()
        })
    }
}
<|endoftext|>


<commit_before>//! A crate that implements [editorconfig](http://editorconfig.org/).
extern crate regex;

extern crate ordermap;

mod ini;
use regex::{Regex, Captures};

use ordermap::OrderMap;

use std::path::{Path, PathBuf};
use std::error::Error;

/// Finds all possible `conffile`s starting from `path` until root.
fn crawl_paths(path: &Path, conffile: &str) -> Result<Vec<PathBuf>, Box<Error>> {
    let mut path = if path.exists() {
        path.canonicalize()?
    } else {
        path.to_path_buf()
    };

    let mut result = vec![];
    while path.parent().is_some() {
        let mut adjacent_file = path.clone();
        adjacent_file.set_file_name(conffile);
        path.pop();
        if !adjacent_file.exists() {
            continue;
        }
        result.push(adjacent_file);
    }
    return Ok(result);
}

fn glob_match(pattern: &String, candidate: &String) -> bool {
    // Step 1. Escape the crap out of the existing pattern
    // println!("B: {}", pattern);
    let pattern = pattern.replace(".", r"\.");
    let unmatched_open_bracket_regex = Regex::new(r"\[([^\]]*)$").unwrap();
    let pattern = unmatched_open_bracket_regex.replace(&pattern, r"\[$1")
        .to_string();
    // Step 2. Convert sh globs to regexes
    // Handling * and ** is weird but this actually works
    let pattern = pattern.replace("*", "[^/]*");
    let pattern = pattern.replace("[^/]*[^/]*", ".*");
    let pattern = pattern.replace("?", ".");
    let pattern = pattern.replace("[!", "[^");
    let alternation_regex = Regex::new(r"\{(.*,.*)\}").unwrap();
    let pattern = alternation_regex.replace(&pattern, |caps: &Captures| {
            let padded_cases = format!(",{},", &caps[1]);
            let quantifier = if padded_cases.contains(",,") { "?" } else { "" };
            let cases = caps[1].replace(",", "|");
            format!("({}){}", cases, quantifier)
        })
        .to_string();
    let pattern = pattern.replace("{", r"\{");
    let pattern = pattern.replace("}", r"\}");
    let pattern = pattern.replace("||", "|");
    let pattern = pattern.replace("(|", "(");
    let pattern = pattern.replace("|)", ")");
    let mut pattern = pattern;
    pattern.push('$');
    // println!("A: {}", pattern);
    // Step 3. Actually do the testing
    let final_regex = Regex::new(&pattern).unwrap();
    return final_regex.is_match(candidate);
}

fn parse_config(target: &Path, conf_file: &Path) -> Result<OrderMap<String, String>, Box<Error>> {
    let ini_data = ini::Ini::load_from_file(conf_file)?;
    let mut result = OrderMap::new();
    if let Some(general) = ini_data.section::<String>(None) {
        if let Some(root) = general.get("root") {
            if root.to_lowercase() == "true" {
                result.insert("root".to_string(), "true".to_string());
            }
        }
    }
    let target = target.as_os_str().to_os_string().into_string().unwrap();
    #[cfg(windows)]
    let target = target.replace("\\", "/");
    for (label, data) in ini_data.iter() {
        if let Some(ref label) = *label {
            if label.len() > 4096 {
                continue;
            }
            if glob_match(label, &target) {
                for (k, v) in data.iter() {
                    result.insert(k.clone(), v.clone());
                }
            }
        }
    }

    // Preprocessing may or may not actually be part of the spec
    // so I'm stealing this from editorconfig-core-py
    if let Some(indent_style) = result.clone().get("indent_style") {
        if indent_style == "tab" {
            if result.get("indent_size").is_none() {
                result.insert("indent_size".to_string(), "tab".to_string());
            }
        }
    }
    if let Some(indent_size) = result.clone().get("indent_size") {
        if indent_size != "tab" {
            if result.get("tab_width").is_none() {
                result.insert("tab_width".to_string(), indent_size.clone());
            }
        } else {
            if let Some(tab_width) = result.clone().get("tab_width") {
                result.insert("indent_size".to_string(), tab_width.clone());
            }
        }
    }
    Ok(result)
}

fn is_known_key(key: &str) -> bool {
    let known_keys = ["indent_style",
                      "indent_size",
                      "tab_width",
                      "end_of_line",
                      "charset",
                      "trim_trailing_whitespace",
                      "insert_final_newline"];
    known_keys.contains(&key)
}

/// Finds the configuration that applies to the file passed in `file_path`.
///
/// The `file_path` argument is the path to a file.
///
/// It looks for a file named `.editorconfig` in the file's directory and in every parent directory.
/// A search for `.editorconfig` files will stop if root (`/`) is reached or an `.editorconfig` file with `root=true` is found.
///
/// # Example
/// ```
/// use std::path::Path;
///
/// let res = editorconfig::get_config(Path::new("./test_files/simple/file.txt")).unwrap();
/// for (k, v) in res.iter() {
///     println!("{}={}", *k, *v);
/// }
/// ```
/// # Errors
///  It returns an error:
///
/// - when the `.editorconfig` file can't be found
///
/// - when it can't parse it
///
/// - when the `file_path` is malformed (check `std::fs::canonicalize` docs) or is a directory.
///
pub fn get_config(file_path: &Path) -> Result<OrderMap<String, String>, Box<Error>> {
    get_config_conffile(file_path, ".editorconfig")
}

/// Finds actual configuration that applies to file with given path.
/// # MAINLY USED FOR TESTING AND INTERNAL USE, CHECK `get_config`.
///
/// Looks for config data in given filename; in normal operation this will be ".editorconfig".
pub fn get_config_conffile(file_path: &Path,
                           conffile: &str)
                           -> Result<OrderMap<String, String>, Box<Error>> {
    let paths = crawl_paths(file_path, conffile)?;

    let mut result = OrderMap::new();
    for conf_path in paths {
        let options = parse_config(file_path, &conf_path)?;
        for (k, v) in options.iter() {
            let k = k.to_lowercase();
            let v = if is_known_key(&k) {
                v.to_lowercase()
            } else {
                v.clone()
            };
            if k.len() > 50 || v.len() > 255 {
                continue;
            }
            if !result.contains_key(&k) && k != "root" {
                result.insert(k, v);
            }
        }
        if let Some(root) = options.get("root") {
            if root.to_lowercase() == "true" {
                break;
            }
        }
    }
    return Ok(result);
}

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

    #[test]
    fn works_with_multi_level_directories() {
        let cfg = get_config(Path::new("./test_files/multi_level/foo/bar/file.txt")).unwrap();
        let mut map = OrderMap::new();
        map.insert("end_of_line".to_owned(), "lf".to_owned());
        map.insert("insert_final_newline".to_owned(), "true".to_owned());
        assert_eq!(cfg, map);
    }

    #[test]
    fn get_editorconfig_for_non_existing_file() {
        assert!(get_config(Path::new("./test_files/diocano")).is_ok());
    }
}
<commit_msg>Update docs<commit_after>//! A crate that implements [editorconfig](http://editorconfig.org/).
extern crate regex;

extern crate ordermap;

mod ini;
use regex::{Regex, Captures};

use ordermap::OrderMap;

use std::path::{Path, PathBuf};
use std::error::Error;

/// Finds all possible `conffile`s starting from `path` until root.
fn crawl_paths(path: &Path, conffile: &str) -> Result<Vec<PathBuf>, Box<Error>> {
    let mut path = if path.exists() {
        path.canonicalize()?
    } else {
        path.to_path_buf()
    };

    let mut result = vec![];
    while path.parent().is_some() {
        let mut adjacent_file = path.clone();
        adjacent_file.set_file_name(conffile);
        path.pop();
        if !adjacent_file.exists() {
            continue;
        }
        result.push(adjacent_file);
    }
    return Ok(result);
}

fn glob_match(pattern: &String, candidate: &String) -> bool {
    // Step 1. Escape the crap out of the existing pattern
    // println!("B: {}", pattern);
    let pattern = pattern.replace(".", r"\.");
    let unmatched_open_bracket_regex = Regex::new(r"\[([^\]]*)$").unwrap();
    let pattern = unmatched_open_bracket_regex.replace(&pattern, r"\[$1")
        .to_string();
    // Step 2. Convert sh globs to regexes
    // Handling * and ** is weird but this actually works
    let pattern = pattern.replace("*", "[^/]*");
    let pattern = pattern.replace("[^/]*[^/]*", ".*");
    let pattern = pattern.replace("?", ".");
    let pattern = pattern.replace("[!", "[^");
    let alternation_regex = Regex::new(r"\{(.*,.*)\}").unwrap();
    let pattern = alternation_regex.replace(&pattern, |caps: &Captures| {
            let padded_cases = format!(",{},", &caps[1]);
            let quantifier = if padded_cases.contains(",,") { "?" } else { "" };
            let cases = caps[1].replace(",", "|");
            format!("({}){}", cases, quantifier)
        })
        .to_string();
    let pattern = pattern.replace("{", r"\{");
    let pattern = pattern.replace("}", r"\}");
    let pattern = pattern.replace("||", "|");
    let pattern = pattern.replace("(|", "(");
    let pattern = pattern.replace("|)", ")");
    let mut pattern = pattern;
    pattern.push('$');
    // println!("A: {}", pattern);
    // Step 3. Actually do the testing
    let final_regex = Regex::new(&pattern).unwrap();
    return final_regex.is_match(candidate);
}

fn parse_config(target: &Path, conf_file: &Path) -> Result<OrderMap<String, String>, Box<Error>> {
    let ini_data = ini::Ini::load_from_file(conf_file)?;
    let mut result = OrderMap::new();
    if let Some(general) = ini_data.section::<String>(None) {
        if let Some(root) = general.get("root") {
            if root.to_lowercase() == "true" {
                result.insert("root".to_string(), "true".to_string());
            }
        }
    }
    let target = target.as_os_str().to_os_string().into_string().unwrap();
    #[cfg(windows)]
    let target = target.replace("\\", "/");
    for (label, data) in ini_data.iter() {
        if let Some(ref label) = *label {
            if label.len() > 4096 {
                continue;
            }
            if glob_match(label, &target) {
                for (k, v) in data.iter() {
                    result.insert(k.clone(), v.clone());
                }
            }
        }
    }

    // Preprocessing may or may not actually be part of the spec
    // so I'm stealing this from editorconfig-core-py
    if let Some(indent_style) = result.clone().get("indent_style") {
        if indent_style == "tab" {
            if result.get("indent_size").is_none() {
                result.insert("indent_size".to_string(), "tab".to_string());
            }
        }
    }
    if let Some(indent_size) = result.clone().get("indent_size") {
        if indent_size != "tab" {
            if result.get("tab_width").is_none() {
                result.insert("tab_width".to_string(), indent_size.clone());
            }
        } else {
            if let Some(tab_width) = result.clone().get("tab_width") {
                result.insert("indent_size".to_string(), tab_width.clone());
            }
        }
    }
    Ok(result)
}

fn is_known_key(key: &str) -> bool {
    let known_keys = ["indent_style",
                      "indent_size",
                      "tab_width",
                      "end_of_line",
                      "charset",
                      "trim_trailing_whitespace",
                      "insert_final_newline"];
    known_keys.contains(&key)
}

/// Finds the configuration that applies to the file passed in `file_path`.
///
/// The `file_path` argument is the path to a file.
///
/// It looks for a file named `.editorconfig` in the file's directory and in every parent directory.
/// A search for `.editorconfig` files will stop if root (`/`) is reached or an `.editorconfig` file with `root=true` is found.
///
/// # Example
/// ```
/// use std::path::Path;
///
/// let res = editorconfig::get_config(Path::new("./test_files/simple/file.txt")).unwrap();
/// for (k, v) in res.iter() {
///     println!("{}={}", *k, *v);
/// }
/// ```
/// # Errors
///  It returns an error:
///
/// - when it can't parse it
///
/// - when the `file_path` is malformed (check `std::fs::canonicalize` docs) or is a directory.
///
pub fn get_config(file_path: &Path) -> Result<OrderMap<String, String>, Box<Error>> {
    get_config_conffile(file_path, ".editorconfig")
}

/// Finds actual configuration that applies to file with given path.
/// # MAINLY USED FOR TESTING AND INTERNAL USE, CHECK `get_config`.
///
/// Looks for config data in given filename; in normal operation this will be ".editorconfig".
pub fn get_config_conffile(file_path: &Path,
                           conffile: &str)
                           -> Result<OrderMap<String, String>, Box<Error>> {
    let paths = crawl_paths(file_path, conffile)?;

    let mut result = OrderMap::new();
    for conf_path in paths {
        let options = parse_config(file_path, &conf_path)?;
        for (k, v) in options.iter() {
            let k = k.to_lowercase();
            let v = if is_known_key(&k) {
                v.to_lowercase()
            } else {
                v.clone()
            };
            if k.len() > 50 || v.len() > 255 {
                continue;
            }
            if !result.contains_key(&k) && k != "root" {
                result.insert(k, v);
            }
        }
        if let Some(root) = options.get("root") {
            if root.to_lowercase() == "true" {
                break;
            }
        }
    }
    return Ok(result);
}

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

    #[test]
    fn works_with_multi_level_directories() {
        let cfg = get_config(Path::new("./test_files/multi_level/foo/bar/file.txt")).unwrap();
        let mut map = OrderMap::new();
        map.insert("end_of_line".to_owned(), "lf".to_owned());
        map.insert("insert_final_newline".to_owned(), "true".to_owned());
        assert_eq!(cfg, map);
    }

    #[test]
    fn get_editorconfig_for_non_existing_file() {
        assert!(get_config(Path::new("./test_files/diocano")).is_ok());
    }
}
<|endoftext|>