<commit_before><commit_msg>Added common helper part, here a cool thread-pool.<commit_after>// common things

use std::thread;

/// This ThreadPool is just a pool of predefined, fixed number
/// of threads. Instead of spawning new, you can just
/// renew it.
/// It is not ideally but a step and nice example of how
/// to pass a closure into a function.
pub struct ThreadPool {
    threads: Vec<thread::JoinHandle<()>>,
}

impl ThreadPool {
    pub fn new(size: usize) -> ThreadPool {
        assert!(size > 0);
        let mut threads = Vec::with_capacity(size);
        for _ in 0..size {
            threads.push(thread::spawn(|| {}));
        }
        ThreadPool { threads }
    }

    // awesome: taking the closure directly from the call!! Works!!
    // but static lifetime seems presumptuous
    pub fn renew<F: 'static + Send>(&mut self, idx: usize, f: F)
    where
        F: FnOnce(),
    {
        assert!(idx < self.threads.len());
        drop(&self.threads[idx]);
        self.threads[idx] = thread::spawn(move || f());
    }
}
<|endoftext|>


<commit_before><commit_msg>Sample windows service<commit_after>#![feature(collections)]
#![feature(asm)]
#![feature(io)]

extern crate winapi;
extern crate "advapi32-sys" as advapi32;

use std::old_io::{File, Open, ReadWrite, IoError, SeekStyle};
use std::ptr;
use std::mem::*;
use winapi::*;
use advapi32::*;

fn main() {
	log("BEGIN");

	unsafe {
		let service_name = service_name();
		let service_table: &[LPCSERVICE_TABLE_ENTRYW] = &[
			&SERVICE_TABLE_ENTRYW {
				lpServiceName: service_name.as_ptr(),
				lpServiceProc: service_main,
			},
			ptr::null()
		];
		//asm!(" int3");
		let result = StartServiceCtrlDispatcherW(*service_table.as_ptr());
		log(format! ("StartServiceCtrlDispatcherW: {}", result).as_slice());
	}
	log("END");
}

fn service_name() -> Vec<u16> {
	let name = "hello";
	let mut result: Vec<u16> = name.utf16_units().collect();
	result.push(0);
	result
}

fn create_service_status(current_state: SERVICE_CURRENT_STATE) -> SERVICE_STATUS {
	SERVICE_STATUS {
		dwServiceType: SERVICE_WIN32_OWN_PROCESS,
		dwCurrentState: current_state,
		dwControlsAccepted: SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN,
		dwWin32ExitCode: 0,
		dwServiceSpecificExitCode: 0,
		dwCheckPoint: 0,
		dwWaitHint: 0,
	}
}

static mut service_handle : Option<SERVICE_STATUS_HANDLE> = None;

unsafe extern "system" fn service_main(
	dwNumServicesArgs: DWORD,
	lpServiceArgVectors: *mut LPWSTR,
) {
	log("service_main: BEGIN");
	let service_name = service_name();
	let handle = RegisterServiceCtrlHandlerExW(service_name.as_ptr(), control_handler, ptr::null_mut());
	service_handle = Some(handle);
	SetServiceStatus (handle, &create_service_status(SERVICE_CURRENT_STATE::START_PENDING));
	SetServiceStatus (handle, &create_service_status(SERVICE_CURRENT_STATE::RUNNING));
	log("service_main: END");
}

unsafe extern "system" fn control_handler(
	dwControl: SERVICE_CONTROL,
	dwEventType: DWORD,
	lpEventData: LPVOID,
	lpContext: LPVOID
) -> DWORD {
	match dwControl {
		SERVICE_CONTROL::STOP | SERVICE_CONTROL::SHUTDOWN => {
			log("control_handler: STOP");
			match service_handle {
				Some(handle) => {SetServiceStatus (handle, &create_service_status(SERVICE_CURRENT_STATE::STOPPED));}
				None => {}
			}
		}
		_ => {}
	};
	0
}

fn log(message: &str) -> Result<(), IoError> {
	let mut file = try! (File::open_mode(&Path::new("C:\\Bozaro\\github\\winapi-rs\\advapi32-sys\\target\\log.txt"), Open, ReadWrite));
	file.seek(0, SeekStyle::SeekEnd);
	file.write_line(message)
}
<|endoftext|>


<commit_before>use super::{
    FnEvalContext,
    CachedMir,
    TerminatorTarget,
    ConstantId,
    GlobalEvalContext,
    ConstantKind,
};
use error::EvalResult;
use rustc::mir::repr as mir;
use rustc::ty::subst::{self, Subst};
use rustc::hir::def_id::DefId;
use rustc::mir::visit::{Visitor, LvalueContext};
use syntax::codemap::Span;
use std::rc::Rc;
use memory::Pointer;

pub enum Event<'a, 'tcx: 'a> {
    Block(mir::BasicBlock),
    Return,
    Call,
    Constant,
    Assignment(&'a mir::Statement<'tcx>),
    Terminator(&'a mir::Terminator<'tcx>),
    Done,
}

pub struct Stepper<'fncx, 'a: 'fncx, 'b: 'a + 'mir, 'mir: 'fncx, 'tcx: 'b>{
    fncx: &'fncx mut FnEvalContext<'a, 'b, 'mir, 'tcx>,

    // a cache of the constants to be computed before the next statement/terminator
    // this is an optimization, so we don't have to allocate a new vector for every statement
    constants: Vec<(ConstantId<'tcx>, Span, Pointer, CachedMir<'mir, 'tcx>)>,
}

impl<'fncx, 'a, 'b: 'a + 'mir, 'mir, 'tcx: 'b> Stepper<'fncx, 'a, 'b, 'mir, 'tcx> {
    pub(super) fn new(fncx: &'fncx mut FnEvalContext<'a, 'b, 'mir, 'tcx>) -> Self {
        Stepper {
            fncx: fncx,
            constants: Vec::new(),
        }
    }

    fn statement<F: for<'f> FnMut(Event<'f, 'tcx>)>(&mut self, mut f: F) -> EvalResult<()> {
        let mir = self.fncx.mir();
        let block_data = mir.basic_block_data(self.fncx.frame().next_block);
        let stmt = &block_data.statements[self.fncx.frame().stmt];
        f(Event::Assignment(stmt));
        let mir::StatementKind::Assign(ref lvalue, ref rvalue) = stmt.kind;
        let result = self.fncx.eval_assignment(lvalue, rvalue);
        self.fncx.maybe_report(result)?;
        self.fncx.frame_mut().stmt += 1;
        Ok(())
    }

    fn terminator<F: for<'f> FnMut(Event<'f, 'tcx>)>(&mut self, mut f: F) -> EvalResult<()> {
        // after a terminator we go to a new block
        self.fncx.frame_mut().stmt = 0;
        let term = {
            let mir = self.fncx.mir();
            let block_data = mir.basic_block_data(self.fncx.frame().next_block);
            let terminator = block_data.terminator();
            f(Event::Terminator(terminator));
            let result = self.fncx.eval_terminator(terminator);
            self.fncx.maybe_report(result)?
        };
        match term {
            TerminatorTarget::Block => f(Event::Block(self.fncx.frame().next_block)),
            TerminatorTarget::Return => {
                f(Event::Return);
                self.fncx.pop_stack_frame();
            },
            TerminatorTarget::Call => f(Event::Call),
        }
        Ok(())
    }

    // returns true as long as there are more things to do
    pub fn step<F: for<'f> FnMut(Event<'f, 'tcx>)>(&mut self, mut f: F) -> EvalResult<()> {
        if self.fncx.stack.is_empty() {
            f(Event::Done);
            return Ok(());
        }

        let block = self.fncx.frame().next_block;
        let stmt = self.fncx.frame().stmt;
        let mir = self.fncx.mir();
        let basic_block = mir.basic_block_data(block);

        if let Some(ref stmt) = basic_block.statements.get(stmt) {
            assert!(self.constants.is_empty());
            ConstantExtractor {
                span: stmt.span,
                substs: self.fncx.substs(),
                def_id: self.fncx.frame().def_id,
                gecx: self.fncx.gecx,
                constants: &mut self.constants,
                mir: &mir,
            }.visit_statement(block, stmt);
            if self.constants.is_empty() {
                return self.statement(f);
            } else {
                return self.extract_constants(f);
            }
        }

        let terminator = basic_block.terminator();
        assert!(self.constants.is_empty());
        ConstantExtractor {
            span: terminator.span,
            substs: self.fncx.substs(),
            def_id: self.fncx.frame().def_id,
            gecx: self.fncx.gecx,
            constants: &mut self.constants,
            mir: &mir,
        }.visit_terminator(block, terminator);
        if self.constants.is_empty() {
            self.terminator(f)
        } else {
            self.extract_constants(f)
        }
    }

    fn extract_constants<F: for<'f> FnMut(Event<'f, 'tcx>)>(&mut self, mut f: F) -> EvalResult<()> {
        assert!(!self.constants.is_empty());
        for (cid, span, return_ptr, mir) in self.constants.drain(..) {
            f(Event::Constant);
            self.fncx.push_stack_frame(cid.def_id, span, mir, cid.substs, Some(return_ptr));
        }
        self.step(f)
    }
}

struct ConstantExtractor<'a, 'b: 'mir, 'mir: 'a, 'tcx: 'b> {
    span: Span,
    constants: &'a mut Vec<(ConstantId<'tcx>, Span, Pointer, CachedMir<'mir, 'tcx>)>,
    gecx: &'a mut GlobalEvalContext<'b, 'tcx>,
    mir: &'a mir::Mir<'tcx>,
    def_id: DefId,
    substs: &'tcx subst::Substs<'tcx>,
}

impl<'a, 'b, 'mir, 'tcx> ConstantExtractor<'a, 'b, 'mir, 'tcx> {
    fn static_item(&mut self, def_id: DefId, substs: &'tcx subst::Substs<'tcx>, span: Span) {
        let cid = ConstantId {
            def_id: def_id,
            substs: substs,
            kind: ConstantKind::Global,
        };
        if self.gecx.statics.contains_key(&cid) {
            return;
        }
        let mir = self.gecx.load_mir(def_id);
        let ptr = self.gecx.alloc_ret_ptr(mir.return_ty, substs).expect("there's no such thing as an unreachable static");
        self.gecx.statics.insert(cid.clone(), ptr);
        self.constants.push((cid, span, ptr, mir));
    }
}

impl<'a, 'b, 'mir, 'tcx> Visitor<'tcx> for ConstantExtractor<'a, 'b, 'mir, 'tcx> {
    fn visit_constant(&mut self, constant: &mir::Constant<'tcx>) {
        self.super_constant(constant);
        match constant.literal {
            // already computed by rustc
            mir::Literal::Value { .. } => {}
            mir::Literal::Item { def_id, substs } => {
                let item_ty = self.gecx.tcx.lookup_item_type(def_id).subst(self.gecx.tcx, substs);
                if item_ty.ty.is_fn() {
                    // unimplemented
                } else {
                    self.static_item(def_id, substs, constant.span);
                }
            },
            mir::Literal::Promoted { index } => {
                let cid = ConstantId {
                    def_id: self.def_id,
                    substs: self.substs,
                    kind: ConstantKind::Promoted(index),
                };
                if self.gecx.statics.contains_key(&cid) {
                    return;
                }
                let mir = self.mir.promoted[index].clone();
                let return_ty = mir.return_ty;
                let return_ptr = self.gecx.alloc_ret_ptr(return_ty, cid.substs).expect("there's no such thing as an unreachable static");
                let mir = CachedMir::Owned(Rc::new(mir));
                self.gecx.statics.insert(cid.clone(), return_ptr);
                self.constants.push((cid, constant.span, return_ptr, mir));
            }
        }
    }

    fn visit_lvalue(&mut self, lvalue: &mir::Lvalue<'tcx>, context: LvalueContext) {
        self.super_lvalue(lvalue, context);
        if let mir::Lvalue::Static(def_id) = *lvalue {
            let substs = self.gecx.tcx.mk_substs(subst::Substs::empty());
            let span = self.span;
            self.static_item(def_id, substs, span);
        }
    }
}
<commit_msg>the statement/terminator has already been computed, don't do it again<commit_after>use super::{
    FnEvalContext,
    CachedMir,
    TerminatorTarget,
    ConstantId,
    GlobalEvalContext,
    ConstantKind,
};
use error::EvalResult;
use rustc::mir::repr as mir;
use rustc::ty::subst::{self, Subst};
use rustc::hir::def_id::DefId;
use rustc::mir::visit::{Visitor, LvalueContext};
use syntax::codemap::Span;
use std::rc::Rc;
use memory::Pointer;

pub enum Event<'a, 'tcx: 'a> {
    Block(mir::BasicBlock),
    Return,
    Call,
    Constant,
    Assignment(&'a mir::Statement<'tcx>),
    Terminator(&'a mir::Terminator<'tcx>),
    Done,
}

pub struct Stepper<'fncx, 'a: 'fncx, 'b: 'a + 'mir, 'mir: 'fncx, 'tcx: 'b>{
    fncx: &'fncx mut FnEvalContext<'a, 'b, 'mir, 'tcx>,

    // a cache of the constants to be computed before the next statement/terminator
    // this is an optimization, so we don't have to allocate a new vector for every statement
    constants: Vec<(ConstantId<'tcx>, Span, Pointer, CachedMir<'mir, 'tcx>)>,
}

impl<'fncx, 'a, 'b: 'a + 'mir, 'mir, 'tcx: 'b> Stepper<'fncx, 'a, 'b, 'mir, 'tcx> {
    pub(super) fn new(fncx: &'fncx mut FnEvalContext<'a, 'b, 'mir, 'tcx>) -> Self {
        Stepper {
            fncx: fncx,
            constants: Vec::new(),
        }
    }

    fn statement<F: for<'f> FnMut(Event<'f, 'tcx>)>(&mut self, mut f: F, stmt: &mir::Statement<'tcx>) -> EvalResult<()> {
        f(Event::Assignment(stmt));
        let mir::StatementKind::Assign(ref lvalue, ref rvalue) = stmt.kind;
        let result = self.fncx.eval_assignment(lvalue, rvalue);
        self.fncx.maybe_report(result)?;
        self.fncx.frame_mut().stmt += 1;
        Ok(())
    }

    fn terminator<F: for<'f> FnMut(Event<'f, 'tcx>)>(&mut self, mut f: F, terminator: &mir::Terminator<'tcx>) -> EvalResult<()> {
        // after a terminator we go to a new block
        self.fncx.frame_mut().stmt = 0;
        let term = {
            f(Event::Terminator(terminator));
            let result = self.fncx.eval_terminator(terminator);
            self.fncx.maybe_report(result)?
        };
        match term {
            TerminatorTarget::Block => f(Event::Block(self.fncx.frame().next_block)),
            TerminatorTarget::Return => {
                f(Event::Return);
                self.fncx.pop_stack_frame();
            },
            TerminatorTarget::Call => f(Event::Call),
        }
        Ok(())
    }

    // returns true as long as there are more things to do
    pub fn step<F: for<'f> FnMut(Event<'f, 'tcx>)>(&mut self, mut f: F) -> EvalResult<()> {
        if self.fncx.stack.is_empty() {
            f(Event::Done);
            return Ok(());
        }

        let block = self.fncx.frame().next_block;
        let stmt = self.fncx.frame().stmt;
        let mir = self.fncx.mir();
        let basic_block = mir.basic_block_data(block);

        if let Some(ref stmt) = basic_block.statements.get(stmt) {
            assert!(self.constants.is_empty());
            ConstantExtractor {
                span: stmt.span,
                substs: self.fncx.substs(),
                def_id: self.fncx.frame().def_id,
                gecx: self.fncx.gecx,
                constants: &mut self.constants,
                mir: &mir,
            }.visit_statement(block, stmt);
            if self.constants.is_empty() {
                return self.statement(f, stmt);
            } else {
                return self.extract_constants(f);
            }
        }

        let terminator = basic_block.terminator();
        assert!(self.constants.is_empty());
        ConstantExtractor {
            span: terminator.span,
            substs: self.fncx.substs(),
            def_id: self.fncx.frame().def_id,
            gecx: self.fncx.gecx,
            constants: &mut self.constants,
            mir: &mir,
        }.visit_terminator(block, terminator);
        if self.constants.is_empty() {
            self.terminator(f, terminator)
        } else {
            self.extract_constants(f)
        }
    }

    fn extract_constants<F: for<'f> FnMut(Event<'f, 'tcx>)>(&mut self, mut f: F) -> EvalResult<()> {
        assert!(!self.constants.is_empty());
        for (cid, span, return_ptr, mir) in self.constants.drain(..) {
            f(Event::Constant);
            self.fncx.push_stack_frame(cid.def_id, span, mir, cid.substs, Some(return_ptr));
        }
        self.step(f)
    }
}

struct ConstantExtractor<'a, 'b: 'mir, 'mir: 'a, 'tcx: 'b> {
    span: Span,
    // FIXME: directly push the new stackframes instead of doing this intermediate caching
    constants: &'a mut Vec<(ConstantId<'tcx>, Span, Pointer, CachedMir<'mir, 'tcx>)>,
    gecx: &'a mut GlobalEvalContext<'b, 'tcx>,
    mir: &'a mir::Mir<'tcx>,
    def_id: DefId,
    substs: &'tcx subst::Substs<'tcx>,
}

impl<'a, 'b, 'mir, 'tcx> ConstantExtractor<'a, 'b, 'mir, 'tcx> {
    fn static_item(&mut self, def_id: DefId, substs: &'tcx subst::Substs<'tcx>, span: Span) {
        let cid = ConstantId {
            def_id: def_id,
            substs: substs,
            kind: ConstantKind::Global,
        };
        if self.gecx.statics.contains_key(&cid) {
            return;
        }
        let mir = self.gecx.load_mir(def_id);
        let ptr = self.gecx.alloc_ret_ptr(mir.return_ty, substs).expect("there's no such thing as an unreachable static");
        self.gecx.statics.insert(cid.clone(), ptr);
        self.constants.push((cid, span, ptr, mir));
    }
}

impl<'a, 'b, 'mir, 'tcx> Visitor<'tcx> for ConstantExtractor<'a, 'b, 'mir, 'tcx> {
    fn visit_constant(&mut self, constant: &mir::Constant<'tcx>) {
        self.super_constant(constant);
        match constant.literal {
            // already computed by rustc
            mir::Literal::Value { .. } => {}
            mir::Literal::Item { def_id, substs } => {
                let item_ty = self.gecx.tcx.lookup_item_type(def_id).subst(self.gecx.tcx, substs);
                if item_ty.ty.is_fn() {
                    // unimplemented
                } else {
                    self.static_item(def_id, substs, constant.span);
                }
            },
            mir::Literal::Promoted { index } => {
                let cid = ConstantId {
                    def_id: self.def_id,
                    substs: self.substs,
                    kind: ConstantKind::Promoted(index),
                };
                if self.gecx.statics.contains_key(&cid) {
                    return;
                }
                let mir = self.mir.promoted[index].clone();
                let return_ty = mir.return_ty;
                let return_ptr = self.gecx.alloc_ret_ptr(return_ty, cid.substs).expect("there's no such thing as an unreachable static");
                let mir = CachedMir::Owned(Rc::new(mir));
                self.gecx.statics.insert(cid.clone(), return_ptr);
                self.constants.push((cid, constant.span, return_ptr, mir));
            }
        }
    }

    fn visit_lvalue(&mut self, lvalue: &mir::Lvalue<'tcx>, context: LvalueContext) {
        self.super_lvalue(lvalue, context);
        if let mir::Lvalue::Static(def_id) = *lvalue {
            let substs = self.gecx.tcx.mk_substs(subst::Substs::empty());
            let span = self.span;
            self.static_item(def_id, substs, span);
        }
    }
}
<|endoftext|>


<commit_before>use std::fmt::{Debug, Formatter, Error};

extern crate log;
use log::{LogRecord, LogLevel, LogLevelFilter, LogMetadata, SetLoggerError};

pub use cli::CliConfig;
pub use configuration::Configuration as Cfg;

use storage::Store;

pub struct ImagLogger {
    lvl: LogLevel,
}

impl ImagLogger {

    pub fn new(lvl: LogLevel) -> ImagLogger {
        ImagLogger {
            lvl: lvl,
        }
    }

    pub fn init(cfg: &Cfg, config: &CliConfig) -> Result<(), SetLoggerError> {
        let lvl = if config.is_debugging() || cfg.is_debugging() {
            LogLevelFilter::Debug
        } else if config.is_verbose() || cfg.is_debugging() {
            LogLevelFilter::Info
        } else {
            LogLevelFilter::Error
        };

        log::set_logger(|max_log_lvl| {
            max_log_lvl.set(lvl);
            debug!("Init logger with: {}", lvl);
            Box::new(ImagLogger::new(lvl.to_log_level().unwrap()))
        })
    }

}

impl log::Log for ImagLogger {

    fn enabled(&self, metadata: &LogMetadata) -> bool {
        metadata.level() <= self.lvl
    }

    fn log(&self, record: &LogRecord) {
        if self.enabled(record.metadata()) {
            println!("[{}]: {}", record.level(), record.args());
        }
    }
}

pub struct Runtime<'a> {
    pub config : CliConfig<'a>,
    pub configuration : Cfg,
    pub store : Store,
}

impl<'a> Runtime<'a> {

    pub fn new(cfg: Cfg, config : CliConfig<'a>) -> Runtime<'a> {
        let sp = config.store_path().unwrap_or(cfg.store_path());
        Runtime {
            config: config,
            configuration: cfg,
            store: Store::new(sp),
        }
    }

    pub fn is_verbose(&self) -> bool {
        self.config.is_verbose() || self.configuration.is_verbose()
    }

    pub fn is_debugging(&self) -> bool {
        self.config.is_debugging() || self.configuration.is_verbose()
    }

    pub fn store_path(&self) -> String {
        self.config.store_path().unwrap_or(self.configuration.store_path())
    }

    pub fn store(&self) -> &Store {
        &self.store
    }

    pub fn get_rtp(&self) -> String {
        if let Some(rtp) = self.config.get_rtp() {
            rtp
        } else {
            self.configuration.get_rtp()
        }
    }

}

impl<'a> Debug for Runtime<'a> {

    fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
        write!(f, "Runtime (verbose: {}, debugging: {}, rtp: {})",
            self.is_verbose(),
            self.is_debugging(),
            self.get_rtp())
    }

}

<commit_msg>runtime.rs: Add possibility to fetch editor<commit_after>use std::fmt::{Debug, Formatter, Error};

extern crate log;
use log::{LogRecord, LogLevel, LogLevelFilter, LogMetadata, SetLoggerError};

pub use cli::CliConfig;
pub use configuration::Configuration as Cfg;

use storage::Store;

pub struct ImagLogger {
    lvl: LogLevel,
}

impl ImagLogger {

    pub fn new(lvl: LogLevel) -> ImagLogger {
        ImagLogger {
            lvl: lvl,
        }
    }

    pub fn init(cfg: &Cfg, config: &CliConfig) -> Result<(), SetLoggerError> {
        let lvl = if config.is_debugging() || cfg.is_debugging() {
            LogLevelFilter::Debug
        } else if config.is_verbose() || cfg.is_debugging() {
            LogLevelFilter::Info
        } else {
            LogLevelFilter::Error
        };

        log::set_logger(|max_log_lvl| {
            max_log_lvl.set(lvl);
            debug!("Init logger with: {}", lvl);
            Box::new(ImagLogger::new(lvl.to_log_level().unwrap()))
        })
    }

}

impl log::Log for ImagLogger {

    fn enabled(&self, metadata: &LogMetadata) -> bool {
        metadata.level() <= self.lvl
    }

    fn log(&self, record: &LogRecord) {
        if self.enabled(record.metadata()) {
            println!("[{}]: {}", record.level(), record.args());
        }
    }
}

pub struct Runtime<'a> {
    pub config : CliConfig<'a>,
    pub configuration : Cfg,
    pub store : Store,
}

impl<'a> Runtime<'a> {

    pub fn new(cfg: Cfg, config : CliConfig<'a>) -> Runtime<'a> {
        let sp = config.store_path().unwrap_or(cfg.store_path());
        Runtime {
            config: config,
            configuration: cfg,
            store: Store::new(sp),
        }
    }

    pub fn is_verbose(&self) -> bool {
        self.config.is_verbose() || self.configuration.is_verbose()
    }

    pub fn is_debugging(&self) -> bool {
        self.config.is_debugging() || self.configuration.is_verbose()
    }

    pub fn store_path(&self) -> String {
        self.config.store_path().unwrap_or(self.configuration.store_path())
    }

    pub fn store(&self) -> &Store {
        &self.store
    }

    pub fn get_rtp(&self) -> String {
        if let Some(rtp) = self.config.get_rtp() {
            rtp
        } else {
            self.configuration.get_rtp()
        }
    }

    pub fn editor(&self) -> String {
        use std::env::var;

        if let Some(editor) = self.config.editor() {
            editor
        } else if let Some(editor) = self.configuration.editor() {
            editor
        } else if let Ok(editor) = var("EDITOR") {
            editor
        } else {
            String::from("vim")
        }
    }

}

impl<'a> Debug for Runtime<'a> {

    fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
        write!(f, "Runtime (verbose: {}, debugging: {}, rtp: {})",
            self.is_verbose(),
            self.is_debugging(),
            self.get_rtp())
    }

}

<|endoftext|>


<commit_before><commit_msg>Prevent early service termination when not blocking for OS signal<commit_after><|endoftext|>


<commit_before><commit_msg>fix test ?<commit_after><|endoftext|>


<commit_before><commit_msg>Add crypto coin ticker lookup functionality<commit_after>use std::io::Read;

use serde_json;
use reqwest;
use reqwest::Method;
use regex::Regex;

use ::bot::{Bot, Node, RoomEvent};

pub struct CryptoCoin {
}

impl CryptoCoin {
    pub fn new() -> Self {
        Self {
        }
    }
}

impl<'a> Node<'a> for CryptoCoin {
    fn handle(&mut self, bot: &Bot, event: RoomEvent) {
        let revent = &event.raw_event;

        if revent.type_ == "m.room.message" && revent.content["msgtype"] == "m.text" {
            let body = &revent.content["body"].as_str().unwrap();

            let re = Regex::new(r"^p +([A-Za-z]{2,4}) *$").unwrap();

            if let Some(m) = re.captures(body) {
                let ticker = m.get(1).unwrap().as_str().to_uppercase();
                bot.reply(&event, &price_string(&ticker));
            }
        }
    }
}

fn price_string(sym: &str) -> String {
    let spot_price = price(sym, PriceType::Spot);
    if spot_price < 0.0 {
        format!("Could not fetch market data for: {}", sym)
    } else {
        let bid_price = price(sym, PriceType::Bid);
        let ask_price = price(sym, PriceType::Ask);

        format!("{} - Spot: ${}, Bid/Ask: ${}/{}",
                sym, spot_price, bid_price, ask_price)
    }
}

fn price(sym: &str, price_type: PriceType) -> f32 {
    let url = format!("https://api.coinbase.com/v2/prices/{}-USD/{}",
                      sym, price_type.value());

    let client = reqwest::Client::new().unwrap();
    match client.request(Method::Get, &url).unwrap().send() {
        Ok(mut resp) => {
            let mut content = String::new();
            resp.read_to_string(&mut content).unwrap();
            match serde_json::from_str::<CBResponse>(&content) {
                Ok(v) => {
                    v.data.amount.parse().unwrap()
                },
                Err(_) => -1.0
            }
        },
        Err(_) => -1.0
    }
}

#[allow(dead_code)]
enum PriceType {
    Spot,
    Bid,
    Ask,
}

impl PriceType {
    fn value(&self) -> &str {
        match *self {
            PriceType::Spot => "spot",
            PriceType::Bid  => "sell",
            PriceType::Ask  => "buy",
        }
    }
}

// These types are used for deserializing the Coin Base API

#[derive(Serialize, Deserialize, Debug)]
struct CBResponse {
    data: Data,
}

#[derive(Serialize, Deserialize, Debug)]
struct Data {
    amount: String,
    currency: String,
}
<|endoftext|>


<commit_before><commit_msg>Basic create_file.rs<commit_after>// Implements http://rosettacode.org/wiki/Create_a_file

use std::io::File;

fn main () {
  // Create a new file.
  let mut new_file = File::create(&Path::new("output.txt")).unwrap();
  // Write something trivial to it.
  new_file.write(bytes!("Nothing here..."))
}
<|endoftext|>


<commit_before><commit_msg>add codegen test<commit_after>// compile-flags: -O
// min-llvm-version: 11.0
#![crate_type = "lib"]

// Ensure that trivial casts of vec elements are O(1)

// CHECK-LABEL: @vec_iterator_cast
#[no_mangle]
pub fn vec_iterator_cast(vec: Vec<isize>) -> Vec<usize> {
    // CHECK-NOT: loop
    // CHECK-NOT: call
    vec.into_iter().map(|e| e as usize).collect()
}
<|endoftext|>


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

// ignore-android: FIXME(#10381)

// compile-flags:-g

// No debugger interaction required: just make sure it compiles without
// crashing.

fn test(a: &Vec<u8>) {
  print!("{}", a.len());
}

pub fn main() {
  let data = vec!();
  test(&data);
}
<|endoftext|>


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

// aux-build:issue-31702-1.rs
// aux-build:issue-31702-2.rs

// this test is actually entirely in the linked library crates

extern crate issue_31702_1;
extern crate issue_31702_2;

fn main() {}
<commit_msg>Auto merge of #31771 - alexcrichton:oops-that-didnt-fix-anything, r=brson<commit_after>// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// aux-build:issue-31702-1.rs
// aux-build:issue-31702-2.rs
// ignore-test: FIXME(#31702) when this test was added it was thought that the
//                            accompanying llvm update would fix it, but
//                            unfortunately it appears that was not the case. In
//                            the interest of not deleting the test, though,
//                            this is just tagged with ignore-test

// this test is actually entirely in the linked library crates

extern crate issue_31702_1;
extern crate issue_31702_2;

fn main() {}
<|endoftext|>


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

use LinkerFlavor;
use target::{LinkArgs, TargetOptions, RelroLevel};
use std::default::Default;

pub fn opts() -> TargetOptions {
    let mut args = LinkArgs::new();
    args.insert(LinkerFlavor::Gcc, vec![
        "-Wl,-Bstatic".to_string(),
        "-Wl,--no-dynamic-linker".to_string(),
        "-Wl,--eh-frame-hdr".to_string(),
        "-Wl,--gc-sections".to_string(),
    ]);

    TargetOptions {
        executables: true,
        target_family: Some("unix".to_string()),
        linker_is_gnu: true,
        pre_link_args: args,
        position_independent_executables: true,
        relro_level: RelroLevel::Full,
        exe_allocation_crate: super::maybe_jemalloc(),
        .. Default::default()
    }
}
<commit_msg>Auto merge of #47089 - EdSchouten:cloudabi-is-not-unix, r=kennytm<commit_after>// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use LinkerFlavor;
use target::{LinkArgs, TargetOptions, RelroLevel};
use std::default::Default;

pub fn opts() -> TargetOptions {
    let mut args = LinkArgs::new();
    args.insert(LinkerFlavor::Gcc, vec![
        "-Wl,-Bstatic".to_string(),
        "-Wl,--no-dynamic-linker".to_string(),
        "-Wl,--eh-frame-hdr".to_string(),
        "-Wl,--gc-sections".to_string(),
    ]);

    TargetOptions {
        executables: true,
        target_family: None,
        linker_is_gnu: true,
        pre_link_args: args,
        position_independent_executables: true,
        relro_level: RelroLevel::Full,
        exe_allocation_crate: super::maybe_jemalloc(),
        .. Default::default()
    }
}
<|endoftext|>


<commit_before><commit_msg>xc2bit: Start writing a bitstream dump program<commit_after>/*
Copyright (c) 2016-2017, Robert Ou <rqou@robertou.com> and contributors
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

1. Redistributions of source code must retain the above copyright notice,
   this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
   this list of conditions and the following disclaimer in the documentation
   and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

use std::fs::File;
use std::io::Read;

extern crate xc2bit;
use xc2bit::*;

fn main() {
    let args = ::std::env::args().collect::<Vec<_>>();

    if args.len() != 2 {
        println!("Usage: {} file.jed", args[0]);
        ::std::process::exit(1);
    }

    // Read the entire file
    let mut f = File::open(&args[1]).expect("failed to open file");
    let mut data = Vec::new();
    f.read_to_end(&mut data).expect("failed to read data");

    let bits_result = read_jed(&data);
    let (bits, device_name_option) = bits_result.expect("failed to read jed");
    let device_name = device_name_option.expect("missing device name in jed");

    let bitstream_result = process_jed(&bits, &device_name);
    let bitstream = bitstream_result.expect("failed to process jed");
}
<|endoftext|>


<commit_before><commit_msg>Add missing file interpreter.rs<commit_after>use std::collections::HashMap;
use std::fmt;
use itertools::free::join;
use bytecode::*;
use parser::Operator;

#[derive(Debug)]
pub struct ExecutionError(pub String);

#[derive(Debug, Clone)]
pub enum Value
{
    Uninitialized,
    Void,
    Int(i64),
    UInt(u64),
    Float(f64),
    Char(char),
    Bool(bool),
    Array(Vec<Value>),
    Func(String),
    Struct(Vec<Value>),
    Sum(usize, Box<Value>),
    Enum(usize),
}

impl fmt::Display for Value
{
    fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error>
    {
        match *self
        {
            Value::Uninitialized => write!(f, "uninitialized"),
            Value::Void => write!(f, "void"),
            Value::Int(v) => write!(f, "int {}", v),
            Value::UInt(v) => write!(f, "uint {}", v),
            Value::Float(v) => write!(f, "float {}", v),
            Value::Char(v) => write!(f, "char {}", v),
            Value::Bool(v) => write!(f, "bool {}", v),
            Value::Array(ref v) => write!(f, "[{}]", join(v.iter(), ", ")),
            Value::Func(ref v) => write!(f, "func {}", v),
            Value::Struct(ref v) => write!(f, "{{{}}}", join(v.iter(), ", ")),
            Value::Sum(idx, ref v) => write!(f, "sum {} {}", idx, v),
            Value::Enum(idx) => write!(f, "enum {}", idx),
        }
    }
}

impl Value
{
    pub fn to_exit_code(&self) -> i32
    {
        match *self
        {
            Value::Int(v) => v as i32,
            Value::Bool(v) => if v == true {0i32} else {1i32},
            _ => 1i32,
        }
    }
}

struct StackFrame
{
    vars: HashMap<String, Value>,
    result: Value,
}

impl StackFrame
{
    pub fn new() -> StackFrame
    {
        StackFrame{
            vars: HashMap::new(),
            result: Value::Void,
        }
    }
}

struct Interpreter<'a>
{
    module: &'a ByteCodeModule,
    stack: Vec<StackFrame>,
}

enum Action
{
    Continue,
    Jump(BasicBlockRef),
    Return,
}

impl<'a> Interpreter<'a>
{
    pub fn new(module: &ByteCodeModule) -> Interpreter
    {
        Interpreter{
            module: module,
            stack: Vec::new(),
        }
    }

    fn add_variable(&mut self, name: &str, v: Value) -> Result<(), ExecutionError>
    {
        let mut sf = self.stack.last_mut().expect("Empty stack");
        if sf.vars.get(name).is_none() {
            Err(ExecutionError(format!("Variable {} already exists", name)))
        } else {
            sf.vars.insert(name.into(), v);
            Ok(())
        }
    }

    fn get_variable(&self, name: &str) -> Result<&Value, ExecutionError>
    {
        for sf in self.stack.iter().rev() {
            if let Some(ref v) = sf.vars.get(name) {
                return Ok(v);
            }
        }

        Err(ExecutionError(format!("Unknown variable {}", name)))
    }

    fn update_variable(&mut self, name: &str, new_value: Value) -> Result<(), ExecutionError>
    {
        for sf in self.stack.iter_mut().rev() {
            if let Some(v) = sf.vars.get_mut(name) {
                *v = new_value;
                return Ok(())
            }
        }

        Err(ExecutionError(format!("Unknown variable {}", name)))
    }

    fn make_value(&self, lit: &ByteCodeLiteral) -> Result<Value, ExecutionError>
    {
        match lit
        {
            &ByteCodeLiteral::Int(v) => Ok(Value::UInt(v)),
            &ByteCodeLiteral::Float(ref num) => {
                match num.parse::<f64>()
                {
                    Ok(f) => Ok(Value::Float(f)),
                    Err(_) => Err(ExecutionError(format!("{} is not a valid floating point number", num))),
                }
            },
            &ByteCodeLiteral::Char(v) => Ok(Value::Char(v as char)),
            &ByteCodeLiteral::String(ref s) => Ok(Value::Array(s.chars().map(|c| Value::Char(c)).collect())),
            &ByteCodeLiteral::Bool(v) => Ok(Value::Bool(v)),
            &ByteCodeLiteral::Array(ref members) => {
                let mut vars = Vec::new();
                for var in members {
                    vars.push(self.get_variable(&var.name)?.clone());
                }
                Ok(Value::Array(vars))
            },
        }
    }

    fn unary_op(&self, op: Operator, var: &str) -> Result<Value, ExecutionError>
    {
        panic!("NYI");
    }

    fn binary_op(&self, op: Operator, left: &str, right: &str) -> Result<Value, ExecutionError>
    {
        panic!("NYI");
    }

    fn call(&self, name: &str, args: &Vec<Var>) -> Result<Value, ExecutionError>
    {
        panic!("NYI");
    }

    fn set(&mut self, name: &str, expr: &ByteCodeExpression) -> Result<(), ExecutionError>
    {
        let value = match *expr
        {
            ByteCodeExpression::Literal(ref l) => self.make_value(l)?,
            ByteCodeExpression::UnaryOp(op, ref v) => self.unary_op(op, &v.name)?,
            ByteCodeExpression::BinaryOp(op, ref a, ref b) => self.binary_op(op, &a.name, &b.name)?,
            ByteCodeExpression::Call(ref name, ref args) => self.call(name, args)?,
            ByteCodeExpression::StructMember(ref obj, index) => panic!("NYI"),
            ByteCodeExpression::SumTypeIndex(ref obj) => panic!("NYI"),
            ByteCodeExpression::SumTypeStruct(ref obj, index) => panic!("NYI"),
            ByteCodeExpression::SumTypeCase(index) => panic!("NYI"),
            ByteCodeExpression::ArrayProperty(ref array, ref property) => panic!("NYI"),
            ByteCodeExpression::ArrayHead(ref array) => panic!("NYI"),
            ByteCodeExpression::ArrayTail(ref array) => panic!("NYI"),
            ByteCodeExpression::Ref(ref obj) => panic!("NYI"),
            ByteCodeExpression::Func(ref func) => panic!("NYI"),
            ByteCodeExpression::HeapAlloc(ref typ) => panic!("NYI"),
        };

        self.update_variable(name, value)
    }

    fn ret(&mut self, name: &str) -> Result<Action, ExecutionError>
    {
        let val = self.get_variable(name)?.clone();
        let mut sf = self.stack.last_mut().expect("Empty stack");
        sf.result = val;
        Ok(Action::Return)
    }

    fn branch_if(&self, var: &str, on_true: BasicBlockRef, on_false: BasicBlockRef) ->  Result<Action, ExecutionError>
    {
        let val = self.get_variable(var)?;
        match val
        {
            &Value::Bool(true) => Ok(Action::Jump(on_true)),
            &Value::Bool(false) => Ok(Action::Jump(on_false)),
            _ => Err(ExecutionError(format!("brif operand {} is not a boolean", var))),
        }
    }

    fn execute_instruction(&mut self, current_bb: BasicBlockRef, instr: &Instruction) -> Result<Action, ExecutionError>
    {
        println!("{}", instr);
        match *instr
        {
            Instruction::Alloc(ref var) => {
                self.add_variable(&var.name, Value::Uninitialized)?;
                Ok(Action::Continue)
            },
            Instruction::SetStructMember{ref obj, member_index, ref value} => {
                panic!("NYI");
            },
            Instruction::StartScope => {
                self.stack.push(StackFrame::new());
                Ok(Action::Continue)
            },
            Instruction::EndScope => {
                self.stack.pop();
                Ok(Action::Continue)
            },
            Instruction::Bind{ref name, ref var} => {
                panic!("NYI");
            },
            Instruction::Set{ref var, ref expr} => {
                self.set(&var.name, expr)?;
                Ok(Action::Continue)
            },
            Instruction::Return(ref var) => {
                self.ret(&var.name)
            },
            Instruction::ReturnVoid => {
                Ok(Action::Return)
            },
            Instruction::Branch(bb) => {
                Ok(Action::Jump(bb))
            },
            Instruction::BranchIf{ref cond, on_true, on_false} => {
                self.branch_if(&cond.name, on_true, on_false)
            },
            Instruction::IncRef(ref v) => {
                panic!("NYI");
            },
            Instruction::DecRef(ref v) => {
                panic!("NYI");
            },
        }
    }

    fn run_bb(&mut self, func: &ByteCodeFunction, bb_ref: BasicBlockRef) -> Result<Action, ExecutionError>
    {
        if let Some(ref bb) = func.blocks.get(&bb_ref) {
            for inst in &bb.instructions {
                let action = self.execute_instruction(bb_ref, inst)?;
                if let Action::Continue = action {
                    continue;
                } else {
                    return Ok(action);
                }
            }

            Ok(Action::Continue)
        } else {
            Err(ExecutionError(format!("Cannot execute basic block {} of function {}", bb_ref, func.sig.name)))
        }
    }

    fn run(&mut self, func: &ByteCodeFunction, args: Vec<(String, Value)>) -> Result<Value, ExecutionError>
    {
        println!("{}:", func.sig.name);
        self.stack.push(StackFrame::new());
        for (name, val) in args {
            self.add_variable(&name, val)?;
        }

        let mut bb_ref = 0;
        loop {
            match self.run_bb(func, bb_ref)?
            {
                Action::Continue => {bb_ref += 1;},
                Action::Jump(bb) => {bb_ref = bb},
                Action::Return => break,
            }
        }

        let sf = self.stack.pop().expect("Empty stack");
        Ok(sf.result)
    }

    pub fn run_function(&mut self, function: &str, args: Vec<(String, Value)>) -> Result<Value, ExecutionError>
    {
        match self.module.functions.iter().find(|func| func.sig.name == function)
        {
            Some(ref func) => {
                self.run(func, args)
            },

            None => {
                Err(ExecutionError(format!("Unknown function {}", function)))
            }
        }
    }
}

pub fn run_byte_code(module: &ByteCodeModule, function: &str) -> Result<Value, ExecutionError>
{
    let mut interpreter = Interpreter::new(module);
    interpreter.run_function(function, vec![])
}
<|endoftext|>


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

#[repr(C)]
enum CEnum {
    Hello = 30,
    World = 60
}

fn test1(c: CEnum) -> i32 {
  let c2 = CEnum::Hello;
  match (c, c2) {
    (CEnum::Hello, CEnum::Hello) => 42,
    (CEnum::World, CEnum::Hello) => 0,
    _ => 1
  }
}

#[repr(packed)]
#[derive(PartialEq, Debug)]
struct Pakd {
    a: u64,
    b: u32,
    c: u16,
    d: u8,
    e: ()
}

impl Drop for Pakd {
    fn drop(&mut self) {}
}

fn test2() -> Pakd {
    Pakd { a: 42, b: 42, c: 42, d: 42, e: () }
}

#[derive(PartialEq, Debug)]
struct TupleLike(u64, u32);

fn test3() -> TupleLike {
    TupleLike(42, 42)
}

fn test4(x: fn(u64, u32) -> TupleLike) -> (TupleLike, TupleLike) {
    let y = TupleLike;
    (x(42, 84), y(42, 84))
}

fn test5(x: fn(u32) -> Option<u32>) -> (Option<u32>, Option<u32>) {
    let y = Some;
    (x(42), y(42))
}

fn main() {
  assert_eq!(test1(CEnum::Hello), 42);
  assert_eq!(test1(CEnum::World), 0);
  assert_eq!(test2(), Pakd { a: 42, b: 42, c: 42, d: 42, e: () });
  assert_eq!(test3(), TupleLike(42, 42));
  let t4 = test4(TupleLike);
  assert_eq!(t4.0, t4.1);
  let t5 = test5(Some);
  assert_eq!(t5.0, t5.1);
}
<commit_msg>Avoid unsafe unaligned loads in test.<commit_after>// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use std::fmt;

#[repr(C)]
enum CEnum {
    Hello = 30,
    World = 60
}

fn test1(c: CEnum) -> i32 {
  let c2 = CEnum::Hello;
  match (c, c2) {
    (CEnum::Hello, CEnum::Hello) => 42,
    (CEnum::World, CEnum::Hello) => 0,
    _ => 1
  }
}

#[repr(packed)]
struct Pakd {
    a: u64,
    b: u32,
    c: u16,
    d: u8,
    e: ()
}

// It is unsafe to use #[derive(Debug)] on a packed struct because the code generated by the derive
// macro takes references to the fields instead of accessing them directly.
impl fmt::Debug for Pakd {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        // It's important that we load the fields into locals by-value here. This will do safe
        // unaligned loads into the locals, then pass references to the properly-aligned locals to
        // the formatting code.
        let Pakd { a, b, c, d, e } = *self;
        f.debug_struct("Pakd")
            .field("a", &a)
            .field("b", &b)
            .field("c", &c)
            .field("d", &d)
            .field("e", &e)
            .finish()
    }
}

// It is unsafe to use #[derive(PartialEq)] on a packed struct because the code generated by the
// derive macro takes references to the fields instead of accessing them directly.
impl PartialEq for Pakd {
    fn eq(&self, other: &Pakd) -> bool {
        self.a == other.a &&
            self.b == other.b &&
            self.c == other.c &&
            self.d == other.d &&
            self.e == other.e
    }
}

impl Drop for Pakd {
    fn drop(&mut self) {}
}

fn test2() -> Pakd {
    Pakd { a: 42, b: 42, c: 42, d: 42, e: () }
}

#[derive(PartialEq, Debug)]
struct TupleLike(u64, u32);

fn test3() -> TupleLike {
    TupleLike(42, 42)
}

fn test4(x: fn(u64, u32) -> TupleLike) -> (TupleLike, TupleLike) {
    let y = TupleLike;
    (x(42, 84), y(42, 84))
}

fn test5(x: fn(u32) -> Option<u32>) -> (Option<u32>, Option<u32>) {
    let y = Some;
    (x(42), y(42))
}

fn main() {
  assert_eq!(test1(CEnum::Hello), 42);
  assert_eq!(test1(CEnum::World), 0);
  assert_eq!(test2(), Pakd { a: 42, b: 42, c: 42, d: 42, e: () });
  assert_eq!(test3(), TupleLike(42, 42));
  let t4 = test4(TupleLike);
  assert_eq!(t4.0, t4.1);
  let t5 = test5(Some);
  assert_eq!(t5.0, t5.1);
}
<|endoftext|>


<commit_before>///! Basic CSS block layout.

use style::{StyledNode, Inline, Block, DisplayNone};
use css::{Keyword, Length, Px};
use std::default::Default;
use std::iter::AdditiveIterator; // for `sum`

// CSS box model. All sizes are in px.

#[deriving(Default, Show)]
pub struct Dimensions {
    // Top left corner of the content area, relative to the document origin:
    pub x: f32,
    pub y: f32,

    // Content area size:
    pub width: f32,
    pub height: f32,

    // Surrounding edges:
    pub padding: EdgeSizes,
    pub border: EdgeSizes,
    pub margin: EdgeSizes,
}

#[deriving(Default, Show)]
pub struct EdgeSizes {
    pub left: f32,
    pub right: f32,
    pub top: f32,
    pub bottom: f32,
}

/// A node in the layout tree.
pub struct LayoutBox<'a> {
    pub dimensions: Dimensions,
    pub box_type: BoxType<'a>,
    pub children: Vec<LayoutBox<'a>>,
}

pub enum BoxType<'a> {
    BlockNode(&'a StyledNode<'a>),
    InlineNode(&'a StyledNode<'a>),
    AnonymousBlock,
}

impl<'a> LayoutBox<'a> {
    fn new(box_type: BoxType) -> LayoutBox {
        LayoutBox {
            box_type: box_type,
            dimensions: Default::default(),
            children: Vec::new(),
        }
    }

    fn get_style_node(&self) -> &'a StyledNode<'a> {
        match self.box_type {
            BlockNode(node) => node,
            InlineNode(node) => node,
            AnonymousBlock => fail!("Anonymous block box has no style node")
        }
    }
}

/// Transform a style tree into a layout tree.
pub fn layout_tree<'a>(node: &'a StyledNode<'a>, containing_block: Dimensions) -> LayoutBox<'a> {
    let mut root_box = build_layout_tree(node);
    root_box.layout(containing_block);
    return root_box;
}

/// Build the tree of LayoutBoxes, but don't perform any layout calculations yet.
fn build_layout_tree<'a>(style_node: &'a StyledNode<'a>) -> LayoutBox<'a> {
    // Create the root box.
    let mut root = LayoutBox::new(match style_node.display() {
        Block => BlockNode(style_node),
        Inline => InlineNode(style_node),
        DisplayNone => fail!("Root node has display: none.")
    });

    // Create the descendant boxes.
    for child in style_node.children.iter() {
        match child.display() {
            Block => root.children.push(build_layout_tree(child)),
            Inline => root.get_inline_container().children.push(build_layout_tree(child)),
            DisplayNone => {} // Don't lay out nodes with `display: none;`
        }
    }
    return root;
}

impl<'a> LayoutBox<'a> {
    /// Lay out a box and its descendants.
    fn layout(&mut self, containing_block: Dimensions) {
        match self.box_type {
            BlockNode(_) => self.layout_block(containing_block),
            InlineNode(_) => {} // TODO
            AnonymousBlock => {} // TODO
        }
    }

    /// Lay out a block-level element and its descendants.
    fn layout_block(&mut self, containing_block: Dimensions) {
        // Child width can depend on parent width, so we need to calculate this node's width before
        // laying out its children.
        self.calculate_block_width(containing_block);

        // Determine where the block is located within its container.
        self.calculate_block_position(containing_block);

        // Recursively lay out the children of this node within its content area.
        self.layout_block_children();

        // Parent height can depend on child height, so `calculate_height` must be called after the
        // content layout is finished.
        self.calculate_block_height();
    }

    /// Calculate the width of a block-level non-replaced element in normal flow.
    ///
    /// http://www.w3.org/TR/CSS2/visudet.html#blockwidth
    ///
    /// Sets the horizontal margin/padding/border dimensions, and the `width`.
    fn calculate_block_width(&mut self, containing_block: Dimensions) {
        let style = self.get_style_node();

        // `width` has initial value `auto`.
        let auto = Keyword("auto".to_string());
        let mut width = style.value("width").unwrap_or(auto.clone());

        // margin, border, and padding have initial value 0.
        let zero = Length(0.0, Px);

        let mut margin_left = style.lookup("margin-left", "margin", &zero);
        let mut margin_right = style.lookup("margin-right", "margin", &zero);

        let border_left = style.lookup("border-left-width", "border-width", &zero);
        let border_right = style.lookup("border-right-width", "border-width", &zero);

        let padding_left = style.lookup("padding-left", "padding", &zero);
        let padding_right = style.lookup("padding-right", "padding", &zero);

        let total = [&margin_left, &margin_right, &border_left, &border_right,
                     &padding_left, &padding_right, &width].iter().map(|v| v.to_px()).sum();

        // If width is not auto and the total is wider than the container, treat auto margins as 0.
        if width != auto && total > containing_block.width {
            if margin_left == auto {
                margin_left = Length(0.0, Px);
            }
            if margin_right == auto {
                margin_right = Length(0.0, Px);
            }
        }

        // Adjust used values so that the above sum equals `containing_block.width`.
        // Each arm of the `match` should increase the total width by exactly `underflow`,
        // and afterward all values should be absolute lengths in px.
        let underflow = containing_block.width - total;
        match (width == auto, margin_left == auto, margin_right == auto) {
            // If the values are overconstrained, calculate margin_right.
            (false, false, false) => {
                margin_right = Length(margin_right.to_px() + underflow, Px);
            }
            // If exactly one value is auto, its used value follows from the equality.
            (false, false, true) => {
                margin_right = Length(underflow, Px);
            }
            (false, true, false) => {
                margin_left = Length(underflow, Px);
            }
            // If width is set to auto, any other auto values become 0.
            (true, _, _) => {
                if margin_left == auto {
                    margin_left = Length(0.0, Px);
                }
                if margin_right == auto {
                    margin_right = Length(0.0, Px);
                }
                width = Length(underflow, Px);
            }
            // If margin-left and margin-right are both auto, their used values are equal.
            (false, true, true) => {
                margin_left = Length(underflow / 2.0, Px);
                margin_right = Length(underflow / 2.0, Px);
            }
        }

        let d = &mut self.dimensions;
        d.width = width.to_px();

        d.padding.left = padding_left.to_px();
        d.padding.right = padding_right.to_px();

        d.border.left = border_left.to_px();
        d.border.right = border_right.to_px();

        d.margin.left = margin_left.to_px();
        d.margin.right = margin_right.to_px();
    }

    /// Finish calculating the block's edge sizes, and position it within its containing block.
    ///
    /// http://www.w3.org/TR/CSS2/visudet.html#normal-block
    ///
    /// Sets the vertical margin/padding/border dimensions, and the `x`, `y` values.
    fn calculate_block_position(&mut self, containing_block: Dimensions) {
        let style = self.get_style_node();
        let d = &mut self.dimensions;

        // margin, border, and padding have initial value 0.
        let zero = Length(0.0, Px);

        // If margin-top or margin-bottom is `auto`, the used value is zero.
        d.margin.top = style.lookup("margin-top", "margin", &zero).to_px();
        d.margin.bottom = style.lookup("margin-bottom", "margin", &zero).to_px();

        d.border.top = style.lookup("border-top-width", "border-width", &zero).to_px();
        d.border.bottom = style.lookup("border-bottom-width", "border-width", &zero).to_px();

        d.padding.top = style.lookup("padding-top", "padding", &zero).to_px();
        d.padding.bottom = style.lookup("padding-bottom", "padding", &zero).to_px();

        // Position the box below all the previous boxes in the container.
        d.x = containing_block.x +
              d.margin.left + d.border.left + d.padding.left;
        d.y = containing_block.y + containing_block.height +
              d.margin.top + d.border.top + d.padding.top;
    }

    /// Lay out the node's children within its content area and return the content height.
    ///
    /// Set `height` to the total content height.
    fn layout_block_children(&mut self) {
        let d = &mut self.dimensions;
        for child in self.children.mut_iter() {
            child.layout(*d);
            // Increment the height so each child is laid out below the previous one.
            d.height = d.height + child.dimensions.margin_box_height();
        }
    }

    /// Height of a block-level non-replaced element in normal flow with overflow visible.
    fn calculate_block_height(&mut self) {
        // If the height is set to an explicit length, use that exact length.
        // Otherwise, just keep the value set by `layout_block_children`.
        match self.get_style_node().value("height") {
            Some(Length(h, Px)) => { self.dimensions.height = h; }
            _ => {}
        }
    }

    /// Where a new inline child should go.
    fn get_inline_container(&mut self) -> &mut LayoutBox<'a> {
        match self.box_type {
            InlineNode(_) | AnonymousBlock => self,
            BlockNode(_) => {
                // If we've just generated an anonymous block box, keep using it.
                // Otherwise, create a new one.
                match self.children.last() {
                    Some(&LayoutBox { box_type: AnonymousBlock,..}) => {}
                    _ => self.children.push(LayoutBox::new(AnonymousBlock))
                }
                self.children.mut_last().unwrap()
            }
        }
    }
}

impl Dimensions {
    /// Total height of a box including its margins, border, and padding.
    fn margin_box_height(&self) -> f32 {
        self.height + self.padding.top + self.padding.bottom
                    + self.border.top + self.border.bottom
                    + self.margin.top + self.margin.bottom
    }
}
<commit_msg>Negative width is illegal<commit_after>///! Basic CSS block layout.

use style::{StyledNode, Inline, Block, DisplayNone};
use css::{Keyword, Length, Px};
use std::default::Default;
use std::iter::AdditiveIterator; // for `sum`

// CSS box model. All sizes are in px.

#[deriving(Default, Show)]
pub struct Dimensions {
    // Top left corner of the content area, relative to the document origin:
    pub x: f32,
    pub y: f32,

    // Content area size:
    pub width: f32,
    pub height: f32,

    // Surrounding edges:
    pub padding: EdgeSizes,
    pub border: EdgeSizes,
    pub margin: EdgeSizes,
}

#[deriving(Default, Show)]
pub struct EdgeSizes {
    pub left: f32,
    pub right: f32,
    pub top: f32,
    pub bottom: f32,
}

/// A node in the layout tree.
pub struct LayoutBox<'a> {
    pub dimensions: Dimensions,
    pub box_type: BoxType<'a>,
    pub children: Vec<LayoutBox<'a>>,
}

pub enum BoxType<'a> {
    BlockNode(&'a StyledNode<'a>),
    InlineNode(&'a StyledNode<'a>),
    AnonymousBlock,
}

impl<'a> LayoutBox<'a> {
    fn new(box_type: BoxType) -> LayoutBox {
        LayoutBox {
            box_type: box_type,
            dimensions: Default::default(),
            children: Vec::new(),
        }
    }

    fn get_style_node(&self) -> &'a StyledNode<'a> {
        match self.box_type {
            BlockNode(node) => node,
            InlineNode(node) => node,
            AnonymousBlock => fail!("Anonymous block box has no style node")
        }
    }
}

/// Transform a style tree into a layout tree.
pub fn layout_tree<'a>(node: &'a StyledNode<'a>, containing_block: Dimensions) -> LayoutBox<'a> {
    let mut root_box = build_layout_tree(node);
    root_box.layout(containing_block);
    return root_box;
}

/// Build the tree of LayoutBoxes, but don't perform any layout calculations yet.
fn build_layout_tree<'a>(style_node: &'a StyledNode<'a>) -> LayoutBox<'a> {
    // Create the root box.
    let mut root = LayoutBox::new(match style_node.display() {
        Block => BlockNode(style_node),
        Inline => InlineNode(style_node),
        DisplayNone => fail!("Root node has display: none.")
    });

    // Create the descendant boxes.
    for child in style_node.children.iter() {
        match child.display() {
            Block => root.children.push(build_layout_tree(child)),
            Inline => root.get_inline_container().children.push(build_layout_tree(child)),
            DisplayNone => {} // Don't lay out nodes with `display: none;`
        }
    }
    return root;
}

impl<'a> LayoutBox<'a> {
    /// Lay out a box and its descendants.
    fn layout(&mut self, containing_block: Dimensions) {
        match self.box_type {
            BlockNode(_) => self.layout_block(containing_block),
            InlineNode(_) => {} // TODO
            AnonymousBlock => {} // TODO
        }
    }

    /// Lay out a block-level element and its descendants.
    fn layout_block(&mut self, containing_block: Dimensions) {
        // Child width can depend on parent width, so we need to calculate this node's width before
        // laying out its children.
        self.calculate_block_width(containing_block);

        // Determine where the block is located within its container.
        self.calculate_block_position(containing_block);

        // Recursively lay out the children of this node within its content area.
        self.layout_block_children();

        // Parent height can depend on child height, so `calculate_height` must be called after the
        // content layout is finished.
        self.calculate_block_height();
    }

    /// Calculate the width of a block-level non-replaced element in normal flow.
    ///
    /// http://www.w3.org/TR/CSS2/visudet.html#blockwidth
    ///
    /// Sets the horizontal margin/padding/border dimensions, and the `width`.
    fn calculate_block_width(&mut self, containing_block: Dimensions) {
        let style = self.get_style_node();

        // `width` has initial value `auto`.
        let auto = Keyword("auto".to_string());
        let mut width = style.value("width").unwrap_or(auto.clone());

        // margin, border, and padding have initial value 0.
        let zero = Length(0.0, Px);

        let mut margin_left = style.lookup("margin-left", "margin", &zero);
        let mut margin_right = style.lookup("margin-right", "margin", &zero);

        let border_left = style.lookup("border-left-width", "border-width", &zero);
        let border_right = style.lookup("border-right-width", "border-width", &zero);

        let padding_left = style.lookup("padding-left", "padding", &zero);
        let padding_right = style.lookup("padding-right", "padding", &zero);

        let total = [&margin_left, &margin_right, &border_left, &border_right,
                     &padding_left, &padding_right, &width].iter().map(|v| v.to_px()).sum();

        // If width is not auto and the total is wider than the container, treat auto margins as 0.
        if width != auto && total > containing_block.width {
            if margin_left == auto {
                margin_left = Length(0.0, Px);
            }
            if margin_right == auto {
                margin_right = Length(0.0, Px);
            }
        }

        // Adjust used values so that the above sum equals `containing_block.width`.
        // Each arm of the `match` should increase the total width by exactly `underflow`,
        // and afterward all values should be absolute lengths in px.
        let underflow = containing_block.width - total;
        match (width == auto, margin_left == auto, margin_right == auto) {
            // If the values are overconstrained, calculate margin_right.
            (false, false, false) => {
                margin_right = Length(margin_right.to_px() + underflow, Px);
            }
            // If exactly one value is auto, its used value follows from the equality.
            (false, false, true) => {
                margin_right = Length(underflow, Px);
            }
            (false, true, false) => {
                margin_left = Length(underflow, Px);
            }
            // If width is set to auto, any other auto values become 0.
            (true, _, _) => {
                if margin_left == auto {
                    margin_left = Length(0.0, Px);
                }
                if margin_right == auto {
                    margin_right = Length(0.0, Px);
                }

                if underflow >= 0.0 {
                    // Expand width to fill the underflow.
                    width = Length(underflow, Px);
                } else {
                    // Width can't be negative. Adjust the right margin instead.
                    width = Length(0.0, Px);
                    margin_right = Length(margin_right.to_px() + underflow, Px);
                }
            }
            // If margin-left and margin-right are both auto, their used values are equal.
            (false, true, true) => {
                margin_left = Length(underflow / 2.0, Px);
                margin_right = Length(underflow / 2.0, Px);
            }
        }

        let d = &mut self.dimensions;
        d.width = width.to_px();

        d.padding.left = padding_left.to_px();
        d.padding.right = padding_right.to_px();

        d.border.left = border_left.to_px();
        d.border.right = border_right.to_px();

        d.margin.left = margin_left.to_px();
        d.margin.right = margin_right.to_px();
    }

    /// Finish calculating the block's edge sizes, and position it within its containing block.
    ///
    /// http://www.w3.org/TR/CSS2/visudet.html#normal-block
    ///
    /// Sets the vertical margin/padding/border dimensions, and the `x`, `y` values.
    fn calculate_block_position(&mut self, containing_block: Dimensions) {
        let style = self.get_style_node();
        let d = &mut self.dimensions;

        // margin, border, and padding have initial value 0.
        let zero = Length(0.0, Px);

        // If margin-top or margin-bottom is `auto`, the used value is zero.
        d.margin.top = style.lookup("margin-top", "margin", &zero).to_px();
        d.margin.bottom = style.lookup("margin-bottom", "margin", &zero).to_px();

        d.border.top = style.lookup("border-top-width", "border-width", &zero).to_px();
        d.border.bottom = style.lookup("border-bottom-width", "border-width", &zero).to_px();

        d.padding.top = style.lookup("padding-top", "padding", &zero).to_px();
        d.padding.bottom = style.lookup("padding-bottom", "padding", &zero).to_px();

        // Position the box below all the previous boxes in the container.
        d.x = containing_block.x +
              d.margin.left + d.border.left + d.padding.left;
        d.y = containing_block.y + containing_block.height +
              d.margin.top + d.border.top + d.padding.top;
    }

    /// Lay out the node's children within its content area and return the content height.
    ///
    /// Set `height` to the total content height.
    fn layout_block_children(&mut self) {
        let d = &mut self.dimensions;
        for child in self.children.mut_iter() {
            child.layout(*d);
            // Increment the height so each child is laid out below the previous one.
            d.height = d.height + child.dimensions.margin_box_height();
        }
    }

    /// Height of a block-level non-replaced element in normal flow with overflow visible.
    fn calculate_block_height(&mut self) {
        // If the height is set to an explicit length, use that exact length.
        // Otherwise, just keep the value set by `layout_block_children`.
        match self.get_style_node().value("height") {
            Some(Length(h, Px)) => { self.dimensions.height = h; }
            _ => {}
        }
    }

    /// Where a new inline child should go.
    fn get_inline_container(&mut self) -> &mut LayoutBox<'a> {
        match self.box_type {
            InlineNode(_) | AnonymousBlock => self,
            BlockNode(_) => {
                // If we've just generated an anonymous block box, keep using it.
                // Otherwise, create a new one.
                match self.children.last() {
                    Some(&LayoutBox { box_type: AnonymousBlock,..}) => {}
                    _ => self.children.push(LayoutBox::new(AnonymousBlock))
                }
                self.children.mut_last().unwrap()
            }
        }
    }
}

impl Dimensions {
    /// Total height of a box including its margins, border, and padding.
    fn margin_box_height(&self) -> f32 {
        self.height + self.padding.top + self.padding.bottom
                    + self.border.top + self.border.bottom
                    + self.margin.top + self.margin.bottom
    }
}
<|endoftext|>


<commit_before><commit_msg>Fix failure on missing file.<commit_after><|endoftext|>


<commit_before><commit_msg>Add the generic GObject wrapper struct<commit_after>// Copyright 2015, The Rust-GNOME Project Developers.
// See the COPYRIGHT file at the top-level directory of this distribution.
// Licensed under the MIT license, see the LICENSE file or <http://opensource.org/licenses/MIT>

use std::marker::PhantomData;
use glib::object::{Ref, Wrapper};
use glib::types::StaticType;

pub use glib::object::{Downcast, Upcast};

/// The generic type for `GObject` descendants in GTK.
pub struct Object<T>(Ref, PhantomData<T>);

impl<T> Wrapper for Object<T>
where Object<T>: StaticType {
    type GlibType = T;
    #[inline]
    unsafe fn wrap(r: Ref) -> Object<T> { Object(r, PhantomData) }
    #[inline]
    fn as_ref(&self) -> &Ref { &self.0 }
    #[inline]
    fn unwrap(self) -> Ref { self.0 }
}

impl<T> Clone for Object<T> {
    fn clone(&self) -> Object<T> {
        Object(self.0.clone(), PhantomData)
    }
}

unsafe impl<T> Upcast<::glib::object::Object> for Object<T> where Object<T>: StaticType { }
<|endoftext|>


<commit_before>use std::cmp::max;
use std::iter::{AdditiveIterator, repeat};

use column::{Column, Cell};
use column::Alignment::Left;
use dir::Dir;
use file::File;
use options::{Columns, FileFilter};
use users::OSUsers;

use ansi_term::Style::Plain;

#[derive(PartialEq, Copy, Debug)]
pub enum View {
    Details(Columns, bool, bool),
    Lines,
    Grid(bool, usize),
}

impl View {
    pub fn view(&self, dir: Option<&Dir>, files: &[File], filter: FileFilter) {
        match *self {
            View::Grid(across, width)       => grid_view(across, width, files),
            View::Details(ref cols, header, tree) => details_view(&*cols.for_dir(dir), files, header, tree, filter),
            View::Lines                     => lines_view(files),
        }
    }
}

/// The lines view literally just displays each file, line-by-line.
fn lines_view(files: &[File]) {
    for file in files.iter() {
        println!("{}", file.file_name_view());
    }
}

fn fit_into_grid(across: bool, console_width: usize, files: &[File]) -> Option<(usize, Vec<usize>)> {
    // TODO: this function could almost certainly be optimised...
    // surely not *all* of the numbers of lines are worth searching through!

    // Instead of numbers of columns, try to find the fewest number of *lines*
    // that the output will fit in.
    for num_lines in range(1, files.len()) {

        // The number of columns is the number of files divided by the number
        // of lines, *rounded up*.
        let mut num_columns = files.len() / num_lines;
        if files.len() % num_lines != 0 {
            num_columns += 1;
        }

        // Early abort: if there are so many columns that the width of the
        // *column separators* is bigger than the width of the screen, then
        // don't even try to tabulate it.
        // This is actually a necessary check, because the width is stored as
        // a usize, and making it go negative makes it huge instead, but it
        // also serves as a speed-up.
        let separator_width = (num_columns - 1) * 2;
        if console_width < separator_width {
            continue;
        }

        // Remove the separator width from the available space.
        let adjusted_width = console_width - separator_width;

        // Find the width of each column by adding the lengths of the file
        // names in that column up.
        let mut column_widths: Vec<usize> = repeat(0).take(num_columns).collect();
        for (index, file) in files.iter().enumerate() {
            let index = if across {
                index % num_columns
            }
            else {
                index / num_lines
            };
            column_widths[index] = max(column_widths[index], file.name.len());
        }

        // If they all fit in the terminal, combined, then success!
        if column_widths.iter().map(|&x| x).sum() < adjusted_width {
            return Some((num_lines, column_widths));
        }
    }

    // If you get here you have really long file names.
    return None;
}

fn grid_view(across: bool, console_width: usize, files: &[File]) {
    if let Some((num_lines, widths)) = fit_into_grid(across, console_width, files) {
        for y in range(0, num_lines) {
            for x in range(0, widths.len()) {
                let num = if across {
                    y * widths.len() + x
                }
                else {
                    y + num_lines * x
                };

                // Show whitespace in the place of trailing files
                if num >= files.len() {
                    continue;
                }

                let ref file = files[num];
                let styled_name = file.file_colour().paint(file.name.as_slice()).to_string();
                if x == widths.len() - 1 {
                    // The final column doesn't need to have trailing spaces
                    print!("{}", styled_name);
                }
                else {
                    assert!(widths[x] >= file.name.len());
                    print!("{}", Left.pad_string(&styled_name, widths[x] - file.name.len() + 2));
                }
            }
            print!("\n");
        }
    }
    else {
        // Drop down to lines view if the file names are too big for a grid
        lines_view(files);
    }
}

fn details_view(columns: &[Column], files: &[File], header: bool, tree: bool, filter: FileFilter) {
    // The output gets formatted into columns, which looks nicer. To
    // do this, we have to write the results into a table, instead of
    // displaying each file immediately, then calculating the maximum
    // width of each column based on the length of the results and
    // padding the fields during output.

    let mut cache = OSUsers::empty_cache();

    let mut table = Vec::new();
    get_files(columns, &mut cache, tree, &mut table, files, 0, filter);

    if header {
        let row = Row {
            depth: 0,
            cells: columns.iter().map(|c| Cell::paint(Plain.underline(), c.header())).collect(),
            name: Plain.underline().paint("Name").to_string()
        };

        table.insert(0, row);
    }

    let column_widths: Vec<usize> = range(0, columns.len())
        .map(|n| table.iter().map(|row| row.cells[n].length).max().unwrap_or(0))
        .collect();

    for row in table.iter() {
        for (num, column) in columns.iter().enumerate() {
            let padding = column_widths[num] - row.cells[num].length;
            print!("{} ", column.alignment().pad_string(&row.cells[num].text, padding));
        }

        if tree {
            for _ in range(0, row.depth) {
                print!("#");
            }

            print!(" ");
        }

        print!("{}\n", row.name);
    }
}

fn get_files(columns: &[Column], cache: &mut OSUsers, recurse: bool, dest: &mut Vec<Row>, src: &[File], depth: u8, filter: FileFilter) {
    for file in src.iter() {

        let row = Row {
            depth: depth,
            cells: columns.iter().map(|c| file.display(c, cache)).collect(),
            name:  file.file_name_view(),
        };

        dest.push(row);

        if recurse {
            if let Some(ref dir) = file.this {
                let files = filter.transform_files(dir.files(true));
                get_files(columns, cache, recurse, dest, files.as_slice(), depth + 1, filter);
            }
        }
    }
}

struct Row {
    pub depth: u8,
    pub cells: Vec<Cell>,
    pub name: String,
}
<commit_msg>Replace hash marks with decent-looking tree<commit_after>use std::cmp::max;
use std::iter::{AdditiveIterator, repeat};

use column::{Column, Cell};
use column::Alignment::Left;
use dir::Dir;
use file::{File, GREY};
use options::{Columns, FileFilter};
use users::OSUsers;

use ansi_term::Style::Plain;

#[derive(PartialEq, Copy, Debug)]
pub enum View {
    Details(Columns, bool, bool),
    Lines,
    Grid(bool, usize),
}

impl View {
    pub fn view(&self, dir: Option<&Dir>, files: &[File], filter: FileFilter) {
        match *self {
            View::Grid(across, width)       => grid_view(across, width, files),
            View::Details(ref cols, header, tree) => details_view(&*cols.for_dir(dir), files, header, tree, filter),
            View::Lines                     => lines_view(files),
        }
    }
}

/// The lines view literally just displays each file, line-by-line.
fn lines_view(files: &[File]) {
    for file in files.iter() {
        println!("{}", file.file_name_view());
    }
}

fn fit_into_grid(across: bool, console_width: usize, files: &[File]) -> Option<(usize, Vec<usize>)> {
    // TODO: this function could almost certainly be optimised...
    // surely not *all* of the numbers of lines are worth searching through!

    // Instead of numbers of columns, try to find the fewest number of *lines*
    // that the output will fit in.
    for num_lines in range(1, files.len()) {

        // The number of columns is the number of files divided by the number
        // of lines, *rounded up*.
        let mut num_columns = files.len() / num_lines;
        if files.len() % num_lines != 0 {
            num_columns += 1;
        }

        // Early abort: if there are so many columns that the width of the
        // *column separators* is bigger than the width of the screen, then
        // don't even try to tabulate it.
        // This is actually a necessary check, because the width is stored as
        // a usize, and making it go negative makes it huge instead, but it
        // also serves as a speed-up.
        let separator_width = (num_columns - 1) * 2;
        if console_width < separator_width {
            continue;
        }

        // Remove the separator width from the available space.
        let adjusted_width = console_width - separator_width;

        // Find the width of each column by adding the lengths of the file
        // names in that column up.
        let mut column_widths: Vec<usize> = repeat(0).take(num_columns).collect();
        for (index, file) in files.iter().enumerate() {
            let index = if across {
                index % num_columns
            }
            else {
                index / num_lines
            };
            column_widths[index] = max(column_widths[index], file.name.len());
        }

        // If they all fit in the terminal, combined, then success!
        if column_widths.iter().map(|&x| x).sum() < adjusted_width {
            return Some((num_lines, column_widths));
        }
    }

    // If you get here you have really long file names.
    return None;
}

fn grid_view(across: bool, console_width: usize, files: &[File]) {
    if let Some((num_lines, widths)) = fit_into_grid(across, console_width, files) {
        for y in range(0, num_lines) {
            for x in range(0, widths.len()) {
                let num = if across {
                    y * widths.len() + x
                }
                else {
                    y + num_lines * x
                };

                // Show whitespace in the place of trailing files
                if num >= files.len() {
                    continue;
                }

                let ref file = files[num];
                let styled_name = file.file_colour().paint(file.name.as_slice()).to_string();
                if x == widths.len() - 1 {
                    // The final column doesn't need to have trailing spaces
                    print!("{}", styled_name);
                }
                else {
                    assert!(widths[x] >= file.name.len());
                    print!("{}", Left.pad_string(&styled_name, widths[x] - file.name.len() + 2));
                }
            }
            print!("\n");
        }
    }
    else {
        // Drop down to lines view if the file names are too big for a grid
        lines_view(files);
    }
}

fn details_view(columns: &[Column], files: &[File], header: bool, tree: bool, filter: FileFilter) {
    // The output gets formatted into columns, which looks nicer. To
    // do this, we have to write the results into a table, instead of
    // displaying each file immediately, then calculating the maximum
    // width of each column based on the length of the results and
    // padding the fields during output.

    let mut cache = OSUsers::empty_cache();

    let mut table = Vec::new();
    get_files(columns, &mut cache, tree, &mut table, files, 0, filter);

    if header {
        let row = Row {
            depth: 0,
            cells: columns.iter().map(|c| Cell::paint(Plain.underline(), c.header())).collect(),
            name: Plain.underline().paint("Name").to_string(),
            last: false,
            children: false,
        };

        table.insert(0, row);
    }

    let column_widths: Vec<usize> = range(0, columns.len())
        .map(|n| table.iter().map(|row| row.cells[n].length).max().unwrap_or(0))
        .collect();

    let mut stack = Vec::new();

    for row in table.iter() {
        for (num, column) in columns.iter().enumerate() {
            let padding = column_widths[num] - row.cells[num].length;
            print!("{} ", column.alignment().pad_string(&row.cells[num].text, padding));
        }

        if tree {
            stack.resize(row.depth  + 1, "├──");
            stack[row.depth ] = if row.last { "└──" } else { "├──" };

            for i in range(1, row.depth + 1) {
                print!("{}", GREY.paint(stack[i ]));
            }

            if row.children {
                stack[row.depth ] = if row.last { "   " } else { "│  " };
            }

            if row.depth != 0 {
                print!(" ");
            }
        }

        print!("{}\n", row.name);
    }
}

fn get_files(columns: &[Column], cache: &mut OSUsers, recurse: bool, dest: &mut Vec<Row>, src: &[File], depth: usize, filter: FileFilter) {
    for (index, file) in src.iter().enumerate() {

        let row = Row {
            depth: depth,
            cells: columns.iter().map(|c| file.display(c, cache)).collect(),
            name:  file.file_name_view(),
            last: index == src.len() - 1,
            children: file.this.is_some(),
        };

        dest.push(row);

        if recurse {
            if let Some(ref dir) = file.this {
                let files = filter.transform_files(dir.files(true));
                get_files(columns, cache, recurse, dest, files.as_slice(), depth + 1, filter);
            }
        }
    }
}

struct Row {
    pub depth: usize,
    pub cells: Vec<Cell>,
    pub name: String,
    pub last: bool,
    pub children: bool,
}
<|endoftext|>


<commit_before><commit_msg>Replace to_uint() with to_usize()<commit_after><|endoftext|>


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

/// A simple static assertion macro. The first argument should be a unique
/// ALL_CAPS identifier that describes the condition.
#[macro_export]
macro_rules! static_assert {
    ($name:ident: $test:expr) => {
        // Use the bool to access an array such that if the bool is false, the access
        // is out-of-bounds.
        #[allow(dead_code)]
        static $name: () = [()][!$test as usize];
    }
}
<commit_msg>Ensure that the `static_assert!` argument is a `bool`<commit_after>// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

/// A simple static assertion macro. The first argument should be a unique
/// ALL_CAPS identifier that describes the condition.
#[macro_export]
#[allow_internal_unstable]
macro_rules! static_assert {
    ($name:ident: $test:expr) => {
        // Use the bool to access an array such that if the bool is false, the access
        // is out-of-bounds.
        #[allow(dead_code)]
        static $name: () = [()][!($test: bool) as usize];
    }
}
<|endoftext|>