<commit_before>use collections::string::String;

use core::mem::size_of;
use core::ops::{BitOrAssign, ShlAssign};

const ZERO_OP: u8 = 0x00;
const ONE_OP: u8 = 0x01;
const NAME_OP: u8 = 0x08;
const BYTE_PREFIX: u8 = 0x0A;
const WORD_PREFIX: u8 = 0x0B;
const DWORD_PREFIX: u8 = 0x0C;
const STRING_PREFIX: u8 = 0x0D;
const QWORD_PREFIX: u8 = 0x0E;
const SCOPE_OP: u8 = 0x10;
const BUFFER_OP: u8 = 0x11;
const PACKAGE_OP: u8 = 0x12;
const METHOD_OP: u8 = 0x14;
const DUAL_NAME_PREFIX: u8 = 0x2E;
const MULTI_NAME_PREFIX: u8 = 0x2F;
const EXT_OP_PREFIX: u8 = 0x5B;
const ROOT_PREFIX: u8 = 0x5C;
const PARENT_PREFIX: u8 = 0x5E;

// EXT
const MUTEX_OP: u8 = 0x01;
const OP_REGION_OP: u8 = 0x80;
const FIELD_OP: u8 = 0x81;
const DEVICE_OP: u8 = 0x82;
const PROCESSOR_OP: u8 = 0x83;

pub fn parse_string(bytes: &[u8], i: &mut usize) -> String {
    let mut string = String::new();

    while *i < bytes.len() {
        let c = bytes[*i];
        if (c >= 0x30 && c <= 0x39) || (c >= 0x41 && c <= 0x5A) || c == 0x5F ||
           c == ROOT_PREFIX || c == PARENT_PREFIX {
            string.push(c as char);
        } else {
            break;
        }

        *i += 1;
    }

    string
}

// This one function required three different unstable features and four trait requirements. Why is generic math so hard?
pub fn parse_num<T: BitOrAssign + From<u8> + ShlAssign<usize>>(bytes: &[u8],
                                                                      i: &mut usize)
                                                                      -> T {
    let mut num: T = T::from(0);

    let mut shift = 0;
    while *i < bytes.len() && shift < size_of::<T>() * 8 {
        let mut b = T::from(bytes[*i]);
        b <<= shift;
        num |= b;
        shift += 8;
        *i += 1;
    }

    num
}

pub fn parse_length(bytes: &[u8], i: &mut usize) -> usize {
    let mut length = 0;

    if *i < bytes.len() {
        let b = bytes[*i] as usize;

        let mut follow = (b & 0b11000000) >> 6;
        if follow == 0 {
            length += b & 0b111111;
        } else {
            length += b & 0b1111;
        }

        *i += 1;

        let mut shift = 4;
        while *i < bytes.len() && follow > 0 {
            length += (bytes[*i] as usize) << shift;

            shift += 8;
            follow -= 1;
            *i += 1;
        }
    }

    length
}

pub fn parse_name(bytes: &[u8], i: &mut usize) -> String {
    let mut name = String::new();

    let mut count = 0;
    while *i < bytes.len() {
        match bytes[*i] {
            ZERO_OP => {
                *i += 1;

                count = 0;
                break;
            }
            DUAL_NAME_PREFIX => {
                *i += 1;

                count = 2;
                break;
            }
            MULTI_NAME_PREFIX => {
                *i += 1;

                if *i < bytes.len() {
                    count = bytes[*i];
                    *i += 1;
                }

                break;
            }
            ROOT_PREFIX => {
                *i += 1;

                name.push('\\');
            }
            PARENT_PREFIX => {
                *i += 1;

                name.push('^');
            }
            _ => {
                count = 1;
                break;
            }
        };
    }

    while count > 0 {
        if !name.is_empty() {
            name.push('.');
        }

        let end = *i + 4;
        let mut leading = true;
        while *i < bytes.len() && *i < end {
            let c = bytes[*i];
            if (c >= 0x30 && c <= 0x39) || (c >= 0x41 && c <= 0x5A) {
                leading = false;
                name.push(c as char);
            } else if c == 0x5F {
                if leading {
                    name.push('_');
                }
            } else {
                syslog_debug!("parse_name: unknown: {:02X}", c);
                break;
            }

            *i += 1;
        }

        *i = end;

        count -= 1;
    }

    name
}

pub fn parse_int(bytes: &[u8], i: &mut usize) -> u64 {
    if *i < bytes.len() {
        let b = bytes[*i];
        *i += 1;

        match b {
            ZERO_OP => return 0,
            ONE_OP => return 1,
            BYTE_PREFIX => return parse_num::<u8>(bytes, i) as u64,
            WORD_PREFIX => return parse_num::<u16>(bytes, i) as u64,
            DWORD_PREFIX => return parse_num::<u32>(bytes, i) as u64,
            QWORD_PREFIX => return parse_num::<u64>(bytes, i),
            _ => syslog_debug!("parse_int: unknown: {:02X}", b),
        }
    }

    return 0;
}

pub fn parse_package(bytes: &[u8], i: &mut usize) {

    let end = *i + parse_length(bytes, i);
    let elements = parse_num::<u8>(bytes, i);

    syslog_debug!("    Package ({})", elements);
    syslog_debug!("    {{");
    while *i < bytes.len() && *i < end {
        let op = bytes[*i];
        *i += 1;

        match op {
            ZERO_OP => {
                syslog_debug!("        Zero");
            }
            ONE_OP => {
                syslog_debug!("        One");
            }
            BYTE_PREFIX => {
                syslog_debug!("        {:02X}", parse_num::<u8>(bytes, i));
            }
            WORD_PREFIX => {
                syslog_debug!("        {:04X}", parse_num::<u16>(bytes, i));
            }
            DWORD_PREFIX => {
                syslog_debug!("        {:08X}", parse_num::<u32>(bytes, i));
            }
            QWORD_PREFIX => {
                syslog_debug!("        {:016X}", parse_num::<u64>(bytes, i));
            }
            PACKAGE_OP => {
                parse_package(bytes, i);
            }
            _ => {
                *i -= 1;
                syslog_debug!("        {}", parse_name(bytes, i));
                // syslog_debug!("        parse_package: unknown: {:02X}", op);
            }
        }
    }
    syslog_debug!("    }}");

    *i = end;
}

pub fn parse_device(bytes: &[u8], i: &mut usize) {
    let end = *i + parse_length(bytes, i);
    let name = parse_name(bytes, i);

    syslog_debug!("    Device ({})", name);
    syslog_debug!("    {{");
    while *i < bytes.len() && *i < end {
        let op = bytes[*i];
        *i += 1;

        match op {
            ZERO_OP => {
                syslog_debug!("        Zero");
            }
            ONE_OP => {
                syslog_debug!("        One");
            }
            BYTE_PREFIX => {
                syslog_debug!("        {:02X}", parse_num::<u8>(bytes, i));
            }
            WORD_PREFIX => {
                syslog_debug!("        {:04X}", parse_num::<u16>(bytes, i));
            }
            DWORD_PREFIX => {
                syslog_debug!("        {:08X}", parse_num::<u32>(bytes, i));
            }
            STRING_PREFIX => {
                syslog_debug!("        {}", parse_string(bytes, i));
            }
            QWORD_PREFIX => {
                syslog_debug!("        {:016X}", parse_num::<u64>(bytes, i));
            }
            NAME_OP => {
                syslog_debug!("        Name({})", parse_string(bytes, i));
            }
            METHOD_OP => {
                let end = *i + parse_length(bytes, i);
                let name = parse_name(bytes, i);
                let flags = parse_num::<u8>(bytes, i);

                syslog_debug!("        Method ({}, {})", name, flags);
                syslog_debug!("        {{");
                syslog_debug!("        }}");

                *i = end;
            }
            BUFFER_OP => {
                let end = *i + parse_length(bytes, i);

                let count = parse_int(bytes, i);

                syslog_debug!("        Buffer ({})", count);

                *i = end;
            }
            PACKAGE_OP => {
                parse_package(bytes, i);
            }
            EXT_OP_PREFIX => {
                if *i < bytes.len() {
                    let ext_op = bytes[*i];
                    *i += 1;

                    match ext_op {
                        OP_REGION_OP => {
                            let name = parse_name(bytes, i);
                            let space = parse_num::<u8>(bytes, i);
                            let offset = parse_int(bytes, i);
                            let size = parse_int(bytes, i);

                            syslog_debug!("        OperationRegion ({}, {}, {}, {})",
                                     name,
                                     space,
                                     offset,
                                     size);
                        }
                        FIELD_OP => {
                            let end = *i + parse_length(bytes, i);

                            let name = parse_name(bytes, i);
                            let flags = parse_num::<u8>(bytes, i);

                            syslog_debug!("        Field ({}, {})", name, flags);
                            syslog_debug!("        {{");
                            while *i < bytes.len() && *i < end {
                                let name = parse_name(bytes, i);
                                let length = parse_length(bytes, i);

                                syslog_debug!("            {}, {}", name, length);
                            }
                            syslog_debug!("        }}");

                            *i = end;
                        }
                        _ => syslog_debug!("        Unknown EXT: {:02X}", ext_op),
                    }
                }
            }
            _ => {
                syslog_debug!("        parse_device: unknown: {:02X}", op);
                break;
            }
        }
    }
    syslog_debug!("    }}");

    *i = end;
}

pub fn parse_scope(bytes: &[u8], i: &mut usize) {
    let end = *i + parse_length(bytes, i);
    let name = parse_name(bytes, i);

    syslog_debug!("Scope ({})", name);
    syslog_debug!("{{");
    while *i < bytes.len() && *i < end {
        let op = bytes[*i];
        *i += 1;

        match op {
            ZERO_OP => {
                syslog_debug!("    Zero");
            }
            ONE_OP => {
                syslog_debug!("    One");
            }
            BYTE_PREFIX => {
                syslog_debug!("    {:02X}", parse_num::<u8>(bytes, i));
            }
            WORD_PREFIX => {
                syslog_debug!("    {:04X}", parse_num::<u16>(bytes, i));
            }
            DWORD_PREFIX => {
                syslog_debug!("    {:08X}", parse_num::<u32>(bytes, i));
            }
            STRING_PREFIX => {
                syslog_debug!("    {}", parse_string(bytes, i));
            }
            QWORD_PREFIX => {
                syslog_debug!("    {:016X}", parse_num::<u64>(bytes, i));
            }
            SCOPE_OP => {
                parse_scope(bytes, i);
            }
            NAME_OP => {
                syslog_debug!("    Name({})", parse_string(bytes, i));
            }
            METHOD_OP => {
                let end = *i + parse_length(bytes, i);
                let name = parse_name(bytes, i);
                let flags = parse_num::<u8>(bytes, i);

                syslog_debug!("    Method ({}, {})", name, flags);
                syslog_debug!("    {{");
                syslog_debug!("    }}");

                *i = end;
            }
            BUFFER_OP => {
                let end = *i + parse_length(bytes, i);

                let count = parse_int(bytes, i);

                syslog_debug!("    Buffer ({})", count);

                *i = end;
            }
            PACKAGE_OP => {
                parse_package(bytes, i);
            }
            EXT_OP_PREFIX => {
                if *i < bytes.len() {
                    let ext_op = bytes[*i];
                    *i += 1;

                    match ext_op {
                        MUTEX_OP => {
                            let name = parse_name(bytes, i);
                            let flags = parse_num::<u8>(bytes, i);

                            syslog_debug!("    Mutex ({}, {})", name, flags);
                        }
                        OP_REGION_OP => {
                            let name = parse_name(bytes, i);
                            let space = parse_num::<u8>(bytes, i);
                            let offset = parse_int(bytes, i);
                            let size = parse_int(bytes, i);

                            syslog_debug!("    OperationRegion ({}, {}, {}, {})",
                                     name,
                                     space,
                                     offset,
                                     size);
                        }
                        FIELD_OP => {
                            let end = *i + parse_length(bytes, i);

                            let name = parse_name(bytes, i);
                            let flags = parse_num::<u8>(bytes, i);

                            syslog_debug!("    Field ({}, {})", name, flags);
                            syslog_debug!("    {{");
                            while *i < bytes.len() && *i < end {
                                let name = parse_name(bytes, i);
                                let length = parse_length(bytes, i);

                                syslog_debug!("        {}, {}", name, length);
                            }
                            syslog_debug!("    }}");

                            *i = end;
                        }
                        DEVICE_OP => {
                            parse_device(bytes, i);
                        }
                        PROCESSOR_OP => {
                            let end = *i + parse_length(bytes, i);

                            let name = parse_name(bytes, i);
                            // let id = parse_num::<u8>(bytes, i);
                            // let blk = parse_num::<u32>(bytes, i);
                            // let blklen = parse_num::<u8>(bytes, i);
                            //

                            syslog_debug!("    Processor ({})", name);

                            *i = end;
                        }
                        _ => syslog_debug!("    Unknown EXT: {:02X}", ext_op),
                    }
                }
            }
            _ => {
                syslog_debug!("    parse_scope: unknown: {:02X}", op);
                break;
            }
        }
    }
    syslog_debug!("}}");

    *i = end;
}

pub fn parse(bytes: &[u8]) {
    for (i, op) in bytes.iter().enumerate() {
        match *op {
            SCOPE_OP => {
                parse_scope(bytes, &mut (i + 1));
            }
            _ => {
                syslog_debug!("parse: unknown: {:02X}", *op);
                break;
            }
        }
    }
}
<commit_msg>Refactor in `acpi::aml::parse_string()` (#690)<commit_after>use collections::string::String;

use core::mem::size_of;
use core::ops::{BitOrAssign, ShlAssign};

const ZERO_OP: u8 = 0x00;
const ONE_OP: u8 = 0x01;
const NAME_OP: u8 = 0x08;
const BYTE_PREFIX: u8 = 0x0A;
const WORD_PREFIX: u8 = 0x0B;
const DWORD_PREFIX: u8 = 0x0C;
const STRING_PREFIX: u8 = 0x0D;
const QWORD_PREFIX: u8 = 0x0E;
const SCOPE_OP: u8 = 0x10;
const BUFFER_OP: u8 = 0x11;
const PACKAGE_OP: u8 = 0x12;
const METHOD_OP: u8 = 0x14;
const DUAL_NAME_PREFIX: u8 = 0x2E;
const MULTI_NAME_PREFIX: u8 = 0x2F;
const EXT_OP_PREFIX: u8 = 0x5B;
const ROOT_PREFIX: u8 = 0x5C;
const PARENT_PREFIX: u8 = 0x5E;

// EXT
const MUTEX_OP: u8 = 0x01;
const OP_REGION_OP: u8 = 0x80;
const FIELD_OP: u8 = 0x81;
const DEVICE_OP: u8 = 0x82;
const PROCESSOR_OP: u8 = 0x83;

pub fn parse_string(bytes: &[u8], i: &mut usize) -> String {
    bytes.iter().skip(*i).scan((), |_, &c| {
        if (c >= 0x30 && c <= 0x39) || (c >= 0x41 && c <= 0x5A) || c == 0x5F ||
            c == ROOT_PREFIX || c == PARENT_PREFIX {
            *i += 1;
            Some(c as char)
        } else {
            None
        }
    }).collect()
}

// This one function required three different unstable features and four trait requirements. Why is generic math so hard?
pub fn parse_num<T: BitOrAssign + From<u8> + ShlAssign<usize>>(bytes: &[u8],
                                                               i: &mut usize)
                                                               -> T {
    let mut num: T = T::from(0);

    let mut shift = 0;
    while *i < bytes.len() && shift < size_of::<T>() * 8 {
        let mut b = T::from(bytes[*i]);
        b <<= shift;
        num |= b;
        shift += 8;
        *i += 1;
    }

    num
}

pub fn parse_length(bytes: &[u8], i: &mut usize) -> usize {
    let mut length = 0;

    if *i < bytes.len() {
        let b = bytes[*i] as usize;

        let mut follow = (b & 0b11000000) >> 6;
        if follow == 0 {
            length += b & 0b111111;
        } else {
            length += b & 0b1111;
        }

        *i += 1;

        let mut shift = 4;
        while *i < bytes.len() && follow > 0 {
            length += (bytes[*i] as usize) << shift;

            shift += 8;
            follow -= 1;
            *i += 1;
        }
    }

    length
}

pub fn parse_name(bytes: &[u8], i: &mut usize) -> String {
    let mut name = String::new();

    let mut count = 0;
    while *i < bytes.len() {
        match bytes[*i] {
            ZERO_OP => {
                *i += 1;

                count = 0;
                break;
            }
            DUAL_NAME_PREFIX => {
                *i += 1;

                count = 2;
                break;
            }
            MULTI_NAME_PREFIX => {
                *i += 1;

                if *i < bytes.len() {
                    count = bytes[*i];
                    *i += 1;
                }

                break;
            }
            ROOT_PREFIX => {
                *i += 1;

                name.push('\\');
            }
            PARENT_PREFIX => {
                *i += 1;

                name.push('^');
            }
            _ => {
                count = 1;
                break;
            }
        };
    }

    while count > 0 {
        if !name.is_empty() {
            name.push('.');
        }

        let end = *i + 4;
        let mut leading = true;
        while *i < bytes.len() && *i < end {
            let c = bytes[*i];
            if (c >= 0x30 && c <= 0x39) || (c >= 0x41 && c <= 0x5A) {
                leading = false;
                name.push(c as char);
            } else if c == 0x5F {
                if leading {
                    name.push('_');
                }
            } else {
                syslog_debug!("parse_name: unknown: {:02X}", c);
                break;
            }

            *i += 1;
        }

        *i = end;

        count -= 1;
    }

    name
}

pub fn parse_int(bytes: &[u8], i: &mut usize) -> u64 {
    if *i < bytes.len() {
        let b = bytes[*i];
        *i += 1;

        match b {
            ZERO_OP => return 0,
            ONE_OP => return 1,
            BYTE_PREFIX => return parse_num::<u8>(bytes, i) as u64,
            WORD_PREFIX => return parse_num::<u16>(bytes, i) as u64,
            DWORD_PREFIX => return parse_num::<u32>(bytes, i) as u64,
            QWORD_PREFIX => return parse_num::<u64>(bytes, i),
            _ => syslog_debug!("parse_int: unknown: {:02X}", b),
        }
    }

    return 0;
}

pub fn parse_package(bytes: &[u8], i: &mut usize) {

    let end = *i + parse_length(bytes, i);
    let elements = parse_num::<u8>(bytes, i);

    syslog_debug!("    Package ({})", elements);
    syslog_debug!("    {{");
    while *i < bytes.len() && *i < end {
        let op = bytes[*i];
        *i += 1;

        match op {
            ZERO_OP => {
                syslog_debug!("        Zero");
            }
            ONE_OP => {
                syslog_debug!("        One");
            }
            BYTE_PREFIX => {
                syslog_debug!("        {:02X}", parse_num::<u8>(bytes, i));
            }
            WORD_PREFIX => {
                syslog_debug!("        {:04X}", parse_num::<u16>(bytes, i));
            }
            DWORD_PREFIX => {
                syslog_debug!("        {:08X}", parse_num::<u32>(bytes, i));
            }
            QWORD_PREFIX => {
                syslog_debug!("        {:016X}", parse_num::<u64>(bytes, i));
            }
            PACKAGE_OP => {
                parse_package(bytes, i);
            }
            _ => {
                *i -= 1;
                syslog_debug!("        {}", parse_name(bytes, i));
                // syslog_debug!("        parse_package: unknown: {:02X}", op);
            }
        }
    }
    syslog_debug!("    }}");

    *i = end;
}

pub fn parse_device(bytes: &[u8], i: &mut usize) {
    let end = *i + parse_length(bytes, i);
    let name = parse_name(bytes, i);

    syslog_debug!("    Device ({})", name);
    syslog_debug!("    {{");
    while *i < bytes.len() && *i < end {
        let op = bytes[*i];
        *i += 1;

        match op {
            ZERO_OP => {
                syslog_debug!("        Zero");
            }
            ONE_OP => {
                syslog_debug!("        One");
            }
            BYTE_PREFIX => {
                syslog_debug!("        {:02X}", parse_num::<u8>(bytes, i));
            }
            WORD_PREFIX => {
                syslog_debug!("        {:04X}", parse_num::<u16>(bytes, i));
            }
            DWORD_PREFIX => {
                syslog_debug!("        {:08X}", parse_num::<u32>(bytes, i));
            }
            STRING_PREFIX => {
                syslog_debug!("        {}", parse_string(bytes, i));
            }
            QWORD_PREFIX => {
                syslog_debug!("        {:016X}", parse_num::<u64>(bytes, i));
            }
            NAME_OP => {
                syslog_debug!("        Name({})", parse_string(bytes, i));
            }
            METHOD_OP => {
                let end = *i + parse_length(bytes, i);
                let name = parse_name(bytes, i);
                let flags = parse_num::<u8>(bytes, i);

                syslog_debug!("        Method ({}, {})", name, flags);
                syslog_debug!("        {{");
                syslog_debug!("        }}");

                *i = end;
            }
            BUFFER_OP => {
                let end = *i + parse_length(bytes, i);

                let count = parse_int(bytes, i);

                syslog_debug!("        Buffer ({})", count);

                *i = end;
            }
            PACKAGE_OP => {
                parse_package(bytes, i);
            }
            EXT_OP_PREFIX => {
                if *i < bytes.len() {
                    let ext_op = bytes[*i];
                    *i += 1;

                    match ext_op {
                        OP_REGION_OP => {
                            let name = parse_name(bytes, i);
                            let space = parse_num::<u8>(bytes, i);
                            let offset = parse_int(bytes, i);
                            let size = parse_int(bytes, i);

                            syslog_debug!("        OperationRegion ({}, {}, {}, {})",
                                     name,
                                     space,
                                     offset,
                                     size);
                        }
                        FIELD_OP => {
                            let end = *i + parse_length(bytes, i);

                            let name = parse_name(bytes, i);
                            let flags = parse_num::<u8>(bytes, i);

                            syslog_debug!("        Field ({}, {})", name, flags);
                            syslog_debug!("        {{");
                            while *i < bytes.len() && *i < end {
                                let name = parse_name(bytes, i);
                                let length = parse_length(bytes, i);

                                syslog_debug!("            {}, {}", name, length);
                            }
                            syslog_debug!("        }}");

                            *i = end;
                        }
                        _ => syslog_debug!("        Unknown EXT: {:02X}", ext_op),
                    }
                }
            }
            _ => {
                syslog_debug!("        parse_device: unknown: {:02X}", op);
                break;
            }
        }
    }
    syslog_debug!("    }}");

    *i = end;
}

pub fn parse_scope(bytes: &[u8], i: &mut usize) {
    let end = *i + parse_length(bytes, i);
    let name = parse_name(bytes, i);

    syslog_debug!("Scope ({})", name);
    syslog_debug!("{{");
    while *i < bytes.len() && *i < end {
        let op = bytes[*i];
        *i += 1;

        match op {
            ZERO_OP => {
                syslog_debug!("    Zero");
            }
            ONE_OP => {
                syslog_debug!("    One");
            }
            BYTE_PREFIX => {
                syslog_debug!("    {:02X}", parse_num::<u8>(bytes, i));
            }
            WORD_PREFIX => {
                syslog_debug!("    {:04X}", parse_num::<u16>(bytes, i));
            }
            DWORD_PREFIX => {
                syslog_debug!("    {:08X}", parse_num::<u32>(bytes, i));
            }
            STRING_PREFIX => {
                syslog_debug!("    {}", parse_string(bytes, i));
            }
            QWORD_PREFIX => {
                syslog_debug!("    {:016X}", parse_num::<u64>(bytes, i));
            }
            SCOPE_OP => {
                parse_scope(bytes, i);
            }
            NAME_OP => {
                syslog_debug!("    Name({})", parse_string(bytes, i));
            }
            METHOD_OP => {
                let end = *i + parse_length(bytes, i);
                let name = parse_name(bytes, i);
                let flags = parse_num::<u8>(bytes, i);

                syslog_debug!("    Method ({}, {})", name, flags);
                syslog_debug!("    {{");
                syslog_debug!("    }}");

                *i = end;
            }
            BUFFER_OP => {
                let end = *i + parse_length(bytes, i);

                let count = parse_int(bytes, i);

                syslog_debug!("    Buffer ({})", count);

                *i = end;
            }
            PACKAGE_OP => {
                parse_package(bytes, i);
            }
            EXT_OP_PREFIX => {
                if *i < bytes.len() {
                    let ext_op = bytes[*i];
                    *i += 1;

                    match ext_op {
                        MUTEX_OP => {
                            let name = parse_name(bytes, i);
                            let flags = parse_num::<u8>(bytes, i);

                            syslog_debug!("    Mutex ({}, {})", name, flags);
                        }
                        OP_REGION_OP => {
                            let name = parse_name(bytes, i);
                            let space = parse_num::<u8>(bytes, i);
                            let offset = parse_int(bytes, i);
                            let size = parse_int(bytes, i);

                            syslog_debug!("    OperationRegion ({}, {}, {}, {})",
                                     name,
                                     space,
                                     offset,
                                     size);
                        }
                        FIELD_OP => {
                            let end = *i + parse_length(bytes, i);

                            let name = parse_name(bytes, i);
                            let flags = parse_num::<u8>(bytes, i);

                            syslog_debug!("    Field ({}, {})", name, flags);
                            syslog_debug!("    {{");
                            while *i < bytes.len() && *i < end {
                                let name = parse_name(bytes, i);
                                let length = parse_length(bytes, i);

                                syslog_debug!("        {}, {}", name, length);
                            }
                            syslog_debug!("    }}");

                            *i = end;
                        }
                        DEVICE_OP => {
                            parse_device(bytes, i);
                        }
                        PROCESSOR_OP => {
                            let end = *i + parse_length(bytes, i);

                            let name = parse_name(bytes, i);
                            // let id = parse_num::<u8>(bytes, i);
                            // let blk = parse_num::<u32>(bytes, i);
                            // let blklen = parse_num::<u8>(bytes, i);
                            //

                            syslog_debug!("    Processor ({})", name);

                            *i = end;
                        }
                        _ => syslog_debug!("    Unknown EXT: {:02X}", ext_op),
                    }
                }
            }
            _ => {
                syslog_debug!("    parse_scope: unknown: {:02X}", op);
                break;
            }
        }
    }
    syslog_debug!("}}");

    *i = end;
}

pub fn parse(bytes: &[u8]) {
    for (i, op) in bytes.iter().enumerate() {
        match *op {
            SCOPE_OP => {
                parse_scope(bytes, &mut (i + 1));
            }
            _ => {
                syslog_debug!("parse: unknown: {:02X}", *op);
                break;
            }
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>Init from func return with params<commit_after><|endoftext|>


<commit_before><commit_msg>kernel: panic support<commit_after><|endoftext|>


<commit_before><commit_msg>add an `ignore` utility function<commit_after><|endoftext|>


<commit_before>/// External linking is a complex implementation to be able to serve a clean and easy-to-use
/// interface.
///
/// Internally, there are no such things as "external links" (plural). Each Entry in the store can
/// only have _one_ external link.
///
/// This library does the following therefor: It allows you to have several external links with one
/// entry, which are internally one file in the store for each link, linked with "internal
/// linking".
///
/// This helps us greatly with deduplication of URLs.
///

use std::ops::Deref;
use std::ops::DerefMut;
use std::collections::BTreeMap;

use libimagstore::store::Entry;
use libimagstore::store::FileLockEntry;
use libimagstore::store::Store;
use libimagstore::storeid::StoreId;
use libimagstore::storeid::IntoStoreId;

use error::LinkError as LE;
use error::LinkErrorKind as LEK;
use result::Result;
use internal::InternalLinker;
use module_path::ModuleEntryPath;

use toml::Value;
use url::Url;
use crypto::sha1::Sha1;
use crypto::digest::Digest;

/// "Link" Type, just an abstraction over FileLockEntry to have some convenience internally.
struct Link<'a> {
    link: FileLockEntry<'a>
}

impl<'a> Link<'a> {

    pub fn new(fle: FileLockEntry<'a>) -> Link<'a> {
        Link { link: fle }
    }

    /// For interal use only. Load an Link from a store id, if this is actually a Link
    fn retrieve(store: &'a Store, id: StoreId) -> Result<Option<Link<'a>>> {
        store.retrieve(id)
            .map(|fle| {
                if let Some(_) = Link::get_link_uri_from_filelockentry(&fle) {
                    Some(Link {
                        link: fle
                    })
                } else {
                    None
                }
            })
            .map_err(|e| LE::new(LEK::StoreReadError, Some(Box::new(e))))
    }

    /// Get a link Url object from a FileLockEntry, ignore errors.
    fn get_link_uri_from_filelockentry(file: &FileLockEntry<'a>) -> Option<Url> {
        file.deref()
            .get_header()
            .read("imag.content.uri")
            .ok()
            .and_then(|opt| {
                match opt {
                    Some(Value::String(s)) => Url::parse(&s[..]).ok(),
                    _ => None
                }
            })
    }

    pub fn get_url(&self) -> Result<Option<Url>> {
        let opt = self.link
            .deref()
            .get_header()
            .read("imag.content.uri");

        match opt {
            Ok(Some(Value::String(s))) => {
                Url::parse(&s[..])
                     .map(|s| Some(s))
                     .map_err(|e| LE::new(LEK::EntryHeaderReadError, Some(Box::new(e))))
            },
            Ok(None) => Ok(None),
            _ => Err(LE::new(LEK::EntryHeaderReadError, None))
        }
    }

}

pub trait ExternalLinker : InternalLinker {

    /// Get the external links from the implementor object
    fn get_external_links(&self, store: &Store) -> Result<Vec<Url>>;

    /// Set the external links for the implementor object
    fn set_external_links(&mut self, store: &Store, links: Vec<Url>) -> Result<()>;

    /// Add an external link to the implementor object
    fn add_external_link(&mut self, store: &Store, link: Url) -> Result<()>;

    /// Remove an external link from the implementor object
    fn remove_external_link(&mut self, store: &Store, link: Url) -> Result<()>;

}

/// Check whether the StoreId starts with `/link/external/`
fn is_link_store_id(id: &StoreId) -> bool {
    debug!("Checking whether this is a /link/external/*: '{:?}'", id);
    id.starts_with("/link/external/")
}

fn get_external_link_from_file(entry: &FileLockEntry) -> Result<Url> {
    Link::get_link_uri_from_filelockentry(entry) // TODO: Do not hide error by using this function
        .ok_or(LE::new(LEK::StoreReadError, None))
}

/// Implement ExternalLinker for Entry, hiding the fact that there is no such thing as an external
/// link in an entry, but internal links to other entries which serve as external links, as one
/// entry in the store can only have one external link.
impl ExternalLinker for Entry {

    /// Get the external links from the implementor object
    fn get_external_links(&self, store: &Store) -> Result<Vec<Url>> {
        // Iterate through all internal links and filter for FileLockEntries which live in
        // /link/external/<SHA> -> load these files and get the external link from their headers,
        // put them into the return vector.
        self.get_internal_links()
            .map(|vect| {
                debug!("Getting external links");
                vect.into_iter()
                    .filter(is_link_store_id)
                    .map(|id| {
                        debug!("Retrieving entry for id: '{:?}'", id);
                        match store.retrieve(id.clone()) {
                            Ok(f) => get_external_link_from_file(&f),
                            Err(e) => {
                                debug!("Retrieving entry for id: '{:?}' failed", id);
                                Err(LE::new(LEK::StoreReadError, Some(Box::new(e))))
                            }
                        }
                    })
                    .filter_map(|x| x.ok()) // TODO: Do not ignore error here
                    .collect()
            })
            .map_err(|e| LE::new(LEK::StoreReadError, Some(Box::new(e))))
    }

    /// Set the external links for the implementor object
    fn set_external_links(&mut self, store: &Store, links: Vec<Url>) -> Result<()> {
        // Take all the links, generate a SHA sum out of each one, filter out the already existing
        // store entries and store the other URIs in the header of one FileLockEntry each, in
        // the path /link/external/<SHA of the URL>

        debug!("Iterating {} links = {:?}", links.len(), links);
        for link in links { // for all links
            let hash = {
                let mut s = Sha1::new();
                s.input_str(&link.serialize()[..]);
                s.result_str()
            };
            let file_id = ModuleEntryPath::new(format!("external/{}", hash)).into_storeid();

            debug!("Link    = '{:?}'", link);
            debug!("Hash    = '{:?}'", hash);
            debug!("StoreId = '{:?}'", file_id);

            // retrieve the file from the store, which implicitely creates the entry if it does not
            // exist
            let file = store.retrieve(file_id.clone());
            if file.is_err() {
                debug!("Failed to create or retrieve an file for this link '{:?}'", link);
                return Err(LE::new(LEK::StoreWriteError, Some(Box::new(file.err().unwrap()))));
            }
            let mut file = file.unwrap();

            debug!("Generating header content!");
            {
                let mut hdr = file.deref_mut().get_header_mut();

                let mut table = match hdr.read("imag.content") {
                    Ok(Some(Value::Table(table))) => table,
                    Ok(Some(_)) => {
                        warn!("There is a value at 'imag.content' which is not a table.");
                        warn!("Going to override this value");
                        BTreeMap::new()
                    },
                    Ok(None) => BTreeMap::new(),
                    Err(e)   => return Err(LE::new(LEK::StoreWriteError, Some(Box::new(e)))),
                };

                let v = Value::String(link.serialize());

                debug!("setting URL = '{:?}", v);
                table.insert(String::from("url"), v);

                if let Err(e) = hdr.set("imag.content", Value::Table(table)) {
                    return Err(LE::new(LEK::StoreWriteError, Some(Box::new(e))));
                } else {
                    debug!("Setting URL worked");
                }
            }

            // then add an internal link to the new file or return an error if this fails
            if let Err(e) = self.add_internal_link(file.deref_mut()) {
                debug!("Error adding internal link");
                return Err(LE::new(LEK::StoreWriteError, Some(Box::new(e))));
            }
        }
        debug!("Ready iterating");
        Ok(())
    }

    /// Add an external link to the implementor object
    fn add_external_link(&mut self, store: &Store, link: Url) -> Result<()> {
        // get external links, add this one, save them
        debug!("Getting links");
        self.get_external_links(store)
            .and_then(|mut links| {
                debug!("Adding link = '{:?}' to links = {:?}", link, links);
                links.push(link);
                debug!("Setting {} links = {:?}", links.len(), links);
                self.set_external_links(store, links)
            })
    }

    /// Remove an external link from the implementor object
    fn remove_external_link(&mut self, store: &Store, link: Url) -> Result<()> {
        // get external links, remove this one, save them
        self.get_external_links(store)
            .and_then(|links| {
                debug!("Removing link = '{:?}' from links = {:?}", link, links);
                let links = links.into_iter()
                    .filter(|l| l.serialize() != link.serialize())
                    .collect();
                self.set_external_links(store, links)
            })
    }

}

<commit_msg>Remove unneeded deref() call<commit_after>/// External linking is a complex implementation to be able to serve a clean and easy-to-use
/// interface.
///
/// Internally, there are no such things as "external links" (plural). Each Entry in the store can
/// only have _one_ external link.
///
/// This library does the following therefor: It allows you to have several external links with one
/// entry, which are internally one file in the store for each link, linked with "internal
/// linking".
///
/// This helps us greatly with deduplication of URLs.
///

use std::ops::DerefMut;
use std::collections::BTreeMap;

use libimagstore::store::Entry;
use libimagstore::store::FileLockEntry;
use libimagstore::store::Store;
use libimagstore::storeid::StoreId;
use libimagstore::storeid::IntoStoreId;

use error::LinkError as LE;
use error::LinkErrorKind as LEK;
use result::Result;
use internal::InternalLinker;
use module_path::ModuleEntryPath;

use toml::Value;
use url::Url;
use crypto::sha1::Sha1;
use crypto::digest::Digest;

/// "Link" Type, just an abstraction over FileLockEntry to have some convenience internally.
struct Link<'a> {
    link: FileLockEntry<'a>
}

impl<'a> Link<'a> {

    pub fn new(fle: FileLockEntry<'a>) -> Link<'a> {
        Link { link: fle }
    }

    /// For interal use only. Load an Link from a store id, if this is actually a Link
    fn retrieve(store: &'a Store, id: StoreId) -> Result<Option<Link<'a>>> {
        store.retrieve(id)
            .map(|fle| {
                if let Some(_) = Link::get_link_uri_from_filelockentry(&fle) {
                    Some(Link {
                        link: fle
                    })
                } else {
                    None
                }
            })
            .map_err(|e| LE::new(LEK::StoreReadError, Some(Box::new(e))))
    }

    /// Get a link Url object from a FileLockEntry, ignore errors.
    fn get_link_uri_from_filelockentry(file: &FileLockEntry<'a>) -> Option<Url> {
        file.get_header()
            .read("imag.content.uri")
            .ok()
            .and_then(|opt| {
                match opt {
                    Some(Value::String(s)) => Url::parse(&s[..]).ok(),
                    _ => None
                }
            })
    }

    pub fn get_url(&self) -> Result<Option<Url>> {
        let opt = self.link
            .get_header()
            .read("imag.content.uri");

        match opt {
            Ok(Some(Value::String(s))) => {
                Url::parse(&s[..])
                     .map(|s| Some(s))
                     .map_err(|e| LE::new(LEK::EntryHeaderReadError, Some(Box::new(e))))
            },
            Ok(None) => Ok(None),
            _ => Err(LE::new(LEK::EntryHeaderReadError, None))
        }
    }

}

pub trait ExternalLinker : InternalLinker {

    /// Get the external links from the implementor object
    fn get_external_links(&self, store: &Store) -> Result<Vec<Url>>;

    /// Set the external links for the implementor object
    fn set_external_links(&mut self, store: &Store, links: Vec<Url>) -> Result<()>;

    /// Add an external link to the implementor object
    fn add_external_link(&mut self, store: &Store, link: Url) -> Result<()>;

    /// Remove an external link from the implementor object
    fn remove_external_link(&mut self, store: &Store, link: Url) -> Result<()>;

}

/// Check whether the StoreId starts with `/link/external/`
fn is_link_store_id(id: &StoreId) -> bool {
    debug!("Checking whether this is a /link/external/*: '{:?}'", id);
    id.starts_with("/link/external/")
}

fn get_external_link_from_file(entry: &FileLockEntry) -> Result<Url> {
    Link::get_link_uri_from_filelockentry(entry) // TODO: Do not hide error by using this function
        .ok_or(LE::new(LEK::StoreReadError, None))
}

/// Implement ExternalLinker for Entry, hiding the fact that there is no such thing as an external
/// link in an entry, but internal links to other entries which serve as external links, as one
/// entry in the store can only have one external link.
impl ExternalLinker for Entry {

    /// Get the external links from the implementor object
    fn get_external_links(&self, store: &Store) -> Result<Vec<Url>> {
        // Iterate through all internal links and filter for FileLockEntries which live in
        // /link/external/<SHA> -> load these files and get the external link from their headers,
        // put them into the return vector.
        self.get_internal_links()
            .map(|vect| {
                debug!("Getting external links");
                vect.into_iter()
                    .filter(is_link_store_id)
                    .map(|id| {
                        debug!("Retrieving entry for id: '{:?}'", id);
                        match store.retrieve(id.clone()) {
                            Ok(f) => get_external_link_from_file(&f),
                            Err(e) => {
                                debug!("Retrieving entry for id: '{:?}' failed", id);
                                Err(LE::new(LEK::StoreReadError, Some(Box::new(e))))
                            }
                        }
                    })
                    .filter_map(|x| x.ok()) // TODO: Do not ignore error here
                    .collect()
            })
            .map_err(|e| LE::new(LEK::StoreReadError, Some(Box::new(e))))
    }

    /// Set the external links for the implementor object
    fn set_external_links(&mut self, store: &Store, links: Vec<Url>) -> Result<()> {
        // Take all the links, generate a SHA sum out of each one, filter out the already existing
        // store entries and store the other URIs in the header of one FileLockEntry each, in
        // the path /link/external/<SHA of the URL>

        debug!("Iterating {} links = {:?}", links.len(), links);
        for link in links { // for all links
            let hash = {
                let mut s = Sha1::new();
                s.input_str(&link.serialize()[..]);
                s.result_str()
            };
            let file_id = ModuleEntryPath::new(format!("external/{}", hash)).into_storeid();

            debug!("Link    = '{:?}'", link);
            debug!("Hash    = '{:?}'", hash);
            debug!("StoreId = '{:?}'", file_id);

            // retrieve the file from the store, which implicitely creates the entry if it does not
            // exist
            let file = store.retrieve(file_id.clone());
            if file.is_err() {
                debug!("Failed to create or retrieve an file for this link '{:?}'", link);
                return Err(LE::new(LEK::StoreWriteError, Some(Box::new(file.err().unwrap()))));
            }
            let mut file = file.unwrap();

            debug!("Generating header content!");
            {
                let mut hdr = file.deref_mut().get_header_mut();

                let mut table = match hdr.read("imag.content") {
                    Ok(Some(Value::Table(table))) => table,
                    Ok(Some(_)) => {
                        warn!("There is a value at 'imag.content' which is not a table.");
                        warn!("Going to override this value");
                        BTreeMap::new()
                    },
                    Ok(None) => BTreeMap::new(),
                    Err(e)   => return Err(LE::new(LEK::StoreWriteError, Some(Box::new(e)))),
                };

                let v = Value::String(link.serialize());

                debug!("setting URL = '{:?}", v);
                table.insert(String::from("url"), v);

                if let Err(e) = hdr.set("imag.content", Value::Table(table)) {
                    return Err(LE::new(LEK::StoreWriteError, Some(Box::new(e))));
                } else {
                    debug!("Setting URL worked");
                }
            }

            // then add an internal link to the new file or return an error if this fails
            if let Err(e) = self.add_internal_link(file.deref_mut()) {
                debug!("Error adding internal link");
                return Err(LE::new(LEK::StoreWriteError, Some(Box::new(e))));
            }
        }
        debug!("Ready iterating");
        Ok(())
    }

    /// Add an external link to the implementor object
    fn add_external_link(&mut self, store: &Store, link: Url) -> Result<()> {
        // get external links, add this one, save them
        debug!("Getting links");
        self.get_external_links(store)
            .and_then(|mut links| {
                debug!("Adding link = '{:?}' to links = {:?}", link, links);
                links.push(link);
                debug!("Setting {} links = {:?}", links.len(), links);
                self.set_external_links(store, links)
            })
    }

    /// Remove an external link from the implementor object
    fn remove_external_link(&mut self, store: &Store, link: Url) -> Result<()> {
        // get external links, remove this one, save them
        self.get_external_links(store)
            .and_then(|links| {
                debug!("Removing link = '{:?}' from links = {:?}", link, links);
                let links = links.into_iter()
                    .filter(|l| l.serialize() != link.serialize())
                    .collect();
                self.set_external_links(store, links)
            })
    }

}

<|endoftext|>


<commit_before><commit_msg>Start an example of JSON parsing<commit_after>#![feature(trace_macros)]

#[macro_use]
extern crate nom;

use nom::{IResult, digit, alphanumeric};

use std::str::{self,FromStr};
use std::collections::HashMap;

#[derive(Debug,PartialEq)]
pub enum JsonValue {
  Str(String),
  Num(f32),
  Array(Vec<JsonValue>),
  Object(HashMap<String,JsonValue>)
}

// FIXME: since we already parsed a serie of digits and dots,
// we know it is correct UTF-8. no need to use from_utf8 to
// verify it is correct
// FIXME: use alt_complete (implement ws for alt_complete)
named!(unsigned_float <f32>, map_res!(
  map_res!(
    recognize!(
      alt!(
        delimited!(digit, tag!("."), opt!(complete!(digit))) |
        delimited!(opt!(digit), tag!("."), digit)            |
        digit
      )
    ),
    str::from_utf8
  ),
  FromStr::from_str
));
named!(float<f32>, map!(
  pair!(
    opt!(alt!(tag!("+") | tag!("-"))),
    unsigned_float
  ),
  |(sign, value): (Option<&[u8]>, f32)| {
    sign.and_then(|s| if s[0] == ('-' as u8) { Some(-1f32) } else { None }).unwrap_or(1f32) * value
  }
));

//FIXME: verify how json strings are formatted
named!(string<&str>,
  dbg_dmp!(
  delimited!(
    tag!("\""),
    map_res!(escaped!(call!(alphanumeric), '\\', is_a!("\"n\\")), str::from_utf8),
    tag!("\"")
  )
  )
);

named!(array < Vec<JsonValue> >,
  ws!(
    delimited!(
      tag!("["),
      separated_list!(tag!(","), value),
      tag!("]")
    )
  )
);

trace_macros!(true);
named!(key_value<(&str,JsonValue)>,
  ws!(
    separated_pair!(
      string,
      tag!(":"),
      value
    )
  )
);
trace_macros!(false);

named!(hash< HashMap<String,JsonValue> >,
  dbg_dmp!(
  ws!(
    map!(
      delimited!(
        tag!("{"),
        separated_list!(tag!(","), key_value),
        tag!("}")
        ),
      |tuple_vec| {
        let mut h: HashMap<String, JsonValue> = HashMap::new();
        for (k, v) in tuple_vec {
          h.insert(String::from(k), v);
        }
        h
      }
    )
  )
  )
);

named!(value<JsonValue>,
  ws!(
    alt!(
      dbg_dmp!(hash)   => { |h|   JsonValue::Object(h)            } |
      array  => { |v|   JsonValue::Array(v)             } |
      string => { |s|   JsonValue::Str(String::from(s)) } |
      float  => { |num| JsonValue::Num(num)             }
    )
  )
);

//trace_macros!(false);

#[test]
fn hash_test() {
  let test = &b"  { \"a\"\t: 42,
  \"b\": \"x\"
  }";

//FIXME: top level value must be an object?
  println!("{:?}", value(&test[..]));
  assert!(false);
}

#[test]
fn parse_example_test() {
  let test = &b"  { \"a\"\t: 42,
  \"b\": [ \"x\", \"y\", 12 ] ,
  \"c\": { \"hello\" : \"world\"
  }
  }";

//FIXME: top level value must be an object?
  println!("{:?}", value(&test[..]));
  assert!(false);
}

<|endoftext|>


<commit_before><commit_msg>Update touch.rs with `ArgParser`<commit_after><|endoftext|>


<commit_before><commit_msg>Feat(cryptoutil): add encrypt/decrypt HMACs<commit_after><|endoftext|>


<commit_before><commit_msg>Test CU directory is the work_dir<commit_after>// compile-flags: -g --remap-path-prefix={{cwd}}=/cwd/ --remap-path-prefix={{src-base}}=/base/
// ignore-tidy-linelength
//
// Ensure that we remap the compile unit directory and that we set it to the compilers current
// working directory and not something else.
#![crate_type="rlib"]

// CHECK-DAG: [[FILE:![0-9]*]] = !DIFile(filename: "/base/debug-compile-unit-path.rs{{.*}}", directory: "/cwd/")
// CHECK-DAG: {{![0-9]*}} = distinct !DICompileUnit({{.*}}file: [[FILE]]
<|endoftext|>


<commit_before><commit_msg>Add support for powerpc-unknown-freebsd<commit_after>pub type c_char = u8;
pub type c_long = i32;
pub type c_ulong = u32;
pub type wchar_t = i32;
pub type time_t = i64;
pub type suseconds_t = i32;
pub type register_t = i32;

s! {
    pub struct stat {
        pub st_dev: ::dev_t,
        pub st_ino: ::ino_t,
        pub st_mode: ::mode_t,
        pub st_nlink: ::nlink_t,
        pub st_uid: ::uid_t,
        pub st_gid: ::gid_t,
        pub st_rdev: ::dev_t,
        pub st_atime: ::time_t,
        pub st_atime_nsec: ::c_long,
        pub st_mtime: ::time_t,
        pub st_mtime_nsec: ::c_long,
        pub st_ctime: ::time_t,
        pub st_ctime_nsec: ::c_long,
        pub st_size: ::off_t,
        pub st_blocks: ::blkcnt_t,
        pub st_blksize: ::blksize_t,
        pub st_flags: ::fflags_t,
        pub st_gen: u32,
        pub st_lspare: i32,
        pub st_birthtime: ::time_t,
        pub st_birthtime_nsec: ::c_long,
    }
}

// should be pub(crate), but that requires Rust 1.18.0
cfg_if! {
    if #[cfg(libc_const_size_of)] {
        #[doc(hidden)]
        pub const _ALIGNBYTES: usize = ::mem::size_of::<::c_int>() - 1;
    } else {
        #[doc(hidden)]
        pub const _ALIGNBYTES: usize = 4 - 1;
    }
}

pub const MAP_32BIT: ::c_int = 0x00080000;
pub const MINSIGSTKSZ: ::size_t = 2048; // 512 * 4
<|endoftext|>


<commit_before>//! Misc low level stuff

export TypeDesc;
export get_type_desc;
export size_of;
export min_align_of;
export pref_align_of;
export refcount;
export log_str;
export shape_eq, shape_lt, shape_le;

// Corresponds to runtime type_desc type
enum TypeDesc = {
    size: uint,
    align: uint
    // Remaining fields not listed
};

/// The representation of a Rust closure
struct Closure {
    code: *();
    env: *();
}

#[abi = "cdecl"]
extern mod rustrt {
    pure fn shape_log_str(t: *sys::TypeDesc, data: *()) -> ~str;
}

#[abi = "rust-intrinsic"]
extern mod rusti {
    fn get_tydesc<T>() -> *();
    fn size_of<T>() -> uint;
    fn pref_align_of<T>() -> uint;
    fn min_align_of<T>() -> uint;
}

/// Compares contents of two pointers using the default method.
/// Equivalent to `*x1 == *x2`.  Useful for hashtables.
pure fn shape_eq<T>(x1: &T, x2: &T) -> bool {
    *x1 == *x2
}

pure fn shape_lt<T>(x1: &T, x2: &T) -> bool {
    *x1 < *x2
}

pure fn shape_le<T>(x1: &T, x2: &T) -> bool {
    *x1 < *x2
}

/**
 * Returns a pointer to a type descriptor.
 *
 * Useful for calling certain function in the Rust runtime or otherwise
 * performing dark magick.
 */
pure fn get_type_desc<T>() -> *TypeDesc {
    unchecked { rusti::get_tydesc::<T>() as *TypeDesc }
}

/// Returns the size of a type
#[inline(always)]
pure fn size_of<T>() -> uint {
    unchecked { rusti::size_of::<T>() }
}

/**
 * Returns the ABI-required minimum alignment of a type
 *
 * This is the alignment used for struct fields. It may be smaller
 * than the preferred alignment.
 */
#[inline(always)]
pure fn min_align_of<T>() -> uint {
    unchecked { rusti::min_align_of::<T>() }
}

/// Returns the preferred alignment of a type
#[inline(always)]
pure fn pref_align_of<T>() -> uint {
    unchecked { rusti::pref_align_of::<T>() }
}

/// Returns the refcount of a shared box (as just before calling this)
pure fn refcount<T>(+t: @T) -> uint {
    unsafe {
        let ref_ptr: *uint = unsafe::reinterpret_cast(t);
        *ref_ptr - 1
    }
}

pure fn log_str<T>(t: T) -> ~str {
    unsafe {
        let data_ptr: *() = unsafe::reinterpret_cast(ptr::addr_of(t));
        rustrt::shape_log_str(get_type_desc::<T>(), data_ptr)
    }
}

#[cfg(test)]
mod tests {

    #[test]
    fn size_of_basic() {
        assert size_of::<u8>() == 1u;
        assert size_of::<u16>() == 2u;
        assert size_of::<u32>() == 4u;
        assert size_of::<u64>() == 8u;
    }

    #[test]
    #[cfg(target_arch = "x86")]
    #[cfg(target_arch = "arm")]
    fn size_of_32() {
        assert size_of::<uint>() == 4u;
        assert size_of::<*uint>() == 4u;
    }

    #[test]
    #[cfg(target_arch = "x86_64")]
    fn size_of_64() {
        assert size_of::<uint>() == 8u;
        assert size_of::<*uint>() == 8u;
    }

    #[test]
    fn align_of_basic() {
        assert pref_align_of::<u8>() == 1u;
        assert pref_align_of::<u16>() == 2u;
        assert pref_align_of::<u32>() == 4u;
    }

    #[test]
    #[cfg(target_arch = "x86")]
    #[cfg(target_arch = "arm")]
    fn align_of_32() {
        assert pref_align_of::<uint>() == 4u;
        assert pref_align_of::<*uint>() == 4u;
    }

    #[test]
    #[cfg(target_arch = "x86_64")]
    fn align_of_64() {
        assert pref_align_of::<uint>() == 8u;
        assert pref_align_of::<*uint>() == 8u;
    }

    #[test]
    fn synthesize_closure() unsafe {
        let x = 10;
        let f: fn(int) -> int = |y| x + y;

        assert f(20) == 30;

        let original_closure: Closure = unsafe::transmute(f);

        let actual_function_pointer = original_closure.code;
        let environment = original_closure.env;

        let new_closure = Closure {
            code: actual_function_pointer,
            env: environment
        };

        let new_f: fn(int) -> int = unsafe::transmute(new_closure);
        assert new_f(20) == 30;
    }
}

// Local Variables:
// mode: rust;
// fill-column: 78;
// indent-tabs-mode: nil
// c-basic-offset: 4
// buffer-file-coding-system: utf-8-unix
// End:
<commit_msg>core: Export sys::Closure<commit_after>//! Misc low level stuff

export TypeDesc;
export Closure;
export get_type_desc;
export size_of;
export min_align_of;
export pref_align_of;
export refcount;
export log_str;
export shape_eq, shape_lt, shape_le;

// Corresponds to runtime type_desc type
enum TypeDesc = {
    size: uint,
    align: uint
    // Remaining fields not listed
};

/// The representation of a Rust closure
struct Closure {
    code: *();
    env: *();
}

#[abi = "cdecl"]
extern mod rustrt {
    pure fn shape_log_str(t: *sys::TypeDesc, data: *()) -> ~str;
}

#[abi = "rust-intrinsic"]
extern mod rusti {
    fn get_tydesc<T>() -> *();
    fn size_of<T>() -> uint;
    fn pref_align_of<T>() -> uint;
    fn min_align_of<T>() -> uint;
}

/// Compares contents of two pointers using the default method.
/// Equivalent to `*x1 == *x2`.  Useful for hashtables.
pure fn shape_eq<T>(x1: &T, x2: &T) -> bool {
    *x1 == *x2
}

pure fn shape_lt<T>(x1: &T, x2: &T) -> bool {
    *x1 < *x2
}

pure fn shape_le<T>(x1: &T, x2: &T) -> bool {
    *x1 < *x2
}

/**
 * Returns a pointer to a type descriptor.
 *
 * Useful for calling certain function in the Rust runtime or otherwise
 * performing dark magick.
 */
pure fn get_type_desc<T>() -> *TypeDesc {
    unchecked { rusti::get_tydesc::<T>() as *TypeDesc }
}

/// Returns the size of a type
#[inline(always)]
pure fn size_of<T>() -> uint {
    unchecked { rusti::size_of::<T>() }
}

/**
 * Returns the ABI-required minimum alignment of a type
 *
 * This is the alignment used for struct fields. It may be smaller
 * than the preferred alignment.
 */
#[inline(always)]
pure fn min_align_of<T>() -> uint {
    unchecked { rusti::min_align_of::<T>() }
}

/// Returns the preferred alignment of a type
#[inline(always)]
pure fn pref_align_of<T>() -> uint {
    unchecked { rusti::pref_align_of::<T>() }
}

/// Returns the refcount of a shared box (as just before calling this)
pure fn refcount<T>(+t: @T) -> uint {
    unsafe {
        let ref_ptr: *uint = unsafe::reinterpret_cast(t);
        *ref_ptr - 1
    }
}

pure fn log_str<T>(t: T) -> ~str {
    unsafe {
        let data_ptr: *() = unsafe::reinterpret_cast(ptr::addr_of(t));
        rustrt::shape_log_str(get_type_desc::<T>(), data_ptr)
    }
}

#[cfg(test)]
mod tests {

    #[test]
    fn size_of_basic() {
        assert size_of::<u8>() == 1u;
        assert size_of::<u16>() == 2u;
        assert size_of::<u32>() == 4u;
        assert size_of::<u64>() == 8u;
    }

    #[test]
    #[cfg(target_arch = "x86")]
    #[cfg(target_arch = "arm")]
    fn size_of_32() {
        assert size_of::<uint>() == 4u;
        assert size_of::<*uint>() == 4u;
    }

    #[test]
    #[cfg(target_arch = "x86_64")]
    fn size_of_64() {
        assert size_of::<uint>() == 8u;
        assert size_of::<*uint>() == 8u;
    }

    #[test]
    fn align_of_basic() {
        assert pref_align_of::<u8>() == 1u;
        assert pref_align_of::<u16>() == 2u;
        assert pref_align_of::<u32>() == 4u;
    }

    #[test]
    #[cfg(target_arch = "x86")]
    #[cfg(target_arch = "arm")]
    fn align_of_32() {
        assert pref_align_of::<uint>() == 4u;
        assert pref_align_of::<*uint>() == 4u;
    }

    #[test]
    #[cfg(target_arch = "x86_64")]
    fn align_of_64() {
        assert pref_align_of::<uint>() == 8u;
        assert pref_align_of::<*uint>() == 8u;
    }

    #[test]
    fn synthesize_closure() unsafe {
        let x = 10;
        let f: fn(int) -> int = |y| x + y;

        assert f(20) == 30;

        let original_closure: Closure = unsafe::transmute(f);

        let actual_function_pointer = original_closure.code;
        let environment = original_closure.env;

        let new_closure = Closure {
            code: actual_function_pointer,
            env: environment
        };

        let new_f: fn(int) -> int = unsafe::transmute(new_closure);
        assert new_f(20) == 30;
    }
}

// Local Variables:
// mode: rust;
// fill-column: 78;
// indent-tabs-mode: nil
// c-basic-offset: 4
// buffer-file-coding-system: utf-8-unix
// End:
<|endoftext|>


<commit_before><commit_msg>Added mod use example<commit_after>// Bind the `deeply::nested::function` path to `other_function`
use deeply::nested::function as other_function;

fn function() {
    println!("called `function()`");
}

mod deeply {
    pub mod nested {
        pub fn function() {
            println!("called `deeply::nested::function()`")
        }
    }
}

fn main() {
    // Easier access to `deeply::nested::function`
    other_function();

    println!("Entering block");
    {
        // This is equivalent to `use deeply::nested::function as function`
        // This `function` will shadow the outer one
        use deeply::nested::function;

        function();

        println!("Leaving block");

        // `use` bindings have a local scope, in this case the `function`
        // shadowing is only available in this scope
    }

    function();
}
<|endoftext|>


<commit_before><commit_msg>Dining philosophers project competed.<commit_after><|endoftext|>


<commit_before><commit_msg>Scheduler api changed: now it's only return the next action, not apply it to world<commit_after><|endoftext|>


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

// no-pretty-expanded FIXME #15189
// ignore-windows FIXME #13259

#![feature(unboxed_closures)]
#![feature(unsafe_destructor)]

use std::env;
use std::old_io::process::Command;
use std::str;
use std::ops::{Drop, FnMut, FnOnce};

#[inline(never)]
fn foo() {
    let _v = vec![1, 2, 3];
    if env::var_os("IS_TEST").is_some() {
        panic!()
    }
}

#[inline(never)]
fn double() {
    struct Double;

    impl Drop for Double {
        fn drop(&mut self) { panic!("twice") }
    }

    let _d = Double;

    panic!("once");
}

fn runtest(me: &str) {
    let mut template = Command::new(me);
    template.env("IS_TEST", "1");

    // Make sure that the stack trace is printed
    let p = template.clone().arg("fail").env("RUST_BACKTRACE", "1").spawn().unwrap();
    let out = p.wait_with_output().unwrap();
    assert!(!out.status.success());
    let s = str::from_utf8(&out.error).unwrap();
    assert!(s.contains("stack backtrace") && s.contains("foo::h"),
            "bad output: {}", s);

    // Make sure the stack trace is *not* printed
    let p = template.clone().arg("fail").spawn().unwrap();
    let out = p.wait_with_output().unwrap();
    assert!(!out.status.success());
    let s = str::from_utf8(&out.error).unwrap();
    assert!(!s.contains("stack backtrace") && !s.contains("foo::h"),
            "bad output2: {}", s);

    // Make sure a stack trace is printed
    let p = template.clone().arg("double-fail").spawn().unwrap();
    let out = p.wait_with_output().unwrap();
    assert!(!out.status.success());
    let s = str::from_utf8(&out.error).unwrap();
    // loosened the following from double::h to double:: due to
    // spurious failures on mac, 32bit, optimized
    assert!(s.contains("stack backtrace") && s.contains("double::"),
            "bad output3: {}", s);

    // Make sure a stack trace isn't printed too many times
    let p = template.clone().arg("double-fail")
                                .env("RUST_BACKTRACE", "1").spawn().unwrap();
    let out = p.wait_with_output().unwrap();
    assert!(!out.status.success());
    let s = str::from_utf8(&out.error).unwrap();
    let mut i = 0;
    for _ in 0..2 {
        i += s[i + 10..].find_str("stack backtrace").unwrap() + 10;
    }
    assert!(s[i + 10..].find_str("stack backtrace").is_none(),
            "bad output4: {}", s);
}

fn main() {
    let args: Vec<String> = env::args().collect();
    if args.len() >= 2 && args[1] == "fail" {
        foo();
    } else if args.len() >= 2 && args[1] == "double-fail" {
        double();
    } else {
        runtest(&args[0]);
    }
}
<commit_msg>Rollup merge of #22970 - pnkfelix:fsk-robust-backtrace-test-against-env, r=alexcrichton<commit_after>// Copyright 2014 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.

// no-pretty-expanded FIXME #15189
// ignore-windows FIXME #13259

#![feature(unboxed_closures)]
#![feature(unsafe_destructor)]

use std::env;
use std::old_io::process::Command;
use std::str;
use std::ops::{Drop, FnMut, FnOnce};

#[inline(never)]
fn foo() {
    let _v = vec![1, 2, 3];
    if env::var_os("IS_TEST").is_some() {
        panic!()
    }
}

#[inline(never)]
fn double() {
    struct Double;

    impl Drop for Double {
        fn drop(&mut self) { panic!("twice") }
    }

    let _d = Double;

    panic!("once");
}

fn runtest(me: &str) {
    let mut template = Command::new(me);
    template.env("IS_TEST", "1");

    // Make sure that the stack trace is printed
    let p = template.clone().arg("fail").env("RUST_BACKTRACE", "1").spawn().unwrap();
    let out = p.wait_with_output().unwrap();
    assert!(!out.status.success());
    let s = str::from_utf8(&out.error).unwrap();
    assert!(s.contains("stack backtrace") && s.contains("foo::h"),
            "bad output: {}", s);

    // Make sure the stack trace is *not* printed
    // (Remove RUST_BACKTRACE from our own environment, in case developer
    // is running `make check` with it on.)
    let p = template.clone().arg("fail").env_remove("RUST_BACKTRACE").spawn().unwrap();
    let out = p.wait_with_output().unwrap();
    assert!(!out.status.success());
    let s = str::from_utf8(&out.error).unwrap();
    assert!(!s.contains("stack backtrace") && !s.contains("foo::h"),
            "bad output2: {}", s);

    // Make sure a stack trace is printed
    let p = template.clone().arg("double-fail").spawn().unwrap();
    let out = p.wait_with_output().unwrap();
    assert!(!out.status.success());
    let s = str::from_utf8(&out.error).unwrap();
    // loosened the following from double::h to double:: due to
    // spurious failures on mac, 32bit, optimized
    assert!(s.contains("stack backtrace") && s.contains("double::"),
            "bad output3: {}", s);

    // Make sure a stack trace isn't printed too many times
    let p = template.clone().arg("double-fail")
                                .env("RUST_BACKTRACE", "1").spawn().unwrap();
    let out = p.wait_with_output().unwrap();
    assert!(!out.status.success());
    let s = str::from_utf8(&out.error).unwrap();
    let mut i = 0;
    for _ in 0..2 {
        i += s[i + 10..].find_str("stack backtrace").unwrap() + 10;
    }
    assert!(s[i + 10..].find_str("stack backtrace").is_none(),
            "bad output4: {}", s);
}

fn main() {
    let args: Vec<String> = env::args().collect();
    if args.len() >= 2 && args[1] == "fail" {
        foo();
    } else if args.len() >= 2 && args[1] == "double-fail" {
        double();
    } else {
        runtest(&args[0]);
    }
}
<|endoftext|>


<commit_before>use std::path::Path;
use std::fs::File;
use std::io::Read;

use utils::{PathExt};

pub static INDEX: &'static [u8] = include_bytes!("index.hbs");
pub static CSS: &'static [u8] = include_bytes!("book.css");
pub static JS: &'static [u8] = include_bytes!("book.js");
pub static HIGHLIGHT_JS: &'static [u8] = include_bytes!("highlight.js");
pub static HIGHLIGHT_CSS: &'static [u8] = include_bytes!("highlight.css");
pub static JQUERY: &'static [u8] = include_bytes!("jquery-2.1.4.min.js");
pub static FONT_AWESOME: &'static [u8] = include_bytes!("_FontAwesome/css/font-awesome.min.css");
pub static FONT_AWESOME_EOT: &'static [u8] = include_bytes!("_FontAwesome/fonts/fontawesome-webfont.eot");
pub static FONT_AWESOME_SVG: &'static [u8] = include_bytes!("_FontAwesome/fonts/fontawesome-webfont.svg");
pub static FONT_AWESOME_TTF: &'static [u8] = include_bytes!("_FontAwesome/fonts/fontawesome-webfont.ttf");
pub static FONT_AWESOME_WOFF: &'static [u8] = include_bytes!("_FontAwesome/fonts/fontawesome-webfont.woff");
pub static FONT_AWESOME_WOFF2: &'static [u8] = include_bytes!("_FontAwesome/fonts/fontawesome-webfont.woff2");
pub static FONT_AWESOME_OTF: &'static [u8] = include_bytes!("_FontAwesome/fonts/FontAwesome.otf");

/// The `Theme` struct should be used instead of the static variables because the `new()` method
/// will look if the user has a theme directory in his source folder and use the users theme instead
/// of the default.
///
/// You should exceptionnaly use the static variables only if you need the default theme even if the
/// user has specified another theme.
pub struct Theme {
    pub index: Vec<u8>,
    pub css: Vec<u8>,
    pub js: Vec<u8>,
    pub highlight_css: Vec<u8>,
    pub highlight_js: Vec<u8>,
    pub jquery: Vec<u8>,
}

impl Theme {
    pub fn new(src: &Path) -> Self{

        // Default theme
        let mut theme = Theme {
            index: INDEX.to_owned(),
            css: CSS.to_owned(),
            js: JS.to_owned(),
            highlight_css: HIGHLIGHT_CSS.to_owned(),
            highlight_js: HIGHLIGHT_JS.to_owned(),
            jquery: JQUERY.to_owned(),
        };

        // Check if the given path exists
        if !src.exists() || !src.is_dir() {
            return theme
        }

        let src = src.join("theme");
        // If src does exist, check if there is a theme directory in it
        if !src.exists() || !src.is_dir() {
            return theme
        }

        // Check for individual files if they exist

        // index.hbs
        match File::open(&src.join("index.hbs")) {
            Ok(mut f) => {
                theme.index.clear(); // Reset the value, because read_to_string appends...
                match f.read_to_end(&mut theme.index) {
                    _ => {}
                };
            },
            _ => {},
        }

        // book.js
        match File::open(&src.join("book.js")) {
            Ok(mut f) => {
                theme.js.clear();
                match f.read_to_end(&mut theme.js){
                    _ => {}
                }
            },
            _ => {},
        }

        // book.css
        match File::open(&src.join("book.css")) {
            Ok(mut f) => {
                theme.css.clear();
                match f.read_to_end(&mut theme.css) {
                    _ => {}
                }
            },
            _ => {},
        }

        // highlight.js
        match File::open(&src.join("highlight.js")) {
            Ok(mut f) => {
                theme.highlight_js.clear();
                match f.read_to_end(&mut theme.highlight_js) {
                    _ => {}
                }
            },
            _ => {},
        }

        // highlight.css
        match File::open(&src.join("highlight.css")) {
            Ok(mut f) => {
                theme.highlight_css.clear();
                match f.read_to_end(&mut theme.highlight_css) {
                    _ => {}
                }
            },
            _ => {},
        }

        theme
    }
}
<commit_msg>Simplify match nesting in theme with if let<commit_after>use std::path::Path;
use std::fs::File;
use std::io::Read;

use utils::{PathExt};

pub static INDEX: &'static [u8] = include_bytes!("index.hbs");
pub static CSS: &'static [u8] = include_bytes!("book.css");
pub static JS: &'static [u8] = include_bytes!("book.js");
pub static HIGHLIGHT_JS: &'static [u8] = include_bytes!("highlight.js");
pub static HIGHLIGHT_CSS: &'static [u8] = include_bytes!("highlight.css");
pub static JQUERY: &'static [u8] = include_bytes!("jquery-2.1.4.min.js");
pub static FONT_AWESOME: &'static [u8] = include_bytes!("_FontAwesome/css/font-awesome.min.css");
pub static FONT_AWESOME_EOT: &'static [u8] = include_bytes!("_FontAwesome/fonts/fontawesome-webfont.eot");
pub static FONT_AWESOME_SVG: &'static [u8] = include_bytes!("_FontAwesome/fonts/fontawesome-webfont.svg");
pub static FONT_AWESOME_TTF: &'static [u8] = include_bytes!("_FontAwesome/fonts/fontawesome-webfont.ttf");
pub static FONT_AWESOME_WOFF: &'static [u8] = include_bytes!("_FontAwesome/fonts/fontawesome-webfont.woff");
pub static FONT_AWESOME_WOFF2: &'static [u8] = include_bytes!("_FontAwesome/fonts/fontawesome-webfont.woff2");
pub static FONT_AWESOME_OTF: &'static [u8] = include_bytes!("_FontAwesome/fonts/FontAwesome.otf");

/// The `Theme` struct should be used instead of the static variables because the `new()` method
/// will look if the user has a theme directory in his source folder and use the users theme instead
/// of the default.
///
/// You should exceptionnaly use the static variables only if you need the default theme even if the
/// user has specified another theme.
pub struct Theme {
    pub index: Vec<u8>,
    pub css: Vec<u8>,
    pub js: Vec<u8>,
    pub highlight_css: Vec<u8>,
    pub highlight_js: Vec<u8>,
    pub jquery: Vec<u8>,
}

impl Theme {
    pub fn new(src: &Path) -> Self {

        // Default theme
        let mut theme = Theme {
            index: INDEX.to_owned(),
            css: CSS.to_owned(),
            js: JS.to_owned(),
            highlight_css: HIGHLIGHT_CSS.to_owned(),
            highlight_js: HIGHLIGHT_JS.to_owned(),
            jquery: JQUERY.to_owned(),
        };

        // Check if the given path exists
        if !src.exists() || !src.is_dir() {
            return theme
        }

        let src = src.join("theme");
        // If src does exist, check if there is a theme directory in it
        if !src.exists() || !src.is_dir() {
            return theme
        }

        // Check for individual files if they exist

        // index.hbs
        if let Ok(mut f) = File::open(&src.join("index.hbs")) {
            theme.index.clear(); // Reset the value, because read_to_string appends...
            let _ = f.read_to_end(&mut theme.index);
        }

        // book.js
        if let Ok(mut f) = File::open(&src.join("book.js")) {
            theme.js.clear();
            let _ =  f.read_to_end(&mut theme.js);
        }

        // book.css
        if let Ok(mut f) = File::open(&src.join("book.css")) {
            theme.css.clear();
            let _ = f.read_to_end(&mut theme.css);
        }

        // highlight.js
        if let Ok(mut f) = File::open(&src.join("highlight.js")) {
            theme.highlight_js.clear();
            let _ = f.read_to_end(&mut theme.highlight_js);
        }

        // highlight.css
        if let Ok(mut f) = File::open(&src.join("highlight.css")) {
            theme.highlight_css.clear();
            let _ = f.read_to_end(&mut theme.highlight_css);
        }

        theme
    }
}
<|endoftext|>


<commit_before><commit_msg>Test case for issue 2718<commit_after>fn sender_terminate<T:send>(p: *packet<T>) {
}

class send_packet<T: send> {
        let mut p: option<*packet<T>>;
        new(p: *packet<T>) { self.p = some(p); }
        drop {
            if self.p != none {
                let mut p = none;
                p <-> self.p;
                sender_terminate(option::unwrap(p))
            }
        }
        fn unwrap() -> *packet<T> {
            let mut p = none;
            p <-> self.p;
            option::unwrap(p)
        }
}

enum state {
        empty,
        full,
        blocked,
        terminated
}

type packet<T: send> = {
        mut state: state,
        mut blocked_task: option<task::task>,
        mut payload: option<T>
};

fn main() {
  let _s: send_packet<int> = send_packet(ptr::addr_of({mut state: empty,
        mut blocked_task: none,
        mut payload: some(42)}));
}
<|endoftext|>


<commit_before><commit_msg>Added a test.<commit_after><|endoftext|>


<commit_before><commit_msg>start new<commit_after>fn quick_sort(l: Vec<u32>) -> Vec<u32> {}

fn main() {
    let result = quick_sort();
    println!("{}", result);
}
<|endoftext|>


<commit_before><commit_msg>Remove unused constants<commit_after><|endoftext|>


<commit_before>/*
Module: result

A type representing either success or failure
*/

/* Section: Types */

/*
Tag: t

The result type
*/
tag t<T, U> {
    /*
    Variant: ok

    Contains the result value
    */
    ok(T);
    /*
    Variant: err

    Contains the error value
    */
    err(U);
}

/* Section: Operations */

/*
Function: get

Get the value out of a successful result

Failure:

If the result is an error
*/
fn get<T, U>(res: t<T, U>) -> T {
    alt res {
      ok(t) { t }
      err(_) {
        // FIXME: Serialize the error value
        // and include it in the fail message
        fail "get called on error result";
      }
    }
}

/*
Function: get_err

Get the value out of an error result

Failure:

If the result is not an error
*/
fn get_err<T, U>(res: t<T, U>) -> U {
    alt res {
      err(u) { u }
      ok(_) {
        fail "get_error called on ok result";
      }
    }
}

/*
Function: success

Returns true if the result is <ok>
*/
fn success<T, U>(res: t<T, U>) -> bool {
    alt res {
      ok(_) { true }
      err(_) { false }
    }
}

/*
Function: failure

Returns true if the result is <error>
*/
fn failure<T, U>(res: t<T, U>) -> bool {
    !success(res)
}

/*
Function: chain

Call a function based on a previous result

If `res` is <ok> then the value is extracted and passed to `op` whereupon
`op`s result is returned. if `res` is <err> then it is immediately returned.
This function can be used to compose the results of two functions.

Example:

> let res = chain(read_file(file), { |buf]
>   ok(parse_buf(buf))
> })

*/
fn chain<T, U, V>(res: t<T, V>, op: block(T) -> t<U, V>) -> t<U, V> {
    alt res {
      ok(t) { op(t) }
      err(e) { err(e) }
    }
}
<commit_msg>stdlib: Fix type in docs for result::chan<commit_after>/*
Module: result

A type representing either success or failure
*/

/* Section: Types */

/*
Tag: t

The result type
*/
tag t<T, U> {
    /*
    Variant: ok

    Contains the result value
    */
    ok(T);
    /*
    Variant: err

    Contains the error value
    */
    err(U);
}

/* Section: Operations */

/*
Function: get

Get the value out of a successful result

Failure:

If the result is an error
*/
fn get<T, U>(res: t<T, U>) -> T {
    alt res {
      ok(t) { t }
      err(_) {
        // FIXME: Serialize the error value
        // and include it in the fail message
        fail "get called on error result";
      }
    }
}

/*
Function: get_err

Get the value out of an error result

Failure:

If the result is not an error
*/
fn get_err<T, U>(res: t<T, U>) -> U {
    alt res {
      err(u) { u }
      ok(_) {
        fail "get_error called on ok result";
      }
    }
}

/*
Function: success

Returns true if the result is <ok>
*/
fn success<T, U>(res: t<T, U>) -> bool {
    alt res {
      ok(_) { true }
      err(_) { false }
    }
}

/*
Function: failure

Returns true if the result is <error>
*/
fn failure<T, U>(res: t<T, U>) -> bool {
    !success(res)
}

/*
Function: chain

Call a function based on a previous result

If `res` is <ok> then the value is extracted and passed to `op` whereupon
`op`s result is returned. if `res` is <err> then it is immediately returned.
This function can be used to compose the results of two functions.

Example:

> let res = chain(read_file(file), { |buf|
>   ok(parse_buf(buf))
> })

*/
fn chain<T, U, V>(res: t<T, V>, op: block(T) -> t<U, V>) -> t<U, V> {
    alt res {
      ok(t) { op(t) }
      err(e) { err(e) }
    }
}
<|endoftext|>


<commit_before><commit_msg>auto merge of #6621 : steveklabnik/rust/expand_reader_docs, r=thestinger<commit_after><|endoftext|>


<commit_before><commit_msg>Small changes<commit_after><|endoftext|>


<commit_before><commit_msg>Simplify test code<commit_after><|endoftext|>


<commit_before><commit_msg>Implemented a generic version of the algorithm<commit_after>use std::ops::Add;
use std::marker::PhantomData;
use std::marker::Copy;

pub trait FletcherSum<T>
    : Default + Add<Self> + From<T> + From<<Self as Add>::Output> + Copy
where
    T: Copy,
{
    fn max_chunk_size() -> usize;
    fn combine(lower: &Self, upper: &Self) -> Self;
    fn reduce(self) -> Self;
}

pub struct Fletcher<T, U> {
    a: T,
    b: T,
    phantom: PhantomData<U>,
}

impl<T, U> Fletcher<T, U>
where
    T: FletcherSum<U>,
    U: Copy,
{
    pub fn new() -> Fletcher<T, U> {
        Fletcher {
            a: Default::default(),
            b: Default::default(),
            phantom: PhantomData,
        }
    }

    pub fn update(&mut self, data: &Vec<U>) {
        let max_chunk_size = T::max_chunk_size();

        for chunk in data.chunks(max_chunk_size) {
            let mut intermediate_a = self.a;
            let mut intermediate_b = self.b;

            for byte in chunk {
                intermediate_a = T::from(intermediate_a + T::from(*byte));
                intermediate_b = T::from(intermediate_b + intermediate_a);
            }

            self.a = intermediate_a.reduce();
            self.b = intermediate_b.reduce();
        }

        self.a = self.a.reduce();
        self.b = self.b.reduce();
    }

    pub fn value(&self) -> T {
        T::combine(&self.a, &self.b)
    }
}
<|endoftext|>


<commit_before><commit_msg>Interrupt tables.<commit_after>//! Interrupts.

use core::fmt;

/// x86 External Interrupts (1-16).
pub static EXCEPTIONS: [InterruptDescription; 21] = [
    Descriptor::new("Division error", Kind::Fault),
    Descriptor::new("Debug trap", Kind::Trap),
    Descriptor::new("Unmaskable interrupt", Kind::Unmaskable),
    Descriptor::new("Breakpoint", Kind::Trap),
    Descriptor::new("Overflow", Kind::Trap),
    Descriptor::new("Out of bound", Kind::Fault),
    Descriptor::new("Invalid opcode", Kind::Fault),
    Descriptor::new("Device unavailable", Kind::Fault),
    Descriptor::new("Double fault", Kind::Fault),
    Descriptor::new("Coprocessor segment overrun", Kind::Fault),
    Descriptor::new("Invalid TSS", Kind::Fault),
    Descriptor::new("Segment not present", Kind::Fault),
    Descriptor::new("Stack-segment fault", Kind::Fault),
    Descriptor::new("General protection", Kind::Fault),
    Descriptor::new("Page fault", Kind::Fault),
    Descriptor::new("Reserved", Kind::Reserved),
    Descriptor::new("x87 FPU", Kind::Fault),
    Descriptor::new("Unaligned memory access", Kind::Fault),
    Descriptor::new("Machine check", Kind::Abort),
    Descriptor::new("SIMD floating-point", Kind::Fault),
    Descriptor::new("SIMD floating-point", Kind::Fault),
    Descriptor::new("Virtualization violation", Kind::Fault),
];

/// An interrupt description.
#[derive(Debug, Copy, Clone)]
pub struct Descriptor {
    /// The description of this interrupt.
    pub desc: &'static str,
    /// The interrupt type.
    pub kind: Kind,
}

impl Descriptor {
    /// Create a new interrupt description.
    pub fn new(desc: &'static str, kind: Kind) -> Descriptor {
        Descriptor {
            desc: desc,
            kind: kind,
        }
    }
}

/// The interrupt kind.
pub enum Kind {
    /// A fault.
    ///
    /// This can have multiple sources, but is often a result of a program error of some sort.
    Fault,
    /// A trap.
    ///
    /// These are often for debugging purposes.
    Trap,
    /// A deliberate abort.
    Abort,
    /// An unmaskable interrupt.
    ///
    /// This is a forced interrupt which need to be handled immediately.
    Unmaskable,
    /// Reserved or deprecated.
    Reserved,
}

/// Enable interrupts.
pub unsafe fn enable() {
    asm!("sti");
}

/// Disable interrupts.
pub unsafe fn disable() {
    asm!("cli");
}

/// Fire a software interrupt.
///
/// Due to inlining being strictly required, we use a macro.
#[macro_export]
macro_rules! interrupt {
    ($int:expr) => {{
            asm!("int $0" :: "N" ($int));
    }};
}
<|endoftext|>


<commit_before><commit_msg>Format branches() test to pass rustfmt<commit_after><|endoftext|>