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

//! A bare-metal library supplying functions rustc may lower code to
//!
//! This library is not intended for general use, and is superseded by a system
//! libc if one is available. In a freestanding context, however, common
//! functions such as memset, memcpy, etc are not implemented. This library
//! provides an implementation of these functions which are either required by
//! libcore or called by rustc implicitly.
//!
//! This library is never included by default, and must be manually included if
//! necessary. It is an error to include this library when also linking with
//! the system libc library.

#![feature(phase)]
#![no_std]

// This library defines the builtin functions, so it would be a shame for
// LLVM to optimize these function calls to themselves!
#![no_builtins]

extern crate core;

#[phase(plugin, link)]
#[cfg(test)] extern crate std;
#[cfg(test)] extern crate native;

use core::ptr::PtrExt;

#[no_mangle]
pub unsafe extern fn memcpy(dest: *mut u8, src: *const u8,
                            n: uint) -> *mut u8 {
    let mut i = 0;
    while i < n {
        *dest.offset(i as int) = *src.offset(i as int);
        i += 1;
    }
    return dest;
}

#[no_mangle]
pub unsafe extern fn memmove(dest: *mut u8, src: *const u8,
                             n: uint) -> *mut u8 {
    if src < dest as *const u8 { // copy from end
        let mut i = n;
        while i != 0 {
            i -= 1;
            *dest.offset(i as int) = *src.offset(i as int);
        }
    } else { // copy from beginning
        let mut i = 0;
        while i < n {
            *dest.offset(i as int) = *src.offset(i as int);
            i += 1;
        }
    }
    return dest;
}

#[no_mangle]
pub unsafe extern fn memset(s: *mut u8, c: i32, n: uint) -> *mut u8 {
    let mut i = 0;
    while i < n {
        *s.offset(i as int) = c as u8;
        i += 1;
    }
    return s;
}

#[no_mangle]
pub unsafe extern fn memcmp(s1: *const u8, s2: *const u8, n: uint) -> i32 {
    let mut i = 0;
    while i < n {
        let a = *s1.offset(i as int);
        let b = *s2.offset(i as int);
        if a != b {
            return a as i32 - b as i32
        }
        i += 1;
    }
    return 0;
}

#[cfg(test)]
mod test {
    use core::str::StrSlice;
    use core::slice::{MutableSlice, ImmutableSlice};

    use super::{memcmp, memset, memcpy, memmove};

    #[test]
    fn memcmp_single_byte_pointers() {
        unsafe {
            assert_eq!(memcmp(&0xFAu8, &0xFAu8, 1), 0x00);
            assert!(memcmp(&0xEFu8, &0xFEu8, 1) < 0x00);
        }
    }

    #[test]
    fn memcmp_strings() {
        {
            let (x, z) = ("Hello!", "Good Bye.");
            let l = x.len();
            unsafe {
                assert_eq!(memcmp(x.as_ptr(), x.as_ptr(), l), 0);
                assert!(memcmp(x.as_ptr(), z.as_ptr(), l) > 0);
                assert!(memcmp(z.as_ptr(), x.as_ptr(), l) < 0);
            }
        }
        {
            let (x, z) = ("hey!", "hey.");
            let l = x.len();
            unsafe {
                assert!(memcmp(x.as_ptr(), z.as_ptr(), l) < 0);
            }
        }
    }

    #[test]
    fn memset_single_byte_pointers() {
        let mut x: u8 = 0xFF;
        unsafe {
            memset(&mut x, 0xAA, 1);
            assert_eq!(x, 0xAA);
            memset(&mut x, 0x00, 1);
            assert_eq!(x, 0x00);
            x = 0x01;
            memset(&mut x, 0x12, 0);
            assert_eq!(x, 0x01);
        }
    }

    #[test]
    fn memset_array() {
        let mut buffer = [b'X', .. 100];
        unsafe {
            memset(buffer.as_mut_ptr(), b'#' as i32, buffer.len());
        }
        for byte in buffer.iter() { assert_eq!(*byte, b'#'); }
    }

    #[test]
    fn memcpy_and_memcmp_arrays() {
        let (src, mut dst) = ([b'X', .. 100], [b'Y', .. 100]);
        unsafe {
            assert!(memcmp(src.as_ptr(), dst.as_ptr(), 100) != 0);
            let _ = memcpy(dst.as_mut_ptr(), src.as_ptr(), 100);
            assert_eq!(memcmp(src.as_ptr(), dst.as_ptr(), 100), 0);
        }
    }

    #[test]
    fn memmove_overlapping() {
        {
            let mut buffer = [ b'0', b'1', b'2', b'3', b'4', b'5', b'6', b'7', b'8', b'9' ];
            unsafe {
                memmove(&mut buffer[4], &buffer[0], 6);
                let mut i = 0;
                for byte in b"0123012345".iter() {
                    assert_eq!(buffer[i], *byte);
                    i += 1;
                }
            }
        }
        {
            let mut buffer = [ b'0', b'1', b'2', b'3', b'4', b'5', b'6', b'7', b'8', b'9' ];
            unsafe {
                memmove(&mut buffer[0], &buffer[4], 6);
                let mut i = 0;
                for byte in b"4567896789".iter() {
                    assert_eq!(buffer[i], *byte);
                    i += 1;
                }
            }
        }
    }
}
<commit_msg>Update tests to master<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.

//! A bare-metal library supplying functions rustc may lower code to
//!
//! This library is not intended for general use, and is superseded by a system
//! libc if one is available. In a freestanding context, however, common
//! functions such as memset, memcpy, etc are not implemented. This library
//! provides an implementation of these functions which are either required by
//! libcore or called by rustc implicitly.
//!
//! This library is never included by default, and must be manually included if
//! necessary. It is an error to include this library when also linking with
//! the system libc library.

#![feature(phase)]
#![no_std]

// This library defines the builtin functions, so it would be a shame for
// LLVM to optimize these function calls to themselves!
#![no_builtins]

extern crate core;

#[phase(plugin, link)]
#[cfg(test)] extern crate std;

use core::ptr::PtrExt;

#[no_mangle]
pub unsafe extern fn memcpy(dest: *mut u8, src: *const u8,
                            n: uint) -> *mut u8 {
    let mut i = 0;
    while i < n {
        *dest.offset(i as int) = *src.offset(i as int);
        i += 1;
    }
    return dest;
}

#[no_mangle]
pub unsafe extern fn memmove(dest: *mut u8, src: *const u8,
                             n: uint) -> *mut u8 {
    if src < dest as *const u8 { // copy from end
        let mut i = n;
        while i != 0 {
            i -= 1;
            *dest.offset(i as int) = *src.offset(i as int);
        }
    } else { // copy from beginning
        let mut i = 0;
        while i < n {
            *dest.offset(i as int) = *src.offset(i as int);
            i += 1;
        }
    }
    return dest;
}

#[no_mangle]
pub unsafe extern fn memset(s: *mut u8, c: i32, n: uint) -> *mut u8 {
    let mut i = 0;
    while i < n {
        *s.offset(i as int) = c as u8;
        i += 1;
    }
    return s;
}

#[no_mangle]
pub unsafe extern fn memcmp(s1: *const u8, s2: *const u8, n: uint) -> i32 {
    let mut i = 0;
    while i < n {
        let a = *s1.offset(i as int);
        let b = *s2.offset(i as int);
        if a != b {
            return a as i32 - b as i32
        }
        i += 1;
    }
    return 0;
}

#[cfg(test)]
mod test {
    use core::str::StrExt;
    use core::slice::SliceExt;

    use super::{memcmp, memset, memcpy, memmove};

    #[test]
    fn memcmp_single_byte_pointers() {
        unsafe {
            assert_eq!(memcmp(&0xFAu8, &0xFAu8, 1), 0x00);
            assert!(memcmp(&0xEFu8, &0xFEu8, 1) < 0x00);
        }
    }

    #[test]
    fn memcmp_strings() {
        {
            let (x, z) = ("Hello!", "Good Bye.");
            let l = x.len();
            unsafe {
                assert_eq!(memcmp(x.as_ptr(), x.as_ptr(), l), 0);
                assert!(memcmp(x.as_ptr(), z.as_ptr(), l) > 0);
                assert!(memcmp(z.as_ptr(), x.as_ptr(), l) < 0);
            }
        }
        {
            let (x, z) = ("hey!", "hey.");
            let l = x.len();
            unsafe {
                assert!(memcmp(x.as_ptr(), z.as_ptr(), l) < 0);
            }
        }
    }

    #[test]
    fn memset_single_byte_pointers() {
        let mut x: u8 = 0xFF;
        unsafe {
            memset(&mut x, 0xAA, 1);
            assert_eq!(x, 0xAA);
            memset(&mut x, 0x00, 1);
            assert_eq!(x, 0x00);
            x = 0x01;
            memset(&mut x, 0x12, 0);
            assert_eq!(x, 0x01);
        }
    }

    #[test]
    fn memset_array() {
        let mut buffer = [b'X', .. 100];
        unsafe {
            memset(buffer.as_mut_ptr(), b'#' as i32, buffer.len());
        }
        for byte in buffer.iter() { assert_eq!(*byte, b'#'); }
    }

    #[test]
    fn memcpy_and_memcmp_arrays() {
        let (src, mut dst) = ([b'X', .. 100], [b'Y', .. 100]);
        unsafe {
            assert!(memcmp(src.as_ptr(), dst.as_ptr(), 100) != 0);
            let _ = memcpy(dst.as_mut_ptr(), src.as_ptr(), 100);
            assert_eq!(memcmp(src.as_ptr(), dst.as_ptr(), 100), 0);
        }
    }

    #[test]
    fn memmove_overlapping() {
        {
            let mut buffer = [ b'0', b'1', b'2', b'3', b'4', b'5', b'6', b'7', b'8', b'9' ];
            unsafe {
                memmove(&mut buffer[4], &buffer[0], 6);
                let mut i = 0;
                for byte in b"0123012345".iter() {
                    assert_eq!(buffer[i], *byte);
                    i += 1;
                }
            }
        }
        {
            let mut buffer = [ b'0', b'1', b'2', b'3', b'4', b'5', b'6', b'7', b'8', b'9' ];
            unsafe {
                memmove(&mut buffer[0], &buffer[4], 6);
                let mut i = 0;
                for byte in b"4567896789".iter() {
                    assert_eq!(buffer[i], *byte);
                    i += 1;
                }
            }
        }
    }
}
<|endoftext|>


<commit_before>//! Generate Rust bindings for C and C++ libraries.
//!
//! Provide a C/C++ header file, receive Rust FFI code to call into C/C++
//! functions and use types defined in the header.
//!
//! See the [Builder](./struct.Builder.html) struct for usage.

#![crate_name = "bindgen"]
#![crate_type = "dylib"]

#![cfg_attr(feature = "clippy", feature(plugin))]
#![cfg_attr(feature = "clippy", plugin(clippy))]

#![deny(missing_docs)]

// We internally use the deprecated BindgenOptions all over the place. Once we
// remove its `pub` declaration, we can un-deprecate it and remove this pragma.
#![allow(deprecated)]

// To avoid rather annoying warnings when matching with CXCursor_xxx as a
// constant.
#![allow(non_upper_case_globals)]

extern crate syntex_syntax as syntax;
extern crate aster;
extern crate quasi;
extern crate clang_sys;
extern crate libc;
extern crate regex;
#[macro_use]
extern crate log;
#[macro_use]
extern crate lazy_static;

mod clangll;
mod clang;
mod ir;
mod parse;
mod regex_set;
mod codegen {
    include!(concat!(env!("OUT_DIR"), "/codegen.rs"));
}

use std::borrow::Borrow;
use std::io::{self, Write};
use std::fs::OpenOptions;
use std::path::Path;
use std::collections::HashSet;

use syntax::ast;
use syntax::codemap::{DUMMY_SP, Span};
use syntax::print::pprust;
use syntax::print::pp::eof;
use syntax::ptr::P;

use ir::context::BindgenContext;
use ir::item::{Item, ItemId};
use parse::{ClangItemParser, ParseError};
use regex_set::RegexSet;

/// Configure and generate Rust bindings for a C/C++ header.
///
/// This is the main entry point to the library.
///
/// ```ignore
/// use bindgen::builder;
///
/// // Configure and generate bindings.
/// let bindings = try!(builder().header("path/to/input/header")
///                              .whitelisted_type("SomeCoolClass")
///                              .whitelisted_function("do_some_cool_thing")
///                              .generate());
///
/// // Write the generated bindings to an output file.
/// try!(bindings.write_to_file("path/to/output.rs"));
/// ```
#[derive(Debug,Default)]
pub struct Builder {
    options: BindgenOptions,
}

/// Construct a new [`Builder`](./struct.Builder.html).
pub fn builder() -> Builder {
    Default::default()
}

impl Builder {
    /// Set the input C/C++ header.
    pub fn header<T: Into<String>>(self, header: T) -> Builder {
        self.clang_arg(header)
    }

    /// Hide the given type from the generated bindings.
    pub fn hide_type<T: Into<String>>(mut self, arg: T) -> Builder {
        self.options.hidden_types.insert(arg.into());
        self
    }

    /// Treat the given type as opaque in the generated bindings.
    pub fn opaque_type<T: Into<String>>(mut self, arg: T) -> Builder {
        self.options.opaque_types.insert(arg.into());
        self
    }

    /// Whitelist the given type so that it (and all types that it transitively
    /// refers to) appears in the generated bindings.
    pub fn whitelisted_type<T: Borrow<str>>(mut self, arg: T) -> Builder {
        self.options.whitelisted_types.insert(&arg);
        self
    }

    /// Whitelist the given function so that it (and all types that it
    /// transitively refers to) appears in the generated bindings.
    pub fn whitelisted_function<T: Borrow<str>>(mut self, arg: T) -> Builder {
        self.options.whitelisted_functions.insert(&arg);
        self
    }

    /// Whitelist the given variable so that it (and all types that it
    /// transitively refers to) appears in the generated bindings.
    pub fn whitelisted_var<T: Borrow<str>>(mut self, arg: T) -> Builder {
        self.options.whitelisted_vars.insert(&arg);
        self
    }

    /// Add a string to prepend to the generated bindings. The string is passed
    /// through without any modification.
    pub fn raw_line<T: Into<String>>(mut self, arg: T) -> Builder {
        self.options.raw_lines.push(arg.into());
        self
    }

    /// Add an argument to be passed straight through to clang.
    pub fn clang_arg<T: Into<String>>(mut self, arg: T) -> Builder {
        self.options.clang_args.push(arg.into());
        self
    }

    /// Make the generated bindings link the given shared library.
    pub fn link<T: Into<String>>(mut self, library: T) -> Builder {
        self.options.links.push((library.into(), LinkType::Default));
        self
    }

    /// Make the generated bindings link the given static library.
    pub fn link_static<T: Into<String>>(mut self, library: T) -> Builder {
        self.options.links.push((library.into(), LinkType::Static));
        self
    }

    /// Make the generated bindings link the given framework.
    pub fn link_framework<T: Into<String>>(mut self, library: T) -> Builder {
        self.options.links.push((library.into(), LinkType::Framework));
        self
    }

    /// Emit bindings for builtin definitions (for example `__builtin_va_list`)
    /// in the generated Rust.
    pub fn emit_builtins(mut self) -> Builder {
        self.options.builtins = true;
        self
    }

    /// Avoid generating any unstable Rust in the generated bindings.
    pub fn no_unstable_rust(mut self) -> Builder {
        self.options.unstable_rust = false;
        self
    }

    /// Generate the Rust bindings using the options built up thus far.
    pub fn generate(self) -> Result<Bindings, ()> {
        Bindings::generate(self.options, None)
    }
}

/// Configuration options for generated bindings.
///
/// Deprecated: use a `Builder` instead.
#[derive(Debug)]
#[deprecated]
pub struct BindgenOptions {
    /// The set of types that have been blacklisted and should not appear
    /// anywhere in the generated code.
    pub hidden_types: HashSet<String>,

    /// The set of types that should be treated as opaque structures in the
    /// generated code.
    pub opaque_types: HashSet<String>,

    /// The set of types that we should have bindings for in the generated
    /// code.
    ///
    /// This includes all types transitively reachable from any type in this
    /// set. One might think of whitelisted types/vars/functions as GC roots,
    /// and the generated Rust code as including everything that gets marked.
    pub whitelisted_types: RegexSet,

    /// Whitelisted functions. See docs for `whitelisted_types` for more.
    pub whitelisted_functions: RegexSet,

    /// Whitelisted variables. See docs for `whitelisted_types` for more.
    pub whitelisted_vars: RegexSet,

    /// Whether we should generate builtins or not.
    pub builtins: bool,

    /// The set of libraries we should link in the generated Rust code.
    pub links: Vec<(String, LinkType)>,

    /// True if we should dump the Clang AST for debugging purposes.
    pub emit_ast: bool,

    /// True if we should ignore functions and only generate bindings for
    /// structures, types, and methods.
    pub ignore_functions: bool,

    /// True if we should avoid generating bindings for methods, and instead
    /// just generate code for structures and types.
    pub ignore_methods: bool,

    /// True if we should emulate C++ namespaces with Rust modules in the
    /// generated bindings.
    pub enable_cxx_namespaces: bool,

    /// True if we shold derive Debug trait implementations for C/C++ structures
    /// and types.
    pub derive_debug: bool,

    /// True if we can use unstable Rust code in the bindings, false if we
    /// cannot.
    pub unstable_rust: bool,

    /// True if we should generate constant names that are **directly** under
    /// namespaces.
    pub namespaced_constants: bool,

    /// True if we should use MSVC name mangling rules.
    pub msvc_mangling: bool,

    /// The set of raw lines to prepend to the generated Rust code.
    pub raw_lines: Vec<String>,

    /// The set of arguments to pass straight through to Clang.
    pub clang_args: Vec<String>,
}

impl Default for BindgenOptions {
    fn default() -> BindgenOptions {
        BindgenOptions {
            hidden_types: Default::default(),
            opaque_types: Default::default(),
            whitelisted_types: Default::default(),
            whitelisted_functions: Default::default(),
            whitelisted_vars: Default::default(),
            builtins: false,
            links: vec![],
            emit_ast: false,
            ignore_functions: false,
            ignore_methods: false,
            derive_debug: true,
            enable_cxx_namespaces: false,
            unstable_rust: true,
            namespaced_constants: true,
            msvc_mangling: false,
            raw_lines: vec![],
            clang_args: vec![],
        }
    }
}

/// The linking type to use with a given library.
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
pub enum LinkType {
    /// Use shared library linking. This is the default.
    Default,
    /// Use static linking.
    Static,
    /// The library is an OSX framework.
    Framework
}

/// Generated Rust bindings.
#[derive(Debug, Clone)]
pub struct Bindings {
    module: ast::Mod,
    raw_lines: Vec<String>,
}

impl Bindings {
    /// Generate bindings for the given options.
    ///
    /// Deprecated - use a `Builder` instead
    #[deprecated]
    pub fn generate(options: BindgenOptions, span: Option<Span>) -> Result<Bindings, ()> {
        let span = span.unwrap_or(DUMMY_SP);

        let mut context = BindgenContext::new(options);
        parse(&mut context);

        let module = ast::Mod {
            inner: span,
            items: codegen::codegen(&mut context),
        };

        Ok(Bindings {
            module: module,
            raw_lines: context.options().raw_lines.clone(),
        })
    }

    /// Convert these bindings into a Rust AST.
    pub fn into_ast(self) -> Vec<P<ast::Item>> {
        self.module.items
    }

    /// Convert these bindings into source text (with raw lines prepended).
    pub fn to_string(&self) -> String {
        let mut mod_str = vec![];
        {
            let ref_writer = Box::new(mod_str.by_ref()) as Box<Write>;
            self.write(ref_writer).expect("Could not write bindings to string");
        }
        String::from_utf8(mod_str).unwrap()
    }

    /// Write these bindings as source text to a file.
    pub fn write_to_file<P: AsRef<Path>>(&self, path: P) -> io::Result<()> {
        let file = try!(OpenOptions::new().write(true).truncate(true).create(true).open(path));
        self.write(Box::new(file))
    }

    /// Write these bindings as source text to the given `Write`able.
    // https://github.com/Manishearth/rust-clippy/issues/740
    #[cfg_attr(feature = "clippy", allow(needless_lifetimes))]
    pub fn write<'a>(&self, mut writer: Box<Write + 'a>) -> io::Result<()> {
        try!(writer.write("/* automatically generated by rust-bindgen */\n\n".as_bytes()));

        for line in self.raw_lines.iter() {
            try!(writer.write(line.as_bytes()));
            try!(writer.write("\n".as_bytes()));
        }
        if !self.raw_lines.is_empty() {
            try!(writer.write("\n".as_bytes()));
        }

        let mut ps = pprust::rust_printer(writer);
        try!(ps.print_mod(&self.module, &[]));
        try!(ps.print_remaining_comments());
        try!(eof(&mut ps.s));
        ps.s.out.flush()
    }
}

/// Determines whether the given cursor is in any of the files matched by the
/// options.
fn filter_builtins(ctx: &BindgenContext, cursor: &clang::Cursor) -> bool {
    let (file, _, _, _) = cursor.location().location();

    match file.name() {
        None => ctx.options().builtins,
        Some(..) => true,
    }
}

/// Parse one `Item` from the Clang cursor.
pub fn parse_one(ctx: &mut BindgenContext,
                 cursor: clang::Cursor,
                 parent: Option<ItemId>,
                 children: &mut Vec<ItemId>) -> clangll::Enum_CXVisitorResult {
    if !filter_builtins(ctx, &cursor) {
        return CXChildVisit_Continue
    }

    use clangll::CXChildVisit_Continue;
    match Item::parse(cursor, parent, ctx) {
        Ok(id) => children.push(id),
        Err(ParseError::Continue) => {},
        Err(ParseError::Recurse) => {
            cursor.visit(|child, _| parse_one(ctx, *child, parent, children));
        }
    }
    CXChildVisit_Continue
}

/// Parse the Clang AST into our `Item` internal representation.
fn parse(context: &mut BindgenContext) {
    use clang::Diagnostic;
    use clangll::*;

    for d in context.translation_unit().diags().iter() {
        let msg = d.format(Diagnostic::default_opts());
        let is_err = d.severity() >= CXDiagnostic_Error;
        println!("{}, err: {}", msg, is_err);
    }

    let cursor = context.translation_unit().cursor();
    if context.options().emit_ast {
        cursor.visit(|cur, _| clang::ast_dump(cur, 0));
    }

    let root = context.root_module();
    context.with_module(root, |context, children| {
        cursor.visit(|cursor, _| parse_one(context, *cursor, None, children))
    });

    assert!(context.current_module() == context.root_module(),
            "How did this happen?");
}
<commit_msg>Add TODO for not ignoring LinkType<commit_after>//! Generate Rust bindings for C and C++ libraries.
//!
//! Provide a C/C++ header file, receive Rust FFI code to call into C/C++
//! functions and use types defined in the header.
//!
//! See the [Builder](./struct.Builder.html) struct for usage.

#![crate_name = "bindgen"]
#![crate_type = "dylib"]

#![cfg_attr(feature = "clippy", feature(plugin))]
#![cfg_attr(feature = "clippy", plugin(clippy))]

#![deny(missing_docs)]

// We internally use the deprecated BindgenOptions all over the place. Once we
// remove its `pub` declaration, we can un-deprecate it and remove this pragma.
#![allow(deprecated)]

// To avoid rather annoying warnings when matching with CXCursor_xxx as a
// constant.
#![allow(non_upper_case_globals)]

extern crate syntex_syntax as syntax;
extern crate aster;
extern crate quasi;
extern crate clang_sys;
extern crate libc;
extern crate regex;
#[macro_use]
extern crate log;
#[macro_use]
extern crate lazy_static;

mod clangll;
mod clang;
mod ir;
mod parse;
mod regex_set;
mod codegen {
    include!(concat!(env!("OUT_DIR"), "/codegen.rs"));
}

use std::borrow::Borrow;
use std::io::{self, Write};
use std::fs::OpenOptions;
use std::path::Path;
use std::collections::HashSet;

use syntax::ast;
use syntax::codemap::{DUMMY_SP, Span};
use syntax::print::pprust;
use syntax::print::pp::eof;
use syntax::ptr::P;

use ir::context::BindgenContext;
use ir::item::{Item, ItemId};
use parse::{ClangItemParser, ParseError};
use regex_set::RegexSet;

/// Configure and generate Rust bindings for a C/C++ header.
///
/// This is the main entry point to the library.
///
/// ```ignore
/// use bindgen::builder;
///
/// // Configure and generate bindings.
/// let bindings = try!(builder().header("path/to/input/header")
///                              .whitelisted_type("SomeCoolClass")
///                              .whitelisted_function("do_some_cool_thing")
///                              .generate());
///
/// // Write the generated bindings to an output file.
/// try!(bindings.write_to_file("path/to/output.rs"));
/// ```
#[derive(Debug,Default)]
pub struct Builder {
    options: BindgenOptions,
}

/// Construct a new [`Builder`](./struct.Builder.html).
pub fn builder() -> Builder {
    Default::default()
}

impl Builder {
    /// Set the input C/C++ header.
    pub fn header<T: Into<String>>(self, header: T) -> Builder {
        self.clang_arg(header)
    }

    /// Hide the given type from the generated bindings.
    pub fn hide_type<T: Into<String>>(mut self, arg: T) -> Builder {
        self.options.hidden_types.insert(arg.into());
        self
    }

    /// Treat the given type as opaque in the generated bindings.
    pub fn opaque_type<T: Into<String>>(mut self, arg: T) -> Builder {
        self.options.opaque_types.insert(arg.into());
        self
    }

    /// Whitelist the given type so that it (and all types that it transitively
    /// refers to) appears in the generated bindings.
    pub fn whitelisted_type<T: Borrow<str>>(mut self, arg: T) -> Builder {
        self.options.whitelisted_types.insert(&arg);
        self
    }

    /// Whitelist the given function so that it (and all types that it
    /// transitively refers to) appears in the generated bindings.
    pub fn whitelisted_function<T: Borrow<str>>(mut self, arg: T) -> Builder {
        self.options.whitelisted_functions.insert(&arg);
        self
    }

    /// Whitelist the given variable so that it (and all types that it
    /// transitively refers to) appears in the generated bindings.
    pub fn whitelisted_var<T: Borrow<str>>(mut self, arg: T) -> Builder {
        self.options.whitelisted_vars.insert(&arg);
        self
    }

    /// Add a string to prepend to the generated bindings. The string is passed
    /// through without any modification.
    pub fn raw_line<T: Into<String>>(mut self, arg: T) -> Builder {
        self.options.raw_lines.push(arg.into());
        self
    }

    /// Add an argument to be passed straight through to clang.
    pub fn clang_arg<T: Into<String>>(mut self, arg: T) -> Builder {
        self.options.clang_args.push(arg.into());
        self
    }

    /// Make the generated bindings link the given shared library.
    pub fn link<T: Into<String>>(mut self, library: T) -> Builder {
        self.options.links.push((library.into(), LinkType::Default));
        self
    }

    /// Make the generated bindings link the given static library.
    pub fn link_static<T: Into<String>>(mut self, library: T) -> Builder {
        self.options.links.push((library.into(), LinkType::Static));
        self
    }

    /// Make the generated bindings link the given framework.
    pub fn link_framework<T: Into<String>>(mut self, library: T) -> Builder {
        self.options.links.push((library.into(), LinkType::Framework));
        self
    }

    /// Emit bindings for builtin definitions (for example `__builtin_va_list`)
    /// in the generated Rust.
    pub fn emit_builtins(mut self) -> Builder {
        self.options.builtins = true;
        self
    }

    /// Avoid generating any unstable Rust in the generated bindings.
    pub fn no_unstable_rust(mut self) -> Builder {
        self.options.unstable_rust = false;
        self
    }

    /// Generate the Rust bindings using the options built up thus far.
    pub fn generate(self) -> Result<Bindings, ()> {
        Bindings::generate(self.options, None)
    }
}

/// Configuration options for generated bindings.
///
/// Deprecated: use a `Builder` instead.
#[derive(Debug)]
#[deprecated]
pub struct BindgenOptions {
    /// The set of types that have been blacklisted and should not appear
    /// anywhere in the generated code.
    pub hidden_types: HashSet<String>,

    /// The set of types that should be treated as opaque structures in the
    /// generated code.
    pub opaque_types: HashSet<String>,

    /// The set of types that we should have bindings for in the generated
    /// code.
    ///
    /// This includes all types transitively reachable from any type in this
    /// set. One might think of whitelisted types/vars/functions as GC roots,
    /// and the generated Rust code as including everything that gets marked.
    pub whitelisted_types: RegexSet,

    /// Whitelisted functions. See docs for `whitelisted_types` for more.
    pub whitelisted_functions: RegexSet,

    /// Whitelisted variables. See docs for `whitelisted_types` for more.
    pub whitelisted_vars: RegexSet,

    /// Whether we should generate builtins or not.
    pub builtins: bool,

    /// The set of libraries we should link in the generated Rust code.
    pub links: Vec<(String, LinkType)>,

    /// True if we should dump the Clang AST for debugging purposes.
    pub emit_ast: bool,

    /// True if we should ignore functions and only generate bindings for
    /// structures, types, and methods.
    pub ignore_functions: bool,

    /// True if we should avoid generating bindings for methods, and instead
    /// just generate code for structures and types.
    pub ignore_methods: bool,

    /// True if we should emulate C++ namespaces with Rust modules in the
    /// generated bindings.
    pub enable_cxx_namespaces: bool,

    /// True if we shold derive Debug trait implementations for C/C++ structures
    /// and types.
    pub derive_debug: bool,

    /// True if we can use unstable Rust code in the bindings, false if we
    /// cannot.
    pub unstable_rust: bool,

    /// True if we should generate constant names that are **directly** under
    /// namespaces.
    pub namespaced_constants: bool,

    /// True if we should use MSVC name mangling rules.
    pub msvc_mangling: bool,

    /// The set of raw lines to prepend to the generated Rust code.
    pub raw_lines: Vec<String>,

    /// The set of arguments to pass straight through to Clang.
    pub clang_args: Vec<String>,
}

impl Default for BindgenOptions {
    fn default() -> BindgenOptions {
        BindgenOptions {
            hidden_types: Default::default(),
            opaque_types: Default::default(),
            whitelisted_types: Default::default(),
            whitelisted_functions: Default::default(),
            whitelisted_vars: Default::default(),
            builtins: false,
            links: vec![],
            emit_ast: false,
            ignore_functions: false,
            ignore_methods: false,
            derive_debug: true,
            enable_cxx_namespaces: false,
            unstable_rust: true,
            namespaced_constants: true,
            msvc_mangling: false,
            raw_lines: vec![],
            clang_args: vec![],
        }
    }
}

/// The linking type to use with a given library.
///
/// TODO: #104: This is ignored at the moment, but shouldn't be.
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
pub enum LinkType {
    /// Use shared library linking. This is the default.
    Default,
    /// Use static linking.
    Static,
    /// The library is an OSX framework.
    Framework
}

/// Generated Rust bindings.
#[derive(Debug, Clone)]
pub struct Bindings {
    module: ast::Mod,
    raw_lines: Vec<String>,
}

impl Bindings {
    /// Generate bindings for the given options.
    ///
    /// Deprecated - use a `Builder` instead
    #[deprecated]
    pub fn generate(options: BindgenOptions, span: Option<Span>) -> Result<Bindings, ()> {
        let span = span.unwrap_or(DUMMY_SP);

        let mut context = BindgenContext::new(options);
        parse(&mut context);

        let module = ast::Mod {
            inner: span,
            items: codegen::codegen(&mut context),
        };

        Ok(Bindings {
            module: module,
            raw_lines: context.options().raw_lines.clone(),
        })
    }

    /// Convert these bindings into a Rust AST.
    pub fn into_ast(self) -> Vec<P<ast::Item>> {
        self.module.items
    }

    /// Convert these bindings into source text (with raw lines prepended).
    pub fn to_string(&self) -> String {
        let mut mod_str = vec![];
        {
            let ref_writer = Box::new(mod_str.by_ref()) as Box<Write>;
            self.write(ref_writer).expect("Could not write bindings to string");
        }
        String::from_utf8(mod_str).unwrap()
    }

    /// Write these bindings as source text to a file.
    pub fn write_to_file<P: AsRef<Path>>(&self, path: P) -> io::Result<()> {
        let file = try!(OpenOptions::new().write(true).truncate(true).create(true).open(path));
        self.write(Box::new(file))
    }

    /// Write these bindings as source text to the given `Write`able.
    // https://github.com/Manishearth/rust-clippy/issues/740
    #[cfg_attr(feature = "clippy", allow(needless_lifetimes))]
    pub fn write<'a>(&self, mut writer: Box<Write + 'a>) -> io::Result<()> {
        try!(writer.write("/* automatically generated by rust-bindgen */\n\n".as_bytes()));

        for line in self.raw_lines.iter() {
            try!(writer.write(line.as_bytes()));
            try!(writer.write("\n".as_bytes()));
        }
        if !self.raw_lines.is_empty() {
            try!(writer.write("\n".as_bytes()));
        }

        let mut ps = pprust::rust_printer(writer);
        try!(ps.print_mod(&self.module, &[]));
        try!(ps.print_remaining_comments());
        try!(eof(&mut ps.s));
        ps.s.out.flush()
    }
}

/// Determines whether the given cursor is in any of the files matched by the
/// options.
fn filter_builtins(ctx: &BindgenContext, cursor: &clang::Cursor) -> bool {
    let (file, _, _, _) = cursor.location().location();

    match file.name() {
        None => ctx.options().builtins,
        Some(..) => true,
    }
}

/// Parse one `Item` from the Clang cursor.
pub fn parse_one(ctx: &mut BindgenContext,
                 cursor: clang::Cursor,
                 parent: Option<ItemId>,
                 children: &mut Vec<ItemId>) -> clangll::Enum_CXVisitorResult {
    if !filter_builtins(ctx, &cursor) {
        return CXChildVisit_Continue
    }

    use clangll::CXChildVisit_Continue;
    match Item::parse(cursor, parent, ctx) {
        Ok(id) => children.push(id),
        Err(ParseError::Continue) => {},
        Err(ParseError::Recurse) => {
            cursor.visit(|child, _| parse_one(ctx, *child, parent, children));
        }
    }
    CXChildVisit_Continue
}

/// Parse the Clang AST into our `Item` internal representation.
fn parse(context: &mut BindgenContext) {
    use clang::Diagnostic;
    use clangll::*;

    for d in context.translation_unit().diags().iter() {
        let msg = d.format(Diagnostic::default_opts());
        let is_err = d.severity() >= CXDiagnostic_Error;
        println!("{}, err: {}", msg, is_err);
    }

    let cursor = context.translation_unit().cursor();
    if context.options().emit_ast {
        cursor.visit(|cur, _| clang::ast_dump(cur, 0));
    }

    let root = context.root_module();
    context.with_module(root, |context, children| {
        cursor.visit(|cursor, _| parse_one(context, *cursor, None, children))
    });

    assert!(context.current_module() == context.root_module(),
            "How did this happen?");
}
<|endoftext|>


<commit_before>
#![deny(missing_copy_implementations)]
#![feature(core, str_char)]

#[macro_use] extern crate bitflags;
extern crate clock_ticks;
extern crate graphics;
#[macro_use] extern crate piston;
extern crate rand;
extern crate "rustc-serialize" as rustc_serialize;
extern crate vecmath;

pub use background::Background;
pub use button::Button;
pub use drop_down_list::DropDownList;
pub use envelope_editor::EnvelopeEditor;
pub use envelope_editor::EnvelopePoint;
pub use label::Label;
pub use number_dialer::NumberDialer;
pub use slider::Slider;
pub use text_box::TextBox;
pub use toggle::Toggle;
pub use widget_matrix::WidgetMatrix;
pub use xy_pad::XYPad;

pub use callback::{ Callable, Callback };
pub use color::{Color, Colorable};
pub use dimensions::Dimensions;
pub use draw::Drawable;
pub use frame::{Framing, Frameable, FrameColor, FrameWidth};
pub use label::{Labelable, LabelText, LabelColor, LabelFontSize};
pub use point::Point;
pub use position::{Positionable, Position};
pub use shape::{Shapeable, Size};
pub use theme::Theme;
pub use ui_context::UiContext;
pub use widget::Widget;

#[macro_use]
pub mod macros;

pub mod background;
pub mod button;
pub mod callback;
pub mod color;
pub mod dimensions;
pub mod draw;
pub mod drop_down_list;
pub mod envelope_editor;
pub mod frame;
pub mod label;
pub mod mouse;
pub mod number_dialer;
pub mod point;
pub mod position;
pub mod rectangle;
pub mod shape;
pub mod slider;
pub mod text_box;
pub mod theme;
pub mod toggle;
pub mod ui_context;
pub mod utils;
pub mod widget;
pub mod widget_matrix;
pub mod xy_pad;
<commit_msg>remove quotes from use statements<commit_after>
#![deny(missing_copy_implementations)]
#![feature(core, str_char)]

#[macro_use] extern crate bitflags;
extern crate clock_ticks;
extern crate graphics;
#[macro_use] extern crate piston;
extern crate rand;
extern crate rustc_serialize;
extern crate vecmath;

pub use background::Background;
pub use button::Button;
pub use drop_down_list::DropDownList;
pub use envelope_editor::EnvelopeEditor;
pub use envelope_editor::EnvelopePoint;
pub use label::Label;
pub use number_dialer::NumberDialer;
pub use slider::Slider;
pub use text_box::TextBox;
pub use toggle::Toggle;
pub use widget_matrix::WidgetMatrix;
pub use xy_pad::XYPad;

pub use callback::{ Callable, Callback };
pub use color::{Color, Colorable};
pub use dimensions::Dimensions;
pub use draw::Drawable;
pub use frame::{Framing, Frameable, FrameColor, FrameWidth};
pub use label::{Labelable, LabelText, LabelColor, LabelFontSize};
pub use point::Point;
pub use position::{Positionable, Position};
pub use shape::{Shapeable, Size};
pub use theme::Theme;
pub use ui_context::UiContext;
pub use widget::Widget;

#[macro_use]
pub mod macros;

pub mod background;
pub mod button;
pub mod callback;
pub mod color;
pub mod dimensions;
pub mod draw;
pub mod drop_down_list;
pub mod envelope_editor;
pub mod frame;
pub mod label;
pub mod mouse;
pub mod number_dialer;
pub mod point;
pub mod position;
pub mod rectangle;
pub mod shape;
pub mod slider;
pub mod text_box;
pub mod theme;
pub mod toggle;
pub mod ui_context;
pub mod utils;
pub mod widget;
pub mod widget_matrix;
pub mod xy_pad;
<|endoftext|>


<commit_before>#![feature(proc_macro)]

#[macro_use]
extern crate log;
extern crate hayaku_http;
#[macro_use(quick_error)]
extern crate quick_error;
extern crate regex;
#[macro_use]
extern crate serde_derive;
extern crate serde_json;

mod error;
mod trie;

use trie::TrieNode;

use hayaku_http::{Handler, Method, Request, RequestHandler, Response, Status};

use std::collections::HashMap;

pub use error::Error;

pub fn get_path_params(req: &Request) -> HashMap<String, String> {
    serde_json::from_slice(&*req.user_data.borrow()).unwrap()
}

type Tree<T> = HashMap<Method, TrieNode<RequestHandler<T>>>;

#[derive(Clone)]
pub struct Router<T: Clone> {
    trees: Tree<T>,
    /// Enables automatic redirection if the current route can't be matched but
    /// a handler for the path with (without) the trailing slash exists.
    /// For example if /foo/ is requested but a route only exists for /foo, the
    /// client is redirected to /foo with http status code 301 for GET requests
    /// and 307 for all other request methods.
    pub redirect_trailing_slash: bool,
    /// If enabled, the router tries to fix the current request path, if no
    /// handle is registered for it.
    /// First superfluous path elements like ../ or // are removed.
    /// Afterwards the router does a case-insensitive lookup of the cleaned path.
    /// If a handle can be found for this route, the router makes a redirection
    /// to the corrected path with status code 301 for GET requests and 307 for
    /// all other request methods.
    /// For example /FOO and /..//Foo could be redirected to /foo.
    /// `redirect_trailing_slash` is independent of this option.
    pub redirect_fixed_path: bool,
    /// If enabled, the router checks if another method is allowed for the
    /// current route, if the current request can not be routed.
    /// If this is the case, the request is answered with `Method Not Allowed`
    /// and HTTP status code 405.
    /// If no other Method is allowed, the request is delegated to the NotFound
    /// handler.
    pub handle_method_not_allowed: bool,
    /// If enabled, the router automatically replies to OPTIONS requests.
    /// Custom OPTIONS handlers take priority over automatic replies.
    pub handle_options: bool,
    /// Configurable handler which is called when no matching route is
    /// found. If it is `None`, the default 404 handler is used.
    not_found: Option<RequestHandler<T>>,
}

impl<T: Clone> Router<T> {
    pub fn new() -> Self {
        Router {
            trees: HashMap::new(),
            redirect_trailing_slash: true,
            redirect_fixed_path: true,
            handle_method_not_allowed: true,
            handle_options: true,
            not_found: None,
        }
    }

    pub fn set_not_found_handler(&mut self, handler: RequestHandler<T>) {
        self.not_found = Some(handler);
    }

    /// `get` is a shortcut for `Self::handle(Method::Get, path, handle)`.
    pub fn get<S: Into<String>>(&mut self,
                                path: S,
                                handle: RequestHandler<T>)
                                -> Result<(), Error> {
        self.handle(Method::Get, path, handle)
    }

    /// `head` is a shortcut for `Self::handle(Method::Head, path, handle)`.
    pub fn head<S: Into<String>>(&mut self,
                                 path: S,
                                 handle: RequestHandler<T>)
                                 -> Result<(), Error> {
        self.handle(Method::Head, path, handle)
    }

    /// `options` is a shortcut for `Self::handle(Method::Options, path, handle)`.
    pub fn options<S: Into<String>>(&mut self,
                                    path: S,
                                    handle: RequestHandler<T>)
                                    -> Result<(), Error> {
        self.handle(Method::Options, path, handle)
    }

    /// `post` is a shortcut for `Self::handle(Method::Post, path, handle)`.
    pub fn post<S: Into<String>>(&mut self,
                                 path: S,
                                 handle: RequestHandler<T>)
                                 -> Result<(), Error> {
        self.handle(Method::Post, path, handle)
    }

    /// `put` is a shortcut for `Self::handle(Method::Put, path, handle)`.
    pub fn put<S: Into<String>>(&mut self,
                                path: S,
                                handle: RequestHandler<T>)
                                -> Result<(), Error> {
        self.handle(Method::Put, path, handle)
    }

    /// `patch` is a shortcut for `Self::handle(Method::Patch, path, handle)`.
    pub fn patch<S: Into<String>>(&mut self,
                                  path: S,
                                  handle: RequestHandler<T>)
                                  -> Result<(), Error> {
        self.handle(Method::Patch, path, handle)
    }

    /// `delete` is a shortcut for `Self::handle(Method::Delete, path, handle)`.
    pub fn delete<S: Into<String>>(&mut self,
                                   path: S,
                                   handle: RequestHandler<T>)
                                   -> Result<(), Error> {
        self.handle(Method::Delete, path, handle)
    }

    /// Registers a new request handle with the given path and method.
    ///
    /// For GET, POST, PUT, PATCH, and DELETE requests the respective
    /// shortcut functions can be used.
    ///
    /// This function is intended for bulk loading and to allow the usage
    /// of less frequently used, non-standardized or custom methods
    /// (e.g. for internal communication with a proxy).
    pub fn handle<S: Into<String>>(&mut self,
                                   method: Method,
                                   path: S,
                                   handle: RequestHandler<T>)
                                   -> Result<(), Error> {
        let path = path.into();
        if !path.starts_with('/') {
            return Err(Error::StartWithSlash(path.to_string()));
        }

        if self.trees.get(&method).is_none() {
            let root = TrieNode::new();
            self.trees.insert(method.clone(), root);
        }

        // TODO(nokaa): we should probably not unwrap here.
        // It may be possible for the retrieval to fail, even
        // though we check just before this.
        let mut root = self.trees.get_mut(&method).unwrap();
        root.insert(path, handle);

        Ok(())
    }
}

impl<T: Clone> Handler<T> for Router<T> {
    // Handler makes the router implement the fasthttp.ListenAndServe interface.
    fn handler(&self, req: &Request, res: &mut Response, ctx: &T) {
        let path = req.path();
        let path = {
            let data_loc = path.find('?').unwrap_or(path.len());
            &path[..data_loc]
        };
        debug!("path: {}", path);
        let method = req.method().clone();
        debug!("method: {:?}", method);

        if let Some(root) = self.trees.get(&method) {
            debug!("tree for method {:?} found", method);
            match root.get(path) {
                Some((val, map)) => {
                    let serialized = serde_json::to_vec(&map).unwrap();
                    *req.user_data.borrow_mut() = serialized;
                    val.unwrap()(req, res, ctx);
                }
                None => {
                    if self.not_found.is_none() {
                        // Default handler
                        res.status(Status::NotFound);
                        let msg = String::from("404, path \"") + path + "\" not found :(";
                        res.body(&msg.into_bytes());
                    } else {
                        // We have already checked that self.not_found is not
                        // `None`, so unwrapping should be okay.
                        let handle = self.not_found.clone().unwrap();
                        handle(req, res, ctx);
                    }
                }
            }
            // TODO(nokaa): We want to send a different error than 404
            // for this case. In this case we have an incorrect method being
            // used.
        } else if self.not_found.is_none() {
            debug!("tree for method {:?} not found", method);
            // Default handler
            res.status(Status::NotFound);
            let msg = String::from("404, path \"") + path + "\" not found :(";
            res.body(&msg.into_bytes());
        } else {
            debug!("tree for method {:?} not found", method);
            // We have already checked that self.not_found is not
            // `None`, so unwrapping should be okay.
            let handle = self.not_found.clone().unwrap();
            handle(req, res, ctx);
        }
    }
}
<commit_msg>Implement redirect_with_trailing_slash<commit_after>#![feature(proc_macro)]

#[macro_use]
extern crate log;
extern crate hayaku_http;
#[macro_use(quick_error)]
extern crate quick_error;
extern crate regex;
#[macro_use]
extern crate serde_derive;
extern crate serde_json;

mod error;
mod trie;

use trie::TrieNode;

use hayaku_http::{Handler, Method, Request, RequestHandler, Response, Status};

use std::collections::HashMap;

pub use error::Error;

pub fn get_path_params(req: &Request) -> HashMap<String, String> {
    serde_json::from_slice(&*req.user_data.borrow()).unwrap()
}

type Tree<T> = HashMap<Method, TrieNode<RequestHandler<T>>>;

#[derive(Clone)]
pub struct Router<T: Clone> {
    trees: Tree<T>,
    /// Enables automatic redirection if the current route can't be matched but
    /// a handler for the path with (without) the trailing slash exists.
    /// For example if /foo/ is requested but a route only exists for /foo, the
    /// client is redirected to /foo with http status code 301 for GET requests
    /// and 307 for all other request methods.
    pub redirect_trailing_slash: bool,
    /// If enabled, the router tries to fix the current request path, if no
    /// handle is registered for it.
    /// First superfluous path elements like ../ or // are removed.
    /// Afterwards the router does a case-insensitive lookup of the cleaned path.
    /// If a handle can be found for this route, the router makes a redirection
    /// to the corrected path with status code 301 for GET requests and 307 for
    /// all other request methods.
    /// For example /FOO and /..//Foo could be redirected to /foo.
    /// `redirect_trailing_slash` is independent of this option.
    pub redirect_fixed_path: bool,
    /// If enabled, the router checks if another method is allowed for the
    /// current route, if the current request can not be routed.
    /// If this is the case, the request is answered with `Method Not Allowed`
    /// and HTTP status code 405.
    /// If no other Method is allowed, the request is delegated to the NotFound
    /// handler.
    pub handle_method_not_allowed: bool,
    /// If enabled, the router automatically replies to OPTIONS requests.
    /// Custom OPTIONS handlers take priority over automatic replies.
    pub handle_options: bool,
    /// Configurable handler which is called when no matching route is
    /// found. If it is `None`, the default 404 handler is used.
    not_found: Option<RequestHandler<T>>,
}

impl<T: Clone> Router<T> {
    pub fn new() -> Self {
        Router {
            trees: HashMap::new(),
            redirect_trailing_slash: true,
            redirect_fixed_path: true,
            handle_method_not_allowed: true,
            handle_options: true,
            not_found: None,
        }
    }

    pub fn set_not_found_handler(&mut self, handler: RequestHandler<T>) {
        self.not_found = Some(handler);
    }

    /// `get` is a shortcut for `Self::handle(Method::Get, path, handle)`.
    pub fn get<S: Into<String>>(&mut self,
                                path: S,
                                handle: RequestHandler<T>)
                                -> Result<(), Error> {
        self.handle(Method::Get, path, handle)
    }

    /// `head` is a shortcut for `Self::handle(Method::Head, path, handle)`.
    pub fn head<S: Into<String>>(&mut self,
                                 path: S,
                                 handle: RequestHandler<T>)
                                 -> Result<(), Error> {
        self.handle(Method::Head, path, handle)
    }

    /// `options` is a shortcut for `Self::handle(Method::Options, path, handle)`.
    pub fn options<S: Into<String>>(&mut self,
                                    path: S,
                                    handle: RequestHandler<T>)
                                    -> Result<(), Error> {
        self.handle(Method::Options, path, handle)
    }

    /// `post` is a shortcut for `Self::handle(Method::Post, path, handle)`.
    pub fn post<S: Into<String>>(&mut self,
                                 path: S,
                                 handle: RequestHandler<T>)
                                 -> Result<(), Error> {
        self.handle(Method::Post, path, handle)
    }

    /// `put` is a shortcut for `Self::handle(Method::Put, path, handle)`.
    pub fn put<S: Into<String>>(&mut self,
                                path: S,
                                handle: RequestHandler<T>)
                                -> Result<(), Error> {
        self.handle(Method::Put, path, handle)
    }

    /// `patch` is a shortcut for `Self::handle(Method::Patch, path, handle)`.
    pub fn patch<S: Into<String>>(&mut self,
                                  path: S,
                                  handle: RequestHandler<T>)
                                  -> Result<(), Error> {
        self.handle(Method::Patch, path, handle)
    }

    /// `delete` is a shortcut for `Self::handle(Method::Delete, path, handle)`.
    pub fn delete<S: Into<String>>(&mut self,
                                   path: S,
                                   handle: RequestHandler<T>)
                                   -> Result<(), Error> {
        self.handle(Method::Delete, path, handle)
    }

    /// Registers a new request handle with the given path and method.
    ///
    /// For GET, POST, PUT, PATCH, and DELETE requests the respective
    /// shortcut functions can be used.
    ///
    /// This function is intended for bulk loading and to allow the usage
    /// of less frequently used, non-standardized or custom methods
    /// (e.g. for internal communication with a proxy).
    pub fn handle<S: Into<String>>(&mut self,
                                   method: Method,
                                   path: S,
                                   handle: RequestHandler<T>)
                                   -> Result<(), Error> {
        let path = path.into();
        if !path.starts_with('/') {
            return Err(Error::StartWithSlash(path.to_string()));
        }

        if self.trees.get(&method).is_none() {
            let root = TrieNode::new();
            self.trees.insert(method.clone(), root);
        }

        // TODO(nokaa): we should probably not unwrap here.
        // It may be possible for the retrieval to fail, even
        // though we check just before this.
        let mut root = self.trees.get_mut(&method).unwrap();
        root.insert(path, handle);

        Ok(())
    }
}

impl<T: Clone> Handler<T> for Router<T> {
    // Handler makes the router implement the fasthttp.ListenAndServe interface.
    fn handler(&self, req: &Request, res: &mut Response, ctx: &T) {
        let path = req.path();
        let path = {
            let data_loc = path.find('?').unwrap_or(path.len());
            &path[..data_loc]
        };
        debug!("path: {}", path);
        let method = req.method().clone();
        debug!("method: {:?}", method);

        if let Some(root) = self.trees.get(&method) {
            debug!("tree for method {:?} found", method);

            // This inner function allows us to easily do searches with
            // multiple variations of the path, based on what router options
            // have been set.
            fn search<T: Clone>(router: &Router<T>,
                                req: &Request,
                                res: &mut Response,
                                ctx: &T,
                                root: &TrieNode<RequestHandler<T>>,
                                path: &str) {
                match root.get(path) {
                    Some((val, map)) => {
                        let serialized = serde_json::to_vec(&map).unwrap();
                        *req.user_data.borrow_mut() = serialized;
                        val.unwrap()(req, res, ctx);
                    }
                    None => {
                        if router.redirect_trailing_slash && path.ends_with('/') {
                            search(router, req, res, ctx, root, &path[..path.len() - 1])
                        } else if router.not_found.is_none() {
                            // Default handler
                            res.status(Status::NotFound);
                            let msg = String::from("404, path \"") + path + "\" not found :(";
                            res.body(&msg.into_bytes());
                        } else {
                            // We have already checked that self.not_found is not
                            // `None`, so unwrapping should be okay.
                            let handle = router.not_found.clone().unwrap();
                            handle(req, res, ctx);
                        }
                    }
                }
            };
            search(&self, req, res, ctx, root, path);

            // TODO(nokaa): We want to send a different error than 404
            // for this case. In this case we have an incorrect method being
            // used.
        } else if self.not_found.is_none() {
            debug!("tree for method {:?} not found", method);
            // Default handler
            res.status(Status::NotFound);
            let msg = String::from("404, path \"") + path + "\" not found :(";
            res.body(&msg.into_bytes());
        } else {
            debug!("tree for method {:?} not found", method);
            // We have already checked that self.not_found is not
            // `None`, so unwrapping should be okay.
            let handle = self.not_found.clone().unwrap();
            handle(req, res, ctx);
        }
    }
}
<|endoftext|>


<commit_before>#![crate_type = "lib"]
#![crate_name = "hyperhyper"]
#![feature(std_misc)]

extern crate mio;

use mio::*;
use mio::tcp::*;
use std::str::FromStr;
use std::net::SocketAddr;
use std::time::Duration;
use mio::buf::{ByteBuf, MutByteBuf, SliceBuf};
use std::net::Shutdown;
use std::collections::LinkedList;
// Define a handler to process the events
use std::{io, thread};

const SERVER: Token = Token(0);
const CLIENT: Token = Token(1);

struct Echo {
    non_block_client: NonBlock<TcpStream>,
    token: Option<Token>,
    mut_buf: Option<MutByteBuf>,

    buf: Option<ByteBuf>,
    interest: Interest
}

impl Echo {
    fn new(client: NonBlock<TcpStream>) -> Echo {
        Echo {
            non_block_client: client,
            mut_buf: Some(ByteBuf::mut_with_capacity(2048)),
            interest: Interest::hup(),
            buf: None,
            token: None,
        }
    }
}
impl Handler for Echo {
    type Timeout = usize;
    type Message = String;

    fn readable(&mut self, event_loop: &mut EventLoop<Echo>, token: Token, hint: ReadHint) {
        let mut buf = ByteBuf::mut_with_capacity(2048);
        match self.non_block_client.read(&mut buf) {
            Ok(None) => {
                println!("We just got readable, but were unable to read from the socket?");
            }
            Ok(Some(r)) => {
                println!("CONN : we read {} bytes!", r);
                self.interest.remove(Interest::readable());
                if (r > 0){
                    event_loop.reregister(&self.non_block_client, token, self.interest,
                                          PollOpt::edge() | PollOpt::oneshot());
                } else {
                    event_loop.shutdown();
                }
            }
            Err(e) => {
                println!("not implemented; client err={:?}", e);
                self.interest.remove(Interest::readable());
            }
        }
    }

    fn writable(&mut self, event_loop: &mut EventLoop<Echo>, token: Token) {
        let mut buf = ByteBuf::from_slice("GET /\n".as_bytes());

        match self.non_block_client.write(&mut buf) {
            Ok(None) => {
                println!("client flushing buf; WOULDBLOCK");

                self.buf = Some(buf);
                self.interest.insert(Interest::writable());
            }
            Ok(Some(r)) => {
                println!("CONN : we wrote {} bytes!", r);

                self.mut_buf = Some(buf.flip());

                self.interest.insert(Interest::readable());
                self.interest.remove(Interest::writable());
            }
            Err(e) => println!("not implemented; client err={:?}", e),
        }
        event_loop.reregister(&self.non_block_client, token, self.interest,
                              PollOpt::edge() | PollOpt::oneshot());
    }
    fn notify(&mut self, event_loop: &mut EventLoop<Echo>, msg: String) {
        println!("test3");
    }
}

pub fn google() -> SocketAddr {
    let s = format!("216.58.192.4:{}", 80);
    FromStr::from_str(&s).unwrap()
}

fn get_web_page(hostname: String, port: u32, get_resource: String) {
    let mut event_loop = EventLoop::new().unwrap();
    // == Create & setup client socket

    let url = String::new();

    // == Run test
    println!("Connecting");
    let (mut sock, _) = tcp::v4().unwrap().connect(&google()).unwrap();
    event_loop.register_opt(&sock, CLIENT, Interest::writable(),
                            PollOpt::edge() | PollOpt::oneshot()).unwrap();
    event_loop.run(&mut Echo::new(sock));
}

#[test]
fn test() {
    println!("test");
    get_web_page("www.google.com".to_string(), 80, "/".to_string());
}
<commit_msg>Support arbitrary urls<commit_after>#![crate_type = "lib"]
#![crate_name = "hyperhyper"]
#![feature(std_misc)]
#![feature(lookup_host)]
#![feature(ip_addr)]
extern crate mio;

use mio::*;
use mio::tcp::*;
use std::str::FromStr;
use std::net::SocketAddr;
use std::time::Duration;
use mio::buf::{ByteBuf, MutByteBuf, SliceBuf};
use std::net::Shutdown;
use std::collections::LinkedList;
// Define a handler to process the events
use std::{io, thread};
use std::net;
const SERVER: Token = Token(0);
const CLIENT: Token = Token(1);

struct Echo {
    non_block_client: NonBlock<TcpStream>,
    token: Option<Token>,
    mut_buf: Option<MutByteBuf>,

    buf: Option<ByteBuf>,
    interest: Interest
}

impl Echo {
    fn new(client: NonBlock<TcpStream>) -> Echo {
        Echo {
            non_block_client: client,
            mut_buf: Some(ByteBuf::mut_with_capacity(2048)),
            interest: Interest::hup(),
            buf: None,
            token: None,
        }
    }
}
impl Handler for Echo {
    type Timeout = usize;
    type Message = String;

    fn readable(&mut self, event_loop: &mut EventLoop<Echo>, token: Token, hint: ReadHint) {
        let mut buf = ByteBuf::mut_with_capacity(2048);
        match self.non_block_client.read(&mut buf) {
            Ok(None) => {
                println!("We just got readable, but were unable to read from the socket?");
            }
            Ok(Some(r)) => {
                println!("CONN : we read {} bytes!", r);
                self.interest.remove(Interest::readable());
                if (r > 0){
                    event_loop.reregister(&self.non_block_client, token, self.interest,
                                          PollOpt::edge() | PollOpt::oneshot());
                } else {
                    event_loop.shutdown();
                }
            }
            Err(e) => {
                println!("not implemented; client err={:?}", e);
                self.interest.remove(Interest::readable());
            }
        }
    }

    fn writable(&mut self, event_loop: &mut EventLoop<Echo>, token: Token) {
        let mut buf = ByteBuf::from_slice("GET /\n".as_bytes());

        match self.non_block_client.write(&mut buf) {
            Ok(None) => {
                println!("client flushing buf; WOULDBLOCK");

                self.buf = Some(buf);
                self.interest.insert(Interest::writable());
            }
            Ok(Some(r)) => {
                println!("CONN : we wrote {} bytes!", r);

                self.mut_buf = Some(buf.flip());

                self.interest.insert(Interest::readable());
                self.interest.remove(Interest::writable());
            }
            Err(e) => println!("not implemented; client err={:?}", e),
        }
        event_loop.reregister(&self.non_block_client, token, self.interest,
                              PollOpt::edge() | PollOpt::oneshot());
    }
    fn notify(&mut self, event_loop: &mut EventLoop<Echo>, msg: String) {
        println!("test3");
    }
}

pub fn google() -> SocketAddr {
    let s = format!("216.58.192.4:{}", 80);
    FromStr::from_str(&s).unwrap()
}

fn get_web_page(hostname: String, port: u16, get_resource: String) {
    let mut event_loop = EventLoop::new().unwrap();
    // == Create & setup client socket

    let url = String::new();

    // == Run test
    println!("Connecting");
    let ip = std::net::lookup_host(&hostname).unwrap().next().unwrap().unwrap();
    let address = SocketAddr::new(ip.ip(), port);
    let (mut sock, _) = tcp::v4().unwrap().connect(&address).unwrap();
    event_loop.register_opt(&sock, CLIENT, Interest::writable(),
                            PollOpt::edge() | PollOpt::oneshot()).unwrap();
    event_loop.run(&mut Echo::new(sock));
}

#[test]
fn test() {
    println!("test");
    get_web_page("www.google.com".to_string(), 80, "/".to_string());
}
<|endoftext|>


<commit_before>//! An implementation of [FLAC](https://xiph.org/flac), free lossless audio
//! codec, written in Rust.
//!
//! # Examples
//!
//! Basic decoding from a file.
//!
//! ```
//! match flac::Stream::from_file("path/to/file.flac") {
//!   Ok(mut stream) => {
//!     // Copy of `StreamInfo` to help convert to a different audio format.
//!     let info = stream.info();
//!
//!     for sample in stream.iter() {
//!       // Iterate over each decoded sample
//!     }
//!   }
//!   Err(error)     => println!("{}", error),
//! }
//! ```

#[macro_use]
extern crate nom;

#[macro_use]
mod utility;
pub mod metadata;
mod frame;
mod subframe;
pub mod stream;

pub use metadata::{metadata_parser, Metadata};
pub use subframe::{subframe_parser, Subframe};
pub use stream::{stream_parser, Stream};
<commit_msg>Remove reexport subframe module items<commit_after>//! An implementation of [FLAC](https://xiph.org/flac), free lossless audio
//! codec, written in Rust.
//!
//! # Examples
//!
//! Basic decoding from a file.
//!
//! ```
//! match flac::Stream::from_file("path/to/file.flac") {
//!   Ok(mut stream) => {
//!     // Copy of `StreamInfo` to help convert to a different audio format.
//!     let info = stream.info();
//!
//!     for sample in stream.iter() {
//!       // Iterate over each decoded sample
//!     }
//!   }
//!   Err(error)     => println!("{}", error),
//! }
//! ```

#[macro_use]
extern crate nom;

#[macro_use]
mod utility;
pub mod metadata;
mod frame;
mod subframe;
pub mod stream;

pub use metadata::{metadata_parser, Metadata};
pub use stream::{stream_parser, Stream};
<|endoftext|>


<commit_before>extern crate futures;

use futures::{Async, Poll, Future, Stream};

pub enum StreamEvent<I, S> {
    Next(I),
    Done(S),
}

pub trait StateStream {
    type Item;
    type State;
    type Error;

    fn poll(&mut self) -> Poll<StreamEvent<Self::Item, Self::State>, Self::Error>;

    #[inline]
    fn into_future(self) -> IntoFuture<Self>
        where Self: Sized
    {
        IntoFuture(Some(self))
    }

    #[inline]
    fn into_stream(self) -> IntoStream<Self>
        where Self: Sized
    {
        IntoStream(self)
    }
}

pub fn stream<S>(stream: S) -> FromStream<S>
    where S: Stream
{
    FromStream(stream)
}

pub struct FromStream<S>(S);

impl<S> StateStream for FromStream<S>
    where S: Stream
{
    type Item = S::Item;
    type State = ();
    type Error = S::Error;

    #[inline]
    fn poll(&mut self) -> Poll<StreamEvent<S::Item, ()>, S::Error> {
        self.0.poll().map(|a| {
            match a {
                Async::Ready(Some(i)) => Async::Ready(StreamEvent::Next(i)),
                Async::Ready(None) => Async::Ready(StreamEvent::Done(())),
                Async::NotReady => Async::NotReady,
            }
        })
    }
}

pub struct IntoFuture<S>(Option<S>);

impl<S> Future for IntoFuture<S>
    where S: StateStream
{
    type Item = (StreamEvent<S::Item, S::State>, S);
    type Error = (S::Error, S);

    #[inline]
    fn poll(&mut self) -> Poll<(StreamEvent<S::Item, S::State>, S), (S::Error, S)> {
        let item = match self.0.as_mut().expect("polling IntoFuture twice").poll() {
            Ok(Async::NotReady) => return Ok(Async::NotReady),
            Ok(Async::Ready(i)) => Ok(i),
            Err(e) => Err(e),
        };
        let stream = self.0.take().unwrap();
        match item {
            Ok(i) => Ok(Async::Ready((i, stream))),
            Err(e) => Err((e, stream)),
        }
    }
}

pub struct IntoStream<S>(S);

impl<S> Stream for IntoStream<S>
    where S: StateStream
{
    type Item = S::Item;
    type Error = S::Error;

    #[inline]
    fn poll(&mut self) -> Poll<Option<S::Item>, S::Error> {
        self.0.poll().map(|a| {
            match a {
                Async::Ready(StreamEvent::Next(i)) => Async::Ready(Some(i)),
                Async::Ready(StreamEvent::Done(_)) => Async::Ready(None),
                Async::NotReady => Async::NotReady,
            }
        })
    }
}<commit_msg>Box stuff<commit_after>extern crate futures;

use futures::{Async, Poll, Future, Stream};

pub type BoxStateStream<T, S, E> = Box<StateStream<Item = T, State = S, Error = E> + Send>;

pub enum StreamEvent<I, S> {
    Next(I),
    Done(S),
}

pub trait StateStream {
    type Item;
    type State;
    type Error;

    fn poll(&mut self) -> Poll<StreamEvent<Self::Item, Self::State>, Self::Error>;

    #[inline]
    fn boxed(self) -> BoxStateStream<Self::Item, Self::State, Self::Error>
        where Self: Sized + Send + 'static
    {
        Box::new(self)
    }

    #[inline]
    fn into_future(self) -> IntoFuture<Self>
        where Self: Sized
    {
        IntoFuture(Some(self))
    }

    #[inline]
    fn into_stream(self) -> IntoStream<Self>
        where Self: Sized
    {
        IntoStream(self)
    }
}

impl<S: ?Sized> StateStream for Box<S>
    where S: StateStream
{
    type Item = S::Item;
    type State = S::State;
    type Error = S::Error;

    #[inline]
    fn poll(&mut self) -> Poll<StreamEvent<S::Item, S::State>, S::Error> {
        S::poll(self)
    }
}

pub fn stream<S>(stream: S) -> FromStream<S>
    where S: Stream
{
    FromStream(stream)
}

pub struct FromStream<S>(S);

impl<S> StateStream for FromStream<S>
    where S: Stream
{
    type Item = S::Item;
    type State = ();
    type Error = S::Error;

    #[inline]
    fn poll(&mut self) -> Poll<StreamEvent<S::Item, ()>, S::Error> {
        self.0.poll().map(|a| {
            match a {
                Async::Ready(Some(i)) => Async::Ready(StreamEvent::Next(i)),
                Async::Ready(None) => Async::Ready(StreamEvent::Done(())),
                Async::NotReady => Async::NotReady,
            }
        })
    }
}

pub struct IntoFuture<S>(Option<S>);

impl<S> Future for IntoFuture<S>
    where S: StateStream
{
    type Item = (StreamEvent<S::Item, S::State>, S);
    type Error = (S::Error, S);

    #[inline]
    fn poll(&mut self) -> Poll<(StreamEvent<S::Item, S::State>, S), (S::Error, S)> {
        let item = match self.0.as_mut().expect("polling IntoFuture twice").poll() {
            Ok(Async::NotReady) => return Ok(Async::NotReady),
            Ok(Async::Ready(i)) => Ok(i),
            Err(e) => Err(e),
        };
        let stream = self.0.take().unwrap();
        match item {
            Ok(i) => Ok(Async::Ready((i, stream))),
            Err(e) => Err((e, stream)),
        }
    }
}

pub struct IntoStream<S>(S);

impl<S> Stream for IntoStream<S>
    where S: StateStream
{
    type Item = S::Item;
    type Error = S::Error;

    #[inline]
    fn poll(&mut self) -> Poll<Option<S::Item>, S::Error> {
        self.0.poll().map(|a| {
            match a {
                Async::Ready(StreamEvent::Next(i)) => Async::Ready(Some(i)),
                Async::Ready(StreamEvent::Done(_)) => Async::Ready(None),
                Async::NotReady => Async::NotReady,
            }
        })
    }
}<|endoftext|>