<commit_before>//! Bindings to LLVM's C API.
//!
//! Refer to the [LLVM documentation](http://llvm.org/docs/) for more
//! information.

extern crate libc;
#[macro_use] extern crate bitflags;

use self::prelude::*;

#[repr(C)]
pub struct LLVMMemoryBuffer;
#[repr(C)]
pub struct LLVMContext;
#[repr(C)]
pub struct LLVMModule;
#[repr(C)]
pub struct LLVMType;
#[repr(C)]
pub struct LLVMValue;
#[repr(C)]
pub struct LLVMBasicBlock;
#[repr(C)]
pub struct LLVMBuilder;
#[repr(C)]
pub struct LLVMModuleProvider;
#[repr(C)]
pub struct LLVMPassManager;
#[repr(C)]
pub struct LLVMPassRegistry;
#[repr(C)]
pub struct LLVMUse;
#[repr(C)]
pub struct LLVMDiagnosticInfo;

/// Core types used throughout LLVM.
///
/// In most cases you will want to `use llvm::prelude::*`.
pub mod prelude {
    pub type LLVMBool = ::libc::c_int;
    pub type LLVMMemoryBufferRef = *mut super::LLVMMemoryBuffer;
    pub type LLVMContextRef = *mut super::LLVMContext;
    pub type LLVMModuleRef = *mut super::LLVMModule;
    pub type LLVMTypeRef = *mut super::LLVMType;
    pub type LLVMValueRef = *mut super::LLVMValue;
    pub type LLVMBasicBlockRef = *mut super::LLVMBasicBlock;
    pub type LLVMBuilderRef = *mut super::LLVMBuilder;
    pub type LLVMModuleProviderRef = *mut super::LLVMModuleProvider;
    pub type LLVMPassManagerRef = *mut super::LLVMPassManager;
    pub type LLVMPassRegistryRef = *mut super::LLVMPassRegistry;
    pub type LLVMUseRef = *mut super::LLVMUse;
    pub type LLVMDiagnosticInfoRef = *mut super::LLVMDiagnosticInfo;
}

pub mod analysis;
pub mod bit_reader;
pub mod bit_writer;
pub mod core;
pub mod disassembler;
pub mod execution_engine;
pub mod initialization;
pub mod ir_reader;
pub mod link_time_optimizer;
pub mod linker;
pub mod lto;
pub mod object;
pub mod target;
pub mod support;
pub mod target_machine;

pub mod transforms {
    pub mod ipo;
    pub mod pass_manager_builder;
    pub mod scalar;
    pub mod vectorize;
}

bitflags! {
    #[repr(C)]
    flags LLVMAttribute: ::libc::c_int {
        #[allow(non_upper_case_globals)]
        const LLVMZExtAttribute = 1 << 0,
        #[allow(non_upper_case_globals)]
        const LLVMSExtAttribute = 1 << 1,
        #[allow(non_upper_case_globals)]
        const LLVMNoReturnAttribute= 4,
        #[allow(non_upper_case_globals)]
        const LLVMInRegAttribute= 8,
        #[allow(non_upper_case_globals)]
        const LLVMStructRetAttribute= 16,
        #[allow(non_upper_case_globals)]
        const LLVMNoUnwindAttribute= 32,
        #[allow(non_upper_case_globals)]
        const LLVMNoAliasAttribute= 64,
        #[allow(non_upper_case_globals)]
        const LLVMByValAttribute= 128,
        #[allow(non_upper_case_globals)]
        const LLVMNestAttribute= 256,
        #[allow(non_upper_case_globals)]
        const LLVMReadNoneAttribute= 512,
        #[allow(non_upper_case_globals)]
        const LLVMReadOnlyAttribute= 1024,
        #[allow(non_upper_case_globals)]
        const LLVMNoInlineAttribute= 2048,
        #[allow(non_upper_case_globals)]
        const LLVMAlwaysInlineAttribute= 4096,
        #[allow(non_upper_case_globals)]
        const LLVMOptimizeForSizeAttribute= 8192,
        #[allow(non_upper_case_globals)]
        const LLVMStackProtectAttribute= 16384,
        #[allow(non_upper_case_globals)]
        const LLVMStackProtectReqAttribute= 32768,
        #[allow(non_upper_case_globals)]
        const LLVMAlignment= 2031616,
        #[allow(non_upper_case_globals)]
        const LLVMNoCaptureAttribute= 2097152,
        #[allow(non_upper_case_globals)]
        const LLVMNoRedZoneAttribute= 4194304,
        #[allow(non_upper_case_globals)]
        const LLVMNoImplicitFloatAttribute= 8388608,
        #[allow(non_upper_case_globals)]
        const LLVMNakedAttribute= 16777216,
        #[allow(non_upper_case_globals)]
        const LLVMInlineHintAttribute= 33554432,
        #[allow(non_upper_case_globals)]
        const LLVMStackAlignment= 469762048,
        #[allow(non_upper_case_globals)]
        const LLVMReturnsTwice= 536870912,
        #[allow(non_upper_case_globals)]
        const LLVMUWTable= 1073741824,
        #[allow(non_upper_case_globals)]
        const LLVMNonLazyBind = 1 << 31
    }
}

#[repr(C)]
pub enum LLVMOpcode {
    LLVMRet = 1,
    LLVMBr = 2,
    LLVMSwitch = 3,
    LLVMIndirectBr = 4,
    LLVMInvoke = 5,
    LLVMUnreachable = 7,
    LLVMAdd = 8,
    LLVMFAdd = 9,
    LLVMSub = 10,
    LLVMFSub = 11,
    LLVMMul = 12,
    LLVMFMul = 13,
    LLVMUDiv = 14,
    LLVMSDiv = 15,
    LLVMFDiv = 16,
    LLVMURem = 17,
    LLVMSRem = 18,
    LLVMFRem = 19,
    LLVMShl = 20,
    LLVMLShr = 21,
    LLVMAShr = 22,
    LLVMAnd = 23,
    LLVMOr = 24,
    LLVMXor = 25,
    LLVMAlloca = 26,
    LLVMLoad = 27,
    LLVMStore = 28,
    LLVMGetElementPtr = 29,
    LLVMTrunc = 30,
    LLVMZExt = 31,
    LLVMSExt = 32,
    LLVMFPToUI = 33,
    LLVMFPToSI = 34,
    LLVMUIToFP = 35,
    LLVMSIToFP = 36,
    LLVMFPTrunc = 37,
    LLVMFPExt = 38,
    LLVMPtrToInt = 39,
    LLVMIntToPtr = 40,
    LLVMBitCast = 41,
    LLVMAddrSpaceCast = 60,
    LLVMICmp = 42,
    LLVMFCmp = 43,
    LLVMPHI = 44,
    LLVMCall = 45,
    LLVMSelect = 46,
    LLVMUserOp1 = 47,
    LLVMUserOp2 = 48,
    LLVMVAArg = 49,
    LLVMExtractElement = 50,
    LLVMInsertElement = 51,
    LLVMShuffleVector = 52,
    LLVMExtractValue = 53,
    LLVMInsertValue = 54,
    LLVMFence = 55,
    LLVMAtomicCmpXchg = 56,
    LLVMAtomicRMW = 57,
    LLVMResume = 58,
    LLVMLandingPad = 59
}

#[repr(C)]
pub enum LLVMTypeKind {
    LLVMVoidTypeKind = 0,
    LLVMHalfTypeKind = 1,
    LLVMFloatTypeKind = 2,
    LLVMDoubleTypeKind = 3,
    LLVMX86_FP80TypeKind = 4,
    LLVMFP128TypeKind = 5,
    LLVMPPC_FP128TypeKind = 6,
    LLVMLabelTypeKind = 7,
    LLVMIntegerTypeKind = 8,
    LLVMFunctionTypeKind = 9,
    LLVMStructTypeKind = 10,
    LLVMArrayTypeKind = 11,
    LLVMPointerTypeKind = 12,
    LLVMVectorTypeKind = 13,
    LLVMMetadataTypeKind = 14,
    LLVMX86_MMXTypeKind = 15
}

#[repr(C)]
pub enum LLVMLinkage {
    LLVMExternalLinkage = 0,
    LLVMAvailableExternallyLinkage = 1,
    LLVMLinkOnceAnyLinkage = 2,
    LLVMLinkOnceODRLinkage = 3,
    LLVMLinkOnceODRAutoHideLinkage = 4,
    LLVMWeakAnyLinkage = 5,
    LLVMWeakODRLinkage = 6,
    LLVMAppendingLinkage = 7,
    LLVMInternalLinkage = 8,
    LLVMPrivateLinkage = 9,
    LLVMDLLImportLinkage = 10,
    LLVMDLLExportLinkage = 11,
    LLVMExternalWeakLinkage = 12,
    LLVMGhostLinkage = 13,
    LLVMCommonLinkage = 14,
    LLVMLinkerPrivateLinkage = 15,
    LLVMLinkerPrivateWeakLinkage = 16
}

#[repr(C)]
pub enum LLVMVisibility {
    LLVMDefaultVisibility = 0,
    LLVMHiddenVisibility = 1,
    LLVMProtectedVisibility = 2
}

#[repr(C)]
pub enum LLVMDLLStorageClass {
    LLVMDefaultStorageClass = 0,
    LLVMDLLImportStorageClass = 1,
    LLVMDLLExportStorageClass = 2
}

#[repr(C)]
pub enum LLVMCallConv {
    LLVMCCallConv = 0,
    LLVMFastCallConv = 8,
    LLVMColdCallConv = 9,
    LLVMWebKitJSCallConv = 12,
    LLVMAnyRegCallConv = 13,
    LLVMX86StdcallCallConv = 64,
    LLVMX86FastcallCallConv = 65,
}

#[repr(C)]
pub enum LLVMIntPredicate {
    LLVMIntEQ = 32,
    LLVMIntNE = 33,
    LLVMIntUGT = 34,
    LLVMIntUGE = 35,
    LLVMIntULT = 36,
    LLVMIntULE = 37,
    LLVMIntSGT = 38,
    LLVMIntSGE = 39,
    LLVMIntSLT = 40,
    LLVMIntSLE = 41,
}

#[repr(C)]
pub enum LLVMRealPredicate {
    LLVMRealPredicateFalse = 0,
    LLVMRealOEQ = 1,
    LLVMRealOGT = 2,
    LLVMRealOGE = 3,
    LLVMRealOLT = 4,
    LLVMRealOLE = 5,
    LLVMRealONE = 6,
    LLVMRealORD = 7,
    LLVMRealUNO = 8,
    LLVMRealUEQ = 9,
    LLVMRealUGT = 10,
    LLVMRealUGE = 11,
    LLVMRealULT = 12,
    LLVMRealULE = 13,
    LLVMRealUNE = 14,
    LLVMRealPredicateTrue = 15,
}

#[repr(C)]
pub enum LLVMLandingPadClauseTy {
    LLVMLandingPadCatch = 0,
    LLVMLandingPadFilter = 1,
}

#[repr(C)]
pub enum LLVMThreadLocalMode {
    LLVMNotThreadLocal = 0,
    LLVMGeneralDynamicTLSModel = 1,
    LLVMLocalDynamicTLSModel = 2,
    LLVMInitialExecTLSModel = 3,
    LLVMLocalExecTLSModel = 4,
}

#[repr(C)]
pub enum LLVMAtomicOrdering {
    LLVMAtomicOrderingNotAtomic = 0,
    LLVMAtomicOrderingUnordered = 1,
    LLVMAtomicOrderingMonotonic = 2,
    LLVMAtomicOrderingAcquire = 4,
    LLVMAtomicOrderingRelease = 5,
    LLVMAtomicOrderingAcquireRelease = 6,
    LLVMAtomicOrderingSequentiallyConsistent = 7,
}

#[repr(C)]
pub enum LLVMAtomicRMWBinOp {
    LLVMAtomicRMWBinOpXchg = 0,
    LLVMAtomicRMWBinOpAdd = 1,
    LLVMAtomicRMWBinOpSub = 2,
    LLVMAtomicRMWBinOpAnd = 3,
    LLVMAtomicRMWBinOpNand = 4,
    LLVMAtomicRMWBinOpOr = 5,
    LLVMAtomicRMWBinOpXor = 6,
    LLVMAtomicRMWBinOpMax = 7,
    LLVMAtomicRMWBinOpMin = 8,
    LLVMAtomicRMWBinOpUMax = 9,
    LLVMAtomicRMWBinOpUMin = 10,
}

#[repr(C)]
pub enum LLVMDiagnosticSeverity {
    LLVMDSError = 0,
    LLVMDSWarning = 1,
    LLVMDSRemark = 2,
    LLVMDSNote = 3,
}

pub type LLVMFatalErrorHandler = extern "C" fn(Reason: *const ::libc::c_char) -> ();
pub type LLVMDiagnosticHandler = extern "C" fn(arg1: LLVMDiagnosticInfoRef,
                                               arg2: *mut ::libc::c_void) -> ();
pub type LLVMYieldCallback = extern "C" fn(arg1: LLVMContextRef,
                                           arg2: *mut ::libc::c_void) -> ();

<commit_msg>Silence warning about non-uppercase globals.<commit_after>//! Bindings to LLVM's C API.
//!
//! Refer to the [LLVM documentation](http://llvm.org/docs/) for more
//! information.

#![allow(non_upper_case_globals)]

extern crate libc;
#[macro_use] extern crate bitflags;

use self::prelude::*;

#[repr(C)]
pub struct LLVMMemoryBuffer;
#[repr(C)]
pub struct LLVMContext;
#[repr(C)]
pub struct LLVMModule;
#[repr(C)]
pub struct LLVMType;
#[repr(C)]
pub struct LLVMValue;
#[repr(C)]
pub struct LLVMBasicBlock;
#[repr(C)]
pub struct LLVMBuilder;
#[repr(C)]
pub struct LLVMModuleProvider;
#[repr(C)]
pub struct LLVMPassManager;
#[repr(C)]
pub struct LLVMPassRegistry;
#[repr(C)]
pub struct LLVMUse;
#[repr(C)]
pub struct LLVMDiagnosticInfo;

/// Core types used throughout LLVM.
///
/// In most cases you will want to `use llvm::prelude::*`.
pub mod prelude {
    pub type LLVMBool = ::libc::c_int;
    pub type LLVMMemoryBufferRef = *mut super::LLVMMemoryBuffer;
    pub type LLVMContextRef = *mut super::LLVMContext;
    pub type LLVMModuleRef = *mut super::LLVMModule;
    pub type LLVMTypeRef = *mut super::LLVMType;
    pub type LLVMValueRef = *mut super::LLVMValue;
    pub type LLVMBasicBlockRef = *mut super::LLVMBasicBlock;
    pub type LLVMBuilderRef = *mut super::LLVMBuilder;
    pub type LLVMModuleProviderRef = *mut super::LLVMModuleProvider;
    pub type LLVMPassManagerRef = *mut super::LLVMPassManager;
    pub type LLVMPassRegistryRef = *mut super::LLVMPassRegistry;
    pub type LLVMUseRef = *mut super::LLVMUse;
    pub type LLVMDiagnosticInfoRef = *mut super::LLVMDiagnosticInfo;
}

pub mod analysis;
pub mod bit_reader;
pub mod bit_writer;
pub mod core;
pub mod disassembler;
pub mod execution_engine;
pub mod initialization;
pub mod ir_reader;
pub mod link_time_optimizer;
pub mod linker;
pub mod lto;
pub mod object;
pub mod target;
pub mod support;
pub mod target_machine;

pub mod transforms {
    pub mod ipo;
    pub mod pass_manager_builder;
    pub mod scalar;
    pub mod vectorize;
}

bitflags! {
    #[repr(C)]
    flags LLVMAttribute: ::libc::c_int {
        #[allow(non_upper_case_globals)]
        const LLVMZExtAttribute = 1 << 0,
        #[allow(non_upper_case_globals)]
        const LLVMSExtAttribute = 1 << 1,
        #[allow(non_upper_case_globals)]
        const LLVMNoReturnAttribute= 4,
        #[allow(non_upper_case_globals)]
        const LLVMInRegAttribute= 8,
        #[allow(non_upper_case_globals)]
        const LLVMStructRetAttribute= 16,
        #[allow(non_upper_case_globals)]
        const LLVMNoUnwindAttribute= 32,
        #[allow(non_upper_case_globals)]
        const LLVMNoAliasAttribute= 64,
        #[allow(non_upper_case_globals)]
        const LLVMByValAttribute= 128,
        #[allow(non_upper_case_globals)]
        const LLVMNestAttribute= 256,
        #[allow(non_upper_case_globals)]
        const LLVMReadNoneAttribute= 512,
        #[allow(non_upper_case_globals)]
        const LLVMReadOnlyAttribute= 1024,
        #[allow(non_upper_case_globals)]
        const LLVMNoInlineAttribute= 2048,
        #[allow(non_upper_case_globals)]
        const LLVMAlwaysInlineAttribute= 4096,
        #[allow(non_upper_case_globals)]
        const LLVMOptimizeForSizeAttribute= 8192,
        #[allow(non_upper_case_globals)]
        const LLVMStackProtectAttribute= 16384,
        #[allow(non_upper_case_globals)]
        const LLVMStackProtectReqAttribute= 32768,
        #[allow(non_upper_case_globals)]
        const LLVMAlignment= 2031616,
        #[allow(non_upper_case_globals)]
        const LLVMNoCaptureAttribute= 2097152,
        #[allow(non_upper_case_globals)]
        const LLVMNoRedZoneAttribute= 4194304,
        #[allow(non_upper_case_globals)]
        const LLVMNoImplicitFloatAttribute= 8388608,
        #[allow(non_upper_case_globals)]
        const LLVMNakedAttribute= 16777216,
        #[allow(non_upper_case_globals)]
        const LLVMInlineHintAttribute= 33554432,
        #[allow(non_upper_case_globals)]
        const LLVMStackAlignment= 469762048,
        #[allow(non_upper_case_globals)]
        const LLVMReturnsTwice= 536870912,
        #[allow(non_upper_case_globals)]
        const LLVMUWTable= 1073741824,
        #[allow(non_upper_case_globals)]
        const LLVMNonLazyBind = 1 << 31
    }
}

#[repr(C)]
pub enum LLVMOpcode {
    LLVMRet = 1,
    LLVMBr = 2,
    LLVMSwitch = 3,
    LLVMIndirectBr = 4,
    LLVMInvoke = 5,
    LLVMUnreachable = 7,
    LLVMAdd = 8,
    LLVMFAdd = 9,
    LLVMSub = 10,
    LLVMFSub = 11,
    LLVMMul = 12,
    LLVMFMul = 13,
    LLVMUDiv = 14,
    LLVMSDiv = 15,
    LLVMFDiv = 16,
    LLVMURem = 17,
    LLVMSRem = 18,
    LLVMFRem = 19,
    LLVMShl = 20,
    LLVMLShr = 21,
    LLVMAShr = 22,
    LLVMAnd = 23,
    LLVMOr = 24,
    LLVMXor = 25,
    LLVMAlloca = 26,
    LLVMLoad = 27,
    LLVMStore = 28,
    LLVMGetElementPtr = 29,
    LLVMTrunc = 30,
    LLVMZExt = 31,
    LLVMSExt = 32,
    LLVMFPToUI = 33,
    LLVMFPToSI = 34,
    LLVMUIToFP = 35,
    LLVMSIToFP = 36,
    LLVMFPTrunc = 37,
    LLVMFPExt = 38,
    LLVMPtrToInt = 39,
    LLVMIntToPtr = 40,
    LLVMBitCast = 41,
    LLVMAddrSpaceCast = 60,
    LLVMICmp = 42,
    LLVMFCmp = 43,
    LLVMPHI = 44,
    LLVMCall = 45,
    LLVMSelect = 46,
    LLVMUserOp1 = 47,
    LLVMUserOp2 = 48,
    LLVMVAArg = 49,
    LLVMExtractElement = 50,
    LLVMInsertElement = 51,
    LLVMShuffleVector = 52,
    LLVMExtractValue = 53,
    LLVMInsertValue = 54,
    LLVMFence = 55,
    LLVMAtomicCmpXchg = 56,
    LLVMAtomicRMW = 57,
    LLVMResume = 58,
    LLVMLandingPad = 59
}

#[repr(C)]
pub enum LLVMTypeKind {
    LLVMVoidTypeKind = 0,
    LLVMHalfTypeKind = 1,
    LLVMFloatTypeKind = 2,
    LLVMDoubleTypeKind = 3,
    LLVMX86_FP80TypeKind = 4,
    LLVMFP128TypeKind = 5,
    LLVMPPC_FP128TypeKind = 6,
    LLVMLabelTypeKind = 7,
    LLVMIntegerTypeKind = 8,
    LLVMFunctionTypeKind = 9,
    LLVMStructTypeKind = 10,
    LLVMArrayTypeKind = 11,
    LLVMPointerTypeKind = 12,
    LLVMVectorTypeKind = 13,
    LLVMMetadataTypeKind = 14,
    LLVMX86_MMXTypeKind = 15
}

#[repr(C)]
pub enum LLVMLinkage {
    LLVMExternalLinkage = 0,
    LLVMAvailableExternallyLinkage = 1,
    LLVMLinkOnceAnyLinkage = 2,
    LLVMLinkOnceODRLinkage = 3,
    LLVMLinkOnceODRAutoHideLinkage = 4,
    LLVMWeakAnyLinkage = 5,
    LLVMWeakODRLinkage = 6,
    LLVMAppendingLinkage = 7,
    LLVMInternalLinkage = 8,
    LLVMPrivateLinkage = 9,
    LLVMDLLImportLinkage = 10,
    LLVMDLLExportLinkage = 11,
    LLVMExternalWeakLinkage = 12,
    LLVMGhostLinkage = 13,
    LLVMCommonLinkage = 14,
    LLVMLinkerPrivateLinkage = 15,
    LLVMLinkerPrivateWeakLinkage = 16
}

#[repr(C)]
pub enum LLVMVisibility {
    LLVMDefaultVisibility = 0,
    LLVMHiddenVisibility = 1,
    LLVMProtectedVisibility = 2
}

#[repr(C)]
pub enum LLVMDLLStorageClass {
    LLVMDefaultStorageClass = 0,
    LLVMDLLImportStorageClass = 1,
    LLVMDLLExportStorageClass = 2
}

#[repr(C)]
pub enum LLVMCallConv {
    LLVMCCallConv = 0,
    LLVMFastCallConv = 8,
    LLVMColdCallConv = 9,
    LLVMWebKitJSCallConv = 12,
    LLVMAnyRegCallConv = 13,
    LLVMX86StdcallCallConv = 64,
    LLVMX86FastcallCallConv = 65,
}

#[repr(C)]
pub enum LLVMIntPredicate {
    LLVMIntEQ = 32,
    LLVMIntNE = 33,
    LLVMIntUGT = 34,
    LLVMIntUGE = 35,
    LLVMIntULT = 36,
    LLVMIntULE = 37,
    LLVMIntSGT = 38,
    LLVMIntSGE = 39,
    LLVMIntSLT = 40,
    LLVMIntSLE = 41,
}

#[repr(C)]
pub enum LLVMRealPredicate {
    LLVMRealPredicateFalse = 0,
    LLVMRealOEQ = 1,
    LLVMRealOGT = 2,
    LLVMRealOGE = 3,
    LLVMRealOLT = 4,
    LLVMRealOLE = 5,
    LLVMRealONE = 6,
    LLVMRealORD = 7,
    LLVMRealUNO = 8,
    LLVMRealUEQ = 9,
    LLVMRealUGT = 10,
    LLVMRealUGE = 11,
    LLVMRealULT = 12,
    LLVMRealULE = 13,
    LLVMRealUNE = 14,
    LLVMRealPredicateTrue = 15,
}

#[repr(C)]
pub enum LLVMLandingPadClauseTy {
    LLVMLandingPadCatch = 0,
    LLVMLandingPadFilter = 1,
}

#[repr(C)]
pub enum LLVMThreadLocalMode {
    LLVMNotThreadLocal = 0,
    LLVMGeneralDynamicTLSModel = 1,
    LLVMLocalDynamicTLSModel = 2,
    LLVMInitialExecTLSModel = 3,
    LLVMLocalExecTLSModel = 4,
}

#[repr(C)]
pub enum LLVMAtomicOrdering {
    LLVMAtomicOrderingNotAtomic = 0,
    LLVMAtomicOrderingUnordered = 1,
    LLVMAtomicOrderingMonotonic = 2,
    LLVMAtomicOrderingAcquire = 4,
    LLVMAtomicOrderingRelease = 5,
    LLVMAtomicOrderingAcquireRelease = 6,
    LLVMAtomicOrderingSequentiallyConsistent = 7,
}

#[repr(C)]
pub enum LLVMAtomicRMWBinOp {
    LLVMAtomicRMWBinOpXchg = 0,
    LLVMAtomicRMWBinOpAdd = 1,
    LLVMAtomicRMWBinOpSub = 2,
    LLVMAtomicRMWBinOpAnd = 3,
    LLVMAtomicRMWBinOpNand = 4,
    LLVMAtomicRMWBinOpOr = 5,
    LLVMAtomicRMWBinOpXor = 6,
    LLVMAtomicRMWBinOpMax = 7,
    LLVMAtomicRMWBinOpMin = 8,
    LLVMAtomicRMWBinOpUMax = 9,
    LLVMAtomicRMWBinOpUMin = 10,
}

#[repr(C)]
pub enum LLVMDiagnosticSeverity {
    LLVMDSError = 0,
    LLVMDSWarning = 1,
    LLVMDSRemark = 2,
    LLVMDSNote = 3,
}

pub type LLVMFatalErrorHandler = extern "C" fn(Reason: *const ::libc::c_char) -> ();
pub type LLVMDiagnosticHandler = extern "C" fn(arg1: LLVMDiagnosticInfoRef,
                                               arg2: *mut ::libc::c_void) -> ();
pub type LLVMYieldCallback = extern "C" fn(arg1: LLVMContextRef,
                                           arg2: *mut ::libc::c_void) -> ();

<|endoftext|>


<commit_before>//! # Console progress bar for Rust
//!
//! Console progress bar for Rust Inspired from [pb](http://github.com/cheggaaa/pb).
//! support and tested on MacOS, Linux and Window
//!
//! ![Screenshot](https://raw.githubusercontent.com/a8m/pb/master/gif/rec_v2.gif)
//!
//! ### Examples
//! 1. simple example
//!
//! ```no_run
//! extern crate pbr;
//!
//! use pbr::ProgressBar;
//! use std::thread;
//!
//! fn main() {
//!     let count = 1000;
//!     let mut pb = ProgressBar::new(count);
//!     for _ in 0..count {
//!         pb.inc();
//!         thread::sleep_ms(200);
//!     }
//!     println!("done!");
//! }
//! ```
//!
//! 2. Broadcast writing(simple file copying)
//!
//! ```ignore
//! #![feature(io)]
//! extern crate pbr;
//!
//! use std::io::copy;
//! use std::io::prelude::*;
//! use std::fs::File;
//! use pbr::{ProgressBar, Units};
//!
//! fn main() {
//!     let mut file = File::open("/usr/share/dict/words").unwrap();
//!     let n_bytes = file.metadata().unwrap().len() as usize;
//!     let mut pb = ProgressBar::new(n_bytes);
//!     pb.set_units(Units::Bytes);
//!     let mut handle = File::create("copy-words").unwrap().broadcast(&mut pb);
//!     copy(&mut file, &mut handle).unwrap();
//!     println!("done!");
//! }
//! ```

// Macro for writing to the giving writer.
// Used in both pb.rs and multi.rs modules.
//
// # Examples
//
// ```
// let w = io::stdout();
// printfl!(w, "");
// printfl!(w, "\r{}", out);
//
// ```
macro_rules! printfl {
   ($w:expr, $($tt:tt)*) => {{
        $w.write(&format!($($tt)*).as_bytes()).ok().expect("write() fail");
        $w.flush().ok().expect("flush() fail");
    }}
}

#[macro_use]
extern crate time;
mod tty;
mod pb;
mod multi;
pub use pb::{ProgressBar, Units};
pub use multi::MultiBar;
use std::io::{Write, Stdout, stdout};

pub struct PbIter<T, I>
    where I: Iterator,
          T: Write
{
    iter: I,
    progress_bar: ProgressBar<T>,
}

impl<I> PbIter<Stdout, I>
    where I: Iterator
{
    pub fn new(iter: I) -> Self {
        Self::on(stdout(), iter)
    }
}

impl<T, I> PbIter<T, I>
    where I: Iterator,
          T: Write
{
    pub fn on(handle: T, iter: I) -> Self {
        let size = iter.size_hint().0;
        PbIter {
            iter: iter,
            progress_bar: ProgressBar::on(handle, size as u64),
        }
    }
}

impl<T, I> Iterator for PbIter<T, I>
    where I: Iterator,
          T: Write
{
    type Item = I::Item;

    fn next(&mut self) -> Option<I::Item> {
        match self.iter.next() {
            Some(i) => {
                self.progress_bar.inc();
                Some(i)
            }
            None => None,
        }
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        self.iter.size_hint()
    }
}
<commit_msg>doc: update screenshot<commit_after>//! # Console progress bar for Rust
//!
//! Console progress bar for Rust Inspired from [pb](http://github.com/cheggaaa/pb).
//! support and tested on MacOS, Linux and Window
//!
//! ![Screenshot](https://raw.githubusercontent.com/a8m/pb/master/gif/rec_v3.gif)
//!
//! ### Examples
//! 1. simple example
//!
//! ```no_run
//! extern crate pbr;
//!
//! use pbr::ProgressBar;
//! use std::thread;
//!
//! fn main() {
//!     let count = 1000;
//!     let mut pb = ProgressBar::new(count);
//!     for _ in 0..count {
//!         pb.inc();
//!         thread::sleep_ms(200);
//!     }
//!     println!("done!");
//! }
//! ```
//!
//! 2. Broadcast writing(simple file copying)
//!
//! ```ignore
//! #![feature(io)]
//! extern crate pbr;
//!
//! use std::io::copy;
//! use std::io::prelude::*;
//! use std::fs::File;
//! use pbr::{ProgressBar, Units};
//!
//! fn main() {
//!     let mut file = File::open("/usr/share/dict/words").unwrap();
//!     let n_bytes = file.metadata().unwrap().len() as usize;
//!     let mut pb = ProgressBar::new(n_bytes);
//!     pb.set_units(Units::Bytes);
//!     let mut handle = File::create("copy-words").unwrap().broadcast(&mut pb);
//!     copy(&mut file, &mut handle).unwrap();
//!     println!("done!");
//! }
//! ```

// Macro for writing to the giving writer.
// Used in both pb.rs and multi.rs modules.
//
// # Examples
//
// ```
// let w = io::stdout();
// printfl!(w, "");
// printfl!(w, "\r{}", out);
//
// ```
macro_rules! printfl {
   ($w:expr, $($tt:tt)*) => {{
        $w.write(&format!($($tt)*).as_bytes()).ok().expect("write() fail");
        $w.flush().ok().expect("flush() fail");
    }}
}

#[macro_use]
extern crate time;
mod tty;
mod pb;
mod multi;
pub use pb::{ProgressBar, Units};
pub use multi::MultiBar;
use std::io::{Write, Stdout, stdout};

pub struct PbIter<T, I>
    where I: Iterator,
          T: Write
{
    iter: I,
    progress_bar: ProgressBar<T>,
}

impl<I> PbIter<Stdout, I>
    where I: Iterator
{
    pub fn new(iter: I) -> Self {
        Self::on(stdout(), iter)
    }
}

impl<T, I> PbIter<T, I>
    where I: Iterator,
          T: Write
{
    pub fn on(handle: T, iter: I) -> Self {
        let size = iter.size_hint().0;
        PbIter {
            iter: iter,
            progress_bar: ProgressBar::on(handle, size as u64),
        }
    }
}

impl<T, I> Iterator for PbIter<T, I>
    where I: Iterator,
          T: Write
{
    type Item = I::Item;

    fn next(&mut self) -> Option<I::Item> {
        match self.iter.next() {
            Some(i) => {
                self.progress_bar.inc();
                Some(i)
            }
            None => None,
        }
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        self.iter.size_hint()
    }
}
<|endoftext|>


<commit_before>#![cfg_attr(unix, feature(fs_ext))]

//! xdg-rs is a utility library to make conforming to the [XDG specification](http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html) easier.
//!
//! Some code borrowed from [rust-xdg](https://github.com/o11c/rust-xdg). ```rust-xdg``` is
//! currently a more complete implementation of the specification. The APIs provided by
//! ```rust-xdg``` and ```xdg-rs``` are different.

pub mod error;

pub use error::*;

use std::convert::From;
use std::env::{self, home_dir, split_paths};
use std::ffi::OsString;
use std::fs;
use std::io;
use std::path::{Path, PathBuf};
use std::result;

#[cfg(unix)]
use std::os::unix::fs::PermissionsExt;

/// Get the data home directory given a closure that returns the the value of an environment variable.
/// This method allows having a custom environment.
///
/// If ```$XDG_DATA_HOME``` is not set, it returns ```$HOME/.local/share```.
pub fn get_data_home_from_env<F>(get_env_var: &F) -> Result<PathBuf>
    where F: Fn(&str) -> Option<OsString>
{
    get_env_path_or_default(get_env_var, "XDG_DATA_HOME", ".local/share")
}

/// Get the data home directory.
///
/// If ```$XDG_DATA_HOME``` is not set, it returns ```$HOME/.local/share```.
pub fn get_data_home() -> Result<PathBuf> {
    get_data_home_from_env(&env::var_os)
}

/// Get the default data directories given a closure that returns the the value of an environment variable.
/// This method allows having a custom environment.
///
/// If ```$XDG_DATA_DIRS``` is not set, it returns ```[/usr/local/share, /usr/share]```.
pub fn get_data_dirs_from_env<F>(get_env_var: &F) -> Vec<PathBuf>
    where F: Fn(&str) -> Option<OsString>
{
    get_env_paths_or_default(get_env_var, "XDG_DATA_DIRS", "/usr/local/share:/usr/share")
}

/// Get the data directories.
///
/// If ```$XDG_DATA_DIRS``` is not set, it returns ```[/usr/local/share, /usr/share]```.
pub fn get_data_dirs() -> Vec<PathBuf> {
    get_data_dirs_from_env(&env::var_os)
}

/// Get the config home directory given a closure that returns the the value of an environment variable.
/// This method allows having a custom environment.
///
/// If ```$XDG_CONFIG_HOME``` is not set, it returns ```$HOME/.config```.
pub fn get_config_home_from_env<F>(get_env_var: &F) -> Result<PathBuf>
    where F: Fn(&str) -> Option<OsString>
{
    get_env_path_or_default(get_env_var, "XDG_CONFIG_HOME", ".config")
}
/// Get the config home directory.
///
/// If ```$XDG_CONFIG_HOME``` is not set, it returns ```$HOME/.config```.
pub fn get_config_home() -> Result<PathBuf> {
    get_config_home_from_env(&env::var_os)
}

/// Get the default config directories given a closure that returns the the value of an environment variable.
/// This method allows having a custom environment.
///
/// If ```$XDG_CONFIG_DIRS``` is not set, it returns ```[/etc/xdg]```.
pub fn get_config_dirs_from_env<F>(get_env_var: &F) -> Vec<PathBuf>
    where F: Fn(&str) -> Option<OsString>
{
    get_env_paths_or_default(get_env_var, "XDG_CONFIG_DIRS", "/etc/xdg")
}

/// Get the config directories.
///
/// If ```$XDG_CONFIG_DIRS``` is not set, it returns ```[/etc/xdg]```.
pub fn get_config_dirs() -> Vec<PathBuf> {
    get_config_dirs_from_env(&env::var_os)
}

/// Get the cache home directory given a closure that returns the the value of an environment variable.
/// This method allows having a custom environment.
///
/// If ```$XDG_CACHE_HOME``` is not set, it returns ```$HOME/.cache```.
pub fn get_cache_home_from_env<F>(get_env_var: &F) -> Result<PathBuf>
    where F: Fn(&str) -> Option<OsString>
{
    get_env_path_or_default(get_env_var, "XDG_CACHE_HOME", ".cache")
}

/// Get the cache home directory.
///
/// If ```$XDG_CACHE_HOME``` is not set, it returns ```$HOME/.cache```.
pub fn get_cache_home() -> Result<PathBuf> {
    get_cache_home_from_env(&env::var_os)
}

/// Get $XDG_RUNTIME_DIR if found in the environment.
///
/// Returns None if ```$XDG_RUNTIME_PATH``` is not set, in which case it is up to the application.
/// to fallback to a location that conforms to the specification.
pub fn get_runtime_dir_from_env<F>(get_env_var: &F) -> Option<PathBuf>
    where F: Fn(&str) -> Option<OsString>
{
    get_env_path(get_env_var, "XDG_RUNTIME_DIR")
}

pub fn get_runtime_dir() -> Option<PathBuf> {
    get_runtime_dir_from_env(&env::var_os)
}

/// Check that the value set for ```$XDG_RUNTIME_DIR``` meets the requirements of the specification.
///
/// Returns Ok(true) if permissions are correct, Ok(false) if permissions are incorrect, or propogates any errors that occurred while checking permissions.
///
/// >$XDG_RUNTIME_DIR defines the base directory relative to which user-specific non-essential runtime files and other file objects (such as sockets, named pipes, ...) should be stored. The directory MUST be owned by the user, and he MUST be the only one having read and write access to it. Its Unix access mode MUST be 0700.
/// >
/// >The lifetime of the directory MUST be bound to the user being logged in. It MUST be created when the user first logs in and if the user fully logs out the directory MUST be removed. If the user logs in more than once he should get pointed to the same directory, and it is mandatory that the directory continues to exist from his first login to his last logout on the system, and not removed in between. Files in the directory MUST not survive reboot or a full logout/login cycle.
/// >
/// >The directory MUST be on a local file system and not shared with any other system. The directory MUST by fully-featured by the standards of the operating system. More specifically, on Unix-like operating systems AF_UNIX sockets, symbolic links, hard links, proper permissions, file locking, sparse files, memory mapping, file change notifications, a reliable hard link count must be supported, and no restrictions on the file name character set should be imposed. Files in this directory MAY be subjected to periodic clean-up. To ensure that your files are not removed, they should have their access time timestamp modified at least once every 6 hours of monotonic time or the 'sticky' bit should be set on the file.
#[cfg(unix)]
pub fn test_runtime_dir<P: AsRef<Path>>(path: P) -> result::Result<bool, io::Error> {
    fs::metadata(path).map(|attr| (attr.permissions().mode() == 0o700))
}

#[cfg(not(unix))]
pub fn test_runtime_dir<P: AsRef<Path>>(path: P) -> result::Result<bool, io::Error> {
    Ok(true)
}

/// Get path from environment variable's value or a default path relative to home_dir
fn get_env_path_or_default<F>(get_env_var: &F, env_var: &str, default: &str) -> Result<PathBuf>
    where F: Fn(&str) -> Option<OsString>
{
    match get_env_path(get_env_var, env_var) {
        Some(p) => Ok(p),
        None => {
            match home_dir().map(|p| p.join(default)) {
                Some(p) => Ok(p),
                None => Err(From::from(XdgError::NoHomeDir)),
            }
        }
    }
}

/// Get an environment variable's value as a PathBuf.
fn get_env_path<F>(get_env_var: &F, env_var: &str) -> Option<PathBuf>
    where F: Fn(&str) -> Option<OsString>
{
    let path = (*get_env_var)(env_var);
    let path = path.map(PathBuf::from);
    match path.iter().next() {
        Some(p) if p.is_absolute() => Some(p.clone()),
        _ => None
    }
}

fn get_env_paths_or_default<F>(get_env_var: &F, env_var: &str, default: &str) -> Vec<PathBuf>
    where F: Fn(&str) -> Option<OsString>
{
    let default_paths = OsString::from(default);

    let paths = match (*get_env_var)(env_var).iter().next() {
        Some(p) if p != "" => p.clone(),
        _ => default_paths
    };

    split_paths(&paths).collect()
}

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

    use std::collections::HashMap;
    use std::env::{self, home_dir, join_paths, split_paths};
    use std::ffi::OsString;
    use std::path::PathBuf;

    #[test]
    fn test_env_with_no_xdg_vars() {
        let mut custom_env = HashMap::new();
        custom_env.insert("dummy", "");

        let f = |var: &str| { custom_env.get(var).map(OsString::from) };

        assert!(get_data_home_from_env(&f).unwrap()   == home_dir().unwrap().join(".local/share"));
        assert!(get_data_dirs_from_env(&f)            == vec![PathBuf::from("/usr/local/share"), PathBuf::from("/usr/share")]);
        assert!(get_config_home_from_env(&f).unwrap() == home_dir().unwrap().join(".config"));
        assert!(get_config_dirs_from_env(&f)          == vec![PathBuf::from("/etc/xdg")]);
        assert!(get_cache_home_from_env(&f).unwrap()  == home_dir().unwrap().join(".cache"));
        assert!(get_runtime_dir_from_env(&f)          == None);
    }

    #[test]
    fn test_env_with_empty_xdg_vars() {
        let mut custom_env = HashMap::new();
        custom_env.insert("XDG_DATA_HOME", "");
        custom_env.insert("XDG_DATA_DIRS", "");
        custom_env.insert("XDG_CONFIG_HOME", "");
        custom_env.insert("XDG_CONFIG_DIRS", "");
        custom_env.insert("XDG_CACHE_HOME", "");

        let f = |var: &str| { custom_env.get(var).map(OsString::from) };

        assert!(get_data_home_from_env(&f).unwrap()   == home_dir().unwrap().join(".local/share"));
        assert!(get_data_dirs_from_env(&f)            == vec![PathBuf::from("/usr/local/share"), PathBuf::from("/usr/share")]);
        assert!(get_config_home_from_env(&f).unwrap() == home_dir().unwrap().join(".config"));
        assert!(get_config_dirs_from_env(&f)          == vec![PathBuf::from("/etc/xdg")]);
        assert!(get_cache_home_from_env(&f).unwrap()  == home_dir().unwrap().join(".cache"));
        assert!(get_runtime_dir_from_env(&f)          == None);
    }

    #[test]
    fn test_env_with_xdg_vars() {
        let cwd = PathBuf::from(&env::current_dir().unwrap());
        let mut custom_env = HashMap::new();

        custom_env.insert("XDG_DATA_HOME", cwd.join("user/data").into_os_string());
        custom_env.insert("XDG_DATA_DIRS", join_paths(vec![cwd.join("share/data"), cwd.join("local/data")]).unwrap());
        custom_env.insert("XDG_CONFIG_HOME", cwd.join("user/config").into_os_string());
        custom_env.insert("XDG_CONFIG_DIRS", join_paths(vec![cwd.join("config"), cwd.join("local/config")]).unwrap());
        custom_env.insert("XDG_CACHE_HOME", cwd.join("user/cache").into_os_string());

        let f = |var: &str| { custom_env.get(var).map(OsString::from) };

        assert!(get_data_home_from_env(&f).unwrap()   == custom_env.get("XDG_DATA_HOME").map(PathBuf::from).unwrap());
        assert!(get_data_dirs_from_env(&f)            == split_paths(&custom_env["XDG_DATA_DIRS"]).collect::<Vec<PathBuf>>());
        assert!(get_config_home_from_env(&f).unwrap() == custom_env.get("XDG_CONFIG_HOME").map(PathBuf::from).unwrap());
        assert!(get_config_dirs_from_env(&f)          == split_paths(&custom_env["XDG_CONFIG_DIRS"]).collect::<Vec<PathBuf>>());
        assert!(get_cache_home_from_env(&f).unwrap()  == custom_env.get("XDG_CACHE_HOME").map(PathBuf::from).unwrap());
    }
}
<commit_msg>use filter instead of match+if<commit_after>#![cfg_attr(unix, feature(fs_ext))]

//! xdg-rs is a utility library to make conforming to the [XDG specification](http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html) easier.
//!
//! Some code borrowed from [rust-xdg](https://github.com/o11c/rust-xdg). ```rust-xdg``` is
//! currently a more complete implementation of the specification. The APIs provided by
//! ```rust-xdg``` and ```xdg-rs``` are different.

pub mod error;

pub use error::*;

use std::convert::From;
use std::env::{self, home_dir, split_paths};
use std::ffi::OsString;
use std::fs;
use std::io;
use std::path::{Path, PathBuf};
use std::result;

#[cfg(unix)]
use std::os::unix::fs::PermissionsExt;

/// Get the data home directory given a closure that returns the the value of an environment variable.
/// This method allows having a custom environment.
///
/// If ```$XDG_DATA_HOME``` is not set, it returns ```$HOME/.local/share```.
pub fn get_data_home_from_env<F>(get_env_var: &F) -> Result<PathBuf>
    where F: Fn(&str) -> Option<OsString>
{
    get_env_path_or_default(get_env_var, "XDG_DATA_HOME", ".local/share")
}

/// Get the data home directory.
///
/// If ```$XDG_DATA_HOME``` is not set, it returns ```$HOME/.local/share```.
pub fn get_data_home() -> Result<PathBuf> {
    get_data_home_from_env(&env::var_os)
}

/// Get the default data directories given a closure that returns the the value of an environment variable.
/// This method allows having a custom environment.
///
/// If ```$XDG_DATA_DIRS``` is not set, it returns ```[/usr/local/share, /usr/share]```.
pub fn get_data_dirs_from_env<F>(get_env_var: &F) -> Vec<PathBuf>
    where F: Fn(&str) -> Option<OsString>
{
    get_env_paths_or_default(get_env_var, "XDG_DATA_DIRS", "/usr/local/share:/usr/share")
}

/// Get the data directories.
///
/// If ```$XDG_DATA_DIRS``` is not set, it returns ```[/usr/local/share, /usr/share]```.
pub fn get_data_dirs() -> Vec<PathBuf> {
    get_data_dirs_from_env(&env::var_os)
}

/// Get the config home directory given a closure that returns the the value of an environment variable.
/// This method allows having a custom environment.
///
/// If ```$XDG_CONFIG_HOME``` is not set, it returns ```$HOME/.config```.
pub fn get_config_home_from_env<F>(get_env_var: &F) -> Result<PathBuf>
    where F: Fn(&str) -> Option<OsString>
{
    get_env_path_or_default(get_env_var, "XDG_CONFIG_HOME", ".config")
}
/// Get the config home directory.
///
/// If ```$XDG_CONFIG_HOME``` is not set, it returns ```$HOME/.config```.
pub fn get_config_home() -> Result<PathBuf> {
    get_config_home_from_env(&env::var_os)
}

/// Get the default config directories given a closure that returns the the value of an environment variable.
/// This method allows having a custom environment.
///
/// If ```$XDG_CONFIG_DIRS``` is not set, it returns ```[/etc/xdg]```.
pub fn get_config_dirs_from_env<F>(get_env_var: &F) -> Vec<PathBuf>
    where F: Fn(&str) -> Option<OsString>
{
    get_env_paths_or_default(get_env_var, "XDG_CONFIG_DIRS", "/etc/xdg")
}

/// Get the config directories.
///
/// If ```$XDG_CONFIG_DIRS``` is not set, it returns ```[/etc/xdg]```.
pub fn get_config_dirs() -> Vec<PathBuf> {
    get_config_dirs_from_env(&env::var_os)
}

/// Get the cache home directory given a closure that returns the the value of an environment variable.
/// This method allows having a custom environment.
///
/// If ```$XDG_CACHE_HOME``` is not set, it returns ```$HOME/.cache```.
pub fn get_cache_home_from_env<F>(get_env_var: &F) -> Result<PathBuf>
    where F: Fn(&str) -> Option<OsString>
{
    get_env_path_or_default(get_env_var, "XDG_CACHE_HOME", ".cache")
}

/// Get the cache home directory.
///
/// If ```$XDG_CACHE_HOME``` is not set, it returns ```$HOME/.cache```.
pub fn get_cache_home() -> Result<PathBuf> {
    get_cache_home_from_env(&env::var_os)
}

/// Get $XDG_RUNTIME_DIR if found in the environment.
///
/// Returns None if ```$XDG_RUNTIME_PATH``` is not set, in which case it is up to the application.
/// to fallback to a location that conforms to the specification.
pub fn get_runtime_dir_from_env<F>(get_env_var: &F) -> Option<PathBuf>
    where F: Fn(&str) -> Option<OsString>
{
    get_env_path(get_env_var, "XDG_RUNTIME_DIR")
}

pub fn get_runtime_dir() -> Option<PathBuf> {
    get_runtime_dir_from_env(&env::var_os)
}

/// Check that the value set for ```$XDG_RUNTIME_DIR``` meets the requirements of the specification.
///
/// Returns Ok(true) if permissions are correct, Ok(false) if permissions are incorrect, or propogates any errors that occurred while checking permissions.
///
/// >$XDG_RUNTIME_DIR defines the base directory relative to which user-specific non-essential runtime files and other file objects (such as sockets, named pipes, ...) should be stored. The directory MUST be owned by the user, and he MUST be the only one having read and write access to it. Its Unix access mode MUST be 0700.
/// >
/// >The lifetime of the directory MUST be bound to the user being logged in. It MUST be created when the user first logs in and if the user fully logs out the directory MUST be removed. If the user logs in more than once he should get pointed to the same directory, and it is mandatory that the directory continues to exist from his first login to his last logout on the system, and not removed in between. Files in the directory MUST not survive reboot or a full logout/login cycle.
/// >
/// >The directory MUST be on a local file system and not shared with any other system. The directory MUST by fully-featured by the standards of the operating system. More specifically, on Unix-like operating systems AF_UNIX sockets, symbolic links, hard links, proper permissions, file locking, sparse files, memory mapping, file change notifications, a reliable hard link count must be supported, and no restrictions on the file name character set should be imposed. Files in this directory MAY be subjected to periodic clean-up. To ensure that your files are not removed, they should have their access time timestamp modified at least once every 6 hours of monotonic time or the 'sticky' bit should be set on the file.
#[cfg(unix)]
pub fn test_runtime_dir<P: AsRef<Path>>(path: P) -> result::Result<bool, io::Error> {
    fs::metadata(path).map(|attr| (attr.permissions().mode() == 0o700))
}

#[cfg(not(unix))]
pub fn test_runtime_dir<P: AsRef<Path>>(path: P) -> result::Result<bool, io::Error> {
    Ok(true)
}

/// Get path from environment variable's value or a default path relative to home_dir
fn get_env_path_or_default<F>(get_env_var: &F, env_var: &str, default: &str) -> Result<PathBuf>
    where F: Fn(&str) -> Option<OsString>
{
    match get_env_path(get_env_var, env_var) {
        Some(p) => Ok(p),
        None => {
            match home_dir().map(|p| p.join(default)) {
                Some(p) => Ok(p),
                None => Err(From::from(XdgError::NoHomeDir)),
            }
        }
    }
}

/// Get an environment variable's value as a PathBuf.
fn get_env_path<F>(get_env_var: &F, env_var: &str) -> Option<PathBuf>
    where F: Fn(&str) -> Option<OsString>
{
    (*get_env_var)(env_var)
        .map(PathBuf::from)
        .into_iter()
        .filter(|x| x.is_absolute())
        .next()
}

fn get_env_paths_or_default<F>(get_env_var: &F, env_var: &str, default: &str) -> Vec<PathBuf>
    where F: Fn(&str) -> Option<OsString>
{
    let path_string = (*get_env_var)(env_var)
        .into_iter()
        .filter(|x| x != "")
        .next()
        .unwrap_or(OsString::from(default));

    split_paths(&path_string).collect()
}

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

    use std::collections::HashMap;
    use std::env::{self, home_dir, join_paths, split_paths};
    use std::ffi::OsString;
    use std::path::PathBuf;

    #[test]
    fn test_env_with_no_xdg_vars() {
        let mut custom_env = HashMap::new();
        custom_env.insert("dummy", "");

        let f = |var: &str| { custom_env.get(var).map(OsString::from) };

        assert!(get_data_home_from_env(&f).unwrap()   == home_dir().unwrap().join(".local/share"));
        assert!(get_data_dirs_from_env(&f)            == vec![PathBuf::from("/usr/local/share"), PathBuf::from("/usr/share")]);
        assert!(get_config_home_from_env(&f).unwrap() == home_dir().unwrap().join(".config"));
        assert!(get_config_dirs_from_env(&f)          == vec![PathBuf::from("/etc/xdg")]);
        assert!(get_cache_home_from_env(&f).unwrap()  == home_dir().unwrap().join(".cache"));
        assert!(get_runtime_dir_from_env(&f)          == None);
    }

    #[test]
    fn test_env_with_empty_xdg_vars() {
        let mut custom_env = HashMap::new();
        custom_env.insert("XDG_DATA_HOME", "");
        custom_env.insert("XDG_DATA_DIRS", "");
        custom_env.insert("XDG_CONFIG_HOME", "");
        custom_env.insert("XDG_CONFIG_DIRS", "");
        custom_env.insert("XDG_CACHE_HOME", "");

        let f = |var: &str| { custom_env.get(var).map(OsString::from) };

        assert!(get_data_home_from_env(&f).unwrap()   == home_dir().unwrap().join(".local/share"));
        assert!(get_data_dirs_from_env(&f)            == vec![PathBuf::from("/usr/local/share"), PathBuf::from("/usr/share")]);
        assert!(get_config_home_from_env(&f).unwrap() == home_dir().unwrap().join(".config"));
        assert!(get_config_dirs_from_env(&f)          == vec![PathBuf::from("/etc/xdg")]);
        assert!(get_cache_home_from_env(&f).unwrap()  == home_dir().unwrap().join(".cache"));
        assert!(get_runtime_dir_from_env(&f)          == None);
    }

    #[test]
    fn test_env_with_xdg_vars() {
        let cwd = PathBuf::from(&env::current_dir().unwrap());
        let mut custom_env = HashMap::new();

        custom_env.insert("XDG_DATA_HOME", cwd.join("user/data").into_os_string());
        custom_env.insert("XDG_DATA_DIRS", join_paths(vec![cwd.join("share/data"), cwd.join("local/data")]).unwrap());
        custom_env.insert("XDG_CONFIG_HOME", cwd.join("user/config").into_os_string());
        custom_env.insert("XDG_CONFIG_DIRS", join_paths(vec![cwd.join("config"), cwd.join("local/config")]).unwrap());
        custom_env.insert("XDG_CACHE_HOME", cwd.join("user/cache").into_os_string());

        let f = |var: &str| { custom_env.get(var).map(OsString::from) };

        assert!(get_data_home_from_env(&f).unwrap()   == custom_env.get("XDG_DATA_HOME").map(PathBuf::from).unwrap());
        assert!(get_data_dirs_from_env(&f)            == split_paths(&custom_env["XDG_DATA_DIRS"]).collect::<Vec<PathBuf>>());
        assert!(get_config_home_from_env(&f).unwrap() == custom_env.get("XDG_CONFIG_HOME").map(PathBuf::from).unwrap());
        assert!(get_config_dirs_from_env(&f)          == split_paths(&custom_env["XDG_CONFIG_DIRS"]).collect::<Vec<PathBuf>>());
        assert!(get_cache_home_from_env(&f).unwrap()  == custom_env.get("XDG_CACHE_HOME").map(PathBuf::from).unwrap());
    }
}
<|endoftext|>


<commit_before>#[crate_id = "fragments#0.1-pre"];

#[comment = "A simple template library for Rust"];
#[license = "MIT"];
#[crate_type = "lib"];
#[crate_type = "rlib"];

extern crate collections;

use std::fmt::Show;
use std::from_str::FromStr;
use collections::hashmap::HashMap;

#[deriving(Eq, TotalEq)]
enum Token {
	String(~str),
	Placeholder(~str)
}

pub struct Template<'a> {
	content: ~HashMap<~str, &'a Show>,
	priv tokens: ~[Token]
}

impl<'a> FromStr for Template<'a> {
	fn from_str(s: &str) -> Option<Template> {
		let mut tokens = ~[];
		let mut current_token = ~"";
		let mut is_placeholder = false;

		let mut chars = s.chars();

		loop {
			match chars.next() {
				Some('[') => {
					if !is_placeholder {
						match chars.next() {
							Some('[') => {
								tokens.push(String(current_token));
								current_token = ~"";
								is_placeholder = true;
							},
							Some(c) => {
								current_token.push_char('[');
								current_token.push_char(c);
							},
							None => current_token.push_char('[')
						}
					} else {
						current_token.push_char('[')
					}
				},
				Some(']') => {
					if is_placeholder {
						match chars.next() {
							Some(']') => {
								tokens.push(Placeholder(current_token));
								current_token = ~"";
								is_placeholder = false;
							},
							Some(c) => {
								current_token.push_char(']');
								current_token.push_char(c);
							},
							None => current_token.push_char(']')
						}
					} else {
						current_token.push_char(']')
					}
				},
				Some(c) => current_token.push_char(c),
				None => break
			}
		}

		if is_placeholder {
			tokens.push(Placeholder(current_token));
		} else {
			tokens.push(String(current_token));
		}

		Some(Template {
			content: ~HashMap::new(),
			tokens: tokens
		})
	}
}

#[cfg(test)]
mod test {
	use super::{Template, Placeholder, String};

	#[test]
	fn basic_tokens() {
		let template: Template = from_str("Hello, [[name]]! This is a [[something]] template.").unwrap();
		assert_eq!(template.tokens[0], String(~"Hello, "));
		assert_eq!(template.tokens[1], Placeholder(~"name"));
		assert_eq!(template.tokens[2], String(~"! This is a "));
		assert_eq!(template.tokens[3], Placeholder(~"something"));
		assert_eq!(template.tokens[4], String(~" template."));
	}

	#[test]
	fn strange_tokens() {
		let template: Template = from_str("Hello, [[[name]]]! This is a [[[[something]] template.").unwrap();
		assert_eq!(template.tokens[0], String(~"Hello, "));
		assert_eq!(template.tokens[1], Placeholder(~"[name"));
		assert_eq!(template.tokens[2], String(~"]! This is a "));
		assert_eq!(template.tokens[3], Placeholder(~"[[something"));
		assert_eq!(template.tokens[4], String(~" template."));
	}
}<commit_msg>Using a buffer to pare the template string<commit_after>#[crate_id = "fragments#0.1-pre"];

#[comment = "A simple template library for Rust"];
#[license = "MIT"];
#[crate_type = "lib"];
#[crate_type = "rlib"];

extern crate collections;

use std::fmt::Show;
use std::from_str::FromStr;
use std::io::BufReader;
use collections::hashmap::HashMap;

#[deriving(Eq, TotalEq)]
enum Token {
	String(~str),
	Placeholder(~str)
}

pub struct Template<'a> {
	content: ~HashMap<~str, &'a Show>,
	priv tokens: ~[Token]
}

impl<'a> Template<'a> {
	pub fn from_buffer(b: &mut Buffer) -> Template {
		let mut tokens = ~[];
		let mut current_token = ~"";
		let mut is_placeholder = false;

		loop {
			match b.read_char() {
				Ok('[') => {
					if !is_placeholder {
						match b.read_char() {
							Ok('[') => {
								tokens.push(String(current_token));
								current_token = ~"";
								is_placeholder = true;
							},
							Ok(c) => {
								current_token.push_char('[');
								current_token.push_char(c);
							},
							Err(_) => current_token.push_char('[')
						}
					} else {
						current_token.push_char('[')
					}
				},
				Ok(']') => {
					if is_placeholder {
						match b.read_char() {
							Ok(']') => {
								tokens.push(Placeholder(current_token));
								current_token = ~"";
								is_placeholder = false;
							},
							Ok(c) => {
								current_token.push_char(']');
								current_token.push_char(c);
							},
							Err(_) => current_token.push_char(']')
						}
					} else {
						current_token.push_char(']')
					}
				},
				Ok(c) => current_token.push_char(c),
				Err(_) => break
			}
		}

		if is_placeholder {
			tokens.push(Placeholder(current_token));
		} else {
			tokens.push(String(current_token));
		}

		Template {
			content: ~HashMap::new(),
			tokens: tokens
		}
	}
}

impl<'a> FromStr for Template<'a> {
	fn from_str(s: &str) -> Option<Template> {
		Some(Template::from_buffer(&mut BufReader::new(s.as_bytes())))
	}
}

#[cfg(test)]
mod test {
	use super::{Template, Placeholder, String};

	#[test]
	fn basic_tokens() {
		let template: Template = from_str("Hello, [[name]]! This is a [[something]] template.").unwrap();
		assert_eq!(template.tokens[0], String(~"Hello, "));
		assert_eq!(template.tokens[1], Placeholder(~"name"));
		assert_eq!(template.tokens[2], String(~"! This is a "));
		assert_eq!(template.tokens[3], Placeholder(~"something"));
		assert_eq!(template.tokens[4], String(~" template."));
	}

	#[test]
	fn strange_tokens() {
		let template: Template = from_str("Hello, [[[name]]]! This is a [[[[something]] template.").unwrap();
		assert_eq!(template.tokens[0], String(~"Hello, "));
		assert_eq!(template.tokens[1], Placeholder(~"[name"));
		assert_eq!(template.tokens[2], String(~"]! This is a "));
		assert_eq!(template.tokens[3], Placeholder(~"[[something"));
		assert_eq!(template.tokens[4], String(~" template."));
	}
}<|endoftext|>


<commit_before>extern crate rustc_serialize;
extern crate websocket;

use std::io::Write;
use std::io::Read;
use rustc_serialize::json::Json;
use rustc_serialize::json;
use websocket::Message;
use websocket::client::request::Url;
use websocket::dataframe::DataFrame;
use websocket::client::sender::Sender;
use websocket::client::receiver::Receiver;
use websocket::stream::WebSocketStream;
use websocket::result::WebSocketError;

pub use websocket::result::WebSocketResult;

mod requests;
mod responses;

use responses::*;
use requests::*;

type Client = websocket::Client<DataFrame, Sender<WebSocketStream>, Receiver<WebSocketStream>>;

fn handshake(url: &Url) -> WebSocketResult<Client> {
    // Handshake with the server
    let knock  = try!( Client::connect(url) );
    let answer = try!( knock.send() );
    try!( answer.validate() );

    // Get referennce to the client
    Ok(answer.begin())
}

fn negotiate(client: &mut Client, version: &str) -> WebSocketResult<NegotiateResp> {
    let request = requests::Connect::new(version);
    let request = Message::Text(request.to_json());

    try!( client.send_message(request) );

    for msg_result in client.incoming_messages::<Message>() {
        if let Ok(Message::Text(plaintext)) = msg_result {
            if let Ok(success) = json::decode::<VersionSuccess>(&plaintext) {
                if success.msg == "connected" {
                    return Ok(NegotiateResp::SessionId(success.session));
                }
            } else if let Ok(failure) = json::decode::<VersionFailed>(&plaintext) {
                if failure.msg == "failed" {
                    return Ok(NegotiateResp::Version(failure.version));
                }
            }
        }
    }
    Err(WebSocketError::ResponseError("No protocol version reply from the server.".to_string()))
}

pub enum NegotiateResp {
    SessionId(String),
    Version(String),
}

fn connect(url: &Url) -> WebSocketResult<(Client, String)> {
    let mut client = try!( handshake(url) );
    let mut curr_version = VER_NOW;

    loop {
        match negotiate(&mut client, curr_version) {
            Err(e) => return Err(e),
            Ok(NegotiateResp::SessionId(session)) => return Ok((client, session)),
            Ok(NegotiateResp::Version(version))   => {
                if let Some(v) = VERSIONS.iter().find(|&v| *v == version) {
                    curr_version = v;
                } else {
                    return Err(WebSocketError::ResponseError("No matching version.".to_string()));
                }
            },
        };
    }
}

#[test]
fn it_works() {

    let url = Url::parse("ws://127.0.0.1:3000/websocket").unwrap(); // Get the URL
    // assert_eq!("{:?}", format!("{:?}", request));

    if let Ok((client, session_id)) = connect(&url) {
        println!("The session id is: {}", session_id);
    }

    // let request = Client::connect(url).ok().expect("Could not connect"); // Connect to the server
    // let response = request.send().ok().expect("Could not send response."); // Send the request
    //
    //
    // response.validate().ok().expect("response is not valid!!"); // Ensure the response is valid
    //
    // let mut client = response.begin(); // Get a Client
    // let body = "{
    //     \"msg\":     \"connect\",
    //     \"version\": \"1\",
    //     \"support\": [\"1\", \"pre2\", \"pre1\"]
    // }".to_string();
    //
    // let message = Message::Text(body);
    // client.send_message(message).ok().unwrap(); // Send message
    //
    // for message in client.incoming_messages::<Message>() {
    //
    //     let json_text = match message.ok().unwrap() {
    //         Message::Text(plain) => plain,
    //         _ => unreachable!(),
    //     };
    //
    //     let json = Json::from_str(&json_text);
    //
    //     let object = match json.ok().unwrap() {
    //         Json::Object(o) => o,
    //         _ => unreachable!(),
    //     };
    //
    //     let message = match object.get("msg") {
    //         Some(m) => match m.clone() {
    //                         Json::String(s) => s,
    //                         _ => unreachable!(),
    //                    },
    //         None    => "No Message".to_string(),
    //     };
    //
    //     println!("The message was: {}", message);
    // }
}
<commit_msg>Made into a struct, added error enums<commit_after>extern crate rustc_serialize;
extern crate websocket;

use rustc_serialize::json;
use rustc_serialize::Encodable;
use websocket::Message;
use websocket::client::request::Url;
use websocket::dataframe::DataFrame;
use websocket::client::sender::Sender;
use websocket::client::receiver::Receiver;
use websocket::stream::WebSocketStream;
use websocket::result::WebSocketError;

pub use websocket::result::WebSocketResult;

mod requests;
mod responses;

use responses::*;
use requests::*;

type Client = websocket::Client<DataFrame, Sender<WebSocketStream>, Receiver<WebSocketStream>>;

pub struct DdpClient {
    client: Client,
    session_id: String,
    version: &'static str,
}

impl DdpClient {
    pub fn new(url: &Url) -> Result<Self, DdpConnError> {
        let (client, session_id, v_index) = try!( DdpClient::connect(url) );
        Ok(DdpClient {
            client:     client,
            session_id: session_id,
            version:    VERSIONS[v_index],
        })
    }

    fn handshake(url: &Url) -> Result<Client, DdpConnError> {
        // Handshake with the server
        let knock  = try!( Client::connect(url).map_err(|e| DdpConnError::Network(e)) );
        let answer = try!( knock.send()        .map_err(|e| DdpConnError::Network(e)) );
        try!( answer.validate()                .map_err(|e| DdpConnError::Network(e)) );

        // Get referennce to the client
        Ok(answer.begin())
    }

    fn negotiate(client: &mut Client, version: &str) -> Result<NegotiateResp, DdpConnError> {
        let request = requests::Connect::new(version);
        let request = Message::Text(request.to_json());

        try!( client.send_message(request).map_err(|e| DdpConnError::Network(e)) );

        for msg_result in client.incoming_messages::<Message>() {
            if let Ok(Message::Text(plaintext)) = msg_result {
                if let Ok(success) = json::decode::<VersionSuccess>(&plaintext) {
                    if success.msg == "connected" {
                        return Ok(NegotiateResp::SessionId(success.session));
                    }
                } else if let Ok(failure) = json::decode::<VersionFailed>(&plaintext) {
                    if failure.msg == "failed" {
                        return Ok(NegotiateResp::Version(failure.version));
                    }
                }
            }
        }
        Err(DdpConnError::NoVersionFromServer)
    }

    fn connect(url: &Url) -> Result<(Client, String, usize), DdpConnError> {
        let mut client = try!( DdpClient::handshake(url) );
        let mut version = VER_NOW;
        let mut v_index = 0;

        loop {
            match DdpClient::negotiate(&mut client, version) {
                Err(e) => return Err(e),
                Ok(NegotiateResp::SessionId(session)) => return Ok((client, session, v_index)),
                Ok(NegotiateResp::Version(server_version))   => {
                    // TODO: Maybe this should be faster, maybe its enough.
                    let found = VERSIONS.iter().enumerate().find(|&(_, &v)| *v == server_version);
                    if let Some((i, &v)) = found {
                        v_index = i;
                        version = v;
                    } else {
                        return Err(DdpConnError::NoMatchingVersion);
                    }
                },
            };
        }
    }

    pub fn send_raw<E>(&mut self, message: &E) where E: Encodable {
        // TODO: Unsafe
        let message = json::encode(message).unwrap();
        let message = Message::Text(message);
        self.client.send_message(message).ok();
    }

    pub fn session(&self) -> &str {
        &self.session_id
    }

    pub fn version(&self) -> &str {
        &self.version
    }
}

pub enum NegotiateResp {
    SessionId(String),
    Version(String),
}

#[derive(Debug)]
pub enum DdpConnError {
    Network(WebSocketError),
    NoVersionFromServer,
    NoMatchingVersion,
}

#[test]
fn test_connect_version() {
    let url = Url::parse("ws://127.0.0.1:3000/websocket").unwrap(); // Get the URL

    let ddp_client_result = DdpClient::new(&url);

    match ddp_client_result {
        Ok(client) => println!("The session id is: {} with DDP v{}", client.session(), client.version()),
        Err(err)   => panic!("An error occured: {:?}", err),
    };
}
<|endoftext|>


<commit_before>#[test]
fn it_works() {
}
<commit_msg>api: initial gpio apis for review<commit_after>// Copyright 2015, Paul Osborne <osbpau@gmail.com>
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/license/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.

//! Generic Interface for GPIOs Across Many Systems
//!
//! This crate provides a set of core traits and related types
//! for accessing GPIOs across a variety of systems.  The goal
//! is that devices may be written depending on these traits
//! and consequently be portable to various systems.

#![crate_type = "lib"]
#![crate_name = "gpio"]

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

#[cfg(test)]
#[macro_use] extern crate std;

// TODO: seperate input/outputs/both from each other via traits?

#[derive(Copy, Clone)]
pub enum Error {
    /// The GPIO was configured as an input but an output action was attempted
    IllegalOperationOnInput,
    /// The GPIO was configured as an output but an input action was attempted
    IllegalOperationOnOutput,
    /// Some other error occurred
    Other(&'static str),
}

pub type Result<T> = core::result::Result<T, Error>;

/// The direction of a GPIO Pin
#[derive(Copy, Clone)]
pub enum Direction {
    /// The pin is an input
    In,
    /// The pin is an output
    Out,
}

/// The logic level of a GPIO Pin
#[derive(Copy, Clone, PartialEq)]
#[repr(u8)]
pub enum Level {
    /// Logic low
    Low,
    /// Logic high
    High,
}

/// Generic trait providing access to a single GPIO
pub trait Gpio {
    /// Get the currently configured direciton of this GPIO
    fn get_direction(&mut self) -> Result<Direction>;
    /// Set the pin to be an input
    fn set_input(&mut self) -> Result<()>;
    /// Set the pin to be an output with the provided level
    fn set_output(&mut self, value: Level) -> Result<()>;
    /// Get the current level of this GPIO (input only)
    fn get_level(&mut self) -> Result<Level>;
    /// Set the current level of this GPIO (output only)
    fn set_level(&mut self, value: Level) -> Result<()>;
}
<|endoftext|>


<commit_before>//! Nom, eating data byte by byte
//!
//! The goal is to make a parser combinator library that is safe,
//! supports streaming (push and pull), and as much as possible zero copy.
//!
//! The code is available on [Github](https://github.com/Geal/nom)
//!
//! # Example
//!
//! ```
//! #[macro_use]
//! extern crate nom;
//!
//! use nom::{IResult,digit,multispace};
//! use nom::IResult::*;
//!
//! // Parser definition
//!
//! use std::str;
//! use std::str::FromStr;
//!
//! named!(parens<i64>, delimited!(
//!     delimited!(opt!(multispace), tag!("("), opt!(multispace)),
//!     expr,
//!     delimited!(opt!(multispace), tag!(")"), opt!(multispace))
//!   )
//! );

//! named!(factor<i64>,
//!   alt!(
//!     map_res!(
//!       map_res!(
//!         delimited!(opt!(multispace), digit, opt!(multispace)),
//!         str::from_utf8
//!       ),
//!       FromStr::from_str
//!     )
//!   | parens
//!   )
//! );
//!
//! named!(term <i64>,
//!   chain!(
//!     mut acc: factor  ~
//!              many0!(
//!                alt!(
//!                  tap!(mul: preceded!(tag!("*"), factor) => acc = acc * mul) |
//!                  tap!(div: preceded!(tag!("/"), factor) => acc = acc / div)
//!                )
//!              ),
//!     || { return acc }
//!   )
//! );
//!
//! named!(expr <i64>,
//!   chain!(
//!     mut acc: term  ~
//!              many0!(
//!                alt!(
//!                  tap!(add: preceded!(tag!("+"), term) => acc = acc + add) |
//!                  tap!(sub: preceded!(tag!("-"), term) => acc = acc - sub)
//!                )
//!              ),
//!     || { return acc }
//!   )
//! );
//!
//! fn main() {
//!   assert_eq!(expr(&b" 1 +  2 "[..]),             IResult::Done(&b""[..], 3));
//!   assert_eq!(expr(&b" 12 + 6 - 4+  3"[..]),      IResult::Done(&b""[..], 17));
//!   assert_eq!(expr(&b" 1 + 2*3 + 4"[..]),         IResult::Done(&b""[..], 11));
//!
//!   assert_eq!(expr(&b" (  2 )"[..]),              IResult::Done(&b""[..], 2));
//!   assert_eq!(expr(&b" 2* (  3 + 4 ) "[..]),      IResult::Done(&b""[..], 14));
//!   assert_eq!(expr(&b"  2*2 / ( 5 - 1) + 3"[..]), IResult::Done(&b""[..], 4));
//! }
//! ```

#![cfg_attr(feature = "core", feature(no_std))]
#![cfg_attr(feature = "core", feature(core))]
#![cfg_attr(feature = "core", feature(collections))]
#![cfg_attr(feature = "core", no_std)]

#[macro_use]
#[cfg(feature = "core")]
extern crate core;
#[cfg(feature = "core")]
extern crate collections;

#[cfg(feature = "core")]
mod std {
#[macro_use]
  pub use core::{fmt, iter, option, ops, slice, mem};
  pub use collections::{boxed, vec, string};
  pub mod prelude {
    pub use core::prelude as v1;
  }
}

pub use self::util::*;
pub use self::internal::*;//{IResult, IResultClosure, GetInput, GetOutput};
pub use self::macros::*;
pub use self::accumulator::*;
#[cfg(not(feature = "core"))]
pub use self::producer::*;//{ProducerState,Producer,FileProducer,MemProducer};
#[cfg(not(feature = "core"))]
pub use self::consumer::*;//{ConsumerState,Consumer};

pub use self::nom::*;

#[macro_use] mod util;
mod internal;
#[macro_use] mod macros;
#[macro_use] mod accumulator;

#[macro_use]
#[cfg(not(feature = "core"))]
mod producer;
#[cfg(not(feature = "core"))]
mod consumer;

#[macro_use] mod nom;

<commit_msg>more info on arithmetic parser<commit_after>//! Nom, eating data byte by byte
//!
//! The goal is to make a parser combinator library that is safe,
//! supports streaming (push and pull), and as much as possible zero copy.
//!
//! The code is available on [Github](https://github.com/Geal/nom)
//!
//! # Example
//!
//! ```
//! #[macro_use]
//! extern crate nom;
//!
//! use nom::{IResult,digit,multispace};
//! use nom::IResult::*;
//!
//! // Parser definition
//!
//! use std::str;
//! use std::str::FromStr;
//!
//! named!(parens<i64>, delimited!(
//!     delimited!(opt!(multispace), tag!("("), opt!(multispace)),
//!     expr,
//!     delimited!(opt!(multispace), tag!(")"), opt!(multispace))
//!   )
//! );
//!
//! // We transform an integer string into a i64
//! // we look for a digit suite, and try to convert it.
//! // if either str::from_utf8 or FromStr::from_str fail,
//! // the parser will fail
//! named!(factor<i64>,
//!   alt!(
//!     map_res!(
//!       map_res!(
//!         delimited!(opt!(multispace), digit, opt!(multispace)),
//!         str::from_utf8
//!       ),
//!       FromStr::from_str
//!     )
//!   | parens
//!   )
//! );
//!
//! // we define acc as mutable to update its value whenever a new term is found
//! named!(term <i64>,
//!   chain!(
//!     mut acc: factor  ~
//!              many0!(
//!                alt!(
//!                  tap!(mul: preceded!(tag!("*"), factor) => acc = acc * mul) |
//!                  tap!(div: preceded!(tag!("/"), factor) => acc = acc / div)
//!                )
//!              ),
//!     || { return acc }
//!   )
//! );
//!
//! named!(expr <i64>,
//!   chain!(
//!     mut acc: term  ~
//!              many0!(
//!                alt!(
//!                  tap!(add: preceded!(tag!("+"), term) => acc = acc + add) |
//!                  tap!(sub: preceded!(tag!("-"), term) => acc = acc - sub)
//!                )
//!              ),
//!     || { return acc }
//!   )
//! );
//!
//! fn main() {
//!   assert_eq!(expr(&b" 1 +  2 "[..]),             IResult::Done(&b""[..], 3));
//!   assert_eq!(expr(&b" 12 + 6 - 4+  3"[..]),      IResult::Done(&b""[..], 17));
//!   assert_eq!(expr(&b" 1 + 2*3 + 4"[..]),         IResult::Done(&b""[..], 11));
//!
//!   assert_eq!(expr(&b" (  2 )"[..]),              IResult::Done(&b""[..], 2));
//!   assert_eq!(expr(&b" 2* (  3 + 4 ) "[..]),      IResult::Done(&b""[..], 14));
//!   assert_eq!(expr(&b"  2*2 / ( 5 - 1) + 3"[..]), IResult::Done(&b""[..], 4));
//! }
//! ```

#![cfg_attr(feature = "core", feature(no_std))]
#![cfg_attr(feature = "core", feature(core))]
#![cfg_attr(feature = "core", feature(collections))]
#![cfg_attr(feature = "core", no_std)]

#[macro_use]
#[cfg(feature = "core")]
extern crate core;
#[cfg(feature = "core")]
extern crate collections;

#[cfg(feature = "core")]
mod std {
#[macro_use]
  pub use core::{fmt, iter, option, ops, slice, mem};
  pub use collections::{boxed, vec, string};
  pub mod prelude {
    pub use core::prelude as v1;
  }
}

pub use self::util::*;
pub use self::internal::*;//{IResult, IResultClosure, GetInput, GetOutput};
pub use self::macros::*;
pub use self::accumulator::*;
#[cfg(not(feature = "core"))]
pub use self::producer::*;//{ProducerState,Producer,FileProducer,MemProducer};
#[cfg(not(feature = "core"))]
pub use self::consumer::*;//{ConsumerState,Consumer};

pub use self::nom::*;

#[macro_use] mod util;
mod internal;
#[macro_use] mod macros;
#[macro_use] mod accumulator;

#[macro_use]
#[cfg(not(feature = "core"))]
mod producer;
#[cfg(not(feature = "core"))]
mod consumer;

#[macro_use] mod nom;

<|endoftext|>


<commit_before>extern crate libc;

use std::os::raw;
use std::ffi::CString;
use std::mem::{transmute, size_of};

#[link(name = "kleeRuntest")]
extern {
    fn klee_make_symbolic(data: *const raw::c_void, length: libc::size_t, name: *const raw::c_char);
    fn klee_set_forking(state: bool);
}

pub unsafe fn any(data: *const raw::c_void, length: usize, name: &str) {
    klee_make_symbolic(data, length as libc::size_t, CString::new(name).unwrap().as_ptr());
}

pub fn set_forking(state: bool) {
    unsafe { klee_set_forking(state); }
}

pub fn some<T>(initial: T, name: &str) -> T {
    let new_symbol = initial;
    symbol(&new_symbol, name);
    return new_symbol;
}

pub fn symbol<T>(data: &T, name: &str) {
    unsafe{ any(transmute(data as *const T), size_of::<T>(), name); }
}
<commit_msg>Update lib.rs<commit_after>extern crate libc;

use std::os::raw;
use std::ffi::CString;
use std::mem::{transmute, size_of};

#[link(name = "kleeRuntest")]
extern {
    fn klee_make_symbolic(data: *const raw::c_void, length: libc::size_t, name: *const raw::c_char);
    fn klee_set_forking(state: bool);
}

pub unsafe fn any(data: *const raw::c_void, length: usize, name: &str) {
    klee_make_symbolic(data, length as libc::size_t, CString::new(name).unwrap().as_ptr());
}

pub fn set_forking(state: bool) {
    unsafe { klee_set_forking(state); }
}

pub fn some<T>(name: &str) -> T {
    let new_symbol : T;
    symbol(&new_symbol, name);
    return new_symbol;
}

pub fn symbol<T>(data: &T, name: &str) {
    unsafe{ any(transmute(data as *const T), size_of::<T>(), name); }
}
<|endoftext|>


<commit_before>#![deny(missing_docs)]

//! A GLFW window back-end for the Piston game engine.

extern crate glfw;
extern crate collections;
extern crate gl;
extern crate window;
extern crate shader_version;
extern crate input;
extern crate current;

// External crates.
use current::{ Get, Modifier };
use collections::RingBuf;
use glfw::Context;
use input::{
    keyboard,
    mouse,
    InputEvent,
};
use window::{
    Window,
    WindowSettings,
    ShouldClose, Size, PollEvent, SwapBuffers,
    CaptureCursor, DrawSize, Title, SetTitle,
    ExitOnEsc
};
use shader_version::opengl::OpenGL;

/// Contains stuff for game window.
pub struct GlfwWindow {
    /// The window.
    pub window: glfw::Window,
    /// Receives events from window.
    events: Receiver<(f64, glfw::WindowEvent)>,
    /// GLFW context.
    pub glfw: glfw::Glfw,
    event_queue: RingBuf<input::InputEvent>,
    // Used to compute relative mouse movement.
    last_mouse_pos: Option<(f64, f64)>,
    // The back-end does not remember the title.
    title: String,
    exit_on_esc: bool,
}

#[test]
fn test_glfw_window() {
    fn foo<T: Window>() {}

    foo::<GlfwWindow>();
}

impl GlfwWindow {
    /// Create a new game window from an existing GLFW window.
    pub fn from_pieces(win: glfw::Window, glfw: glfw::Glfw,
                       events: Receiver<(f64, glfw::WindowEvent)>,
                       exit_on_esc: bool) -> GlfwWindow {
        win.set_all_polling(true);
        win.make_current();
        let title = "<unknown window title, created from_pieces>";
        GlfwWindow {
            window: win,
            events: events,
            glfw: glfw,
            exit_on_esc: exit_on_esc,
            event_queue: RingBuf::new(),
            last_mouse_pos: None,
            title: title.to_string(),
        }
    }

    /// Creates a new game window for GLFW.
    pub fn new(opengl: OpenGL, settings: WindowSettings) -> GlfwWindow {
        use glfw::Context;

        // Initialize GLFW.
        let glfw = glfw::init(glfw::FAIL_ON_ERRORS).unwrap();

        let (major, minor) = opengl.get_major_minor();

        // Make sure we have the right GL version.
        glfw.window_hint(glfw::ContextVersion(major as u32, minor as u32));
        glfw.window_hint(glfw::OpenglForwardCompat(true));
        glfw.window_hint(glfw::OpenglProfile(glfw::OpenGlCoreProfile));
        glfw.window_hint(glfw::Samples(settings.samples as u32));

        // Create GLFW window.
        let (window, events) = glfw.create_window(
            settings.size[0],
            settings.size[1],
            settings.title.as_slice(), glfw::Windowed
        ).expect("Failed to create GLFW window.");
        window.set_all_polling(true);
        window.make_current();

        // Load the OpenGL function pointers
        gl::load_with(|s| window.get_proc_address(s));

        GlfwWindow {
            window: window,
            events: events,
            glfw: glfw,
            event_queue: RingBuf::new(),
            last_mouse_pos: None,
            title: settings.title,
            exit_on_esc: settings.exit_on_esc,
        }
    }

    fn flush_messages(&mut self) {
        if self.event_queue.len() != 0 {
            return;
        }

        self.glfw.poll_events();
        for (_, event) in glfw::flush_messages(&self.events) {
            match event {
                glfw::KeyEvent(glfw::KeyEscape, _, glfw::Press, _)
                if self.exit_on_esc => {
                    self.window.set_should_close(true);
                }
                glfw::CharEvent(ch) => {
                    self.event_queue.push_back(input::Text(ch.to_string()));
                }
                glfw::KeyEvent(key, _, glfw::Press, _) => {
                    self.event_queue.push_back(
                        input::Press(input::Keyboard(glfw_map_key(key)))
                    );
                }
                glfw::KeyEvent(key, _, glfw::Release, _) => {
                    self.event_queue.push_back(
                        input::Release(input::Keyboard(glfw_map_key(key)))
                    );
                }
                glfw::MouseButtonEvent(button, glfw::Press, _) => {
                    self.event_queue.push_back(
                        input::Press(input::Mouse(glfw_map_mouse(button)))
                    );
                }
                glfw::MouseButtonEvent(button, glfw::Release, _) => {
                    self.event_queue.push_back(
                        input::Release(input::Mouse(glfw_map_mouse(button)))
                    );
                }
                glfw::CursorPosEvent(x, y) => {
                    self.event_queue.push_back(input::Move(input::MouseCursor(x, y)));
                    match self.last_mouse_pos {
                        Some((lx, ly)) => {
                            self.event_queue.push_back(
                                input::Move(input::MouseRelative(x - lx, y - ly))
                            )
                        }
                        None => {}
                    };
                    self.last_mouse_pos = Some((x, y));
                }
                glfw::ScrollEvent(x, y) => {
                    self.event_queue.push_back(input::Move(input::MouseScroll(x, y)));
                }
                glfw::SizeEvent(w, h) => {
                    self.event_queue.push_back(input::Resize(w as u32, h as u32));
                }
                glfw::FocusEvent(focus) => {
                    self.event_queue.push_back(input::Focus(focus));
                }
                _ => {}
            }
        }
    }
}

impl Get<Size> for GlfwWindow {
    fn get(&self) -> Size {
        let (w, h) = self.window.get_size();
        Size([w as u32, h as u32])
    }
}

impl Get<ShouldClose> for GlfwWindow {
    fn get(&self) -> ShouldClose {
        ShouldClose(self.window.should_close())
    }
}

impl PollEvent<InputEvent> for GlfwWindow {
    fn poll_event(&mut self) -> Option<input::InputEvent> {
        self.flush_messages();

        if self.event_queue.len() != 0 {
            self.event_queue.pop_front()
        } else {
            None
        }
    }
}

impl SwapBuffers for GlfwWindow {
    fn swap_buffers(&mut self) {
        use glfw::Context;

        self.window.swap_buffers();
    }
}

impl Modifier<GlfwWindow> for CaptureCursor {
    fn modify(self, window: &mut GlfwWindow) {
        let CaptureCursor(enabled) = self;
        if enabled {
            window.window.set_cursor_mode(glfw::CursorDisabled)
        } else {
            window.window.set_cursor_mode(glfw::CursorNormal);
            window.last_mouse_pos = None;
        }
    }
}

impl Modifier<GlfwWindow> for ShouldClose {
    fn modify(self, window: &mut GlfwWindow) {
        let ShouldClose(val) = self;
        window.window.set_should_close(val);
    }
}

impl Get<DrawSize> for GlfwWindow {
    fn get(&self) -> DrawSize {
        let (w, h) = self.window.get_framebuffer_size();
        DrawSize([w as u32, h as u32])
    }
}

impl Get<Title> for GlfwWindow {
    fn get(&self) -> Title {
        Title(self.title.clone())
    }
}

impl Modifier<GlfwWindow> for Title {
    fn modify(self, window: &mut GlfwWindow) {
        let Title(val) = self;
        window.window.set_title(val.as_slice())
    }
}

impl Get<ExitOnEsc> for GlfwWindow {
    fn get(&self) -> ExitOnEsc {
        ExitOnEsc(self.exit_on_esc)
    }
}

impl Modifier<GlfwWindow> for ExitOnEsc {
    fn modify(self, window: &mut GlfwWindow) {
        let ExitOnEsc(val) = self;
        window.exit_on_esc = val;
    }
}

fn glfw_map_key(keycode: glfw::Key) -> keyboard::Key {
    match keycode {
        glfw::Key0 => keyboard::D0,
        glfw::Key1 => keyboard::D1,
        glfw::Key2 => keyboard::D2,
        glfw::Key3 => keyboard::D3,
        glfw::Key4 => keyboard::D4,
        glfw::Key5 => keyboard::D5,
        glfw::Key6 => keyboard::D6,
        glfw::Key7 => keyboard::D7,
        glfw::Key8 => keyboard::D8,
        glfw::Key9 => keyboard::D9,
        glfw::KeyA => keyboard::A,
        glfw::KeyB => keyboard::B,
        glfw::KeyC => keyboard::C,
        glfw::KeyD => keyboard::D,
        glfw::KeyE => keyboard::E,
        glfw::KeyF => keyboard::F,
        glfw::KeyG => keyboard::G,
        glfw::KeyH => keyboard::H,
        glfw::KeyI => keyboard::I,
        glfw::KeyJ => keyboard::J,
        glfw::KeyK => keyboard::K,
        glfw::KeyL => keyboard::L,
        glfw::KeyM => keyboard::M,
        glfw::KeyN => keyboard::N,
        glfw::KeyO => keyboard::O,
        glfw::KeyP => keyboard::P,
        glfw::KeyQ => keyboard::Q,
        glfw::KeyR => keyboard::R,
        glfw::KeyS => keyboard::S,
        glfw::KeyT => keyboard::T,
        glfw::KeyU => keyboard::U,
        glfw::KeyV => keyboard::V,
        glfw::KeyW => keyboard::W,
        glfw::KeyX => keyboard::X,
        glfw::KeyY => keyboard::Y,
        glfw::KeyZ => keyboard::Z,
        glfw::KeyApostrophe => keyboard::Unknown,
        glfw::KeyBackslash => keyboard::Backslash,
        glfw::KeyBackspace => keyboard::Backspace,
        glfw::KeyCapsLock => keyboard::CapsLock,
        glfw::KeyDelete => keyboard::Delete,
        glfw::KeyComma => keyboard::Comma,
        glfw::KeyDown => keyboard::Down,
        glfw::KeyEnd => keyboard::End,
        glfw::KeyEnter => keyboard::Return,
        glfw::KeyEqual => keyboard::Equals,
        glfw::KeyEscape => keyboard::Escape,
        glfw::KeyF1 => keyboard::F1,
        glfw::KeyF2 => keyboard::F2,
        glfw::KeyF3 => keyboard::F3,
        glfw::KeyF4 => keyboard::F4,
        glfw::KeyF5 => keyboard::F5,
        glfw::KeyF6 => keyboard::F6,
        glfw::KeyF7 => keyboard::F7,
        glfw::KeyF8 => keyboard::F8,
        glfw::KeyF9 => keyboard::F9,
        glfw::KeyF10 => keyboard::F10,
        glfw::KeyF11 => keyboard::F11,
        glfw::KeyF12 => keyboard::F12,
        glfw::KeyF13 => keyboard::F13,
        glfw::KeyF14 => keyboard::F14,
        glfw::KeyF15 => keyboard::F15,
        glfw::KeyF16 => keyboard::F16,
        glfw::KeyF17 => keyboard::F17,
        glfw::KeyF18 => keyboard::F18,
        glfw::KeyF19 => keyboard::F19,
        glfw::KeyF20 => keyboard::F20,
        glfw::KeyF21 => keyboard::F21,
        glfw::KeyF22 => keyboard::F22,
        glfw::KeyF23 => keyboard::F23,
        glfw::KeyF24 => keyboard::F24,
        // Possibly next code.
        glfw::KeyF25 => keyboard::Unknown,
        glfw::KeyKp0 => keyboard::NumPad0,
        glfw::KeyKp1 => keyboard::NumPad1,
        glfw::KeyKp2 => keyboard::NumPad2,
        glfw::KeyKp3 => keyboard::NumPad3,
        glfw::KeyKp4 => keyboard::NumPad4,
        glfw::KeyKp5 => keyboard::NumPad5,
        glfw::KeyKp6 => keyboard::NumPad6,
        glfw::KeyKp7 => keyboard::NumPad7,
        glfw::KeyKp8 => keyboard::NumPad8,
        glfw::KeyKp9 => keyboard::NumPad9,
        glfw::KeyKpDecimal => keyboard::NumPadDecimal,
        glfw::KeyKpDivide => keyboard::NumPadDivide,
        glfw::KeyKpMultiply => keyboard::NumPadMultiply,
        glfw::KeyKpSubtract => keyboard::NumPadMinus,
        glfw::KeyKpAdd => keyboard::NumPadPlus,
        glfw::KeyKpEnter => keyboard::NumPadEnter,
        glfw::KeyKpEqual => keyboard::NumPadEquals,
        glfw::KeyLeftShift => keyboard::LShift,
        glfw::KeyLeftControl => keyboard::LCtrl,
        glfw::KeyLeftAlt => keyboard::LAlt,
        glfw::KeyLeftSuper => keyboard::LGui,
        glfw::KeyRightShift => keyboard::RShift,
        glfw::KeyRightControl => keyboard::RCtrl,
        glfw::KeyRightAlt => keyboard::RAlt,
        glfw::KeyRightSuper => keyboard::RGui,
        // Map to backslash?
        glfw::KeyGraveAccent => keyboard::Unknown,
        glfw::KeyHome => keyboard::Home,
        glfw::KeyInsert => keyboard::Insert,
        glfw::KeyLeft => keyboard::Left,
        glfw::KeyLeftBracket => keyboard::LeftBracket,
        glfw::KeyMenu => keyboard::Menu,
        glfw::KeyMinus => keyboard::Minus,
        glfw::KeyNumLock => keyboard::NumLockClear,
        glfw::KeyPageDown => keyboard::PageDown,
        glfw::KeyPageUp => keyboard::PageUp,
        glfw::KeyPause => keyboard::Pause,
        glfw::KeyPeriod => keyboard::Period,
        glfw::KeyPrintScreen => keyboard::PrintScreen,
        glfw::KeyRight => keyboard::Right,
        glfw::KeyRightBracket => keyboard::RightBracket,
        glfw::KeyScrollLock => keyboard::ScrollLock,
        glfw::KeySemicolon => keyboard::Semicolon,
        glfw::KeySlash => keyboard::Slash,
        glfw::KeySpace => keyboard::Space,
        glfw::KeyTab => keyboard::Tab,
        glfw::KeyUp => keyboard::Up,
        glfw::KeyWorld1 => keyboard::Unknown,
        glfw::KeyWorld2 => keyboard::Unknown,
        // _ => keyboard::Unknown,
    }
}

fn glfw_map_mouse(mouse_button: glfw::MouseButton) -> mouse::Button {
    match mouse_button {
        glfw::MouseButton1 => mouse::Left,
        glfw::MouseButton2 => mouse::Right,
        glfw::MouseButton3 => mouse::Middle,
        glfw::MouseButton4 => mouse::X1,
        glfw::MouseButton5 => mouse::X2,
        glfw::MouseButton6 => mouse::Button6,
        glfw::MouseButton7 => mouse::Button7,
        glfw::MouseButton8 => mouse::Button8,
    }
}
<commit_msg>Updating for namespace changes in glfw<commit_after>#![deny(missing_docs)]

//! A GLFW window back-end for the Piston game engine.

extern crate glfw;
extern crate collections;
extern crate gl;
extern crate window;
extern crate shader_version;
extern crate input;
extern crate current;

// External crates.
use current::{ Get, Modifier };
use collections::RingBuf;
use glfw::Context;
use input::{
    keyboard,
    mouse,
    InputEvent,
};
use window::{
    Window,
    WindowSettings,
    ShouldClose, Size, PollEvent, SwapBuffers,
    CaptureCursor, DrawSize, Title, SetTitle,
    ExitOnEsc
};
use shader_version::opengl::OpenGL;

/// Contains stuff for game window.
pub struct GlfwWindow {
    /// The window.
    pub window: glfw::Window,
    /// Receives events from window.
    events: Receiver<(f64, glfw::WindowEvent)>,
    /// GLFW context.
    pub glfw: glfw::Glfw,
    event_queue: RingBuf<input::InputEvent>,
    // Used to compute relative mouse movement.
    last_mouse_pos: Option<(f64, f64)>,
    // The back-end does not remember the title.
    title: String,
    exit_on_esc: bool,
}

#[test]
fn test_glfw_window() {
    fn foo<T: Window>() {}

    foo::<GlfwWindow>();
}

impl GlfwWindow {
    /// Create a new game window from an existing GLFW window.
    pub fn from_pieces(win: glfw::Window, glfw: glfw::Glfw,
                       events: Receiver<(f64, glfw::WindowEvent)>,
                       exit_on_esc: bool) -> GlfwWindow {
        win.set_all_polling(true);
        win.make_current();
        let title = "<unknown window title, created from_pieces>";
        GlfwWindow {
            window: win,
            events: events,
            glfw: glfw,
            exit_on_esc: exit_on_esc,
            event_queue: RingBuf::new(),
            last_mouse_pos: None,
            title: title.to_string(),
        }
    }

    /// Creates a new game window for GLFW.
    pub fn new(opengl: OpenGL, settings: WindowSettings) -> GlfwWindow {
        use glfw::Context;

        // Initialize GLFW.
        let glfw = glfw::init(glfw::FAIL_ON_ERRORS).unwrap();

        let (major, minor) = opengl.get_major_minor();

        // Make sure we have the right GL version.
        glfw.window_hint(glfw::ContextVersion(major as u32, minor as u32));
        glfw.window_hint(glfw::OpenglForwardCompat(true));
        glfw.window_hint(glfw::OpenglProfile(glfw::OpenGlProfileHint::Core));
        glfw.window_hint(glfw::Samples(settings.samples as u32));

        // Create GLFW window.
        let (window, events) = glfw.create_window(
            settings.size[0],
            settings.size[1],
            settings.title.as_slice(), glfw::Windowed
        ).expect("Failed to create GLFW window.");
        window.set_all_polling(true);
        window.make_current();

        // Load the OpenGL function pointers
        gl::load_with(|s| window.get_proc_address(s));

        GlfwWindow {
            window: window,
            events: events,
            glfw: glfw,
            event_queue: RingBuf::new(),
            last_mouse_pos: None,
            title: settings.title,
            exit_on_esc: settings.exit_on_esc,
        }
    }

    fn flush_messages(&mut self) {
        if self.event_queue.len() != 0 {
            return;
        }

        self.glfw.poll_events();
        for (_, event) in glfw::flush_messages(&self.events) {
            match event {
                glfw::KeyEvent(glfw::Key::Escape, _, glfw::Press, _)
                if self.exit_on_esc => {
                    self.window.set_should_close(true);
                }
                glfw::CharEvent(ch) => {
                    self.event_queue.push_back(input::Text(ch.to_string()));
                }
                glfw::KeyEvent(key, _, glfw::Press, _) => {
                    self.event_queue.push_back(
                        input::Press(input::Keyboard(glfw_map_key(key)))
                    );
                }
                glfw::KeyEvent(key, _, glfw::Release, _) => {
                    self.event_queue.push_back(
                        input::Release(input::Keyboard(glfw_map_key(key)))
                    );
                }
                glfw::MouseButtonEvent(button, glfw::Press, _) => {
                    self.event_queue.push_back(
                        input::Press(input::Mouse(glfw_map_mouse(button)))
                    );
                }
                glfw::MouseButtonEvent(button, glfw::Release, _) => {
                    self.event_queue.push_back(
                        input::Release(input::Mouse(glfw_map_mouse(button)))
                    );
                }
                glfw::CursorPosEvent(x, y) => {
                    self.event_queue.push_back(input::Move(input::MouseCursor(x, y)));
                    match self.last_mouse_pos {
                        Some((lx, ly)) => {
                            self.event_queue.push_back(
                                input::Move(input::MouseRelative(x - lx, y - ly))
                            )
                        }
                        None => {}
                    };
                    self.last_mouse_pos = Some((x, y));
                }
                glfw::ScrollEvent(x, y) => {
                    self.event_queue.push_back(input::Move(input::MouseScroll(x, y)));
                }
                glfw::SizeEvent(w, h) => {
                    self.event_queue.push_back(input::Resize(w as u32, h as u32));
                }
                glfw::FocusEvent(focus) => {
                    self.event_queue.push_back(input::Focus(focus));
                }
                _ => {}
            }
        }
    }
}

impl Get<Size> for GlfwWindow {
    fn get(&self) -> Size {
        let (w, h) = self.window.get_size();
        Size([w as u32, h as u32])
    }
}

impl Get<ShouldClose> for GlfwWindow {
    fn get(&self) -> ShouldClose {
        ShouldClose(self.window.should_close())
    }
}

impl PollEvent<InputEvent> for GlfwWindow {
    fn poll_event(&mut self) -> Option<input::InputEvent> {
        self.flush_messages();

        if self.event_queue.len() != 0 {
            self.event_queue.pop_front()
        } else {
            None
        }
    }
}

impl SwapBuffers for GlfwWindow {
    fn swap_buffers(&mut self) {
        use glfw::Context;

        self.window.swap_buffers();
    }
}

impl Modifier<GlfwWindow> for CaptureCursor {
    fn modify(self, window: &mut GlfwWindow) {
        let CaptureCursor(enabled) = self;
        if enabled {
            window.window.set_cursor_mode(glfw::CursorMode::Disabled)
        } else {
            window.window.set_cursor_mode(glfw::CursorMode::Normal);
            window.last_mouse_pos = None;
        }
    }
}

impl Modifier<GlfwWindow> for ShouldClose {
    fn modify(self, window: &mut GlfwWindow) {
        let ShouldClose(val) = self;
        window.window.set_should_close(val);
    }
}

impl Get<DrawSize> for GlfwWindow {
    fn get(&self) -> DrawSize {
        let (w, h) = self.window.get_framebuffer_size();
        DrawSize([w as u32, h as u32])
    }
}

impl Get<Title> for GlfwWindow {
    fn get(&self) -> Title {
        Title(self.title.clone())
    }
}

impl Modifier<GlfwWindow> for Title {
    fn modify(self, window: &mut GlfwWindow) {
        let Title(val) = self;
        window.window.set_title(val.as_slice())
    }
}

impl Get<ExitOnEsc> for GlfwWindow {
    fn get(&self) -> ExitOnEsc {
        ExitOnEsc(self.exit_on_esc)
    }
}

impl Modifier<GlfwWindow> for ExitOnEsc {
    fn modify(self, window: &mut GlfwWindow) {
        let ExitOnEsc(val) = self;
        window.exit_on_esc = val;
    }
}

fn glfw_map_key(keycode: glfw::Key) -> keyboard::Key {
    match keycode {
        glfw::Key::Num0 => keyboard::D0,
        glfw::Key::Num1 => keyboard::D1,
        glfw::Key::Num2 => keyboard::D2,
        glfw::Key::Num3 => keyboard::D3,
        glfw::Key::Num4 => keyboard::D4,
        glfw::Key::Num5 => keyboard::D5,
        glfw::Key::Num6 => keyboard::D6,
        glfw::Key::Num7 => keyboard::D7,
        glfw::Key::Num8 => keyboard::D8,
        glfw::Key::Num9 => keyboard::D9,
        glfw::Key::A => keyboard::A,
        glfw::Key::B => keyboard::B,
        glfw::Key::C => keyboard::C,
        glfw::Key::D => keyboard::D,
        glfw::Key::E => keyboard::E,
        glfw::Key::F => keyboard::F,
        glfw::Key::G => keyboard::G,
        glfw::Key::H => keyboard::H,
        glfw::Key::I => keyboard::I,
        glfw::Key::J => keyboard::J,
        glfw::Key::K => keyboard::K,
        glfw::Key::L => keyboard::L,
        glfw::Key::M => keyboard::M,
        glfw::Key::N => keyboard::N,
        glfw::Key::O => keyboard::O,
        glfw::Key::P => keyboard::P,
        glfw::Key::Q => keyboard::Q,
        glfw::Key::R => keyboard::R,
        glfw::Key::S => keyboard::S,
        glfw::Key::T => keyboard::T,
        glfw::Key::U => keyboard::U,
        glfw::Key::V => keyboard::V,
        glfw::Key::W => keyboard::W,
        glfw::Key::X => keyboard::X,
        glfw::Key::Y => keyboard::Y,
        glfw::Key::Z => keyboard::Z,
        glfw::Key::Apostrophe => keyboard::Unknown,
        glfw::Key::Backslash => keyboard::Backslash,
        glfw::Key::Backspace => keyboard::Backspace,
        glfw::Key::CapsLock => keyboard::CapsLock,
        glfw::Key::Delete => keyboard::Delete,
        glfw::Key::Comma => keyboard::Comma,
        glfw::Key::Down => keyboard::Down,
        glfw::Key::End => keyboard::End,
        glfw::Key::Enter => keyboard::Return,
        glfw::Key::Equal => keyboard::Equals,
        glfw::Key::Escape => keyboard::Escape,
        glfw::Key::F1 => keyboard::F1,
        glfw::Key::F2 => keyboard::F2,
        glfw::Key::F3 => keyboard::F3,
        glfw::Key::F4 => keyboard::F4,
        glfw::Key::F5 => keyboard::F5,
        glfw::Key::F6 => keyboard::F6,
        glfw::Key::F7 => keyboard::F7,
        glfw::Key::F8 => keyboard::F8,
        glfw::Key::F9 => keyboard::F9,
        glfw::Key::F10 => keyboard::F10,
        glfw::Key::F11 => keyboard::F11,
        glfw::Key::F12 => keyboard::F12,
        glfw::Key::F13 => keyboard::F13,
        glfw::Key::F14 => keyboard::F14,
        glfw::Key::F15 => keyboard::F15,
        glfw::Key::F16 => keyboard::F16,
        glfw::Key::F17 => keyboard::F17,
        glfw::Key::F18 => keyboard::F18,
        glfw::Key::F19 => keyboard::F19,
        glfw::Key::F20 => keyboard::F20,
        glfw::Key::F21 => keyboard::F21,
        glfw::Key::F22 => keyboard::F22,
        glfw::Key::F23 => keyboard::F23,
        glfw::Key::F24 => keyboard::F24,
        // Possibly next code.
        glfw::Key::F25 => keyboard::Unknown,
        glfw::Key::Kp0 => keyboard::NumPad0,
        glfw::Key::Kp1 => keyboard::NumPad1,
        glfw::Key::Kp2 => keyboard::NumPad2,
        glfw::Key::Kp3 => keyboard::NumPad3,
        glfw::Key::Kp4 => keyboard::NumPad4,
        glfw::Key::Kp5 => keyboard::NumPad5,
        glfw::Key::Kp6 => keyboard::NumPad6,
        glfw::Key::Kp7 => keyboard::NumPad7,
        glfw::Key::Kp8 => keyboard::NumPad8,
        glfw::Key::Kp9 => keyboard::NumPad9,
        glfw::Key::KpDecimal => keyboard::NumPadDecimal,
        glfw::Key::KpDivide => keyboard::NumPadDivide,
        glfw::Key::KpMultiply => keyboard::NumPadMultiply,
        glfw::Key::KpSubtract => keyboard::NumPadMinus,
        glfw::Key::KpAdd => keyboard::NumPadPlus,
        glfw::Key::KpEnter => keyboard::NumPadEnter,
        glfw::Key::KpEqual => keyboard::NumPadEquals,
        glfw::Key::LeftShift => keyboard::LShift,
        glfw::Key::LeftControl => keyboard::LCtrl,
        glfw::Key::LeftAlt => keyboard::LAlt,
        glfw::Key::LeftSuper => keyboard::LGui,
        glfw::Key::RightShift => keyboard::RShift,
        glfw::Key::RightControl => keyboard::RCtrl,
        glfw::Key::RightAlt => keyboard::RAlt,
        glfw::Key::RightSuper => keyboard::RGui,
        // Map to backslash?
        glfw::Key::GraveAccent => keyboard::Unknown,
        glfw::Key::Home => keyboard::Home,
        glfw::Key::Insert => keyboard::Insert,
        glfw::Key::Left => keyboard::Left,
        glfw::Key::LeftBracket => keyboard::LeftBracket,
        glfw::Key::Menu => keyboard::Menu,
        glfw::Key::Minus => keyboard::Minus,
        glfw::Key::NumLock => keyboard::NumLockClear,
        glfw::Key::PageDown => keyboard::PageDown,
        glfw::Key::PageUp => keyboard::PageUp,
        glfw::Key::Pause => keyboard::Pause,
        glfw::Key::Period => keyboard::Period,
        glfw::Key::PrintScreen => keyboard::PrintScreen,
        glfw::Key::Right => keyboard::Right,
        glfw::Key::RightBracket => keyboard::RightBracket,
        glfw::Key::ScrollLock => keyboard::ScrollLock,
        glfw::Key::Semicolon => keyboard::Semicolon,
        glfw::Key::Slash => keyboard::Slash,
        glfw::Key::Space => keyboard::Space,
        glfw::Key::Tab => keyboard::Tab,
        glfw::Key::Up => keyboard::Up,
        glfw::Key::World1 => keyboard::Unknown,
        glfw::Key::World2 => keyboard::Unknown,
        // _ => keyboard::Unknown,
    }
}

fn glfw_map_mouse(mouse_button: glfw::MouseButton) -> mouse::Button {
    match mouse_button {
        glfw::MouseButton::Button1 => mouse::Left,
        glfw::MouseButton::Button2 => mouse::Right,
        glfw::MouseButton::Button3 => mouse::Middle,
        glfw::MouseButton::Button4 => mouse::X1,
        glfw::MouseButton::Button5 => mouse::X2,
        glfw::MouseButton::Button6 => mouse::Button6,
        glfw::MouseButton::Button7 => mouse::Button7,
        glfw::MouseButton::Button8 => mouse::Button8,
    }
}
<|endoftext|>