<commit_before>extern crate html5ever;
#[macro_use(qualname,ns,atom)]
extern crate string_cache;
#[macro_use(format_tendril)]
extern crate tendril;

use html5ever::rcdom::NodeEnum::Element;
use html5ever::rcdom::{RcDom, Handle};
use html5ever::serialize::{SerializeOpts, serialize};
use html5ever::tendril::TendrilSink;
use html5ever::tree_builder::{TreeBuilderOpts, TreeSink, NodeOrText};
use html5ever::{ParseOpts, parse_document};
use std::string::String;
use std::io;

enum Entry {
    Method(Handle),
}

fn main() {
    let opts = ParseOpts {
        tree_builder: TreeBuilderOpts { drop_doctype: true, ..Default::default() },
        ..Default::default()
    };

    let stdin = io::stdin();
    let mut dom = parse_document(RcDom::default(), opts)
                      .from_utf8()
                      .read_from(&mut stdin.lock())
                      .unwrap();

    let entries = find_entry_elements(&mut dom);

    // https://kapeli.com/docsets#tableofcontents
    // https://kapeli.com/docsets#supportedentrytypes
    for entry in entries {
        match entry {
            Entry::Method(e) => {
                add_dash_link_before_entry(&mut dom, &e, "method", "42")
            }
        }
    }

    let mut bytes = vec![];
    serialize(&mut bytes, &dom.document, SerializeOpts::default()).unwrap();
    let result = String::from_utf8(bytes).unwrap();
    println!("{}", result);
}

fn add_dash_link_before_entry(dom: &mut RcDom, p: &Handle, entrytype: &str, entryname: &str) {
    let class_attr = html5ever::Attribute {
        name: qualname!("", "class"),
        value: format_tendril!("dashAnchor"),
    };

    let name_attr = html5ever::Attribute {
        name: qualname!("", "name"),
        value: format_tendril!("//apple_ref/cpp/{}/{}", entrytype, entryname),
    };

    let dash_link = dom.create_element(qualname!(html, "a"), vec![name_attr, class_attr.clone()]);
    let _ = dom.append_before_sibling(p.clone(), NodeOrText::AppendNode(dash_link));
}

fn find_entry_elements(dom: &mut RcDom) -> Vec<Entry> {
    let mut entries = vec![];
    walk_tree(&dom.document, &mut entries);
    entries
}

fn walk_tree(h: &Handle, entries: &mut Vec<Entry>) {
    let node = h.borrow();
    for e in node.children.iter() {
        if let Element(_, _, ref attrs) = e.borrow().node {
            if let Some(attr) = attrs.iter().find(|ref x| x.name == qualname!("", "class")) {
                match attr.clone().value.to_string().as_str() {
                    "method" => entries.push(Entry::Method(e.clone())),
                    _ => {}
                }
            }
        }
        walk_tree(e, entries);
    }
}
<commit_msg>Next step in simple test setup<commit_after>extern crate html5ever;
#[macro_use(qualname,ns,atom)]
extern crate string_cache;
#[macro_use(format_tendril)]
extern crate tendril;

use html5ever::rcdom::NodeEnum::Element;
use html5ever::rcdom::{RcDom, Handle};
use html5ever::serialize::{SerializeOpts, serialize};
use html5ever::tendril::TendrilSink;
use html5ever::tree_builder::{TreeBuilderOpts, TreeSink, NodeOrText};
use html5ever::{ParseOpts, parse_document};
use std::string::String;
use std::io;

enum Entry {
    Const(Handle),
    // Enum(Handle),
    // Function(Handle),
    // Macro(Handle),
    Method(Handle),
    Module(Handle),
    Struct(Handle),
    Trait(Handle),
    Type(Handle),
}

fn main() {
    let opts = ParseOpts {
        tree_builder: TreeBuilderOpts { drop_doctype: true, ..Default::default() },
        ..Default::default()
    };

    let stdin = io::stdin();
    let mut dom = parse_document(RcDom::default(), opts)
                      .from_utf8()
                      .read_from(&mut stdin.lock())
                      .unwrap();

    let entries = find_entry_elements(&mut dom);

    // https://kapeli.com/docsets#tableofcontents
    // https://kapeli.com/docsets#supportedentrytypes
    for entry in entries {
        match entry {
            Entry::Method(e) => {
                add_dash_link_before_entry(&mut dom, &e, "method", "42")
            }
            _ => {}
        }
    }

    let mut bytes = vec![];
    serialize(&mut bytes, &dom.document, SerializeOpts::default()).unwrap();
    let result = String::from_utf8(bytes).unwrap();
    println!("{}", result);
}

fn add_dash_link_before_entry(dom: &mut RcDom, p: &Handle, entrytype: &str, entryname: &str) {
    let class_attr = html5ever::Attribute {
        name: qualname!("", "class"),
        value: format_tendril!("dashAnchor"),
    };

    let name_attr = html5ever::Attribute {
        name: qualname!("", "name"),
        // TODO: percent escape entryname
        value: format_tendril!("//apple_ref/cpp/{}/{}", entrytype, entryname),
    };

    let dash_link = dom.create_element(qualname!(html, "a"), vec![name_attr, class_attr.clone()]);
    let _ = dom.append_before_sibling(p.clone(), NodeOrText::AppendNode(dash_link));
}

fn find_entry_elements(dom: &mut RcDom) -> Vec<Entry> {
    let mut entries = vec![];
    walk_tree(&dom.document, &mut entries);
    entries
}

fn walk_tree(h: &Handle, entries: &mut Vec<Entry>) {
    let node = h.borrow();
    for e in node.children.iter() {
        if let Element(ref name, _, ref attrs) = e.borrow().node {
            if name.eq(&qualname!(html, "section")) {
                let tag = &(*name.local.to_ascii_lowercase());
                if let Some(attr) = attrs.iter().find(|ref x| x.name == qualname!("", "class")) {
                    match (tag, attr.clone().value.to_string().as_str()) {
                        ("h4", "method") => entries.push(Entry::Method(e.clone())),
                        ("section", "content mod") => entries.push(Entry::Module(e.clone())),
                        ("section", "content constant") => entries.push(Entry::Const(e.clone())),
                        ("section", "content struct") => entries.push(Entry::Struct(e.clone())),
                        ("section", "content trait") => entries.push(Entry::Trait(e.clone())),
                        ("section", "type") => entries.push(Entry::Type(e.clone())),
                        (_, _) => {}
                    }
                }
            }
        }
        walk_tree(e, entries);
    }
}

#[cfg(test)]
mod tests {
    use html5ever::{ParseOpts, parse_document};
    use html5ever::rcdom::{RcDom, Handle};
    use tendril::TendrilSink;
    use html5ever::tree_builder::TreeBuilderOpts;

    fn dom_from_snippet(s: &str) -> Handle {
        let opts = ParseOpts {
            tree_builder: TreeBuilderOpts { drop_doctype: true, ..Default::default() },
            ..Default::default()
        };

        let dom = parse_document(RcDom::default(), opts)
                      .from_utf8()
                      .read_from(&mut format!("{}", s)
                                          .as_bytes())
                      .unwrap();

        dom.document
    }

    #[test]
    fn it_extracts_name_for_const_correctly() {
        let document_with_constant_section = dom_from_snippet("

alloc::\
                                                               <wbr>boxed::<wbr>HEAP  \
                                                               [−] \
                                                                [src]
</sect\
                                                               ion>");

        let mut entries: Vec<super::Entry> = Vec::new();
        super::walk_tree(&document_with_constant_section, &mut entries);

        assert_eq!(entries.len(), 1);
        match entries[0] {
            super::Entry::Const(_) => assert!(true),
            _ => assert!(false),
        }
    }
}

// const:

// enum:

Enum collections::<wbr>borrow::<wbr>Cow1.0.0  [−]  [src]

// function:

Function std::<wbr>fs::<wbr>metadata1.0.0  [−]  [src]

// macro:
 //
std::<wbr>println!1.0.0  [−]  [src]

// method:
fn hash<H: Hasher>(&self, state: &mut H)[−]

// modules:

Crate collections  [−]  [src]

// struct:

Struct std::<wbr>io::<wbr>Bytes1.0.0  [−]  [src]

// trait:

Trait collections::<wbr>fmt::<wbr>Binary1.0.0  [−]  [src]

// type:
type Output = bool

<|endoftext|>


<commit_before>// The MIT License (MIT)
//
// Copyright (c) 2015 Johan Johansson
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

#![feature(libc)]

extern crate libc;
extern crate winapi;

use libc::c_void;
use winapi::{ REFIID, REFGUID, GUID, HRESULT, ULONG, UINT, IUnknown, LARGE_INTEGER };

use ffi_vtable::c_vtable;

mod ffi_vtable;

macro_rules! define_guid {
	($name:ident, $d1:expr, $d2:expr, $d3:expr, $d4:expr) => {
		#[allow(non_upper_case_globals, dead_code)]
		static $name: GUID = GUID{ Data1: $d1, Data2: $d2, Data3: $d3, Data4: $d4 };
	}
}

define_guid!(IID_IDXGIFactory1,
	0x770aae78, 0xf26f, 0x4dba, [0xa8, 0x29, 0x25, 0x3c, 0x83, 0xd1, 0xb3, 0x87]);
define_guid!(IID_IDXGIObject,
	0xaec22fb8, 0x76f3, 0x4639, [0x9b, 0xe0, 0x28, 0xeb, 0x43, 0xa6, 0x7a, 0x2e]);
define_guid!(IID_IDXGIDeviceSubObject,
	0x3d3e0379, 0xf9de, 0x4d58, [0xbb, 0x6c, 0x18, 0xd6, 0x29, 0x92, 0xf1, 0xa6]);
define_guid!(IID_IDXGIResource,
	0x035f3ab4, 0x482e, 0x4e50, [0xb4, 0x1f, 0x8a, 0x7f, 0x8b, 0xd8, 0x96, 0x0b]);
define_guid!(IID_IDXGIKeyedMutex,
	0x9d8e1289, 0xd7b3, 0x465f, [0x81, 0x26, 0x25, 0x0e, 0x34, 0x9a, 0xf8, 0x5d]);
define_guid!(IID_IDXGISurface,
	0xcafcb56c, 0x6ac3, 0x4889, [0xbf, 0x47, 0x9e, 0x23, 0xbb, 0xd2, 0x60, 0xec]);
define_guid!(IID_IDXGISurface1,
	0x4AE63092, 0x6327, 0x4c1b, [0x80, 0xAE, 0xBF, 0xE1, 0x2E, 0xA3, 0x2B, 0x86]);
define_guid!(IID_IDXGIAdapter,
	0x2411e7e1, 0x12ac, 0x4ccf, [0xbd, 0x14, 0x97, 0x98, 0xe8, 0x53, 0x4d, 0xc0]);
define_guid!(IID_IDXGIOutput,
	0xae02eedb, 0xc735, 0x4690, [0x8d, 0x52, 0x5a, 0x8d, 0xc2, 0x02, 0x13, 0xaa]);
define_guid!(IID_IDXGISwapChain,
	0x310d36a0, 0xd2e7, 0x4c0a, [0xaa, 0x04, 0x6a, 0x9d, 0x23, 0xb8, 0x88, 0x6a]);
define_guid!(IID_IDXGIFactory,
	0x7b7166ec, 0x21c7, 0x44ae, [0xb2, 0x1a, 0xc9, 0xae, 0x32, 0x1a, 0xe3, 0x69]);
define_guid!(IID_IDXGIDevice,
	0x54ec77fa, 0x1377, 0x44e6, [0x8c, 0x32, 0x88, 0xfd, 0x5f, 0x44, 0xc8, 0x4c]);
define_guid!(IID_IDXGIFactory1,
	0x770aae78, 0xf26f, 0x4dba, [0xa8, 0x29, 0x25, 0x3c, 0x83, 0xd1, 0xb3, 0x87]);
define_guid!(IID_IDXGIAdapter1,
	0x29038f61, 0x3839, 0x4626, [0x91, 0xfd, 0x08, 0x68, 0x79, 0x01, 0x1a, 0x05]);
define_guid!(IID_IDXGIDevice1,
	0x77db970f, 0x6276, 0x48ba, [0xba, 0x28, 0x07, 0x01, 0x43, 0xb4, 0x39, 0x2c]);

#[repr(C)]
struct IDXGIObject {
	vtable: *mut IDXGIFactoryVtbl
}

#[repr(C)] c_vtable!(
IDXGIObjectVtbl of IDXGIObject {
	fn QueryInterface(riid: REFIID, object: *mut *mut c_void) -> HRESULT,
	fn AddRef() -> ULONG,
	fn Release() -> ULONG,
	fn SetPrivateData(name: REFGUID, data_size: UINT, data: *const c_void) -> HRESULT,
	fn SetPrivateDataInterface(name: REFGUID, unknown: *const IUnknown) -> HRESULT,
	fn GetPrivateData(name: REFGUID, data_size: UINT, data: *mut c_void) -> HRESULT,
	fn GetParent(riid: REFIID, parent: *mut *mut c_void) -> HRESULT,
});

#[repr(C)]
struct IDXGIAdapter {
	vtable: *mut IDXGIFactoryVtbl
}

#[repr(C)] c_vtable!(
IDXGIAdapterVtbl of IDXGIAdapter {
	fn QueryInterface(riid: REFIID, object: *mut *mut c_void) -> HRESULT,
	fn AddRef() -> ULONG,
	fn Release() -> ULONG,
	fn SetPrivateData(name: REFGUID, data_size: UINT, data: *const c_void) -> HRESULT,
	fn SetPrivateDataInterface(name: REFGUID, unknown: *const IUnknown) -> HRESULT,
	fn GetPrivateData(name: REFGUID, data_size: UINT, data: *mut c_void) -> HRESULT,
	fn GetParent(riid: REFIID, parent: *mut *mut c_void) -> HRESULT,

	fn EnumOutputs(output_i: UINT, out_output:*mut *mut IDXGIOutput) -> HRESULT,
	fn GetDesc(out_desc: *mut *mut DXGI_ADAPTER_DESC) -> HRESULT,
	fn CheckInterfaceSupport(interface_name: REFGUID, out_umd_version: LARGE_INTEGER)
		-> HRESULT,
});

#[repr(C)]
struct IDXGIFactory {
	vtable: *mut IDXGIFactoryVtbl
}

#[repr(C)] c_vtable!(
IDXGIFactoryVtbl of IDXGIFactory {
	fn QueryInterface(riid: REFIID, object: *mut *mut c_void) -> HRESULT,
	fn AddRef() -> ULONG,
	fn Release() -> ULONG,
	fn SetPrivateData(name: REFGUID, data_size: UINT, data: *const c_void) -> HRESULT,
	fn SetPrivateDataInterface(name: REFGUID, unknown: *const IUnknown) -> HRESULT,
	fn GetPrivateData(name: REFGUID, data_size: UINT, data: *mut c_void) -> HRESULT,
	fn GetParent(riid: REFIID, parent: *mut *mut c_void) -> HRESULT,

	fn EnumAdapters(adapter_i: UINT, out_adapter: *mut *mut IDXGIAdapter) -> HRESULT,
	fn MakeWindowAssociation(window_handle: HWND, flags: UINT) -> HRESULT,
	fn GetWindowAssociation(out_window_handle: *mut HWND) -> HRESULT,
	fn CreateSwapChain(device: *mut IUnknown, desc: *mut DXGI_SWAP_CHAIN_DESC,
		out_swapchain: *mut *mut IDXGISwapChain) -> HRESULT,
	fn CreateSoftwareAdapter(module: HMODULE, out_adapter: *mut *mut IDXGIAdapter) -> HRESULT
});

#[link(name="dxgi")]
extern "C" {
	#![allow(dead_code)]

	fn CreateDXGIFactory1(riid: REFIID, ppFactory: *mut *mut c_void) -> HRESULT;
}

fn main() {
	use std::ptr;
	let mut factory: *mut c_void = ptr::null_mut();
	assert_eq!(0, unsafe { CreateDXGIFactory1(&IID_IDXGIFactory1, &mut factory) });
}<commit_msg>Use inheritance for vtables in main<commit_after>// The MIT License (MIT)
//
// Copyright (c) 2015 Johan Johansson
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

#![feature(libc)]

extern crate libc;
extern crate winapi;

use libc::c_void;
use winapi::{ REFIID, REFGUID, GUID,
	HRESULT, ULONG, UINT,
	IUnknown, LARGE_INTEGER, SIZE_T,
	WCHAR, LUID, HWND, BOOL};
use dxgi_structures::*;

use ffi_vtable::c_vtable;

mod ffi_vtable;

define_guid!(IID_IDXGIObject,
	0xaec22fb8, 0x76f3, 0x4639, [0x9b, 0xe0, 0x28, 0xeb, 0x43, 0xa6, 0x7a, 0x2e]);
define_guid!(IID_IDXGIDeviceSubObject,
	0x3d3e0379, 0xf9de, 0x4d58, [0xbb, 0x6c, 0x18, 0xd6, 0x29, 0x92, 0xf1, 0xa6]);
define_guid!(IID_IDXGIResource,
	0x035f3ab4, 0x482e, 0x4e50, [0xb4, 0x1f, 0x8a, 0x7f, 0x8b, 0xd8, 0x96, 0x0b]);
define_guid!(IID_IDXGIKeyedMutex,
	0x9d8e1289, 0xd7b3, 0x465f, [0x81, 0x26, 0x25, 0x0e, 0x34, 0x9a, 0xf8, 0x5d]);
define_guid!(IID_IDXGISurface,
	0xcafcb56c, 0x6ac3, 0x4889, [0xbf, 0x47, 0x9e, 0x23, 0xbb, 0xd2, 0x60, 0xec]);
define_guid!(IID_IDXGISurface1,
	0x4AE63092, 0x6327, 0x4c1b, [0x80, 0xAE, 0xBF, 0xE1, 0x2E, 0xA3, 0x2B, 0x86]);
define_guid!(IID_IDXGIAdapter,
	0x2411e7e1, 0x12ac, 0x4ccf, [0xbd, 0x14, 0x97, 0x98, 0xe8, 0x53, 0x4d, 0xc0]);
define_guid!(IID_IDXGIOutput,
	0xae02eedb, 0xc735, 0x4690, [0x8d, 0x52, 0x5a, 0x8d, 0xc2, 0x02, 0x13, 0xaa]);
define_guid!(IID_IDXGISwapChain,
	0x310d36a0, 0xd2e7, 0x4c0a, [0xaa, 0x04, 0x6a, 0x9d, 0x23, 0xb8, 0x88, 0x6a]);
define_guid!(IID_IDXGIFactory,
	0x7b7166ec, 0x21c7, 0x44ae, [0xb2, 0x1a, 0xc9, 0xae, 0x32, 0x1a, 0xe3, 0x69]);
define_guid!(IID_IDXGIDevice,
	0x54ec77fa, 0x1377, 0x44e6, [0x8c, 0x32, 0x88, 0xfd, 0x5f, 0x44, 0xc8, 0x4c]);
define_guid!(IID_IDXGIFactory1,
	0x770aae78, 0xf26f, 0x4dba, [0xa8, 0x29, 0x25, 0x3c, 0x83, 0xd1, 0xb3, 0x87]);
define_guid!(IID_IDXGIAdapter1,
	0x29038f61, 0x3839, 0x4626, [0x91, 0xfd, 0x08, 0x68, 0x79, 0x01, 0x1a, 0x05]);
define_guid!(IID_IDXGIDevice1,
	0x77db970f, 0x6276, 0x48ba, [0xba, 0x28, 0x07, 0x01, 0x43, 0xb4, 0x39, 0x2c]);

#[repr(C)] struct IDXGIObject {
	vtable: *mut IDXGIObjectVtbl
}

#[repr(C)] struct IDXGIAdapter {
	vtable: *mut IDXGIAdapterVtbl
}

#[repr(C)]
struct IDXGIFactory {
	vtable: *mut IDXGIFactoryVtbl
}

#[repr(C)]
struct IDXGIOutput {
	vtable: *mut IDXGIOutputVtbl
}

#[repr(C)] c_vtable!(
IDXGIObjectVtbl of IDXGIObject {
	fn QueryInterface(riid: REFIID, object: *mut *mut c_void) -> HRESULT,
	fn AddRef() -> ULONG,
	fn Release() -> ULONG,
	fn SetPrivateData(name: REFGUID, data_size: UINT, data: *const c_void) -> HRESULT,
	fn SetPrivateDataInterface(name: REFGUID, unknown: *const IUnknown) -> HRESULT,
	fn GetPrivateData(name: REFGUID, data_size: UINT, data: *mut c_void) -> HRESULT,
	fn GetParent(riid: REFIID, parent: *mut *mut c_void) -> HRESULT,
} with heirs [
	IDXGIAdapterVtbl of IDXGIAdapter {
		fn EnumOutputs(output_i: UINT, output:*mut *mut IDXGIOutput) -> HRESULT,
		fn GetDesc(desc: *mut *mut DXGI_ADAPTER_DESC) -> HRESULT,
		fn CheckInterfaceSupport(interface_name: REFGUID, umd_version: LARGE_INTEGER) -> HRESULT,
	};
	IDXGIFactoryVtbl of IDXGIFactory {
		fn EnumAdapters(adapter_i: UINT, adapter: *mut *mut IDXGIAdapter) -> HRESULT,
		fn MakeWindowAssociation(window_handle: HWND, flags: UINT) -> HRESULT,
		fn GetWindowAssociation(window_handle: *mut HWND) -> HRESULT,
		fn CreateSwapChain(device: *mut IUnknown, desc: *mut DXGI_SWAP_CHAIN_DESC,
			swapchain: *mut *mut IDXGISwapChain) -> HRESULT,
		fn CreateSoftwareAdapter(module: HMODULE, adapter: *mut *mut IDXGIAdapter) -> HRESULT,
	};
	IDXGIOutputVtbl of IDXGIOutput {
		fn GetDesc(desc: *mut DXGI_OUTPUT_DESC) -> HRESULT,
		fn GetDisplayModeList(enum_format: DXGI_FORMAT, flags: UINT, num_modes: *mut UINT,
			desc: *mut DXGI_MODE_DESC) -> HRESULT,
		fn FingClosestMatchingMode(mode_to_match: *const DXGI_MODE_DESC,
			closest_match: *mut DXGI_MODE_DESC, concerned_device: IUnknown) -> HRESULT,
		fn WaitForVBlank() -> HRESULT,
		fn TakeOwnerShip(device: *mut IUnknown, exclusive: BOOL) -> HRESULT,
		fn ReleaseOwnership() -> (),
		fn GetGammaControlCapabilities(gamma_caps: *mut DXGI_GAMMA_CONTROL_CAPABILITIES) -> HRESULT,
		fn SetGammaControl(array: *const DXGI_GAMMA_CONTROL) -> HRESULT,
		fn GetGammaControl(arrau: *mut DXGI_GAMMA_CONTROL) -> HRESULT,
		fn SetDisplaySurface(scanout_surface: *mut IDXGISurface) -> HRESULT,
		fn GetDispleySurfaceData(destination: *mut IDXGISurface) -> HRESULT,
		fn GetFrameStatistics(stats: *mut DXGI_FRAME_STATISTICS) -> HRESULT,
	};
]);

#[link(name="dxgi")]
extern "C" {
	#![allow(dead_code)]

	fn CreateDXGIFactory1(riid: REFIID, ppFactory: *mut *mut c_void) -> HRESULT;
}

fn main() {
	use std::ptr;
	let mut factory: *mut c_void = ptr::null_mut();
	assert_eq!(0, unsafe { CreateDXGIFactory1(&IID_IDXGIFactory1, &mut factory) });
}<|endoftext|>


<commit_before>#![deny(warnings)]
#![feature(exit_status)]
#![feature(path)]
#![feature(path_ext)]

extern crate env_logger;
#[macro_use]
extern crate log;
extern crate tempdir;

use std::env;
use std::fs::{PathExt, self};
use std::path::Path;
use std::process::{Command, Stdio};

use tempdir::TempDir;

fn main() {
    env_logger::init().unwrap();

    let args: Vec<_> = env::args().skip(1).collect();

    // If `--run` is not in the arguments: pass all the arguments to `rustc`
    if args.iter().all(|arg| *arg != "--run") {
        let mut cmd = Command::new("rustc");
        cmd.args(&args);

        // Inherit stdio
        cmd.stderr(Stdio::inherit());
        cmd.stdin(Stdio::inherit());
        cmd.stdout(Stdio::inherit());

        info!("cwd: . | cmd: `{:?}`", cmd);
        match cmd.output() {
            Err(e) => panic!("`{:?}` failed: {}", cmd, e),
            Ok(output) =>  {
                env::set_exit_status(output.status.code().unwrap());

                return;
            },
        }
    }

    // Before `--`: arguments for the compiler
    // After `--`: arguments for the executable
    let mut splitted_args = args.split(|arg| *arg == "--");
    let compiler_args = splitted_args.next().unwrap();
    let executable_args = splitted_args.next();

    // TODO `--crate-type=lib` should also be forbidden
    // XXX What if the crate has a `crate_type=*lib` attribute?
    if compiler_args.iter().any(|arg| *arg == "--out-dir") {
        panic!("Can't use both `--out-dir` and `--run` flags at the same time");
    }

    // Build the rustc command
    let mut cmd = Command::new("rustc");
    // Make all paths absolute, filter out the `--run` flag
    let current_dir = env::current_dir().ok().expect("Couldn't fetch the current directory");
    for arg in compiler_args.iter().filter(|arg| **arg != "--run") {
        let path = Path::new(arg);

        if path.exists() && path.is_relative() {
            cmd.arg(&current_dir.join(path));
        } else {
            cmd.arg(arg);
        }
    }

    // Create temporary directory
    let temp_dir = TempDir::new("rust").unwrap();
    let temp_dir_path = temp_dir.path();

    // Inherit stdio
    cmd.stderr(Stdio::inherit());
    cmd.stdin(Stdio::inherit());
    cmd.stdout(Stdio::inherit());

    // Compile
    info!("cwd: {:?} | cmd: `{:?}`", temp_dir_path, cmd);
    match cmd.current_dir(temp_dir_path).output() {
        Err(e) => panic!("`{:?}` failed: {}", cmd, e),
        Ok(output) => if !output.status.success() {
            env::set_exit_status(output.status.code().unwrap());

            return;
        },
    }

    // Look for the produced binary
    let mut cmd = match fs::read_dir(temp_dir_path) {
        Err(e) => panic!("`ls {:?}` failed: {}", temp_dir_path, e),
        Ok(mut paths) => match paths.next() {
            Some(Ok(entry)) => Command::new(&entry.path()),
            _ => panic!("no binary found in {:?}", temp_dir_path),
        }
    };

    // Build the executable command
    match executable_args {
        None => {},
        Some(args) => {
            cmd.args(args);
        },
    }

    // Inherit stdio
    cmd.stderr(Stdio::inherit());
    cmd.stdin(Stdio::inherit());
    cmd.stdout(Stdio::inherit());

    // Execute
    info!("cwd: . | cmd: `{:?}`", cmd);
    match cmd.output() {
        Err(e) => panic!("`{:?}` failed: {}", cmd, e),
        Ok(output) => if !output.status.success() {

            env::set_exit_status(output.status.code().unwrap());

            return;
        },
    }
}
<commit_msg>fix: update to rust nightly<commit_after>#![deny(warnings)]
#![feature(exit_status)]
#![feature(path_ext)]

extern crate env_logger;
#[macro_use]
extern crate log;
extern crate tempdir;

use std::env;
use std::fs::{PathExt, self};
use std::path::Path;
use std::process::{Command, Stdio};

use tempdir::TempDir;

fn main() {
    env_logger::init().unwrap();

    let args: Vec<_> = env::args().skip(1).collect();

    // If `--run` is not in the arguments: pass all the arguments to `rustc`
    if args.iter().all(|arg| *arg != "--run") {
        let mut cmd = Command::new("rustc");
        cmd.args(&args);

        // Inherit stdio
        cmd.stderr(Stdio::inherit());
        cmd.stdin(Stdio::inherit());
        cmd.stdout(Stdio::inherit());

        info!("cwd: . | cmd: `{:?}`", cmd);
        match cmd.output() {
            Err(e) => panic!("`{:?}` failed: {}", cmd, e),
            Ok(output) =>  {
                env::set_exit_status(output.status.code().unwrap());

                return;
            },
        }
    }

    // Before `--`: arguments for the compiler
    // After `--`: arguments for the executable
    let mut splitted_args = args.split(|arg| *arg == "--");
    let compiler_args = splitted_args.next().unwrap();
    let executable_args = splitted_args.next();

    // TODO `--crate-type=lib` should also be forbidden
    // XXX What if the crate has a `crate_type=*lib` attribute?
    if compiler_args.iter().any(|arg| *arg == "--out-dir") {
        panic!("Can't use both `--out-dir` and `--run` flags at the same time");
    }

    // Build the rustc command
    let mut cmd = Command::new("rustc");
    // Make all paths absolute, filter out the `--run` flag
    let current_dir = env::current_dir().ok().expect("Couldn't fetch the current directory");
    for arg in compiler_args.iter().filter(|arg| **arg != "--run") {
        let path = Path::new(arg);

        if path.exists() && path.is_relative() {
            cmd.arg(&current_dir.join(path));
        } else {
            cmd.arg(arg);
        }
    }

    // Create temporary directory
    let temp_dir = TempDir::new("rust").unwrap();
    let temp_dir_path = temp_dir.path();

    // Inherit stdio
    cmd.stderr(Stdio::inherit());
    cmd.stdin(Stdio::inherit());
    cmd.stdout(Stdio::inherit());

    // Compile
    info!("cwd: {:?} | cmd: `{:?}`", temp_dir_path, cmd);
    match cmd.current_dir(temp_dir_path).output() {
        Err(e) => panic!("`{:?}` failed: {}", cmd, e),
        Ok(output) => if !output.status.success() {
            env::set_exit_status(output.status.code().unwrap());

            return;
        },
    }

    // Look for the produced binary
    let mut cmd = match fs::read_dir(temp_dir_path) {
        Err(e) => panic!("`ls {:?}` failed: {}", temp_dir_path, e),
        Ok(mut paths) => match paths.next() {
            Some(Ok(entry)) => Command::new(&entry.path()),
            _ => panic!("no binary found in {:?}", temp_dir_path),
        }
    };

    // Build the executable command
    match executable_args {
        None => {},
        Some(args) => {
            cmd.args(args);
        },
    }

    // Inherit stdio
    cmd.stderr(Stdio::inherit());
    cmd.stdin(Stdio::inherit());
    cmd.stdout(Stdio::inherit());

    // Execute
    info!("cwd: . | cmd: `{:?}`", cmd);
    match cmd.output() {
        Err(e) => panic!("`{:?}` failed: {}", cmd, e),
        Ok(output) => if !output.status.success() {

            env::set_exit_status(output.status.code().unwrap());

            return;
        },
    }
}
<|endoftext|>


<commit_before>extern crate rand;

use std::string::String;
use std::collections::HashMap;
use std::vec::Vec;
use std::fs::{File};
use std::env;
use std::path::{Path};
use std::io::{self, BufReader, BufRead};
use std::iter;

use rand::{Closed01, Rng};
use rand::distributions::{IndependentSample, Sample, Gamma, LogNormal, RandSample};

type Bag = HashMap<usize, usize>;

fn load_bags<P: AsRef<Path>>(path: P) -> io::Result<(Vec<usize>, Vec<Bag>, usize)> {
    let mut bags = Vec::new();
    let mut labels = Vec::new();
    let mut vocab_size = 0;
    let file = try!(File::open(path));
    let file = BufReader::new(file);
    for line in file.lines() {
        let line = line.unwrap();
        let mut iter = line.split_whitespace();
        let label = iter.next().unwrap().parse::<usize>().unwrap();
        let mut bag = Bag::new();
        for elm in iter {
            let mut iter = elm.split(':');
            let index = iter.next().unwrap().parse::<usize>().unwrap();
            let value = iter.next().unwrap().parse::<usize>().unwrap();
            bag.insert(index - 1, value);    // We assume one-based indexing
            if vocab_size < index {
                vocab_size = index;
            }
        }
        labels.push(label);
        bags.push(bag);
    }
    Ok((labels, bags, vocab_size))
}

fn load_text_vocabulary<P: AsRef<Path>>(path: P) -> io::Result<Vec<String>> {
    let mut vocab = Vec::new();
    let file = try!(File::open(path));
    let file = BufReader::new(file);
    for line in file.lines() {
        let line = line.unwrap();
        vocab.push(line);
    }
    Ok(vocab)
}

#[derive(Clone)]
struct Categorical {
    prop: Vec<f64>,
}

impl Categorical {
    fn new(weights: Vec<f64>) -> Categorical {
        let sum: f64 = weights.iter().sum();
        let prop: Vec<f64> = weights.iter().map(|w| w / sum).collect();
        Categorical {
            prop: prop,
        }
    }
}

impl Sample<usize> for Categorical {
    fn sample<R: Rng>(&mut self, rng: &mut R) -> usize {
        self.ind_sample(rng)
    }
}

impl IndependentSample<usize> for Categorical {
    fn ind_sample<R: Rng>(&self, rng: &mut R) -> usize {
        let closed01 = RandSample::<Closed01<f64>>::new();
        let Closed01(x) = closed01.ind_sample(rng);

        let mut sum = 0.0;
        let mut ret = self.prop.len() - 1;
        for (k, &p) in self.prop.iter().enumerate() {
            sum += p;
            if x <= sum {
                ret = k;
                break;
            }
        }
        ret
    }
}

#[derive(Clone)]
struct Dirichlet {
    alpha: Vec<f64>,
}

impl Dirichlet {
    fn new(alpha: Vec<f64>) -> Dirichlet {
        Dirichlet {
            alpha: alpha,
        }
    }
}

impl Sample<Vec<f64>> for Dirichlet {
    fn sample<R: Rng>(&mut self, rng: &mut R) -> Vec<f64> {
        self.ind_sample(rng)
    }
}

impl IndependentSample<Vec<f64>> for Dirichlet {
    fn ind_sample<R: Rng>(&self, rng: &mut R) -> Vec<f64> {
        let mut sum = 0.0;
        let mut xs = Vec::new();
        for &a in &self.alpha {
            let gamma = Gamma::new(a, 1.0);
            let y = gamma.ind_sample(rng);
            xs.push(y);
            sum += y;
        }
        for x in xs.iter_mut() {
            *x /= sum;
        }
        xs
    }
}

fn lda(dataset: Vec<Bag>, alpha: Vec<f64>, beta: Vec<f64>, burn_in: usize, num_samples: usize) {
    // Initialization
    let num_topics: usize = alpha.len();
    let vocab_size: usize = beta.len();
    println!("K = {}", num_topics);
    println!("M = {}", &dataset.len());
    println!("V = {}", vocab_size);

    let mut w: Vec<Vec<usize>> = Vec::new();
    let mut z: Vec<Vec<usize>> = Vec::new();
    let mut z_samples: Vec<Vec<Vec<usize>>> = Vec::new();
    let mut theta: Vec<Vec<f64>> = Vec::new();
    let mut ndk: Vec<Vec<usize>> = Vec::new();
    for bag in &dataset {
        // w
        let mut w_d = Vec::new();
        for (&index, &count) in bag {
            for _ in 0..count {
                w_d.push(index);
            }
        }
        w.push(w_d);
        // z
        let mut z_d = Vec::new();
        let mut z_samples_d = Vec::new();
        for &count in bag.values() {
            for _ in 0..count {
                z_d.push(0);
                let zeros: Vec<usize> = iter::repeat(0).take(num_topics).collect();
                z_samples_d.push(zeros);
            }
        }
        let n_d = z_d.len();
        z.push(z_d);
        z_samples.push(z_samples_d);
        // theta
        let mut theta_d = Vec::with_capacity(num_topics);
        for _k in 0..num_topics {
            theta_d.push(1.0 / num_topics as f64);
        }
        theta.push(theta_d);
        // ndk
        let mut ndk_d = Vec::with_capacity(num_topics);
        ndk_d.push(n_d);
        for _k in 1..num_topics {
            ndk_d.push(0);
        }
        ndk.push(ndk_d);
    }
    println!("z = {:?}", z);
    println!("theta = {:?}", theta);
    println!("ndk = {:?}", ndk);

    let mut phi: Vec<Vec<f64>> = Vec::new();
    let mut nkv: Vec<Vec<usize>> = Vec::new();
    // phi
    for _k in 0..num_topics {
        let mut phi_k = Vec::new();
        for _v in 0..vocab_size {
            phi_k.push(1.0 / vocab_size as f64);
        }
        phi.push(phi_k);
    }
    // nkv
    let mut nkv_0 = Vec::new();
    for _v in 0..vocab_size {
        nkv_0.push(0);
    }
    for bag in &dataset {
        for (&index, &count) in bag {
            nkv_0[index] += count;
        }
    }
    nkv.push(nkv_0);
    for _k in 1..num_topics {
        let mut nkv_k = Vec::new();
        for _v in 0..vocab_size {
            nkv_k.push(0);
        }
        nkv.push(nkv_k);
    }
    println!("phi = {:?}", phi);
    println!("nkv = {:?}", nkv);

    // Sampling
    let mut rng = rand::thread_rng();
    for s in 0..(burn_in + num_samples) {
        for (d, w_d) in w.iter().enumerate() {
            for (i, &w_di) in w_d.iter().enumerate() {
                let v = w_di;
                // Sample z_di
                let mut weights: Vec<f64> = Vec::new();
                for k in 0..num_topics {
                    weights.push(theta[d][k] * phi[k][v]);
                }
                let cat = Categorical::new(weights);
                let old_z_di = z[d][i];
                let new_z_di = cat.ind_sample(&mut rng);
                z[d][i] = new_z_di;
                if s >= burn_in {
                    z_samples[d][i][new_z_di] += 1;
                }
                // Update ndk and nkv
                ndk[d][old_z_di] -= 1;
                ndk[d][new_z_di] += 1;
                nkv[old_z_di][v] -= 1;
                nkv[new_z_di][v] += 1;
            }
            // Sample theta_d
            let mut alpha_d: Vec<f64> = Vec::new();
            for k in 0..num_topics {
                alpha_d.push(ndk[d][k] as f64 + alpha[k]);
            }
            let dir = Dirichlet::new(alpha_d);
            theta[d] = dir.ind_sample(&mut rng);
        }
        for k in 0..num_topics {
            // Sample phi_k
            let mut beta_k: Vec<f64> = Vec::new();
            for v in 0..vocab_size {
                beta_k.push(nkv[k][v] as f64 + beta[v]);
            }
            let dir = Dirichlet::new(beta_k);
            phi[k] = dir.ind_sample(&mut rng);
        }
        // Evaluate the log-likelihood value for the current parameters
        let mut log_likelihood = 0.0;
        for k in 0..num_topics {
            for v in 0..vocab_size {
                log_likelihood += nkv[k][v] as f64 * f64::ln(phi[k][v]);
            }
        }
        println!("log_likelihood = {}", log_likelihood);
    }
    for (d, z_samples_d) in z_samples.iter().enumerate() {
        for (i, samples) in z_samples_d.iter().enumerate() {
            let mut sum = 0.0;
            for k in 0..num_topics {
                sum += samples[k] as f64;
            }
            print!("z[{:3}][{:3}] = ", d, i);
            for k in 0..num_topics {
                print!("{:3}:{:.2} ", k, samples[k] as f64 / sum);
            }
            println!("");
        }
    }
}

fn make_dataset(num_docs: usize, alpha: Vec<f64>, beta: Vec<f64>) -> Vec<Bag> {
    let num_topics: usize = alpha.len();
    let vocab_size: usize = beta.len();
    let mut rng = rand::thread_rng();
    // phi
    let dir_beta = Dirichlet::new(beta);
    let mut phi: Vec<Vec<f64>> = Vec::with_capacity(num_topics);
    for k in 0..num_topics {
        // Sample phi_k
        phi.push(dir_beta.ind_sample(&mut rng));
    }
    // theta, nd, z, w
    let dir_alpha = Dirichlet::new(alpha);
    let lognorm = LogNormal::new(100.0, 30.0);
    let mut theta: Vec<Vec<f64>> = Vec::with_capacity(num_docs);
    let mut nd: Vec<usize> = Vec::with_capacity(num_docs);
    let mut z: Vec<Vec<usize>> = Vec::with_capacity(num_docs);
    let mut w: Vec<Vec<usize>> = Vec::with_capacity(num_docs);
    for d in 0..num_docs {
        theta.push(dir_alpha.ind_sample(&mut rng));
        nd.push(f64::floor(lognorm.ind_sample(&mut rng)) as usize);
        let cat_theta = Categorical::new(theta[d].clone());
        let mut z_d = Vec::with_capacity(nd[d]);
        let mut w_d = Vec::with_capacity(nd[d]);
        for i in 0..nd[d] {
            z_d.push(cat_theta.ind_sample(&mut rng));
            let cat_phi = Categorical::new(phi[z_d[i]].clone());
            w_d.push(cat_phi.ind_sample(&mut rng));
        }
        z.push(z_d);
        w.push(w_d);
    }
    // Make bags
    let mut bags: Vec<Bag> = Vec::new();
    for w_d in w {
        let mut bag: Bag = Bag::new();
        for v in w_d {
            let counter = bag.entry(v).or_insert(0);
            *counter += 1;
        }
        bags.push(bag);
    }
    bags
}

fn main() {
    let args: Vec<String> = env::args().collect();
    let (labels, dataset, vocab_size) = load_bags(&args[1]).unwrap();
    let vocab: Option<Vec<String>> = if args.len() < 3 {
        None
    }
    else {
        Some(load_text_vocabulary(&args[2]).unwrap())
    };
    println!("{:?}", labels);
    println!("{:?}", dataset);
    println!("{:?}", vocab);

    let num_topics = 3;
    let alpha: Vec<f64> = iter::repeat(1.0).take(num_topics).collect();
    let beta: Vec<f64> = iter::repeat(1.0).take(vocab_size).collect();

    lda(dataset, alpha, beta, 1000, 10000);
}
<commit_msg>Make make_dataset() take parameters for a log-normal distribution<commit_after>extern crate rand;

use std::string::String;
use std::collections::HashMap;
use std::vec::Vec;
use std::fs::{File};
use std::env;
use std::path::{Path};
use std::io::{self, BufReader, BufRead};
use std::iter;

use rand::{Closed01, Rng};
use rand::distributions::{IndependentSample, Sample, Gamma, LogNormal, RandSample};

type Bag = HashMap<usize, usize>;

fn load_bags<P: AsRef<Path>>(path: P) -> io::Result<(Vec<usize>, Vec<Bag>, usize)> {
    let mut bags = Vec::new();
    let mut labels = Vec::new();
    let mut vocab_size = 0;
    let file = try!(File::open(path));
    let file = BufReader::new(file);
    for line in file.lines() {
        let line = line.unwrap();
        let mut iter = line.split_whitespace();
        let label = iter.next().unwrap().parse::<usize>().unwrap();
        let mut bag = Bag::new();
        for elm in iter {
            let mut iter = elm.split(':');
            let index = iter.next().unwrap().parse::<usize>().unwrap();
            let value = iter.next().unwrap().parse::<usize>().unwrap();
            bag.insert(index - 1, value);    // We assume one-based indexing
            if vocab_size < index {
                vocab_size = index;
            }
        }
        labels.push(label);
        bags.push(bag);
    }
    Ok((labels, bags, vocab_size))
}

fn load_text_vocabulary<P: AsRef<Path>>(path: P) -> io::Result<Vec<String>> {
    let mut vocab = Vec::new();
    let file = try!(File::open(path));
    let file = BufReader::new(file);
    for line in file.lines() {
        let line = line.unwrap();
        vocab.push(line);
    }
    Ok(vocab)
}

#[derive(Clone)]
struct Categorical {
    prop: Vec<f64>,
}

impl Categorical {
    fn new(weights: Vec<f64>) -> Categorical {
        let sum: f64 = weights.iter().sum();
        let prop: Vec<f64> = weights.iter().map(|w| w / sum).collect();
        Categorical {
            prop: prop,
        }
    }
}

impl Sample<usize> for Categorical {
    fn sample<R: Rng>(&mut self, rng: &mut R) -> usize {
        self.ind_sample(rng)
    }
}

impl IndependentSample<usize> for Categorical {
    fn ind_sample<R: Rng>(&self, rng: &mut R) -> usize {
        let closed01 = RandSample::<Closed01<f64>>::new();
        let Closed01(x) = closed01.ind_sample(rng);

        let mut sum = 0.0;
        let mut ret = self.prop.len() - 1;
        for (k, &p) in self.prop.iter().enumerate() {
            sum += p;
            if x <= sum {
                ret = k;
                break;
            }
        }
        ret
    }
}

#[derive(Clone)]
struct Dirichlet {
    alpha: Vec<f64>,
}

impl Dirichlet {
    fn new(alpha: Vec<f64>) -> Dirichlet {
        Dirichlet {
            alpha: alpha,
        }
    }
}

impl Sample<Vec<f64>> for Dirichlet {
    fn sample<R: Rng>(&mut self, rng: &mut R) -> Vec<f64> {
        self.ind_sample(rng)
    }
}

impl IndependentSample<Vec<f64>> for Dirichlet {
    fn ind_sample<R: Rng>(&self, rng: &mut R) -> Vec<f64> {
        let mut sum = 0.0;
        let mut xs = Vec::new();
        for &a in &self.alpha {
            let gamma = Gamma::new(a, 1.0);
            let y = gamma.ind_sample(rng);
            xs.push(y);
            sum += y;
        }
        for x in xs.iter_mut() {
            *x /= sum;
        }
        xs
    }
}

fn lda(dataset: Vec<Bag>, alpha: Vec<f64>, beta: Vec<f64>, burn_in: usize, num_samples: usize) {
    // Initialization
    let num_topics: usize = alpha.len();
    let vocab_size: usize = beta.len();
    println!("K = {}", num_topics);
    println!("M = {}", &dataset.len());
    println!("V = {}", vocab_size);

    let mut w: Vec<Vec<usize>> = Vec::new();
    let mut z: Vec<Vec<usize>> = Vec::new();
    let mut z_samples: Vec<Vec<Vec<usize>>> = Vec::new();
    let mut theta: Vec<Vec<f64>> = Vec::new();
    let mut ndk: Vec<Vec<usize>> = Vec::new();
    for bag in &dataset {
        // w
        let mut w_d = Vec::new();
        for (&index, &count) in bag {
            for _ in 0..count {
                w_d.push(index);
            }
        }
        w.push(w_d);
        // z
        let mut z_d = Vec::new();
        let mut z_samples_d = Vec::new();
        for &count in bag.values() {
            for _ in 0..count {
                z_d.push(0);
                let zeros: Vec<usize> = iter::repeat(0).take(num_topics).collect();
                z_samples_d.push(zeros);
            }
        }
        let n_d = z_d.len();
        z.push(z_d);
        z_samples.push(z_samples_d);
        // theta
        let mut theta_d = Vec::with_capacity(num_topics);
        for _k in 0..num_topics {
            theta_d.push(1.0 / num_topics as f64);
        }
        theta.push(theta_d);
        // ndk
        let mut ndk_d = Vec::with_capacity(num_topics);
        ndk_d.push(n_d);
        for _k in 1..num_topics {
            ndk_d.push(0);
        }
        ndk.push(ndk_d);
    }
    println!("z = {:?}", z);
    println!("theta = {:?}", theta);
    println!("ndk = {:?}", ndk);

    let mut phi: Vec<Vec<f64>> = Vec::new();
    let mut nkv: Vec<Vec<usize>> = Vec::new();
    // phi
    for _k in 0..num_topics {
        let mut phi_k = Vec::new();
        for _v in 0..vocab_size {
            phi_k.push(1.0 / vocab_size as f64);
        }
        phi.push(phi_k);
    }
    // nkv
    let mut nkv_0 = Vec::new();
    for _v in 0..vocab_size {
        nkv_0.push(0);
    }
    for bag in &dataset {
        for (&index, &count) in bag {
            nkv_0[index] += count;
        }
    }
    nkv.push(nkv_0);
    for _k in 1..num_topics {
        let mut nkv_k = Vec::new();
        for _v in 0..vocab_size {
            nkv_k.push(0);
        }
        nkv.push(nkv_k);
    }
    println!("phi = {:?}", phi);
    println!("nkv = {:?}", nkv);

    // Sampling
    let mut rng = rand::thread_rng();
    for s in 0..(burn_in + num_samples) {
        for (d, w_d) in w.iter().enumerate() {
            for (i, &w_di) in w_d.iter().enumerate() {
                let v = w_di;
                // Sample z_di
                let mut weights: Vec<f64> = Vec::new();
                for k in 0..num_topics {
                    weights.push(theta[d][k] * phi[k][v]);
                }
                let cat = Categorical::new(weights);
                let old_z_di = z[d][i];
                let new_z_di = cat.ind_sample(&mut rng);
                z[d][i] = new_z_di;
                if s >= burn_in {
                    z_samples[d][i][new_z_di] += 1;
                }
                // Update ndk and nkv
                ndk[d][old_z_di] -= 1;
                ndk[d][new_z_di] += 1;
                nkv[old_z_di][v] -= 1;
                nkv[new_z_di][v] += 1;
            }
            // Sample theta_d
            let mut alpha_d: Vec<f64> = Vec::new();
            for k in 0..num_topics {
                alpha_d.push(ndk[d][k] as f64 + alpha[k]);
            }
            let dir = Dirichlet::new(alpha_d);
            theta[d] = dir.ind_sample(&mut rng);
        }
        for k in 0..num_topics {
            // Sample phi_k
            let mut beta_k: Vec<f64> = Vec::new();
            for v in 0..vocab_size {
                beta_k.push(nkv[k][v] as f64 + beta[v]);
            }
            let dir = Dirichlet::new(beta_k);
            phi[k] = dir.ind_sample(&mut rng);
        }
        // Evaluate the log-likelihood value for the current parameters
        let mut log_likelihood = 0.0;
        for k in 0..num_topics {
            for v in 0..vocab_size {
                log_likelihood += nkv[k][v] as f64 * f64::ln(phi[k][v]);
            }
        }
        println!("log_likelihood = {}", log_likelihood);
    }
    for (d, z_samples_d) in z_samples.iter().enumerate() {
        for (i, samples) in z_samples_d.iter().enumerate() {
            let mut sum = 0.0;
            for k in 0..num_topics {
                sum += samples[k] as f64;
            }
            print!("z[{:3}][{:3}] = ", d, i);
            for k in 0..num_topics {
                print!("{:3}:{:.2} ", k, samples[k] as f64 / sum);
            }
            println!("");
        }
    }
}

fn make_dataset(num_docs: usize, mean_nd: f64, std_dev_nd: f64, alpha: Vec<f64>, beta: Vec<f64>) -> Vec<Bag> {
    let num_topics: usize = alpha.len();
    let vocab_size: usize = beta.len();
    let mut rng = rand::thread_rng();
    // phi
    let dir_beta = Dirichlet::new(beta);
    let mut phi: Vec<Vec<f64>> = Vec::with_capacity(num_topics);
    for k in 0..num_topics {
        // Sample phi_k
        phi.push(dir_beta.ind_sample(&mut rng));
    }
    // theta, nd, z, w
    let dir_alpha = Dirichlet::new(alpha);
    let lognorm = LogNormal::new(mean_nd, std_dev_nd);
    let mut theta: Vec<Vec<f64>> = Vec::with_capacity(num_docs);
    let mut nd: Vec<usize> = Vec::with_capacity(num_docs);
    let mut z: Vec<Vec<usize>> = Vec::with_capacity(num_docs);
    let mut w: Vec<Vec<usize>> = Vec::with_capacity(num_docs);
    for d in 0..num_docs {
        theta.push(dir_alpha.ind_sample(&mut rng));
        nd.push(f64::floor(lognorm.ind_sample(&mut rng)) as usize);
        let cat_theta = Categorical::new(theta[d].clone());
        let mut z_d = Vec::with_capacity(nd[d]);
        let mut w_d = Vec::with_capacity(nd[d]);
        for i in 0..nd[d] {
            z_d.push(cat_theta.ind_sample(&mut rng));
            let cat_phi = Categorical::new(phi[z_d[i]].clone());
            w_d.push(cat_phi.ind_sample(&mut rng));
        }
        z.push(z_d);
        w.push(w_d);
    }
    // Make bags
    let mut bags: Vec<Bag> = Vec::new();
    for w_d in w {
        let mut bag: Bag = Bag::new();
        for v in w_d {
            let counter = bag.entry(v).or_insert(0);
            *counter += 1;
        }
        bags.push(bag);
    }
    bags
}

fn main() {
    let args: Vec<String> = env::args().collect();
    let (labels, dataset, vocab_size) = load_bags(&args[1]).unwrap();
    let vocab: Option<Vec<String>> = if args.len() < 3 {
        None
    }
    else {
        Some(load_text_vocabulary(&args[2]).unwrap())
    };
    println!("{:?}", labels);
    println!("{:?}", dataset);
    println!("{:?}", vocab);

    let num_topics = 3;
    let alpha: Vec<f64> = iter::repeat(1.0).take(num_topics).collect();
    let beta: Vec<f64> = iter::repeat(1.0).take(vocab_size).collect();

    lda(dataset, alpha, beta, 1000, 10000);
}
<|endoftext|>


<commit_before>use std::io::Read;
use std::collections::HashMap;
use std::str::Split;

pub struct Command<'a> {
    command: &'a str,
    exec: Box<FnMut(Vec<&str>) + 'a>,
    complete: Option<Box<FnMut(Vec<&str>) + 'a>>
}

impl<'a> Command<'a> {
    fn new<T: FnMut(Vec<&str>) + 'a, U: FnMut(Vec<&str>) + 'a>(cmd: &'a str, exec_handler: T, complete_handler: Option<U>) -> Command<'a> {
        let mut obj = Command {
            command: cmd,
            exec: Box::new(exec_handler),
            complete: None
        };

        if let Some(cb) = complete_handler {
            obj.complete = Some(Box::new(cb));
        }

        obj
    }
}

pub struct Cli<'a> {
    commands: HashMap<&'a str, Command<'a>>
}

impl<'a> Cli<'a>{

    fn new() -> Cli<'a> {
        Cli {
            commands: HashMap::new()
        }
    }

    fn register<T: FnMut(Vec<&str>) + 'a>(&mut self, cmd: &'a str, exec: T) -> Result<(), Command> {
        let tmp = Command {
            command: cmd,
            exec: Box::new(exec),
            complete: None
        };

        match self.commands.insert(cmd, tmp) {
            Some(existing) => Err(existing),
            None => Ok(())
        }
    }

    fn complete(&self, argv: &str) -> Vec<&str> {
        println!("complete for '{}'", argv.trim());
        self.commands.keys()
            .filter(|cmd| cmd.starts_with(argv.trim()))
            .cloned()
            .collect()
    }

    fn exec(&mut self, cmd: &str) {
        if let Some(command) = self.commands.get_mut(cmd) {
            //TODO: figure out why I can't do that in one line
            let ref mut x = command.exec;
            x(vec!["blah"]);
        }
    }
}

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

    #[test]
    fn test_register_and_execute() {
        let mut called = false;
        {
            let mut cli = Cli::new();
            cli.register("my first command", | args | { called=true } );
            cli.exec("my first command");
        }
        assert!(called == true)
    }

    #[test]
    fn test_complete_empty_str() {
        let mut cli = Cli::new();
        cli.register("foo", | args | { } );
        cli.register("bar", | args | { } );
        assert!(vec!["foo", "bar"] == cli.complete(""))
    }

    #[test]
    fn test_complete_partial() {
        let mut cli = Cli::new();
        cli.register("foo", | args | { } );
        assert!(vec!["foo"] == cli.complete("f"));
        assert!(vec!["foo"] == cli.complete("fo"));
        assert!(vec!["foo"] == cli.complete("foo"));
    }

    #[test]
    fn test_complete_composite() {
        let mut cli = Cli::new();
        cli.register("foo bar", | args | { } );
        assert!(vec!["foo bar"] == cli.complete("f"));
        assert!(vec!["foo bar"] == cli.complete("foo"));
        assert!(vec!["foo bar"] == cli.complete("foo "));
        assert!(vec!["foo bar"] == cli.complete("foo b"));
    }
}

    //fn new(callback: Option<Box<Fn()>>) -> Cli<'a> {
        //Cli {
            //commands: HashMap::new(),
            //exec: callback,
            //complete_cb: None,
        //}
    //}

    //fn register<T: Fn() + 'static>(&mut self, command: Vec<&'a str>, callback: T) {
        //let mut it = command.iter();
        //self._register(it, callback);
    //}

    //fn _register<T: Fn() + 'static>(&mut self, mut it: std::slice::Iter<&'a str>, callback: T) {
        //if let Some(portion) = it.next() {
            //if !self.commands.contains_key(portion) {
                //self.commands.insert(portion, Cli::new(Some(Box::new(callback))));
            //}

            //self.commands.get_mut(portion).unwrap()._register(it, callback);
        //}
    //}

    //fn suggest(&mut self, command: &str) -> Vec<&str> {
        //let mut portions = command.trim().split(" ");
        //let mut suggestions = self._suggest(&mut portions);
        //if let Some(ref cb) = self.complete_cb {
            //cb();
            //println!("got callback");
        //}
        //suggestions
    //}

    //fn _suggest(&self, portions: &mut std::str::Split<&str>) -> Vec<&str> {
        //let mut ret = Vec::with_capacity(self.commands.len());

        //if let Some(portion) = portions.next() {
            //if !portion.is_empty() {
                //if let Some(cmd) = self.commands.get(portion) {
                    //ret = cmd._suggest(portions);
                //}
            //} else {
                //for key in self.commands.keys() {
                    //ret.push(*key);
                //}
            //}
        //} else {
            //for key in self.commands.keys() {
                //ret.push(*key);
            //}
        //}

        //ret
    //}
//}

fn foo(argv: Vec<&str>) {

}

fn main() {
    let mut cli = Cli::new();

    cli.register("show stuff", foo);
    cli.register("show other", foo);
    cli.register("list other cool", foo);
    cli.register("list other uncool", foo);

    loop {
        let mut line = String::new();
        std::io::stdin().read_line(&mut line).unwrap();

        println!("got: {:?}", cli.complete(&line));
    }
}
<commit_msg>meh ...<commit_after>use std::io::Read;
use std::collections::HashMap;
use std::str::Split;
use std::slice::Iter;

pub struct Command<'a> {
    command: Vec<&'a str>,
    exec: Box<FnMut(Vec<&str>) + 'a>,
    complete: Option<Box<FnMut(Vec<&str>) + 'a>>
}

impl<'a> Command<'a> {
    fn new<T: FnMut(Vec<&str>) + 'a, U: FnMut(Vec<&str>) + 'a>(cmd: Vec<&'a str>, exec_handler: T, complete_handler: Option<U>) -> Command<'a> {
        let mut obj = Command {
            command: cmd,
            exec: Box::new(exec_handler),
            complete: None
        };

        if let Some(cb) = complete_handler {
            obj.complete = Some(Box::new(cb));
        }

        obj
    }
}

pub struct Cli<'a> {
    commands: HashMap<&'a str, Option<Cli<'a>>>,
    handler: Option<Command<'a>>
}

impl<'a> Cli<'a>{

    fn new() -> Cli<'a> {
        Cli {
            commands: HashMap::new(),
            handler: None
        }
    }

    fn register<T: FnMut(Vec<&str>) + 'a>(&mut self, cmd: Vec<&'a str>, exec: T) -> Result<(), Command> {
        let tmp = Command {
            command: cmd.clone(),
            exec: Box::new(exec),
            complete: None
        };

        self._register(cmd.iter(), tmp)
    }

    fn _register(&mut self, it: Iter<&'a str>, command: Command, parent: &mut Cli) -> Result<(), Command> {
        let cli = Cli::new();

        if let Some(portion) = it.next() {
            if (!self.commands.contains_key(portion)) {
                self.commands.insert(portion, Some(cli));
            }
        }
        Ok(())
    }

    fn complete(&self, argv: &str) -> Vec<&str> {
        println!("complete for '{}'", argv.trim());
        self.commands.keys()
            .filter(|cmd| cmd.starts_with(argv.trim()))
            .cloned()
            .collect()
    }

    fn exec(&mut self, cmd: &str) {
        //if let Some(command) = self.commands.get_mut(cmd) {
            //TODO: figure out why I can't do that in one line
            //let ref mut x = command.exec;
            //x(vec!["blah"]);
        //}
    }
}

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

    #[test]
    fn test_register_and_execute() {
        let mut called = false;
        {
            let mut cli = Cli::new();
            cli.register(vec!["foo bar"], | args | { called=true } );
            cli.exec("foo bar");
        }
        assert!(called == true)
    }

    #[test]
    fn test_complete_empty_str() {
        let mut cli = Cli::new();
        cli.register(vec!["foo"], | args | { } );
        cli.register(vec!["bar"], | args | { } );
        assert!(vec!["foo", "bar"] == cli.complete(""))
    }

    #[test]
    fn test_complete_partial() {
        let mut cli = Cli::new();
        cli.register(vec!["foo"], | args | { } );
        assert!(vec!["foo"] == cli.complete("f"));
        assert!(vec!["foo"] == cli.complete("fo"));
        assert!(vec!["foo"] == cli.complete("foo"));
    }

    #[test]
    fn test_complete_composite() {
        let mut cli = Cli::new();
        cli.register(vec!["foo", "bar"], | args | { } );
        assert!(vec!["foo", "bar"] == cli.complete("f"));
        assert!(vec!["foo", "bar"] == cli.complete("foo"));
        assert!(vec!["foo", "bar"] == cli.complete("foo "));
        assert!(vec!["foo", "bar"] == cli.complete("foo b"));
    }
}

    //fn new(callback: Option<Box<Fn()>>) -> Cli<'a> {
        //Cli {
            //commands: HashMap::new(),
            //exec: callback,
            //complete_cb: None,
        //}
    //}

    //fn register<T: Fn() + 'static>(&mut self, command: Vec<&'a str>, callback: T) {
        //let mut it = command.iter();
        //self._register(it, callback);
    //}

    //fn _register<T: Fn() + 'static>(&mut self, mut it: std::slice::Iter<&'a str>, callback: T) {
        //if let Some(portion) = it.next() {
            //if !self.commands.contains_key(portion) {
                //self.commands.insert(portion, Cli::new(Some(Box::new(callback))));
            //}

            //self.commands.get_mut(portion).unwrap()._register(it, callback);
        //}
    //}

    //fn suggest(&mut self, command: &str) -> Vec<&str> {
        //let mut portions = command.trim().split(" ");
        //let mut suggestions = self._suggest(&mut portions);
        //if let Some(ref cb) = self.complete_cb {
            //cb();
            //println!("got callback");
        //}
        //suggestions
    //}

    //fn _suggest(&self, portions: &mut std::str::Split<&str>) -> Vec<&str> {
        //let mut ret = Vec::with_capacity(self.commands.len());

        //if let Some(portion) = portions.next() {
            //if !portion.is_empty() {
                //if let Some(cmd) = self.commands.get(portion) {
                    //ret = cmd._suggest(portions);
                //}
            //} else {
                //for key in self.commands.keys() {
                    //ret.push(*key);
                //}
            //}
        //} else {
            //for key in self.commands.keys() {
                //ret.push(*key);
            //}
        //}

        //ret
    //}
//}

fn foo(argv: Vec<&str>) {

}

fn main() {
    let mut cli = Cli::new();

    cli.register(vec!["show", "stuff"], foo);
    cli.register(vec!["show", "other"], foo);
    cli.register(vec!["list", "other cool"], foo);
    cli.register(vec!["list", "other uncool"], foo);

    loop {
        let mut line = String::new();
        std::io::stdin().read_line(&mut line).unwrap();

        println!("got: {:?}", cli.complete(&line));
    }
}
<|endoftext|>


<commit_before>use std::io::Command;

fn main() {
    Command::new("git").arg("commit").arg("-am").arg("Git commit & push on program execution.").status();
    Command::new("git").arg("push").arg("--force").status();
}
<commit_msg>Remove --force from push.<commit_after>use std::io::Command;

fn main() {
    Command::new("git").arg("commit").arg("-am").arg("Remove --force from push.").status();
    Command::new("git").arg("push").status();
}
<|endoftext|>


<commit_before>extern crate libc;
extern crate neovim;
extern crate rgtk;
extern crate "rustc-serialize" as rustc_serialize;

use rgtk::*;
use std::collections::HashSet;
use std::io::fs;
use std::io::fs::PathExtensions;

mod projects;
mod ui;
mod utils;

mod ffi {
    pub use libc::{c_int, c_uchar, c_void};
    pub use libc::funcs::posix88::unistd::{close, pipe, read, write};
    pub use libc::types::os::arch::c95::size_t;

    extern "C" {
        pub fn fork () -> c_int;
        pub fn kill (pid: c_int, sig: c_int);
    }
}

fn gui_main(
    pty: &mut gtk::VtePty,
    read_fd: ffi::c_int,
    write_fd: ffi::c_int,
    pid: ffi::c_int)
{
    gtk::init();

    // constants

    let width = 1242;
    let height = 768;
    let editor_height = ((height as f32) * 0.75) as i32;

    // create the window

    let title = format!("SolidOak {}.{}.{}",
                        option_env!("CARGO_PKG_VERSION_MAJOR").unwrap(),
                        option_env!("CARGO_PKG_VERSION_MINOR").unwrap(),
                        option_env!("CARGO_PKG_VERSION_PATCH").unwrap());
    let mut window = gtk::Window::new(gtk::WindowType::TopLevel).unwrap();
    window.set_title(title.as_slice());
    window.set_window_position(gtk::WindowPosition::Center);
    window.set_default_size(width, height);

    window.connect(gtk::signals::DeleteEvent::new(&mut |&: _| {
        unsafe {
            ffi::close(read_fd);
            ffi::close(write_fd);
            ffi::kill(pid, 15);
        }
        gtk::main_quit();
        true
    }));

    // create the panes

    let new_button = gtk::Button::new_with_label("New Project").unwrap();
    let import_button = gtk::Button::new_with_label("Import").unwrap();
    let rename_button = gtk::Button::new_with_label("Rename").unwrap();
    let remove_button = gtk::Button::new_with_label("Remove").unwrap();

    let mut project_buttons = gtk::Box::new(gtk::Orientation::Horizontal, 0).unwrap();
    project_buttons.set_size_request(-1, -1);
    project_buttons.add(&new_button);
    project_buttons.add(&import_button);
    project_buttons.add(&rename_button);
    project_buttons.add(&remove_button);

    let mut project_tree = gtk::TreeView::new().unwrap();
    let selection = project_tree.get_selection().unwrap();
    let column_types = [glib::ffi::g_type_string, glib::ffi::g_type_string];
    let store = gtk::TreeStore::new(&column_types).unwrap();
    let model = store.get_model().unwrap();
    project_tree.set_model(&model);
    project_tree.set_headers_visible(false);

    let mut scroll_pane = gtk::ScrolledWindow::new(None, None).unwrap();
    scroll_pane.add(&project_tree);

    let column = gtk::TreeViewColumn::new().unwrap();
    let cell = gtk::CellRendererText::new().unwrap();
    column.pack_start(&cell, true);
    column.add_attribute(&cell, "text", 0);
    project_tree.append_column(&column);

    let mut project_pane = gtk::Box::new(gtk::Orientation::Vertical, 0).unwrap();
    project_pane.set_size_request(-1, -1);
    project_pane.pack_start(&project_buttons, false, true, 0);
    project_pane.pack_start(&scroll_pane, true, true, 0);

    let mut editor_pane = gtk::VteTerminal::new().unwrap();
    editor_pane.set_size_request(-1, editor_height);
    editor_pane.set_pty(pty);
    editor_pane.watch_child(pid);

    let run_button = gtk::Button::new_with_label("Run").unwrap();
    let build_button = gtk::Button::new_with_label("Build").unwrap();
    let test_button = gtk::Button::new_with_label("Test").unwrap();
    let clean_button = gtk::Button::new_with_label("Clean").unwrap();
    let stop_button = gtk::Button::new_with_label("Stop").unwrap();

    let mut build_buttons = gtk::Box::new(gtk::Orientation::Horizontal, 0).unwrap();
    build_buttons.set_size_request(-1, -1);
    build_buttons.add(&run_button);
    build_buttons.add(&build_button);
    build_buttons.add(&test_button);
    build_buttons.add(&clean_button);
    build_buttons.add(&stop_button);

    let build_term = gtk::VteTerminal::new().unwrap();

    let mut build_pane = gtk::Box::new(gtk::Orientation::Vertical, 0).unwrap();
    build_pane.pack_start(&build_buttons, false, true, 0);
    build_pane.pack_start(&build_term, true, true, 0);

    let mut content = gtk::Box::new(gtk::Orientation::Vertical, 0).unwrap();
    content.pack_start(&editor_pane, false, true, 0);
    content.pack_start(&build_pane, true, true, 0);

    let mut hbox = gtk::Box::new(gtk::Orientation::Horizontal, 0).unwrap();
    hbox.pack_start(&project_pane, false, true, 0);
    hbox.pack_start(&content, true, true, 0);
    window.add(&hbox);

    // populate the project tree

    let mut state = ::utils::State{
        projects: HashSet::new(),
        expansions: HashSet::new(),
        selection: None,
        tree_model: &model,
        tree_store: &store,
        tree_selection: &selection,
        rename_button: &rename_button,
        remove_button: &remove_button,
    };

    ::utils::read_prefs(&mut state);
    ::ui::update_project_tree(&mut state, &mut project_tree);

    // connect to the signals

    new_button.connect(gtk::signals::Clicked::new(&mut |&mut:| {
        ::projects::new_project(&mut state, &mut project_tree);
    }));
    import_button.connect(gtk::signals::Clicked::new(&mut |&mut:| {
        ::projects::import_project(&mut state, &mut project_tree);
    }));
    rename_button.connect(gtk::signals::Clicked::new(&mut |&mut:| {
        ::projects::rename_file(&mut state);
    }));
    remove_button.connect(gtk::signals::Clicked::new(&mut |&mut:| {
        ::projects::remove_item(&mut state);
    }));
    selection.connect(gtk::signals::Changed::new(&mut |&mut:| {
        ::projects::save_selection(&mut state);
    }));
    project_tree.connect(gtk::signals::RowCollapsed::new(&mut |&mut: iter_raw, _| {
        let iter = gtk::TreeIter::wrap_pointer(iter_raw);
        ::projects::remove_expansion(&mut state, &iter);
    }));
    project_tree.connect(gtk::signals::RowExpanded::new(&mut |&mut: iter_raw, _| {
        let iter = gtk::TreeIter::wrap_pointer(iter_raw);
        ::projects::add_expansion(&mut state, &iter);
    }));

    // show the window

    window.show_all();
    gtk::main();
}

fn receive_message (fd: ffi::c_int) -> Option<neovim::Array> {
    let mut buf : [ffi::c_uchar; 1024] = [0; 1024];
    let n = unsafe { ffi::read(fd, buf.as_mut_ptr() as *mut ffi::c_void, 1024) };
    if n < 0 {
        return None;
    }
    unsafe {
        let v = Vec::from_raw_buf(buf.as_ptr(), n as usize);
        let s = String::from_utf8_unchecked(v);
        Some(neovim::deserialize_message(&s))
    }
}

fn main() {
    // create data dir
    let home_dir = ::utils::get_home_dir();
    let data_dir = home_dir.join(::utils::DATA_DIR);
    if !data_dir.exists() {
        match fs::mkdir(&data_dir, ::std::io::USER_DIR) {
            Ok(_) => {
                for res in ::utils::DATA_CONTENT.iter() {
                    let res_path = data_dir.join_many(res.path);
                    ::std::io::fs::mkdir_recursive(&res_path.dir_path(), ::std::io::USER_DIR).ok();
                    ::std::io::File::create(&res_path).write(res.data.as_bytes()).ok();
                }
                println!("Created data dir at {}", data_dir.as_str().unwrap());
            },
            Err(e) => { println!("Error creating data dir: {}", e) }
        }
    }

    // set $VIM to the data dir if it isn't already set
    if ::std::os::getenv("VIM").is_none() {
        ::std::os::setenv("VIM", data_dir.as_str().unwrap());
    }

    // create config file
    let config_file = home_dir.join(::utils::CONFIG_FILE);
    if !config_file.exists() {
        match ::std::io::File::create(&config_file).write(::utils::CONFIG_CONTENT.as_bytes()) {
            Ok(_) => { println!("Created config file at {}", config_file.as_str().unwrap()) },
            Err(e) => { println!("Error creating config file: {}", e) }
        }
    }

    // takes care of piping stdin/stdout between the gui and nvim
    let mut pty = gtk::VtePty::new().unwrap();

    // two pairs of anonymous pipes for msgpack-rpc between the gui and nvim
    let mut nvim_from_gui : [ffi::c_int; 2] = [0; 2];
    let mut gui_from_nvim : [ffi::c_int; 2] = [0; 2];
    unsafe {
        ffi::pipe(nvim_from_gui.as_mut_ptr());
        ffi::pipe(gui_from_nvim.as_mut_ptr());
    };

    // split into two processes
    let pid = unsafe { ffi::fork() };

    if pid > 0 { // the gui process
        ::std::thread::Thread::spawn(move || {
            // send attach_ui message
            {
                let mut arr = neovim::Array::new();
                arr.add_integer(80);
                arr.add_integer(24);
                let msg = neovim::serialize_message(1, "attach_ui", &arr);
                let msg_ptr = msg.as_slice().as_ptr() as *const ffi::c_void;
                unsafe { ffi::write(nvim_from_gui[1], msg_ptr, msg.len() as ffi::size_t) };
                if let Some(recv_arr) = receive_message(gui_from_nvim[0]) {
                    println!("Received: {:?}", recv_arr);
                }
            }

            // send vim_subscribe message
            {
                let mut arr = neovim::Array::new();
                arr.add_string("bufread");
                let msg = neovim::serialize_message(1, "vim_subscribe", &arr);
                let msg_ptr = msg.as_slice().as_ptr() as *const ffi::c_void;
                unsafe { ffi::write(nvim_from_gui[1], msg_ptr, msg.len() as ffi::size_t) };
                if let Some(recv_arr) = receive_message(gui_from_nvim[0]) {
                    println!("Received: {:?}", recv_arr);
                }
            }

            // send vim_command message
            {
                let mut arr = neovim::Array::new();
                let s = format!("au BufRead * call rpcnotify(1, \"bufread\", bufname(\"\"))");
                arr.add_string(s.as_slice());
                let msg = neovim::serialize_message(1, "vim_command", &arr);
                let msg_ptr = msg.as_slice().as_ptr() as *const ffi::c_void;
                unsafe { ffi::write(nvim_from_gui[1], msg_ptr, msg.len() as ffi::size_t) };
                if let Some(recv_arr) = receive_message(gui_from_nvim[0]) {
                    println!("Received: {:?}", recv_arr);
                }
            }

            // listen for messages
            while let Some(recv_arr) = receive_message(gui_from_nvim[0]) {
                if recv_arr.len() > 0 {
                    println!("Received: {:?}", recv_arr);
                }
            }
        });

        // start the gui
        gui_main(&mut pty, gui_from_nvim[0], gui_from_nvim[1], pid);
    } else { // the nvim process
        // prepare this process to be piped into the gui
        pty.child_setup();

        // start nvim
        let mut args = ::std::os::args().clone();
        args.push_all(&["-u".to_string(), config_file.as_str().unwrap().to_string()]);
        neovim::main_setup(args);
        neovim::channel_from_fds(nvim_from_gui[0], gui_from_nvim[1]);
        neovim::main_loop();
    }
}
<commit_msg>Update for latest version of Neovim<commit_after>extern crate libc;
extern crate neovim;
extern crate rgtk;
extern crate "rustc-serialize" as rustc_serialize;

use rgtk::*;
use std::collections::HashSet;
use std::io::fs;
use std::io::fs::PathExtensions;

mod projects;
mod ui;
mod utils;

mod ffi {
    pub use libc::{c_int, c_uchar, c_void};
    pub use libc::funcs::posix88::unistd::{close, pipe, read, write};
    pub use libc::types::os::arch::c95::size_t;

    extern "C" {
        pub fn fork () -> c_int;
        pub fn kill (pid: c_int, sig: c_int);
    }
}

fn gui_main(
    pty: &mut gtk::VtePty,
    read_fd: ffi::c_int,
    write_fd: ffi::c_int,
    pid: ffi::c_int)
{
    gtk::init();

    // constants

    let width = 1242;
    let height = 768;
    let editor_height = ((height as f32) * 0.75) as i32;

    // create the window

    let title = format!("SolidOak {}.{}.{}",
                        option_env!("CARGO_PKG_VERSION_MAJOR").unwrap(),
                        option_env!("CARGO_PKG_VERSION_MINOR").unwrap(),
                        option_env!("CARGO_PKG_VERSION_PATCH").unwrap());
    let mut window = gtk::Window::new(gtk::WindowType::TopLevel).unwrap();
    window.set_title(title.as_slice());
    window.set_window_position(gtk::WindowPosition::Center);
    window.set_default_size(width, height);

    window.connect(gtk::signals::DeleteEvent::new(&mut |&: _| {
        unsafe {
            ffi::close(read_fd);
            ffi::close(write_fd);
            ffi::kill(pid, 15);
        }
        gtk::main_quit();
        true
    }));

    // create the panes

    let new_button = gtk::Button::new_with_label("New Project").unwrap();
    let import_button = gtk::Button::new_with_label("Import").unwrap();
    let rename_button = gtk::Button::new_with_label("Rename").unwrap();
    let remove_button = gtk::Button::new_with_label("Remove").unwrap();

    let mut project_buttons = gtk::Box::new(gtk::Orientation::Horizontal, 0).unwrap();
    project_buttons.set_size_request(-1, -1);
    project_buttons.add(&new_button);
    project_buttons.add(&import_button);
    project_buttons.add(&rename_button);
    project_buttons.add(&remove_button);

    let mut project_tree = gtk::TreeView::new().unwrap();
    let selection = project_tree.get_selection().unwrap();
    let column_types = [glib::ffi::g_type_string, glib::ffi::g_type_string];
    let store = gtk::TreeStore::new(&column_types).unwrap();
    let model = store.get_model().unwrap();
    project_tree.set_model(&model);
    project_tree.set_headers_visible(false);

    let mut scroll_pane = gtk::ScrolledWindow::new(None, None).unwrap();
    scroll_pane.add(&project_tree);

    let column = gtk::TreeViewColumn::new().unwrap();
    let cell = gtk::CellRendererText::new().unwrap();
    column.pack_start(&cell, true);
    column.add_attribute(&cell, "text", 0);
    project_tree.append_column(&column);

    let mut project_pane = gtk::Box::new(gtk::Orientation::Vertical, 0).unwrap();
    project_pane.set_size_request(-1, -1);
    project_pane.pack_start(&project_buttons, false, true, 0);
    project_pane.pack_start(&scroll_pane, true, true, 0);

    let mut editor_pane = gtk::VteTerminal::new().unwrap();
    editor_pane.set_size_request(-1, editor_height);
    editor_pane.set_pty(pty);
    editor_pane.watch_child(pid);

    let run_button = gtk::Button::new_with_label("Run").unwrap();
    let build_button = gtk::Button::new_with_label("Build").unwrap();
    let test_button = gtk::Button::new_with_label("Test").unwrap();
    let clean_button = gtk::Button::new_with_label("Clean").unwrap();
    let stop_button = gtk::Button::new_with_label("Stop").unwrap();

    let mut build_buttons = gtk::Box::new(gtk::Orientation::Horizontal, 0).unwrap();
    build_buttons.set_size_request(-1, -1);
    build_buttons.add(&run_button);
    build_buttons.add(&build_button);
    build_buttons.add(&test_button);
    build_buttons.add(&clean_button);
    build_buttons.add(&stop_button);

    let build_term = gtk::VteTerminal::new().unwrap();

    let mut build_pane = gtk::Box::new(gtk::Orientation::Vertical, 0).unwrap();
    build_pane.pack_start(&build_buttons, false, true, 0);
    build_pane.pack_start(&build_term, true, true, 0);

    let mut content = gtk::Box::new(gtk::Orientation::Vertical, 0).unwrap();
    content.pack_start(&editor_pane, false, true, 0);
    content.pack_start(&build_pane, true, true, 0);

    let mut hbox = gtk::Box::new(gtk::Orientation::Horizontal, 0).unwrap();
    hbox.pack_start(&project_pane, false, true, 0);
    hbox.pack_start(&content, true, true, 0);
    window.add(&hbox);

    // populate the project tree

    let mut state = ::utils::State{
        projects: HashSet::new(),
        expansions: HashSet::new(),
        selection: None,
        tree_model: &model,
        tree_store: &store,
        tree_selection: &selection,
        rename_button: &rename_button,
        remove_button: &remove_button,
    };

    ::utils::read_prefs(&mut state);
    ::ui::update_project_tree(&mut state, &mut project_tree);

    // connect to the signals

    new_button.connect(gtk::signals::Clicked::new(&mut |&mut:| {
        ::projects::new_project(&mut state, &mut project_tree);
    }));
    import_button.connect(gtk::signals::Clicked::new(&mut |&mut:| {
        ::projects::import_project(&mut state, &mut project_tree);
    }));
    rename_button.connect(gtk::signals::Clicked::new(&mut |&mut:| {
        ::projects::rename_file(&mut state);
    }));
    remove_button.connect(gtk::signals::Clicked::new(&mut |&mut:| {
        ::projects::remove_item(&mut state);
    }));
    selection.connect(gtk::signals::Changed::new(&mut |&mut:| {
        ::projects::save_selection(&mut state);
    }));
    project_tree.connect(gtk::signals::RowCollapsed::new(&mut |&mut: iter_raw, _| {
        let iter = gtk::TreeIter::wrap_pointer(iter_raw);
        ::projects::remove_expansion(&mut state, &iter);
    }));
    project_tree.connect(gtk::signals::RowExpanded::new(&mut |&mut: iter_raw, _| {
        let iter = gtk::TreeIter::wrap_pointer(iter_raw);
        ::projects::add_expansion(&mut state, &iter);
    }));

    // show the window

    window.show_all();
    gtk::main();
}

fn receive_message (fd: ffi::c_int) -> Option<neovim::Array> {
    let mut buf : [ffi::c_uchar; 1024] = [0; 1024];
    let n = unsafe { ffi::read(fd, buf.as_mut_ptr() as *mut ffi::c_void, 1024) };
    if n < 0 {
        return None;
    }
    unsafe {
        let v = Vec::from_raw_buf(buf.as_ptr(), n as usize);
        let s = String::from_utf8_unchecked(v);
        Some(neovim::deserialize_message(&s))
    }
}

fn main() {
    // create data dir
    let home_dir = ::utils::get_home_dir();
    let data_dir = home_dir.join(::utils::DATA_DIR);
    if !data_dir.exists() {
        match fs::mkdir(&data_dir, ::std::io::USER_DIR) {
            Ok(_) => {
                for res in ::utils::DATA_CONTENT.iter() {
                    let res_path = data_dir.join_many(res.path);
                    ::std::io::fs::mkdir_recursive(&res_path.dir_path(), ::std::io::USER_DIR).ok();
                    ::std::io::File::create(&res_path).write(res.data.as_bytes()).ok();
                }
                println!("Created data dir at {}", data_dir.as_str().unwrap());
            },
            Err(e) => { println!("Error creating data dir: {}", e) }
        }
    }

    // set $VIM to the data dir if it isn't already set
    if ::std::os::getenv("VIM").is_none() {
        ::std::os::setenv("VIM", data_dir.as_str().unwrap());
    }

    // create config file
    let config_file = home_dir.join(::utils::CONFIG_FILE);
    if !config_file.exists() {
        match ::std::io::File::create(&config_file).write(::utils::CONFIG_CONTENT.as_bytes()) {
            Ok(_) => { println!("Created config file at {}", config_file.as_str().unwrap()) },
            Err(e) => { println!("Error creating config file: {}", e) }
        }
    }

    // takes care of piping stdin/stdout between the gui and nvim
    let mut pty = gtk::VtePty::new().unwrap();

    // two pairs of anonymous pipes for msgpack-rpc between the gui and nvim
    let mut nvim_from_gui : [ffi::c_int; 2] = [0; 2];
    let mut gui_from_nvim : [ffi::c_int; 2] = [0; 2];
    unsafe {
        ffi::pipe(nvim_from_gui.as_mut_ptr());
        ffi::pipe(gui_from_nvim.as_mut_ptr());
    };

    // split into two processes
    let pid = unsafe { ffi::fork() };

    if pid > 0 { // the gui process
        ::std::thread::Thread::spawn(move || {
            // start communicating with nvim
            {
                let mut arr = neovim::Array::new();
                arr.add_integer(80);
                arr.add_integer(24);
                arr.add_boolean(true);
                let msg = neovim::serialize_message(1, "ui_attach", &arr);
                let msg_ptr = msg.as_slice().as_ptr() as *const ffi::c_void;
                unsafe { ffi::write(nvim_from_gui[1], msg_ptr, msg.len() as ffi::size_t) };
                if let Some(recv_arr) = receive_message(gui_from_nvim[0]) {
                    println!("Received: {:?}", recv_arr);
                }
            }

            // listen for bufread events
            {
                let mut arr = neovim::Array::new();
                let s = format!("au BufRead * call rpcnotify(1, \"bufread\", bufname(\"\"))");
                arr.add_string(s.as_slice());
                let msg = neovim::serialize_message(1, "vim_command", &arr);
                let msg_ptr = msg.as_slice().as_ptr() as *const ffi::c_void;
                unsafe { ffi::write(nvim_from_gui[1], msg_ptr, msg.len() as ffi::size_t) };
                if let Some(recv_arr) = receive_message(gui_from_nvim[0]) {
                    println!("Received: {:?}", recv_arr);
                }
            }

            // listen for messages
            while let Some(recv_arr) = receive_message(gui_from_nvim[0]) {
                if recv_arr.len() > 0 {
                    println!("Received: {:?}", recv_arr);
                }
            }
        });

        // start the gui
        gui_main(&mut pty, gui_from_nvim[0], gui_from_nvim[1], pid);
    } else { // the nvim process
        // prepare this process to be piped into the gui
        pty.child_setup();

        // start nvim
        let mut args = ::std::os::args().clone();
        args.push_all(&["-u".to_string(), config_file.as_str().unwrap().to_string()]);
        neovim::main_setup(args);
        neovim::channel_from_fds(nvim_from_gui[0], gui_from_nvim[1]);
        neovim::main_loop();
    }
}
<|endoftext|>


<commit_before>fn main() {
    println!("Hello, world!");
}
<commit_msg>start the chip8 struct<commit_after>struct Chip8Unit {
    /*
     * 0x000-0x1FF - Chip 8 interpreter (contains font set in emu)
     * 0x050-0x0A0 - Used for the built in 4x5 pixel font set (0-F)
     * 0x200-0xFFF - Program ROM and work RAM
     */
    memory:    [u8; 4096],

    /*
     * CPU registers: The Chip 8 has 15 8-bit general purpose registers
     * named V0,V1 up to VE. The 16th register is used  for the ‘carry flag’.
     */
    registers: [u8; 16],

    // Index register
    i: u16,

    // program counter
    pc: u16,

    // Screen - 64 x 32 pixels
    graphics: [u8; 64*32],

    // No timers, but 60hz counters
    delay_timer: u8,
    sound_timer: u8,

    // Stack needed to jump to certain addresses or call subroutines
    // The chip8 stack has 16 levels
    stack_pointer: u16,
    stack: [u16; 16],

    // Chip8 keypad had 16 keys - keep track of the kb state
    keypad: [u8; 16],
}

fn main() {
    println!("Hello, world!");
}
<|endoftext|>


<commit_before>#![recursion_limit = "128"]

extern crate ape;
extern crate app_dirs;
extern crate core;
#[macro_use]
extern crate error_chain;
extern crate getopts;
extern crate hyper;
extern crate id3;
extern crate image;
extern crate iron;
extern crate lewton;
extern crate metaflac;
extern crate mount;
extern crate ogg;
extern crate oven;
extern crate params;
extern crate regex;
extern crate serde;
#[macro_use]
extern crate serde_derive;
extern crate serde_json;
extern crate staticfile;
extern crate sqlite;
extern crate toml;
extern crate url;

#[cfg(windows)]
extern crate uuid;
#[cfg(windows)]
extern crate winapi;
#[cfg(windows)]
extern crate kernel32;
#[cfg(windows)]
extern crate shell32;
#[cfg(windows)]
extern crate user32;

use errors::*;
use getopts::Options;
use iron::prelude::*;
use mount::Mount;
use staticfile::Static;
use std::path::Path;
use std::sync::Arc;

mod api;
mod collection;
mod config;
mod ddns;
mod errors;
mod index;
mod metadata;
mod ui;
mod utils;
mod thumbnails;
mod vfs;

fn main() {
	if let Err(ref e) = run() {
		println!("Error: {}", e);

		for e in e.iter().skip(1) {
			println!("caused by: {}", e);
		}
		if let Some(backtrace) = e.backtrace() {
			println!("backtrace: {:?}", backtrace);
		}
		::std::process::exit(1);
	}
}

fn run() -> Result<()> {

	// Parse CLI options
	let args: Vec<String> = std::env::args().collect();
	let mut options = Options::new();
	options.optopt("c", "config", "set the configuration file", "FILE");
	let matches = match options.parse(&args[1..]) {
		Ok(m) => m,
		Err(f) => panic!(f.to_string()),
	};
	let config_file_name = matches.opt_str("c");
	let config_file_path = config_file_name.map(|n| Path::new(n.as_str()).to_path_buf());

	// Parse config
	let config = config::Config::parse(config_file_path)?;

	// Init VFS
	let vfs = Arc::new(vfs::Vfs::new(config.vfs.clone()));

	// Init index
	println!("Starting up index");
	let index = Arc::new(index::Index::new(vfs.clone(), &config.index)?);
	let index_ref = index.clone();
	std::thread::spawn(move || index_ref.run());

	// Start server
	println!("Starting up server");
	let mut api_chain;
	{
		let api_handler;
		{
			let mut collection = collection::Collection::new(vfs, index);
			collection.load_config(&config)?;
			let collection = Arc::new(collection);
			api_handler = api::get_api_handler(collection);
		}
		api_chain = Chain::new(api_handler);

		let auth_secret = config.secret.to_owned();
		let cookie_middleware = oven::new(auth_secret.into_bytes());
		api_chain.link(cookie_middleware);
	}

	let mut mount = Mount::new();
	mount.mount("/api/", api_chain);
	mount.mount("/", Static::new(Path::new("web")));
	let mut server = Iron::new(mount).http(("0.0.0.0", 5050))?;

	// Start DDNS updates
	match config.ddns {
		Some(ref ddns_config) => {
			let ddns_config = ddns_config.clone();
			std::thread::spawn(|| { ddns::run(ddns_config); });
		}
		None => (),
	};

	// Run UI
	ui::run();

	println!("Shutting down server");
	server.close()?;

	Ok(())
}
<commit_msg>Serve /web files from app data rather than relative path. Also added CLI option to serve from custom path.<commit_after>#![recursion_limit = "128"]

extern crate ape;
extern crate app_dirs;
extern crate core;
#[macro_use]
extern crate error_chain;
extern crate getopts;
extern crate hyper;
extern crate id3;
extern crate image;
extern crate iron;
extern crate lewton;
extern crate metaflac;
extern crate mount;
extern crate ogg;
extern crate oven;
extern crate params;
extern crate regex;
extern crate serde;
#[macro_use]
extern crate serde_derive;
extern crate serde_json;
extern crate staticfile;
extern crate sqlite;
extern crate toml;
extern crate url;

#[cfg(windows)]
extern crate uuid;
#[cfg(windows)]
extern crate winapi;
#[cfg(windows)]
extern crate kernel32;
#[cfg(windows)]
extern crate shell32;
#[cfg(windows)]
extern crate user32;

use errors::*;
use getopts::Options;
use iron::prelude::*;
use mount::Mount;
use staticfile::Static;
use std::path::Path;
use std::sync::Arc;

mod api;
mod collection;
mod config;
mod ddns;
mod errors;
mod index;
mod metadata;
mod ui;
mod utils;
mod thumbnails;
mod vfs;

fn main() {
	if let Err(ref e) = run() {
		println!("Error: {}", e);

		for e in e.iter().skip(1) {
			println!("caused by: {}", e);
		}
		if let Some(backtrace) = e.backtrace() {
			println!("backtrace: {:?}", backtrace);
		}
		::std::process::exit(1);
	}
}

fn run() -> Result<()> {

	// Parse CLI options
	let args: Vec<String> = std::env::args().collect();
	let mut options = Options::new();
	options.optopt("c", "config", "set the configuration file", "FILE");
	options.optopt("w", "web", "set the path to web client files", "DIRECTORY");
	let matches = match options.parse(&args[1..]) {
		Ok(m) => m,
		Err(f) => panic!(f.to_string()),
	};

	// Parse config
	let config_file_name = matches.opt_str("c");
	let config_file_path = config_file_name.map(|n| Path::new(n.as_str()).to_path_buf());
	let config = config::Config::parse(config_file_path)?;

	// Init VFS
	let vfs = Arc::new(vfs::Vfs::new(config.vfs.clone()));

	// Init index
	println!("Starting up index");
	let index = Arc::new(index::Index::new(vfs.clone(), &config.index)?);
	let index_ref = index.clone();
	std::thread::spawn(move || index_ref.run());

	// Mount API
	println!("Mounting API");
	let mut mount = Mount::new();
	let mut api_chain;
	{
		let api_handler;
		{
			let mut collection = collection::Collection::new(vfs, index);
			collection.load_config(&config)?;
			let collection = Arc::new(collection);
			api_handler = api::get_api_handler(collection);
		}
		api_chain = Chain::new(api_handler);

		let auth_secret = config.secret.to_owned();
		let cookie_middleware = oven::new(auth_secret.into_bytes());
		api_chain.link(cookie_middleware);
	}
	mount.mount("/api/", api_chain);

	// Mount static files
	println!("Mounting static files");
	let web_dir_name = matches.opt_str("w");
	let mut default_web_dir = utils::get_data_root()?;
	default_web_dir.push("web");
	let web_dir_path = web_dir_name
		.map(|n| Path::new(n.as_str()).to_path_buf())
		.unwrap_or(default_web_dir);

	mount.mount("/", Static::new(web_dir_path));

	println!("Starting up server");
	let mut server = Iron::new(mount).http(("0.0.0.0", 5050))?;

	// Start DDNS updates
	match config.ddns {
		Some(ref ddns_config) => {
			let ddns_config = ddns_config.clone();
			std::thread::spawn(|| { ddns::run(ddns_config); });
		}
		None => (),
	};

	// Run UI
	ui::run();

	println!("Shutting down server");
	server.close()?;

	Ok(())
}
<|endoftext|>