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

use core::mem::size_of;
use core::num::Zero;
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 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> + Zero>(bytes: &[u8], i: &mut usize) -> T {
    let mut num: T = T::zero();

    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 {
                debugln!("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),
            _ => debugln!("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);

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

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

        *i = end;
}

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

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

        match op {
            ZERO_OP => {
                debugln!("        Zero");
            },
            ONE_OP => {
                debugln!("        One");
            },
            BYTE_PREFIX => {
                debugln!("        {:02X}", parse_num::<u8>(bytes, i));
            },
            WORD_PREFIX => {
                debugln!("        {:04X}", parse_num::<u16>(bytes, i));
            },
            DWORD_PREFIX => {
                debugln!("        {:08X}", parse_num::<u32>(bytes, i));
            },
            STRING_PREFIX => {
                debugln!("        {}", parse_string(bytes, i));
            },
            QWORD_PREFIX => {
                debugln!("        {:016X}", parse_num::<u64>(bytes, i));
            },
            NAME_OP => {
                debugln!("        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);

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

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

                let count = parse_int(bytes, i);

                debugln!("        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);

                            debugln!("        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);

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

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

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

    *i = end;
}

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

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

        match op {
            ZERO_OP => {
                debugln!("    Zero");
            },
            ONE_OP => {
                debugln!("    One");
            },
            BYTE_PREFIX => {
                debugln!("    {:02X}", parse_num::<u8>(bytes, i));
            },
            WORD_PREFIX => {
                debugln!("    {:04X}", parse_num::<u16>(bytes, i));
            },
            DWORD_PREFIX => {
                debugln!("    {:08X}", parse_num::<u32>(bytes, i));
            },
            STRING_PREFIX => {
                debugln!("    {}", parse_string(bytes, i));
            }
            QWORD_PREFIX => {
                debugln!("    {:016X}", parse_num::<u64>(bytes, i));
            },
            SCOPE_OP => {
                parse_scope(bytes, i);
            },
            NAME_OP => {
                debugln!("    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);

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

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

                let count = parse_int(bytes, i);

                debugln!("    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);

                            debugln!("    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);

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

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

                            *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);

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

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

    *i = end;
}

pub fn parse(bytes: &[u8]) {
    let mut i = 0;
    while i < bytes.len() {
        let op = bytes[i];
        i += 1;

        match op {
            SCOPE_OP => {
                parse_scope(bytes, &mut i);
            },
            _ => {
                debugln!("parse: unknown: {:02X}", op);
                break;
            }
        }
    }
}
<commit_msg>No more unknowns in the Qemu DSDT<commit_after>use collections::string::String;

use core::mem::size_of;
use core::num::Zero;
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> + Zero>(bytes: &[u8], i: &mut usize) -> T {
    let mut num: T = T::zero();

    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 {
                debugln!("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),
            _ => debugln!("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);

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

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

        *i = end;
}

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

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

        match op {
            ZERO_OP => {
                debugln!("        Zero");
            },
            ONE_OP => {
                debugln!("        One");
            },
            BYTE_PREFIX => {
                debugln!("        {:02X}", parse_num::<u8>(bytes, i));
            },
            WORD_PREFIX => {
                debugln!("        {:04X}", parse_num::<u16>(bytes, i));
            },
            DWORD_PREFIX => {
                debugln!("        {:08X}", parse_num::<u32>(bytes, i));
            },
            STRING_PREFIX => {
                debugln!("        {}", parse_string(bytes, i));
            },
            QWORD_PREFIX => {
                debugln!("        {:016X}", parse_num::<u64>(bytes, i));
            },
            NAME_OP => {
                debugln!("        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);

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

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

                let count = parse_int(bytes, i);

                debugln!("        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);

                            debugln!("        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);

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

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

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

    *i = end;
}

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

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

        match op {
            ZERO_OP => {
                debugln!("    Zero");
            },
            ONE_OP => {
                debugln!("    One");
            },
            BYTE_PREFIX => {
                debugln!("    {:02X}", parse_num::<u8>(bytes, i));
            },
            WORD_PREFIX => {
                debugln!("    {:04X}", parse_num::<u16>(bytes, i));
            },
            DWORD_PREFIX => {
                debugln!("    {:08X}", parse_num::<u32>(bytes, i));
            },
            STRING_PREFIX => {
                debugln!("    {}", parse_string(bytes, i));
            }
            QWORD_PREFIX => {
                debugln!("    {:016X}", parse_num::<u64>(bytes, i));
            },
            SCOPE_OP => {
                parse_scope(bytes, i);
            },
            NAME_OP => {
                debugln!("    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);

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

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

                let count = parse_int(bytes, i);

                debugln!("    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);

                            debugln!("    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);

                            debugln!("    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);

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

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

                            *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);

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

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

    *i = end;
}

pub fn parse(bytes: &[u8]) {
    let mut i = 0;
    while i < bytes.len() {
        let op = bytes[i];
        i += 1;

        match op {
            SCOPE_OP => {
                parse_scope(bytes, &mut i);
            },
            _ => {
                debugln!("parse: unknown: {:02X}", op);
                break;
            }
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>Add ApplicationError type<commit_after>use std::error::Error;

struct ApplicationError {
    str: String
}

impl Error for ApplicationError {

    fn description(&self) -> &str {
    }

    fn cause(&self) -> Option<&Error> {
    }
}
<|endoftext|>


<commit_before><commit_msg>Factor clearing of Vulkan images into methods, and use it to clear new images<commit_after><|endoftext|>


<commit_before><commit_msg>ebpf program in rust<commit_after>#![no_std]
#![no_main]

use aya_bpf::{
    bindings::xdp_action,
    macros::{map, xdp},
    maps::{HashMap, PerfEventArray},
    programs::XdpContext,
};

use core::mem;
use memoffset::offset_of;
use myapp_common::PacketLog;

mod bindings;
use bindings::{ethhdr, iphdr};

#[panic_handler]
fn panic(_info: &core::panic::PanicInfo) -> ! {
    unreachable!()
}

#[map(name = "EVENTS")]
static mut EVENTS: PerfEventArray<PacketLog> =
    PerfEventArray::<PacketLog>::with_max_entries(1024, 0);

#[map(name = "BLOCKLIST")]
static mut BLOCKLIST: HashMap<u32, u32> = HashMap::<u32, u32>::with_max_entries(1024, 0);

#[xdp]
pub fn xdp_firewall(ctx: XdpContext) -> u32 {
    match try_xdp_firewall(ctx) {
        Ok(ret) => ret,
        Err(_) => xdp_action::XDP_ABORTED,
    }
}

#[inline(always)]
unsafe fn ptr_at<T>(ctx: &XdpContext, offset: usize) -> Result<*const T, ()> {
    let start = ctx.data();
    let end = ctx.data_end();
    let len = mem::size_of::<T>();

    if start + offset + len > end {
        return Err(());
    }

    Ok((start + offset) as *const T)
}

fn block_ip(address: u32) -> bool {
    unsafe { BLOCKLIST.get(&address).is_some() }
}

fn try_xdp_firewall(ctx: XdpContext) -> Result<u32, ()> {
    let h_proto = u16::from_be(unsafe { *ptr_at(&ctx, offset_of!(ethhdr, h_proto))? });
    if h_proto != ETH_P_IP {
        return Ok(xdp_action::XDP_PASS);
    }
    let source = u32::from_be(unsafe { *ptr_at(&ctx, ETH_HDR_LEN + offset_of!(iphdr, saddr))? });

    let action = if block_ip(source) {
        xdp_action::XDP_DROP
    } else {
        xdp_action::XDP_PASS
    };

    let log_entry = PacketLog {
        ipv4_address: source,
        action: action,
    };

    unsafe {
        EVENTS.output(&ctx, &log_entry, 0);
    }

    Ok(action)
}

const ETH_P_IP: u16 = 0x0800;
const ETH_HDR_LEN: usize = mem::size_of::<ethhdr>();<|endoftext|>


<commit_before><commit_msg>Fix the error with using try<commit_after><|endoftext|>


<commit_before><commit_msg>get &mut Cell from coordinates<commit_after><|endoftext|>


<commit_before><commit_msg>docs(PasswordHasher): fix a typo<commit_after><|endoftext|>


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

// PrometheusReporter aggregates metrics into metricsfamilies and passes them every second to the
// attached prometheus reporter at a regular basis.

extern crate prometheus_reporter;
extern crate protobuf;
use self::prometheus_reporter::PrometheusReporter as Pr;
use self::prometheus_reporter::promo_proto;

use std::time::Duration;
use std::thread;
use metrics::Metric;
use time;
use std::collections::HashMap;
use std::sync::mpsc;
use reporter::Reporter;
use self::protobuf::repeated::RepeatedField;

struct PrometheusMetricEntry {
    name: String,
    metric: Metric,
    labels: HashMap<String, String>,
}

// TODO perhaps we autodiscover the host and port
//
pub struct PrometheusReporter {
    reporter_name: &'static str,
    tx: mpsc::Sender<Result<PrometheusMetricEntry, &'static str>>,
    join_handle: thread::JoinHandle<Result<(), String>>,
}
impl Reporter for PrometheusReporter {
    fn get_unique_reporter_name(&self) -> &str {
        &(*self.reporter_name)
    }
    fn stop(self) -> Result<thread::JoinHandle<Result<(), String>>, String> {
        match self.tx.send(Err("stop")) {
            Ok(_) => Ok(self.join_handle),
            Err(x) => Err(format!("Unable to stop reporter:{}", x)),
        }
    }
    fn addl<S: Into<String>>(&mut self,
                             name: S,
                             metric: Metric,
                             labels: Option<HashMap<String, String>>)
                             -> Result<(), String> {
        // TODO return error
        let ref mut tx = &self.tx;
        match tx.send(Ok(PrometheusMetricEntry {
            name: name.into(),
            metric: metric,
            labels: labels.unwrap_or(HashMap::new()),
        })) {
            Ok(_) => Ok(()),
            Err(x) => Err(format!("Unable to stop reporter: {}", x)),
        }
    }
}

impl PrometheusReporter {
    pub fn new(reporter_name: &'static str, host_and_port: &'static str, delay_ms: u64) -> Self {
        let (tx, rx) = mpsc::channel();
        PrometheusReporter {
            reporter_name: reporter_name,
            tx: tx,
            join_handle: thread::spawn(move || {
                let mut stop = false;
                let mut prometheus_reporter = Pr::new(host_and_port);
                while !stop {
                    match collect_to_send(&rx) {
                        // Unwraping is always dangerouns. In this case our prometheus reporter is
                        // overwhelmed by metrics
                        Ok(metrics) => {
                            try!(prometheus_reporter.add(metrics));
                        }
                        Err(_) => stop = true,
                    }
                    thread::sleep(Duration::from_millis(delay_ms));
                }
                Ok(())
            }),
        }
    }
}

fn to_repeated_fields_labels(labels: HashMap<String, String>)
                             -> RepeatedField<promo_proto::LabelPair> {
    let mut repeated_fields = Vec::new();
    // name/value is what they call it in the protobufs *shrug*
    for (name, value) in labels {
        let mut label_pair = promo_proto::LabelPair::new();
        label_pair.set_name(name);
        label_pair.set_value(value);
        repeated_fields.push(label_pair);
    }
    RepeatedField::from_vec(repeated_fields)
}

fn make_metric(metric: &Metric,
               labels: &HashMap<String, String>)
               -> (promo_proto::Metric, promo_proto::MetricType) {

    let mut pb_metric = promo_proto::Metric::new();
    let ts = time::now().to_timespec().sec;

    pb_metric.set_timestamp_ms(ts);
    pb_metric.set_label(to_repeated_fields_labels(labels.clone()));
    match *metric {
        Metric::Counter(ref x) => {
            let snapshot = x.snapshot();
            let mut counter = promo_proto::Counter::new();
            counter.set_value(snapshot.value as f64);
            pb_metric.set_counter(counter);
            (pb_metric, promo_proto::MetricType::COUNTER)
        }
        Metric::Gauge(ref x) => {
            let snapshot = x.snapshot();
            let mut gauge = promo_proto::Gauge::new();
            gauge.set_value(snapshot.value as f64);
            pb_metric.set_gauge(gauge);
            (pb_metric, promo_proto::MetricType::GAUGE)
        }
        Metric::Meter(_) => {
            pb_metric.set_summary(promo_proto::Summary::new());
            (pb_metric, promo_proto::MetricType::SUMMARY)

        }
        Metric::Histogram(_) => {
            pb_metric.set_histogram(promo_proto::Histogram::new());
            (pb_metric, promo_proto::MetricType::HISTOGRAM)
        }
    }
}

fn collect_to_send(metric_entries: &mpsc::Receiver<Result<PrometheusMetricEntry, &'static str>>)
                   -> Result<Vec<promo_proto::MetricFamily>, &'static str> {
    let mut entries_group = HashMap::<String, Vec<PrometheusMetricEntry>>::new();

    // Group them by name TODO we should include tags and types in the grouping
    for _entry in metric_entries {
        let entry = try!(_entry);
        let name = entry.name.clone();
        let mut entries = entries_group.remove(&name).unwrap_or(vec![]);
        entries.push(entry);
        entries_group.insert(name, entries);
    }
    Ok(metric_entries_to_family(entries_group))

}

fn metric_entries_to_family(entries_group: HashMap<String, Vec<PrometheusMetricEntry>>)
                            -> Vec<promo_proto::MetricFamily> {
    let mut families = Vec::new();
    for (name, metric_entries) in &entries_group {
        let formatted_metric = format!("{}_{}_{}", "application_name", name, "bytes");
        // TODO check for 0 length

        let ref e1: PrometheusMetricEntry = metric_entries[0];
        let (_, pb_metric_type) = make_metric(&e1.metric, &e1.labels);

        let mut family = promo_proto::MetricFamily::new();
        let mut pb_metrics = Vec::new();

        for metric_entry in metric_entries {
            // TODO maybe don't assume they have the same type
            let (pb_metric, _) = make_metric(&metric_entry.metric, &metric_entry.labels);
            pb_metrics.push(pb_metric);
        }

        family.set_name(String::from(formatted_metric));
        family.set_field_type(pb_metric_type);
        family.set_metric(RepeatedField::from_vec(pb_metrics));
        families.push(family);
    }
    families
}

#[cfg(test)]
mod test {
    use histogram::Histogram;
    use std::collections::HashMap;
    use metrics::{Counter, Gauge, Meter, Metric, StdCounter, StdGauge, StdMeter};
    use super::PrometheusReporter;
    use reporter::Reporter;

    #[test]
    fn meter() {
        let m = StdMeter::new();
        m.mark(100);

        let c = StdCounter::new();
        c.inc();

        let g = StdGauge::new();
        g.set(2);

        let mut h = Histogram::configure()
            .max_value(100)
            .precision(1)
            .build()
            .unwrap();

        h.increment_by(1, 1).unwrap();

        let mut reporter = PrometheusReporter::new("test", "0.0.0.0:80", 1024);
        let labels = Some(HashMap::new());
        reporter.addl("meter1", Metric::Meter(m.clone()), labels.clone());
        reporter.addl("counter1", Metric::Counter(c.clone()), labels.clone());
        reporter.addl("gauge1", Metric::Gauge(g.clone()), labels.clone());
        reporter.addl("histogram", Metric::Histogram(h), labels);
        reporter.stop().unwrap().join().unwrap().unwrap();
    }
}
<commit_msg>Rust-fmt of code<commit_after>// 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.

// PrometheusReporter aggregates metrics into metricsfamilies and passes them every second to the
// attached prometheus reporter at a regular basis.

extern crate prometheus_reporter;
extern crate protobuf;
use self::prometheus_reporter::PrometheusReporter as Pr;
use self::prometheus_reporter::promo_proto;

use std::time::Duration;
use std::thread;
use metrics::Metric;
use time;
use std::collections::HashMap;
use std::sync::mpsc;
use reporter::Reporter;
use self::protobuf::repeated::RepeatedField;

struct PrometheusMetricEntry {
    name: String,
    metric: Metric,
    labels: HashMap<String, String>,
}

// TODO perhaps we autodiscover the host and port
//
pub struct PrometheusReporter {
    reporter_name: &'static str,
    tx: mpsc::Sender<Result<PrometheusMetricEntry, &'static str>>,
    join_handle: thread::JoinHandle<Result<(), String>>,
}
impl Reporter for PrometheusReporter {
    fn get_unique_reporter_name(&self) -> &str {
        &(*self.reporter_name)
    }
    fn stop(self) -> Result<thread::JoinHandle<Result<(), String>>, String> {
        match self.tx.send(Err("stop")) {
            Ok(_) => Ok(self.join_handle),
            Err(x) => Err(format!("Unable to stop reporter:{}", x)),
        }
    }
    fn addl<S: Into<String>>(&mut self,
                             name: S,
                             metric: Metric,
                             labels: Option<HashMap<String, String>>)
                             -> Result<(), String> {
        // TODO return error
        let ref mut tx = &self.tx;
        match tx.send(Ok(PrometheusMetricEntry {
            name: name.into(),
            metric: metric,
            labels: labels.unwrap_or(HashMap::new()),
        })) {
            Ok(_) => Ok(()),
            Err(x) => Err(format!("Unable to stop reporter: {}", x)),
        }
    }
}

impl PrometheusReporter {
    pub fn new(reporter_name: &'static str, host_and_port: &'static str, delay_ms: u64) -> Self {
        let (tx, rx) = mpsc::channel();
        PrometheusReporter {
            reporter_name: reporter_name,
            tx: tx,
            join_handle: thread::spawn(move || {
                let mut stop = false;
                let mut prometheus_reporter = Pr::new(host_and_port);
                while !stop {
                    match collect_to_send(&rx) {
                        // Unwraping is always dangerouns. In this case our prometheus reporter is
                        // overwhelmed by metrics
                        Ok(metrics) => {
                            try!(prometheus_reporter.add(metrics));
                        }
                        Err(_) => stop = true,
                    }
                    thread::sleep(Duration::from_millis(delay_ms));
                }
                Ok(())
            }),
        }
    }
}

fn to_repeated_fields_labels(labels: HashMap<String, String>)
                             -> RepeatedField<promo_proto::LabelPair> {
    let mut repeated_fields = Vec::new();
    // name/value is what they call it in the protobufs *shrug*
    for (name, value) in labels {
        let mut label_pair = promo_proto::LabelPair::new();
        label_pair.set_name(name);
        label_pair.set_value(value);
        repeated_fields.push(label_pair);
    }
    RepeatedField::from_vec(repeated_fields)
}

fn make_metric(metric: &Metric,
               labels: &HashMap<String, String>)
               -> (promo_proto::Metric, promo_proto::MetricType) {

    let mut pb_metric = promo_proto::Metric::new();
    let ts = time::now().to_timespec().sec;

    pb_metric.set_timestamp_ms(ts);
    pb_metric.set_label(to_repeated_fields_labels(labels.clone()));
    match *metric {
        Metric::Counter(ref x) => {
            let snapshot = x.snapshot();
            let mut counter = promo_proto::Counter::new();
            counter.set_value(snapshot.value as f64);
            pb_metric.set_counter(counter);
            (pb_metric, promo_proto::MetricType::COUNTER)
        }
        Metric::Gauge(ref x) => {
            let snapshot = x.snapshot();
            let mut gauge = promo_proto::Gauge::new();
            gauge.set_value(snapshot.value as f64);
            pb_metric.set_gauge(gauge);
            (pb_metric, promo_proto::MetricType::GAUGE)
        }
        Metric::Meter(_) => {
            pb_metric.set_summary(promo_proto::Summary::new());
            (pb_metric, promo_proto::MetricType::SUMMARY)

        }
        Metric::Histogram(_) => {
            pb_metric.set_histogram(promo_proto::Histogram::new());
            (pb_metric, promo_proto::MetricType::HISTOGRAM)
        }
    }
}

fn collect_to_send(metric_entries: &mpsc::Receiver<Result<PrometheusMetricEntry, &'static str>>)
                   -> Result<Vec<promo_proto::MetricFamily>, &'static str> {
    let mut entries_group = HashMap::<String, Vec<PrometheusMetricEntry>>::new();

    // Group them by name TODO we should include tags and types in the grouping
    for _entry in metric_entries {
        let entry = try!(_entry);
        let name = entry.name.clone();
        let mut entries = entries_group.remove(&name).unwrap_or(vec![]);
        entries.push(entry);
        entries_group.insert(name, entries);
    }
    Ok(metric_entries_to_family(entries_group))

}

fn metric_entries_to_family(entries_group: HashMap<String, Vec<PrometheusMetricEntry>>)
                            -> Vec<promo_proto::MetricFamily> {
    let mut families = Vec::new();
    for (name, metric_entries) in &entries_group {
        let formatted_metric = format!("{}_{}_{}", "application_name", name, "bytes");
        // TODO check for 0 length

        let ref e1: PrometheusMetricEntry = metric_entries[0];
        let (_, pb_metric_type) = make_metric(&e1.metric, &e1.labels);

        let mut family = promo_proto::MetricFamily::new();
        let mut pb_metrics = Vec::new();

        for metric_entry in metric_entries {
            // TODO maybe don't assume they have the same type
            let (pb_metric, _) = make_metric(&metric_entry.metric, &metric_entry.labels);
            pb_metrics.push(pb_metric);
        }

        family.set_name(String::from(formatted_metric));
        family.set_field_type(pb_metric_type);
        family.set_metric(RepeatedField::from_vec(pb_metrics));
        families.push(family);
    }
    families
}

#[cfg(test)]
mod test {
    use histogram::Histogram;
    use std::collections::HashMap;
    use metrics::{Counter, Gauge, Meter, Metric, StdCounter, StdGauge, StdMeter};
    use super::PrometheusReporter;
    use reporter::Reporter;

    #[test]
    fn meter() {
        let m = StdMeter::new();
        m.mark(100);

        let c = StdCounter::new();
        c.inc();

        let g = StdGauge::new();
        g.set(2);

        let mut h = Histogram::configure()
                        .max_value(100)
                        .precision(1)
                        .build()
                        .unwrap();

        h.increment_by(1, 1).unwrap();

        let mut reporter = PrometheusReporter::new("test", "0.0.0.0:80", 1024);
        let labels = Some(HashMap::new());
        reporter.addl("meter1", Metric::Meter(m.clone()), labels.clone());
        reporter.addl("counter1", Metric::Counter(c.clone()), labels.clone());
        reporter.addl("gauge1", Metric::Gauge(g.clone()), labels.clone());
        reporter.addl("histogram", Metric::Histogram(h), labels);
        reporter.stop().unwrap().join().unwrap().unwrap();
    }
}
<|endoftext|>


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

use std::fmt;
use std::io::prelude::*;
use std::io;

use externalfiles::ExternalHtml;

#[derive(Clone)]
pub struct Layout {
    pub logo: String,
    pub favicon: String,
    pub external_html: ExternalHtml,
    pub krate: String,
    pub playground_url: String,
}

pub struct Page<'a> {
    pub title: &'a str,
    pub ty: &'a str,
    pub root_path: &'a str,
    pub description: &'a str,
    pub keywords: &'a str
}

pub fn render<T: fmt::Display, S: fmt::Display>(
    dst: &mut io::Write, layout: &Layout, page: &Page, sidebar: &S, t: &T)
    -> io::Result<()>
{
    write!(dst,
r##"<!DOCTYPE html>

    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta name="generator" content="rustdoc">
    <meta name="description" content="{description}">
    <meta name="keywords" content="{keywords}">

    <title>{title}</title>

    <link rel="stylesheet" type="text/css" href="{root_path}main.css">

    {favicon}
    {in_header}

    {before_content}

        {logo}
        {sidebar}

        <form class="search-form js-only">

                <input class="search-input" name="search"
                       autocomplete="off"
                       placeholder="Click or press 'S' to search, '?' for more options..."
                       type="search">

        </form>

{content}

Keyboard shortcuts

?

Show this help dialog

S

Focus the search field

⇤

Move up in search results

⇥

Move down in search results

⏎

Go to active search result

Search tricks

                Prefix searches with a type followed by a colon (e.g.
                fn:) to restrict the search to a given type.

                Accepted types are: fn, mod,
                struct, enum,
                trait, typedef (or
                tdef).

    {after_content}

    {play_js}

"##,
    content   = *t,
    root_path = page.root_path,
    ty        = page.ty,
    logo      = if layout.logo.is_empty() {
        "".to_string()
    } else {
        format!("\
                 ",
                page.root_path, layout.krate,
                layout.logo)
    },
    title     = page.title,
    description = page.description,
    keywords = page.keywords,
    favicon   = if layout.favicon.is_empty() {
        "".to_string()
    } else {
        format!(r#"<link rel="shortcut icon" href="{}">"#, layout.favicon)
    },
    in_header = layout.external_html.in_header,
    before_content = layout.external_html.before_content,
    after_content = layout.external_html.after_content,
    sidebar   = *sidebar,
    krate     = layout.krate,
    play_url  = layout.playground_url,
    play_js   = if layout.playground_url.is_empty() {
        "".to_string()
    } else {
        format!(r#""#, page.root_path)
    },
    )
}

pub fn redirect(dst: &mut io::Write, url: &str) -> io::Result<()> {
    //

"##,
    url = url,
    )
}
<commit_msg>Add note about type signature searching to docs<commit_after>// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use std::fmt;
use std::io::prelude::*;
use std::io;

use externalfiles::ExternalHtml;

#[derive(Clone)]
pub struct Layout {
    pub logo: String,
    pub favicon: String,
    pub external_html: ExternalHtml,
    pub krate: String,
    pub playground_url: String,
}

pub struct Page<'a> {
    pub title: &'a str,
    pub ty: &'a str,
    pub root_path: &'a str,
    pub description: &'a str,
    pub keywords: &'a str
}

pub fn render<T: fmt::Display, S: fmt::Display>(
    dst: &mut io::Write, layout: &Layout, page: &Page, sidebar: &S, t: &T)
    -> io::Result<()>
{
    write!(dst,
r##"<!DOCTYPE html>

    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta name="generator" content="rustdoc">
    <meta name="description" content="{description}">
    <meta name="keywords" content="{keywords}">

    <title>{title}</title>

    <link rel="stylesheet" type="text/css" href="{root_path}main.css">

    {favicon}
    {in_header}

    {before_content}

        {logo}
        {sidebar}

        <form class="search-form js-only">

                <input class="search-input" name="search"
                       autocomplete="off"
                       placeholder="Click or press 'S' to search, '?' for more options..."
                       type="search">

        </form>

{content}

Keyboard shortcuts

?

Show this help dialog

S

Focus the search field

⇤

Move up in search results

⇥

Move down in search results

⏎

Go to active search result

Search tricks

                Prefix searches with a type followed by a colon (e.g.
                fn:) to restrict the search to a given type.

                Accepted types are: fn, mod,
                struct, enum,
                trait, typedef (or
                tdef).

                Search functions by type signature (e.g.
                vec -> usize)

    {after_content}

    {play_js}

"##,
    content   = *t,
    root_path = page.root_path,
    ty        = page.ty,
    logo      = if layout.logo.is_empty() {
        "".to_string()
    } else {
        format!("\
                 ",
                page.root_path, layout.krate,
                layout.logo)
    },
    title     = page.title,
    description = page.description,
    keywords = page.keywords,
    favicon   = if layout.favicon.is_empty() {
        "".to_string()
    } else {
        format!(r#"<link rel="shortcut icon" href="{}">"#, layout.favicon)
    },
    in_header = layout.external_html.in_header,
    before_content = layout.external_html.before_content,
    after_content = layout.external_html.after_content,
    sidebar   = *sidebar,
    krate     = layout.krate,
    play_url  = layout.playground_url,
    play_js   = if layout.playground_url.is_empty() {
        "".to_string()
    } else {
        format!(r#""#, page.root_path)
    },
    )
}

pub fn redirect(dst: &mut io::Write, url: &str) -> io::Result<()> {
    //

"##,
    url = url,
    )
}
<|endoftext|>


<commit_before><commit_msg>created sourced names w/o past names map part<commit_after><|endoftext|>


<commit_before><commit_msg>blank message<commit_after><|endoftext|>


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


<commit_before><commit_msg>parser: remove unused enum field<commit_after><|endoftext|>


<commit_before><commit_msg>Added prune<commit_after>use super::PathInfo;

use super::SideEffectRefs;

/// This matcher checks the type of the file.
pub struct PruneMatcher {
}

impl PruneMatcher {
    pub fn new() -> PruneMatcher {
        PruneMatcher {}
    }

    pub fn new_box() -> Box<super::Matcher> {
        Box::new(PruneMatcher::new())
    }
}

impl super::Matcher for PruneMatcher {
    fn matches(&self, _: &PathInfo, side_effects: &mut SideEffectRefs) -> bool {
        side_effects.should_skip_current_dir = true;
        return true;
    }

    fn has_side_effects(&self) -> bool {
        false
    }
}
#[cfg(test)]

mod tests {
    use super::super::tests::get_dir_entry_for;
    use super::PruneMatcher;
    use super::super::Matcher;
    use super::super::SideEffectRefs;

    #[test]
    fn file_type_matcher() {
        let dir = get_dir_entry_for("test_data", "simple");

        let mut side_effects = SideEffectRefs::new();
        assert!(!side_effects.should_skip_current_dir);
        let matcher = PruneMatcher::new();
        assert!(matcher.matches(&dir, &mut side_effects));
        assert!(side_effects.should_skip_current_dir);
    }

}
<|endoftext|>


<commit_before><commit_msg>added risk classification status for tracking item priority<commit_after>use rustc_serialize::{Encodable, Encoder, Decodable, Decoder};
use std::cmp::Ordering;
use cli::clap::ArgMatches;

#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
pub enum Risk {
    Null,
    Low,
    Moderate,
    High,
    Critical,
}

impl Risk {
    // to_u8, matches Risk variant to an assigned u8 field
    fn to_u8(&self) -> u8 {
        match *self {
            Risk::Null => 0,
            Risk::Low => 10,
            Risk::Moderate => 20,
            Risk::High => 30,
            Risk::Critical => 40,
        }
    }

    // from_u8, matches u8 to Risk variant
    fn from_u8(v: u8) -> Self {
        match v {
            10 => Risk::Low,
            20 => Risk::Moderate,
            30 => Risk::High,
            40 => Risk::Critical,
            _ => Risk::Null,
        }
    }

    // from_option_matches, finds risk classification based on explicit cli arguments and alias
    pub fn from_option_matches(o: &ArgMatches) -> Self {
        if o.is_present("low") {
            Risk::Low
        } else if o.is_present("moderate") {
            Risk::Moderate
        } else if o.is_present("high") {
            Risk::High
        } else if o.is_present("critical") {
            Risk::Critical
        } else if let Some(e) = o.value_of("pr") {
            match e {
                "low" | "l" => Risk::Low,
                "moderate" | "m" => Risk::Moderate,
                "high" | "h" => Risk::High,
                "critical" | "crit" | "c" => Risk::Critical,
                _ => Risk::Null,
            }
        } else {
            Risk::Null
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>Add missing file.<commit_after>pub trait Simplex<V, N>
{
  fn new(V)                               -> Self;
  fn add_point(&mut self, V);
  fn project_origin_and_reduce(&mut self) -> V;
  fn project_origin(&mut self)            -> V;
  fn contains_point(&self, &V)            -> bool; // FIXME: remove that
  fn dimension(&self)                     -> uint;
  fn max_sq_len(&self)                    -> N;
}
<|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.

use core::mem;
use core::ptr::*;
use core::cell::RefCell;

/// Create a null pointer to a mutable slice.  This is implemented like
/// `slice::from_raw_parts_mut`, which we can't use directly because
/// having a null `&mut [T]` even temporarily is UB.
fn null_slice<T>() -> *mut [T] {
    unsafe {
        #[repr(C)]
        struct Repr<T> {
            pub data: *mut T,
            pub len: usize,
        }

        mem::transmute(Repr { data: null_mut::<T>(), len: 0 })
    }
}

#[test]
fn test() {
    unsafe {
        struct Pair {
            fst: isize,
            snd: isize
        };
        let mut p = Pair {fst: 10, snd: 20};
        let pptr: *mut Pair = &mut p;
        let iptr: *mut isize = pptr as *mut isize;
        assert_eq!(*iptr, 10);
        *iptr = 30;
        assert_eq!(*iptr, 30);
        assert_eq!(p.fst, 30);

        *pptr = Pair {fst: 50, snd: 60};
        assert_eq!(*iptr, 50);
        assert_eq!(p.fst, 50);
        assert_eq!(p.snd, 60);

        let v0 = vec![32000u16, 32001u16, 32002u16];
        let mut v1 = vec![0u16, 0u16, 0u16];

        copy(v0.as_ptr().offset(1), v1.as_mut_ptr().offset(1), 1);
        assert!((v1[0] == 0u16 &&
                 v1[1] == 32001u16 &&
                 v1[2] == 0u16));
        copy(v0.as_ptr().offset(2), v1.as_mut_ptr(), 1);
        assert!((v1[0] == 32002u16 &&
                 v1[1] == 32001u16 &&
                 v1[2] == 0u16));
        copy(v0.as_ptr(), v1.as_mut_ptr().offset(2), 1);
        assert!((v1[0] == 32002u16 &&
                 v1[1] == 32001u16 &&
                 v1[2] == 32000u16));
    }
}

#[test]
fn test_is_null() {
    let p: *const isize = null();
    assert!(p.is_null());

    let q = unsafe { p.offset(1) };
    assert!(!q.is_null());

    let mp: *mut isize = null_mut();
    assert!(mp.is_null());

    let mq = unsafe { mp.offset(1) };
    assert!(!mq.is_null());

    // Pointers to unsized types
    let s: &mut [u8] = &mut [1, 2, 3];
    let cs: *const [u8] = s;
    assert!(!cs.is_null());

    let ms: *mut [u8] = s;
    assert!(!ms.is_null());

    let cz: *const [u8] = &[];
    assert!(!cz.is_null());

    let mz: *mut [u8] = &mut [];
    assert!(!mz.is_null());

    let ncs: *const [u8] = null_slice();
    assert!(ncs.is_null());

    let nms: *mut [u8] = null_slice();
    assert!(nms.is_null());
}

#[test]
fn test_as_ref() {
    unsafe {
        let p: *const isize = null();
        assert_eq!(p.as_ref(), None);

        let q: *const isize = &2;
        assert_eq!(q.as_ref().unwrap(), &2);

        let p: *mut isize = null_mut();
        assert_eq!(p.as_ref(), None);

        let q: *mut isize = &mut 2;
        assert_eq!(q.as_ref().unwrap(), &2);

        // Lifetime inference
        let u = 2isize;
        {
            let p = &u as *const isize;
            assert_eq!(p.as_ref().unwrap(), &2);
        }

        // Pointers to unsized types
        let s: &mut [u8] = &mut [1, 2, 3];
        let cs: *const [u8] = s;
        assert_eq!(cs.as_ref(), Some(&*s));

        let ms: *mut [u8] = s;
        assert_eq!(ms.as_ref(), Some(&*s));

        let cz: *const [u8] = &[];
        assert_eq!(cz.as_ref(), Some(&[][..]));

        let mz: *mut [u8] = &mut [];
        assert_eq!(mz.as_ref(), Some(&[][..]));

        let ncs: *const [u8] = null_slice();
        assert_eq!(ncs.as_ref(), None);

        let nms: *mut [u8] = null_slice();
        assert_eq!(nms.as_ref(), None);
    }
}

#[test]
fn test_as_mut() {
    unsafe {
        let p: *mut isize = null_mut();
        assert!(p.as_mut() == None);

        let q: *mut isize = &mut 2;
        assert!(q.as_mut().unwrap() == &mut 2);

        // Lifetime inference
        let mut u = 2isize;
        {
            let p = &mut u as *mut isize;
            assert!(p.as_mut().unwrap() == &mut 2);
        }

        // Pointers to unsized types
        let s: &mut [u8] = &mut [1, 2, 3];
        let ms: *mut [u8] = s;
        assert_eq!(ms.as_mut(), Some(s));

        let mz: *mut [u8] = &mut [];
        assert_eq!(mz.as_mut(), Some(&mut [][..]));

        let nms: *mut [u8] = null_slice();
        assert_eq!(nms.as_mut(), None);
    }
}

#[test]
fn test_ptr_addition() {
    unsafe {
        let xs = vec![5; 16];
        let mut ptr = xs.as_ptr();
        let end = ptr.offset(16);

        while ptr < end {
            assert_eq!(*ptr, 5);
            ptr = ptr.offset(1);
        }

        let mut xs_mut = xs;
        let mut m_ptr = xs_mut.as_mut_ptr();
        let m_end = m_ptr.offset(16);

        while m_ptr < m_end {
            *m_ptr += 5;
            m_ptr = m_ptr.offset(1);
        }

        assert!(xs_mut == vec![10; 16]);
    }
}

#[test]
fn test_ptr_subtraction() {
    unsafe {
        let xs = vec![0,1,2,3,4,5,6,7,8,9];
        let mut idx = 9;
        let ptr = xs.as_ptr();

        while idx >= 0 {
            assert_eq!(*(ptr.offset(idx as isize)), idx as isize);
            idx = idx - 1;
        }

        let mut xs_mut = xs;
        let m_start = xs_mut.as_mut_ptr();
        let mut m_ptr = m_start.offset(9);

        while m_ptr >= m_start {
            *m_ptr += *m_ptr;
            m_ptr = m_ptr.offset(-1);
        }

        assert_eq!(xs_mut, [0,2,4,6,8,10,12,14,16,18]);
    }
}

#[test]
fn test_set_memory() {
    let mut xs = [0u8; 20];
    let ptr = xs.as_mut_ptr();
    unsafe { write_bytes(ptr, 5u8, xs.len()); }
    assert!(xs == [5u8; 20]);
}

#[test]
fn test_unsized_unique() {
    let xs: &[i32] = &[1, 2, 3];
    let ptr = unsafe { Unique::new_unchecked(xs as *const [i32] as *mut [i32]) };
    let ys = unsafe { ptr.as_ref() };
    let zs: &[i32] = &[1, 2, 3];
    assert!(ys == zs);
}

#[test]
#[allow(warnings)]
// Have a symbol for the test below. It doesn’t need to be an actual variadic function, match the
// ABI, or even point to an actual executable code, because the function itself is never invoked.
#[no_mangle]
pub fn test_variadic_fnptr() {
    use core::hash::{Hash, SipHasher};
    extern {
        fn test_variadic_fnptr(_: u64, ...) -> f64;
    }
    let p: unsafe extern fn(u64, ...) -> f64 = test_variadic_fnptr;
    let q = p.clone();
    assert_eq!(p, q);
    assert!(!(p < q));
    let mut s = SipHasher::new();
    assert_eq!(p.hash(&mut s), q.hash(&mut s));
}

#[test]
fn write_unaligned_drop() {
    thread_local! {
        static DROPS: RefCell<Vec<u32>> = RefCell::new(Vec::new());
    }

    struct Dropper(u32);

    impl Drop for Dropper {
        fn drop(&mut self) {
            DROPS.with(|d| d.borrow_mut().push(self.0));
        }
    }

    {
        let c = Dropper(0);
        let mut t = Dropper(1);
        unsafe { write_unaligned(&mut t, c); }
    }
    DROPS.with(|d| assert_eq!(*d.borrow(), [0]));
}
<commit_msg>Use unsized coercions for null ptr tests<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.

use core::ptr::*;
use core::cell::RefCell;

#[test]
fn test() {
    unsafe {
        struct Pair {
            fst: isize,
            snd: isize
        };
        let mut p = Pair {fst: 10, snd: 20};
        let pptr: *mut Pair = &mut p;
        let iptr: *mut isize = pptr as *mut isize;
        assert_eq!(*iptr, 10);
        *iptr = 30;
        assert_eq!(*iptr, 30);
        assert_eq!(p.fst, 30);

        *pptr = Pair {fst: 50, snd: 60};
        assert_eq!(*iptr, 50);
        assert_eq!(p.fst, 50);
        assert_eq!(p.snd, 60);

        let v0 = vec![32000u16, 32001u16, 32002u16];
        let mut v1 = vec![0u16, 0u16, 0u16];

        copy(v0.as_ptr().offset(1), v1.as_mut_ptr().offset(1), 1);
        assert!((v1[0] == 0u16 &&
                 v1[1] == 32001u16 &&
                 v1[2] == 0u16));
        copy(v0.as_ptr().offset(2), v1.as_mut_ptr(), 1);
        assert!((v1[0] == 32002u16 &&
                 v1[1] == 32001u16 &&
                 v1[2] == 0u16));
        copy(v0.as_ptr(), v1.as_mut_ptr().offset(2), 1);
        assert!((v1[0] == 32002u16 &&
                 v1[1] == 32001u16 &&
                 v1[2] == 32000u16));
    }
}

#[test]
fn test_is_null() {
    let p: *const isize = null();
    assert!(p.is_null());

    let q = unsafe { p.offset(1) };
    assert!(!q.is_null());

    let mp: *mut isize = null_mut();
    assert!(mp.is_null());

    let mq = unsafe { mp.offset(1) };
    assert!(!mq.is_null());

    // Pointers to unsized types -- slices
    let s: &mut [u8] = &mut [1, 2, 3];
    let cs: *const [u8] = s;
    assert!(!cs.is_null());

    let ms: *mut [u8] = s;
    assert!(!ms.is_null());

    let cz: *const [u8] = &[];
    assert!(!cz.is_null());

    let mz: *mut [u8] = &mut [];
    assert!(!mz.is_null());

    let ncs: *const [u8] = null::<[u8; 3]>();
    assert!(ncs.is_null());

    let nms: *mut [u8] = null_mut::<[u8; 3]>();
    assert!(nms.is_null());

    // Pointers to unsized types -- trait objects
    let ci: *const ToString = &3;
    assert!(!ci.is_null());

    let mi: *mut ToString = &mut 3;
    assert!(!mi.is_null());

    let nci: *const ToString = null::<isize>();
    assert!(nci.is_null());

    let nmi: *mut ToString = null_mut::<isize>();
    assert!(nmi.is_null());
}

#[test]
fn test_as_ref() {
    unsafe {
        let p: *const isize = null();
        assert_eq!(p.as_ref(), None);

        let q: *const isize = &2;
        assert_eq!(q.as_ref().unwrap(), &2);

        let p: *mut isize = null_mut();
        assert_eq!(p.as_ref(), None);

        let q: *mut isize = &mut 2;
        assert_eq!(q.as_ref().unwrap(), &2);

        // Lifetime inference
        let u = 2isize;
        {
            let p = &u as *const isize;
            assert_eq!(p.as_ref().unwrap(), &2);
        }

        // Pointers to unsized types -- slices
        let s: &mut [u8] = &mut [1, 2, 3];
        let cs: *const [u8] = s;
        assert_eq!(cs.as_ref(), Some(&*s));

        let ms: *mut [u8] = s;
        assert_eq!(ms.as_ref(), Some(&*s));

        let cz: *const [u8] = &[];
        assert_eq!(cz.as_ref(), Some(&[][..]));

        let mz: *mut [u8] = &mut [];
        assert_eq!(mz.as_ref(), Some(&[][..]));

        let ncs: *const [u8] = null::<[u8; 3]>();
        assert_eq!(ncs.as_ref(), None);

        let nms: *mut [u8] = null_mut::<[u8; 3]>();
        assert_eq!(nms.as_ref(), None);

        // Pointers to unsized types -- trait objects
        let ci: *const ToString = &3;
        assert!(ci.as_ref().is_some());

        let mi: *mut ToString = &mut 3;
        assert!(mi.as_ref().is_some());

        let nci: *const ToString = null::<isize>();
        assert!(nci.as_ref().is_none());

        let nmi: *mut ToString = null_mut::<isize>();
        assert!(nmi.as_ref().is_none());
    }
}

#[test]
fn test_as_mut() {
    unsafe {
        let p: *mut isize = null_mut();
        assert!(p.as_mut() == None);

        let q: *mut isize = &mut 2;
        assert!(q.as_mut().unwrap() == &mut 2);

        // Lifetime inference
        let mut u = 2isize;
        {
            let p = &mut u as *mut isize;
            assert!(p.as_mut().unwrap() == &mut 2);
        }

        // Pointers to unsized types -- slices
        let s: &mut [u8] = &mut [1, 2, 3];
        let ms: *mut [u8] = s;
        assert_eq!(ms.as_mut(), Some(s));

        let mz: *mut [u8] = &mut [];
        assert_eq!(mz.as_mut(), Some(&mut [][..]));

        let nms: *mut [u8] = null_mut::<[u8; 3]>();
        assert_eq!(nms.as_mut(), None);

        // Pointers to unsized types -- trait objects
        let mi: *mut ToString = &mut 3;
        assert!(mi.as_mut().is_some());

        let nmi: *mut ToString = null_mut::<isize>();
        assert!(nmi.as_mut().is_none());
    }
}

#[test]
fn test_ptr_addition() {
    unsafe {
        let xs = vec![5; 16];
        let mut ptr = xs.as_ptr();
        let end = ptr.offset(16);

        while ptr < end {
            assert_eq!(*ptr, 5);
            ptr = ptr.offset(1);
        }

        let mut xs_mut = xs;
        let mut m_ptr = xs_mut.as_mut_ptr();
        let m_end = m_ptr.offset(16);

        while m_ptr < m_end {
            *m_ptr += 5;
            m_ptr = m_ptr.offset(1);
        }

        assert!(xs_mut == vec![10; 16]);
    }
}

#[test]
fn test_ptr_subtraction() {
    unsafe {
        let xs = vec![0,1,2,3,4,5,6,7,8,9];
        let mut idx = 9;
        let ptr = xs.as_ptr();

        while idx >= 0 {
            assert_eq!(*(ptr.offset(idx as isize)), idx as isize);
            idx = idx - 1;
        }

        let mut xs_mut = xs;
        let m_start = xs_mut.as_mut_ptr();
        let mut m_ptr = m_start.offset(9);

        while m_ptr >= m_start {
            *m_ptr += *m_ptr;
            m_ptr = m_ptr.offset(-1);
        }

        assert_eq!(xs_mut, [0,2,4,6,8,10,12,14,16,18]);
    }
}

#[test]
fn test_set_memory() {
    let mut xs = [0u8; 20];
    let ptr = xs.as_mut_ptr();
    unsafe { write_bytes(ptr, 5u8, xs.len()); }
    assert!(xs == [5u8; 20]);
}

#[test]
fn test_unsized_unique() {
    let xs: &[i32] = &[1, 2, 3];
    let ptr = unsafe { Unique::new_unchecked(xs as *const [i32] as *mut [i32]) };
    let ys = unsafe { ptr.as_ref() };
    let zs: &[i32] = &[1, 2, 3];
    assert!(ys == zs);
}

#[test]
#[allow(warnings)]
// Have a symbol for the test below. It doesn’t need to be an actual variadic function, match the
// ABI, or even point to an actual executable code, because the function itself is never invoked.
#[no_mangle]
pub fn test_variadic_fnptr() {
    use core::hash::{Hash, SipHasher};
    extern {
        fn test_variadic_fnptr(_: u64, ...) -> f64;
    }
    let p: unsafe extern fn(u64, ...) -> f64 = test_variadic_fnptr;
    let q = p.clone();
    assert_eq!(p, q);
    assert!(!(p < q));
    let mut s = SipHasher::new();
    assert_eq!(p.hash(&mut s), q.hash(&mut s));
}

#[test]
fn write_unaligned_drop() {
    thread_local! {
        static DROPS: RefCell<Vec<u32>> = RefCell::new(Vec::new());
    }

    struct Dropper(u32);

    impl Drop for Dropper {
        fn drop(&mut self) {
            DROPS.with(|d| d.borrow_mut().push(self.0));
        }
    }

    {
        let c = Dropper(0);
        let mut t = Dropper(1);
        unsafe { write_unaligned(&mut t, c); }
    }
    DROPS.with(|d| assert_eq!(*d.borrow(), [0]));
}
<|endoftext|>


<commit_before><commit_msg>Delete main.rs<commit_after><|endoftext|>


<commit_before><commit_msg>start on systems expansion example<commit_after>pub mod my_system {
	#[derive(Default)]
	struct State {
		i: i64
	}

	pub static ref state: SharedMutex<State> = SharedMutex::new(State::default());

	impl State {
		fn event_name(&mut self, data: &Vec<event_name::Data>, positions: &Vec<Position>, descriptions: &mut Vec<Description> ) {
			let position = positions[0];
			descriptions[0].set(format!("Position = {},{}", position.x, position.y));
		}
	}

	pub fn event_name(&Vec<event_name::Data> event_data, components: Vec<Any>) {
		let components_iter = components.iter();
		let positions : &Vec<Position> = components
			.next().expect("Event components list too short.")
			.downcast_ref().expect("Event component not of expected type.");
		let positions : &mut Vec<Description> = components
			.next().expect("Event components list too short.")
			.downcast_ref().expect("Event component not of expected type.");
		let state = state.write().expect("System lock corrupted.");
		state.event_name(event_data, positions, descriptions);
	}

	pub fn register() {
		events::register_handler(event_name, vec![Position::type_id()], vec![Description::type_id()]);
	}
}<|endoftext|>


<commit_before>use read_write::*;
use service::*;
use libc::*;
use std::mem::transmute;

pub static API_VERSION: &'static str = "ProDBG Backend 1";

pub trait Backend {
    fn new(service: &Service) -> Self;
    fn update(&mut self, reader: &mut Reader, writer: &mut Writer);
}

#[repr(C)]
pub struct CBackendCallbacks {
    pub name: *const c_uchar,
    pub create_instance: Option<fn(service_func: extern "C" fn(service: *const c_char)) -> *mut c_void>,
    pub destroy_instance: Option<fn(*mut c_void)>,
    pub register_menu: Option<fn() -> *mut c_void>,
    pub update: Option<fn(ptr: *mut c_void, action: *mut c_int, reader_api: *mut c_void, writer_api: *mut c_void)>,
}

pub fn create_backend_instance<T: Backend>(service_func: extern "C" fn(service: *const c_char)) -> *mut c_void {
    let service = Service { service_func: service_func };
    let instance = unsafe { transmute(Box::new(T::new(&service))) };
    println!("Lets create instance!");
    instance
}

pub fn destroy_backend_instance<T: Backend>(ptr: *mut c_void) {
    println!("rust: backend: destroy");
    let _: Box<T> = unsafe { transmute(ptr) };
    // implicitly dropped
}

pub fn update_backend_instance<T: Backend>(ptr: *mut c_void,
                                           _: *mut c_int,
                                           reader_api: *mut c_void,
                                           writer_api: *mut c_void) {
    let backend: &mut T = unsafe { &mut *(ptr as *mut T) };
    let c_reader: &mut CPDReaderAPI = unsafe { &mut *(reader_api as *mut CPDReaderAPI) };
    let c_writer: &mut CPDWriterAPI = unsafe { &mut *(writer_api as *mut CPDWriterAPI) };
    let mut reader = Reader {
        api: c_reader,
        it: 0,
    };

    let mut writer = Writer { api: c_writer };

    println!("writer.api {:?}", writer.api);

    backend.update(&mut reader, &mut writer);
}

#[macro_export]
macro_rules! define_backend_plugin {
    ($x:ty) => {
        {
            static S: &'static [u8] = b"Test\0";
            let mut plugin = CBackendCallbacks {
                name: S.as_ptr(),
                create_instance: Some(prodbg::backend::create_backend_instance::<$x>),
                destroy_instance: Some(prodbg::backend::destroy_backend_instance::<$x>),
                register_menu: None,
                update: Some(prodbg::backend::update_backend_instance::<$x>)
             };

            Box::new(plugin)
        }
    }
}
<commit_msg>Some minor cleanup<commit_after>use read_write::*;
use service::*;
use libc::*;
use std::mem::transmute;

pub static API_VERSION: &'static str = "ProDBG Backend 1";

pub trait Backend {
    fn new(service: &Service) -> Self;
    fn update(&mut self, reader: &mut Reader, writer: &mut Writer);
}

#[repr(C)]
pub struct CBackendCallbacks {
    pub name: *const c_uchar,
    pub create_instance: Option<fn(service_func: extern "C" fn(service: *const c_char)) -> *mut c_void>,
    pub destroy_instance: Option<fn(*mut c_void)>,
    pub register_menu: Option<fn() -> *mut c_void>,
    pub update: Option<fn(ptr: *mut c_void, a: *mut c_int, ra: *mut c_void, wa: *mut c_void)>,
}

pub fn create_backend_instance<T: Backend>(service_func: extern "C" fn(service: *const c_char)) -> *mut c_void {
    let service = Service { service_func: service_func };
    let instance = unsafe { transmute(Box::new(T::new(&service))) };
    println!("Lets create instance!");
    instance
}

pub fn destroy_backend_instance<T: Backend>(ptr: *mut c_void) {
    println!("rust: backend: destroy");
    let _: Box<T> = unsafe { transmute(ptr) };
    // implicitly dropped
}

pub fn update_backend_instance<T: Backend>(ptr: *mut c_void,
                                           _: *mut c_int,
                                           reader_api: *mut c_void,
                                           writer_api: *mut c_void) {
    let backend: &mut T = unsafe { &mut *(ptr as *mut T) };
    let c_reader: &mut CPDReaderAPI = unsafe { &mut *(reader_api as *mut CPDReaderAPI) };
    let c_writer: &mut CPDWriterAPI = unsafe { &mut *(writer_api as *mut CPDWriterAPI) };
    let mut reader = Reader {
        api: c_reader,
        it: 0,
    };

    let mut writer = Writer { api: c_writer };

    println!("writer.api {:?}", writer.api);

    backend.update(&mut reader, &mut writer);
}

#[macro_export]
macro_rules! define_backend_plugin {
    ($x:ty) => {
        {
            static S: &'static [u8] = b"Test\0";
            let mut plugin = CBackendCallbacks {
                name: S.as_ptr(),
                create_instance: Some(prodbg::backend::create_backend_instance::<$x>),
                destroy_instance: Some(prodbg::backend::destroy_backend_instance::<$x>),
                register_menu: None,
                update: Some(prodbg::backend::update_backend_instance::<$x>)
             };

            Box::new(plugin)
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>added sample for split_array_const<commit_after>// https://github.com/rust-lang/rust/issues/74674

#![feature(const_refs_to_cell)]
#![feature(const_ptr_read)]
#![feature(const_ptr_offset)]
#![feature(generic_const_exprs)]

use core::mem::ManuallyDrop;

const fn split_arr<T, const N: usize, const M: usize>(arr: [T; N]) -> ([T; M], [T; N - M])
where
    [T; N - M]: ,
{
    let arr = ManuallyDrop::new(arr);
    let start_ptr = &arr as *const _ as *const T;
    let arr_1_ptr = start_ptr as *const [T; M];
    let arr_2_ptr = unsafe { start_ptr.add(M) } as *const [T; N - M];

    unsafe { (arr_1_ptr.read(), arr_2_ptr.read()) }
}

const ARR: [u8; 10] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

const FIRST_3: [u8; 3] = split_arr(ARR).0;

// This last one doesn't work, since rustc can't infer the constant
// const LAST_7: [u8; 7] = split_arr(ARR).1;

// We just need to specify the generic params...
const LAST_7: [u8; 7] = split_arr::<u8, 10, 3>(ARR).1;

fn main()
{
    println!("ARR: {:?} FIRST_3: {:?} LAST_7: {:?}", ARR, FIRST_3, LAST_7);
}
<|endoftext|>


<commit_before><commit_msg>Keep track of private and public channels<commit_after><|endoftext|>


<commit_before><commit_msg>Try at least tree times before dying<commit_after><|endoftext|>


<commit_before><commit_msg>src\main.rs<commit_after><|endoftext|>


<commit_before><commit_msg>Reduce some redundancy in creating edges in main().<commit_after><|endoftext|>


<commit_before><commit_msg>Ord and PartialOrd<commit_after>// Rust specifies the behavior of the ordered comparison operators <, >, <=, and >=
// all in terms of a single trait,
// std::cmp::PartialOrd:

trait PartialOrd<Rhs = Self>: PartialEq<Rhs>  where Rhs: ?Sized {
    fn partial_cmp(&self, other: &Rhs) -> Option<Ordering>;

    fn lt(&self, other: &Rhs) -> bool {
        //...
    }
    fn le(&self, other: &Rhs) -> bool {
        //...
    }
    fn gt(&self, other: &Rhs) -> bool {
        //...
    }
    fn ge(&self, other: &Rhs) -> bool {
        //...
    }
}

// Note that PartialOrd<Rhs> extends PartialEq<Rhs>: you can do ordered comparisons only on types that you can also compare for equality.
// The only method of PartialOrd you must implement yourself is partial_cmp.
// When partial_cmp returns Some(o), then o indicates self’s relationship to other:

enum Ordering {
    Less, // self < other
    Equal, // self == other
    Greater, // self > other
}

// But if partial_cmp returns None, that means self and other are unordered
// with respect to each other: neither is greater than the other, nor are they equal.
// Among all of Rust’s primitive types, only comparisons between floating-point values ever return None

// Stricter Ord version. Return Ordering instead of Option<Ordering>
// Much nicer to use and much more deterministic.
trait Ord: Eq + PartialOrd<Self> {
    fn cmp(&self, other: &Self) -> Ordering;
}
<|endoftext|>