<commit_before>extern crate ruroonga_command as ruroonga;
use ruroonga::selectable::drilldown::Drilldown;
use ruroonga::selectable::drilldown_builder::DrilldownBuilder;
use ruroonga::commandable::Commandable;
use ruroonga::queryable::Queryable;
use ruroonga::dsl::*;

fn simple_example() {
    let select = select("Entries".to_string())
                 .filter("content @ \"fast\"".to_string());
    let drilldown = Drilldown::new()
                 .drilldown("tag".to_string());
    let builder = DrilldownBuilder::new(select, drilldown).build();
    println!("simple: {:?}", builder);
}

fn to_query_example() {
    let select = select("Entries".to_string())
                 .filter("content @ \"fast\"".to_string());
    let drilldown = Drilldown::new()
                 .drilldown("tag".to_string());
    let builder = DrilldownBuilder::new(select, drilldown).to_query();
    println!("query: {}", builder);
}

fn to_command_example() {
    let select = select("Entries".to_string())
                 .filter("content @ \"fast\"".to_string());
    let drilldown = Drilldown::new()
                 .drilldown("tag".to_string());
    let builder = DrilldownBuilder::new(select, drilldown).to_command();
    println!("command line: {}", builder);
}

fn main() {
    simple_example();
    to_query_example();
    to_command_example();
}
<commit_msg>examples: Use std::ops::Add for select and drilldown<commit_after>extern crate ruroonga_command as ruroonga;
use ruroonga::selectable::drilldown::Drilldown;
use ruroonga::commandable::Commandable;
use ruroonga::queryable::Queryable;
use ruroonga::dsl::*;

fn simple_example() {
    let select = select("Entries".to_string())
                 .filter("content @ \"fast\"".to_string());
    let drilldown = Drilldown::new()
                 .drilldown("tag".to_string());
    let builder = (select + drilldown).build();
    println!("simple: {:?}", builder);
}

fn to_query_example() {
    let select = select("Entries".to_string())
                 .filter("content @ \"fast\"".to_string());
    let drilldown = Drilldown::new()
                 .drilldown("tag".to_string());
    let builder = (select + drilldown).to_query();
    println!("query: {}", builder);
}

fn to_command_example() {
    let select = select("Entries".to_string())
                 .filter("content @ \"fast\"".to_string());
    let drilldown = Drilldown::new()
                 .drilldown("tag".to_string());
    let builder = (select + drilldown).to_command();
    println!("command line: {}", builder);
}

fn main() {
    simple_example();
    to_query_example();
    to_command_example();
}
<|endoftext|>


<commit_before>use crate::utils;
use rustc_hir::intravisit::FnKind;
use rustc_hir::{Body, FnDecl, HirId};
use rustc_infer::infer::TyCtxtInferExt;
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::ty::{Opaque, Predicate::Trait, ToPolyTraitRef};
use rustc_session::{declare_lint_pass, declare_tool_lint};
use rustc_span::{sym, Span};
use rustc_trait_selection::traits::error_reporting::suggestions::InferCtxtExt;
use rustc_trait_selection::traits::{self, FulfillmentError, TraitEngine};

declare_clippy_lint! {
    /// **What it does:** This lint requires Future implementations returned from
    /// functions and methods to implement the `Send` marker trait. It is mostly
    /// used by library authors (public and internal) that target an audience where
    /// multithreaded executors are likely to be used for running these Futures.
    ///
    /// **Why is this bad?** A Future implementation captures some state that it
    /// needs to eventually produce its final value. When targeting a multithreaded
    /// executor (which is the norm on non-embedded devices) this means that this
    /// state may need to be transported to other threads, in other words the
    /// whole Future needs to implement the `Send` marker trait. If it does not,
    /// then the resulting Future cannot be submitted to a thread pool in the
    /// end user’s code.
    ///
    /// Especially for generic functions it can be confusing to leave the
    /// discovery of this problem to the end user: the reported error location
    /// will be far from its cause and can in many cases not even be fixed without
    /// modifying the library where the offending Future implementation is
    /// produced.
    ///
    /// **Known problems:** None.
    ///
    /// **Example:**
    ///
    /// ```rust
    /// async fn not_send(bytes: std::rc::Rc<[u8]>) {}
    /// ```
    /// Use instead:
    /// ```rust
    /// async fn is_send(bytes: std::sync::Arc<[u8]>) {}
    /// ```
    pub FUTURE_NOT_SEND,
    nursery,
    "public Futures must be Send"
}

declare_lint_pass!(FutureNotSend => [FUTURE_NOT_SEND]);

impl<'a, 'tcx> LateLintPass<'a, 'tcx> for FutureNotSend {
    fn check_fn(
        &mut self,
        cx: &LateContext<'a, 'tcx>,
        kind: FnKind<'tcx>,
        decl: &'tcx FnDecl<'tcx>,
        _: &'tcx Body<'tcx>,
        _: Span,
        hir_id: HirId,
    ) {
        if let FnKind::Closure(_) = kind {
            return;
        }
        let def_id = cx.tcx.hir().local_def_id(hir_id);
        let fn_sig = cx.tcx.fn_sig(def_id);
        let fn_sig = cx.tcx.erase_late_bound_regions(&fn_sig);
        let ret_ty = fn_sig.output();
        if let Opaque(id, subst) = ret_ty.kind {
            let preds = cx.tcx.predicates_of(id).instantiate(cx.tcx, subst);
            let mut is_future = false;
            for p in preds.predicates {
                if let Some(trait_ref) = p.to_opt_poly_trait_ref() {
                    if Some(trait_ref.def_id()) == cx.tcx.lang_items().future_trait() {
                        is_future = true;
                        break;
                    }
                }
            }
            if is_future {
                let send_trait = cx.tcx.get_diagnostic_item(sym::send_trait).unwrap();
                let span = decl.output.span();
                let send_result = cx.tcx.infer_ctxt().enter(|infcx| {
                    let cause = traits::ObligationCause::misc(span, hir_id);
                    let mut fulfillment_cx = traits::FulfillmentContext::new();
                    fulfillment_cx.register_bound(&infcx, cx.param_env, ret_ty, send_trait, cause);
                    fulfillment_cx.select_all_or_error(&infcx)
                });
                if let Err(send_errors) = send_result {
                    utils::span_lint_and_then(
                        cx,
                        FUTURE_NOT_SEND,
                        span,
                        "future cannot be sent between threads safely",
                        |db| {
                            cx.tcx.infer_ctxt().enter(|infcx| {
                                for FulfillmentError { obligation, .. } in send_errors {
                                    infcx.maybe_note_obligation_cause_for_async_await(db, &obligation);
                                    if let Trait(trait_pred, _) = obligation.predicate {
                                        let trait_ref = trait_pred.to_poly_trait_ref();
                                        db.note(&*format!(
                                            "`{}` doesn't implement `{}`",
                                            trait_ref.self_ty(),
                                            trait_ref.print_only_trait_path(),
                                        ));
                                    }
                                }
                            })
                        },
                    );
                }
            }
        }
    }
}
<commit_msg>Auto merge of #5488 - phansch:future-not-send-ret-ty, r=flip1995<commit_after>use crate::utils;
use rustc_hir::intravisit::FnKind;
use rustc_hir::{Body, FnDecl, HirId};
use rustc_infer::infer::TyCtxtInferExt;
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::ty::{Opaque, Predicate::Trait, ToPolyTraitRef};
use rustc_session::{declare_lint_pass, declare_tool_lint};
use rustc_span::{sym, Span};
use rustc_trait_selection::traits::error_reporting::suggestions::InferCtxtExt;
use rustc_trait_selection::traits::{self, FulfillmentError, TraitEngine};

declare_clippy_lint! {
    /// **What it does:** This lint requires Future implementations returned from
    /// functions and methods to implement the `Send` marker trait. It is mostly
    /// used by library authors (public and internal) that target an audience where
    /// multithreaded executors are likely to be used for running these Futures.
    ///
    /// **Why is this bad?** A Future implementation captures some state that it
    /// needs to eventually produce its final value. When targeting a multithreaded
    /// executor (which is the norm on non-embedded devices) this means that this
    /// state may need to be transported to other threads, in other words the
    /// whole Future needs to implement the `Send` marker trait. If it does not,
    /// then the resulting Future cannot be submitted to a thread pool in the
    /// end user’s code.
    ///
    /// Especially for generic functions it can be confusing to leave the
    /// discovery of this problem to the end user: the reported error location
    /// will be far from its cause and can in many cases not even be fixed without
    /// modifying the library where the offending Future implementation is
    /// produced.
    ///
    /// **Known problems:** None.
    ///
    /// **Example:**
    ///
    /// ```rust
    /// async fn not_send(bytes: std::rc::Rc<[u8]>) {}
    /// ```
    /// Use instead:
    /// ```rust
    /// async fn is_send(bytes: std::sync::Arc<[u8]>) {}
    /// ```
    pub FUTURE_NOT_SEND,
    nursery,
    "public Futures must be Send"
}

declare_lint_pass!(FutureNotSend => [FUTURE_NOT_SEND]);

impl<'a, 'tcx> LateLintPass<'a, 'tcx> for FutureNotSend {
    fn check_fn(
        &mut self,
        cx: &LateContext<'a, 'tcx>,
        kind: FnKind<'tcx>,
        decl: &'tcx FnDecl<'tcx>,
        _: &'tcx Body<'tcx>,
        _: Span,
        hir_id: HirId,
    ) {
        if let FnKind::Closure(_) = kind {
            return;
        }
        let ret_ty = utils::return_ty(cx, hir_id);
        if let Opaque(id, subst) = ret_ty.kind {
            let preds = cx.tcx.predicates_of(id).instantiate(cx.tcx, subst);
            let mut is_future = false;
            for p in preds.predicates {
                if let Some(trait_ref) = p.to_opt_poly_trait_ref() {
                    if Some(trait_ref.def_id()) == cx.tcx.lang_items().future_trait() {
                        is_future = true;
                        break;
                    }
                }
            }
            if is_future {
                let send_trait = cx.tcx.get_diagnostic_item(sym::send_trait).unwrap();
                let span = decl.output.span();
                let send_result = cx.tcx.infer_ctxt().enter(|infcx| {
                    let cause = traits::ObligationCause::misc(span, hir_id);
                    let mut fulfillment_cx = traits::FulfillmentContext::new();
                    fulfillment_cx.register_bound(&infcx, cx.param_env, ret_ty, send_trait, cause);
                    fulfillment_cx.select_all_or_error(&infcx)
                });
                if let Err(send_errors) = send_result {
                    utils::span_lint_and_then(
                        cx,
                        FUTURE_NOT_SEND,
                        span,
                        "future cannot be sent between threads safely",
                        |db| {
                            cx.tcx.infer_ctxt().enter(|infcx| {
                                for FulfillmentError { obligation, .. } in send_errors {
                                    infcx.maybe_note_obligation_cause_for_async_await(db, &obligation);
                                    if let Trait(trait_pred, _) = obligation.predicate {
                                        let trait_ref = trait_pred.to_poly_trait_ref();
                                        db.note(&*format!(
                                            "`{}` doesn't implement `{}`",
                                            trait_ref.self_ty(),
                                            trait_ref.print_only_trait_path(),
                                        ));
                                    }
                                }
                            })
                        },
                    );
                }
            }
        }
    }
}
<|endoftext|>


<commit_before>pub(super) mod imp;
pub(crate) mod scope;

use ra_syntax::{
    ast::{self, AstNode, NameOwner},
    SmolStr, SyntaxNode,
};
use relative_path::RelativePathBuf;

use crate::{db::SyntaxDatabase, syntax_ptr::SyntaxPtr, FileId};

pub(crate) use self::scope::ModuleScope;

/// Phisically, rust source is organized as a set of files, but logically it is
/// organized as a tree of modules. Usually, a single file corresponds to a
/// single module, but it is not nessary the case.
///
/// Module encapsulate the logic of transitioning from the fuzzy world of files
/// (which can have multiple parents) to the precise world of modules (which
/// always have one parent).
#[derive(Debug, PartialEq, Eq, Hash)]
pub(crate) struct ModuleTree {
    mods: Vec<ModuleData>,
    links: Vec<LinkData>,
}

impl ModuleTree {
    pub(crate) fn modules_for_file(&self, file_id: FileId) -> Vec<ModuleId> {
        self.mods
            .iter()
            .enumerate()
            .filter(|(_idx, it)| it.source.is_file(file_id))
            .map(|(idx, _)| ModuleId(idx as u32))
            .collect()
    }

    pub(crate) fn any_module_for_file(&self, file_id: FileId) -> Option<ModuleId> {
        self.modules_for_file(file_id).pop()
    }
}

/// `ModuleSource` is the syntax tree element that produced this module:
/// either a file, or an inlinde module.
/// TODO: we don't produce Inline modules yet
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub(crate) enum ModuleSource {
    File(FileId),
    #[allow(dead_code)]
    Inline(SyntaxPtr),
}

/// An owned syntax node for a module. Unlike `ModuleSource`,
/// this holds onto the AST for the whole file.
enum ModuleSourceNode {
    Root(ast::RootNode),
    Inline(ast::ModuleNode),
}

#[derive(Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, Debug)]
pub(crate) struct ModuleId(u32);

#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
pub(crate) struct LinkId(u32);

#[derive(Clone, Debug, Hash, PartialEq, Eq)]
pub enum Problem {
    UnresolvedModule {
        candidate: RelativePathBuf,
    },
    NotDirOwner {
        move_to: RelativePathBuf,
        candidate: RelativePathBuf,
    },
}

impl ModuleId {
    pub(crate) fn source(self, tree: &ModuleTree) -> ModuleSource {
        tree.module(self).source
    }
    pub(crate) fn parent_link(self, tree: &ModuleTree) -> Option<LinkId> {
        tree.module(self).parent
    }
    pub(crate) fn parent(self, tree: &ModuleTree) -> Option<ModuleId> {
        let link = self.parent_link(tree)?;
        Some(tree.link(link).owner)
    }
    pub(crate) fn root(self, tree: &ModuleTree) -> ModuleId {
        let mut curr = self;
        let mut i = 0;
        while let Some(next) = curr.parent(tree) {
            curr = next;
            i += 1;
            // simplistic cycle detection
            if i > 100 {
                return self;
            }
        }
        curr
    }
    pub(crate) fn child(self, tree: &ModuleTree, name: &str) -> Option<ModuleId> {
        let link = tree
            .module(self)
            .children
            .iter()
            .map(|&it| tree.link(it))
            .find(|it| it.name == name)?;
        Some(*link.points_to.first()?)
    }
    pub(crate) fn problems(
        self,
        tree: &ModuleTree,
        db: &impl SyntaxDatabase,
    ) -> Vec<(SyntaxNode, Problem)> {
        tree.module(self)
            .children
            .iter()
            .filter_map(|&it| {
                let p = tree.link(it).problem.clone()?;
                let s = it.bind_source(tree, db);
                let s = s.ast().name().unwrap().syntax().owned();
                Some((s, p))
            })
            .collect()
    }
}

impl LinkId {
    pub(crate) fn owner(self, tree: &ModuleTree) -> ModuleId {
        tree.link(self).owner
    }
    pub(crate) fn bind_source<'a>(
        self,
        tree: &ModuleTree,
        db: &impl SyntaxDatabase,
    ) -> ast::ModuleNode {
        let owner = self.owner(tree);
        match owner.source(tree).resolve(db) {
            ModuleSourceNode::Root(root) => {
                let ast = imp::modules(root.ast())
                    .find(|(name, _)| name == &tree.link(self).name)
                    .unwrap()
                    .1;
                ast.into()
            }
            ModuleSourceNode::Inline(..) => {
                unimplemented!("https://github.com/rust-analyzer/rust-analyzer/issues/181")
            }
        }
    }
}

#[derive(Debug, PartialEq, Eq, Hash)]
struct ModuleData {
    source: ModuleSource,
    parent: Option<LinkId>,
    children: Vec<LinkId>,
}

impl ModuleSource {
    pub(crate) fn as_file(self) -> Option<FileId> {
        match self {
            ModuleSource::File(f) => Some(f),
            ModuleSource::Inline(..) => None,
        }
    }

    fn resolve(self, db: &impl SyntaxDatabase) -> ModuleSourceNode {
        match self {
            ModuleSource::File(file_id) => {
                let syntax = db.file_syntax(file_id);
                ModuleSourceNode::Root(syntax.ast().into())
            }
            ModuleSource::Inline(ptr) => {
                let syntax = db.resolve_syntax_ptr(ptr);
                let syntax = syntax.borrowed();
                let module = ast::Module::cast(syntax).unwrap();
                ModuleSourceNode::Inline(module.into())
            }
        }
    }

    fn is_file(self, file_id: FileId) -> bool {
        self.as_file() == Some(file_id)
    }
}

#[derive(Hash, Debug, PartialEq, Eq)]
struct LinkData {
    owner: ModuleId,
    name: SmolStr,
    points_to: Vec<ModuleId>,
    problem: Option<Problem>,
}

impl ModuleTree {
    fn module(&self, id: ModuleId) -> &ModuleData {
        &self.mods[id.0 as usize]
    }
    fn module_mut(&mut self, id: ModuleId) -> &mut ModuleData {
        &mut self.mods[id.0 as usize]
    }
    fn link(&self, id: LinkId) -> &LinkData {
        &self.links[id.0 as usize]
    }
    fn link_mut(&mut self, id: LinkId) -> &mut LinkData {
        &mut self.links[id.0 as usize]
    }

    fn push_mod(&mut self, data: ModuleData) -> ModuleId {
        let id = ModuleId(self.mods.len() as u32);
        self.mods.push(data);
        id
    }
    fn push_link(&mut self, data: LinkData) -> LinkId {
        let id = LinkId(self.links.len() as u32);
        self.mods[data.owner.0 as usize].children.push(id);
        self.links.push(data);
        id
    }
}
<commit_msg>Introduce modules_from_source fn<commit_after>pub(super) mod imp;
pub(crate) mod scope;

use ra_syntax::{
    ast::{self, AstNode, NameOwner},
    SmolStr, SyntaxNode,
};
use relative_path::RelativePathBuf;

use crate::{db::SyntaxDatabase, syntax_ptr::SyntaxPtr, FileId};

pub(crate) use self::scope::ModuleScope;

/// Phisically, rust source is organized as a set of files, but logically it is
/// organized as a tree of modules. Usually, a single file corresponds to a
/// single module, but it is not nessary the case.
///
/// Module encapsulate the logic of transitioning from the fuzzy world of files
/// (which can have multiple parents) to the precise world of modules (which
/// always have one parent).
#[derive(Debug, PartialEq, Eq, Hash)]
pub(crate) struct ModuleTree {
    mods: Vec<ModuleData>,
    links: Vec<LinkData>,
}

impl ModuleTree {
    pub(crate) fn modules_for_source(&self, source: ModuleSource) -> Vec<ModuleId> {
        self.mods
            .iter()
            .enumerate()
            .filter(|(_idx, it)| it.source == source)
            .map(|(idx, _)| ModuleId(idx as u32))
            .collect()
    }

    pub(crate) fn modules_for_file(&self, file_id: FileId) -> Vec<ModuleId> {
        self.modules_for_source(ModuleSource::File(file_id))
    }

    pub(crate) fn any_module_for_file(&self, file_id: FileId) -> Option<ModuleId> {
        self.modules_for_file(file_id).pop()
    }
}

/// `ModuleSource` is the syntax tree element that produced this module:
/// either a file, or an inlinde module.
/// TODO: we don't produce Inline modules yet
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub(crate) enum ModuleSource {
    File(FileId),
    #[allow(dead_code)]
    Inline(SyntaxPtr),
}

/// An owned syntax node for a module. Unlike `ModuleSource`,
/// this holds onto the AST for the whole file.
enum ModuleSourceNode {
    Root(ast::RootNode),
    Inline(ast::ModuleNode),
}

#[derive(Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, Debug)]
pub(crate) struct ModuleId(u32);

#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
pub(crate) struct LinkId(u32);

#[derive(Clone, Debug, Hash, PartialEq, Eq)]
pub enum Problem {
    UnresolvedModule {
        candidate: RelativePathBuf,
    },
    NotDirOwner {
        move_to: RelativePathBuf,
        candidate: RelativePathBuf,
    },
}

impl ModuleId {
    pub(crate) fn source(self, tree: &ModuleTree) -> ModuleSource {
        tree.module(self).source
    }
    pub(crate) fn parent_link(self, tree: &ModuleTree) -> Option<LinkId> {
        tree.module(self).parent
    }
    pub(crate) fn parent(self, tree: &ModuleTree) -> Option<ModuleId> {
        let link = self.parent_link(tree)?;
        Some(tree.link(link).owner)
    }
    pub(crate) fn root(self, tree: &ModuleTree) -> ModuleId {
        let mut curr = self;
        let mut i = 0;
        while let Some(next) = curr.parent(tree) {
            curr = next;
            i += 1;
            // simplistic cycle detection
            if i > 100 {
                return self;
            }
        }
        curr
    }
    pub(crate) fn child(self, tree: &ModuleTree, name: &str) -> Option<ModuleId> {
        let link = tree
            .module(self)
            .children
            .iter()
            .map(|&it| tree.link(it))
            .find(|it| it.name == name)?;
        Some(*link.points_to.first()?)
    }
    pub(crate) fn problems(
        self,
        tree: &ModuleTree,
        db: &impl SyntaxDatabase,
    ) -> Vec<(SyntaxNode, Problem)> {
        tree.module(self)
            .children
            .iter()
            .filter_map(|&it| {
                let p = tree.link(it).problem.clone()?;
                let s = it.bind_source(tree, db);
                let s = s.ast().name().unwrap().syntax().owned();
                Some((s, p))
            })
            .collect()
    }
}

impl LinkId {
    pub(crate) fn owner(self, tree: &ModuleTree) -> ModuleId {
        tree.link(self).owner
    }
    pub(crate) fn bind_source<'a>(
        self,
        tree: &ModuleTree,
        db: &impl SyntaxDatabase,
    ) -> ast::ModuleNode {
        let owner = self.owner(tree);
        match owner.source(tree).resolve(db) {
            ModuleSourceNode::Root(root) => {
                let ast = imp::modules(root.ast())
                    .find(|(name, _)| name == &tree.link(self).name)
                    .unwrap()
                    .1;
                ast.into()
            }
            ModuleSourceNode::Inline(..) => {
                unimplemented!("https://github.com/rust-analyzer/rust-analyzer/issues/181")
            }
        }
    }
}

#[derive(Debug, PartialEq, Eq, Hash)]
struct ModuleData {
    source: ModuleSource,
    parent: Option<LinkId>,
    children: Vec<LinkId>,
}

impl ModuleSource {
    pub(crate) fn as_file(self) -> Option<FileId> {
        match self {
            ModuleSource::File(f) => Some(f),
            ModuleSource::Inline(..) => None,
        }
    }

    fn resolve(self, db: &impl SyntaxDatabase) -> ModuleSourceNode {
        match self {
            ModuleSource::File(file_id) => {
                let syntax = db.file_syntax(file_id);
                ModuleSourceNode::Root(syntax.ast().into())
            }
            ModuleSource::Inline(ptr) => {
                let syntax = db.resolve_syntax_ptr(ptr);
                let syntax = syntax.borrowed();
                let module = ast::Module::cast(syntax).unwrap();
                ModuleSourceNode::Inline(module.into())
            }
        }
    }
}

#[derive(Hash, Debug, PartialEq, Eq)]
struct LinkData {
    owner: ModuleId,
    name: SmolStr,
    points_to: Vec<ModuleId>,
    problem: Option<Problem>,
}

impl ModuleTree {
    fn module(&self, id: ModuleId) -> &ModuleData {
        &self.mods[id.0 as usize]
    }
    fn module_mut(&mut self, id: ModuleId) -> &mut ModuleData {
        &mut self.mods[id.0 as usize]
    }
    fn link(&self, id: LinkId) -> &LinkData {
        &self.links[id.0 as usize]
    }
    fn link_mut(&mut self, id: LinkId) -> &mut LinkData {
        &mut self.links[id.0 as usize]
    }

    fn push_mod(&mut self, data: ModuleData) -> ModuleId {
        let id = ModuleId(self.mods.len() as u32);
        self.mods.push(data);
        id
    }
    fn push_link(&mut self, data: LinkData) -> LinkId {
        let id = LinkId(self.links.len() as u32);
        self.mods[data.owner.0 as usize].children.push(id);
        self.links.push(data);
        id
    }
}
<|endoftext|>


<commit_before>#![feature(asm)]

extern crate syscall;

use syscall::iopl;

use pci::{Pci, PciBar, PciClass};

mod pci;

fn enumerate_pci() {
    println!("PCI BS/DV/FN VEND:DEVI CL.SC.IN.RV");

    let pci = Pci::new();
    for bus in pci.buses() {
        for dev in bus.devs() {
            for func in dev.funcs() {
                if let Some(header) = func.header() {
                    print!("PCI {:>02X}/{:>02X}/{:>02X} {:>04X}:{:>04X} {:>02X}.{:>02X}.{:>02X}.{:>02X}",
                            bus.num, dev.num, func.num,
                            header.vendor_id, header.device_id,
                            header.class, header.subclass, header.interface, header.revision);

                    let pci_class = PciClass::from(header.class);
                    print!(" {:?}", pci_class);
                    match pci_class {
                        PciClass::Storage => match header.subclass {
                            0x01 => {
                                print!(" IDE");
                            },
                            0x06 => {
                                print!(" SATA");
                            },
                            _ => ()
                        },
                        PciClass::SerialBus => match header.subclass {
                            0x03 => match header.interface {
                                0x00 => {
                                    print!(" UHCI");
                                },
                                0x10 => {
                                    print!(" OHCI");
                                },
                                0x20 => {
                                    print!(" EHCI");
                                },
                                0x30 => {
                                    print!(" XHCI");
                                },
                                _ => ()
                            },
                            _ => ()
                        },
                        _ => ()
                    }

                    for i in 0..header.bars.len() {
                        match PciBar::from(header.bars[i]) {
                            PciBar::None => (),
                            PciBar::Memory(address) => print!(" {}={:>08X}", i, address),
                            PciBar::Port(address) => print!(" {}={:>04X}", i, address)
                        }
                    }

                    print!("\n");
                }
            }
        }
    }
}

fn main() {
    unsafe { iopl(3).unwrap() };

    enumerate_pci();
}
<commit_msg>Run pcid as a daemon<commit_after>#![feature(asm)]

extern crate syscall;

use std::thread;
use syscall::iopl;

use pci::{Pci, PciBar, PciClass};

mod pci;

fn enumerate_pci() {
    println!("PCI BS/DV/FN VEND:DEVI CL.SC.IN.RV");

    let pci = Pci::new();
    for bus in pci.buses() {
        for dev in bus.devs() {
            for func in dev.funcs() {
                if let Some(header) = func.header() {
                    print!("PCI {:>02X}/{:>02X}/{:>02X} {:>04X}:{:>04X} {:>02X}.{:>02X}.{:>02X}.{:>02X}",
                            bus.num, dev.num, func.num,
                            header.vendor_id, header.device_id,
                            header.class, header.subclass, header.interface, header.revision);

                    let pci_class = PciClass::from(header.class);
                    print!(" {:?}", pci_class);
                    match pci_class {
                        PciClass::Storage => match header.subclass {
                            0x01 => {
                                print!(" IDE");
                            },
                            0x06 => {
                                print!(" SATA");
                            },
                            _ => ()
                        },
                        PciClass::SerialBus => match header.subclass {
                            0x03 => match header.interface {
                                0x00 => {
                                    print!(" UHCI");
                                },
                                0x10 => {
                                    print!(" OHCI");
                                },
                                0x20 => {
                                    print!(" EHCI");
                                },
                                0x30 => {
                                    print!(" XHCI");
                                },
                                _ => ()
                            },
                            _ => ()
                        },
                        _ => ()
                    }

                    for i in 0..header.bars.len() {
                        match PciBar::from(header.bars[i]) {
                            PciBar::None => (),
                            PciBar::Memory(address) => print!(" {}={:>08X}", i, address),
                            PciBar::Port(address) => print!(" {}={:>04X}", i, address)
                        }
                    }

                    print!("\n");
                }
            }
        }
    }
}

fn main() {
    thread::spawn(||{
        unsafe { iopl(3).unwrap() };

        enumerate_pci();
    });
}
<|endoftext|>


<commit_before>// pest. The Elegant Parser
// Copyright (c) 2018 Dragoș Tiselice
//
// 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. All files in the project carrying such notice may not be copied,
// modified, or distributed except according to those terms.

use std::fmt;
use std::hash::{Hash, Hasher};
use std::ptr;
use std::rc::Rc;
use std::str;

use super::flat_pairs::{self, FlatPairs};
use super::pair::{self, Pair};
use super::queueable_token::QueueableToken;
use super::tokens::{self, Tokens};
use RuleType;

/// An iterator over [`Pair`]s. It is created by [`pest::state`] and [`Pair::into_inner`].
///
/// [`Pair`]: struct.Pair.html
/// [`pest::state`]: ../fn.state.html
/// [`Pair::into_inner`]: struct.Pair.html#method.into_inner
#[derive(Clone)]
pub struct Pairs<'i, R> {
    queue: Rc<Vec<QueueableToken<R>>>,
    input: &'i [u8],
    start: usize,
    end: usize
}

pub fn new<R: RuleType>(
    queue: Rc<Vec<QueueableToken<R>>>,
    input: &[u8],
    start: usize,
    end: usize
) -> Pairs<R> {
    Pairs {
        queue,
        input,
        start,
        end
    }
}

impl<'i, R: RuleType> Pairs<'i, R> {
    /// Captures a slice from the `&str` defined by the starting position of the first token `Pair`
    /// and the ending position of the last token `Pair` of the `Pairs`. This also captures
    /// the input between those two token `Pair`s.
    ///
    /// # Examples
    ///
    /// ```
    /// # use std::rc::Rc;
    /// # use pest;
    /// # #[allow(non_camel_case_types)]
    /// # #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
    /// enum Rule {
    ///     a,
    ///     b
    /// }
    ///
    /// let input = "a b";
    /// let pairs = pest::state(input, |state| {
    ///     // generating Token pairs with Rule::a and Rule::b ...
    /// #     state.rule(Rule::a, |s| s.match_string("a")).and_then(|s| s.skip(1))
    /// #         .and_then(|s| s.rule(Rule::b, |s| s.match_string("b")))
    /// }).unwrap();
    ///
    /// assert_eq!(pairs.as_str(), "a b");
    /// ```
    #[inline]
    pub fn as_str(&self) -> &'i str {
        let start = self.pos(self.start);
        let end = self.pos(self.end - 1);

        // Generated positions always come from Positions and are UTF-8 borders.
        unsafe { str::from_utf8_unchecked(&self.input[start..end]) }
    }

    /// Captures inner token `Pair`s and concatenates resulting `&str`s. This does not capture
    /// the input between token `Pair`s.
    ///
    /// # Examples
    ///
    /// ```
    /// # use std::rc::Rc;
    /// # use pest;
    /// # #[allow(non_camel_case_types)]
    /// # #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
    /// enum Rule {
    ///     a,
    ///     b
    /// }
    ///
    /// let input = "a b";
    /// let pairs = pest::state(input, |state| {
    ///     // generating Token pairs with Rule::a and Rule::b ...
    /// #     state.rule(Rule::a, |s| s.match_string("a")).and_then(|s| s.skip(1))
    /// #         .and_then(|s| s.rule(Rule::b, |s| s.match_string("b")))
    /// }).unwrap();
    ///
    /// assert_eq!(pairs.concat(), "ab");
    /// ```
    #[inline]
    pub fn concat(&self) -> String {
        self.clone().fold(String::new(), |string, pair| string + pair.as_str())
    }

    /// Flattens the `Pairs`.
    ///
    /// # Examples
    ///
    /// ```
    /// # use std::rc::Rc;
    /// # use pest;
    /// # #[allow(non_camel_case_types)]
    /// # #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
    /// enum Rule {
    ///     a,
    ///     b
    /// }
    ///
    /// let input = "";
    /// let pairs = pest::state(input, |state| {
    ///     // generating nested Token pair with Rule::b inside Rule::a
    /// #     state.rule(Rule::a, |state| {
    /// #         state.rule(Rule::b, |s| Ok(s))
    /// #     })
    /// }).unwrap();
    /// let tokens: Vec<_> = pairs.flatten().tokens().collect();
    ///
    /// assert_eq!(tokens.len(), 4);
    /// ```
    #[inline]
    pub fn flatten(self) -> FlatPairs<'i, R> {
        flat_pairs::new(self.queue, self.input, self.start, self.end)
    }

    /// Returns the `Tokens` for the `Pairs`.
    ///
    /// # Examples
    ///
    /// ```
    /// # use std::rc::Rc;
    /// # use pest;
    /// # #[allow(non_camel_case_types)]
    /// # #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
    /// enum Rule {
    ///     a
    /// }
    ///
    /// let input = "";
    /// let pairs = pest::state(input, |state| {
    ///     // generating Token pair with Rule::a ...
    /// #     state.rule(Rule::a, |s| Ok(s))
    /// }).unwrap();
    /// let tokens: Vec<_> = pairs.tokens().collect();
    ///
    /// assert_eq!(tokens.len(), 2);
    /// ```
    #[inline]
    pub fn tokens(self) -> Tokens<'i, R> {
        tokens::new(self.queue, self.input, self.start, self.end)
    }

    #[inline]
    pub fn peek(&mut self) -> Option<Pair> {
        if self.start < self.end {
            Some(pair::new(Rc::clone(&self.queue), self.input, self.start))
        } else {
            None
        }
    }

    fn pair(&self) -> usize {
        match self.queue[self.start] {
            QueueableToken::Start {
                end_token_index, ..
            } => end_token_index,
            _ => unreachable!()
        }
    }

    fn pair_from_end(&self) -> usize {
        match self.queue[self.end - 1] {
            QueueableToken::End {
                start_token_index, ..
            } => start_token_index,
            _ => unreachable!()
        }
    }

    fn pos(&self, index: usize) -> usize {
        match self.queue[index] {
            QueueableToken::Start { input_pos, .. } | QueueableToken::End { input_pos, .. } => {
                input_pos
            }
        }
    }
}

impl<'i, R: RuleType> Iterator for Pairs<'i, R> {
    type Item = Pair<'i, R>;

    fn next(&mut self) -> Option<Self::Item> {
        let pair = self.peek()?;
        self.start = self.pair() + 1;
        Some(pair)
    }
}

impl<'i, R: RuleType> DoubleEndedIterator for Pairs<'i, R> {
    fn next_back(&mut self) -> Option<Self::Item> {
        if self.end <= self.start {
            return None;
        }

        self.end = self.pair_from_end();

        let pair = pair::new(Rc::clone(&self.queue), self.input, self.end);

        Some(pair)
    }
}

impl<'i, R: RuleType> fmt::Debug for Pairs<'i, R> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.debug_list().entries(self.clone()).finish()
    }
}

impl<'i, R: RuleType> fmt::Display for Pairs<'i, R> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(
            f,
            "[{}]",
            self.clone()
                .map(|pair| format!("{}", pair))
                .collect::<Vec<_>>()
                .join(", ")
        )
    }
}

impl<'i, R: PartialEq> PartialEq for Pairs<'i, R> {
    fn eq(&self, other: &Pairs<'i, R>) -> bool {
        Rc::ptr_eq(&self.queue, &other.queue) && ptr::eq(self.input, other.input)
            && self.start == other.start && self.end == other.end
    }
}

impl<'i, R: Eq> Eq for Pairs<'i, R> {}

impl<'i, R: Hash> Hash for Pairs<'i, R> {
    fn hash<H: Hasher>(&self, state: &mut H) {
        (&*self.queue as *const Vec<QueueableToken<R>>).hash(state);
        (self.input as *const [u8]).hash(state);
        self.start.hash(state);
        self.end.hash(state);
    }
}

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

    #[test]
    fn as_str() {
        let pairs = AbcParser::parse(Rule::a, "abcde").unwrap();

        assert_eq!(pairs.as_str(), "abcde");
    }

    #[test]
    fn concat() {
        let pairs = AbcParser::parse(Rule::a, "abcde").unwrap();

        assert_eq!(pairs.concat(), "abce");
    }

    #[test]
    fn pairs_debug() {
        let pairs = AbcParser::parse(Rule::a, "abcde").unwrap();

        assert_eq!(
            format!("{:?}", pairs),
            "[\
                Pair { rule: a, span: Span { str: \"abc\", start: 0, end: 3 }, inner: [\
                    Pair { rule: b, span: Span { str: \"b\", start: 1, end: 2 }, inner: [] }\
                ] }, \
                Pair { rule: c, span: Span { str: \"e\", start: 4, end: 5 }, inner: [] }\
            ]"
        .to_owned()
        );
    }

    #[test]
    fn pairs_display() {
        let pairs = AbcParser::parse(Rule::a, "abcde").unwrap();

        assert_eq!(
            format!("{}", pairs),
            "[a(0, 3, [b(1, 2)]), c(4, 5)]".to_owned()
        );
    }

    #[test]
    fn iter_for_pairs() {
        let pairs = AbcParser::parse(Rule::a, "abcde").unwrap();
        assert_eq!(
            pairs.map(|p| p.as_rule()).collect::<Vec<Rule>>(),
            vec![Rule::a, Rule::c]
        );
    }

    #[test]
    fn double_ended_iter_for_pairs() {
        let pairs = AbcParser::parse(Rule::a, "abcde").unwrap();
        assert_eq!(
            pairs.rev().map(|p| p.as_rule()).collect::<Vec<Rule>>(),
            vec![Rule::c, Rule::a]
        );
    }
}
<commit_msg>Fix peek signature<commit_after>// pest. The Elegant Parser
// Copyright (c) 2018 Dragoș Tiselice
//
// 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. All files in the project carrying such notice may not be copied,
// modified, or distributed except according to those terms.

use std::fmt;
use std::hash::{Hash, Hasher};
use std::ptr;
use std::rc::Rc;
use std::str;

use super::flat_pairs::{self, FlatPairs};
use super::pair::{self, Pair};
use super::queueable_token::QueueableToken;
use super::tokens::{self, Tokens};
use RuleType;

/// An iterator over [`Pair`]s. It is created by [`pest::state`] and [`Pair::into_inner`].
///
/// [`Pair`]: struct.Pair.html
/// [`pest::state`]: ../fn.state.html
/// [`Pair::into_inner`]: struct.Pair.html#method.into_inner
#[derive(Clone)]
pub struct Pairs<'i, R> {
    queue: Rc<Vec<QueueableToken<R>>>,
    input: &'i [u8],
    start: usize,
    end: usize
}

pub fn new<R: RuleType>(
    queue: Rc<Vec<QueueableToken<R>>>,
    input: &[u8],
    start: usize,
    end: usize
) -> Pairs<R> {
    Pairs {
        queue,
        input,
        start,
        end
    }
}

impl<'i, R: RuleType> Pairs<'i, R> {
    /// Captures a slice from the `&str` defined by the starting position of the first token `Pair`
    /// and the ending position of the last token `Pair` of the `Pairs`. This also captures
    /// the input between those two token `Pair`s.
    ///
    /// # Examples
    ///
    /// ```
    /// # use std::rc::Rc;
    /// # use pest;
    /// # #[allow(non_camel_case_types)]
    /// # #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
    /// enum Rule {
    ///     a,
    ///     b
    /// }
    ///
    /// let input = "a b";
    /// let pairs = pest::state(input, |state| {
    ///     // generating Token pairs with Rule::a and Rule::b ...
    /// #     state.rule(Rule::a, |s| s.match_string("a")).and_then(|s| s.skip(1))
    /// #         .and_then(|s| s.rule(Rule::b, |s| s.match_string("b")))
    /// }).unwrap();
    ///
    /// assert_eq!(pairs.as_str(), "a b");
    /// ```
    #[inline]
    pub fn as_str(&self) -> &'i str {
        let start = self.pos(self.start);
        let end = self.pos(self.end - 1);

        // Generated positions always come from Positions and are UTF-8 borders.
        unsafe { str::from_utf8_unchecked(&self.input[start..end]) }
    }

    /// Captures inner token `Pair`s and concatenates resulting `&str`s. This does not capture
    /// the input between token `Pair`s.
    ///
    /// # Examples
    ///
    /// ```
    /// # use std::rc::Rc;
    /// # use pest;
    /// # #[allow(non_camel_case_types)]
    /// # #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
    /// enum Rule {
    ///     a,
    ///     b
    /// }
    ///
    /// let input = "a b";
    /// let pairs = pest::state(input, |state| {
    ///     // generating Token pairs with Rule::a and Rule::b ...
    /// #     state.rule(Rule::a, |s| s.match_string("a")).and_then(|s| s.skip(1))
    /// #         .and_then(|s| s.rule(Rule::b, |s| s.match_string("b")))
    /// }).unwrap();
    ///
    /// assert_eq!(pairs.concat(), "ab");
    /// ```
    #[inline]
    pub fn concat(&self) -> String {
        self.clone().fold(String::new(), |string, pair| string + pair.as_str())
    }

    /// Flattens the `Pairs`.
    ///
    /// # Examples
    ///
    /// ```
    /// # use std::rc::Rc;
    /// # use pest;
    /// # #[allow(non_camel_case_types)]
    /// # #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
    /// enum Rule {
    ///     a,
    ///     b
    /// }
    ///
    /// let input = "";
    /// let pairs = pest::state(input, |state| {
    ///     // generating nested Token pair with Rule::b inside Rule::a
    /// #     state.rule(Rule::a, |state| {
    /// #         state.rule(Rule::b, |s| Ok(s))
    /// #     })
    /// }).unwrap();
    /// let tokens: Vec<_> = pairs.flatten().tokens().collect();
    ///
    /// assert_eq!(tokens.len(), 4);
    /// ```
    #[inline]
    pub fn flatten(self) -> FlatPairs<'i, R> {
        flat_pairs::new(self.queue, self.input, self.start, self.end)
    }

    /// Returns the `Tokens` for the `Pairs`.
    ///
    /// # Examples
    ///
    /// ```
    /// # use std::rc::Rc;
    /// # use pest;
    /// # #[allow(non_camel_case_types)]
    /// # #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
    /// enum Rule {
    ///     a
    /// }
    ///
    /// let input = "";
    /// let pairs = pest::state(input, |state| {
    ///     // generating Token pair with Rule::a ...
    /// #     state.rule(Rule::a, |s| Ok(s))
    /// }).unwrap();
    /// let tokens: Vec<_> = pairs.tokens().collect();
    ///
    /// assert_eq!(tokens.len(), 2);
    /// ```
    #[inline]
    pub fn tokens(self) -> Tokens<'i, R> {
        tokens::new(self.queue, self.input, self.start, self.end)
    }

    #[inline]
    pub fn peek(&mut self) -> Option<Pair<'i, R>> {
        if self.start < self.end {
            Some(pair::new(Rc::clone(&self.queue), self.input, self.start))
        } else {
            None
        }
    }

    fn pair(&self) -> usize {
        match self.queue[self.start] {
            QueueableToken::Start {
                end_token_index, ..
            } => end_token_index,
            _ => unreachable!()
        }
    }

    fn pair_from_end(&self) -> usize {
        match self.queue[self.end - 1] {
            QueueableToken::End {
                start_token_index, ..
            } => start_token_index,
            _ => unreachable!()
        }
    }

    fn pos(&self, index: usize) -> usize {
        match self.queue[index] {
            QueueableToken::Start { input_pos, .. } | QueueableToken::End { input_pos, .. } => {
                input_pos
            }
        }
    }
}

impl<'i, R: RuleType> Iterator for Pairs<'i, R> {
    type Item = Pair<'i, R>;

    fn next(&mut self) -> Option<Self::Item> {
        let pair = self.peek()?;
        self.start = self.pair() + 1;
        Some(pair)
    }
}

impl<'i, R: RuleType> DoubleEndedIterator for Pairs<'i, R> {
    fn next_back(&mut self) -> Option<Self::Item> {
        if self.end <= self.start {
            return None;
        }

        self.end = self.pair_from_end();

        let pair = pair::new(Rc::clone(&self.queue), self.input, self.end);

        Some(pair)
    }
}

impl<'i, R: RuleType> fmt::Debug for Pairs<'i, R> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.debug_list().entries(self.clone()).finish()
    }
}

impl<'i, R: RuleType> fmt::Display for Pairs<'i, R> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(
            f,
            "[{}]",
            self.clone()
                .map(|pair| format!("{}", pair))
                .collect::<Vec<_>>()
                .join(", ")
        )
    }
}

impl<'i, R: PartialEq> PartialEq for Pairs<'i, R> {
    fn eq(&self, other: &Pairs<'i, R>) -> bool {
        Rc::ptr_eq(&self.queue, &other.queue) && ptr::eq(self.input, other.input)
            && self.start == other.start && self.end == other.end
    }
}

impl<'i, R: Eq> Eq for Pairs<'i, R> {}

impl<'i, R: Hash> Hash for Pairs<'i, R> {
    fn hash<H: Hasher>(&self, state: &mut H) {
        (&*self.queue as *const Vec<QueueableToken<R>>).hash(state);
        (self.input as *const [u8]).hash(state);
        self.start.hash(state);
        self.end.hash(state);
    }
}

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

    #[test]
    fn as_str() {
        let pairs = AbcParser::parse(Rule::a, "abcde").unwrap();

        assert_eq!(pairs.as_str(), "abcde");
    }

    #[test]
    fn concat() {
        let pairs = AbcParser::parse(Rule::a, "abcde").unwrap();

        assert_eq!(pairs.concat(), "abce");
    }

    #[test]
    fn pairs_debug() {
        let pairs = AbcParser::parse(Rule::a, "abcde").unwrap();

        assert_eq!(
            format!("{:?}", pairs),
            "[\
                Pair { rule: a, span: Span { str: \"abc\", start: 0, end: 3 }, inner: [\
                    Pair { rule: b, span: Span { str: \"b\", start: 1, end: 2 }, inner: [] }\
                ] }, \
                Pair { rule: c, span: Span { str: \"e\", start: 4, end: 5 }, inner: [] }\
            ]"
        .to_owned()
        );
    }

    #[test]
    fn pairs_display() {
        let pairs = AbcParser::parse(Rule::a, "abcde").unwrap();

        assert_eq!(
            format!("{}", pairs),
            "[a(0, 3, [b(1, 2)]), c(4, 5)]".to_owned()
        );
    }

    #[test]
    fn iter_for_pairs() {
        let pairs = AbcParser::parse(Rule::a, "abcde").unwrap();
        assert_eq!(
            pairs.map(|p| p.as_rule()).collect::<Vec<Rule>>(),
            vec![Rule::a, Rule::c]
        );
    }

    #[test]
    fn double_ended_iter_for_pairs() {
        let pairs = AbcParser::parse(Rule::a, "abcde").unwrap();
        assert_eq!(
            pairs.rev().map(|p| p.as_rule()).collect::<Vec<Rule>>(),
            vec![Rule::c, Rule::a]
        );
    }
}
<|endoftext|>


<commit_before>use std::fs::File;

pub fn load_sql_file( path: &str ) -> &str{

        let f =  File::open(&args[1]).unwrap();

        return " ";

}

let mut a = 5;
<commit_msg>parser<commit_after>use std::fs::File;

pub fn load_sql_file( path: &str ) -> &str{

        let f =  File::open(&args[1]).unwrap();

        return " ";

}
<|endoftext|>


<commit_before>use crate::index::index_ro;
use crates_index_diff::{Change, CrateVersion, Index};
use git_repository as git;

#[test]
fn addition() -> crate::Result {
    let changes = changes(index_ro()?, ":/initial commit")?;
    assert_eq!(changes.len(), 3228);
    assert!(matches!(
        changes
            .first()
            .and_then(|c| c.added().map(|v| v.name.as_str())),
        Some("gi-get-artifact")
    ));
    assert!(matches!(
        changes.last().expect("present"),
        Change::Added(CrateVersion {name, ..}) if name == "gizmo"
    ));
    Ok(())
}

#[test]
fn deletion() -> crate::Result {
    let changes = changes(index_ro()?, "@~^{/Updating crate `git-shell#0.3.0`}~1")?;
    assert_eq!(changes.len(), 1);
    assert_eq!(changes.first().and_then(|c| c.deleted()), Some("girl"));
    Ok(())
}

#[test]
fn new_version() -> crate::Result {
    let changes = changes(index_ro()?, ":/Updating crate `git-repository#0.22.1`")?;
    assert_eq!(changes.len(), 1);
    assert_eq!(
        changes
            .first()
            .and_then(|c| c.added().map(|v| v.name.as_str())),
        Some("git-repository")
    );
    Ok(())
}

#[test]
fn yanked() -> crate::Result {
    let changes = changes(index_ro()?, ":/Yanking crate `github_release_rs#0.1.0`")?;
    assert_eq!(changes.len(), 1);
    assert_eq!(
        changes
            .first()
            .and_then(|c| c.yanked().map(|v| v.name.as_str())),
        Some("github_release_rs")
    );
    Ok(())
}

#[test]
fn yanked_in_new_file() -> crate::Result {
    let changes = changes(index_ro()?, ":/reproduce issue #19")?;
    assert_eq!(changes.len(), 1);
    assert_eq!(
        changes
            .first()
            .and_then(|c| c.yanked().map(|v| v.name.as_str())),
        Some("allowed")
    );
    Ok(())
}

#[test]
fn unyanked_crates_recognized_as_added() -> crate::Result {
    let changes = changes(index_ro()?, ":/Unyanking crate `git2mail#0.3.2`")?;
    assert_eq!(changes.len(), 1);
    assert_eq!(
        changes
            .first()
            .and_then(|c| c.added().map(|v| v.name.as_str())),
        Some("git2mail")
    );
    Ok(())
}

#[test]
fn normalization() -> crate::Result {
    let changes = changes(index_ro()?, ":/normalize")?;
    assert_eq!(
        changes.len(),
        0,
        "normalization changes the representation, but the data itself stays the same"
    );
    Ok(())
}

fn changes(mut index: Index, revspec: &str) -> crate::Result<Vec<Change>> {
    let (prev, current) = {
        let repo = index.repository_mut();
        repo.object_cache_size_if_unset(4 * 1024 * 1024);
        let commit = repo.rev_parse(revspec)?.single().unwrap();
        let ancestor_tree = commit
            .object()?
            .into_commit()
            .parent_ids()
            .next()
            .and_then(|parent| {
                parent
                    .object()
                    .ok()?
                    .into_commit()
                    .tree_id()
                    .ok()
                    .map(|id| id.detach())
            })
            .unwrap_or_else(|| git::hash::ObjectId::empty_tree(repo.object_hash()));
        (ancestor_tree, commit.detach())
    };
    Ok(index.changes_between_commits(prev, current)?)
}
<commit_msg>fix rev-spec<commit_after>use crate::index::index_ro;
use crates_index_diff::{Change, CrateVersion, Index};
use git_repository as git;

#[test]
fn addition() -> crate::Result {
    let changes = changes(index_ro()?, ":/initial commit")?;
    assert_eq!(changes.len(), 3228);
    assert!(matches!(
        changes
            .first()
            .and_then(|c| c.added().map(|v| v.name.as_str())),
        Some("gi-get-artifact")
    ));
    assert!(matches!(
        changes.last().expect("present"),
        Change::Added(CrateVersion {name, ..}) if name == "gizmo"
    ));
    Ok(())
}

#[test]
fn deletion() -> crate::Result {
    let changes = changes(index_ro()?, "@^{/Updating crate `git-shell#0.3.0`}~1")?;
    assert_eq!(changes.len(), 1);
    assert_eq!(changes.first().and_then(|c| c.deleted()), Some("girl"));
    Ok(())
}

#[test]
fn new_version() -> crate::Result {
    let changes = changes(index_ro()?, ":/Updating crate `git-repository#0.22.1`")?;
    assert_eq!(changes.len(), 1);
    assert_eq!(
        changes
            .first()
            .and_then(|c| c.added().map(|v| v.name.as_str())),
        Some("git-repository")
    );
    Ok(())
}

#[test]
fn yanked() -> crate::Result {
    let changes = changes(index_ro()?, ":/Yanking crate `github_release_rs#0.1.0`")?;
    assert_eq!(changes.len(), 1);
    assert_eq!(
        changes
            .first()
            .and_then(|c| c.yanked().map(|v| v.name.as_str())),
        Some("github_release_rs")
    );
    Ok(())
}

#[test]
fn yanked_in_new_file() -> crate::Result {
    let changes = changes(index_ro()?, ":/reproduce issue #19")?;
    assert_eq!(changes.len(), 1);
    assert_eq!(
        changes
            .first()
            .and_then(|c| c.yanked().map(|v| v.name.as_str())),
        Some("allowed")
    );
    Ok(())
}

#[test]
fn unyanked_crates_recognized_as_added() -> crate::Result {
    let changes = changes(index_ro()?, ":/Unyanking crate `git2mail#0.3.2`")?;
    assert_eq!(changes.len(), 1);
    assert_eq!(
        changes
            .first()
            .and_then(|c| c.added().map(|v| v.name.as_str())),
        Some("git2mail")
    );
    Ok(())
}

#[test]
fn normalization() -> crate::Result {
    let changes = changes(index_ro()?, ":/normalize")?;
    assert_eq!(
        changes.len(),
        0,
        "normalization changes the representation, but the data itself stays the same"
    );
    Ok(())
}

fn changes(mut index: Index, revspec: &str) -> crate::Result<Vec<Change>> {
    let (prev, current) = {
        let repo = index.repository_mut();
        repo.object_cache_size_if_unset(4 * 1024 * 1024);
        let commit = repo.rev_parse(revspec)?.single().unwrap();
        let ancestor_tree = commit
            .object()?
            .into_commit()
            .parent_ids()
            .next()
            .and_then(|parent| {
                parent
                    .object()
                    .ok()?
                    .into_commit()
                    .tree_id()
                    .ok()
                    .map(|id| id.detach())
            })
            .unwrap_or_else(|| git::hash::ObjectId::empty_tree(repo.object_hash()));
        (ancestor_tree, commit.detach())
    };
    Ok(index.changes_between_commits(prev, current)?)
}
<|endoftext|>


<commit_before>///! Process syscalls

use core::mem;
use core::str;

use arch;
use arch::memory::allocate_frame;
use arch::paging::{ActivePageTable, InactivePageTable, Page, VirtualAddress, entry};
use arch::paging::temporary_page::TemporaryPage;
use context;
use elf;
use scheme;
use syscall::{self, Error, Result};

pub fn brk(address: usize) -> Result<usize> {
    let contexts = context::contexts();
    let context_lock = contexts.current().ok_or(Error::NoProcess)?;
    let mut context = context_lock.write();

    let mut current = arch::USER_HEAP_OFFSET;
    if let Some(ref heap) = context.heap {
        current = heap.start_address().get() + heap.size();
    }
    if address == 0 {
        //println!("Brk query {:X}", current);
        Ok(current)
    } else if address >= arch::USER_HEAP_OFFSET {
        //TODO: out of memory errors
        if let Some(ref mut heap) = context.heap {
            heap.resize(address - arch::USER_HEAP_OFFSET, true, true);
            return Ok(address);
        }

        context.heap = Some(context::memory::Memory::new(
            VirtualAddress::new(arch::USER_HEAP_OFFSET),
            address - arch::USER_HEAP_OFFSET,
            entry::WRITABLE | entry::NO_EXECUTE | entry::USER_ACCESSIBLE,
            true,
            true
        ));

        Ok(address)
    } else {
        //TODO: Return correct error
        Err(Error::NotPermitted)
    }
}

pub fn clone(flags: usize, stack_base: usize) -> Result<usize> {
    //TODO: Implement flags
    //TODO: Copy on write?
    println!("Clone {:X}: {:X}", flags, stack_base);

    let pid;
    {
        let arch;
        let mut kstack_option = None;
        let mut offset = 0;
        let mut image = vec![];
        let mut heap_option = None;
        let mut stack_option = None;
        let mut files = vec![];

        // Copy from old process
        {
            let contexts = context::contexts();
            let context_lock = contexts.current().ok_or(Error::NoProcess)?;
            let context = context_lock.read();
            arch = context.arch.clone();

            if let Some(ref stack) = context.kstack {
                offset = stack_base - stack.as_ptr() as usize - mem::size_of::<usize>(); // Add clone ret
                let mut new_stack = stack.clone();
                unsafe {
                    let func_ptr = new_stack.as_mut_ptr().offset(offset as isize);
                    *(func_ptr as *mut usize) = arch::interrupt::syscall::clone_ret as usize;
                }
                kstack_option = Some(new_stack);
            }

            for memory in context.image.iter() {
                let mut new_memory = context::memory::Memory::new(
                    VirtualAddress::new(memory.start_address().get() + arch::USER_TMP_OFFSET),
                    memory.size(),
                    entry::PRESENT | entry::NO_EXECUTE | entry::WRITABLE,
                    true,
                    false
                );
                unsafe {
                    arch::externs::memcpy(new_memory.start_address().get() as *mut u8,
                                          memory.start_address().get() as *const u8,
                                          memory.size());
                }
                new_memory.remap(memory.flags(), true);
                image.push(new_memory);
            }

            if let Some(ref heap) = context.heap {
                let mut new_heap = context::memory::Memory::new(
                    VirtualAddress::new(arch::USER_TMP_HEAP_OFFSET),
                    heap.size(),
                    entry::PRESENT | entry::NO_EXECUTE | entry::WRITABLE,
                    true,
                    false
                );
                unsafe {
                    arch::externs::memcpy(new_heap.start_address().get() as *mut u8,
                                          heap.start_address().get() as *const u8,
                                          heap.size());
                }
                new_heap.remap(heap.flags(), true);
                heap_option = Some(new_heap);
            }

            if let Some(ref stack) = context.stack {
                let mut new_stack = context::memory::Memory::new(
                    VirtualAddress::new(arch::USER_TMP_STACK_OFFSET),
                    stack.size(),
                    entry::PRESENT | entry::NO_EXECUTE | entry::WRITABLE,
                    true,
                    false
                );
                unsafe {
                    arch::externs::memcpy(new_stack.start_address().get() as *mut u8,
                                          stack.start_address().get() as *const u8,
                                          stack.size());
                }
                new_stack.remap(stack.flags(), true);
                stack_option = Some(new_stack);
            }

            for (fd, file_option) in context.files.iter().enumerate() {
                if let Some(file) = *file_option {
                    let result = {
                        let schemes = scheme::schemes();
                        let scheme_mutex = schemes.get(file.scheme).ok_or(Error::BadFile)?;
                        let result = scheme_mutex.lock().dup(file.number);
                        result
                    };
                    match result {
                        Ok(new_number) => {
                            files.push(Some(context::file::File { scheme: file.scheme, number: new_number }));
                        },
                        Err(err) => {
                            println!("clone: failed to dup {}: {:?}", fd, err);
                        }
                    }
                } else {
                    files.push(None);
                }
            }
        }

        // Set up new process
        {
            let mut contexts = context::contexts_mut();
            let context_lock = contexts.new_context()?;
            let mut context = context_lock.write();

            pid = context.id;

            context.arch = arch;

            let mut active_table = unsafe { ActivePageTable::new() };

            let mut temporary_page = TemporaryPage::new(Page::containing_address(VirtualAddress::new(0x8_0000_0000)));

            let mut new_table = {
                let frame = allocate_frame().expect("no more frames in syscall::clone new_table");
                InactivePageTable::new(frame, &mut active_table, &mut temporary_page)
            };

            // Copy kernel mapping
            {
                let kernel_frame = active_table.p4()[510].pointed_frame().expect("kernel table not mapped");
                active_table.with(&mut new_table, &mut temporary_page, |mapper| {
                    mapper.p4_mut()[510].set(kernel_frame, entry::PRESENT | entry::WRITABLE);
                });
            }

            // Copy percpu mapping
            {
                extern {
                    /// The starting byte of the thread data segment
                    static mut __tdata_start: u8;
                    /// The ending byte of the thread BSS segment
                    static mut __tbss_end: u8;
                }

                let size = unsafe { & __tbss_end as *const _ as usize - & __tdata_start as *const _ as usize };

                let start = arch::KERNEL_PERCPU_OFFSET + arch::KERNEL_PERCPU_SIZE * ::cpu_id();
                let end = start + size;

                let start_page = Page::containing_address(VirtualAddress::new(start));
                let end_page = Page::containing_address(VirtualAddress::new(end - 1));
                for page in Page::range_inclusive(start_page, end_page) {
                    let frame = active_table.translate_page(page).expect("kernel percpu not mapped");
                    active_table.with(&mut new_table, &mut temporary_page, |mapper| {
                        mapper.map_to(page, frame, entry::PRESENT | entry::NO_EXECUTE | entry::WRITABLE);
                    });
                }
            }

            if let Some(stack) = kstack_option.take() {
                context.arch.set_stack(stack.as_ptr() as usize + offset);
                context.kstack = Some(stack);
            }

            for memory in image.iter_mut() {
                let start = VirtualAddress::new(memory.start_address().get() - arch::USER_TMP_OFFSET + arch::USER_OFFSET);
                memory.move_to(start, &mut new_table, &mut temporary_page, true);
            }
            context.image = image;

            if let Some(mut heap) = heap_option.take() {
                heap.move_to(VirtualAddress::new(arch::USER_HEAP_OFFSET), &mut new_table, &mut temporary_page, true);
                context.heap = Some(heap);
            }

            if let Some(mut stack) = stack_option.take() {
                stack.move_to(VirtualAddress::new(arch::USER_STACK_OFFSET), &mut new_table, &mut temporary_page, true);
                context.stack = Some(stack);
            }

            context.files = files;

            context.arch.set_page_table(unsafe { new_table.address() });

            context.status = context::Status::Runnable;
        }
    }

    unsafe { context::switch(); }

    Ok(pid)
}

pub fn exit(status: usize) -> ! {
    println!("Exit {}", status);

    {
        let contexts = context::contexts();
        let context_lock = contexts.current().expect("tried to exit without context");
        let mut context = context_lock.write();
        context.image.clear();
        drop(context.heap.take());
        drop(context.stack.take());
        context.status = context::Status::Exited;
    }

    unsafe { context::switch(); }

    unreachable!();
}

pub fn exec(path: &[u8], _args: &[[usize; 2]]) -> Result<usize> {
    //TODO: Use args
    //TODO: Unmap previous mappings
    //TODO: Drop data vec
    println!("Exec {}", unsafe { str::from_utf8_unchecked(path) });

    let file = syscall::open(path, 0)?;
    let mut data = vec![];
    loop {
        let mut buf = [0; 4096];
        let count = syscall::read(file, &mut buf)?;
        if count > 0 {
            data.extend_from_slice(&buf[..count]);
        } else {
            break;
        }
    }
    let _ = syscall::close(file);

    match elf::Elf::from(&data) {
        Ok(elf) => {
            elf.run().and(Ok(0))
        },
        Err(err) => {
            println!("failed to execute {}: {}", unsafe { str::from_utf8_unchecked(path) }, err);
            Err(Error::NoExec)
        }
    }
}

pub fn getpid() -> Result<usize> {
    let contexts = context::contexts();
    let context_lock = contexts.current().ok_or(Error::NoProcess)?;
    let context = context_lock.read();
    Ok(context.id)
}

pub fn iopl(_level: usize) -> Result<usize> {
    //TODO
    Ok(0)
}

pub fn sched_yield() -> Result<usize> {
    unsafe { context::switch(); }
    Ok(0)
}
<commit_msg>Panic upon use of unsupported flags<commit_after>///! Process syscalls

use core::mem;
use core::str;

use arch;
use arch::memory::allocate_frame;
use arch::paging::{ActivePageTable, InactivePageTable, Page, VirtualAddress, entry};
use arch::paging::temporary_page::TemporaryPage;
use context;
use elf;
use scheme;
use syscall::{self, Error, Result};

pub fn brk(address: usize) -> Result<usize> {
    let contexts = context::contexts();
    let context_lock = contexts.current().ok_or(Error::NoProcess)?;
    let mut context = context_lock.write();

    let mut current = arch::USER_HEAP_OFFSET;
    if let Some(ref heap) = context.heap {
        current = heap.start_address().get() + heap.size();
    }
    if address == 0 {
        //println!("Brk query {:X}", current);
        Ok(current)
    } else if address >= arch::USER_HEAP_OFFSET {
        //TODO: out of memory errors
        if let Some(ref mut heap) = context.heap {
            heap.resize(address - arch::USER_HEAP_OFFSET, true, true);
            return Ok(address);
        }

        context.heap = Some(context::memory::Memory::new(
            VirtualAddress::new(arch::USER_HEAP_OFFSET),
            address - arch::USER_HEAP_OFFSET,
            entry::WRITABLE | entry::NO_EXECUTE | entry::USER_ACCESSIBLE,
            true,
            true
        ));

        Ok(address)
    } else {
        //TODO: Return correct error
        Err(Error::NotPermitted)
    }
}

pub const CLONE_VM: usize = 0x100;
pub const CLONE_FS: usize = 0x200;
pub const CLONE_FILES: usize = 0x400;
pub const CLONE_VFORK: usize = 0x4000;
pub fn clone(flags: usize, stack_base: usize) -> Result<usize> {
    //TODO: Implement flags
    //TODO: Copy on write?
    println!("Clone {:X}: {:X}", flags, stack_base);

    let pid;
    {
        let arch;
        let mut kstack_option = None;
        let mut offset = 0;
        let mut image = vec![];
        let mut heap_option = None;
        let mut stack_option = None;
        let mut files = vec![];

        // Copy from old process
        {
            let contexts = context::contexts();
            let context_lock = contexts.current().ok_or(Error::NoProcess)?;
            let context = context_lock.read();
            arch = context.arch.clone();

            if let Some(ref stack) = context.kstack {
                offset = stack_base - stack.as_ptr() as usize - mem::size_of::<usize>(); // Add clone ret
                let mut new_stack = stack.clone();
                unsafe {
                    let func_ptr = new_stack.as_mut_ptr().offset(offset as isize);
                    *(func_ptr as *mut usize) = arch::interrupt::syscall::clone_ret as usize;
                }
                kstack_option = Some(new_stack);
            }

            if flags & CLONE_VM == CLONE_VM {
                panic!("unimplemented: CLONE_VM");
            } else {
                for memory in context.image.iter() {
                    let mut new_memory = context::memory::Memory::new(
                        VirtualAddress::new(memory.start_address().get() + arch::USER_TMP_OFFSET),
                        memory.size(),
                        entry::PRESENT | entry::NO_EXECUTE | entry::WRITABLE,
                        true,
                        false
                    );
                    unsafe {
                        arch::externs::memcpy(new_memory.start_address().get() as *mut u8,
                                              memory.start_address().get() as *const u8,
                                              memory.size());
                    }
                    new_memory.remap(memory.flags(), true);
                    image.push(new_memory);
                }

                if let Some(ref heap) = context.heap {
                    let mut new_heap = context::memory::Memory::new(
                        VirtualAddress::new(arch::USER_TMP_HEAP_OFFSET),
                        heap.size(),
                        entry::PRESENT | entry::NO_EXECUTE | entry::WRITABLE,
                        true,
                        false
                    );
                    unsafe {
                        arch::externs::memcpy(new_heap.start_address().get() as *mut u8,
                                              heap.start_address().get() as *const u8,
                                              heap.size());
                    }
                    new_heap.remap(heap.flags(), true);
                    heap_option = Some(new_heap);
                }
            }

            if let Some(ref stack) = context.stack {
                let mut new_stack = context::memory::Memory::new(
                    VirtualAddress::new(arch::USER_TMP_STACK_OFFSET),
                    stack.size(),
                    entry::PRESENT | entry::NO_EXECUTE | entry::WRITABLE,
                    true,
                    false
                );
                unsafe {
                    arch::externs::memcpy(new_stack.start_address().get() as *mut u8,
                                          stack.start_address().get() as *const u8,
                                          stack.size());
                }
                new_stack.remap(stack.flags(), true);
                stack_option = Some(new_stack);
            }

            if flags & CLONE_FILES == CLONE_FILES {
                panic!("unimplemented: CLONE_FILES");
            } else {
                for (fd, file_option) in context.files.iter().enumerate() {
                    if let Some(file) = *file_option {
                        let result = {
                            let schemes = scheme::schemes();
                            let scheme_mutex = schemes.get(file.scheme).ok_or(Error::BadFile)?;
                            let result = scheme_mutex.lock().dup(file.number);
                            result
                        };
                        match result {
                            Ok(new_number) => {
                                files.push(Some(context::file::File { scheme: file.scheme, number: new_number }));
                            },
                            Err(err) => {
                                println!("clone: failed to dup {}: {:?}", fd, err);
                            }
                        }
                    } else {
                        files.push(None);
                    }
                }
            }
        }

        // Set up new process
        {
            let mut contexts = context::contexts_mut();
            let context_lock = contexts.new_context()?;
            let mut context = context_lock.write();

            pid = context.id;

            context.arch = arch;

            let mut active_table = unsafe { ActivePageTable::new() };

            let mut temporary_page = TemporaryPage::new(Page::containing_address(VirtualAddress::new(0x8_0000_0000)));

            let mut new_table = {
                let frame = allocate_frame().expect("no more frames in syscall::clone new_table");
                InactivePageTable::new(frame, &mut active_table, &mut temporary_page)
            };

            // Copy kernel mapping
            {
                let kernel_frame = active_table.p4()[510].pointed_frame().expect("kernel table not mapped");
                active_table.with(&mut new_table, &mut temporary_page, |mapper| {
                    mapper.p4_mut()[510].set(kernel_frame, entry::PRESENT | entry::WRITABLE);
                });
            }

            // Copy percpu mapping
            {
                extern {
                    /// The starting byte of the thread data segment
                    static mut __tdata_start: u8;
                    /// The ending byte of the thread BSS segment
                    static mut __tbss_end: u8;
                }

                let size = unsafe { & __tbss_end as *const _ as usize - & __tdata_start as *const _ as usize };

                let start = arch::KERNEL_PERCPU_OFFSET + arch::KERNEL_PERCPU_SIZE * ::cpu_id();
                let end = start + size;

                let start_page = Page::containing_address(VirtualAddress::new(start));
                let end_page = Page::containing_address(VirtualAddress::new(end - 1));
                for page in Page::range_inclusive(start_page, end_page) {
                    let frame = active_table.translate_page(page).expect("kernel percpu not mapped");
                    active_table.with(&mut new_table, &mut temporary_page, |mapper| {
                        mapper.map_to(page, frame, entry::PRESENT | entry::NO_EXECUTE | entry::WRITABLE);
                    });
                }
            }

            if let Some(stack) = kstack_option.take() {
                context.arch.set_stack(stack.as_ptr() as usize + offset);
                context.kstack = Some(stack);
            }

            for memory in image.iter_mut() {
                let start = VirtualAddress::new(memory.start_address().get() - arch::USER_TMP_OFFSET + arch::USER_OFFSET);
                memory.move_to(start, &mut new_table, &mut temporary_page, true);
            }
            context.image = image;

            if let Some(mut heap) = heap_option.take() {
                heap.move_to(VirtualAddress::new(arch::USER_HEAP_OFFSET), &mut new_table, &mut temporary_page, true);
                context.heap = Some(heap);
            }

            if let Some(mut stack) = stack_option.take() {
                stack.move_to(VirtualAddress::new(arch::USER_STACK_OFFSET), &mut new_table, &mut temporary_page, true);
                context.stack = Some(stack);
            }

            context.files = files;

            context.arch.set_page_table(unsafe { new_table.address() });

            context.status = context::Status::Runnable;
        }
    }

    unsafe { context::switch(); }

    Ok(pid)
}

pub fn exit(status: usize) -> ! {
    println!("Exit {}", status);

    {
        let contexts = context::contexts();
        let context_lock = contexts.current().expect("tried to exit without context");
        let mut context = context_lock.write();
        context.image.clear();
        drop(context.heap.take());
        drop(context.stack.take());
        context.status = context::Status::Exited;
    }

    unsafe { context::switch(); }

    unreachable!();
}

pub fn exec(path: &[u8], _args: &[[usize; 2]]) -> Result<usize> {
    //TODO: Use args
    //TODO: Unmap previous mappings
    //TODO: Drop data vec
    println!("Exec {}", unsafe { str::from_utf8_unchecked(path) });

    let file = syscall::open(path, 0)?;
    let mut data = vec![];
    loop {
        let mut buf = [0; 4096];
        let count = syscall::read(file, &mut buf)?;
        if count > 0 {
            data.extend_from_slice(&buf[..count]);
        } else {
            break;
        }
    }
    let _ = syscall::close(file);

    match elf::Elf::from(&data) {
        Ok(elf) => {
            elf.run().and(Ok(0))
        },
        Err(err) => {
            println!("failed to execute {}: {}", unsafe { str::from_utf8_unchecked(path) }, err);
            Err(Error::NoExec)
        }
    }
}

pub fn getpid() -> Result<usize> {
    let contexts = context::contexts();
    let context_lock = contexts.current().ok_or(Error::NoProcess)?;
    let context = context_lock.read();
    Ok(context.id)
}

pub fn iopl(_level: usize) -> Result<usize> {
    //TODO
    Ok(0)
}

pub fn sched_yield() -> Result<usize> {
    unsafe { context::switch(); }
    Ok(0)
}
<|endoftext|>


<commit_before>use llvm_sys::execution_engine::*;
use super::*;
use std::mem;

pub struct ExecutionEngine {
    pub ptr: LLVMExecutionEngineRef,
}

impl ExecutionEngine {
    pub fn create_for_module(module: Module) -> Result<ExecutionEngine, &'static str> {
        unsafe {
            let mut ee = mem::uninitialized();
            let mut out = mem::zeroed();

            let res = LLVMCreateExecutionEngineForModule(&mut ee, module.ptr, &mut out);

            if res == 0 { // no error message was set
                Ok(ExecutionEngine{
                    ptr: ee
                })
            } else {
                Err(c_str_to_str!(out as *const i8))
            }
        }
    }

    pub fn get_function_address(&self, fname: &str) -> Option<extern "C" fn()> {
        let fname_s = CString::new(fname).unwrap();
        unsafe {
            let addr = LLVMGetFunctionAddress(self.ptr, fname_s.as_ptr());

            if addr == 0 {
                None
            } else {
                Some(mem::transmute(addr))
            }
        }
    }
}

impl Drop for ExecutionEngine {
    fn drop(&mut self) {
        unsafe {
            LLVMDisposeExecutionEngine(self.ptr);
        }
    }
}

pub fn link_in_mcjit() {
    unsafe {
        LLVMLinkInMCJIT();
    }
}
<commit_msg>ExecEngine create_for_module take a reference<commit_after>use llvm_sys::execution_engine::*;
use super::*;
use std::mem;

pub struct ExecutionEngine {
    pub ptr: LLVMExecutionEngineRef,
}

impl ExecutionEngine {
    pub fn create_for_module(module: &Module) -> Result<ExecutionEngine, &'static str> {
        unsafe {
            let mut ee = mem::uninitialized();
            let mut out = mem::zeroed();

            let res = LLVMCreateExecutionEngineForModule(&mut ee, module.ptr, &mut out);

            if res == 0 { // no error message was set
                Ok(ExecutionEngine{
                    ptr: ee
                })
            } else {
                Err(c_str_to_str!(out as *const i8))
            }
        }
    }

    pub fn get_function_address(&self, fname: &str) -> Option<extern "C" fn()> {
        let fname_s = CString::new(fname).unwrap();
        unsafe {
            let addr = LLVMGetFunctionAddress(self.ptr, fname_s.as_ptr());

            if addr == 0 {
                None
            } else {
                Some(mem::transmute(addr))
            }
        }
    }
}

impl Drop for ExecutionEngine {
    fn drop(&mut self) {
        unsafe {
            LLVMDisposeExecutionEngine(self.ptr);
        }
    }
}

pub fn link_in_mcjit() {
    unsafe {
        LLVMLinkInMCJIT();
    }
}
<|endoftext|>


<commit_before>#![feature(str_split_at)]
#![feature(convert)]

extern crate gr;
use gr::*;

enum OpType {
    Func(String),
    Const(usize),
    Var(usize),
    UVar(usize),
    Op(String),
    Pow(i32)
}

struct FuncObj {
    user_vars: Vec<GI>,
    constants: Vec<GI>,
    instructions: Vec<OpType>,
    switched: bool,
    func: Box<fn(&Vec<GI>) -> GI>
}

fn dummy(_x: &Vec<GI>) -> GI {
    GI::new_c("1.0")
}

impl FuncObj {
    pub fn call(&self, _x: &Vec<GI>) -> GI {
        if self.switched {
            func(_x)
        }
        else {
            self.interpreted(_x)
        }
    }

    fn interpreted(&self, _x: &Vec<GI>) -> GI {
        let mut stack: Vec<GI> = Vec::new();
        for inst in &self.instructions {
            match inst {
                &OpType::Func(ref s) => {
                    let op = stack.pop().unwrap();
                    let result = match s.as_str() {
                        "abs" => abs(op),
                        "sin" => sin(op),
                        "cos" => cos(op),
                        "tan" => tan(op),
                        "exp" => exp(op),
                        "log" => log(op),
                        "neg" => -op,
                        _     => unreachable!()
                    };
                    stack.push(result);
                },
                &OpType::Const(i) => {
                    stack.push(self.constants[i]);
                },
                &OpType::Var(i) => {
                    stack.push(_x[i]);
                },
                &OpType::UVar(i) => {
                    stack.push(self.user_vars[i]);
                },
                &OpType::Op(ref s) => {
                    let right = stack.pop().unwrap();
                    let left = stack.pop().unwrap();
                    let result = match s.as_str() {
                        "+" => left + right,
                        "-" => left - right,
                        "*" => left * right,
                        "/" => left / right,
                        "p" => powi(left, right),
                        _   => unreachable!()
                    };
                    stack.push(result);
                },
                &OpType::Pow(exp) => {
                    let arg = stack.pop().unwrap();
                    stack.push(gr::pow(arg, exp));
                }
            }
        }
        stack[0]
    }

    fn new(consts: &Vec<GI>, instructions: &String) -> FuncObj {
        let mut insts = vec![];

        for inst in instructions.split(',') {
            let dummy = inst.trim().to_string();
            let (first, rest) = dummy.split_at(1);
            insts.push(match first {
                "c" => OpType::Const(rest.to_string().parse::<usize>().unwrap()),
                "i" => OpType::Var(rest.to_string().parse::<usize>().unwrap()),
                "v" => OpType::UVar(rest.to_string().parse::<usize>().unwrap()),
                "o" => OpType::Op(rest.to_string()),
                "f" => OpType::Func(rest.to_string()),
                "p" => OpType::Pow(rest.to_string().parse::<i32>().unwrap()),
                _   => panic!()
            });
        }

        FuncObj{user_vars: vec![],
                constants: consts.clone(),
                instructions: insts,
                switched: false,
                func: Box::new(dummy)}
    }
}

#[test]
fn test1() {
    let constants = vec![GI::new_c("1"), GI::new_c("2"), GI::new_c("3")];
    let f = FuncObj::new(&constants,
                         &"c0,c1,o-,c2,o+".to_string());
    let expected = ((GI::new_c("1") - GI::new_c("2")) + GI::new_c("3")).to_string();
    assert!(f.call(&vec![]).to_string() == expected);
}

#[test]
fn test2() {
    let consts = vec![GI::new_c("1"), GI::new_c("2"), GI::new_c("3")];
    let f = FuncObj::new(&consts,
                         &"c0,fsin,c1,o*,fcos,c2,o/".to_string());
    let expected = cos(sin(consts[0]) * consts[1])/consts[2];
    assert!(f.call(&vec![]).to_string() == expected.to_string());
}

#[test]
fn sum_inputs() {
    let consts = vec![];
    let v = vec![GI::new_d(1.0, 1.0), GI::new_d(1.0, 2.0), GI::new_d(1.0, 3.0),
                 GI::new_d(1.0, 4.0), GI::new_d(1.0, 5.0), GI::new_d(1.0, 6.0)];
    let f = FuncObj::new(&consts,
                         &"i0,i1, o+, i2, o+, i3, o+, i4, o+, i5, o+".to_string());
    let expected = (v[0] + v[1] + v[2] + v[3] + v[4] + v[5]).to_string();
    let real = f.call(&v).to_string();
    assert!(real == expected, "real = {}, expected = {}", real, expected);
}

#[test]
fn test3() {
    let consts = vec![GI::new_c("0.1")];
    let v = vec![];
    let f = FuncObj::new(&consts,
                &"c0, fsin".to_string());
    let expected = sin(consts[0]).to_string();
    let real = f.call(&v).to_string();
    assert!(real == expected, "real = {}, expected = {}", real, expected);
}

#[test]
fn test4() {
    let consts = vec![GI::new_c("[-3, 4]")];
    let v = vec![];
    let f = FuncObj::new(&consts,
                &"c0, fabs".to_string());
    let expected = abs(consts[0]).to_string();
    let real = f.call(&v).to_string();
    assert!(real == expected, "real = {}, expected = {}", real, expected);
}

#[test]
fn test5() {
    let consts = vec![GI::new_c("[-3, 4]")];
    let v = vec![];
    let f = FuncObj::new(&consts,
                &"c0, fcos".to_string());
    let expected = cos(consts[0]).to_string();
    let real = f.call(&v).to_string();
    assert!(real == expected, "real = {}, expected = {}", real, expected);
}

#[test]
fn test6() {
    let consts = vec![GI::new_c("[-3, 4]")];
    let v = vec![];
    let f = FuncObj::new(&consts,
                &"c0, ftan".to_string());
    let expected = tan(consts[0]).to_string();
    let real = f.call(&v).to_string();
    assert!(real == expected, "real = {}, expected = {}", real, expected);
}

#[test]
fn test7() {
    let consts = vec![GI::new_c("[-3, 4]")];
    let v = vec![];
    let f = FuncObj::new(&consts,
                &"c0, fexp".to_string());
    let expected = exp(consts[0]).to_string();
    let real = f.call(&v).to_string();
    assert!(real == expected, "real = {}, expected = {}", real, expected);
}

#[test]
fn test8() {
    let consts = vec![GI::new_c("[-3, 4]")];
    let v = vec![];
    let f = FuncObj::new(&consts,
                &"c0, fneg".to_string());
    let expected = (-consts[0]).to_string();
    let real = f.call(&v).to_string();
    assert!(real == expected, "real = {}, expected = {}", real, expected);
}

#[test]
fn test9() {
    let consts = vec![GI::new_c("[0.1, .2]")];
    let v = vec![];
    let f = FuncObj::new(&consts,
                &"c0, flog".to_string());
    let expected = log(consts[0]).to_string();
    let real = f.call(&v).to_string();
    assert!(real == expected, "real = {}, expected = {}", real, expected);
}
#[test]
fn test10() {
    let consts = vec![GI::new_c("[2.0, 3.0]"),
                      GI::new_c("[1.5, 2.5]")];
    let v = vec![];
    let f = FuncObj::new(&consts,
                         &"c0, c1, op".to_string());
    let expected = powi(consts[0], consts[1]).to_string();
    let real = f.call(&v).to_string();
    assert!(real == expected, "real = {}, expected = {}", real, expected);
}
#[test]
fn test_power() {
    let consts = vec![GI::new_c("[2.0, 3.0]"),
                      GI::new_c("[1.5, 2.5]")];
    let v = vec![];
    let f = FuncObj::new(&consts,
                         &"c0, p-1, c1, p2, o+".to_string());
    let expected = (pow(consts[0], -1) + pow(consts[1], 2)).to_string();
    let real = f.call(&v).to_string();
    assert!(real == expected, "real = {}, expected = {}", real, expected);
}
<commit_msg>I knew inplace functions could be useful<commit_after>#![feature(str_split_at)]
#![feature(convert)]

extern crate gr;
use gr::*;

use std::sync::atomic::{AtomicBool, Ordering};

enum OpType {
    Func(String),
    Const(usize),
    Var(usize),
    UVar(usize),
    Op(String),
    Pow(i32)
}

struct FuncObj {
    user_vars: Vec<GI>,
    constants: Vec<GI>,
    instructions: Vec<OpType>,
    switched: AtomicBool,
    func: Box<fn(&Vec<GI>) -> GI>
}

fn dummy(_x: &Vec<GI>) -> GI {
    GI::new_c("1.0")
}

impl FuncObj {
    pub fn call(&self, _x: &Vec<GI>) -> GI {
        if self.switched.load(Ordering::SeqCst) {
            func(_x)
        }
        else {
            self.interpreted(_x)
        }
    }

    fn interpreted(&self, _x: &Vec<GI>) -> GI {
        let mut stack: Vec<GI> = Vec::new();
        for inst in &self.instructions {
            match inst {
                &OpType::Func(ref s) => {
                    let op = stack.last_mut().unwrap();
                    match s.as_str() {
                        "abs" => op.abs(),
                        "sin" => op.sin(),
                        "cos" => op.cos(),
                        "tan" => op.tan(),
                        "exp" => op.exp(),
                        "log" => op.log(),
                        "neg" => op.neg(),
                        _     => unreachable!()
                    };
                },
                &OpType::Const(i) => {
                    stack.push(self.constants[i]);
                },
                &OpType::Var(i) => {
                    stack.push(_x[i]);
                },
                &OpType::UVar(i) => {
                    stack.push(self.user_vars[i]);
                },
                &OpType::Op(ref s) => {
                    let right = stack.pop().unwrap();
                    let left = stack.last_mut().unwrap();
                    match s.as_str() {
                        "+" => left.add(right),
                        "-" => left.sub(right),
                        "*" => left.mul(right),
                        "/" => left.div(right),
                        "p" => left.powi(right),
                        _   => unreachable!()
                    };
                },
                &OpType::Pow(exp) => {
                    let arg = stack.last_mut().unwrap();
                    arg.pow(exp);
                }
            }
        }
        stack[0]
    }

    fn new(consts: &Vec<GI>, instructions: &String) -> FuncObj {
        let mut insts = vec![];

        for inst in instructions.split(',') {
            let dummy = inst.trim().to_string();
            let (first, rest) = dummy.split_at(1);
            insts.push(match first {
                "c" => OpType::Const(rest.to_string().parse::<usize>().unwrap()),
                "i" => OpType::Var(rest.to_string().parse::<usize>().unwrap()),
                "v" => OpType::UVar(rest.to_string().parse::<usize>().unwrap()),
                "o" => OpType::Op(rest.to_string()),
                "f" => OpType::Func(rest.to_string()),
                "p" => OpType::Pow(rest.to_string().parse::<i32>().unwrap()),
                _   => panic!()
            });
        }

        FuncObj{user_vars: vec![],
                constants: consts.clone(),
                instructions: insts,
                switched: AtomicBool::new(false),
                func: Box::new(dummy)}
    }
}

#[test]
fn test1() {
    let constants = vec![GI::new_c("1"), GI::new_c("2"), GI::new_c("3")];
    let f = FuncObj::new(&constants,
                         &"c0,c1,o-,c2,o+".to_string());
    let expected = ((GI::new_c("1") - GI::new_c("2")) + GI::new_c("3")).to_string();
    assert!(f.call(&vec![]).to_string() == expected);
}

#[test]
fn test2() {
    let consts = vec![GI::new_c("1"), GI::new_c("2"), GI::new_c("3")];
    let f = FuncObj::new(&consts,
                         &"c0,fsin,c1,o*,fcos,c2,o/".to_string());
    let expected = cos(sin(consts[0]) * consts[1])/consts[2];
    assert!(f.call(&vec![]).to_string() == expected.to_string());
}

#[test]
fn sum_inputs() {
    let consts = vec![];
    let v = vec![GI::new_d(1.0, 1.0), GI::new_d(1.0, 2.0), GI::new_d(1.0, 3.0),
                 GI::new_d(1.0, 4.0), GI::new_d(1.0, 5.0), GI::new_d(1.0, 6.0)];
    let f = FuncObj::new(&consts,
                         &"i0,i1, o+, i2, o+, i3, o+, i4, o+, i5, o+".to_string());
    let expected = (v[0] + v[1] + v[2] + v[3] + v[4] + v[5]).to_string();
    let real = f.call(&v).to_string();
    assert!(real == expected, "real = {}, expected = {}", real, expected);
}

#[test]
fn test3() {
    let consts = vec![GI::new_c("0.1")];
    let v = vec![];
    let f = FuncObj::new(&consts,
                &"c0, fsin".to_string());
    let expected = sin(consts[0]).to_string();
    let real = f.call(&v).to_string();
    assert!(real == expected, "real = {}, expected = {}", real, expected);
}

#[test]
fn test4() {
    let consts = vec![GI::new_c("[-3, 4]")];
    let v = vec![];
    let f = FuncObj::new(&consts,
                &"c0, fabs".to_string());
    let expected = abs(consts[0]).to_string();
    let real = f.call(&v).to_string();
    assert!(real == expected, "real = {}, expected = {}", real, expected);
}

#[test]
fn test5() {
    let consts = vec![GI::new_c("[-3, 4]")];
    let v = vec![];
    let f = FuncObj::new(&consts,
                &"c0, fcos".to_string());
    let expected = cos(consts[0]).to_string();
    let real = f.call(&v).to_string();
    assert!(real == expected, "real = {}, expected = {}", real, expected);
}

#[test]
fn test6() {
    let consts = vec![GI::new_c("[-3, 4]")];
    let v = vec![];
    let f = FuncObj::new(&consts,
                &"c0, ftan".to_string());
    let expected = tan(consts[0]).to_string();
    let real = f.call(&v).to_string();
    assert!(real == expected, "real = {}, expected = {}", real, expected);
}

#[test]
fn test7() {
    let consts = vec![GI::new_c("[-3, 4]")];
    let v = vec![];
    let f = FuncObj::new(&consts,
                &"c0, fexp".to_string());
    let expected = exp(consts[0]).to_string();
    let real = f.call(&v).to_string();
    assert!(real == expected, "real = {}, expected = {}", real, expected);
}

#[test]
fn test8() {
    let consts = vec![GI::new_c("[-3, 4]")];
    let v = vec![];
    let f = FuncObj::new(&consts,
                &"c0, fneg".to_string());
    let expected = (-consts[0]).to_string();
    let real = f.call(&v).to_string();
    assert!(real == expected, "real = {}, expected = {}", real, expected);
}

#[test]
fn test9() {
    let consts = vec![GI::new_c("[0.1, .2]")];
    let v = vec![];
    let f = FuncObj::new(&consts,
                &"c0, flog".to_string());
    let expected = log(consts[0]).to_string();
    let real = f.call(&v).to_string();
    assert!(real == expected, "real = {}, expected = {}", real, expected);
}
#[test]
fn test10() {
    let consts = vec![GI::new_c("[2.0, 3.0]"),
                      GI::new_c("[1.5, 2.5]")];
    let v = vec![];
    let f = FuncObj::new(&consts,
                         &"c0, c1, op".to_string());
    let expected = powi(consts[0], consts[1]).to_string();
    let real = f.call(&v).to_string();
    assert!(real == expected, "real = {}, expected = {}", real, expected);
}
#[test]
fn test_power() {
    let consts = vec![GI::new_c("[2.0, 3.0]"),
                      GI::new_c("[1.5, 2.5]")];
    let v = vec![];
    let f = FuncObj::new(&consts,
                         &"c0, p-1, c1, p2, o+".to_string());
    let expected = (pow(consts[0], -1) + pow(consts[1], 2)).to_string();
    let real = f.call(&v).to_string();
    assert!(real == expected, "real = {}, expected = {}", real, expected);
}
<|endoftext|>