<commit_before>use core::error::FromError;
use std::collections::HashMap;
use std::old_io::{BufferedReader, File, IoError};

use architecture::*;

#[derive(Debug)]
pub enum AssmError { IoError(IoError), ParseError(String) }

impl FromError<IoError> for AssmError {
  fn from_error(err: IoError) -> AssmError {
    AssmError::IoError(err)
  }
}

pub type Label = String;

pub type LInsn = InsnGen<Label, Label>;

#[derive(Debug)]
pub enum Assm {
  LABEL(Label),
  Insn(LInsn),
  RET,
  LEA(RName, Label),
  LC(RName, Label),
  CODE,
  DATA,
  ADDR(UIMM16),
  FALIGN,
  FILL(IMM16),
  STRINGZ(String),
  BLKW(UIMM16),
  LCONST(Label, IMM16),
  LUCONST(Label, UIMM16)
}

peg_file! lc4_grammar("grammar/lc4.pegjs");

fn read_assembly_line(line: String) -> Result<Assm, AssmError> {
  match lc4_grammar::assm(&line.trim()[..]) {
    Err(err) => Err(AssmError::ParseError(err)),
    Ok(assm) => Ok(assm)
  }
}

pub fn read_assembly_file(filename: &str) -> Result<Vec<Assm>, AssmError> {
  let file = try!(File::open(&Path::new(filename)));
  let mut reader = BufferedReader::new(file);
  let mut assms = Vec::new();
  for line in reader.lines() {
    assms.push(try!(read_assembly_line(try!(line))))
  }
  Ok(assms)
}

#[derive(Copy, Debug, Eq, PartialEq)]
pub enum Section { CODE, DATA }

pub struct AssmData {
  pub memory: Box<[Mem; 0x10000]>,
  pub labels: HashMap<Label, (Section, u16)>,
  pub heap: u16
}

pub fn pad16(addr: u16) -> u16 {
  let mut padded = addr & 0xFFF0;
  if padded < addr { padded += 0x10; }
  padded
}

pub fn assemble(assm_lines: Vec<Assm>) -> AssmData {

  let mut section: Section = Section::CODE;

  let mut code_addr: u16 = 0;
  let mut data_addr: u16 = 0;

  let mut addr_labels: HashMap<Label, (Section, u16)> = HashMap::new();
  let mut value_labels: HashMap<Label, i16> = HashMap::new();

  /* First-pass, setup labels */

  for &ref assm in assm_lines.iter() {
    match assm {

      // Instructions and Pseudo-Instructions
      &Assm::Insn(_) => {
        assert!(section == Section::CODE);
        code_addr += 1
      },
      &Assm::RET => {
        assert!(section == Section::CODE);
        code_addr += 1
      },
      &Assm::LEA(_, _) => {
        assert!(section == Section::CODE);
        code_addr += 1
      },
      &Assm::LC(_, _) => {
        assert!(section == Section::CODE);
        code_addr += 1
      },

      // Assembler Directives
      &Assm::LABEL(ref l) => {
        if addr_labels.contains_key(l) {
          panic!("Cannot have duplicate labels")
        }
        addr_labels.insert(l.clone(), (section, code_addr));
      },

      &Assm::CODE => section = Section::CODE,
      &Assm::DATA => section = Section::DATA,

      &Assm::ADDR(ref u) =>
        match section {
          Section::CODE => code_addr = u.value,
          Section::DATA => data_addr = u.value
        },

      &Assm::FALIGN => {
        match section {
          Section::CODE => code_addr = pad16(code_addr),
          Section::DATA => data_addr = pad16(data_addr)
        }
      },

      &Assm::FILL(_) => {
        assert!(section == Section::DATA);
        data_addr += 1
      },
      &Assm::STRINGZ(ref s) => {
        assert!(section == Section::DATA);
        data_addr += s.len() as u16
      },

      &Assm::BLKW(ref u) => {
        match section {
          Section::CODE => code_addr += u.value,
          Section::DATA => data_addr += u.value
        }
      },

      &Assm::LCONST(ref l, ref i) => {
        if value_labels.contains_key(l) {
          panic!("Cannot have duplicate labels")
        }
        value_labels.insert(l.clone(), i.value);
      }
      &Assm::LUCONST(ref l, ref u) => {
        if value_labels.contains_key(l) {
          panic!("Cannot have duplicate labels")
        }
        value_labels.insert(l.clone(), u.value as i16);
      }
    }
  }

  /* Second pass, write to memory */

  let mut memory = box [Mem::DATA(0); 0x10000];
  let base_data_addr = pad16(code_addr);
  let base_heap_addr = pad16(base_data_addr + data_addr);
  let mut addr: u16 = 0;

  for &ref assm in assm_lines.iter() {
    match assm {

      &Assm::LABEL(ref target) => {
        let (label_section, label_addr) = addr_labels[target.clone()];
        match label_section {
          Section::CODE => addr = label_addr,
          Section::DATA => addr = label_addr + base_data_addr
        }
      },

      &Assm::Insn(InsnGen::BR(cc, ref target)) => {
        let (section, label_addr) = addr_labels[target.clone()];
        assert!(section == Section::CODE);
        memory[addr as usize] = Mem::CODE(InsnGen::BR(cc, IMM9{value: (label_addr - (addr + 1)) as i16}));
        addr += 1
      },
      &Assm::Insn(InsnGen::JSR(ref target)) => {
        let (section, label_addr) = addr_labels[target.clone()];
        assert!(section == Section::CODE);
        memory[addr as usize] = Mem::CODE(InsnGen::JSR(IMM11{value: (label_addr - (addr & 0x8000)) as i16 >> 4}));
        addr += 1
      },
      &Assm::Insn(InsnGen::JMP(ref target)) => {
        let (section, label_addr) = addr_labels[target.clone()];
        assert!(section == Section::CODE);
        memory[addr as usize] = Mem::CODE(InsnGen::JMP(IMM11{value: (label_addr - (addr + 1)) as i16}));
        addr += 1
      },

      &Assm::Insn(ref insn) => {
        memory[addr as usize] = Mem::CODE(partial_cast(insn));
        addr += 1
      }

      &Assm::RET => {
        memory[addr as usize] = Mem::CODE(InsnGen::JMPr(R7));
        addr += 1
      },

      &Assm::LEA(rd, ref target) => {
        let (section, label_addr) = addr_labels[target.clone()];
        let label_addr = match section {
          Section::CODE => label_addr,
          Section::DATA => label_addr + base_data_addr
        };
        let low = IMM9{value: label_addr as i16 & 0x01FF};
        let high = UIMM8{value: label_addr >> 8};
        memory[addr as usize] = Mem::CODE(InsnGen::CONST(rd, low));
        memory[addr as usize + 1] = Mem::CODE(InsnGen::HICONST(rd, high));
        addr += 2
      },

      &Assm::LC(rd, ref target) => {
        let label_value = value_labels[target.clone()];
        let low = IMM9{value: label_value & 0x01FF};
        let high = UIMM8{value: label_value as u16 >> 8};
        memory[addr as usize] = Mem::CODE(InsnGen::CONST(rd, low));
        memory[addr as usize + 1] = Mem::CODE(InsnGen::HICONST(rd, high));
        addr += 2
      }

      &Assm::CODE => (),
      &Assm::DATA => (),
      &Assm::ADDR(_) => (),
      &Assm::FALIGN => (),

      &Assm::FILL(i) => {
        memory[addr as usize] = Mem::DATA(i.value);
        addr += 1
      },

      &Assm::STRINGZ(_) => panic!("Not implemented"),

      &Assm::BLKW(_) => (),
      &Assm::LCONST(_,_) => (),
      &Assm::LUCONST(_,_) => ()
    }
  }

  AssmData{
    memory: memory,
    labels: addr_labels,
    heap: base_heap_addr
  }
}

#[derive(Clone, Copy, Debug)]
pub enum Mem {
  CODE(Insn),
  DATA(i16)
}<commit_msg>refactor main assembler loop<commit_after>use core::error::FromError;
use std::collections::HashMap;
use std::old_io::{BufferedReader, File, IoError};

use architecture::*;

#[derive(Debug)]
pub enum AssmError { IoError(IoError), ParseError(String) }

impl FromError<IoError> for AssmError {
  fn from_error(err: IoError) -> AssmError {
    AssmError::IoError(err)
  }
}

pub type Label = String;

pub type LInsn = InsnGen<Label, Label>;

#[derive(Debug)]
pub enum Assm {
  LABEL(Label),
  Insn(LInsn),
  RET,
  LEA(RName, Label),
  LC(RName, Label),
  CODE,
  DATA,
  ADDR(UIMM16),
  FALIGN,
  FILL(IMM16),
  STRINGZ(String),
  BLKW(UIMM16),
  LCONST(Label, IMM16),
  LUCONST(Label, UIMM16)
}

peg_file! lc4_grammar("grammar/lc4.pegjs");

fn read_assembly_line(line: String) -> Result<Assm, AssmError> {
  match lc4_grammar::assm(&line.trim()[..]) {
    Err(err) => Err(AssmError::ParseError(err)),
    Ok(assm) => Ok(assm)
  }
}

pub fn read_assembly_file(filename: &str) -> Result<Vec<Assm>, AssmError> {
  let file = try!(File::open(&Path::new(filename)));
  let mut reader = BufferedReader::new(file);
  let mut assms = Vec::new();
  for line in reader.lines() {
    assms.push(try!(read_assembly_line(try!(line))))
  }
  Ok(assms)
}

#[derive(Copy, Debug, Eq, PartialEq)]
pub enum Section { CODE, DATA }

#[derive(Clone, Copy, Debug)]
pub enum Mem {
  CODE(Insn),
  DATA(i16)
}

pub struct AssmData {
  pub memory: Box<[Mem; 0x10000]>,
  pub labels: HashMap<Label, (Section, u16)>,
  pub heap: u16
}

pub fn pad16(addr: u16) -> u16 {
  let mut padded = addr & 0xFFF0;
  if padded < addr { padded += 0x10; }
  padded
}

pub fn assemble(assm_lines: Vec<Assm>) -> AssmData {

  let mut section: Section = Section::CODE;

  let mut code_addr: u16 = 0;
  let mut data_addr: u16 = 0;

  let mut addr_labels: HashMap<Label, (Section, u16)> = HashMap::new();
  let mut value_labels: HashMap<Label, i16> = HashMap::new();

  /* First-pass, setup labels */

  for &ref assm in assm_lines.iter() {
    match assm {

      // Instructions and Pseudo-Instructions
      &Assm::Insn(_) => {
        assert!(section == Section::CODE);
        code_addr += 1
      },
      &Assm::RET => {
        assert!(section == Section::CODE);
        code_addr += 1
      },
      &Assm::LEA(_, _) => {
        assert!(section == Section::CODE);
        code_addr += 1
      },
      &Assm::LC(_, _) => {
        assert!(section == Section::CODE);
        code_addr += 1
      },

      // Assembler Directives
      &Assm::LABEL(ref l) => {
        if addr_labels.contains_key(l) {
          panic!("Cannot have duplicate labels")
        }
        addr_labels.insert(l.clone(), (section, code_addr));
      },

      &Assm::CODE => section = Section::CODE,
      &Assm::DATA => section = Section::DATA,

      &Assm::ADDR(ref u) =>
        match section {
          Section::CODE => code_addr = u.value,
          Section::DATA => data_addr = u.value
        },

      &Assm::FALIGN => {
        match section {
          Section::CODE => code_addr = pad16(code_addr),
          Section::DATA => data_addr = pad16(data_addr)
        }
      },

      &Assm::FILL(_) => {
        assert!(section == Section::DATA);
        data_addr += 1
      },
      &Assm::STRINGZ(ref s) => {
        assert!(section == Section::DATA);
        data_addr += s.len() as u16
      },

      &Assm::BLKW(ref u) => {
        match section {
          Section::CODE => code_addr += u.value,
          Section::DATA => data_addr += u.value
        }
      },

      &Assm::LCONST(ref l, ref i) => {
        if value_labels.contains_key(l) {
          panic!("Cannot have duplicate labels")
        }
        value_labels.insert(l.clone(), i.value);
      }
      &Assm::LUCONST(ref l, ref u) => {
        if value_labels.contains_key(l) {
          panic!("Cannot have duplicate labels")
        }
        value_labels.insert(l.clone(), u.value as i16);
      }
    }
  }

  /* Second pass, write to memory */

  let mut memory = box [Mem::DATA(0); 0x10000];
  let base_data_addr = pad16(code_addr);
  let base_heap_addr = pad16(base_data_addr + data_addr);
  let mut addr: u16 = 0;

  for &ref assm in assm_lines.iter() {
    match assm {

      &Assm::LABEL(ref target) => {
        let (label_section, label_addr) = addr_labels[target.clone()];
        match label_section {
          Section::CODE => addr = label_addr,
          Section::DATA => addr = label_addr + base_data_addr
        }
      },

      &Assm::Insn(InsnGen::BR(cc, ref target)) => {
        let (section, label_addr) = addr_labels[target.clone()];
        assert!(section == Section::CODE);
        memory[addr as usize] = Mem::CODE(InsnGen::BR(cc, IMM9{value: (label_addr - (addr + 1)) as i16}));
        addr += 1
      },
      &Assm::Insn(InsnGen::JSR(ref target)) => {
        let (section, label_addr) = addr_labels[target.clone()];
        assert!(section == Section::CODE);
        memory[addr as usize] = Mem::CODE(InsnGen::JSR(IMM11{value: (label_addr - (addr & 0x8000)) as i16 >> 4}));
        addr += 1
      },
      &Assm::Insn(InsnGen::JMP(ref target)) => {
        let (section, label_addr) = addr_labels[target.clone()];
        assert!(section == Section::CODE);
        memory[addr as usize] = Mem::CODE(InsnGen::JMP(IMM11{value: (label_addr - (addr + 1)) as i16}));
        addr += 1
      },

      &Assm::Insn(ref insn) => {
        memory[addr as usize] = Mem::CODE(partial_cast(insn));
        addr += 1
      }

      &Assm::RET => {
        memory[addr as usize] = Mem::CODE(InsnGen::JMPr(R7));
        addr += 1
      },

      &Assm::LEA(rd, ref target) => {
        let (section, label_addr) = addr_labels[target.clone()];
        let label_addr = match section {
          Section::CODE => label_addr,
          Section::DATA => label_addr + base_data_addr
        };
        let low = IMM9{value: label_addr as i16 & 0x01FF};
        let high = UIMM8{value: label_addr >> 8};
        memory[addr as usize] = Mem::CODE(InsnGen::CONST(rd, low));
        memory[addr as usize + 1] = Mem::CODE(InsnGen::HICONST(rd, high));
        addr += 2
      },

      &Assm::LC(rd, ref target) => {
        let label_value = value_labels[target.clone()];
        let low = IMM9{value: label_value & 0x01FF};
        let high = UIMM8{value: label_value as u16 >> 8};
        memory[addr as usize] = Mem::CODE(InsnGen::CONST(rd, low));
        memory[addr as usize + 1] = Mem::CODE(InsnGen::HICONST(rd, high));
        addr += 2
      }

      &Assm::CODE => (),
      &Assm::DATA => (),
      &Assm::ADDR(_) => (),
      &Assm::FALIGN => (),

      &Assm::FILL(i) => {
        memory[addr as usize] = Mem::DATA(i.value);
        addr += 1
      },

      &Assm::STRINGZ(_) => panic!("Not implemented"),

      &Assm::BLKW(_) => (),
      &Assm::LCONST(_,_) => (),
      &Assm::LUCONST(_,_) => ()
    }
  }

  AssmData{
    memory: memory,
    labels: addr_labels,
    heap: base_heap_addr
  }
}

pub fn encode_word(mem: Mem) -> i16 {
  match mem {
    case CODE(insn) => panic!("Not implemented"),
    case DATA(i) => i
  }
}<|endoftext|>


<commit_before>// Copyright 2018 Guillaume Pinot (@TeXitoi) <texitoi@texitoi.eu>
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![deny(warnings)]
#![cfg(feature = "nightly")]// TODO: remove that when never is stable

#[macro_use]
extern crate structopt;

use structopt::StructOpt;

fn try_str(s: &str) -> Result<String, !> {
    Ok(s.into())
}

#[test]
fn warning_never_struct() {
    #[derive(Debug, PartialEq, StructOpt)]
    struct Opt {
        #[structopt(parse(try_from_str = "try_str"))]
        s: String,
    }
    assert_eq!(Opt { s: "foo".to_string() },
               Opt::from_iter(&["test", "foo"]));

}

#[test]
fn warning_never_enum() {
    #[derive(Debug, PartialEq, StructOpt)]
    enum Opt {
        Foo {
            #[structopt(parse(try_from_str = "try_str"))]
            s: String,
        }
    }
    assert_eq!(Opt::Foo { s: "foo".to_string() },
               Opt::from_iter(&["test", "Foo", "foo"]));

}

<commit_msg>fix nightly<commit_after>// Copyright 2018 Guillaume Pinot (@TeXitoi) <texitoi@texitoi.eu>
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![deny(warnings)]
#![cfg(feature = "nightly")]// TODO: remove that when never is stable
#![feature(never_type)]

#[macro_use]
extern crate structopt;

use structopt::StructOpt;

fn try_str(s: &str) -> Result<String, !> {
    Ok(s.into())
}

#[test]
fn warning_never_struct() {
    #[derive(Debug, PartialEq, StructOpt)]
    struct Opt {
        #[structopt(parse(try_from_str = "try_str"))]
        s: String,
    }
    assert_eq!(Opt { s: "foo".to_string() },
               Opt::from_iter(&["test", "foo"]));

}

#[test]
fn warning_never_enum() {
    #[derive(Debug, PartialEq, StructOpt)]
    enum Opt {
        Foo {
            #[structopt(parse(try_from_str = "try_str"))]
            s: String,
        }
    }
    assert_eq!(Opt::Foo { s: "foo".to_string() },
               Opt::from_iter(&["test", "Foo", "foo"]));

}

<|endoftext|>


<commit_before>#![feature(globs, macro_rules, phase)]

#[phase(syntax, link)]
extern crate log;

#[phase(syntax, link)]
extern crate windows = "rust-windows";

use std::ptr;
use std::cell::RefCell;
use std::default::Default;
use std::owned::Box;

use windows::main_window_loop;
use windows::ll::types::{UINT, HBRUSH};
use windows::ll::all::CREATESTRUCT;
use windows::instance::Instance;
use windows::resource::*;
use windows::window::{WindowImpl, Window, WndClass, WindowParams};
use windows::window::{OnCreate, OnSize, OnDestroy, OnPaint, OnFocus};
use windows::window;
use windows::gdi::PaintDc;
use windows::font::Font;
use windows::font;

// TODO duplicate of hello.rc
static IDI_ICON: int = 0x101;
static MENU_MAIN: int = 0x201;
//static MENU_NEW: int = 0x202;
//static MENU_EXIT: int = 0x203;

struct MainFrame {
    win: Window,
    title: String,
    text_height: int,
    edit: RefCell<Option<Window>>,
    font: RefCell<Option<Font>>,
}

wnd_proc!(MainFrame, win, WM_CREATE, WM_DESTROY, WM_SIZE, WM_SETFOCUS, WM_PAINT)

impl OnCreate for MainFrame {
    fn on_create(&self, _cs: &CREATESTRUCT) -> bool {
        let rect = self.win.client_rect().unwrap();
        let params = WindowParams {
            window_name: "Hello World".to_strbuf(),
            style: window::WS_CHILD | window::WS_VISIBLE | window::WS_BORDER | window::WS_VSCROLL |
                window::ES_AUTOVSCROLL | window::ES_MULTILINE | window::ES_NOHIDESEL,
            x: 0,
            y: self.text_height,
            width: rect.right as int,
            height: rect.bottom as int - self.text_height,
            parent: self.win,
            menu: ptr::mut_null(),
            ex_style: 0,
        };
        let edit = Window::new(Instance::main_instance(), None, "EDIT", &params);
        match edit {
            None => false,
            Some(e) => {
                let font_attr = Default::default();
                let font = font::Font::new(&font_attr);
                debug!("font: {:?}", font);
                match font {
                    None => false,
                    Some(f) => {
                        static WM_SETFONT: UINT = 0x0030;
                        unsafe {
                            e.send_message(WM_SETFONT, std::mem::transmute(f.font), 0);
                        }
                        *self.edit.borrow_mut() = Some(e);
                        *self.font.borrow_mut() = Some(f);
                        true
                    }
                }
            }
        }
    }
}

impl OnSize for MainFrame {
    fn on_size(&self, width: int, height: int) {
        // SWP_NOOWNERZORDER | SWP_NOZORDER
        let h = self.text_height;
        self.edit.borrow().expect("edit is empty")
            .set_window_pos(0, h, width, height - h, 0x200 | 0x4);
    }
}

impl OnDestroy for MainFrame {}

impl OnPaint for MainFrame {
    fn on_paint(&self) {
        let font = self.font.borrow();
        let pdc = PaintDc::new(self).expect("Paint DC");
        pdc.dc.select_font(&font.expect("font is empty"));
        pdc.dc.text_out(0, 0, self.title.as_slice());
    }
}

impl OnFocus for MainFrame {
    fn on_focus(&self, _w: Window) {
        self.edit.borrow().expect("edit is empty").set_focus();
    }
}

impl MainFrame {
    fn new(instance: Instance, title: String, text_height: int) -> Option<Window> {
        let icon = Image::load_resource(instance, IDI_ICON, IMAGE_ICON, 0, 0);
        let wnd_class = WndClass {
            classname: "MainFrame".to_strbuf(),
            style: 0x0001 | 0x0002, // CS_HREDRAW | CS_VREDRAW
            icon: icon,
            icon_small: None,
            cursor: Image::load_cursor_resource(32514), // hourglass
            background: (5 + 1) as HBRUSH,
            menu: MenuId(MENU_MAIN),
            cls_extra: 0,
            wnd_extra: 0,
        };
        let res = wnd_class.register(instance);
        if !res {
            return None;
        }

        let wproc = box MainFrame {
            win: Window::null(),
            title: title.clone(),
            text_height: text_height,
            edit: RefCell::new(None),
            font: RefCell::new(None),
        };

        let win_params = WindowParams {
            window_name: title,
            style: window::WS_OVERLAPPEDWINDOW,
            x: 0,
            y: 0,
            width: 400,
            height: 400,
            parent: Window::null(),
            menu: ptr::mut_null(),
            ex_style: 0,
        };

        Window::new(instance, Some(wproc as Box<WindowImpl:Send>),
                    wnd_class.classname.as_slice(), &win_params)
    }
}

fn main() {
    window::init_window_map();

    let instance = Instance::main_instance();
    let main = MainFrame::new(instance, "Hello Rust".to_strbuf(), 20);
    let main = main.unwrap();

    main.show(1);
    main.update();

    let exit_code = main_window_loop();
    std::os::set_exit_status(exit_code as int);
}
<commit_msg>Making example code work with language changes<commit_after>#![feature(globs, macro_rules, phase)]

#[phase(plugin, link)]
extern crate log;

#[phase(plugin, link)]
extern crate windows = "rust-windows";

extern crate debug;

use std::ptr;
use std::cell::RefCell;
use std::default::Default;
use std::owned::Box;

use windows::main_window_loop;
use windows::ll::types::{UINT, HBRUSH};
use windows::ll::all::CREATESTRUCT;
use windows::instance::Instance;
use windows::resource::*;
use windows::window::{WindowImpl, Window, WndClass, WindowParams};
use windows::window::{OnCreate, OnSize, OnDestroy, OnPaint, OnFocus};
use windows::window;
use windows::gdi::PaintDc;
use windows::font::Font;
use windows::font;

// TODO duplicate of hello.rc
static IDI_ICON: int = 0x101;
static MENU_MAIN: int = 0x201;
//static MENU_NEW: int = 0x202;
//static MENU_EXIT: int = 0x203;

struct MainFrame {
    win: Window,
    title: String,
    text_height: int,
    edit: RefCell<Option<Window>>,
    font: RefCell<Option<Font>>,
}

wnd_proc!(MainFrame, win, WM_CREATE, WM_DESTROY, WM_SIZE, WM_SETFOCUS, WM_PAINT)

impl OnCreate for MainFrame {
    fn on_create(&self, _cs: &CREATESTRUCT) -> bool {
        let rect = self.win.client_rect().unwrap();
        let params = WindowParams {
            window_name: "Hello World".to_string(),
            style: window::WS_CHILD | window::WS_VISIBLE | window::WS_BORDER | window::WS_VSCROLL |
                window::ES_AUTOVSCROLL | window::ES_MULTILINE | window::ES_NOHIDESEL,
            x: 0,
            y: self.text_height,
            width: rect.right as int,
            height: rect.bottom as int - self.text_height,
            parent: self.win,
            menu: ptr::mut_null(),
            ex_style: 0,
        };
        let edit = Window::new(Instance::main_instance(), None, "EDIT", &params);
        match edit {
            None => false,
            Some(e) => {
                let font_attr = Default::default();
                let font = font::Font::new(&font_attr);
                debug!("font: {:?}", font);
                match font {
                    None => false,
                    Some(f) => {
                        static WM_SETFONT: UINT = 0x0030;
                        unsafe {
                            e.send_message(WM_SETFONT, std::mem::transmute(f.font), 0);
                        }
                        *self.edit.borrow_mut() = Some(e);
                        *self.font.borrow_mut() = Some(f);
                        true
                    }
                }
            }
        }
    }
}

impl OnSize for MainFrame {
    fn on_size(&self, width: int, height: int) {
        // SWP_NOOWNERZORDER | SWP_NOZORDER
        let h = self.text_height;
        self.edit.borrow().expect("edit is empty")
            .set_window_pos(0, h, width, height - h, 0x200 | 0x4);
    }
}

impl OnDestroy for MainFrame {}

impl OnPaint for MainFrame {
    fn on_paint(&self) {
        let font = self.font.borrow();
        let pdc = PaintDc::new(self).expect("Paint DC");
        pdc.dc.select_font(&font.expect("font is empty"));
        pdc.dc.text_out(0, 0, self.title.as_slice());
    }
}

impl OnFocus for MainFrame {
    fn on_focus(&self, _w: Window) {
        self.edit.borrow().expect("edit is empty").set_focus();
    }
}

impl MainFrame {
    fn new(instance: Instance, title: String, text_height: int) -> Option<Window> {
        let icon = Image::load_resource(instance, IDI_ICON, IMAGE_ICON, 0, 0);
        let wnd_class = WndClass {
            classname: "MainFrame".to_string(),
            style: 0x0001 | 0x0002, // CS_HREDRAW | CS_VREDRAW
            icon: icon,
            icon_small: None,
            cursor: Image::load_cursor_resource(32514), // hourglass
            background: (5 + 1) as HBRUSH,
            menu: MenuId(MENU_MAIN),
            cls_extra: 0,
            wnd_extra: 0,
        };
        let res = wnd_class.register(instance);
        if !res {
            return None;
        }

        let wproc = box MainFrame {
            win: Window::null(),
            title: title.clone(),
            text_height: text_height,
            edit: RefCell::new(None),
            font: RefCell::new(None),
        };

        let win_params = WindowParams {
            window_name: title,
            style: window::WS_OVERLAPPEDWINDOW,
            x: 0,
            y: 0,
            width: 400,
            height: 400,
            parent: Window::null(),
            menu: ptr::mut_null(),
            ex_style: 0,
        };

        Window::new(instance, Some(wproc as Box<WindowImpl+Send>),
                    wnd_class.classname.as_slice(), &win_params)
    }
}

fn main() {
    window::init_window_map();

    let instance = Instance::main_instance();
    let main = MainFrame::new(instance, "Hello Rust".to_string(), 20);
    let main = main.unwrap();

    main.show(1);
    main.update();

    let exit_code = main_window_loop();
    std::os::set_exit_status(exit_code as int);
}
<|endoftext|>


<commit_before>#![allow(non_upper_case_globals)]
#![allow(non_snake_case)]

extern crate glfw;
use self::glfw::Context;

extern crate gl;
use self::gl::types::*;

use std::ptr;
use std::mem;
use std::os::raw::c_void;
use std::ffi::CStr;

use common::{process_events, processInput, loadTexture};
use shader::Shader;
use camera::Camera;

use cgmath::{Matrix4, vec3,  Deg, perspective, Point3};
use cgmath::prelude::*;

// settings
const SCR_WIDTH: u32 = 1280;
const SCR_HEIGHT: u32 = 720;

// TODO!: started as copy of 4.1.1
pub fn main_4_6_1() {
    let mut camera = Camera {
        Position: Point3::new(0.0, 0.0, 3.0),
        ..Camera::default()
    };

    let mut firstMouse = true;
    let mut lastX: f32 = SCR_WIDTH as f32 / 2.0;
    let mut lastY: f32 = SCR_HEIGHT as f32 / 2.0;

    // timing
    let mut deltaTime: f32; // time between current frame and last frame
    let mut lastFrame: f32 = 0.0;

    // glfw: initialize and configure
    // ------------------------------
    let mut glfw = glfw::init(glfw::FAIL_ON_ERRORS).unwrap();
    glfw.window_hint(glfw::WindowHint::ContextVersion(3, 3));
    glfw.window_hint(glfw::WindowHint::OpenGlProfile(glfw::OpenGlProfileHint::Core));
    #[cfg(target_os = "macos")]
    glfw.window_hint(glfw::WindowHint::OpenGlForwardCompat(true));

    // glfw window creation
    // --------------------
    let (mut window, events) = glfw.create_window(SCR_WIDTH, SCR_HEIGHT, "LearnOpenGL", glfw::WindowMode::Windowed)
        .expect("Failed to create GLFW window");

    window.make_current();
    window.set_framebuffer_size_polling(true);
    window.set_cursor_pos_polling(true);
    window.set_scroll_polling(true);

    // tell GLFW to capture our mouse
    window.set_cursor_mode(glfw::CursorMode::Disabled);

    // gl: load all OpenGL function pointers
    // ---------------------------------------
    gl::load_with(|symbol| window.get_proc_address(symbol) as *const _);

    let (shader, cubeVBO, cubeVAO, planeVBO, planeVAO, cubeTexture, floorTexture) = unsafe {
        // configure global opengl state
        // -----------------------------
        gl::Enable(gl::DEPTH_TEST);
        gl::DepthFunc(gl::ALWAYS); // always pass the depth test (same effect as glDisable(GL_DEPTH_TEST))

        // build and compile our shader program
        // ------------------------------------
        let shader = Shader::new(
            "src/_4_advanced_opengl/shaders/1.1.depth_testing.vs",
            "src/_4_advanced_opengl/shaders/1.1.depth_testing.fs");

        // set up vertex data (and buffer(s)) and configure vertex attributes
        // ------------------------------------------------------------------
        let cubeVertices: [f32; 180] = [
             // positions       // texture Coords
             -0.5, -0.5, -0.5,  0.0, 0.0,
              0.5, -0.5, -0.5,  1.0, 0.0,
              0.5,  0.5, -0.5,  1.0, 1.0,
              0.5,  0.5, -0.5,  1.0, 1.0,
             -0.5,  0.5, -0.5,  0.0, 1.0,
             -0.5, -0.5, -0.5,  0.0, 0.0,

             -0.5, -0.5,  0.5,  0.0, 0.0,
              0.5, -0.5,  0.5,  1.0, 0.0,
              0.5,  0.5,  0.5,  1.0, 1.0,
              0.5,  0.5,  0.5,  1.0, 1.0,
             -0.5,  0.5,  0.5,  0.0, 1.0,
             -0.5, -0.5,  0.5,  0.0, 0.0,

             -0.5,  0.5,  0.5,  1.0, 0.0,
             -0.5,  0.5, -0.5,  1.0, 1.0,
             -0.5, -0.5, -0.5,  0.0, 1.0,
             -0.5, -0.5, -0.5,  0.0, 1.0,
             -0.5, -0.5,  0.5,  0.0, 0.0,
             -0.5,  0.5,  0.5,  1.0, 0.0,

              0.5,  0.5,  0.5,  1.0, 0.0,
              0.5,  0.5, -0.5,  1.0, 1.0,
              0.5, -0.5, -0.5,  0.0, 1.0,
              0.5, -0.5, -0.5,  0.0, 1.0,
              0.5, -0.5,  0.5,  0.0, 0.0,
              0.5,  0.5,  0.5,  1.0, 0.0,

             -0.5, -0.5, -0.5,  0.0, 1.0,
              0.5, -0.5, -0.5,  1.0, 1.0,
              0.5, -0.5,  0.5,  1.0, 0.0,
              0.5, -0.5,  0.5,  1.0, 0.0,
             -0.5, -0.5,  0.5,  0.0, 0.0,
             -0.5, -0.5, -0.5,  0.0, 1.0,

             -0.5,  0.5, -0.5,  0.0, 1.0,
              0.5,  0.5, -0.5,  1.0, 1.0,
              0.5,  0.5,  0.5,  1.0, 0.0,
              0.5,  0.5,  0.5,  1.0, 0.0,
             -0.5,  0.5,  0.5,  0.0, 0.0,
             -0.5,  0.5, -0.5,  0.0, 1.0
        ];
        let planeVertices: [f32; 30] = [
            // positions       // texture Coords (note we set these higher than 1 (together with GL_REPEAT as texture wrapping mode). this will cause the floor texture to repeat)
             5.0, -0.5,  5.0,  2.0, 0.0,
            -5.0, -0.5,  5.0,  0.0, 0.0,
            -5.0, -0.5, -5.0,  0.0, 2.0,

             5.0, -0.5,  5.0,  2.0, 0.0,
            -5.0, -0.5, -5.0,  0.0, 2.0,
             5.0, -0.5, -5.0,  2.0, 2.0
        ];
        // cube VAO
        let (mut cubeVAO, mut cubeVBO) = (0, 0);
        gl::GenVertexArrays(1, &mut cubeVAO);
        gl::GenBuffers(1, &mut cubeVBO);
        gl::BindVertexArray(cubeVAO);
        gl::BindBuffer(gl::ARRAY_BUFFER, cubeVBO);
        gl::BufferData(gl::ARRAY_BUFFER,
                       (cubeVertices.len() * mem::size_of::<GLfloat>()) as GLsizeiptr,
                       &cubeVertices[0] as *const f32 as *const c_void,
                       gl::STATIC_DRAW);
        let stride = 5 * mem::size_of::<GLfloat>() as GLsizei;
        gl::EnableVertexAttribArray(0);
        gl::VertexAttribPointer(0, 3, gl::FLOAT, gl::FALSE, stride, ptr::null());
        gl::EnableVertexAttribArray(1);
        gl::VertexAttribPointer(1, 2, gl::FLOAT, gl::FALSE, stride, (3 * mem::size_of::<GLfloat>()) as *const c_void);
        gl::BindVertexArray(0);
        // plane VAO
        let (mut planeVAO, mut planeVBO) = (0, 0);
        gl::GenVertexArrays(1, &mut planeVAO);
        gl::GenBuffers(1, &mut planeVBO);
        gl::BindVertexArray(planeVAO);
        gl::BindBuffer(gl::ARRAY_BUFFER, planeVBO);
        gl::BufferData(gl::ARRAY_BUFFER,
                       (planeVertices.len() * mem::size_of::<GLfloat>()) as GLsizeiptr,
                       &planeVertices[0] as *const f32 as *const c_void,
                       gl::STATIC_DRAW);
        gl::EnableVertexAttribArray(0);
        gl::VertexAttribPointer(0, 3, gl::FLOAT, gl::FALSE, stride, ptr::null());
        gl::EnableVertexAttribArray(1);
        gl::VertexAttribPointer(1, 2, gl::FLOAT, gl::FALSE, stride, (3 * mem::size_of::<GLfloat>()) as *const c_void);
        gl::BindVertexArray(0);

        // load textures
        // -------------
        let cubeTexture = loadTexture("resources/textures/marble.jpg");
        let floorTexture = loadTexture("resources/textures/metal.png");

        // shader configuration
        // --------------------
        shader.useProgram();
        shader.setInt(c_str!("texture1"), 0);

        (shader, cubeVBO, cubeVAO, planeVBO, planeVAO, cubeTexture, floorTexture)
    };

    // render loop
    // -----------
    while !window.should_close() {
        // per-frame time logic
        // --------------------
        let currentFrame = glfw.get_time() as f32;
        deltaTime = currentFrame - lastFrame;
        lastFrame = currentFrame;

        // events
        // -----
        process_events(&events, &mut firstMouse, &mut lastX, &mut lastY, &mut camera);

        // input
        // -----
        processInput(&mut window, deltaTime, &mut camera);

        // render
        // ------
        unsafe {
            gl::ClearColor(0.1, 0.1, 0.1, 1.0);
            gl::Clear(gl::COLOR_BUFFER_BIT | gl::DEPTH_BUFFER_BIT);

            shader.useProgram();
            let mut model: Matrix4<f32>;
            let view = camera.GetViewMatrix();
            let projection: Matrix4<f32> = perspective(Deg(camera.Zoom), SCR_WIDTH as f32 / SCR_HEIGHT as f32 , 0.1, 100.0);
            shader.setMat4(c_str!("view"), &view);
            shader.setMat4(c_str!("projection"), &projection);
            // cubes
            gl::BindVertexArray(cubeVAO);
            gl::ActiveTexture(gl::TEXTURE0);
            gl::BindTexture(gl::TEXTURE_2D, cubeTexture);
            model = Matrix4::from_translation(vec3(-1.0, 0.0, -1.0));
            shader.setMat4(c_str!("model"), &model);
            gl::DrawArrays(gl::TRIANGLES, 0, 36);
            model = Matrix4::from_translation(vec3(2.0, 0.0, 0.0));
            shader.setMat4(c_str!("model"), &model);
            gl::DrawArrays(gl::TRIANGLES, 0, 36);
            // floor
            gl::BindVertexArray(planeVAO);
            gl::BindTexture(gl::TEXTURE_2D, floorTexture);
            shader.setMat4(c_str!("model"), &Matrix4::identity());
            gl::DrawArrays(gl::TRIANGLES, 0, 6);
            gl::BindVertexArray(0);
        }

        // glfw: swap buffers and poll IO events (keys pressed/released, mouse moved etc.)
        // -------------------------------------------------------------------------------
        window.swap_buffers();
        glfw.poll_events();
    }

    // optional: de-allocate all resources once they've outlived their purpose:
    // ------------------------------------------------------------------------
    unsafe {
        gl::DeleteVertexArrays(1, &cubeVAO);
        gl::DeleteVertexArrays(1, &planeVAO);
        gl::DeleteBuffers(1, &cubeVBO);
        gl::DeleteBuffers(1, &planeVBO);
    }
}
<commit_msg>4.6.1 WIP<commit_after>#![allow(non_upper_case_globals)]
#![allow(non_snake_case)]

extern crate glfw;
use self::glfw::Context;

extern crate gl;
use self::gl::types::*;

use std::ptr;
use std::mem;
use std::os::raw::c_void;
use std::ffi::CStr;

use common::{process_events, processInput, loadTexture};
use shader::Shader;
use camera::Camera;

use cgmath::{Matrix4, vec3,  Deg, perspective, Point3};
use cgmath::prelude::*;

// settings
const SCR_WIDTH: u32 = 1280;
const SCR_HEIGHT: u32 = 720;

// TODO!: started as copy of 4.1.1
pub fn main_4_6_1() {
    let mut camera = Camera {
        Position: Point3::new(0.0, 0.0, 3.0),
        ..Camera::default()
    };

    let mut firstMouse = true;
    let mut lastX: f32 = SCR_WIDTH as f32 / 2.0;
    let mut lastY: f32 = SCR_HEIGHT as f32 / 2.0;

    // timing
    let mut deltaTime: f32; // time between current frame and last frame
    let mut lastFrame: f32 = 0.0;

    // glfw: initialize and configure
    // ------------------------------
    let mut glfw = glfw::init(glfw::FAIL_ON_ERRORS).unwrap();
    glfw.window_hint(glfw::WindowHint::ContextVersion(3, 3));
    glfw.window_hint(glfw::WindowHint::OpenGlProfile(glfw::OpenGlProfileHint::Core));
    #[cfg(target_os = "macos")]
    glfw.window_hint(glfw::WindowHint::OpenGlForwardCompat(true));

    // glfw window creation
    // --------------------
    let (mut window, events) = glfw.create_window(SCR_WIDTH, SCR_HEIGHT, "LearnOpenGL", glfw::WindowMode::Windowed)
        .expect("Failed to create GLFW window");

    window.make_current();
    window.set_framebuffer_size_polling(true);
    window.set_cursor_pos_polling(true);
    window.set_scroll_polling(true);

    // tell GLFW to capture our mouse
    window.set_cursor_mode(glfw::CursorMode::Disabled);

    // gl: load all OpenGL function pointers
    // ---------------------------------------
    gl::load_with(|symbol| window.get_proc_address(symbol) as *const _);

    let (shader, cubeVBO, cubeVAO, skyboxVBO, skyboxVAO, cubeTexture) = unsafe {
        // configure global opengl state
        // -----------------------------
        gl::Enable(gl::DEPTH_TEST);
        gl::DepthFunc(gl::ALWAYS); // always pass the depth test (same effect as glDisable(GL_DEPTH_TEST))

        // build and compile our shader program
        // ------------------------------------
        let shader = Shader::new(
            "src/_4_advanced_opengl/shaders/6.1.cubemaps.vs",
            "src/_4_advanced_opengl/shaders/6.1.cubemaps.fs");
        let shader = Shader::new(
            "src/_4_advanced_opengl/shaders/6.1.skybox.vs",
            "src/_4_advanced_opengl/shaders/6.1.skybox.fs");

        // set up vertex data (and buffer(s)) and configure vertex attributes
        // ------------------------------------------------------------------
        let cubeVertices: [f32; 180] = [
             // positions       // texture Coords
             -0.5, -0.5, -0.5,  0.0, 0.0,
              0.5, -0.5, -0.5,  1.0, 0.0,
              0.5,  0.5, -0.5,  1.0, 1.0,
              0.5,  0.5, -0.5,  1.0, 1.0,
             -0.5,  0.5, -0.5,  0.0, 1.0,
             -0.5, -0.5, -0.5,  0.0, 0.0,

             -0.5, -0.5,  0.5,  0.0, 0.0,
              0.5, -0.5,  0.5,  1.0, 0.0,
              0.5,  0.5,  0.5,  1.0, 1.0,
              0.5,  0.5,  0.5,  1.0, 1.0,
             -0.5,  0.5,  0.5,  0.0, 1.0,
             -0.5, -0.5,  0.5,  0.0, 0.0,

             -0.5,  0.5,  0.5,  1.0, 0.0,
             -0.5,  0.5, -0.5,  1.0, 1.0,
             -0.5, -0.5, -0.5,  0.0, 1.0,
             -0.5, -0.5, -0.5,  0.0, 1.0,
             -0.5, -0.5,  0.5,  0.0, 0.0,
             -0.5,  0.5,  0.5,  1.0, 0.0,

              0.5,  0.5,  0.5,  1.0, 0.0,
              0.5,  0.5, -0.5,  1.0, 1.0,
              0.5, -0.5, -0.5,  0.0, 1.0,
              0.5, -0.5, -0.5,  0.0, 1.0,
              0.5, -0.5,  0.5,  0.0, 0.0,
              0.5,  0.5,  0.5,  1.0, 0.0,

             -0.5, -0.5, -0.5,  0.0, 1.0,
              0.5, -0.5, -0.5,  1.0, 1.0,
              0.5, -0.5,  0.5,  1.0, 0.0,
              0.5, -0.5,  0.5,  1.0, 0.0,
             -0.5, -0.5,  0.5,  0.0, 0.0,
             -0.5, -0.5, -0.5,  0.0, 1.0,

             -0.5,  0.5, -0.5,  0.0, 1.0,
              0.5,  0.5, -0.5,  1.0, 1.0,
              0.5,  0.5,  0.5,  1.0, 0.0,
              0.5,  0.5,  0.5,  1.0, 0.0,
             -0.5,  0.5,  0.5,  0.0, 0.0,
             -0.5,  0.5, -0.5,  0.0, 1.0
        ];
        let skyboxVertices: [f32; 108] = [
            // positions
            -1.0,  1.0, -1.0,
            -1.0, -1.0, -1.0,
             1.0, -1.0, -1.0,
             1.0, -1.0, -1.0,
             1.0,  1.0, -1.0,
            -1.0,  1.0, -1.0,

            -1.0, -1.0,  1.0,
            -1.0, -1.0, -1.0,
            -1.0,  1.0, -1.0,
            -1.0,  1.0, -1.0,
            -1.0,  1.0,  1.0,
            -1.0, -1.0,  1.0,

             1.0, -1.0, -1.0,
             1.0, -1.0,  1.0,
             1.0,  1.0,  1.0,
             1.0,  1.0,  1.0,
             1.0,  1.0, -1.0,
             1.0, -1.0, -1.0,

            -1.0, -1.0,  1.0,
            -1.0,  1.0,  1.0,
             1.0,  1.0,  1.0,
             1.0,  1.0,  1.0,
             1.0, -1.0,  1.0,
            -1.0, -1.0,  1.0,

            -1.0,  1.0, -1.0,
             1.0,  1.0, -1.0,
             1.0,  1.0,  1.0,
             1.0,  1.0,  1.0,
            -1.0,  1.0,  1.0,
            -1.0,  1.0, -1.0,

            -1.0, -1.0, -1.0,
            -1.0, -1.0,  1.0,
             1.0, -1.0, -1.0,
             1.0, -1.0, -1.0,
            -1.0, -1.0,  1.0,
             1.0, -1.0,  1.0
        ];

        // cube VAO
        let (mut cubeVAO, mut cubeVBO) = (0, 0);
        gl::GenVertexArrays(1, &mut cubeVAO);
        gl::GenBuffers(1, &mut cubeVBO);
        gl::BindVertexArray(cubeVAO);
        gl::BindBuffer(gl::ARRAY_BUFFER, cubeVBO);
        gl::BufferData(gl::ARRAY_BUFFER,
                       (cubeVertices.len() * mem::size_of::<GLfloat>()) as GLsizeiptr,
                       &cubeVertices[0] as *const f32 as *const c_void,
                       gl::STATIC_DRAW);
        let mut stride = 5 * mem::size_of::<GLfloat>() as GLsizei;
        gl::EnableVertexAttribArray(0);
        gl::VertexAttribPointer(0, 3, gl::FLOAT, gl::FALSE, stride, ptr::null());
        gl::EnableVertexAttribArray(1);
        gl::VertexAttribPointer(1, 2, gl::FLOAT, gl::FALSE, stride, (3 * mem::size_of::<GLfloat>()) as *const c_void);
        gl::BindVertexArray(0);
        // skybox VAO
        let (mut skyboxVAO, mut skyboxVBO) = (0, 0);
        gl::GenVertexArrays(1, &mut skyboxVAO);
        gl::GenBuffers(1, &mut skyboxVBO);
        gl::BindVertexArray(skyboxVAO);
        gl::BindBuffer(gl::ARRAY_BUFFER, skyboxVBO);
        gl::BufferData(gl::ARRAY_BUFFER,
                       (skyboxVertices.len() * mem::size_of::<GLfloat>()) as GLsizeiptr,
                       &skyboxVertices[0] as *const f32 as *const c_void,
                       gl::STATIC_DRAW);
        gl::EnableVertexAttribArray(0);
        stride = 3 * mem::size_of::<GLfloat>() as GLsizei;
        gl::VertexAttribPointer(0, 3, gl::FLOAT, gl::FALSE, stride, ptr::null());

        // load textures
        // -------------
        let cubeTexture = loadTexture("resources/textures/marble.jpg");

        // TODO!!!

        // shader configuration
        // --------------------
        shader.useProgram();
        shader.setInt(c_str!("texture1"), 0);

        (shader, cubeVBO, cubeVAO, skyboxVBO, skyboxVAO, cubeTexture)
    };

    // render loop
    // -----------
    while !window.should_close() {
        // per-frame time logic
        // --------------------
        let currentFrame = glfw.get_time() as f32;
        deltaTime = currentFrame - lastFrame;
        lastFrame = currentFrame;

        // events
        // -----
        process_events(&events, &mut firstMouse, &mut lastX, &mut lastY, &mut camera);

        // input
        // -----
        processInput(&mut window, deltaTime, &mut camera);

        // render
        // ------
        unsafe {
            gl::ClearColor(0.1, 0.1, 0.1, 1.0);
            gl::Clear(gl::COLOR_BUFFER_BIT | gl::DEPTH_BUFFER_BIT);

            shader.useProgram();
            let mut model: Matrix4<f32>;
            let view = camera.GetViewMatrix();
            let projection: Matrix4<f32> = perspective(Deg(camera.Zoom), SCR_WIDTH as f32 / SCR_HEIGHT as f32 , 0.1, 100.0);
            shader.setMat4(c_str!("view"), &view);
            shader.setMat4(c_str!("projection"), &projection);
            // cubes
            gl::BindVertexArray(cubeVAO);
            gl::ActiveTexture(gl::TEXTURE0);
            gl::BindTexture(gl::TEXTURE_2D, cubeTexture);
            model = Matrix4::from_translation(vec3(-1.0, 0.0, -1.0));
            shader.setMat4(c_str!("model"), &model);
            gl::DrawArrays(gl::TRIANGLES, 0, 36);
            model = Matrix4::from_translation(vec3(2.0, 0.0, 0.0));
            shader.setMat4(c_str!("model"), &model);
            gl::DrawArrays(gl::TRIANGLES, 0, 36);
        }

        // glfw: swap buffers and poll IO events (keys pressed/released, mouse moved etc.)
        // -------------------------------------------------------------------------------
        window.swap_buffers();
        glfw.poll_events();
    }

    // optional: de-allocate all resources once they've outlived their purpose:
    // ------------------------------------------------------------------------
    unsafe {
        gl::DeleteVertexArrays(1, &cubeVAO);
        gl::DeleteVertexArrays(1, &skyboxVAO);
        gl::DeleteBuffers(1, &cubeVBO);
        gl::DeleteBuffers(1, &skyboxVBO);
    }
}
<|endoftext|>


<commit_before><commit_msg>Update Spirc depreciated rand method<commit_after><|endoftext|>


<commit_before>extern mod glfw;

fn main() {
    do glfw::spawn {
        io::println(fmt!("Primary monitor: %s\n", glfw::get_primary_monitor().get_name()));

        io::println(~"Available monitors\n\
                      ------------------");

        glfw::get_monitors().map(|monitor| {
            io::println(fmt!("%s:", monitor.get_name()));

            do monitor.get_video_modes().map |mode| {
                io::println(fmt!("  %s", mode.to_str()));
            }
        });
    }
}
<commit_msg>Print Monitor::get_video_mode in modes example<commit_after>extern mod glfw;

fn main() {
    do glfw::spawn {
        io::println(fmt!("%s:", glfw::get_primary_monitor().get_name()));
        io::println(fmt!("    %s\n", glfw::get_primary_monitor().get_video_mode().to_str()));

        io::println(~"Available monitors\n\
                      ------------------");
        glfw::get_monitors().map(|monitor| {
            io::println(fmt!("%s:", monitor.get_name()));

            do monitor.get_video_modes().map |mode| {
                io::println(fmt!("  %s", mode.to_str()));
            }
        });
    }
}
<|endoftext|>


<commit_before>use command_prelude::*;

use std::io::{self, BufRead};

use cargo::core::{Source, SourceId};
use cargo::sources::RegistrySource;
use cargo::util::{CargoError, CargoResultExt};
use cargo::ops;

pub fn cli() -> App {
    subcommand("login")
        .about(
            "Save an api token from the registry locally. \
             If token is not specified, it will be read from stdin.",
        )
        .arg(Arg::with_name("token"))
        .arg(opt("host", "Host to set the token for").value_name("HOST"))
        .arg(opt("registry", "Registry to use").value_name("REGISTRY"))
}

pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
    let registry = args.registry(config)?;

    let token = match args.value_of("token") {
        Some(token) => token.to_string(),
        None => {
            let host = match registry {
                Some(ref _registry) => {
                    return Err(format_err!(
                        "token must be provided when \
                         --registry is provided."
                    ).into());
                }
                None => {
                    let src = SourceId::crates_io(config)?;
                    let mut src = RegistrySource::remote(&src, config);
                    src.update()?;
                    let config = src.config()?.unwrap();
                    args.value_of("host")
                        .map(|s| s.to_string())
                        .unwrap_or_else(|| config.api.unwrap())
                }
            };
            println!("please visit {}me and paste the API Token below", host);
            let mut line = String::new();
            let input = io::stdin();
            input
                .lock()
                .read_line(&mut line)
                .chain_err(|| "failed to read stdin")
                .map_err(CargoError::from)?;
            line.trim().to_string()
        }
    };

    ops::registry_login(config, token, registry)?;
    Ok(())
}
<commit_msg>fix: login url<commit_after>use command_prelude::*;

use std::io::{self, BufRead};

use cargo::core::{Source, SourceId};
use cargo::sources::RegistrySource;
use cargo::util::{CargoError, CargoResultExt};
use cargo::ops;

pub fn cli() -> App {
    subcommand("login")
        .about(
            "Save an api token from the registry locally. \
             If token is not specified, it will be read from stdin.",
        )
        .arg(Arg::with_name("token"))
        .arg(opt("host", "Host to set the token for").value_name("HOST"))
        .arg(opt("registry", "Registry to use").value_name("REGISTRY"))
}

pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
    let registry = args.registry(config)?;

    let token = match args.value_of("token") {
        Some(token) => token.to_string(),
        None => {
            let host = match registry {
                Some(ref _registry) => {
                    return Err(format_err!(
                        "token must be provided when \
                         --registry is provided."
                    ).into());
                }
                None => {
                    let src = SourceId::crates_io(config)?;
                    let mut src = RegistrySource::remote(&src, config);
                    src.update()?;
                    let config = src.config()?.unwrap();
                    args.value_of("host")
                        .map(|s| s.to_string())
                        .unwrap_or_else(|| config.api.unwrap())
                }
            };
            println!("please visit {}/me and paste the API Token below", host);
            let mut line = String::new();
            let input = io::stdin();
            input
                .lock()
                .read_line(&mut line)
                .chain_err(|| "failed to read stdin")
                .map_err(CargoError::from)?;
            line.trim().to_string()
        }
    };

    ops::registry_login(config, token, registry)?;
    Ok(())
}
<|endoftext|>


<commit_before>extern crate rand;
extern crate pbr;
use rand::Rng;
use pbr::MultiBar;
use std::thread;
use std::time::Duration;

fn main() {
    let mut mb = MultiBar::new();
    mb.println("Your Application Header:");
    mb.println("");

    for i in 1..6 {
        let count = 100 * i;
        let mut pb = mb.create_bar(count);
        pb.tick_format("▏▎▍▌▋▊▉██▉▊▋▌▍▎▏");
        pb.show_message = true;
        thread::spawn(move || {
            for _ in 0..count/20 {
                for _ in 0..20 {
            	    pb.message("Waiting  : ");
            	    thread::sleep(Duration::from_millis(50));
            	    pb.tick();
        	    }
        	    for _ in 0..20 {
                    let n = rand::thread_rng().gen_range(0, 100 * i);
            	    pb.message("Connected: ");
            	    thread::sleep(Duration::from_millis(n));
            	    pb.inc();
        	    }
            }
    	    for _ in 0..20 {
        	    pb.message("Cleaning :");
        	    thread::sleep(Duration::from_millis(100));
            	pb.tick();
        	}
        	pb.message("Completed! ");
            pb.tick();
            pb.finish();
        });
    }

    mb.println("");
    mb.println("Text lines separate between two sections: ");
    mb.println("");

    for i in 1..4 {
        let count = 100 * i;
        let mut pb = mb.create_bar(count);
        thread::spawn(move || {
            for _ in 0..count {
                pb.inc();
                let n = rand::thread_rng().gen_range(0, 100 * i);
        	    thread::sleep(Duration::from_millis(n));
            }
            pb.finish();
        });
    }

    mb.listen();

    println!("\nall bars done!\n");
}
<commit_msg>fmt: fmt example<commit_after>extern crate rand;
extern crate pbr;
use rand::Rng;
use pbr::MultiBar;
use std::thread;
use std::time::Duration;

fn main() {
    let mut mb = MultiBar::new();
    mb.println("Your Application Header:");
    mb.println("");

    for i in 1..6 {
        let count = 100 * i;
        let mut pb = mb.create_bar(count);
        pb.tick_format("▏▎▍▌▋▊▉██▉▊▋▌▍▎▏");
        pb.show_message = true;
        thread::spawn(move || {
            for _ in 0..count / 20 {
                for _ in 0..20 {
                    pb.message("Waiting  : ");
                    thread::sleep(Duration::from_millis(50));
                    pb.tick();
                }
                for _ in 0..20 {
                    let n = rand::thread_rng().gen_range(0, 100 * i);
                    pb.message("Connected: ");
                    thread::sleep(Duration::from_millis(n));
                    pb.inc();
                }
            }
            for _ in 0..20 {
                pb.message("Cleaning :");
                thread::sleep(Duration::from_millis(100));
                pb.tick();
            }
            pb.message("Completed! ");
            pb.tick();
            pb.finish();
        });
    }

    mb.println("");
    mb.println("Text lines separate between two sections: ");
    mb.println("");

    for i in 1..4 {
        let count = 100 * i;
        let mut pb = mb.create_bar(count);
        thread::spawn(move || {
            for _ in 0..count {
                pb.inc();
                let n = rand::thread_rng().gen_range(0, 100 * i);
                thread::sleep(Duration::from_millis(n));
            }
            pb.finish();
        });
    }

    mb.listen();

    println!("\nall bars done!\n");
}
<|endoftext|>


<commit_before>extern crate polydraw;

use polydraw::{Application, Renderer, RenderFrame};

pub fn rand_u8(seed: &mut u64) -> u8 {
    *seed = seed.wrapping_mul(58321).wrapping_add(11113);
    (seed.wrapping_shr(16) % 256) as u8
}

pub fn update_data(data: &mut Vec<u8>, width: u32, height: u32, seed: &mut u64) {
   for y in 0..height {
      for x in 0..width {
         let i: usize = (3 * (x + y * width)) as usize;
         let r = rand_u8(seed);
         data[i] = r;
         data[i + 1] = r;
         data[i + 2] = r;
      }
   }
}

struct NoiseRenderer {
   counter: u64,
   seed: u64,
}

impl NoiseRenderer {
   fn new() -> Self {
      NoiseRenderer {
         counter: 0,
         seed: 0,
      }
   }
}

impl Renderer for NoiseRenderer {
   fn render(&mut self, render_frame: &mut RenderFrame) {
      self.counter += 1;
      self.seed = self.counter;
      update_data(&mut render_frame.data, render_frame.width, render_frame.height, &mut self.seed);
   }
}

fn main() {
   let mut renderer = NoiseRenderer::new();

   Application::new()
      .renderer(&mut renderer)
      .title("Noise")
      .size(800, 400)
      .position(400, 200)
      .run();
}
<commit_msg>Noise example using put_pixel method<commit_after>extern crate polydraw;

use polydraw::{Application, Renderer, RenderFrame};
use polydraw::draw::RGB;

pub fn rand_u8(seed: &mut u64) -> u8 {
    *seed = seed.wrapping_mul(58321).wrapping_add(11113);
    (seed.wrapping_shr(16) % 256) as u8
}

struct NoiseRenderer {
   counter: u64,
   seed: u64,
}

impl NoiseRenderer {
   fn new() -> Self {
      NoiseRenderer {
         counter: 0,
         seed: 0,
      }
   }
}

impl Renderer for NoiseRenderer {
   fn render(&mut self, frame: &mut RenderFrame) {
      self.counter += 1;
      self.seed = self.counter;

      for y in 0..frame.height as i32 {
         for x in 0..frame.width as i32 {
            let r = rand_u8(&mut self.seed);
            frame.put_pixel(x, y, &RGB::new(r, r, r));
         }
      }
   }
}

fn main() {
   let mut renderer = NoiseRenderer::new();

   Application::new()
      .renderer(&mut renderer)
      .title("Noise")
      .size(800, 400)
      .position(400, 200)
      .run();
}
<|endoftext|>


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

extern crate cargo;
extern crate env_logger;
extern crate git2_curl;
extern crate rustc_serialize;
extern crate toml;
#[macro_use] extern crate log;

use std::collections::BTreeSet;
use std::env;
use std::fs;
use std::io;
use std::path::{PathBuf, Path};
use std::process::Command;

use cargo::{execute_main_without_stdin, handle_error, shell};
use cargo::core::MultiShell;
use cargo::util::{CliError, CliResult, lev_distance, Config};

#[derive(RustcDecodable)]
struct Flags {
    flag_list: bool,
    flag_verbose: bool,
    arg_command: String,
    arg_args: Vec<String>,
}

const USAGE: &'static str = "
Rust's package manager

Usage:
    cargo <command> [<args>...]
    cargo [options]

Options:
    -h, --help       Display this message
    -V, --version    Print version info and exit
    --list           List installed commands
    -v, --verbose    Use verbose output

Some common cargo commands are:
    build       Compile the current project
    clean       Remove the target directory
    doc         Build this project's and its dependencies' documentation
    new         Create a new cargo project
    run         Build and execute src/main.rs
    test        Run the tests
    bench       Run the benchmarks
    update      Update dependencies listed in Cargo.lock
    search      Search crates from host of a registry

See 'cargo help <command>' for more information on a specific command.
";

fn main() {
    env_logger::init().unwrap();
    execute_main_without_stdin(execute, true, USAGE)
}

macro_rules! each_subcommand{ ($mac:ident) => ({
    $mac!(bench);
    $mac!(build);
    $mac!(clean);
    $mac!(doc);
    $mac!(fetch);
    $mac!(generate_lockfile);
    $mac!(git_checkout);
    $mac!(help);
    $mac!(locate_project);
    $mac!(login);
    $mac!(new);
    $mac!(owner);
    $mac!(package);
    $mac!(pkgid);
    $mac!(publish);
    $mac!(read_manifest);
    $mac!(run);
    $mac!(search);
    $mac!(test);
    $mac!(update);
    $mac!(verify_project);
    $mac!(version);
    $mac!(yank);
}) }

/**
  The top-level `cargo` command handles configuration and project location
  because they are fundamental (and intertwined). Other commands can rely
  on this top-level information.
*/
fn execute(flags: Flags, config: &Config) -> CliResult<Option<()>> {
    config.shell().set_verbose(flags.flag_verbose);

    init_git_transports(config);

    if flags.flag_list {
        println!("Installed Commands:");
        for command in list_commands().into_iter() {
            println!("    {}", command);
        };
        return Ok(None)
    }

    let args = match &flags.arg_command[..] {
        // For the commands `cargo` and `cargo help`, re-execute ourselves as
        // `cargo -h` so we can go through the normal process of printing the
        // help message.
        "" | "help" if flags.arg_args.is_empty() => {
            config.shell().set_verbose(true);
            let args = &["cargo".to_string(), "-h".to_string()];
            let r = cargo::call_main_without_stdin(execute, config, USAGE, args,
                                                   false);
            cargo::process_executed(r, &mut config.shell());
            return Ok(None)
        }

        // For `cargo help -h` and `cargo help --help`, print out the help
        // message for `cargo help`
        "help" if flags.arg_args[0] == "-h" ||
                  flags.arg_args[0] == "--help" => {
            vec!["cargo".to_string(), "help".to_string(), "-h".to_string()]
        }

        // For `cargo help foo`, print out the usage message for the specified
        // subcommand by executing the command with the `-h` flag.
        "help" => {
            vec!["cargo".to_string(), flags.arg_args[0].clone(),
                 "-h".to_string()]
        }

        // For all other invocations, we're of the form `cargo foo args...`. We
        // use the exact environment arguments to preserve tokens like `--` for
        // example.
        _ => env::args().collect(),
    };

    macro_rules! cmd{ ($name:ident) => (
        if args[1] == stringify!($name).replace("_", "-") {
            mod $name;
            config.shell().set_verbose(true);
            let r = cargo::call_main_without_stdin($name::execute, config,
                                                   $name::USAGE,
                                                   &args,
                                                   false);
            cargo::process_executed(r, &mut config.shell());
            return Ok(None)
        }
    ) }
    each_subcommand!(cmd);

    execute_subcommand(&args[1], &args, &mut config.shell());
    Ok(None)
}

fn find_closest(cmd: &str) -> Option<String> {
    let cmds = list_commands();
    // Only consider candidates with a lev_distance of 3 or less so we don't
    // suggest out-of-the-blue options.
    let mut filtered = cmds.iter().map(|c| (lev_distance(&c, cmd), c))
                                  .filter(|&(d, _)| d < 4)
                                  .collect::<Vec<_>>();
    filtered.sort_by(|a, b| a.0.cmp(&b.0));

    if filtered.len() == 0 {
        None
    } else {
        Some(filtered[0].1.to_string())
    }
}

fn execute_subcommand(cmd: &str, args: &[String], shell: &mut MultiShell) {
    let command = match find_command(cmd) {
        Some(command) => command,
        None => {
            let msg = match find_closest(cmd) {
                Some(closest) => format!("No such subcommand\n\n\t\
                                          Did you mean `{}`?\n", closest),
                None => "No such subcommand".to_string()
            };
            return handle_error(CliError::new(&msg, 127), shell)
        }
    };
    match Command::new(&command).args(&args[1..]).status() {
        Ok(ref status) if status.success() => {}
        Ok(ref status) => {
            match status.code() {
                Some(code) => handle_error(CliError::new("", code), shell),
                None => {
                    let msg = format!("subcommand failed with: {}", status);
                    handle_error(CliError::new(&msg, 101), shell)
                }
            }
        }
        Err(ref e) if e.kind() == io::ErrorKind::NotFound => {
            handle_error(CliError::new("No such subcommand", 127), shell)
        }
        Err(err) => {
            let msg = format!("Subcommand failed to run: {}", err);
            handle_error(CliError::new(&msg, 127), shell)
        }
    }
}

/// List all runnable commands. find_command should always succeed
/// if given one of returned command.
fn list_commands() -> BTreeSet<String> {
    let command_prefix = "cargo-";
    let mut commands = BTreeSet::new();
    for dir in list_command_directory().iter() {
        let entries = match fs::read_dir(dir) {
            Ok(entries) => entries,
            _ => continue
        };
        for entry in entries {
            let entry = match entry { Ok(e) => e, Err(..) => continue };
            let entry = entry.path();
            let filename = match entry.file_name().and_then(|s| s.to_str()) {
                Some(filename) => filename,
                _ => continue
            };
            if filename.starts_with(command_prefix) &&
               filename.ends_with(env::consts::EXE_SUFFIX) &&
               is_executable(&entry) {
                let command = &filename[
                    command_prefix.len()..
                    filename.len() - env::consts::EXE_SUFFIX.len()];
                commands.insert(command.to_string());
            }
        }
    }

    macro_rules! add_cmd{ ($cmd:ident) => ({
        commands.insert(stringify!($cmd).replace("_", "-"));
    }) }
    each_subcommand!(add_cmd);
    commands
}

#[cfg(unix)]
fn is_executable(path: &Path) -> bool {
    use std::os::unix::prelude::*;
    fs::metadata(path).map(|m| {
        m.permissions().mode() & 0o001 == 0o001
    }).unwrap_or(false)
}
#[cfg(windows)]
fn is_executable(path: &Path) -> bool {
    fs::metadata(path).map(|m| m.is_file()).unwrap_or(false)
}

/// Get `Command` to run given command.
fn find_command(cmd: &str) -> Option<PathBuf> {
    let command_exe = format!("cargo-{}{}", cmd, env::consts::EXE_SUFFIX);
    let dirs = list_command_directory();
    let mut command_paths = dirs.iter().map(|dir| dir.join(&command_exe));
    command_paths.find(|path| fs::metadata(&path).is_ok())
}

/// List candidate locations where subcommands might be installed.
fn list_command_directory() -> Vec<PathBuf> {
    let mut dirs = vec![];
    if let Ok(mut path) = env::current_exe() {
        path.pop();
        dirs.push(path.join("../lib/cargo"));
        dirs.push(path);
    }
    if let Some(val) = env::var_os("PATH") {
        dirs.extend(env::split_paths(&val));
    }
    dirs
}

fn init_git_transports(config: &Config) {
    // Only use a custom transport if a proxy is configured, right now libgit2
    // doesn't support proxies and we have to use a custom transport in this
    // case. The custom transport, however, is not as well battle-tested.
    match cargo::ops::http_proxy_exists(config) {
        Ok(true) => {}
        _ => return
    }

    let handle = match cargo::ops::http_handle(config) {
        Ok(handle) => handle,
        Err(..) => return,
    };

    // The unsafety of the registration function derives from two aspects:
    //
    // 1. This call must be synchronized with all other registration calls as
    //    well as construction of new transports.
    // 2. The argument is leaked.
    //
    // We're clear on point (1) because this is only called at the start of this
    // binary (we know what the state of the world looks like) and we're mostly
    // clear on point (2) because we'd only free it after everything is done
    // anyway
    unsafe {
        git2_curl::register(handle);
    }
}
<commit_msg>change search help to better message<commit_after>#![cfg_attr(unix, feature(fs_ext))]

extern crate cargo;
extern crate env_logger;
extern crate git2_curl;
extern crate rustc_serialize;
extern crate toml;
#[macro_use] extern crate log;

use std::collections::BTreeSet;
use std::env;
use std::fs;
use std::io;
use std::path::{PathBuf, Path};
use std::process::Command;

use cargo::{execute_main_without_stdin, handle_error, shell};
use cargo::core::MultiShell;
use cargo::util::{CliError, CliResult, lev_distance, Config};

#[derive(RustcDecodable)]
struct Flags {
    flag_list: bool,
    flag_verbose: bool,
    arg_command: String,
    arg_args: Vec<String>,
}

const USAGE: &'static str = "
Rust's package manager

Usage:
    cargo <command> [<args>...]
    cargo [options]

Options:
    -h, --help       Display this message
    -V, --version    Print version info and exit
    --list           List installed commands
    -v, --verbose    Use verbose output

Some common cargo commands are:
    build       Compile the current project
    clean       Remove the target directory
    doc         Build this project's and its dependencies' documentation
    new         Create a new cargo project
    run         Build and execute src/main.rs
    test        Run the tests
    bench       Run the benchmarks
    update      Update dependencies listed in Cargo.lock
    search      Search registry for crates

See 'cargo help <command>' for more information on a specific command.
";

fn main() {
    env_logger::init().unwrap();
    execute_main_without_stdin(execute, true, USAGE)
}

macro_rules! each_subcommand{ ($mac:ident) => ({
    $mac!(bench);
    $mac!(build);
    $mac!(clean);
    $mac!(doc);
    $mac!(fetch);
    $mac!(generate_lockfile);
    $mac!(git_checkout);
    $mac!(help);
    $mac!(locate_project);
    $mac!(login);
    $mac!(new);
    $mac!(owner);
    $mac!(package);
    $mac!(pkgid);
    $mac!(publish);
    $mac!(read_manifest);
    $mac!(run);
    $mac!(search);
    $mac!(test);
    $mac!(update);
    $mac!(verify_project);
    $mac!(version);
    $mac!(yank);
}) }

/**
  The top-level `cargo` command handles configuration and project location
  because they are fundamental (and intertwined). Other commands can rely
  on this top-level information.
*/
fn execute(flags: Flags, config: &Config) -> CliResult<Option<()>> {
    config.shell().set_verbose(flags.flag_verbose);

    init_git_transports(config);

    if flags.flag_list {
        println!("Installed Commands:");
        for command in list_commands().into_iter() {
            println!("    {}", command);
        };
        return Ok(None)
    }

    let args = match &flags.arg_command[..] {
        // For the commands `cargo` and `cargo help`, re-execute ourselves as
        // `cargo -h` so we can go through the normal process of printing the
        // help message.
        "" | "help" if flags.arg_args.is_empty() => {
            config.shell().set_verbose(true);
            let args = &["cargo".to_string(), "-h".to_string()];
            let r = cargo::call_main_without_stdin(execute, config, USAGE, args,
                                                   false);
            cargo::process_executed(r, &mut config.shell());
            return Ok(None)
        }

        // For `cargo help -h` and `cargo help --help`, print out the help
        // message for `cargo help`
        "help" if flags.arg_args[0] == "-h" ||
                  flags.arg_args[0] == "--help" => {
            vec!["cargo".to_string(), "help".to_string(), "-h".to_string()]
        }

        // For `cargo help foo`, print out the usage message for the specified
        // subcommand by executing the command with the `-h` flag.
        "help" => {
            vec!["cargo".to_string(), flags.arg_args[0].clone(),
                 "-h".to_string()]
        }

        // For all other invocations, we're of the form `cargo foo args...`. We
        // use the exact environment arguments to preserve tokens like `--` for
        // example.
        _ => env::args().collect(),
    };

    macro_rules! cmd{ ($name:ident) => (
        if args[1] == stringify!($name).replace("_", "-") {
            mod $name;
            config.shell().set_verbose(true);
            let r = cargo::call_main_without_stdin($name::execute, config,
                                                   $name::USAGE,
                                                   &args,
                                                   false);
            cargo::process_executed(r, &mut config.shell());
            return Ok(None)
        }
    ) }
    each_subcommand!(cmd);

    execute_subcommand(&args[1], &args, &mut config.shell());
    Ok(None)
}

fn find_closest(cmd: &str) -> Option<String> {
    let cmds = list_commands();
    // Only consider candidates with a lev_distance of 3 or less so we don't
    // suggest out-of-the-blue options.
    let mut filtered = cmds.iter().map(|c| (lev_distance(&c, cmd), c))
                                  .filter(|&(d, _)| d < 4)
                                  .collect::<Vec<_>>();
    filtered.sort_by(|a, b| a.0.cmp(&b.0));

    if filtered.len() == 0 {
        None
    } else {
        Some(filtered[0].1.to_string())
    }
}

fn execute_subcommand(cmd: &str, args: &[String], shell: &mut MultiShell) {
    let command = match find_command(cmd) {
        Some(command) => command,
        None => {
            let msg = match find_closest(cmd) {
                Some(closest) => format!("No such subcommand\n\n\t\
                                          Did you mean `{}`?\n", closest),
                None => "No such subcommand".to_string()
            };
            return handle_error(CliError::new(&msg, 127), shell)
        }
    };
    match Command::new(&command).args(&args[1..]).status() {
        Ok(ref status) if status.success() => {}
        Ok(ref status) => {
            match status.code() {
                Some(code) => handle_error(CliError::new("", code), shell),
                None => {
                    let msg = format!("subcommand failed with: {}", status);
                    handle_error(CliError::new(&msg, 101), shell)
                }
            }
        }
        Err(ref e) if e.kind() == io::ErrorKind::NotFound => {
            handle_error(CliError::new("No such subcommand", 127), shell)
        }
        Err(err) => {
            let msg = format!("Subcommand failed to run: {}", err);
            handle_error(CliError::new(&msg, 127), shell)
        }
    }
}

/// List all runnable commands. find_command should always succeed
/// if given one of returned command.
fn list_commands() -> BTreeSet<String> {
    let command_prefix = "cargo-";
    let mut commands = BTreeSet::new();
    for dir in list_command_directory().iter() {
        let entries = match fs::read_dir(dir) {
            Ok(entries) => entries,
            _ => continue
        };
        for entry in entries {
            let entry = match entry { Ok(e) => e, Err(..) => continue };
            let entry = entry.path();
            let filename = match entry.file_name().and_then(|s| s.to_str()) {
                Some(filename) => filename,
                _ => continue
            };
            if filename.starts_with(command_prefix) &&
               filename.ends_with(env::consts::EXE_SUFFIX) &&
               is_executable(&entry) {
                let command = &filename[
                    command_prefix.len()..
                    filename.len() - env::consts::EXE_SUFFIX.len()];
                commands.insert(command.to_string());
            }
        }
    }

    macro_rules! add_cmd{ ($cmd:ident) => ({
        commands.insert(stringify!($cmd).replace("_", "-"));
    }) }
    each_subcommand!(add_cmd);
    commands
}

#[cfg(unix)]
fn is_executable(path: &Path) -> bool {
    use std::os::unix::prelude::*;
    fs::metadata(path).map(|m| {
        m.permissions().mode() & 0o001 == 0o001
    }).unwrap_or(false)
}
#[cfg(windows)]
fn is_executable(path: &Path) -> bool {
    fs::metadata(path).map(|m| m.is_file()).unwrap_or(false)
}

/// Get `Command` to run given command.
fn find_command(cmd: &str) -> Option<PathBuf> {
    let command_exe = format!("cargo-{}{}", cmd, env::consts::EXE_SUFFIX);
    let dirs = list_command_directory();
    let mut command_paths = dirs.iter().map(|dir| dir.join(&command_exe));
    command_paths.find(|path| fs::metadata(&path).is_ok())
}

/// List candidate locations where subcommands might be installed.
fn list_command_directory() -> Vec<PathBuf> {
    let mut dirs = vec![];
    if let Ok(mut path) = env::current_exe() {
        path.pop();
        dirs.push(path.join("../lib/cargo"));
        dirs.push(path);
    }
    if let Some(val) = env::var_os("PATH") {
        dirs.extend(env::split_paths(&val));
    }
    dirs
}

fn init_git_transports(config: &Config) {
    // Only use a custom transport if a proxy is configured, right now libgit2
    // doesn't support proxies and we have to use a custom transport in this
    // case. The custom transport, however, is not as well battle-tested.
    match cargo::ops::http_proxy_exists(config) {
        Ok(true) => {}
        _ => return
    }

    let handle = match cargo::ops::http_handle(config) {
        Ok(handle) => handle,
        Err(..) => return,
    };

    // The unsafety of the registration function derives from two aspects:
    //
    // 1. This call must be synchronized with all other registration calls as
    //    well as construction of new transports.
    // 2. The argument is leaked.
    //
    // We're clear on point (1) because this is only called at the start of this
    // binary (we know what the state of the world looks like) and we're mostly
    // clear on point (2) because we'd only free it after everything is done
    // anyway
    unsafe {
        git2_curl::register(handle);
    }
}
<|endoftext|>


<commit_before>#[macro_use]
extern crate error_chain;
#[macro_use]
extern crate lanta;

use lanta::{cmd, Lanta, ModKey};
use lanta::errors::*;
use lanta::layout::*;

macro_rules! spawn {
    ($cmd:expr) => (::lanta::cmd::lazy::spawn(::std::process::Command::new($cmd)));
    ($cmd:expr, $($arg:expr),*) => {{
        let mut command = ::std::process::Command::new($cmd);
        $(
            command.arg($arg);
        )*
        ::lanta::cmd::lazy::spawn(command)
    }}
}

fn run() -> Result<()> {
    lanta::intiailize_logger()?;

    let modkey = ModKey::Control;
    let shift = ModKey::Shift;
    let mut keys = keys![
        ([modkey], XK_w, cmd::lazy::close_focused_window()),
        ([modkey], XK_j, cmd::lazy::focus_next()),
        ([modkey], XK_k, cmd::lazy::focus_previous()),
        ([modkey, shift], XK_j, cmd::lazy::shuffle_next()),
        ([modkey, shift], XK_k, cmd::lazy::shuffle_previous()),
        ([modkey], XK_Tab, cmd::lazy::layout_next()),
        ([modkey], XK_Return, spawn!("urxvt")),
        ([modkey], XK_c, spawn!("chrome")),
        ([modkey], XK_v, spawn!("code")),
        (
            [modkey],
            XK_q,
            spawn!("change-wallpaper")
        ),
        ([], XF86XK_MonBrightnessUp, spawn!("xbacklight", "-inc", "10")),
        ([], XF86XK_MonBrightnessDown, spawn!("xbacklight", "-dec", "10")),
        ([], XF86XK_AudioPrev, spawn!("playerctl", "previous")),
        ([], XF86XK_AudioPlay, spawn!("playerctl", "play-pause")),
        ([], XF86XK_AudioNext, spawn!("playerctl", "next")),
        ([], XF86XK_AudioRaiseVolume, spawn!("amixer", "-q", "set", "Master", "5%+")),
        ([], XF86XK_AudioLowerVolume, spawn!("amixer", "-q", "set", "Master", "5%-")),
        ([], XF86XK_AudioMute, spawn!("amixer", "-q", "set", "Master", "toggle")),
    ];

    let padding = 20;
    let layouts = vec![
        StackLayout::new("stack-padded", padding),
        StackLayout::new("stack", 0),
        TiledLayout::new("tiled", padding),
    ];

    let groups = groups!{
        keys,
        [
            ([modkey], XK_a, "chrome", "stack"),
            ([modkey], XK_s, "code", "stack"),
            ([modkey], XK_d, "term", "tiled"),
            ([modkey], XK_f, "misc", "tiled"),
        ]
    };

    Lanta::new(keys, groups, layouts)?.run();

    Ok(())
}

quick_main!(run);
<commit_msg>Tweak formatting.<commit_after>#[macro_use]
extern crate error_chain;
#[macro_use]
extern crate lanta;

use lanta::{cmd, Lanta, ModKey};
use lanta::errors::*;
use lanta::layout::*;

macro_rules! spawn {
    ($cmd:expr) => (::lanta::cmd::lazy::spawn(::std::process::Command::new($cmd)));
    ($cmd:expr, $($arg:expr),*) => {{
        let mut command = ::std::process::Command::new($cmd);
        $(
            command.arg($arg);
        )*
        ::lanta::cmd::lazy::spawn(command)
    }}
}

fn run() -> Result<()> {
    lanta::intiailize_logger()?;

    let modkey = ModKey::Control;
    let shift = ModKey::Shift;
    let mut keys = keys![
        ([modkey], XK_w, cmd::lazy::close_focused_window()),
        ([modkey], XK_j, cmd::lazy::focus_next()),
        ([modkey], XK_k, cmd::lazy::focus_previous()),
        ([modkey, shift], XK_j, cmd::lazy::shuffle_next()),
        ([modkey, shift], XK_k, cmd::lazy::shuffle_previous()),
        ([modkey], XK_Tab, cmd::lazy::layout_next()),
        ([modkey], XK_Return, spawn!("urxvt")),
        ([modkey], XK_c, spawn!("chrome")),
        ([modkey], XK_v, spawn!("code")),
        ([modkey], XK_q, spawn!("change-wallpaper")),
        ([], XF86XK_MonBrightnessUp, spawn!("xbacklight", "-inc", "10")),
        ([], XF86XK_MonBrightnessDown, spawn!("xbacklight", "-dec", "10")),
        ([], XF86XK_AudioPrev, spawn!("playerctl", "previous")),
        ([], XF86XK_AudioPlay, spawn!("playerctl", "play-pause")),
        ([], XF86XK_AudioNext, spawn!("playerctl", "next")),
        ([], XF86XK_AudioRaiseVolume, spawn!("amixer", "-q", "set", "Master", "5%+")),
        ([], XF86XK_AudioLowerVolume, spawn!("amixer", "-q", "set", "Master", "5%-")),
        ([], XF86XK_AudioMute, spawn!("amixer", "-q", "set", "Master", "toggle")),
    ];

    let padding = 20;
    let layouts = vec![
        StackLayout::new("stack-padded", padding),
        StackLayout::new("stack", 0),
        TiledLayout::new("tiled", padding),
    ];

    let groups = groups!{
        keys,
        [
            ([modkey], XK_a, "chrome", "stack"),
            ([modkey], XK_s, "code", "stack"),
            ([modkey], XK_d, "term", "tiled"),
            ([modkey], XK_f, "misc", "tiled"),
        ]
    };

    Lanta::new(keys, groups, layouts)?.run();

    Ok(())
}

quick_main!(run);
<|endoftext|>