<commit_before><commit_msg>Added a file I forgot in previous commit<commit_after>// Copyright 2015 Adrien Champion. See the COPYRIGHT file at the top-level
// directory of this distribution.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use term::{ Term, TermSet } ;

use Domain ;

/** A chain is an increasing-ordered list containing values and
representative / equivalence class pairs.

It is ordered on the values. */
#[derive(PartialEq, Eq, Clone)]
pub enum Chain< Val: Domain, Info: PartialEq + Eq + Clone > {
  /** Empty chain. */
  Nil,
  /** Chain constructor. */
  Cons(Val, Term, Info, Box< Chain<Val, Info> >),
}
impl<Val: Domain, Info: PartialEq + Eq + Clone> Chain<Val, Info> {
  /** Empty chain. */
  #[inline]
  pub fn nil() -> Self { Chain::Nil }
  /** Chain constructor. */
  #[inline]
  pub fn cons(self, v: Val, t: Term, s: Info) -> Self {
    Chain::Cons(v, t, s, Box::new(self))
  }
  /** Checks if a chain is empty. */
  #[inline]
  pub fn is_empty(& self) -> bool { * self == Chain::Nil }
  /** Returns the top value of a chain, if any. */
  #[inline]
  pub fn top_value(& self) -> Option<(Val, Term)> {
    use self::Chain::* ;
    match * self {
      Cons(ref v, ref rep, _, _) => Some( (v.clone(), rep.clone()) ),
      Nil => None,
    }
  }

  /** Returns the longest subchain of a chain the values of which are
  all greater than or equal to some value, and the rest of the chain.

  First subchain is a vector of representatives and is sorted in **increasing
  order** on their value (which have been removed at this point).
  The second subchain is an actual `Chain` and is still sorted in **decreasing
  order**. */
  pub fn split_at(mut self, value: & Val) -> (Vec<Term>, Self) {
    use self::Chain::* ;
    let mut res = Vec::with_capacity(3) ;
    loop {
      if let Cons(val, rep, set, tail) = self {
        if value <= & val {
          res.push(rep) ;
          self = * tail
        } else {
          // We have `val < value`, stop here.
          self = Cons(val, rep, set, tail) ;
          break
        }
      } else {
        // Chain is empty, we done.
        break
      }
    }
    (res, self)
  }

  /** Reverses the first chain and appends it to the second one. */
  #[inline]
  pub fn rev_append(mut self, mut that: Self) -> Self {
    use self::Chain::* ;
    while let Cons(val, term, set, tail) = self {
      that = Cons( val, term, set, Box::new(that) ) ;
      self = * tail
    }
    that
  }
  /** Reverses a chain. */
  #[inline]
  pub fn rev(self) -> Self {
    self.rev_append(Chain::Nil)
  }
}
impl<Val: Domain> Chain<Val, TermSet> {
  /** Maps to `Chain<Val, ()>`, calling a function on each element. */
  pub fn map_to_unit<
    Input, F: Fn(& mut Input, Val, Term, TermSet)
  >(mut self, f: F, i: & mut Input) -> Chain<Val, ()> {
    use self::Chain::* ;
    let mut res = Nil ;
    while let Cons(val, rep, set, tail) = self {
      self = * tail ;
      f(i, val.clone(), rep.clone(), set) ;
      res = res.cons(val, rep, ())
    }
    res.rev()
  }

  /** Inserts a term in a chain given its value. */
  pub fn insert(mut self, v: Val, t: Term) -> Result<Self, String> {
    use self::Chain::* ;
    use std::cmp::Ordering::* ;
    let mut prefix = Nil ;
    loop {
      if let Cons(val, term, mut set, tail) = self {
        match val.cmp(& v) {
          Less => return Ok(
            // Insert term found as a new node in the chain.
            prefix.rev_append(
              Cons(val, term, set, tail).cons(v, t, TermSet::new())
            )
          ),
          Equal => {
            // Insert term in the set of this node.
            debug_assert!( ! set.contains(& t) ) ;
            let _ = set.insert(t) ;
            return Ok( prefix.rev_append( Cons(val, term, set, tail) ) )
          },
          Greater => {
            // Need to go deeper, iterating.
            prefix = prefix.cons(val, term, set) ;
            self = * tail
          },
        }
      } else {
        // Reached end of list, inserting.
        return Ok(
          prefix.rev_append( Nil.cons(v, t, TermSet::new()) )
        )
      }
    }
  }
}<|endoftext|>


<commit_before><commit_msg>Add is_pinned<commit_after><|endoftext|>


<commit_before><commit_msg>Invalid error type name Fixed<commit_after><|endoftext|>


<commit_before><commit_msg>Add test for alias shadowing external subcommand<commit_after><|endoftext|>


<commit_before><commit_msg>Push Opcode<commit_after><|endoftext|>


<commit_before><commit_msg>Add simple_draw example for testing and demonstrating the new Draw API<commit_after>extern crate nannou;

use nannou::prelude::*;

fn main() {
    nannou::run(model, event, view);
}

struct Model {
    window: WindowId,
}

fn model(app: &App) -> Model {
    let window = app.new_window().build().unwrap();
    Model { window }
}

fn event(_app: &App, model: Model, _event: Event) -> Model {
    model
}

fn view(app: &App, model: &Model, frame: Frame) -> Frame {
    // Begin drawing
    let draw = app.draw(model.window).unwrap();

    // Clear the background to blue.
    draw.background().rgb(0.0, 0.0, 1.0);

    // Short-hand helper functions.
    draw.ellipse()
        .x_y(app.mouse.x, app.mouse.y)
        .w_h(app.window.width * 0.5, app.window.height * 0.5)
        .rgb(1.0, 0.0, 0.0);

    // Write the result of our drawing to the window's OpenGL frame.
    draw.to_frame(app, &frame).unwrap();

    // Return the drawn frame.
    frame
}
<|endoftext|>


<commit_before><commit_msg>Add regression test for #54582<commit_after>// run-pass

pub trait Stage: Sync {}

pub enum Enum {
    A,
    B,
}

impl Stage for Enum {}

pub static ARRAY: [(&Stage, &str); 1] = [
    (&Enum::A, ""),
];

fn main() {}
<|endoftext|>


<commit_before><commit_msg>Fix fomatting with cargofmt<commit_after><|endoftext|>


<commit_before>//! Graph algorithms.
//!
//! It is a goal to gradually migrate the algorithms to be based on graph traits
//! so that they are generally applicable. For now, most of these use only the
//! **Graph** type.

use std::collections::BinaryHeap;
use std::borrow::{Borrow};

use super::{
    Graph,
    Directed,
    Undirected,
    EdgeDirection,
    EdgeType,
    Outgoing,
    Incoming,
    Dfs,
};
use scored::MinScored;
use super::visit::{
    Visitable,
    VisitMap,
};
use super::unionfind::UnionFind;
use super::graph::{
    NodeIndex,
    IndexType,
};

pub use super::isomorphism::{
    is_isomorphic,
    is_isomorphic_matching,
};
pub use super::dijkstra::dijkstra;

/// Return `true` if the input graph contains a cycle.
///
/// Always treats the input graph as if undirected.
pub fn is_cyclic_undirected<N, E, Ty, Ix>(g: &Graph<N, E, Ty, Ix>) -> bool
    where Ty: EdgeType,
          Ix: IndexType,
{
    let mut edge_sets = UnionFind::new(g.node_count());
    for edge in g.raw_edges() {
        let (a, b) = (edge.source(), edge.target());

        // union the two vertices of the edge
        //  -- if they were already the same, then we have a cycle
        if !edge_sets.union(a.index(), b.index()) {
            return true
        }
    }
    false
}

/// **Deprecated: Renamed to `is_cyclic_undirected`.**
pub fn is_cyclic<N, E, Ty, Ix>(g: &Graph<N, E, Ty, Ix>) -> bool
    where Ty: EdgeType,
          Ix: IndexType,
{
    is_cyclic_undirected(g)
}

/// Perform a topological sort of a directed graph `g`.
///
/// Visit each node in order (if it is part of a topological order).
///
/// You can pass `g` as either **&Graph** or **&mut Graph**, and it
/// will be passed on to the visitor closure.
#[inline]
fn toposort_generic<N, E, Ix, G, F>(mut g: G, mut visit: F)
    where Ix: IndexType,
          G: Borrow<Graph<N, E, Directed, Ix>>,
          F: FnMut(&mut G, NodeIndex<Ix>),
{
    let mut ordered = g.borrow().visit_map();
    let mut tovisit = Vec::new();

    // find all initial nodes
    tovisit.extend(g.borrow().externals(Incoming));

    // Take an unvisited element and find which of its neighbors are next
    while let Some(nix) = tovisit.pop() {
        if ordered.is_visited(&nix) {
            continue;
        }
        visit(&mut g, nix);
        ordered.visit(nix);
        for neigh in g.borrow().neighbors_directed(nix, Outgoing) {
            // Look at each neighbor, and those that only have incoming edges
            // from the already ordered list, they are the next to visit.
            if g.borrow().neighbors_directed(neigh, Incoming).all(|b| ordered.is_visited(&b)) {
                tovisit.push(neigh);
            }
        }
    }
}

/// Return `true` if the input directed graph contains a cycle.
///
/// Using the topological sort algorithm.
pub fn is_cyclic_directed<N, E, Ix>(g: &Graph<N, E, Directed, Ix>) -> bool
    where Ix: IndexType,
{
    let mut n_ordered = 0;
    toposort_generic(g, |_, _| n_ordered += 1);
    n_ordered != g.node_count()
}

/// Perform a topological sort of a directed graph.
///
/// Return a vector of nodes in topological order: each node is ordered
/// before its successors.
///
/// If the returned vec contains less than all the nodes of the graph, then
/// the graph was cyclic.
pub fn toposort<N, E, Ix>(g: &Graph<N, E, Directed, Ix>) -> Vec<NodeIndex<Ix>>
    where Ix: IndexType,
{
    let mut order = Vec::with_capacity(g.node_count());
    toposort_generic(g, |_, ix| order.push(ix));
    order
}

/// Compute the *strongly connected components* using Kosaraju's algorithm.
///
/// Return a vector where each element is an scc.
///
/// For an undirected graph, the sccs are simply the connected components.
pub fn scc<N, E, Ty, Ix>(g: &Graph<N, E, Ty, Ix>) -> Vec<Vec<NodeIndex<Ix>>>
    where Ty: EdgeType,
          Ix: IndexType,
{
    let mut dfs = Dfs::empty(g);

    // First phase, reverse dfs pass, compute finishing times.
    // http://stackoverflow.com/a/26780899/161659
    let mut finished = g.visit_map();
    let mut finish_order = Vec::new();
    for i in 0..g.node_count() {
        let nindex = NodeIndex::new(i);
        if dfs.discovered.is_visited(&nindex) {
            continue
        }

        dfs.stack.push(nindex);
        while let Some(&nx) = dfs.stack.last() {
            if dfs.discovered.visit(nx) {
                // First time visiting `nx`: Push neighbors, don't pop `nx`
                for succ in g.neighbors_directed(nx.clone(), EdgeDirection::Incoming) {
                    if !dfs.discovered.is_visited(&succ) {
                        dfs.stack.push(succ);
                    }
                }
            } else {
                dfs.stack.pop();
                if finished.visit(nx) {
                    // Second time: All reachable nodes must have been finished
                    finish_order.push(nx);
                }
            }
        }
    }

    dfs.discovered.clear();
    let mut sccs = Vec::new();

    // Second phase
    // Process in decreasing finishing time order
    for &nindex in finish_order.iter().rev() {
        if dfs.discovered.is_visited(&nindex) {
            continue;
        }
        // Move to the leader node.
        dfs.move_to(nindex);
        //let leader = nindex;
        let mut scc = Vec::new();
        while let Some(nx) = dfs.next(g) {
            scc.push(nx);
        }
        sccs.push(scc);
    }
    sccs
}

/// Condense every strongly connected component into a single node and return the result.
///
/// If `make_acyclic` is true, self-loops and multi edges are ignored, guaranteeing that
/// the output is acyclic.
pub fn condensation<N, E, Ty, Ix>(g: Graph<N, E, Ty, Ix>, make_acyclic: bool) -> Graph<Vec<N>, E, Ty, Ix>
    where Ty: EdgeType,
          Ix: IndexType,
{
    let sccs = scc(&g);
    let mut condensed: Graph<Vec<N>, E, Ty, Ix> = Graph::with_capacity(sccs.len(), g.edge_count());

    // Build a map from old indices to new ones.
    let mut node_map = vec![NodeIndex::end(); g.node_count()];
    for comp in sccs {
        let new_nix = condensed.add_node(Vec::new());
        for nix in comp {
            node_map[nix.index()] = new_nix;
        }
    }

    // Consume nodes and edges of the old graph and insert them into the new one.
    let (nodes, edges) = g.destructure();
    for (nix, node) in nodes.into_iter().enumerate() {
        condensed.node_weight_mut(node_map[nix]).unwrap().push(node.weight);
    }
    for edge in edges {
        let source = node_map[edge.source().index()];
        let target = node_map[edge.target().index()];
        if make_acyclic {
            if source != target {
                condensed.update_edge(source, target, edge.weight);
            }
        } else {
            condensed.add_edge(source, target, edge.weight);
        }
    }
    condensed
}

/// Return the number of connected components of the graph.
///
/// For a directed graph, this is the *weakly* connected components.
pub fn connected_components<N, E, Ty, Ix>(g: &Graph<N, E, Ty, Ix>) -> usize
    where Ty: EdgeType,
          Ix: IndexType,
{
    let mut vertex_sets = UnionFind::new(g.node_count());
    for edge in g.raw_edges() {
        let (a, b) = (edge.source(), edge.target());

        // union the two vertices of the edge
        vertex_sets.union(a.index(), b.index());
    }
    let mut labels = vertex_sets.into_labeling();
    labels.sort();
    labels.dedup();
    labels.len()
}

/// Compute a *minimum spanning tree* of a graph.
///
/// Treat the input graph as undirected.
///
/// Using Kruskal's algorithm with runtime **O(|E| log |E|)**. We actually
/// return a minimum spanning forest, i.e. a minimum spanning tree for each connected
/// component of the graph.
///
/// The resulting graph has all the vertices of the input graph (with identical node indices),
/// and **|V| - c** edges, where **c** is the number of connected components in `g`.
pub fn min_spanning_tree<N, E, Ty, Ix>(g: &Graph<N, E, Ty, Ix>)
    -> Graph<N, E, Undirected, Ix>
    where N: Clone,
          E: Clone + PartialOrd,
          Ty: EdgeType,
          Ix: IndexType,
{
    if g.node_count() == 0 {
        return Graph::with_capacity(0, 0)
    }

    // Create a mst skeleton by copying all nodes
    let mut mst = Graph::with_capacity(g.node_count(), g.node_count() - 1);
    for node in g.raw_nodes() {
        mst.add_node(node.weight.clone());
    }

    // Initially each vertex is its own disjoint subgraph, track the connectedness
    // of the pre-MST with a union & find datastructure.
    let mut subgraphs = UnionFind::new(g.node_count());

    let mut sort_edges = BinaryHeap::with_capacity(g.edge_count());
    for edge in g.raw_edges() {
        sort_edges.push(MinScored(edge.weight.clone(), (edge.source(), edge.target())));
    }

    // Kruskal's algorithm.
    // Algorithm is this:
    //
    // 1. Create a pre-MST with all the vertices and no edges.
    // 2. Repeat:
    //
    //  a. Remove the shortest edge from the original graph.
    //  b. If the edge connects two disjoint trees in the pre-MST,
    //     add the edge.
    while let Some(MinScored(score, (a, b))) = sort_edges.pop() {
        // check if the edge would connect two disjoint parts
        if subgraphs.union(a.index(), b.index()) {
            mst.add_edge(a, b, score);
        }
    }

    debug_assert!(mst.node_count() == g.node_count());
    debug_assert!(mst.edge_count() < g.node_count());
    mst
}
<commit_msg>condensation: Use indexing notation<commit_after>//! Graph algorithms.
//!
//! It is a goal to gradually migrate the algorithms to be based on graph traits
//! so that they are generally applicable. For now, most of these use only the
//! **Graph** type.

use std::collections::BinaryHeap;
use std::borrow::{Borrow};

use super::{
    Graph,
    Directed,
    Undirected,
    EdgeDirection,
    EdgeType,
    Outgoing,
    Incoming,
    Dfs,
};
use scored::MinScored;
use super::visit::{
    Visitable,
    VisitMap,
};
use super::unionfind::UnionFind;
use super::graph::{
    NodeIndex,
    IndexType,
};

pub use super::isomorphism::{
    is_isomorphic,
    is_isomorphic_matching,
};
pub use super::dijkstra::dijkstra;

/// Return `true` if the input graph contains a cycle.
///
/// Always treats the input graph as if undirected.
pub fn is_cyclic_undirected<N, E, Ty, Ix>(g: &Graph<N, E, Ty, Ix>) -> bool
    where Ty: EdgeType,
          Ix: IndexType,
{
    let mut edge_sets = UnionFind::new(g.node_count());
    for edge in g.raw_edges() {
        let (a, b) = (edge.source(), edge.target());

        // union the two vertices of the edge
        //  -- if they were already the same, then we have a cycle
        if !edge_sets.union(a.index(), b.index()) {
            return true
        }
    }
    false
}

/// **Deprecated: Renamed to `is_cyclic_undirected`.**
pub fn is_cyclic<N, E, Ty, Ix>(g: &Graph<N, E, Ty, Ix>) -> bool
    where Ty: EdgeType,
          Ix: IndexType,
{
    is_cyclic_undirected(g)
}

/// Perform a topological sort of a directed graph `g`.
///
/// Visit each node in order (if it is part of a topological order).
///
/// You can pass `g` as either **&Graph** or **&mut Graph**, and it
/// will be passed on to the visitor closure.
#[inline]
fn toposort_generic<N, E, Ix, G, F>(mut g: G, mut visit: F)
    where Ix: IndexType,
          G: Borrow<Graph<N, E, Directed, Ix>>,
          F: FnMut(&mut G, NodeIndex<Ix>),
{
    let mut ordered = g.borrow().visit_map();
    let mut tovisit = Vec::new();

    // find all initial nodes
    tovisit.extend(g.borrow().externals(Incoming));

    // Take an unvisited element and find which of its neighbors are next
    while let Some(nix) = tovisit.pop() {
        if ordered.is_visited(&nix) {
            continue;
        }
        visit(&mut g, nix);
        ordered.visit(nix);
        for neigh in g.borrow().neighbors_directed(nix, Outgoing) {
            // Look at each neighbor, and those that only have incoming edges
            // from the already ordered list, they are the next to visit.
            if g.borrow().neighbors_directed(neigh, Incoming).all(|b| ordered.is_visited(&b)) {
                tovisit.push(neigh);
            }
        }
    }
}

/// Return `true` if the input directed graph contains a cycle.
///
/// Using the topological sort algorithm.
pub fn is_cyclic_directed<N, E, Ix>(g: &Graph<N, E, Directed, Ix>) -> bool
    where Ix: IndexType,
{
    let mut n_ordered = 0;
    toposort_generic(g, |_, _| n_ordered += 1);
    n_ordered != g.node_count()
}

/// Perform a topological sort of a directed graph.
///
/// Return a vector of nodes in topological order: each node is ordered
/// before its successors.
///
/// If the returned vec contains less than all the nodes of the graph, then
/// the graph was cyclic.
pub fn toposort<N, E, Ix>(g: &Graph<N, E, Directed, Ix>) -> Vec<NodeIndex<Ix>>
    where Ix: IndexType,
{
    let mut order = Vec::with_capacity(g.node_count());
    toposort_generic(g, |_, ix| order.push(ix));
    order
}

/// Compute the *strongly connected components* using Kosaraju's algorithm.
///
/// Return a vector where each element is an scc.
///
/// For an undirected graph, the sccs are simply the connected components.
pub fn scc<N, E, Ty, Ix>(g: &Graph<N, E, Ty, Ix>) -> Vec<Vec<NodeIndex<Ix>>>
    where Ty: EdgeType,
          Ix: IndexType,
{
    let mut dfs = Dfs::empty(g);

    // First phase, reverse dfs pass, compute finishing times.
    // http://stackoverflow.com/a/26780899/161659
    let mut finished = g.visit_map();
    let mut finish_order = Vec::new();
    for i in 0..g.node_count() {
        let nindex = NodeIndex::new(i);
        if dfs.discovered.is_visited(&nindex) {
            continue
        }

        dfs.stack.push(nindex);
        while let Some(&nx) = dfs.stack.last() {
            if dfs.discovered.visit(nx) {
                // First time visiting `nx`: Push neighbors, don't pop `nx`
                for succ in g.neighbors_directed(nx.clone(), EdgeDirection::Incoming) {
                    if !dfs.discovered.is_visited(&succ) {
                        dfs.stack.push(succ);
                    }
                }
            } else {
                dfs.stack.pop();
                if finished.visit(nx) {
                    // Second time: All reachable nodes must have been finished
                    finish_order.push(nx);
                }
            }
        }
    }

    dfs.discovered.clear();
    let mut sccs = Vec::new();

    // Second phase
    // Process in decreasing finishing time order
    for &nindex in finish_order.iter().rev() {
        if dfs.discovered.is_visited(&nindex) {
            continue;
        }
        // Move to the leader node.
        dfs.move_to(nindex);
        //let leader = nindex;
        let mut scc = Vec::new();
        while let Some(nx) = dfs.next(g) {
            scc.push(nx);
        }
        sccs.push(scc);
    }
    sccs
}

/// Condense every strongly connected component into a single node and return the result.
///
/// If `make_acyclic` is true, self-loops and multi edges are ignored, guaranteeing that
/// the output is acyclic.
pub fn condensation<N, E, Ty, Ix>(g: Graph<N, E, Ty, Ix>, make_acyclic: bool) -> Graph<Vec<N>, E, Ty, Ix>
    where Ty: EdgeType,
          Ix: IndexType,
{
    let sccs = scc(&g);
    let mut condensed: Graph<Vec<N>, E, Ty, Ix> = Graph::with_capacity(sccs.len(), g.edge_count());

    // Build a map from old indices to new ones.
    let mut node_map = vec![NodeIndex::end(); g.node_count()];
    for comp in sccs {
        let new_nix = condensed.add_node(Vec::new());
        for nix in comp {
            node_map[nix.index()] = new_nix;
        }
    }

    // Consume nodes and edges of the old graph and insert them into the new one.
    let (nodes, edges) = g.destructure();
    for (nix, node) in nodes.into_iter().enumerate() {
        condensed[node_map[nix]].push(node.weight);
    }
    for edge in edges {
        let source = node_map[edge.source().index()];
        let target = node_map[edge.target().index()];
        if make_acyclic {
            if source != target {
                condensed.update_edge(source, target, edge.weight);
            }
        } else {
            condensed.add_edge(source, target, edge.weight);
        }
    }
    condensed
}

/// Return the number of connected components of the graph.
///
/// For a directed graph, this is the *weakly* connected components.
pub fn connected_components<N, E, Ty, Ix>(g: &Graph<N, E, Ty, Ix>) -> usize
    where Ty: EdgeType,
          Ix: IndexType,
{
    let mut vertex_sets = UnionFind::new(g.node_count());
    for edge in g.raw_edges() {
        let (a, b) = (edge.source(), edge.target());

        // union the two vertices of the edge
        vertex_sets.union(a.index(), b.index());
    }
    let mut labels = vertex_sets.into_labeling();
    labels.sort();
    labels.dedup();
    labels.len()
}

/// Compute a *minimum spanning tree* of a graph.
///
/// Treat the input graph as undirected.
///
/// Using Kruskal's algorithm with runtime **O(|E| log |E|)**. We actually
/// return a minimum spanning forest, i.e. a minimum spanning tree for each connected
/// component of the graph.
///
/// The resulting graph has all the vertices of the input graph (with identical node indices),
/// and **|V| - c** edges, where **c** is the number of connected components in `g`.
pub fn min_spanning_tree<N, E, Ty, Ix>(g: &Graph<N, E, Ty, Ix>)
    -> Graph<N, E, Undirected, Ix>
    where N: Clone,
          E: Clone + PartialOrd,
          Ty: EdgeType,
          Ix: IndexType,
{
    if g.node_count() == 0 {
        return Graph::with_capacity(0, 0)
    }

    // Create a mst skeleton by copying all nodes
    let mut mst = Graph::with_capacity(g.node_count(), g.node_count() - 1);
    for node in g.raw_nodes() {
        mst.add_node(node.weight.clone());
    }

    // Initially each vertex is its own disjoint subgraph, track the connectedness
    // of the pre-MST with a union & find datastructure.
    let mut subgraphs = UnionFind::new(g.node_count());

    let mut sort_edges = BinaryHeap::with_capacity(g.edge_count());
    for edge in g.raw_edges() {
        sort_edges.push(MinScored(edge.weight.clone(), (edge.source(), edge.target())));
    }

    // Kruskal's algorithm.
    // Algorithm is this:
    //
    // 1. Create a pre-MST with all the vertices and no edges.
    // 2. Repeat:
    //
    //  a. Remove the shortest edge from the original graph.
    //  b. If the edge connects two disjoint trees in the pre-MST,
    //     add the edge.
    while let Some(MinScored(score, (a, b))) = sort_edges.pop() {
        // check if the edge would connect two disjoint parts
        if subgraphs.union(a.index(), b.index()) {
            mst.add_edge(a, b, score);
        }
    }

    debug_assert!(mst.node_count() == g.node_count());
    debug_assert!(mst.edge_count() < g.node_count());
    mst
}
<|endoftext|>


<commit_before>use std::fmt;
use std::borrow::Cow;

use escape::Escaped;

/// An [HTML attribute](https://www.w3.org/TR/html/syntax.html#attributes-0).
///
/// The name for the attribute will not be validated, you must ensure it meets
/// the requirements specified in the spec yourself.
///
/// The value for the attribute will be escaped automatically. If it is an
/// empty string then the attribute will be written with the 'Empty attribute
/// syntax'.
///
/// # Examples
///
/// ```rust
/// let attr = hamlet::attr::Attribute::new("id", "foo");
/// assert_eq!(format!("{}", attr), "id=\"foo\"");
/// ```
///
/// ```rust
/// let attr = hamlet::attr::Attribute::new("id", "bar & baz");
/// assert_eq!(format!("{}", attr), "id=\"bar & baz\"");
/// ```
///
/// ```rust
/// let attr = hamlet::attr::Attribute::new("invalid=id", "foo");
/// assert_eq!(format!("{}", attr), "invalid=id=\"foo\"");
/// ```
///
/// ```rust
/// let attr = hamlet::attr::Attribute::new("checked", "");
/// assert_eq!(format!("{}", attr), "checked");
/// ```
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct Attribute<'a> {
    pub name: Cow<'a, str>,
    pub value: Cow<'a, str>,
}

impl<'a> Attribute<'a> {
    /// Create an attribute, useful to avoid having to convert strings to
    /// `Cow<str>` yourself.
    ///
    /// Generally this shouldn't be used directly by end users, it's likely
    /// that there are builder APIs or macros available that make attribute
    /// construction easier, for example the modification methods on
    /// [`AttributeList`](struct.AttributeList.html#methods) or the
    /// [`attrs!`](macro.attrs!.html) macro.
    ///
    /// # Examples
    ///
    /// ```rust
    /// use std::borrow::Cow;
    /// use hamlet::attr::Attribute;
    ///
    /// let foo = "foo".to_owned();
    /// let foo2 = foo.clone();
    /// assert_eq!(
    ///     Attribute::new("id", foo),
    ///     Attribute {
    ///         name: Cow::Borrowed("id"),
    ///         value: Cow::Owned(foo2),
    ///     });
    /// ```
    pub fn new<N, V>(name: N, value: V) -> Attribute<'a>
        where N: Into<Cow<'a, str>>,
              V: Into<Cow<'a, str>>
    {
        Attribute {
            name: name.into(),
            value: value.into(),
        }
    }
}

impl<'a> fmt::Display for Attribute<'a> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        if self.value == "" {
            write!(f, "{}", self.name)
        } else {
            write!(f, "{}=\"{}\"", self.name.as_ref(), Escaped(&self.value))
        }
    }
}

#[derive(Clone, Debug)]
/// A list of [`Attribute`](./struct.Attribute.html)s.
///
/// This is stored as a plain list instead of a set as in most cases it will
/// be a small collection over which linear search will be more efficient.
pub struct AttributeList<'a>(Cow<'a, [Attribute<'a>]>);

impl<'a> AttributeList<'a> {
    /// Return an empty `AttributeList`
    pub fn empty() -> AttributeList<'a> {
        AttributeList(Cow::Borrowed(&[]))
    }

    /// Note that this does not check for duplicate attribute names. Generally,
    /// end users are not expected to call this method, and instead use
    /// high-level builder APIs or macros available to make construction easier,
    /// such as the provided [`attrs!`](./macro.attrs!.html) macro.
    pub fn from_vec(attrs: Vec<Attribute<'a>>) -> AttributeList<'a> {
        AttributeList(Cow::Owned(attrs))
    }

    pub fn into_vec(self) -> Vec<Attribute<'a>> {
        self.0.into_owned()
    }

    /// Try and get the value of an attribute.
    ///
    /// # Examples
    ///
    /// ```rust
    /// # #[macro_use] extern crate hamlet;
    /// # fn main() {
    /// let attrs = attrs!(id = "foo");
    /// assert_eq!(attrs.get("id"), Some("foo"));
    /// # }
    /// ```
    ///
    /// ```rust
    /// # #[macro_use] extern crate hamlet;
    /// # fn main() {
    /// let attrs = attrs!(id = "foo");
    /// assert_eq!(attrs.get("class"), None);
    /// # }
    /// ```
    pub fn get<S>(&self, name: S) -> Option<&str>
        where S: AsRef<str>
    {
        self.0.iter().find(|attr| attr.name == name.as_ref()).map(|a| a.value.as_ref())
    }

    /// Unconditionally set an attribute to a value. If the attribute already
    /// exists in the set will update its value, otherwise will add a new
    /// attribute to the set.
    ///
    /// # Examples
    ///
    /// ```rust
    /// # #[macro_use] extern crate hamlet;
    /// # fn main() {
    /// let mut attrs = attrs!(id = "foo");
    ///
    /// attrs.set("id", "bar");
    ///
    /// assert_eq!(attrs.get("id"), Some("bar"));
    /// # }
    /// ```
    ///
    /// ```rust
    /// # #[macro_use] extern crate hamlet;
    /// # fn main() {
    /// let mut attrs = attrs!(id = "foo");
    ///
    /// attrs.set("class", "bar");
    ///
    /// assert_eq!(attrs.get("class"), Some("bar"));
    /// # }
    /// ```
    pub fn set<N, V>(&mut self, name: N, value: V)
        where N: Into<Cow<'a, str>>,
              V: Into<Cow<'a, str>>
    {
        let (name, value) = (name.into(), value.into());
        let attrs = self.0.to_mut();

        if let Some(pos) = attrs.iter().position(|attr| attr.name == name) {
            attrs[pos].value = value;
        } else {
            attrs.push(Attribute::new(name, value));
        }
    }

    /// Removes and returns the attribute it if there was one.
    ///
    /// # Examples
    ///
    /// ```rust
    /// # #[macro_use] extern crate hamlet;
    /// # fn main() {
    /// let mut attrs = attrs!(id = "foo");
    ///
    /// assert_eq!(attrs.remove("id").map(|a| a.value).unwrap().as_ref(), "foo");
    /// # }
    /// ```
    pub fn remove<S>(&mut self, name: S) -> Option<Attribute<'a>>
        where S: AsRef<str>
    {
        let attrs = self.0.to_mut();

        if let Some(pos) = attrs.iter().position(|attr| attr.name.as_ref() == name.as_ref()) {
            Some(attrs.remove(pos))
        } else {
            None
        }
    }

    pub fn iter<'b>(&'b self) -> Iter<'b, 'a> {
        Iter {
            inner: self.0.as_ref(),
            index: 0,
        }
    }
}

pub struct Iter<'b, 'a: 'b> {
    inner: &'b [Attribute<'a>],
    index: usize,
}

impl<'a, 'b> Iterator for Iter<'b, 'a> {
    type Item = &'b Attribute<'a>;

    fn next(&mut self) -> Option<Self::Item> {
        self.index += 1;
        self.inner.get(self.index - 1)
    }
}
<commit_msg>Minor documentation wording<commit_after>use std::fmt;
use std::borrow::Cow;

use escape::Escaped;

/// An [HTML attribute](https://www.w3.org/TR/html/syntax.html#attributes-0).
///
/// The name for the attribute will not be validated, you must ensure it meets
/// the requirements specified in the spec yourself.
///
/// The value for the attribute will be escaped automatically. If it is an
/// empty string then the attribute will be written with the 'Empty attribute
/// syntax'.
///
/// # Examples
///
/// ```rust
/// let attr = hamlet::attr::Attribute::new("id", "foo");
/// assert_eq!(format!("{}", attr), "id=\"foo\"");
/// ```
///
/// ```rust
/// let attr = hamlet::attr::Attribute::new("id", "bar & baz");
/// assert_eq!(format!("{}", attr), "id=\"bar & baz\"");
/// ```
///
/// ```rust
/// let attr = hamlet::attr::Attribute::new("invalid=id", "foo");
/// assert_eq!(format!("{}", attr), "invalid=id=\"foo\"");
/// ```
///
/// ```rust
/// let attr = hamlet::attr::Attribute::new("checked", "");
/// assert_eq!(format!("{}", attr), "checked");
/// ```
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct Attribute<'a> {
    pub name: Cow<'a, str>,
    pub value: Cow<'a, str>,
}

impl<'a> Attribute<'a> {
    /// Create an attribute, useful to avoid having to convert strings to
    /// `Cow<str>` yourself.
    ///
    /// Generally this shouldn't be used directly by end users, it's likely
    /// that there are builder APIs or macros available that make attribute
    /// construction easier, for example the modification methods on
    /// [`AttributeList`](struct.AttributeList.html#methods) or the
    /// [`attrs!`](macro.attrs!.html) macro.
    ///
    /// # Examples
    ///
    /// ```rust
    /// use std::borrow::Cow;
    /// use hamlet::attr::Attribute;
    ///
    /// let foo = "foo".to_owned();
    /// let foo2 = foo.clone();
    /// assert_eq!(
    ///     Attribute::new("id", foo),
    ///     Attribute {
    ///         name: Cow::Borrowed("id"),
    ///         value: Cow::Owned(foo2),
    ///     });
    /// ```
    pub fn new<N, V>(name: N, value: V) -> Attribute<'a>
        where N: Into<Cow<'a, str>>,
              V: Into<Cow<'a, str>>
    {
        Attribute {
            name: name.into(),
            value: value.into(),
        }
    }
}

impl<'a> fmt::Display for Attribute<'a> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        if self.value == "" {
            write!(f, "{}", self.name)
        } else {
            write!(f, "{}=\"{}\"", self.name.as_ref(), Escaped(&self.value))
        }
    }
}

#[derive(Clone, Debug)]
/// A list of [`Attribute`](./struct.Attribute.html)s.
///
/// This is stored as a plain list instead of a set as in most cases it will
/// be a small collection over which a linear search will be more efficient.
pub struct AttributeList<'a>(Cow<'a, [Attribute<'a>]>);

impl<'a> AttributeList<'a> {
    /// Return an empty `AttributeList`
    pub fn empty() -> AttributeList<'a> {
        AttributeList(Cow::Borrowed(&[]))
    }

    /// Note that this does not check for duplicate attribute names. Generally,
    /// end users are not expected to call this method, and instead use
    /// high-level builder APIs or macros available to make construction easier,
    /// such as the provided [`attrs!`](./macro.attrs!.html) macro.
    pub fn from_vec(attrs: Vec<Attribute<'a>>) -> AttributeList<'a> {
        AttributeList(Cow::Owned(attrs))
    }

    pub fn into_vec(self) -> Vec<Attribute<'a>> {
        self.0.into_owned()
    }

    /// Try and get the value of an attribute.
    ///
    /// # Examples
    ///
    /// ```rust
    /// # #[macro_use] extern crate hamlet;
    /// # fn main() {
    /// let attrs = attrs!(id = "foo");
    /// assert_eq!(attrs.get("id"), Some("foo"));
    /// # }
    /// ```
    ///
    /// ```rust
    /// # #[macro_use] extern crate hamlet;
    /// # fn main() {
    /// let attrs = attrs!(id = "foo");
    /// assert_eq!(attrs.get("class"), None);
    /// # }
    /// ```
    pub fn get<S>(&self, name: S) -> Option<&str>
        where S: AsRef<str>
    {
        self.0.iter().find(|attr| attr.name == name.as_ref()).map(|a| a.value.as_ref())
    }

    /// Unconditionally set an attribute to a value. If the attribute already
    /// exists in the list, update its value, otherwise add a new attribute to
    /// the list.
    ///
    /// # Examples
    ///
    /// ```rust
    /// # #[macro_use] extern crate hamlet;
    /// # fn main() {
    /// let mut attrs = attrs!(id = "foo");
    ///
    /// attrs.set("id", "bar");
    ///
    /// assert_eq!(attrs.get("id"), Some("bar"));
    /// # }
    /// ```
    ///
    /// ```rust
    /// # #[macro_use] extern crate hamlet;
    /// # fn main() {
    /// let mut attrs = attrs!(id = "foo");
    ///
    /// attrs.set("class", "bar");
    ///
    /// assert_eq!(attrs.get("class"), Some("bar"));
    /// # }
    /// ```
    pub fn set<N, V>(&mut self, name: N, value: V)
        where N: Into<Cow<'a, str>>,
              V: Into<Cow<'a, str>>
    {
        let (name, value) = (name.into(), value.into());
        let attrs = self.0.to_mut();

        if let Some(pos) = attrs.iter().position(|attr| attr.name == name) {
            attrs[pos].value = value;
        } else {
            attrs.push(Attribute::new(name, value));
        }
    }

    /// Removes and returns the attribute if there was one.
    ///
    /// # Examples
    ///
    /// ```rust
    /// # #[macro_use] extern crate hamlet;
    /// # fn main() {
    /// let mut attrs = attrs!(id = "foo");
    ///
    /// assert_eq!(attrs.remove("id").map(|a| a.value).unwrap().as_ref(), "foo");
    /// # }
    /// ```
    pub fn remove<S>(&mut self, name: S) -> Option<Attribute<'a>>
        where S: AsRef<str>
    {
        let attrs = self.0.to_mut();

        if let Some(pos) = attrs.iter().position(|attr| attr.name.as_ref() == name.as_ref()) {
            Some(attrs.remove(pos))
        } else {
            None
        }
    }

    pub fn iter<'b>(&'b self) -> Iter<'b, 'a> {
        Iter {
            inner: self.0.as_ref(),
            index: 0,
        }
    }
}

pub struct Iter<'b, 'a: 'b> {
    inner: &'b [Attribute<'a>],
    index: usize,
}

impl<'a, 'b> Iterator for Iter<'b, 'a> {
    type Item = &'b Attribute<'a>;

    fn next(&mut self) -> Option<Self::Item> {
        self.index += 1;
        self.inner.get(self.index - 1)
    }
}
<|endoftext|>


<commit_before>use hyper::header::AccessControlAllowOrigin;
use hyper::server::Request;
use hyper::net::HttpStream;

pub fn read_origin(req: &Request<HttpStream>) -> Option<String> {
	match req.headers().get_raw("origin") {
		Some(ref v) if v.len() == 1 => {
			String::from_utf8(v[0].clone()).ok()
		},
		_ => None
	}
}

pub fn get_cors_header(allowed: &Option<Vec<AccessControlAllowOrigin>>, origin: &Option<String>) -> Option<AccessControlAllowOrigin> {

	if allowed.is_none() {
		return None;
	}
	let allowed = allowed.as_ref().unwrap();

	match *origin {
		Some(ref origin) => {
			allowed.iter().find(|cors| {
				match **cors {
					AccessControlAllowOrigin::Any => true,
					AccessControlAllowOrigin::Value(ref val) if val == origin => true,
					_ => false
				}
			}).cloned()
		},
		None => {
			allowed.iter().find(|cors| **cors == AccessControlAllowOrigin::Null).cloned()
		},
	}
}

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

	#[test]
	fn should_return_none_when_there_are_no_cors_domains() {
		// given
		let origin = None;

		// when
		let res = get_cors_header(&None, &origin);

		// then
		assert_eq!(res, None);
	}

	#[test]
	fn should_return_none_for_empty_origin() {
		// given
		let origin = None;

		// when
		let res = get_cors_header(
			&Some(vec![AccessControlAllowOrigin::Value("http://ethereum.org".into())]),
			&origin
		);

		// then
		assert_eq!(res, None);
	}

	#[test]
	fn should_return_none_for_empty_list() {
		// given
		let origin = None;

		// when
		let res = get_cors_header(&Some(Vec::new()), &origin);

		// then
		assert_eq!(res, None);
	}

	#[test]
	fn should_return_none_for_not_matching_origin() {
		// given
		let origin = Some("http://ethcore.io".into());

		// when
		let res = get_cors_header(
			&Some(vec![AccessControlAllowOrigin::Value("http://ethereum.org".into())]),
			&origin
		);

		// then
		assert_eq!(res, None);
	}

	#[test]
	fn should_return_specific_origin_if_we_allow_any() {
		// given
		let origin = Some("http://ethcore.io".into());

		// when
		let res = get_cors_header(&Some(vec![AccessControlAllowOrigin::Any]), &origin);

		// then
		assert_eq!(res, Some(AccessControlAllowOrigin::Value("http://ethcore.io".into())));
	}

	#[test]
	fn should_return_null_only_if_null_is_set_and_origin_is_not_defined() {
		// given
		let origin = None;

		// when
		let res = get_cors_header(
			&Some(vec![AccessControlAllowOrigin::Null]),
			&origin
		);

		// then
		assert_eq!(res, Some(AccessControlAllowOrigin::Null));
	}

	#[test]
	fn should_return_specific_origin_if_there_is_a_match() {
		// given
		let origin = Some("http://ethcore.io".into());

		// when
		let res = get_cors_header(
			&Some(vec![AccessControlAllowOrigin::Value("http://ethereum.org".into()), AccessControlAllowOrigin::Value("http://ethcore.io".into())]),
			&origin
			);

		// then
		assert_eq!(res, Some(AccessControlAllowOrigin::Value("http://ethcore.io".into())));
	}
}
<commit_msg>Fixing test<commit_after>use hyper::header::AccessControlAllowOrigin;
use hyper::server::Request;
use hyper::net::HttpStream;

pub fn read_origin(req: &Request<HttpStream>) -> Option<String> {
	match req.headers().get_raw("origin") {
		Some(ref v) if v.len() == 1 => {
			String::from_utf8(v[0].clone()).ok()
		},
		_ => None
	}
}

pub fn get_cors_header(allowed: &Option<Vec<AccessControlAllowOrigin>>, origin: &Option<String>) -> Option<AccessControlAllowOrigin> {

	if allowed.is_none() {
		return None;
	}
	let allowed = allowed.as_ref().unwrap();

	match *origin {
		Some(ref origin) => {
			allowed.iter().find(|cors| {
				match **cors {
					AccessControlAllowOrigin::Any => true,
					AccessControlAllowOrigin::Value(ref val) if val == origin => true,
					_ => false
				}
			}).map(|cors| {
				match *cors {
					AccessControlAllowOrigin::Any => AccessControlAllowOrigin::Value(origin.clone()),
					ref cors => cors.clone(),
				}
			})
		},
		None => {
			allowed.iter().find(|cors| **cors == AccessControlAllowOrigin::Null).cloned()
		},
	}
}

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

	#[test]
	fn should_return_none_when_there_are_no_cors_domains() {
		// given
		let origin = None;

		// when
		let res = get_cors_header(&None, &origin);

		// then
		assert_eq!(res, None);
	}

	#[test]
	fn should_return_none_for_empty_origin() {
		// given
		let origin = None;

		// when
		let res = get_cors_header(
			&Some(vec![AccessControlAllowOrigin::Value("http://ethereum.org".into())]),
			&origin
		);

		// then
		assert_eq!(res, None);
	}

	#[test]
	fn should_return_none_for_empty_list() {
		// given
		let origin = None;

		// when
		let res = get_cors_header(&Some(Vec::new()), &origin);

		// then
		assert_eq!(res, None);
	}

	#[test]
	fn should_return_none_for_not_matching_origin() {
		// given
		let origin = Some("http://ethcore.io".into());

		// when
		let res = get_cors_header(
			&Some(vec![AccessControlAllowOrigin::Value("http://ethereum.org".into())]),
			&origin
		);

		// then
		assert_eq!(res, None);
	}

	#[test]
	fn should_return_specific_origin_if_we_allow_any() {
		// given
		let origin = Some("http://ethcore.io".into());

		// when
		let res = get_cors_header(&Some(vec![AccessControlAllowOrigin::Any]), &origin);

		// then
		assert_eq!(res, Some(AccessControlAllowOrigin::Value("http://ethcore.io".into())));
	}

	#[test]
	fn should_return_null_only_if_null_is_set_and_origin_is_not_defined() {
		// given
		let origin = None;

		// when
		let res = get_cors_header(
			&Some(vec![AccessControlAllowOrigin::Null]),
			&origin
		);

		// then
		assert_eq!(res, Some(AccessControlAllowOrigin::Null));
	}

	#[test]
	fn should_return_specific_origin_if_there_is_a_match() {
		// given
		let origin = Some("http://ethcore.io".into());

		// when
		let res = get_cors_header(
			&Some(vec![AccessControlAllowOrigin::Value("http://ethereum.org".into()), AccessControlAllowOrigin::Value("http://ethcore.io".into())]),
			&origin
			);

		// then
		assert_eq!(res, Some(AccessControlAllowOrigin::Value("http://ethcore.io".into())));
	}
}
<|endoftext|>


<commit_before>//
//  SOS: the Stupid Operating System
//  by Eliza Weisman (eliza@elizas.website)
//
//  Copyright (c) 2015-2017 Eliza Weisman
//  Released under the terms of the MIT license. See `LICENSE` in the root
//  directory of this repository for more information.
//
//! # SOS kernel
//! This crate contains the kernel for SOS, the Stupid Operating System.
//!
//! # SOS: the Stupid Operating System
//! SOS is a simple, tiny toy OS implemented in Rust. It targets the `x86`,
//! `x86_64`, and ARM v7 CPU architectures.
//!
//! I'm writing this mostly for fun, to learn more about OS design and kernel
//! hacking, so don't expect anything new or exciting out of this project.
//!
//! SOS is copyright 2015-2017 Eliza Weisman, and is released under the terms
//! of the MIT license.

#![crate_name = "sos_kernel"]

#![doc(html_root_url = "https://hawkw.github.io/sos-kernel/")]

#![feature( lang_items, asm, naked_functions )]
#![feature( linkage )]
#![feature( const_fn
          , slice_patterns
          , associated_consts
          , type_ascription
          , custom_derive )]
#![feature( collections )]

#![cfg_attr(feature="clippy", feature(plugin))]
#![cfg_attr(feature="clippy", plugin(clippy))]
#![cfg_attr( any(target_arch = "x86_64", target_arch="x86")
           , feature(abi_x86_interrupt))]

#![no_std]
#![cfg_attr(not(test), no_main)]

// -- non-SOS dependencies --------------------------------------------------
#[macro_use] extern crate lazy_static;
#[macro_use] extern crate bitflags;
#[macro_use] extern crate log;

extern crate collections;
extern crate rlibc;
extern crate spin;

// -- SOS dependencies ------------------------------------------------------
#[macro_use] extern crate vga;

extern crate alloc;
extern crate cpu;
extern crate elf;
extern crate util;
extern crate memory;

#[macro_use] pub mod io;

pub mod heap;
pub mod params;
pub mod arch;
pub mod logger;

/// SOS version number
pub const VERSION_STRING: &'static str
    = concat!("Stupid Operating System v", env!("CARGO_PKG_VERSION"));

use params::InitParams;

/// Kernel main loop
pub fn kernel_main() -> ! {
    let mut a_vec = collections::vec::Vec::<usize>::new();
    info!(target: "test", "Created a vector in kernel space! {:?}", a_vec);
    a_vec.push(1);
    info!(target: "test", "pushed to vec: {:?}", a_vec);
    a_vec.push(2);
    info!(target: "test", "pushed to vec: {:?}", a_vec);

    loop { }
}

/// Kernel initialization function called from ASM
///
/// The kernel main loop expects to be passed the address of a valid
/// Multiboot 2 info struct. It's the bootloader's responsibility to ensure
/// that this is passed in the correct register as expected by the calling
/// convention (`edi` on x86). If this isn't there, you can expect to have a
/// bad problem and not go to space today.
pub fn kernel_init(params: &InitParams) {
    kinfoln!("Hello from the kernel!");

    // -- initialize interrupts ----------------------------------------------
    kinfoln!(dots: " . ", "Initializing interrupts:");
    unsafe {
        arch::interrupts::initialize();
    };
    kinfoln!(dots: " . ", target: "Enabling interrupts", "[ OKAY ]");

    // -- initialize the heap ------------------------------------------------

    if unsafe { heap::initialize(params) }.is_ok() {
        kinfoln!( dots: " . ", target: "Intializing heap"
                , "[ OKAY ]"
                );
        kinfoln!( dots: " . . "
                , "Heap begins at {:#x} and ends at {:#x}"
                , params.heap_base, params.heap_top);
    } else {
        kinfoln!( dots: " . ", target: "Intializing heap"
                , "[ FAIL ]"
                );
    }

    println!("\n{} {}-bit\n", VERSION_STRING, arch::ARCH_BITS);
    // -- call into kernel main loop ------------------------------------------
    // (currently, this does nothing)
    kernel_main()

}

/// This fake `main` function exists only to placate `cargo test`.
#[cfg(test)]
fn main() {

}
<commit_msg>doc(kernel_init): update incorrect docs in<commit_after>//
//  SOS: the Stupid Operating System
//  by Eliza Weisman (eliza@elizas.website)
//
//  Copyright (c) 2015-2017 Eliza Weisman
//  Released under the terms of the MIT license. See `LICENSE` in the root
//  directory of this repository for more information.
//
//! # SOS kernel
//! This crate contains the kernel for SOS, the Stupid Operating System.
//!
//! # SOS: the Stupid Operating System
//! SOS is a simple, tiny toy OS implemented in Rust. It targets the `x86`,
//! `x86_64`, and ARM v7 CPU architectures.
//!
//! I'm writing this mostly for fun, to learn more about OS design and kernel
//! hacking, so don't expect anything new or exciting out of this project.
//!
//! SOS is copyright 2015-2017 Eliza Weisman, and is released under the terms
//! of the MIT license.

#![crate_name = "sos_kernel"]

#![doc(html_root_url = "https://hawkw.github.io/sos-kernel/")]

#![feature( lang_items, asm, naked_functions )]
#![feature( linkage )]
#![feature( const_fn
          , slice_patterns
          , associated_consts
          , type_ascription
          , custom_derive )]
#![feature( collections )]

#![cfg_attr(feature="clippy", feature(plugin))]
#![cfg_attr(feature="clippy", plugin(clippy))]
#![cfg_attr( any(target_arch = "x86_64", target_arch="x86")
           , feature(abi_x86_interrupt))]

#![no_std]
#![cfg_attr(not(test), no_main)]

// -- non-SOS dependencies --------------------------------------------------
#[macro_use] extern crate lazy_static;
#[macro_use] extern crate bitflags;
#[macro_use] extern crate log;

extern crate collections;
extern crate rlibc;
extern crate spin;

// -- SOS dependencies ------------------------------------------------------
#[macro_use] extern crate vga;

extern crate alloc;
extern crate cpu;
extern crate elf;
extern crate util;
extern crate memory;

#[macro_use] pub mod io;

pub mod heap;
pub mod params;
pub mod arch;
pub mod logger;

/// SOS version number
pub const VERSION_STRING: &'static str
    = concat!("Stupid Operating System v", env!("CARGO_PKG_VERSION"));

use params::InitParams;

/// Kernel main loop
pub fn kernel_main() -> ! {
    let mut a_vec = collections::vec::Vec::<usize>::new();
    info!(target: "test", "Created a vector in kernel space! {:?}", a_vec);
    a_vec.push(1);
    info!(target: "test", "pushed to vec: {:?}", a_vec);
    a_vec.push(2);
    info!(target: "test", "pushed to vec: {:?}", a_vec);

    loop { }
}

/// Cross-architecture kernel initialization.
///
/// This function is called by the arch specific init function.
pub fn kernel_init(params: &InitParams) {
    kinfoln!("Hello from the kernel!");

    // -- initialize interrupts ----------------------------------------------
    kinfoln!(dots: " . ", "Initializing interrupts:");
    // TODO: this whole function *may* want to just be made `unsafe`...
    unsafe { arch::interrupts::initialize(); };
    kinfoln!(dots: " . ", target: "Enabling interrupts", "[ OKAY ]");

    // -- initialize the heap ------------------------------------------------

    if unsafe { heap::initialize(params) }.is_ok() {
        kinfoln!( dots: " . ", target: "Intializing heap"
                , "[ OKAY ]"
                );
        kinfoln!( dots: " . . "
                , "Heap begins at {:#x} and ends at {:#x}"
                , params.heap_base, params.heap_top);
    } else {
        kinfoln!( dots: " . ", target: "Intializing heap"
                , "[ FAIL ]"
                );
    }

    println!("\n{} {}-bit\n", VERSION_STRING, arch::ARCH_BITS);
    // -- call into kernel main loop ------------------------------------------
    // (currently, this does nothing)
    kernel_main()

}

/// This fake `main` function exists only to placate `cargo test`.
#[cfg(test)]
fn main() {

}
<|endoftext|>


<commit_before>#![cfg_attr(test, deny(warnings))]

extern crate atty;
extern crate chrono;
#[macro_use]
extern crate clap;
extern crate colored;
extern crate doug;
extern crate serde;
extern crate serde_json;

use std::io::stdout;

use atty::Stream;
use clap::{App, AppSettings, Arg, Shell, SubCommand};
use colored::Colorize;

use doug::*;
use std::process;

fn main() {
    if !atty::is(Stream::Stdout) {
        colored::control::set_override(false);
    }

    let mut cli =
        App::new("Doug")
            .version(crate_version!())
            .about("A time tracking command-line utility")
            .author(crate_authors!())
            .settings(&[
                AppSettings::DeriveDisplayOrder,
                AppSettings::GlobalVersion,
                AppSettings::SubcommandRequiredElseHelp,
                AppSettings::VersionlessSubcommands,
                AppSettings::DisableHelpSubcommand,
                AppSettings::ColorAuto,
            ]).arg(
                Arg::with_name("path")
                    .short("p")
                    .long("path")
                    .help("Path to load settings file from. (default: ~/.doug/settings.json)"),
            ).subcommand(
                SubCommand::with_name("start")
                    .about("Track new or existing project")
                    .arg(Arg::with_name("project").help(
                        "project to track. If missing, start subcommand behaves like restart.",
                    )),
            ).subcommand(
                SubCommand::with_name("status")
                    .about("Display elapsed time, start time, and running project name")
                    .arg(
                        Arg::with_name("t")
                            .short("t")
                            .long("time")
                            .help("Print time for currently tracked project."),
                    ).arg(Arg::with_name("s").short("s").long("simple").help(
                        "Print running project name or nothing if there isn't a running project.",
                    )),
            ).subcommand(SubCommand::with_name("stop").about("Stop any running projects"))
            .subcommand(SubCommand::with_name("s").about("Stop any running projects").settings(&[AppSettings::Hidden, AppSettings::HidePossibleValuesInHelp]))
            .subcommand(
                SubCommand::with_name("cancel")
                    .about("Stop running project and remove most recent time interval"),
            ).subcommand(SubCommand::with_name("restart").about("Track last running project"))
            .subcommand(SubCommand::with_name("r").about("Track last running project").settings(&[AppSettings::Hidden, AppSettings::HidePossibleValuesInHelp]))
            .subcommand(
                SubCommand::with_name("log").about("Display time intervals across all projects"),
            ).subcommand(
                SubCommand::with_name("report")
                    .about("Display aggregate time from projects")
                    .arg(
                        Arg::with_name("year")
                            .short("y")
                            .long("year")
                            .help("Limit report to past year. Use multiple to increase interval.")
                            .overrides_with_all(&["month", "week", "day", "from", "to"])
                            .multiple(true),
                    ).arg(
                        Arg::with_name("month")
                            .short("m")
                            .long("month")
                            .help("Limit report to past month. Use multiple to increase interval.")
                            .overrides_with_all(&["year", "week", "day", "from", "to"])
                            .multiple(true),
                    ).arg(
                        Arg::with_name("week")
                            .short("w")
                            .long("week")
                            .help("Limit report to past week. Use multiple to increase interval.")
                            .overrides_with_all(&["year", "month", "day", "from", "to"])
                            .multiple(true),
                    ).arg(
                        Arg::with_name("day")
                            .short("d")
                            .long("day")
                            .help("Limit report to past day. Use multiple to increase interval.")
                            .overrides_with_all(&["year", "month", "week", "from", "to"])
                            .multiple(true),
                    ).arg(
                        Arg::with_name("from")
                            .short("f")
                            .long("from")
                            .help("Date when report should start (e.g. 2018-1-1)")
                            .overrides_with_all(&["year", "month", "week", "day"])
                            .takes_value(true),
                    ).arg(
                        Arg::with_name("to")
                            .short("t")
                            .long("to")
                            .help("Date when report should end (e.g. 2018-1-20)")
                            .overrides_with_all(&["year", "month", "week", "day"])
                            .takes_value(true),
                    ),
            ).subcommand(
                SubCommand::with_name("amend")
                    .about("Change name of currently running project")
                    .arg(
                        Arg::with_name("project")
                            .help("new project name")
                            .required(true),
                    ),
            ).subcommand(
                SubCommand::with_name("edit")
                    .about("Edit last frame or currently running frame")
                    .arg(
                        Arg::with_name("start")
                            .short("s")
                            .long("start")
                            .help("starting date")
                            .takes_value(true),
                    ).arg(
                        Arg::with_name("end")
                            .short("e")
                            .long("end")
                            .help("ending date")
                            .takes_value(true),
                    ),
            )
            .subcommand(
                SubCommand::with_name("settings")
                .about("configure doug settings")
                .arg(
                    Arg::with_name("path")
                    .short("p")
                    .long("path")
                    .takes_value(true)
                    .help("path to store data file")
                    .long_help("path to store data file. this only affects the data file location. settings are stored in $HOME.")
                ).arg(
                    Arg::with_name("clear")
                    .short("c")
                    .long("clear")
                    .help("clear settings file")
                )
            ).subcommand(
                SubCommand::with_name("generate-completions")
                    .about("Generate completions")
                    .arg(
                        Arg::with_name("shell")
                            .help("shell to generate completion for (default: bash).")
                            .short("s")
                            .long("shell")
                            .possible_values(&["bash", "zsh", "fish", "powershell"])
                            .case_insensitive(true)
                            .default_value("bash")
                            .takes_value(true),
                    ),
            ).subcommand(
                SubCommand::with_name("delete")
                    .about("Delete all intervals for project")
                    .arg(
                        Arg::with_name("project")
                            .help("new project name")
                            .required(true),
                    ),
            );

    let matches = cli.clone().get_matches();

    let mut doug = match Doug::new(matches.value_of("path")) {
        Ok(x) => x,
        Err(e) => {
            eprintln!("Error: {}", e);
            process::exit(1)
        }
    };

    let results = match matches.subcommand() {
        ("start", Some(matches)) | ("s", Some(matches)) => match matches.value_of("project") {
            Some(project) => doug.start(project),
            // Restart last project if not argument is provided
            None => doug.restart(),
        },
        ("amend", Some(matches)) => match matches.value_of("project") {
            Some(project) => doug.amend(project),
            None => Err("Missing project name".to_string()),
        },
        ("delete", Some(matches)) => match matches.value_of("project") {
            Some(project) => doug.delete(project),
            None => Err("missing project name".to_string()),
        },
        ("status", Some(matches)) => doug.status(matches.is_present("s"), matches.is_present("t")),
        ("report", Some(matches)) => doug.report(
            matches.occurrences_of("year") as i32,
            matches.occurrences_of("month") as i32,
            matches.occurrences_of("week") as i32,
            matches.occurrences_of("day") as i32,
            matches.value_of("from"),
            matches.value_of("to"),
        ),
        ("generate-completions", Some(matches)) => match matches.value_of("shell") {
            Some("bash") => {
                cli.gen_completions_to("doug", Shell::Bash, &mut stdout());
                Ok(None)
            }
            Some("zsh") => {
                cli.gen_completions_to("doug", Shell::Zsh, &mut stdout());
                Ok(None)
            }
            Some("fish") => {
                cli.gen_completions_to("doug", Shell::Fish, &mut stdout());
                Ok(None)
            }
            Some("powershell") => {
                cli.gen_completions_to("doug", Shell::PowerShell, &mut stdout());
                Ok(None)
            }
            _ => Err("Invalid option".to_string()),
        },
        ("edit", Some(matches)) => doug.edit(matches.value_of("start"), matches.value_of("end")),
        ("stop", Some(_)) => doug.stop(),
        ("cancel", Some(_)) => doug.cancel(),
        ("restart", Some(_)) | ("r", Some(_)) => doug.restart(),
        ("log", Some(_)) => doug.log(),
        ("settings", Some(matches)) => {
            doug.settings(matches.value_of("path"), matches.is_present("clear"))
        }
        (_, Some(_)) | (_, None) => unreachable!(),
    };

    match results {
        Ok(Some(m)) => {
            // There are some inconsistencies for outputs so some commands return new lines and
            // some don't
            println!("{}", m.trim_right())
        }
        // nothing to print
        Ok(None) => {}
        Err(e) => {
            eprintln!("{} {}", "Error:".red(), e);
            process::exit(1)
        }
    }
}
<commit_msg>remove unnecessary `extern crate` usage<commit_after>#![cfg_attr(test, deny(warnings))]

use std::io::stdout;

use atty::Stream;
use clap::{crate_authors, crate_version, App, AppSettings, Arg, Shell, SubCommand};
use colored::Colorize;

use doug::*;
use std::process;

fn main() {
    if !atty::is(Stream::Stdout) {
        colored::control::set_override(false);
    }

    let mut cli =
        App::new("Doug")
            .version(crate_version!())
            .about("A time tracking command-line utility")
            .author(crate_authors!())
            .settings(&[
                AppSettings::DeriveDisplayOrder,
                AppSettings::GlobalVersion,
                AppSettings::SubcommandRequiredElseHelp,
                AppSettings::VersionlessSubcommands,
                AppSettings::DisableHelpSubcommand,
                AppSettings::ColorAuto,
            ]).arg(
                Arg::with_name("path")
                    .short("p")
                    .long("path")
                    .help("Path to load settings file from. (default: ~/.doug/settings.json)"),
            ).subcommand(
                SubCommand::with_name("start")
                    .about("Track new or existing project")
                    .arg(Arg::with_name("project").help(
                        "project to track. If missing, start subcommand behaves like restart.",
                    )),
            ).subcommand(
                SubCommand::with_name("status")
                    .about("Display elapsed time, start time, and running project name")
                    .arg(
                        Arg::with_name("t")
                            .short("t")
                            .long("time")
                            .help("Print time for currently tracked project."),
                    ).arg(Arg::with_name("s").short("s").long("simple").help(
                        "Print running project name or nothing if there isn't a running project.",
                    )),
            ).subcommand(SubCommand::with_name("stop").about("Stop any running projects"))
            .subcommand(SubCommand::with_name("s").about("Stop any running projects").settings(&[AppSettings::Hidden, AppSettings::HidePossibleValuesInHelp]))
            .subcommand(
                SubCommand::with_name("cancel")
                    .about("Stop running project and remove most recent time interval"),
            ).subcommand(SubCommand::with_name("restart").about("Track last running project"))
            .subcommand(SubCommand::with_name("r").about("Track last running project").settings(&[AppSettings::Hidden, AppSettings::HidePossibleValuesInHelp]))
            .subcommand(
                SubCommand::with_name("log").about("Display time intervals across all projects"),
            ).subcommand(
                SubCommand::with_name("report")
                    .about("Display aggregate time from projects")
                    .arg(
                        Arg::with_name("year")
                            .short("y")
                            .long("year")
                            .help("Limit report to past year. Use multiple to increase interval.")
                            .overrides_with_all(&["month", "week", "day", "from", "to"])
                            .multiple(true),
                    ).arg(
                        Arg::with_name("month")
                            .short("m")
                            .long("month")
                            .help("Limit report to past month. Use multiple to increase interval.")
                            .overrides_with_all(&["year", "week", "day", "from", "to"])
                            .multiple(true),
                    ).arg(
                        Arg::with_name("week")
                            .short("w")
                            .long("week")
                            .help("Limit report to past week. Use multiple to increase interval.")
                            .overrides_with_all(&["year", "month", "day", "from", "to"])
                            .multiple(true),
                    ).arg(
                        Arg::with_name("day")
                            .short("d")
                            .long("day")
                            .help("Limit report to past day. Use multiple to increase interval.")
                            .overrides_with_all(&["year", "month", "week", "from", "to"])
                            .multiple(true),
                    ).arg(
                        Arg::with_name("from")
                            .short("f")
                            .long("from")
                            .help("Date when report should start (e.g. 2018-1-1)")
                            .overrides_with_all(&["year", "month", "week", "day"])
                            .takes_value(true),
                    ).arg(
                        Arg::with_name("to")
                            .short("t")
                            .long("to")
                            .help("Date when report should end (e.g. 2018-1-20)")
                            .overrides_with_all(&["year", "month", "week", "day"])
                            .takes_value(true),
                    ),
            ).subcommand(
                SubCommand::with_name("amend")
                    .about("Change name of currently running project")
                    .arg(
                        Arg::with_name("project")
                            .help("new project name")
                            .required(true),
                    ),
            ).subcommand(
                SubCommand::with_name("edit")
                    .about("Edit last frame or currently running frame")
                    .arg(
                        Arg::with_name("start")
                            .short("s")
                            .long("start")
                            .help("starting date")
                            .takes_value(true),
                    ).arg(
                        Arg::with_name("end")
                            .short("e")
                            .long("end")
                            .help("ending date")
                            .takes_value(true),
                    ),
            )
            .subcommand(
                SubCommand::with_name("settings")
                .about("configure doug settings")
                .arg(
                    Arg::with_name("path")
                    .short("p")
                    .long("path")
                    .takes_value(true)
                    .help("path to store data file")
                    .long_help("path to store data file. this only affects the data file location. settings are stored in $HOME.")
                ).arg(
                    Arg::with_name("clear")
                    .short("c")
                    .long("clear")
                    .help("clear settings file")
                )
            ).subcommand(
                SubCommand::with_name("generate-completions")
                    .about("Generate completions")
                    .arg(
                        Arg::with_name("shell")
                            .help("shell to generate completion for (default: bash).")
                            .short("s")
                            .long("shell")
                            .possible_values(&["bash", "zsh", "fish", "powershell"])
                            .case_insensitive(true)
                            .default_value("bash")
                            .takes_value(true),
                    ),
            ).subcommand(
                SubCommand::with_name("delete")
                    .about("Delete all intervals for project")
                    .arg(
                        Arg::with_name("project")
                            .help("new project name")
                            .required(true),
                    ),
            );

    let matches = cli.clone().get_matches();

    let mut doug = match Doug::new(matches.value_of("path")) {
        Ok(x) => x,
        Err(e) => {
            eprintln!("Error: {}", e);
            process::exit(1)
        }
    };

    let results = match matches.subcommand() {
        ("start", Some(matches)) | ("s", Some(matches)) => match matches.value_of("project") {
            Some(project) => doug.start(project),
            // Restart last project if not argument is provided
            None => doug.restart(),
        },
        ("amend", Some(matches)) => match matches.value_of("project") {
            Some(project) => doug.amend(project),
            None => Err("Missing project name".to_string()),
        },
        ("delete", Some(matches)) => match matches.value_of("project") {
            Some(project) => doug.delete(project),
            None => Err("missing project name".to_string()),
        },
        ("status", Some(matches)) => doug.status(matches.is_present("s"), matches.is_present("t")),
        ("report", Some(matches)) => doug.report(
            matches.occurrences_of("year") as i32,
            matches.occurrences_of("month") as i32,
            matches.occurrences_of("week") as i32,
            matches.occurrences_of("day") as i32,
            matches.value_of("from"),
            matches.value_of("to"),
        ),
        ("generate-completions", Some(matches)) => match matches.value_of("shell") {
            Some("bash") => {
                cli.gen_completions_to("doug", Shell::Bash, &mut stdout());
                Ok(None)
            }
            Some("zsh") => {
                cli.gen_completions_to("doug", Shell::Zsh, &mut stdout());
                Ok(None)
            }
            Some("fish") => {
                cli.gen_completions_to("doug", Shell::Fish, &mut stdout());
                Ok(None)
            }
            Some("powershell") => {
                cli.gen_completions_to("doug", Shell::PowerShell, &mut stdout());
                Ok(None)
            }
            _ => Err("Invalid option".to_string()),
        },
        ("edit", Some(matches)) => doug.edit(matches.value_of("start"), matches.value_of("end")),
        ("stop", Some(_)) => doug.stop(),
        ("cancel", Some(_)) => doug.cancel(),
        ("restart", Some(_)) | ("r", Some(_)) => doug.restart(),
        ("log", Some(_)) => doug.log(),
        ("settings", Some(matches)) => {
            doug.settings(matches.value_of("path"), matches.is_present("clear"))
        }
        (_, Some(_)) | (_, None) => unreachable!(),
    };

    match results {
        Ok(Some(m)) => {
            // There are some inconsistencies for outputs so some commands return new lines and
            // some don't
            println!("{}", m.trim_right())
        }
        // nothing to print
        Ok(None) => {}
        Err(e) => {
            eprintln!("{} {}", "Error:".red(), e);
            process::exit(1)
        }
    }
}
<|endoftext|>