<commit_before> use redox::*;

// TODO: Structure using loops
// TODO: Make capital commands doing the reverse of the command
//       Y: Yank before the cursor
//       D: Delete before the cursor.

use super::Mode;
use super::Mode::*;
use super::Editor;

// TODO: Move vars to `Editor`
pub fn exec(editor: &mut Editor, mode: &mut Mode, multiplier: &mut Option<u32>, last_change: &mut String, key_event: KeyEvent, window: &mut Window, swap: &mut usize, period: &mut String, is_recording: &mut bool, clipboard: &mut String) {
    match (*mode, key_event.scancode) {
        (Insert, K_ESC) => {
            *mode = Normal;
        },
        (Insert, K_BKSP) => editor.backspace(window),
        (Insert, K_DEL) => editor.delete(window),
        (_, K_F5) => editor.reload(window),
        (_, K_F6) => editor.save(window),
        (_, K_HOME) => editor.offset = 0,
        (_, K_UP) => editor.up(),
        (_, K_LEFT) => editor.left(),
        (_, K_RIGHT) => editor.right(),
        (_, K_END) => editor.offset = editor.string.len(),
        (_, K_DOWN) => editor.down(),
        (m, _) => {
            let (no_mult, mut times) = match *multiplier {
                Some(n) => (false, n),
                None => (true, 1),
            };
            let mut is_none = false;

            match (*mode, key_event.character) {
                (Normal, '0') if !no_mult => times *= 10,

                (Normal, '1') if no_mult => times = 1,
                (Normal, '1') => times = times * 10 + 1,

                (Normal, '2') if no_mult => times = 2,
                (Normal, '2') => times = times * 10 + 2,

                (Normal, '3') if no_mult => times = 3,
                (Normal, '3') => times = times * 10 + 3,

                (Normal, '4') if no_mult => times = 4,
                (Normal, '4') => times = times * 10 + 4,

                (Normal, '5') if no_mult => times = 5,
                (Normal, '5') => times = times * 10 + 5,

                (Normal, '6') if no_mult => times = 6,
                (Normal, '6') => times = times * 10 + 6,

                (Normal, '7') if no_mult => times = 7,
                (Normal, '7') => times = times * 10 + 7,

                (Normal, '8') if no_mult => times = 8,
                (Normal, '8') => times = times * 10 + 8,

                (Normal, '9') if no_mult => times = 9,
                (Normal, '9') => times = times * 10 + 9,
                (_, _) => {
                    if *is_recording {
                        if key_event.character == ',' {
                            *is_recording = false;
                        } else {
                            period.push(key_event.character);
                        }
                    } else {
                        for _ in 0 .. times {
                            match (m, key_event.character) {
                                (Normal, 'i') => {
                                    *mode = Insert;
                                    *last_change = editor.string.clone();
                                },
                                (Normal, 'h') | (Normal, ' ') => editor.left(),
                                (Normal, 'l') => editor.right(),
                                (Normal, 'k') => editor.up(),
                                (Normal, 'j') | (Normal, '\n') => editor.down(),
                                (Normal, 'K') => {
                                    for _ in 1..15 {
                                        editor.up();
                                    }
                                },
                                (Normal, 'J') => {
                                    for _ in 1..15 {
                                        editor.down();
                                    }
                                },
                                (Normal, 'g') => editor.offset = 0,
                                (Normal, 'G') => editor.offset = editor.string.len(),
                                (Normal, 'a') => {
                                    editor.right();
                                    *mode = Insert;
                                    *last_change = editor.string.clone();
                                },
                                (Normal, 'x') => editor.delete(window),
                                (Normal, 'X') => editor.backspace(window),
                                (Normal, 'u') => {
                                    editor.offset = 0;
                                    ::core::mem::swap(last_change, &mut editor.string);
                                },
                                (Normal, 'c') => {
                                    ::core::mem::swap(&mut editor.offset, swap);
                                },
                                (Normal, 'z') => {
                                    *clipboard = String::new();
                                    while editor.cur() != '\n' &&
                                          editor.offset < editor.string.len() {
                                        *clipboard = clipboard.clone().to_string() + &editor.cur().to_string();
                                        editor.delete(window);
                                    }
                                },
                                (Normal, 'Z') => {
                                    *clipboard = String::new();
                                    while editor.cur() != '\n' &&
                                          editor.offset >= 0 {
                                        clipboard.push(editor.cur());
                                        editor.backspace(window);
                                        editor.left();
                                    }
                                    editor.right();
                                },
                                (Normal, 's') => {
                                    editor.delete(window);
                                    *mode = Insert;
                                },
                                (Normal, 'o') => {
                                    while editor.cur() != '\n' &&
                                          editor.cur() != '\0' &&
                                          editor.offset < editor.string.len() {
                                        editor.right();
                                    }
                                    editor.insert('\n', window);
                                    *mode = Insert;
                                },
                                (Normal, 'O') => {
                                    while editor.cur() != '\n' &&
                                          editor.cur() != '\0' &&
                                          editor.offset >= 1 {
                                        editor.left();
                                    }
                                    editor.insert('\n', window);
                                    editor.left();
                                    *mode = Insert;
                                },
                                (Normal, '^') | (Normal, 'H') => {
                                    editor.left();
                                    while editor.cur() != '\n' &&
                                          editor.cur() != '\0' &&
                                          editor.offset >= 0 {
                                        editor.left();
                                    }
                                    editor.right();
                                    while (editor.cur() == ' ' ||
                                          editor.cur() == '\t') &&
                                          editor.offset < editor.string.len() {
                                        editor.right();
                                    }
                                },
                                (Normal, 'y') => {
                                    *clipboard = String::new();
                                    let mut mov = 1;
                                    while editor.cur() != '\n' &&
                                          editor.offset < editor.string.len() {
                                        clipboard.push(editor.cur());
                                        editor.right();
                                        mov += 1;
                                    }

                                    for _ in 1..mov {
                                        editor.left();
                                    }
                                },
                                (Normal, 'Y') => {
                                    *clipboard = String::new();
                                    let mut mov = 1;
                                    while editor.cur() != '\n' &&
                                          editor.offset < editor.string.len() {
                                        *clipboard = editor.cur().to_string() + clipboard;
                                        editor.left();
                                        mov += 1;
                                    }

                                    for _ in 1..mov {
                                        editor.right();
                                    }
                                },
                                (Normal, 'p') => {
                                    for c in clipboard.chars() {
                                        editor.insert(c, window);
                                    }
                                },
                                (Normal, '$') | (Normal, 'L') => {
                                    while editor.cur() != '\n' &&
                                          editor.cur() != '\0' &&
                                          editor.offset < editor.string.len() {
                                        editor.right();
                                    }
                                },
                                (Normal,  '0') => {
                                    editor.left();
                                    while editor.cur() != '\n' &&
                                          editor.cur() != '\0' &&
                                          editor.offset >= 1 {
                                        editor.left();
                                    }
                                    editor.right();
                                },
                                (Normal, 'd') => {
                                    while editor.cur() != '\n' &&
                                          editor.cur() != '\0' &&
                                          editor.offset < editor.string.len() {
                                        editor.delete(window);
                                    }
                                },
                                (Normal, 'D') => {
                                    while editor.cur() != '\n' &&
                                          editor.cur() != '\0' &&
                                          editor.offset >= 1 {
                                        editor.backspace(window);
                                        editor.left();
                                    }
                                    editor.right();
                                },
                                (Normal, 'w') => {
                                    editor.save(window);
                                },
                                (Normal, 'e') => {
                                    editor.right();
                                    while editor.cur() != '.' &&
                                          editor.cur() != '{' &&
                                          editor.cur() != ',' &&
                                          editor.cur() != ' ' &&
                                          editor.cur() != '}' &&
                                          editor.cur() != '(' &&
                                          editor.cur() != ')' &&
                                          editor.cur() != '[' &&
                                          editor.cur() != ']' &&
                                          editor.cur() != ';' &&
                                          editor.cur() != '"' &&
                                          editor.cur() != '\'' &&
                                          editor.cur() != '\n' &&
                                          editor.offset < editor.string.len() {
                                        editor.right();
                                    }
                                },
                                (Normal, 'b') => {
                                    editor.left();
                                    while editor.cur() != '.' &&
                                          editor.cur() != '{' &&
                                          editor.cur() != ',' &&
                                          editor.cur() != ' ' &&
                                          editor.cur() != '}' &&
                                          editor.cur() != '(' &&
                                          editor.cur() != ')' &&
                                          editor.cur() != '[' &&
                                          editor.cur() != ']' &&
                                          editor.cur() != ';' &&
                                          editor.cur() != '"' &&
                                          editor.cur() != '\'' &&
                                          editor.cur() != '\n' &&
                                          editor.offset >= 1 {
                                        editor.left();
                                    }
                                },
                                (Normal, 'E') => {
                                    editor.right();
                                    while editor.cur() != ' ' && editor.offset < editor.string.len() {
                                        editor.right();
                                    }
                                },
                                (Normal, 'B') => {
                                    editor.left();
                                    while editor.cur() != ' ' && editor.offset >= 1 {
                                        editor.left();
                                    }
                                },
                                (Normal, ',') => {
                                    *is_recording = true;
                                    *period = String::new();
                                },
                                (Normal, '%') => {
                                    match editor.cur() {
                                        '(' | '[' | '{' => {
                                            let mut i = 1;
                                            while i != 0 &&
                                                  editor.offset < editor.string.len() {
                                                editor.right();
                                                i += match editor.cur() {
                                                    '(' | '[' | '{' => 1,
                                                    ')' | ']' | '}' => -1,
                                                    _ => 0,
                                                };
                                            }
                                        },
                                        ')' | ']' | '}' => {
                                            let mut i = 1;
                                            while i != 0 &&
                                                  editor.offset < editor.string.len() {
                                                editor.left();
                                                i += match editor.cur() {
                                                    '(' | '[' | '{' => -1,
                                                    ')' | ']' | '}' => 1,
                                                    _ => 0,
                                                };
                                            }
                                        },
                                        _ => {},

                                    }
                                },
                                (Normal, '!') => {
                                    for c in period.clone().chars() {
                                        exec(editor, mode, multiplier, last_change, KeyEvent {
                                            character: c,
                                            scancode: 0,
                                            pressed: true,
                                        }, window, swap, period, is_recording, clipboard);
                                    }
                                },
                                (Insert, '\0') => (),
                                (Insert, c) => {
                                    editor.insert(c, window);
                                },
                                _ => {},
                            }
                        }
                    }
                    is_none = true;
                }
            }

            if !is_none {
                *multiplier = Some(times);
            } else {
                *multiplier = None;
            }
        }
    }
}
<commit_msg>Fix space alias<commit_after> use redox::*;

// TODO: Structure using loops
// TODO: Make capital commands doing the reverse of the command
//       Y: Yank before the cursor
//       D: Delete before the cursor.

use super::Mode;
use super::Mode::*;
use super::Editor;

// TODO: Move vars to `Editor`
pub fn exec(editor: &mut Editor, mode: &mut Mode, multiplier: &mut Option<u32>, last_change: &mut String, key_event: KeyEvent, window: &mut Window, swap: &mut usize, period: &mut String, is_recording: &mut bool, clipboard: &mut String) {
    match (*mode, key_event.scancode) {
        (Insert, K_ESC) => {
            *mode = Normal;
        },
        (Insert, K_BKSP) => editor.backspace(window),
        (Insert, K_DEL) => editor.delete(window),
        (_, K_F5) => editor.reload(window),
        (_, K_F6) => editor.save(window),
        (_, K_HOME) => editor.offset = 0,
        (_, K_UP) => editor.up(),
        (_, K_LEFT) => editor.left(),
        (_, K_RIGHT) => editor.right(),
        (_, K_END) => editor.offset = editor.string.len(),
        (_, K_DOWN) => editor.down(),
        (m, _) => {
            let (no_mult, mut times) = match *multiplier {
                Some(n) => (false, n),
                None => (true, 1),
            };
            let mut is_none = false;

            match (*mode, key_event.character) {
                (Normal, '0') if !no_mult => times *= 10,

                (Normal, '1') if no_mult => times = 1,
                (Normal, '1') => times = times * 10 + 1,

                (Normal, '2') if no_mult => times = 2,
                (Normal, '2') => times = times * 10 + 2,

                (Normal, '3') if no_mult => times = 3,
                (Normal, '3') => times = times * 10 + 3,

                (Normal, '4') if no_mult => times = 4,
                (Normal, '4') => times = times * 10 + 4,

                (Normal, '5') if no_mult => times = 5,
                (Normal, '5') => times = times * 10 + 5,

                (Normal, '6') if no_mult => times = 6,
                (Normal, '6') => times = times * 10 + 6,

                (Normal, '7') if no_mult => times = 7,
                (Normal, '7') => times = times * 10 + 7,

                (Normal, '8') if no_mult => times = 8,
                (Normal, '8') => times = times * 10 + 8,

                (Normal, '9') if no_mult => times = 9,
                (Normal, '9') => times = times * 10 + 9,
                (_, _) => {
                    if *is_recording {
                        if key_event.character == ',' {
                            *is_recording = false;
                        } else {
                            period.push(key_event.character);
                        }
                    } else {
                        for _ in 0 .. times {
                            match (m, key_event.character) {
                                (Normal, 'i') => {
                                    *mode = Insert;
                                    *last_change = editor.string.clone();
                                },
                                (Normal, 'h') => editor.left(),
                                (Normal, 'l') | (Normal, ' ') => editor.right(),
                                (Normal, 'k') => editor.up(),
                                (Normal, 'j') | (Normal, '\n') => editor.down(),
                                (Normal, 'K') => {
                                    for _ in 1..15 {
                                        editor.up();
                                    }
                                },
                                (Normal, 'J') => {
                                    for _ in 1..15 {
                                        editor.down();
                                    }
                                },
                                (Normal, 'g') => editor.offset = 0,
                                (Normal, 'G') => editor.offset = editor.string.len(),
                                (Normal, 'a') => {
                                    editor.right();
                                    *mode = Insert;
                                    *last_change = editor.string.clone();
                                },
                                (Normal, 'x') => editor.delete(window),
                                (Normal, 'X') => editor.backspace(window),
                                (Normal, 'u') => {
                                    editor.offset = 0;
                                    ::core::mem::swap(last_change, &mut editor.string);
                                },
                                (Normal, 'c') => {
                                    ::core::mem::swap(&mut editor.offset, swap);
                                },
                                (Normal, 'z') => {
                                    *clipboard = String::new();
                                    while editor.cur() != '\n' &&
                                          editor.offset < editor.string.len() {
                                        *clipboard = clipboard.clone().to_string() + &editor.cur().to_string();
                                        editor.delete(window);
                                    }
                                },
                                (Normal, 'Z') => {
                                    *clipboard = String::new();
                                    while editor.cur() != '\n' &&
                                          editor.offset >= 0 {
                                        clipboard.push(editor.cur());
                                        editor.backspace(window);
                                        editor.left();
                                    }
                                    editor.right();
                                },
                                (Normal, 's') => {
                                    editor.delete(window);
                                    *mode = Insert;
                                },
                                (Normal, 'o') => {
                                    while editor.cur() != '\n' &&
                                          editor.cur() != '\0' &&
                                          editor.offset < editor.string.len() {
                                        editor.right();
                                    }
                                    editor.insert('\n', window);
                                    *mode = Insert;
                                },
                                (Normal, 'O') => {
                                    while editor.cur() != '\n' &&
                                          editor.cur() != '\0' &&
                                          editor.offset >= 1 {
                                        editor.left();
                                    }
                                    editor.insert('\n', window);
                                    editor.left();
                                    *mode = Insert;
                                },
                                (Normal, '^') | (Normal, 'H') => {
                                    editor.left();
                                    while editor.cur() != '\n' &&
                                          editor.cur() != '\0' &&
                                          editor.offset >= 0 {
                                        editor.left();
                                    }
                                    editor.right();
                                    while (editor.cur() == ' ' ||
                                          editor.cur() == '\t') &&
                                          editor.offset < editor.string.len() {
                                        editor.right();
                                    }
                                },
                                (Normal, 'y') => {
                                    *clipboard = String::new();
                                    let mut mov = 1;
                                    while editor.cur() != '\n' &&
                                          editor.offset < editor.string.len() {
                                        clipboard.push(editor.cur());
                                        editor.right();
                                        mov += 1;
                                    }

                                    for _ in 1..mov {
                                        editor.left();
                                    }
                                },
                                (Normal, 'Y') => {
                                    *clipboard = String::new();
                                    let mut mov = 1;
                                    while editor.cur() != '\n' &&
                                          editor.offset < editor.string.len() {
                                        *clipboard = editor.cur().to_string() + clipboard;
                                        editor.left();
                                        mov += 1;
                                    }

                                    for _ in 1..mov {
                                        editor.right();
                                    }
                                },
                                (Normal, 'p') => {
                                    for c in clipboard.chars() {
                                        editor.insert(c, window);
                                    }
                                },
                                (Normal, '$') | (Normal, 'L') => {
                                    while editor.cur() != '\n' &&
                                          editor.cur() != '\0' &&
                                          editor.offset < editor.string.len() {
                                        editor.right();
                                    }
                                },
                                (Normal,  '0') => {
                                    editor.left();
                                    while editor.cur() != '\n' &&
                                          editor.cur() != '\0' &&
                                          editor.offset >= 1 {
                                        editor.left();
                                    }
                                    editor.right();
                                },
                                (Normal, 'd') => {
                                    while editor.cur() != '\n' &&
                                          editor.cur() != '\0' &&
                                          editor.offset < editor.string.len() {
                                        editor.delete(window);
                                    }
                                },
                                (Normal, 'D') => {
                                    while editor.cur() != '\n' &&
                                          editor.cur() != '\0' &&
                                          editor.offset >= 1 {
                                        editor.backspace(window);
                                        editor.left();
                                    }
                                    editor.right();
                                },
                                (Normal, 'w') => {
                                    editor.save(window);
                                },
                                (Normal, 'e') => {
                                    editor.right();
                                    while editor.cur() != '.' &&
                                          editor.cur() != '{' &&
                                          editor.cur() != ',' &&
                                          editor.cur() != ' ' &&
                                          editor.cur() != '}' &&
                                          editor.cur() != '(' &&
                                          editor.cur() != ')' &&
                                          editor.cur() != '[' &&
                                          editor.cur() != ']' &&
                                          editor.cur() != ';' &&
                                          editor.cur() != '"' &&
                                          editor.cur() != '\'' &&
                                          editor.cur() != '\n' &&
                                          editor.offset < editor.string.len() {
                                        editor.right();
                                    }
                                },
                                (Normal, 'b') => {
                                    editor.left();
                                    while editor.cur() != '.' &&
                                          editor.cur() != '{' &&
                                          editor.cur() != ',' &&
                                          editor.cur() != ' ' &&
                                          editor.cur() != '}' &&
                                          editor.cur() != '(' &&
                                          editor.cur() != ')' &&
                                          editor.cur() != '[' &&
                                          editor.cur() != ']' &&
                                          editor.cur() != ';' &&
                                          editor.cur() != '"' &&
                                          editor.cur() != '\'' &&
                                          editor.cur() != '\n' &&
                                          editor.offset >= 1 {
                                        editor.left();
                                    }
                                },
                                (Normal, 'E') => {
                                    editor.right();
                                    while editor.cur() != ' ' && editor.offset < editor.string.len() {
                                        editor.right();
                                    }
                                },
                                (Normal, 'B') => {
                                    editor.left();
                                    while editor.cur() != ' ' && editor.offset >= 1 {
                                        editor.left();
                                    }
                                },
                                (Normal, ',') => {
                                    *is_recording = true;
                                    *period = String::new();
                                },
                                (Normal, '%') => {
                                    match editor.cur() {
                                        '(' | '[' | '{' => {
                                            let mut i = 1;
                                            while i != 0 &&
                                                  editor.offset < editor.string.len() {
                                                editor.right();
                                                i += match editor.cur() {
                                                    '(' | '[' | '{' => 1,
                                                    ')' | ']' | '}' => -1,
                                                    _ => 0,
                                                };
                                            }
                                        },
                                        ')' | ']' | '}' => {
                                            let mut i = 1;
                                            while i != 0 &&
                                                  editor.offset < editor.string.len() {
                                                editor.left();
                                                i += match editor.cur() {
                                                    '(' | '[' | '{' => -1,
                                                    ')' | ']' | '}' => 1,
                                                    _ => 0,
                                                };
                                            }
                                        },
                                        _ => {},

                                    }
                                },
                                (Normal, '!') => {
                                    for c in period.clone().chars() {
                                        exec(editor, mode, multiplier, last_change, KeyEvent {
                                            character: c,
                                            scancode: 0,
                                            pressed: true,
                                        }, window, swap, period, is_recording, clipboard);
                                    }
                                },
                                (Insert, '\0') => (),
                                (Insert, c) => {
                                    editor.insert(c, window);
                                },
                                _ => {},
                            }
                        }
                    }
                    is_none = true;
                }
            }

            if !is_none {
                *multiplier = Some(times);
            } else {
                *multiplier = None;
            }
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>tests(AppSettings): adds some additional tests<commit_after><|endoftext|>


<commit_before><commit_msg>Add rust code for phone-number case<commit_after>#![feature(ascii_ctype)]
use std::ascii::AsciiExt;

fn check_countrycode(mut phone: Vec<u8>) -> Option<String> {
    println!("{:?}", phone);

    if phone[0] != b'1' {
        return None;
    }

    String::from_utf8(phone.drain(1..).collect()).ok()
}

pub fn number(phone: &str) -> Option<String> {
    let result = phone
        .chars()
        .filter(|x| x.is_ascii_digit())
        .map(|x| x as u8)
        .collect::<Vec<u8>>();

    match result.len() {
        11 => check_countrycode(result),
        10 => String::from_utf8(result).ok(),
        _ => None,
    }
}

pub fn area_code(phone: &str) -> Option<String> {
    number(phone).map(|r| r[..3].to_string())
}

pub fn pretty_print(phone: &str) -> String {
    let v = number(phone);

    if v.is_none() {
        return "invalid".to_string();
    }

    let r = v.unwrap();

    format!("({}) {}-{}", &r[..3], &r[3..6], &r[6..])
}
<|endoftext|>


<commit_before>struct A;          // Concrete type `A`.
struct S(A);       // Concrete type `S`.
struct SGen<T>(T); // Generic type `SGen`.

// These functions all take ownership of the variable passed into
// them and immediately go out of scope freeing the variable.

// Define a function `reg_fn` that takes an argument `s` of type `S`.
// This has no `<T>` so this is not a generic function.
fn reg_fn(s: S) {}

// Define a function `gen_spec_t` that takes an argument `s` of type `SGen<T>`
// that has been explicitly given the type parameter `A`. Because A has not
// been specified as a generic type parameter for gen_spec_t, it is not generic.
fn gen_spec_t(s: SGen<A>) {}

// Define a function `gen_spec_i32` that takes an argument `s` of type `SGen<i32>`
// that has been explicitly given the type parameter `i32`.
// This function is also not generic.
fn gen_spec_i32(s: SGen<i32>) {}

// Define a function `generic` that takes an argument `s` of type `SGen<T>`.
// Because `SGen<T>` is preceded by `<T>`, this function is generic over `T`.
fn generic<T>(s: SGen<T>) {}

fn main() {
    // Using the non-generic functions
    reg_fn(S(A));          // Concrete type.
    gen_spec_t(SGen(A));   // Implicitly specified type parameter `A`.
    gen_spec_i32(SGen(6)); // Implicitly specified type parameter `i32`.

    // Explicitly specified type parameter `char` to `generic()`.
    generic::<char>(SGen('a'));

    // Implicitly specified type parameter `char` to `generic()`.
    generic(SGen('c'));
}

<commit_msg>generics/gen_fn: fix warning about unused variable<commit_after>struct A;          // Concrete type `A`.
struct S(A);       // Concrete type `S`.
struct SGen<T>(T); // Generic type `SGen`.

// These functions all take ownership of the variable passed into
// them and immediately go out of scope freeing the variable.

// Define a function `reg_fn` that takes an argument `s` of type `S`.
// This has no `<T>` so this is not a generic function.
fn reg_fn(_s: S) {}

// Define a function `gen_spec_t` that takes an argument `s` of type `SGen<T>`
// that has been explicitly given the type parameter `A`. Because A has not
// been specified as a generic type parameter for gen_spec_t, it is not generic.
fn gen_spec_t(_s: SGen<A>) {}

// Define a function `gen_spec_i32` that takes an argument `s` of type `SGen<i32>`
// that has been explicitly given the type parameter `i32`.
// This function is also not generic.
fn gen_spec_i32(_s: SGen<i32>) {}

// Define a function `generic` that takes an argument `s` of type `SGen<T>`.
// Because `SGen<T>` is preceded by `<T>`, this function is generic over `T`.
fn generic<T>(_s: SGen<T>) {}

fn main() {
    // Using the non-generic functions
    reg_fn(S(A));          // Concrete type.
    gen_spec_t(SGen(A));   // Implicitly specified type parameter `A`.
    gen_spec_i32(SGen(6)); // Implicitly specified type parameter `i32`.

    // Explicitly specified type parameter `char` to `generic()`.
    generic::<char>(SGen('a'));

    // Implicitly specified type parameter `char` to `generic()`.
    generic(SGen('c'));
}

<|endoftext|>


<commit_before><commit_msg>using multiple mode functions in single import:<commit_after><|endoftext|>


<commit_before><commit_msg>add Alphanumeric String Sort implmentation in Rust<commit_after>use std::iter::FromIterator;

fn sort(string: &str) -> String {
  let mut ords : [Vec<char>; 4] = Default::default();
  for ch in string.chars() {
    match ch {
      'a'..= 'z' => ords[0].push(ch),
      'A'..= 'Z' => ords[1].push(ch),
      '0'..= '9' if ch.to_digit(10).unwrap() % 2 == 0 => ords[2].push(ch),
      '0'..= '9' => ords[3].push(ch),
      _ => println!("{} is not alphanumeric", ch)
    }
  }
  let mut ord_string = String::new();
  for ord in ords.iter_mut() {
    ord.sort();
    ord_string.push_str(&String::from_iter(&*ord));
  }
  ord_string
}

fn main() {
  println!("{}", sort("Sorting0123456789"));// ginortS0246813579
}

mod tests {
  use super::sort;

  #[test]
  fn sorts() {
    assert_eq!("ginortS0246813579", sort("Sorting0123456789"));
  }

  #[test]
  fn sorts_lowercase() {
    assert_eq!("abfoor2244811337", sort("foobar1237348421"));
  }

  #[test]
  fn sorts_numbers() {
    assert_eq!("02466881355799", sort("90856123456789"));
  }

}
<|endoftext|>


<commit_before><commit_msg>Add problem #124<commit_after>#[crate_type = "rlib"];

extern mod extra;
extern mod math;

use extra::priority_queue::PriorityQueue;
use math::prime::Prime;

pub static EXPECTED_ANSWER: &'static str = "21417";

struct Multiple(uint, uint);

impl Ord for Multiple {
    #[inline]
    fn lt(&self, other: &Multiple) -> bool {
        let Multiple(ref sn, _) = *self;
        let Multiple(ref on, _) = *other;
        on.lt(sn)
    }
}

struct Multiples {
    facts: ~[uint],
    queue: PriorityQueue<Multiple>
}

impl Multiples {
    #[inline]
    fn new(base: uint, facts: ~[uint]) -> Multiples {
        let mut queue = PriorityQueue::new();
        queue.push(Multiple(base, 0));
        Multiples { facts: facts, queue: queue }
    }
}

impl Iterator<uint> for Multiples {
    #[inline]
    fn next(&mut self) -> Option<uint> {
        if self.queue.is_empty() { return None }

        let Multiple(n, i) = self.queue.pop();

        if i < self.facts.len() {
            // n = ... * f[i]^k => ... * f[i]^(k+1)
            self.queue.push(Multiple(n * self.facts[i], i));
        }

        for j in range(i + 1, self.facts.len()) {
            // n = ... * f[i]^k => ... * f[i]^k * f[j]
            self.queue.push(Multiple(n * self.facts[j], j));
        }

        Some(n)
    }
}

struct RadValue(uint, ~[uint], uint);

impl Ord for RadValue {
    #[inline]
    fn lt(&self, other: &RadValue) -> bool {
        let RadValue(ref sn, _, _) = *self;
        let RadValue(ref on, _, _) = *other;
        on.lt(sn)
    }
}

struct RadValues {
    prime: Prime,
    queue: PriorityQueue<RadValue>
}

impl RadValues {
    #[inline]
    fn new() -> RadValues {
        let mut queue = PriorityQueue::new();
        queue.push(RadValue(1, ~[], 0));
        RadValues { prime: Prime::new(), queue: queue }
    }
}

impl Iterator<(uint, ~[uint])> for RadValues {
    #[inline]
    fn next(&mut self) -> Option<(uint, ~[uint])> {
        let RadValue(n, facts, i) = self.queue.pop();
        let p = self.prime.nth(i);

        // n = ... * p[i-1] => ... * p[i-1] * p[i] (append p[i])
        self.queue.push(RadValue(n * p, facts + &[p], i + 1));

        if !facts.is_empty() {
            // n = ... * p[i-1] => ... * p[i] (replace p[i-1] with p[i])
            let last = *facts.last();
            let mut next_facts = facts.clone();
            next_facts[next_facts.len() - 1] = p;
            self.queue.push(RadValue(p * n / last, next_facts, i + 1));
        }

        Some((n, facts))
    }
}

pub fn solve() -> ~str {
    static LIMIT: uint = 100000;
    let index = 10000;

    RadValues::new()
        .take_while(|&(n, _)| n <= LIMIT)
        .flat_map(|(base, facts)| Multiples::new(base, facts).take_while(|&n| n <= LIMIT))
        .nth(index - 1)
        .unwrap()
        .to_str()
}

#[cfg(test)]
mod test {
    use super::{Multiples, RadValues};

    #[test]
    fn rad_nums() {
        let mut it = RadValues::new();
        assert_eq!(Some((1, ~[])), it.next());
        assert_eq!(Some((2, ~[2])), it.next());
        assert_eq!(Some((3, ~[3])), it.next());
        assert_eq!(Some((5, ~[5])), it.next());
        assert_eq!(Some((6, ~[2, 3])), it.next());
        assert_eq!(Some((7, ~[7])), it.next());
        assert_eq!(Some((10, ~[2, 5])), it.next());
        assert_eq!(Some((11, ~[11])), it.next());
        assert_eq!(Some((13, ~[13])), it.next());
        assert_eq!(Some((14, ~[2, 7])), it.next());
        assert_eq!(Some((15, ~[3, 5])), it.next());
        assert_eq!(Some((17, ~[17])), it.next());
        assert_eq!(Some((19, ~[19])), it.next());
        assert_eq!(Some((21, ~[3, 7])), it.next());
        assert_eq!(Some((22, ~[2, 11])), it.next());
        assert_eq!(Some((23, ~[23])), it.next());
        assert_eq!(Some((26, ~[2, 13])), it.next());
        assert_eq!(Some((29, ~[29])), it.next());
        assert_eq!(Some((30, ~[2, 3, 5])), it.next());
    }

    #[test]
    fn prod_nums() {
        let mut it = Multiples::new(1, ~[]);
        assert_eq!(Some(1), it.next());
        assert_eq!(None, it.next());

        let mut it = Multiples::new(2, ~[2]);
        assert_eq!(Some(2), it.next());
        assert_eq!(Some(4), it.next());
        assert_eq!(Some(8), it.next());
        assert_eq!(Some(16), it.next());
        assert_eq!(Some(32), it.next());

        let mut it = Multiples::new(6, ~[2, 3]);
        assert_eq!(Some(6 * 1), it.next());
        assert_eq!(Some(6 * 2), it.next());
        assert_eq!(Some(6 * 3), it.next());
        assert_eq!(Some(6 * 4), it.next());
        assert_eq!(Some(6 * 6), it.next());
        assert_eq!(Some(6 * 8), it.next());
        assert_eq!(Some(6 * 9), it.next());
        assert_eq!(Some(6 * 12), it.next());
        assert_eq!(Some(6 * 16), it.next());
        assert_eq!(Some(6 * 18), it.next());
        assert_eq!(Some(6 * 24), it.next());

        let mut it = Multiples::new(30, ~[2, 3, 5]);
        assert_eq!(Some(30 * 1), it.next());
        assert_eq!(Some(30 * 2), it.next());
        assert_eq!(Some(30 * 3), it.next());
        assert_eq!(Some(30 * 4), it.next());
        assert_eq!(Some(30 * 5), it.next());
        assert_eq!(Some(30 * 6), it.next());
        assert_eq!(Some(30 * 8), it.next());
        assert_eq!(Some(30 * 9), it.next());
        assert_eq!(Some(30 * 10), it.next());
        assert_eq!(Some(30 * 12), it.next());
        assert_eq!(Some(30 * 15), it.next());
        assert_eq!(Some(30 * 16), it.next());
        assert_eq!(Some(30 * 18), it.next());
        assert_eq!(Some(30 * 20), it.next());
        assert_eq!(Some(30 * 24), it.next());
        assert_eq!(Some(30 * 25), it.next());
    }

    #[test]
    fn rad() {
        let mut it = RadValues::new()
            .take_while(|&(n, _)| n <= 10)
            .flat_map(|(base, facts)| Multiples::new(base, facts).take_while(|&n| n <= 10));

        assert_eq!(Some(1), it.next());
        assert_eq!(Some(2), it.next());
        assert_eq!(Some(4), it.next());
        assert_eq!(Some(8), it.next());
        assert_eq!(Some(3), it.next());
        assert_eq!(Some(9), it.next());
        assert_eq!(Some(5), it.next());
        assert_eq!(Some(6), it.next());
        assert_eq!(Some(7), it.next());
        assert_eq!(Some(10), it.next());
        assert_eq!(None, it.next());
    }
}

#[cfg(test)]
mod bench {
    use extra::test::BenchHarness;
    use super::RadValues;

    #[bench]
    fn rad_value_below_10000(bh: &mut BenchHarness) {
        bh.iter(|| for _n in RadValues::new().take_while(|&(n, _)| n < 10000) {})
    }
}
<|endoftext|>


<commit_before><commit_msg>Add an example derived from #15.<commit_after><|endoftext|>


<commit_before><commit_msg>Refactor(syncfile): update some comments<commit_after><|endoftext|>


<commit_before><commit_msg>Incomplete implementation of a TOML parser<commit_after>/// A TOML [1] configuration file parser
///
/// [1]: https://github.com/mojombo/toml

use std::io::mem::MemReader;
use std::io::File;
use std::hashmap::HashMap;

fn read_char(rd: &mut MemReader) -> char {
  match rd.read_byte() {
    Some(b) => b as char,
    None => fail!()
  }
}

#[deriving(ToStr)]
enum Value {
    True,
    False,
    Unsigned(u64),
    Integer(i64),
    Float(f64),
    String(~str),
    Array(~[Value]),
    Datetime, // XXX
    Map(HashMap<~str, Value>)
}

// parse values recursivly
fn parse_value(rd: &mut MemReader) -> Value {
    enum State {
        st_value,
        st_number,
        st_got_number
    }

    let mut state: State = st_value;
    let mut val: ~str = ~"";

    loop {
        match state {
            st_value => {
                if rd.eof() { fail!() }
                let ch = read_char(rd);
                match ch {
                    '\r' | '\n' | ' ' | '\t' => { }
                    '0' .. '9' => {
                        val.push_char(ch);
                        state = st_number;
                    }
                    't' => {
                        assert!(read_char(rd) == 'r');
                        assert!(read_char(rd) == 'u');
                        assert!(read_char(rd) == 'e');
                        return True
                    }
                    'f' => {
                        assert!(read_char(rd) == 'a');
                        assert!(read_char(rd) == 'l');
                        assert!(read_char(rd) == 's');
                        assert!(read_char(rd) == 'e');
                        return False
                    }
                    '"' => {
                        loop {
                            let ch = read_char(rd);
                            if ch == '"' {
                                break;
                            }
                            val.push_char(ch);
                        }
                        return String(val)
                    }
                    _ => { fail!() }
                }
            }
            st_got_number => {
                return Unsigned(from_str(val).unwrap())
            }
            st_number => {
                if rd.eof() {
                    state = st_got_number;
                } else {
                    let ch = read_char(rd);
                    match ch {
                        '\r' | '\n' | ' ' | '\t' => { state = st_got_number }
                        '0' .. '9' => {
                            val.push_char(ch);
                        }
                        _ => { fail!() }
                    }
                }
            }
        }
    }
}

fn parse(rd: &mut MemReader) -> HashMap<~str, Value> {
    enum State {
        st_toplevel,
        st_comment,
        st_section,
        st_ident,
        st_assign_wanted,
        st_value_wanted
    }

    let mut state = st_toplevel;
    let mut buf: ~str = ~"";
    let mut path: ~str = ~"";

    let mut root = HashMap::new();

    loop {
        match state {
            st_toplevel => {
                if rd.eof() { break }
                let ch = read_char(rd);
                match ch {
                    // ignore whitespace
                    '\r' | '\n' | ' ' | '\t' => { }

                    // comment
                    '#' => { state = st_comment }

                    // section
                    '[' => { state = st_section }

                    // identifier
                    'a' .. 'z' | 'A' .. 'Z' | '_' => {
                        state = st_ident;
                        buf.push_char(ch)
                    }

                    _ => { fail!() }
                }
            }
            st_comment => {
                if rd.eof() { break }
                match read_char(rd) {
                    '\n' => { state = st_toplevel }
                    _ => { }
                }
            }
            st_section => {
                if rd.eof() { fail!() }
                let ch = read_char(rd);
                match ch {
                    'a' .. 'z' | 'A' .. 'Z' | '0' .. '9' | '.' | '_'=> {
                        buf.push_char(ch);
                    }
                    ']' => {
                        debug!("Section: {}", buf);
                        path = buf.clone();
                        buf.truncate(0);
                        state = st_toplevel;
                    }
                    _ => { fail!() }
                }
            }
            st_ident => {
                if rd.eof() { fail!() }
                let ch = read_char(rd);
                match ch {
                    'a' .. 'z' | 'A' .. 'Z' | '0' .. '9' | '_'=> {
                        buf.push_char(ch);
                    }

                    '\r' | '\n' | ' ' | '\t' => { state = st_assign_wanted }

                    '=' => { state = st_value_wanted }

                    _ => { fail!() }
                }
            }
            st_assign_wanted => {
                if rd.eof() { fail!() }
                match read_char(rd) {
                    '\r' | '\n' | ' ' | '\t' => { }
                    '=' => { state = st_value_wanted }
                    _ => { fail!() }
                }
            }
            st_value_wanted => {
                debug!("Key: {}", buf);
                let val = parse_value(rd);

                debug!("Value: {:?}", val);
                debug!("Path: {}", path);

                // XXX: split path
                let mut m = root.find_or_insert(path.clone(), Map(HashMap::new())); // XXX: remove clone
                match *m {
                    Map(ref mut map) => {
                        let fresh = map.insert(buf.clone(), val);
                        assert!(fresh == true);
                    }
                    _ => { fail!("Invalid TOML") }
                }

                buf.truncate(0);
                state = st_toplevel;
            }
        }
    }

    return root;
}

fn main() {
  let contents = File::open(&Path::new(std::os::args()[1])).read_to_end();
  let mut rd = MemReader::new(contents);
  let root = parse(&mut rd);
  println!("{:s}", root.to_str());
}
<|endoftext|>


<commit_before><commit_msg>example to ilustract open_auth<commit_after>/*
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library.  If not, see
 * <http://www.gnu.org/licenses/>.
 *
 * Sahid Orentino Ferdjaoui <sahid.ferdjaoui@redhat.com>
 */

//! A trivial example to ilustract how to setup a connection auth
//! hanlder.
//!
//! By default the program try to connect to
//! 'test+tcp://127.0.0.1/default'
//!
//! An example of libvirtd configuration for sasl:
//!
//! ```
//!  listen_tls=0
//!  listen_tcp=1
//!  auth_tcp=sasl
//!  listen_addr="127.0.0.1"
//! ```
//!
//! Then to create user nad password:
//!
//! ```
//! saslpasswd2 -a libvirt user
//! ```

extern crate virt;

use std::{env, io};

use virt::connect::{Connect, ConnectCredential, ConnectAuth};

fn main() {
    let uri = match env::args().nth(1) {
        Some(u) => u,
        None => String::from("test+tcp://127.0.0.1/default"),
    };

    fn callback(creds: &mut Vec<ConnectCredential>) {
        for cred in creds {
            let mut input = String::new();

            println!("{}:", cred.prompt);
            match cred.typed {
                ::virt::connect::VIR_CRED_AUTHNAME => {
                    io::stdin().read_line(&mut input).expect("");
                    cred.result = Some(String::from(input.trim()));
                }
                ::virt::connect::VIR_CRED_PASSPHRASE => {
                    io::stdin().read_line(&mut input).expect("");
                    cred.result = Some(String::from(input.trim()));
                }
                _ => {
                    panic!("Should not be here...");
                }
            }
        }
    };
    let mut auth = ConnectAuth::new(vec![::virt::connect::VIR_CRED_AUTHNAME,
                                         ::virt::connect::VIR_CRED_PASSPHRASE],
                                    callback);

    println!("Attempting to connect to hypervisor: '{}'...", uri);
    let mut conn = match Connect::open_auth(&uri, &mut auth, 0) {
        Ok(c) => {
            println!("Connected");
            c
        }
        Err(e) => panic!("Not connected, code: {}, message: {}", e.code, e.message),
    };
    if let Err(e) = conn.close() {
        panic!("Failed to disconnect from hypervisor: code {}, message: {}",
               e.code,
               e.message);
    }
}
<|endoftext|>


<commit_before><commit_msg>	new file:   src/daemon.rs<commit_after><|endoftext|>


<commit_before><commit_msg>List interfaces example<commit_after>// Copyright (c) 2014, 2015 Robert Clipsham <robert@octarineparrot.com>
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

/// This examples simply print all interfaces to stdout

extern crate pnet;

use pnet::datalink;

fn main() {
    for interface in datalink::interfaces() {
        let mac = interface.mac.map(|mac| mac.to_string()).unwrap_or("N/A".to_owned());
        println!("{}:", interface.name);
        println!("  index: {}", interface.index);
        println!("  flags: {}", interface.flags);
        println!("  MAC: {}", mac);
        println!("  IPs:");
        for ip in interface.ips {
            println!("    {:?}", ip);
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>Show current value in config subcommand<commit_after><|endoftext|>


<commit_before><commit_msg>Add Vulkan command buffer reset method<commit_after><|endoftext|>


<commit_before><commit_msg>Stop the Vulkan renderer from creating endless vertex array buffers by resetting the index each frame for the recently created N3 vertex array kind<commit_after><|endoftext|>


<commit_before><commit_msg>[Rust] Temporary variable and lifetime<commit_after>struct S;

fn f() -> Vec<S> {
    vec![S, S, S]
}

fn main() {
    let a = f().first();

}
<|endoftext|>


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

use ast;
use ext::tt::macro_parser;
use parse::{token, ParseSess};
use print::pprust;
use symbol::keywords;
use syntax_pos::{BytePos, Span, DUMMY_SP};
use tokenstream;

use std::rc::Rc;

/// Contains the sub-token-trees of a "delimited" token tree, such as the contents of `(`. Note
/// that the delimiter itself might be `NoDelim`.
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
pub struct Delimited {
    pub delim: token::DelimToken,
    pub tts: Vec<TokenTree>,
}

impl Delimited {
    /// Return the opening delimiter (possibly `NoDelim`).
    pub fn open_token(&self) -> token::Token {
        token::OpenDelim(self.delim)
    }

    /// Return the closing delimiter (possibly `NoDelim`).
    pub fn close_token(&self) -> token::Token {
        token::CloseDelim(self.delim)
    }

    /// Return a `self::TokenTree` witha a `Span` corresponding to the opening delimiter.
    pub fn open_tt(&self, span: Span) -> TokenTree {
        let open_span = if span == DUMMY_SP {
            DUMMY_SP
        } else {
            span.with_lo(span.lo() + BytePos(self.delim.len() as u32))
        };
        TokenTree::Token(open_span, self.open_token())
    }

    /// Return a `self::TokenTree` witha a `Span` corresponding to the closing delimiter.
    pub fn close_tt(&self, span: Span) -> TokenTree {
        let close_span = if span == DUMMY_SP {
            DUMMY_SP
        } else {
            span.with_lo(span.hi() - BytePos(self.delim.len() as u32))
        };
        TokenTree::Token(close_span, self.close_token())
    }
}

#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
pub struct SequenceRepetition {
    /// The sequence of token trees
    pub tts: Vec<TokenTree>,
    /// The optional separator
    pub separator: Option<token::Token>,
    /// Whether the sequence can be repeated zero (*), or one or more times (+)
    pub op: KleeneOp,
    /// The number of `Match`s that appear in the sequence (and subsequences)
    pub num_captures: usize,
}

/// A Kleene-style [repetition operator](http://en.wikipedia.org/wiki/Kleene_star)
/// for token sequences.
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
pub enum KleeneOp {
    /// Kleene star (`*`) for zero or more repetitions
    ZeroOrMore,
    /// Kleene plus (`+`) for one or more repetitions
    OneOrMore,
}

/// Similar to `tokenstream::TokenTree`, except that `$i`, `$i:ident`, and `$(...)`
/// are "first-class" token trees. Useful for parsing macros.
#[derive(Debug, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash)]
pub enum TokenTree {
    Token(Span, token::Token),
    Delimited(Span, Rc<Delimited>),
    /// A kleene-style repetition sequence
    Sequence(Span, Rc<SequenceRepetition>),
    /// E.g. `$var`
    MetaVar(Span, ast::Ident),
    /// E.g. `$var:expr`. This is only used in the left hand side of MBE macros.
    MetaVarDecl(
        Span,
        ast::Ident, /* name to bind */
        ast::Ident, /* kind of nonterminal */
    ),
}

impl TokenTree {
    /// Return the number of tokens in the tree.
    pub fn len(&self) -> usize {
        match *self {
            TokenTree::Delimited(_, ref delimed) => match delimed.delim {
                token::NoDelim => delimed.tts.len(),
                _ => delimed.tts.len() + 2,
            },
            TokenTree::Sequence(_, ref seq) => seq.tts.len(),
            _ => 0,
        }
    }

    /// Returns true if the given token tree contains no other tokens. This is vacuously true for
    /// single tokens or metavar/decls, but may be false for delimited trees or sequences.
    pub fn is_empty(&self) -> bool {
        match *self {
            TokenTree::Delimited(_, ref delimed) => match delimed.delim {
                token::NoDelim => delimed.tts.is_empty(),
                _ => false,
            },
            TokenTree::Sequence(_, ref seq) => seq.tts.is_empty(),
            _ => true,
        }
    }

    /// Get the `index`-th sub-token-tree. This only makes sense for delimited trees and sequences.
    pub fn get_tt(&self, index: usize) -> TokenTree {
        match (self, index) {
            (&TokenTree::Delimited(_, ref delimed), _) if delimed.delim == token::NoDelim => {
                delimed.tts[index].clone()
            }
            (&TokenTree::Delimited(span, ref delimed), _) => {
                if index == 0 {
                    return delimed.open_tt(span);
                }
                if index == delimed.tts.len() + 1 {
                    return delimed.close_tt(span);
                }
                delimed.tts[index - 1].clone()
            }
            (&TokenTree::Sequence(_, ref seq), _) => seq.tts[index].clone(),
            _ => panic!("Cannot expand a token tree"),
        }
    }

    /// Retrieve the `TokenTree`'s span.
    pub fn span(&self) -> Span {
        match *self {
            TokenTree::Token(sp, _)
            | TokenTree::MetaVar(sp, _)
            | TokenTree::MetaVarDecl(sp, _, _)
            | TokenTree::Delimited(sp, _)
            | TokenTree::Sequence(sp, _) => sp,
        }
    }
}

/// Takes a `tokenstream::TokenStream` and returns a `Vec<self::TokenTree>`. Specifically, this
/// takes a generic `TokenStream`, such as is used in the rest of the compiler, and returns a
/// collection of `TokenTree` for use in parsing a macro.
///
/// # Parameters
///
/// - `input`: a token stream to read from, the contents of which we are parsing.
/// - `expect_matchers`: `parse` can be used to parse either the "patterns" or the "body" of a
///   macro. Both take roughly the same form _except_ that in a pattern, metavars are declared with
///   their "matcher" type. For example `$var:expr` or `$id:ident`. In this example, `expr` and
///   `ident` are "matchers". They are not present in the body of a macro rule -- just in the
///   pattern, so we pass a parameter to indicate whether to expect them or not.
/// - `sess`: the parsing session. Any errors will be emitted to this session.
///
/// # Returns
///
/// A collection of `self::TokenTree`. There may also be some errors emitted to `sess`.
pub fn parse(
    input: tokenstream::TokenStream,
    expect_matchers: bool,
    sess: &ParseSess,
) -> Vec<TokenTree> {
    // Will contain the final collection of `self::TokenTree`
    let mut result = Vec::new();

    // For each token tree in `input`, parse the token into a `self::TokenTree`, consuming
    // additional trees if need be.
    let mut trees = input.trees();
    while let Some(tree) = trees.next() {
        let tree = parse_tree(tree, &mut trees, expect_matchers, sess);

        // Given the parsed tree, if there is a metavar and we are expecting matchers, actually
        // parse out the matcher (i.e. in `$id:ident` this would parse the `:` and `ident`).
        match tree {
            TokenTree::MetaVar(start_sp, ident) if expect_matchers => {
                let span = match trees.next() {
                    Some(tokenstream::TokenTree::Token(span, token::Colon)) => match trees.next() {
                        Some(tokenstream::TokenTree::Token(end_sp, ref tok)) => match tok.ident() {
                            Some(kind) => {
                                let span = end_sp.with_lo(start_sp.lo());
                                result.push(TokenTree::MetaVarDecl(span, ident, kind));
                                continue;
                            }
                            _ => end_sp,
                        },
                        tree => tree.as_ref()
                            .map(tokenstream::TokenTree::span)
                            .unwrap_or(span),
                    },
                    tree => tree.as_ref()
                        .map(tokenstream::TokenTree::span)
                        .unwrap_or(start_sp),
                };
                sess.missing_fragment_specifiers.borrow_mut().insert(span);
                result.push(TokenTree::MetaVarDecl(
                    span,
                    ident,
                    keywords::Invalid.ident(),
                ));
            }

            // Not a metavar or no matchers allowed, so just return the tree
            _ => result.push(tree),
        }
    }
    result
}

/// Takes a `tokenstream::TokenTree` and returns a `self::TokenTree`. Specifically, this takes a
/// generic `TokenTree`, such as is used in the rest of the compiler, and returns a `TokenTree`
/// for use in parsing a macro.
///
/// Converting the given tree may involve reading more tokens.
///
/// # Parameters
///
/// - `tree`: the tree wish to convert.
/// - `trees`: an iterator over trees. We may need to read more tokens from it in order to finish
///   converting `tree`
/// - `expect_matchers`: same as for `parse` (see above).
/// - `sess`: the parsing session. Any errors will be emitted to this session.
fn parse_tree<I>(
    tree: tokenstream::TokenTree,
    trees: &mut I,
    expect_matchers: bool,
    sess: &ParseSess,
) -> TokenTree
where
    I: Iterator<Item = tokenstream::TokenTree>,
{
    // Depending on what `tree` is, we could be parsing different parts of a macro
    match tree {
        // `tree` is a `$` token. Look at the next token in `trees`
        tokenstream::TokenTree::Token(span, token::Dollar) => match trees.next() {
            // `tree` is followed by a delimited set of token trees. This indicates the beginning
            // of a repetition sequence in the macro (e.g. `$(pat)*`).
            Some(tokenstream::TokenTree::Delimited(span, delimited)) => {
                // Must have `(` not `{` or `[`
                if delimited.delim != token::Paren {
                    let tok = pprust::token_to_string(&token::OpenDelim(delimited.delim));
                    let msg = format!("expected `(`, found `{}`", tok);
                    sess.span_diagnostic.span_err(span, &msg);
                }
                // Parse the contents of the sequence itself
                let sequence = parse(delimited.tts.into(), expect_matchers, sess);
                // Get the Kleene operator and optional separator
                let (separator, op) = parse_sep_and_kleene_op(trees, span, sess);
                // Count the number of captured "names" (i.e. named metavars)
                let name_captures = macro_parser::count_names(&sequence);
                TokenTree::Sequence(
                    span,
                    Rc::new(SequenceRepetition {
                        tts: sequence,
                        separator,
                        op,
                        num_captures: name_captures,
                    }),
                )
            }

            // `tree` is followed by an `ident`. This could be `$meta_var` or the `$crate` special
            // metavariable that names the crate of the invokation.
            Some(tokenstream::TokenTree::Token(ident_span, ref token)) if token.is_ident() => {
                let ident = token.ident().unwrap();
                let span = ident_span.with_lo(span.lo());
                if ident.name == keywords::Crate.name() {
                    let ident = ast::Ident {
                        name: keywords::DollarCrate.name(),
                        ..ident
                    };
                    TokenTree::Token(span, token::Ident(ident))
                } else {
                    TokenTree::MetaVar(span, ident)
                }
            }

            // `tree` is followed by a random token. This is an error.
            Some(tokenstream::TokenTree::Token(span, tok)) => {
                let msg = format!(
                    "expected identifier, found `{}`",
                    pprust::token_to_string(&tok)
                );
                sess.span_diagnostic.span_err(span, &msg);
                TokenTree::MetaVar(span, keywords::Invalid.ident())
            }

            // There are no more tokens. Just return the `$` we already have.
            None => TokenTree::Token(span, token::Dollar),
        },

        // `tree` is an arbitrary token. Keep it.
        tokenstream::TokenTree::Token(span, tok) => TokenTree::Token(span, tok),

        // `tree` is the beginning of a delimited set of tokens (e.g. `(` or `{`). We need to
        // descend into the delimited set and further parse it.
        tokenstream::TokenTree::Delimited(span, delimited) => TokenTree::Delimited(
            span,
            Rc::new(Delimited {
                delim: delimited.delim,
                tts: parse(delimited.tts.into(), expect_matchers, sess),
            }),
        ),
    }
}

/// Attempt to parse a single Kleene star, possibly with a separator.
///
/// For example, in a pattern such as `$(a),*`, `a` is the pattern to be repeated, `,` is the
/// separator, and `*` is the Kleene operator. This function is specifically concerned with parsing
/// the last two tokens of such a pattern: namely, the optional separator and the Kleene operator
/// itself. Note that here we are parsing the _macro_ itself, rather than trying to match some
/// stream of tokens in an invokation of a macro.
///
/// This function will take some input iterator `input` corresponding to `span` and a parsing
/// session `sess`. If the next one (or possibly two) tokens in `input` correspond to a Kleene
/// operator and separator, then a tuple with `(separator, KleeneOp)` is returned. Otherwise, an
/// error with the appropriate span is emitted to `sess` and a dummy value is returned.
fn parse_sep_and_kleene_op<I>(
    input: &mut I,
    span: Span,
    sess: &ParseSess,
) -> (Option<token::Token>, KleeneOp)
where
    I: Iterator<Item = tokenstream::TokenTree>,
{
    fn kleene_op(token: &token::Token) -> Option<KleeneOp> {
        match *token {
            token::BinOp(token::Star) => Some(KleeneOp::ZeroOrMore),
            token::BinOp(token::Plus) => Some(KleeneOp::OneOrMore),
            _ => None,
        }
    }

    // We attempt to look at the next two token trees in `input`. I will call the first #1 and the
    // second #2. If #1 and #2 don't match a valid KleeneOp with/without separator, that is an
    // error, and we should emit an error on the most specific span possible.
    let span = match input.next() {
        // #1 is a token
        Some(tokenstream::TokenTree::Token(span, tok)) => match kleene_op(&tok) {
            // #1 is a KleeneOp with no separator
            Some(op) => return (None, op),

            // #1 is not a KleeneOp, but may be a separator... need to look at #2
            None => match input.next() {
                // #2 is a token
                Some(tokenstream::TokenTree::Token(span, tok2)) => match kleene_op(&tok2) {
                    // #2 is a KleeneOp, so #1 must be a separator
                    Some(op) => return (Some(tok), op),

                    // #2 is not a KleeneOp... error
                    None => span,
                },

                // #2 is not a token at all... error
                tree => tree.as_ref()
                    .map(tokenstream::TokenTree::span)
                    .unwrap_or(span),
            },
        },

        // #1 is not a token at all... error
        tree => tree.as_ref()
            .map(tokenstream::TokenTree::span)
            .unwrap_or(span),
    };

    // Error...
    sess.span_diagnostic.span_err(span, "expected `*` or `+`");
    (None, KleeneOp::ZeroOrMore)
}
<commit_msg>fix typos<commit_after>// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use ast;
use ext::tt::macro_parser;
use parse::{token, ParseSess};
use print::pprust;
use symbol::keywords;
use syntax_pos::{BytePos, Span, DUMMY_SP};
use tokenstream;

use std::rc::Rc;

/// Contains the sub-token-trees of a "delimited" token tree, such as the contents of `(`. Note
/// that the delimiter itself might be `NoDelim`.
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
pub struct Delimited {
    pub delim: token::DelimToken,
    pub tts: Vec<TokenTree>,
}

impl Delimited {
    /// Return the opening delimiter (possibly `NoDelim`).
    pub fn open_token(&self) -> token::Token {
        token::OpenDelim(self.delim)
    }

    /// Return the closing delimiter (possibly `NoDelim`).
    pub fn close_token(&self) -> token::Token {
        token::CloseDelim(self.delim)
    }

    /// Return a `self::TokenTree` with a `Span` corresponding to the opening delimiter.
    pub fn open_tt(&self, span: Span) -> TokenTree {
        let open_span = if span == DUMMY_SP {
            DUMMY_SP
        } else {
            span.with_lo(span.lo() + BytePos(self.delim.len() as u32))
        };
        TokenTree::Token(open_span, self.open_token())
    }

    /// Return a `self::TokenTree` with a `Span` corresponding to the closing delimiter.
    pub fn close_tt(&self, span: Span) -> TokenTree {
        let close_span = if span == DUMMY_SP {
            DUMMY_SP
        } else {
            span.with_lo(span.hi() - BytePos(self.delim.len() as u32))
        };
        TokenTree::Token(close_span, self.close_token())
    }
}

#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
pub struct SequenceRepetition {
    /// The sequence of token trees
    pub tts: Vec<TokenTree>,
    /// The optional separator
    pub separator: Option<token::Token>,
    /// Whether the sequence can be repeated zero (*), or one or more times (+)
    pub op: KleeneOp,
    /// The number of `Match`s that appear in the sequence (and subsequences)
    pub num_captures: usize,
}

/// A Kleene-style [repetition operator](http://en.wikipedia.org/wiki/Kleene_star)
/// for token sequences.
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
pub enum KleeneOp {
    /// Kleene star (`*`) for zero or more repetitions
    ZeroOrMore,
    /// Kleene plus (`+`) for one or more repetitions
    OneOrMore,
}

/// Similar to `tokenstream::TokenTree`, except that `$i`, `$i:ident`, and `$(...)`
/// are "first-class" token trees. Useful for parsing macros.
#[derive(Debug, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash)]
pub enum TokenTree {
    Token(Span, token::Token),
    Delimited(Span, Rc<Delimited>),
    /// A kleene-style repetition sequence
    Sequence(Span, Rc<SequenceRepetition>),
    /// E.g. `$var`
    MetaVar(Span, ast::Ident),
    /// E.g. `$var:expr`. This is only used in the left hand side of MBE macros.
    MetaVarDecl(
        Span,
        ast::Ident, /* name to bind */
        ast::Ident, /* kind of nonterminal */
    ),
}

impl TokenTree {
    /// Return the number of tokens in the tree.
    pub fn len(&self) -> usize {
        match *self {
            TokenTree::Delimited(_, ref delimed) => match delimed.delim {
                token::NoDelim => delimed.tts.len(),
                _ => delimed.tts.len() + 2,
            },
            TokenTree::Sequence(_, ref seq) => seq.tts.len(),
            _ => 0,
        }
    }

    /// Returns true if the given token tree contains no other tokens. This is vacuously true for
    /// single tokens or metavar/decls, but may be false for delimited trees or sequences.
    pub fn is_empty(&self) -> bool {
        match *self {
            TokenTree::Delimited(_, ref delimed) => match delimed.delim {
                token::NoDelim => delimed.tts.is_empty(),
                _ => false,
            },
            TokenTree::Sequence(_, ref seq) => seq.tts.is_empty(),
            _ => true,
        }
    }

    /// Get the `index`-th sub-token-tree. This only makes sense for delimited trees and sequences.
    pub fn get_tt(&self, index: usize) -> TokenTree {
        match (self, index) {
            (&TokenTree::Delimited(_, ref delimed), _) if delimed.delim == token::NoDelim => {
                delimed.tts[index].clone()
            }
            (&TokenTree::Delimited(span, ref delimed), _) => {
                if index == 0 {
                    return delimed.open_tt(span);
                }
                if index == delimed.tts.len() + 1 {
                    return delimed.close_tt(span);
                }
                delimed.tts[index - 1].clone()
            }
            (&TokenTree::Sequence(_, ref seq), _) => seq.tts[index].clone(),
            _ => panic!("Cannot expand a token tree"),
        }
    }

    /// Retrieve the `TokenTree`'s span.
    pub fn span(&self) -> Span {
        match *self {
            TokenTree::Token(sp, _)
            | TokenTree::MetaVar(sp, _)
            | TokenTree::MetaVarDecl(sp, _, _)
            | TokenTree::Delimited(sp, _)
            | TokenTree::Sequence(sp, _) => sp,
        }
    }
}

/// Takes a `tokenstream::TokenStream` and returns a `Vec<self::TokenTree>`. Specifically, this
/// takes a generic `TokenStream`, such as is used in the rest of the compiler, and returns a
/// collection of `TokenTree` for use in parsing a macro.
///
/// # Parameters
///
/// - `input`: a token stream to read from, the contents of which we are parsing.
/// - `expect_matchers`: `parse` can be used to parse either the "patterns" or the "body" of a
///   macro. Both take roughly the same form _except_ that in a pattern, metavars are declared with
///   their "matcher" type. For example `$var:expr` or `$id:ident`. In this example, `expr` and
///   `ident` are "matchers". They are not present in the body of a macro rule -- just in the
///   pattern, so we pass a parameter to indicate whether to expect them or not.
/// - `sess`: the parsing session. Any errors will be emitted to this session.
///
/// # Returns
///
/// A collection of `self::TokenTree`. There may also be some errors emitted to `sess`.
pub fn parse(
    input: tokenstream::TokenStream,
    expect_matchers: bool,
    sess: &ParseSess,
) -> Vec<TokenTree> {
    // Will contain the final collection of `self::TokenTree`
    let mut result = Vec::new();

    // For each token tree in `input`, parse the token into a `self::TokenTree`, consuming
    // additional trees if need be.
    let mut trees = input.trees();
    while let Some(tree) = trees.next() {
        let tree = parse_tree(tree, &mut trees, expect_matchers, sess);

        // Given the parsed tree, if there is a metavar and we are expecting matchers, actually
        // parse out the matcher (i.e. in `$id:ident` this would parse the `:` and `ident`).
        match tree {
            TokenTree::MetaVar(start_sp, ident) if expect_matchers => {
                let span = match trees.next() {
                    Some(tokenstream::TokenTree::Token(span, token::Colon)) => match trees.next() {
                        Some(tokenstream::TokenTree::Token(end_sp, ref tok)) => match tok.ident() {
                            Some(kind) => {
                                let span = end_sp.with_lo(start_sp.lo());
                                result.push(TokenTree::MetaVarDecl(span, ident, kind));
                                continue;
                            }
                            _ => end_sp,
                        },
                        tree => tree.as_ref()
                            .map(tokenstream::TokenTree::span)
                            .unwrap_or(span),
                    },
                    tree => tree.as_ref()
                        .map(tokenstream::TokenTree::span)
                        .unwrap_or(start_sp),
                };
                sess.missing_fragment_specifiers.borrow_mut().insert(span);
                result.push(TokenTree::MetaVarDecl(
                    span,
                    ident,
                    keywords::Invalid.ident(),
                ));
            }

            // Not a metavar or no matchers allowed, so just return the tree
            _ => result.push(tree),
        }
    }
    result
}

/// Takes a `tokenstream::TokenTree` and returns a `self::TokenTree`. Specifically, this takes a
/// generic `TokenTree`, such as is used in the rest of the compiler, and returns a `TokenTree`
/// for use in parsing a macro.
///
/// Converting the given tree may involve reading more tokens.
///
/// # Parameters
///
/// - `tree`: the tree we wish to convert.
/// - `trees`: an iterator over trees. We may need to read more tokens from it in order to finish
///   converting `tree`
/// - `expect_matchers`: same as for `parse` (see above).
/// - `sess`: the parsing session. Any errors will be emitted to this session.
fn parse_tree<I>(
    tree: tokenstream::TokenTree,
    trees: &mut I,
    expect_matchers: bool,
    sess: &ParseSess,
) -> TokenTree
where
    I: Iterator<Item = tokenstream::TokenTree>,
{
    // Depending on what `tree` is, we could be parsing different parts of a macro
    match tree {
        // `tree` is a `$` token. Look at the next token in `trees`
        tokenstream::TokenTree::Token(span, token::Dollar) => match trees.next() {
            // `tree` is followed by a delimited set of token trees. This indicates the beginning
            // of a repetition sequence in the macro (e.g. `$(pat)*`).
            Some(tokenstream::TokenTree::Delimited(span, delimited)) => {
                // Must have `(` not `{` or `[`
                if delimited.delim != token::Paren {
                    let tok = pprust::token_to_string(&token::OpenDelim(delimited.delim));
                    let msg = format!("expected `(`, found `{}`", tok);
                    sess.span_diagnostic.span_err(span, &msg);
                }
                // Parse the contents of the sequence itself
                let sequence = parse(delimited.tts.into(), expect_matchers, sess);
                // Get the Kleene operator and optional separator
                let (separator, op) = parse_sep_and_kleene_op(trees, span, sess);
                // Count the number of captured "names" (i.e. named metavars)
                let name_captures = macro_parser::count_names(&sequence);
                TokenTree::Sequence(
                    span,
                    Rc::new(SequenceRepetition {
                        tts: sequence,
                        separator,
                        op,
                        num_captures: name_captures,
                    }),
                )
            }

            // `tree` is followed by an `ident`. This could be `$meta_var` or the `$crate` special
            // metavariable that names the crate of the invokation.
            Some(tokenstream::TokenTree::Token(ident_span, ref token)) if token.is_ident() => {
                let ident = token.ident().unwrap();
                let span = ident_span.with_lo(span.lo());
                if ident.name == keywords::Crate.name() {
                    let ident = ast::Ident {
                        name: keywords::DollarCrate.name(),
                        ..ident
                    };
                    TokenTree::Token(span, token::Ident(ident))
                } else {
                    TokenTree::MetaVar(span, ident)
                }
            }

            // `tree` is followed by a random token. This is an error.
            Some(tokenstream::TokenTree::Token(span, tok)) => {
                let msg = format!(
                    "expected identifier, found `{}`",
                    pprust::token_to_string(&tok)
                );
                sess.span_diagnostic.span_err(span, &msg);
                TokenTree::MetaVar(span, keywords::Invalid.ident())
            }

            // There are no more tokens. Just return the `$` we already have.
            None => TokenTree::Token(span, token::Dollar),
        },

        // `tree` is an arbitrary token. Keep it.
        tokenstream::TokenTree::Token(span, tok) => TokenTree::Token(span, tok),

        // `tree` is the beginning of a delimited set of tokens (e.g. `(` or `{`). We need to
        // descend into the delimited set and further parse it.
        tokenstream::TokenTree::Delimited(span, delimited) => TokenTree::Delimited(
            span,
            Rc::new(Delimited {
                delim: delimited.delim,
                tts: parse(delimited.tts.into(), expect_matchers, sess),
            }),
        ),
    }
}

/// Attempt to parse a single Kleene star, possibly with a separator.
///
/// For example, in a pattern such as `$(a),*`, `a` is the pattern to be repeated, `,` is the
/// separator, and `*` is the Kleene operator. This function is specifically concerned with parsing
/// the last two tokens of such a pattern: namely, the optional separator and the Kleene operator
/// itself. Note that here we are parsing the _macro_ itself, rather than trying to match some
/// stream of tokens in an invocation of a macro.
///
/// This function will take some input iterator `input` corresponding to `span` and a parsing
/// session `sess`. If the next one (or possibly two) tokens in `input` correspond to a Kleene
/// operator and separator, then a tuple with `(separator, KleeneOp)` is returned. Otherwise, an
/// error with the appropriate span is emitted to `sess` and a dummy value is returned.
fn parse_sep_and_kleene_op<I>(
    input: &mut I,
    span: Span,
    sess: &ParseSess,
) -> (Option<token::Token>, KleeneOp)
where
    I: Iterator<Item = tokenstream::TokenTree>,
{
    fn kleene_op(token: &token::Token) -> Option<KleeneOp> {
        match *token {
            token::BinOp(token::Star) => Some(KleeneOp::ZeroOrMore),
            token::BinOp(token::Plus) => Some(KleeneOp::OneOrMore),
            _ => None,
        }
    }

    // We attempt to look at the next two token trees in `input`. I will call the first #1 and the
    // second #2. If #1 and #2 don't match a valid KleeneOp with/without separator, that is an
    // error, and we should emit an error on the most specific span possible.
    let span = match input.next() {
        // #1 is a token
        Some(tokenstream::TokenTree::Token(span, tok)) => match kleene_op(&tok) {
            // #1 is a KleeneOp with no separator
            Some(op) => return (None, op),

            // #1 is not a KleeneOp, but may be a separator... need to look at #2
            None => match input.next() {
                // #2 is a token
                Some(tokenstream::TokenTree::Token(span, tok2)) => match kleene_op(&tok2) {
                    // #2 is a KleeneOp, so #1 must be a separator
                    Some(op) => return (Some(tok), op),

                    // #2 is not a KleeneOp... error
                    None => span,
                },

                // #2 is not a token at all... error
                tree => tree.as_ref()
                    .map(tokenstream::TokenTree::span)
                    .unwrap_or(span),
            },
        },

        // #1 is not a token at all... error
        tree => tree.as_ref()
            .map(tokenstream::TokenTree::span)
            .unwrap_or(span),
    };

    // Error...
    sess.span_diagnostic.span_err(span, "expected `*` or `+`");
    (None, KleeneOp::ZeroOrMore)
}
<|endoftext|>


<commit_before><commit_msg>rust example of lifetime event handling<commit_after>/**
 * In terms of C++, rust lack of constuctor ... as alternative there is Default traits to
 * initilize object with some default values
 * bash-3.2$ rustc -A unused_variables lifetime.rs
 *
 * bash-3.2$ ./lifetime
main started
scope started
B(0x7fff571df328)::drop
scope ended
main ended
B(0x7fff571df3a0)::drop
B(0x7fff571df3a8)::drop
 */

struct A;

struct B;

impl Drop for B {
  fn drop(&mut self) {
    println! ("B({:p})::drop", self);
  }
}

fn main() {
   println!("main started");
   let x = A;
   let a = B;
   let b = B;
   println!("x:{:p}, a:{:p}, b:{:p}", &x, &a, &b);
   println!("scope started");
   {
	let c = B;
	println!("c:{:p}", &c);
   }
   println!("scope ended");
   println!("main ended");
}
<|endoftext|>


<commit_before><commit_msg>test: Add a test case for issue #362, "ret none".<commit_after>tag option[T] { none; some(T); }

fn f[T]() -> option[T] { ret none; }

fn main() { f[int](); }

<|endoftext|>


<commit_before><commit_msg>Auto merge of #25271 - asajeffrey:gstplugin-glthread, r=Manishearth<commit_after><|endoftext|>


<commit_before><commit_msg>add libmruby build.rs<commit_after>
use std::io::Command;
use std::io::fs::PathExtensions;

fn main() {
    let mruby = &Path::new("./libmruby.a");
    if !mruby.exists() {
        let git = Command::new("git")
            .arg(" clone https://github.com/mruby/mruby ")
            .status().unwrap();
        if !git.success() {
            panic!("fail to clone");
        }
        let build = Command::new("make").cwd(&Path::new("./mruby"))
            .env("CFLAGS","-fPIC -std=c99").status().unwrap();
        if !build.success() {
            panic!("fail to build");
        }
        let copy = Command::new("cp")
            .cwd(&Path::new("./mruby"))
            .arg("build/host/lib/libmruby.a")
            .arg("../")
            .status().unwrap();
        if !copy.success() {
            panic!("fail to cp");
        }
    }
}
<|endoftext|>