<commit_before>// Copyright 2014 Pierre Talbot (IRCAM)

// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at

//     http://www.apache.org/licenses/LICENSE-2.0

// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#![crate_name = "testpeg"]
#![experimental]
#![crate_type = "bin"]

#![feature(phase,globs)]

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

use std::os;
use std::io::File;
use std::io::fs;

use peg::Parser;

pub mod ntcc;

enum ExpectedResult {
  Match,
  PartialMatch,
  Error
}

fn expectation_to_string(expected: ExpectedResult) -> &'static str
{
  match expected {
    Match => "fully match",
    PartialMatch => "partially match",
    Error => "fail"
  }
}

fn parsing_result_to_string<'a>(res: &Result<Option<&'a str>, String>) -> String
{
  match res {
    &Ok(None) => String::from_str("fully matched"),
    &Ok(Some(ref rest)) =>
      format!("partially matched (it remains `{}`)", rest),
    &Err(ref msg) =>
      format!("failed with the error \"{}\"", msg)
  }
}

fn skip_test(test_name: &String, reason: &String)
{
  fail!(format!("[Skip] {}: {}.", test_name, reason));
}

struct Test
{
  name: String,
  parser: Box<Parser>
}

impl Test
{
  fn test_directory(&self, directory: Path, expectation: ExpectedResult)
  {
    match fs::readdir(&directory) {
      Ok(dir_entries) => {
        for entry in dir_entries.iter() {
          if entry.is_file() {
            self.test_file(entry, expectation);
          }
        }
      }
      Err(io_err) => skip_test(&self.name,
        &format!("Impossible to read the directory `{}`, the error is `{}`",
          directory.display(), io_err))
    }
  }

  fn test_file(&self, filepath: &Path, expectation: ExpectedResult)
  {
    let mut file = File::open(filepath);
    match file {
      Err(io_err) => fail!(format!("[Failure] Could not open test `{}`, the error is `{}`",
        filepath.display(), io_err)),
      Ok(ref mut file) => {
        let contents = file.read_to_end();
        match contents {
          Err(io_err) => fail!(format!("[Failure] Could not read test `{}`, the error is `{}`",
            filepath.display(), io_err)),
          Ok(contents) => {
            let utf8_contents = std::str::from_utf8(contents.as_slice());
            self.test_input(utf8_contents.unwrap(), expectation);
          }
        }
      }
    }
  }

  fn test_input(&self, input: &str, expectation: ExpectedResult)
  {
    match (expectation, self.parser.parse(input)) {
      (Match, Ok(None))
    | (PartialMatch, Ok(Some(_)))
    | (Error, Err(_)) => (),
      (_, res) => {
        fail!(format!("Grammar {}: `{}` was expected to {} but {}.",
          self.name, input, expectation_to_string(expectation),
          parsing_result_to_string(&res)));
      }
    }
  }
}

struct TestEngine
{
  test_path : Path,
  tests : Vec<Test>,
  current_test_idx: uint
}

impl TestEngine
{
  fn new(test_path: Path) -> TestEngine
  {
    if !test_path.is_dir() {
      fail!(format!("`{}` is not a valid grammar directory.", test_path.display()));
    }
    TestEngine{
      test_path: test_path,
      tests : Vec::new(),
      current_test_idx : 0
    }
  }

  fn register(&mut self, name: &str, parser: Box<Parser>)
  {
    self.tests.push(Test{name: String::from_str(name), parser: parser});
  }

  fn run(&self)
  {
    for test in self.tests.iter() {
      let path = self.test_path.join(Path::new(test.name.clone()));
      test.test_directory(path.join(Path::new("run-pass")), Match);
      test.test_directory(path.join(Path::new("run-fail")), Error);
    }
  }
}

fn main()
{
  let args = os::args();
  if args.len() != 2 {
    fail!(format!("usage: {} <data-dir>", args.as_slice()[0]));
  }
  let data_path = Path::new(args.as_slice()[1].clone());
  if !data_path.is_dir() {
    fail!(format!("`{}` is not a valid data directory.", data_path.display()));
  }
  let mut test_path = data_path.clone();
  test_path.push("test");
  let mut test_engine = TestEngine::new(test_path);
  test_engine.register("ntcc", box ntcc::ntcc::Parser::new());
  test_engine.run();
}
<commit_msg>[Tests] Better testing messages and nice look and feel.<commit_after>// Copyright 2014 Pierre Talbot (IRCAM)

// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at

//     http://www.apache.org/licenses/LICENSE-2.0

// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#![crate_name = "testpeg"]
#![experimental]
#![crate_type = "bin"]

#![feature(phase,globs)]

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

use std::os;
use std::io::File;
use std::io::fs;
use std::io;

use peg::Parser;

use term::*;

pub mod ntcc;

enum ExpectedResult {
  Match,
  Error
}

struct TestDisplay
{
  terminal: Box<Terminal<WriterWrapper>>,
  code_snippet_len: uint
}

impl TestDisplay
{
  pub fn new(code_snippet_len: uint) -> TestDisplay
  {
    TestDisplay{
      terminal: term::stdout().unwrap(),
      code_snippet_len: code_snippet_len
    }
  }

  pub fn info(&mut self, msg: &String)
  {
    self.write_line(term::color::CYAN, "\n[ info ] ", msg);
  }

  pub fn error(&mut self, msg: &String)
  {
    self.write_line(term::color::RED, "  [ error ] ", msg);
  }

  pub fn path(&mut self, path: &Path)
  {
    self.write_line(term::color::CYAN, "  [ path ] ",
      &format!("{}", path.display()));
  }

  pub fn failure<'a>(&mut self, path: &Path, expectation: ExpectedResult,
    result: &Result<Option<&'a str>, String>)
  {
    let test_name = self.filestem(path);
    self.write_line(term::color::RED, "[ failed ] ", &test_name);
    self.path(path);
    self.expected(expectation);
    self.wrong_result(result);
  }

  fn expected(&mut self, expectation: ExpectedResult)
  {
    let msg = match expectation {
      Match => "Fully match",
      Error => "Error"
    };
    self.write_line(term::color::CYAN, "  [ expected ] ", &format!("{}", msg))
  }

  fn wrong_result<'a>(&mut self, result: &Result<Option<&'a str>, String>)
  {
    let msg = match result {
      &Ok(Some(input)) => format!("Partial match, stopped at `{}`.", self.code_snippet(input)),
      &Ok(None) => format!("Fully matched."),
      &Err(ref msg) => msg.clone()
    };
    self.error(&msg)
  }

  fn code_snippet<'a>(&self, code: &'a str) -> &'a str
  {
    code.slice_to(std::cmp::min(code.len()-1, self.code_snippet_len))
  }

  pub fn success(&mut self, path: &Path)
  {
    let test_name = self.filestem(path);
    self.write_line(term::color::GREEN, "[ passed ] ", &test_name);
  }

  fn filestem(&self, path: &Path) -> String
  {
    format!("{}", path.filestem_str().unwrap())
  }

  pub fn warn(&mut self, msg: &String)
  {
    self.write_line(term::color::MAGENTA, "  [ warning ] ", msg);
  }

  pub fn fs_error(&mut self, msg: &str, path: &Path, io_err: &io::IoError)
  {
    self.system_error(&format!("{}", msg));
    self.path(path);
    self.error(&format!("{}", io_err));
  }

  pub fn system_error(&mut self, msg: &String)
  {
    self.write_line(term::color::RED, "[ system error ] ", msg);
  }

  fn write_line(&mut self, color: color::Color, header: &str, msg: &String)
  {
    self.write_header(color, header);
    self.write_msg(msg.as_slice());
    self.write_msg("\n");
  }

  fn write_header(&mut self, color: color::Color, header: &str)
  {
    self.terminal.fg(color).unwrap();
    self.write_msg(header);
    self.terminal.reset().unwrap();
  }

  fn write_msg(&mut self, msg: &str)
  {
    (write!(self.terminal, "{}", msg)).unwrap();
  }
}

struct GrammarInfo
{
  name: String,
  parser: Box<Parser>
}

struct Test<'a>
{
  info: &'a GrammarInfo,
  display: &'a mut TestDisplay,
}

impl<'a> Test<'a>
{
  fn test_directory(&mut self, start_msg: &String, directory: &Path, expectation: ExpectedResult)
  {
    self.display.info(start_msg);

    match fs::readdir(directory) {
      Ok(dir_entries) => {
        for entry in dir_entries.iter() {
          if entry.is_file() {
            self.test_file(entry, expectation);
          } else {
            self.display.warn(&format!("Entry ignored because it's not a file."));
            self.display.path(entry);
          }
        }
      }
      Err(ref io_err) => {
        self.display.fs_error("Can't read directory.", directory, io_err);
      }
    }
  }

  fn test_file(&mut self, filepath: &Path, expectation: ExpectedResult)
  {
    let mut file = File::open(filepath);
    match file {
      Ok(ref mut file) => {
        let contents = file.read_to_end();
        match contents {
          Ok(contents) => {
            let utf8_contents = std::str::from_utf8(contents.as_slice());
            self.test_input(utf8_contents.unwrap(), expectation, filepath);
          },
          Err(ref io_err) => {
            self.display.fs_error("Can't read file.", filepath, io_err);
          }
        }
      },
      Err(ref io_err) => {
        self.display.fs_error("Can't open file.", filepath, io_err);
      }
    }
  }

  fn test_input(&mut self, input: &str, expectation: ExpectedResult, test_path: &Path)
  {
    match (expectation, self.info.parser.parse(input)) {
      (Match, Ok(None))
    | (Error, Ok(Some(_)))
    | (Error, Err(_)) => self.display.success(test_path),
      (_, ref res) => {
        self.display.failure(test_path, expectation, res);
      }
    }
  }
}

struct TestEngine
{
  test_path : Path,
  grammars : Vec<GrammarInfo>,
  display : TestDisplay
}

impl TestEngine
{
  fn new(test_path: Path) -> TestEngine
  {
    if !test_path.is_dir() {
      fail!(format!("`{}` is not a valid grammar directory.", test_path.display()));
    }
    TestEngine{
      test_path: test_path.clone(),
      grammars : Vec::new(),
      display : TestDisplay::new(20)
    }
  }

  fn register(&mut self, name: &str, parser: Box<Parser>)
  {
    self.grammars.push(GrammarInfo{name: String::from_str(name), parser: parser});
  }

  fn run(&mut self)
  {
    self.display.info(&format!("Start PEG library tests suite."));
    for grammar in self.grammars.iter() {
      let grammar_path = self.test_path.join(Path::new(grammar.name.clone()));
      self.display.info(&format!("Start tests of grammar `{}`", grammar.name));
      self.display.path(&grammar_path);
      let mut test = Test{
        info: grammar,
        display: &mut self.display
      };
      test.test_directory(&format!("Run and Pass tests of `{}`", grammar.name),
        &grammar_path.join(Path::new("run-pass")), Match);
      test.test_directory(&format!("Run and Fail tests of `{}`", grammar.name),
        &grammar_path.join(Path::new("run-fail")), Error);
    }
  }
}

fn main()
{
  let args = os::args();
  if args.len() != 2 {
    fail!(format!("usage: {} <data-dir>", args.as_slice()[0]));
  }
  let data_path = Path::new(args.as_slice()[1].clone());
  if !data_path.is_dir() {
    fail!(format!("`{}` is not a valid data directory.", data_path.display()));
  }
  let mut test_path = data_path.clone();
  test_path.push("test");
  let mut test_engine = TestEngine::new(test_path);
  test_engine.register("ntcc", box ntcc::ntcc::Parser::new());
  test_engine.run();
}
<|endoftext|>


<commit_before><commit_msg>Fix off by one in LockstepArray::pop()<commit_after><|endoftext|>


<commit_before><commit_msg>Update YUV example to work again.<commit_after><|endoftext|>


<commit_before>use irc::parse::IrcMsg;
use rand::{thread_rng, Rng};

use command_mapper::{
    RustBotPlugin,
    CommandMapperDispatch,
    IrcBotConfigurator,
    Format,
    Token,
};

const CMD_8BALL: Token = Token(0);
const ANSWERS: &'static [&'static str] = &[
    "It is certain",
    "It is decidedly so",
    "Without a doubt",
    "Yes, definitely",
    "You may rely on it",
    "As I see it, yes",
    "Most likely",
    "Outlook good",
    "Yes",
    "Signs point to yes",
    "Reply hazy try again",
    "Ask again later",
    "Better not tell you now",
    "Cannot predict now",
    "Concentrate and ask again",
    "Don't count on it",
    "My reply is no",
    "My sources say no",
    "Outlook not so good",
    "Very doubtful",
];

pub struct EightBallPlugin;

impl EightBallPlugin {
    pub fn new() -> EightBallPlugin {
        EightBallPlugin
    }

    pub fn get_plugin_name() -> &'static str {
        "8ball"
    }
}

enum EightBallCommandType {
    EightBall,
}

fn parse_command<'a>(m: &CommandMapperDispatch) -> Option<EightBallCommandType> {
    match m.command().token {
        CMD_8BALL => Some(EightBallCommandType::EightBall),
        _ => None
    }
}

impl RustBotPlugin for EightBallPlugin {
    fn configure(&mut self, conf: &mut IrcBotConfigurator) {
        conf.map_format(CMD_8BALL, Format::from_str("8ball {*query}").ok().unwrap());
    }

    fn dispatch_cmd(&mut self, m: &CommandMapperDispatch, msg: &IrcMsg) {
        match parse_command(m) {
            Some(EightBallCommandType::EightBall) => {
                let prefix = msg.get_prefix();
                let nick = match prefix.nick() {
                    Some(nick) => nick,
                    None => return,
                };
                let answer = match thread_rng().choose(ANSWERS) {
                    Some(answer) => answer,
                    None => return,
                };
                let msg = format!("{}: {}", nick, answer);
                m.reply(&msg);
            },
            None => return
        }
    }
}
<commit_msg>plugin(8ball): supprt command without query<commit_after>use irc::parse::IrcMsg;
use rand::{thread_rng, Rng};

use command_mapper::{
    RustBotPlugin,
    CommandMapperDispatch,
    IrcBotConfigurator,
    Format,
    Token,
};

const CMD_8BALL_QUERY: Token = Token(0);
const CMD_8BALL: Token = Token(1);

const ANSWERS: &'static [&'static str] = &[
    "It is certain",
    "It is decidedly so",
    "Without a doubt",
    "Yes, definitely",
    "You may rely on it",
    "As I see it, yes",
    "Most likely",
    "Outlook good",
    "Yes",
    "Signs point to yes",
    "Reply hazy try again",
    "Ask again later",
    "Better not tell you now",
    "Cannot predict now",
    "Concentrate and ask again",
    "Don't count on it",
    "My reply is no",
    "My sources say no",
    "Outlook not so good",
    "Very doubtful",
];

pub struct EightBallPlugin;

impl EightBallPlugin {
    pub fn new() -> EightBallPlugin {
        EightBallPlugin
    }

    pub fn get_plugin_name() -> &'static str {
        "8ball"
    }
}

enum EightBallCommandType {
    EightBall,
}

fn parse_command<'a>(m: &CommandMapperDispatch) -> Option<EightBallCommandType> {
    match m.command().token {
        CMD_8BALL_QUERY => Some(EightBallCommandType::EightBall),
        CMD_8BALL => Some(EightBallCommandType::EightBall),
        _ => None
    }
}

impl RustBotPlugin for EightBallPlugin {
    fn configure(&mut self, conf: &mut IrcBotConfigurator) {
        conf.map_format(CMD_8BALL_QUERY, Format::from_str("8ball {*query}").ok().unwrap());
        conf.map_format(CMD_8BALL, Format::from_str("8ball").ok().unwrap());
    }

    fn dispatch_cmd(&mut self, m: &CommandMapperDispatch, msg: &IrcMsg) {
        match parse_command(m) {
            Some(EightBallCommandType::EightBall) => {
                let prefix = msg.get_prefix();
                let nick = match prefix.nick() {
                    Some(nick) => nick,
                    None => return,
                };
                let answer = match thread_rng().choose(ANSWERS) {
                    Some(answer) => answer,
                    None => return,
                };
                let msg = format!("{}: {}", nick, answer);
                m.reply(&msg);
            },
            None => return
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>test whitespace config<commit_after><|endoftext|>


<commit_before>//! Builds IR command buffers from Objects and feeds them into the backend.

use renderer::backend::Backend;
use renderer::ir::{AddCommands, CommandEncoder, CommandQueue};
use renderer::types::Buffer;

/// A light source.
#[derive(Clone)]
pub enum Light {
    Area,
    Directional {
        color: [f32; 4],
        direction: [f32; 3],
        intensity: f32,
    },
    Point {
        color: [f32; 4],
        intensity: f32,
        location: [f32; 3],
    },
    Spot {
        angle: f32,
        color: [f32; 4],
        direction: [f32; 3],
        intensity: f32,
        location: [f32; 3],
    },
}

/// A physical renderable object.
#[derive(Clone)]
pub enum Object {
    Emitter,
    IndexedMesh {
        indices: Buffer,
        vertices: Buffer,
    },
    Mesh {
        vertices: Buffer,
    },
    Sprite,
}

/// A collection of lights and objects to be rendered by the frontend.
pub struct Frame {
    pub lights: Vec<Light>,
    pub objects: Vec<Object>,
}

impl Frame {
    pub fn new() -> Frame {
        Frame {
            lights: Vec::new(),
            objects: Vec::new(),
        }
    }
}

/// Simple renderer frontend.
pub struct Frontend {
    backend: Box<Backend>,
    queue: CommandQueue,
}

impl Frontend {
    pub fn new<T: 'static>(backend: T) -> Frontend
        where T: Backend
    {
        Frontend {
            backend: Box::new(backend),
            queue: CommandQueue::new(),
        }
    }

    pub fn load_render_path(&mut self) {
        unimplemented!();
    }

    /// Draws a frame with the currently set render path. TODO: Build actual
    /// modular, parallelized Object translators.
    pub fn draw(&mut self, frame: Frame) {
        for light in frame.lights {
            self.queue.submit(match light {
                Light::Area => CommandEncoder::new().finish(),
                Light::Directional { col, dir, int } => CommandEncoder::new().finish(),
                Light::Point { col, int, loc } => CommandEncoder::new().finish(),
                Light::Spot { ang, col, dir, int, loc } => CommandEncoder::new().finish(),
            });
        }

        for obj in frame.objects {
            self.queue.submit(match obj {
                Object::Emitter => CommandEncoder::new().finish(),
                Object::IndexedMesh { inds, verts } => {
                    CommandEncoder::new()
                        .set_buffer(inds)
                        .set_buffer(verts)
                        .draw_indexed(0, 0, 0)
                        .finish()
                }
                Object::Mesh { verts } => {
                    CommandEncoder::new()
                        .set_buffer(verts)
                        .draw(0, 0)
                        .finish()
                }
                Object::Sprite => {
                    CommandEncoder::new()
                        .draw(0, 3)
                        .finish()
                }
            });
        }

        let commands = self.queue.sort_and_flush();
        self.backend.process(commands);
    }
}
<commit_msg>fix variable names in match<commit_after>//! Builds IR command buffers from Objects and feeds them into the backend.

use renderer::backend::Backend;
use renderer::ir::{AddCommands, CommandEncoder, CommandQueue};
use renderer::types::Buffer;

/// A light source.
#[derive(Clone)]
pub enum Light {
    Area,
    Directional {
        color: [f32; 4],
        direction: [f32; 3],
        intensity: f32,
    },
    Point {
        color: [f32; 4],
        intensity: f32,
        location: [f32; 3],
    },
    Spot {
        angle: f32,
        color: [f32; 4],
        direction: [f32; 3],
        intensity: f32,
        location: [f32; 3],
    },
}

/// A physical renderable object.
#[derive(Clone)]
pub enum Object {
    Emitter,
    IndexedMesh {
        indices: Buffer,
        vertices: Buffer,
    },
    Mesh {
        vertices: Buffer,
    },
    Sprite,
}

/// A collection of lights and objects to be rendered by the frontend.
pub struct Frame {
    pub lights: Vec<Light>,
    pub objects: Vec<Object>,
}

impl Frame {
    pub fn new() -> Frame {
        Frame {
            lights: Vec::new(),
            objects: Vec::new(),
        }
    }
}

/// Simple renderer frontend.
pub struct Frontend {
    backend: Box<Backend>,
    queue: CommandQueue,
}

impl Frontend {
    pub fn new<T: 'static>(backend: T) -> Frontend
        where T: Backend
    {
        Frontend {
            backend: Box::new(backend),
            queue: CommandQueue::new(),
        }
    }

    pub fn load_render_path(&mut self) {
        unimplemented!();
    }

    /// Draws a frame with the currently set render path. TODO: Build actual
    /// modular, parallelized Object translators.
    pub fn draw(&mut self, frame: Frame) {
        for light in frame.lights {
            self.queue.submit(match light {
                Light::Area => CommandEncoder::new().finish(),
                Light::Directional { color, direction, intensity } => {
                    CommandEncoder::new().finish()
                }
                Light::Point { color, intensity, location } => {
                    CommandEncoder::new().finish()
                }
                Light::Spot { angle, color, direction, intensity, location } => {
                    CommandEncoder::new().finish()
                }
            });
        }

        for obj in frame.objects {
            self.queue.submit(match obj {
                Object::Emitter => CommandEncoder::new().finish(),
                Object::IndexedMesh { indices, vertices } => {
                    CommandEncoder::new()
                        .set_buffer(indices)
                        .set_buffer(vertices)
                        .draw_indexed(0, 0, 0)
                        .finish()
                }
                Object::Mesh { vertices } => {
                    CommandEncoder::new()
                        .set_buffer(vertices)
                        .draw(0, 0)
                        .finish()
                }
                Object::Sprite => {
                    CommandEncoder::new()
                        .draw(0, 3)
                        .finish()
                }
            });
        }

        let commands = self.queue.sort_and_flush();
        self.backend.process(commands);
    }
}
<|endoftext|>


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

#![allow(non_snake_case)]

register_long_diagnostics! {
E0454: r##"
A link name was given with an empty name. Erroneous code example:

```compile_fail,E0454
#[link(name = "")] extern {} // error: #[link(name = "")] given with empty name
```

The rust compiler cannot link to an external library if you don't give it its
name. Example:

```ignore
#[link(name = "some_lib")] extern {} // ok!
```
"##,

E0455: r##"
Linking with `kind=framework` is only supported when targeting OS X,
as frameworks are specific to that operating system.

Erroneous code example:

```compile_fail,E0455
#[link(name = "FooCoreServices",  kind = "framework")] extern {}
// OS used to compile is Linux for example
```

To solve this error you can use conditional compilation:

```
#[cfg_attr(target="macos", link(name = "FooCoreServices", kind = "framework"))]
extern {}
```

See more: https://doc.rust-lang.org/book/conditional-compilation.html
"##,

E0458: r##"
An unknown "kind" was specified for a link attribute. Erroneous code example:

```compile_fail,E0458
#[link(kind = "wonderful_unicorn")] extern {}
// error: unknown kind: `wonderful_unicorn`
```

Please specify a valid "kind" value, from one of the following:
 * static
 * dylib
 * framework
"##,

E0459: r##"
A link was used without a name parameter. Erroneous code example:

```compile_fail,E0459
#[link(kind = "dylib")] extern {}
// error: #[link(...)] specified without `name = "foo"`
```

Please add the name parameter to allow the rust compiler to find the library
you want. Example:

```ignore
#[link(kind = "dylib", name = "some_lib")] extern {} // ok!
```
"##,

E0463: r##"
A plugin/crate was declared but cannot be found. Erroneous code example:

```compile_fail,E0463
#![feature(plugin)]
#![plugin(cookie_monster)] // error: can't find crate for `cookie_monster`
extern crate cake_is_a_lie; // error: can't find crate for `cake_is_a_lie`
```

You need to link your code to the relevant crate in order to be able to use it
(through Cargo or the `-L` option of rustc example). Plugins are crates as
well, and you link to them the same way.
"##,

E0466: r##"
Macro import declarations were malformed.

Erroneous code examples:

```compile_fail,E0466
#[macro_use(a_macro(another_macro))] // error: invalid import declaration
extern crate some_crate;

#[macro_use(i_want = "some_macros")] // error: invalid import declaration
extern crate another_crate;
```

This is a syntax error at the level of attribute declarations. The proper
syntax for macro imports is the following:

```ignore
// In some_crate:
#[macro_export]
macro_rules! get_tacos {
    ...
}

#[macro_export]
macro_rules! get_pimientos {
    ...
}

// In your crate:
#[macro_use(get_tacos, get_pimientos)] // It imports `get_tacos` and
extern crate some_crate;               // `get_pimientos` macros from some_crate
```

If you would like to import all exported macros, write `macro_use` with no
arguments.
"##,

E0467: r##"
Macro reexport declarations were empty or malformed.

Erroneous code examples:

```compile_fail,E0467
#[macro_reexport]                    // error: no macros listed for export
extern crate macros_for_good;

#[macro_reexport(fun_macro = "foo")] // error: not a macro identifier
extern crate other_macros_for_good;
```

This is a syntax error at the level of attribute declarations.

Currently, `macro_reexport` requires at least one macro name to be listed.
Unlike `macro_use`, listing no names does not reexport all macros from the
given crate.

Decide which macros you would like to export and list them properly.

These are proper reexport declarations:

```ignore
#[macro_reexport(some_macro, another_macro)]
extern crate macros_for_good;
```
"##,

E0468: r##"
A non-root module attempts to import macros from another crate.

Example of erroneous code:

```compile_fail,E0468
mod foo {
    #[macro_use(helpful_macro)] // error: must be at crate root to import
    extern crate some_crate;    //        macros from another crate
    helpful_macro!(...)
}
```

Only `extern crate` imports at the crate root level are allowed to import
macros.

Either move the macro import to crate root or do without the foreign macros.
This will work:

```ignore
#[macro_use(helpful_macro)]
extern crate some_crate;

mod foo {
    helpful_macro!(...)
}
```
"##,

E0469: r##"
A macro listed for import was not found.

Erroneous code example:

```compile_fail,E0469
#[macro_use(drink, be_merry)] // error: imported macro not found
extern crate collections;

fn main() {
    // ...
}
```

Either the listed macro is not contained in the imported crate, or it is not
exported from the given crate.

This could be caused by a typo. Did you misspell the macro's name?

Double-check the names of the macros listed for import, and that the crate
in question exports them.

A working version would be:

```ignore
// In some_crate crate:
#[macro_export]
macro_rules! eat {
    ...
}

#[macro_export]
macro_rules! drink {
    ...
}

// In your crate:
#[macro_use(eat, drink)]
extern crate some_crate; //ok!
```
"##,

E0470: r##"
A macro listed for reexport was not found.

Erroneous code example:

```compile_fail,E0470
#[macro_reexport(drink, be_merry)]
extern crate collections;

fn main() {
    // ...
}
```

Either the listed macro is not contained in the imported crate, or it is not
exported from the given crate.

This could be caused by a typo. Did you misspell the macro's name?

Double-check the names of the macros listed for reexport, and that the crate
in question exports them.

A working version:

```ignore
// In some_crate crate:
#[macro_export]
macro_rules! eat {
    ...
}

#[macro_export]
macro_rules! drink {
    ...
}

// In your_crate:
#[macro_reexport(eat, drink)]
extern crate some_crate;
```
"##,

}

register_diagnostics! {
    E0456, // plugin `..` is not available for triple `..`
    E0457, // plugin `..` only found in rlib format, but must be available...
    E0514, // metadata version mismatch
    E0460, // found possibly newer version of crate `..`
    E0461, // couldn't find crate `..` with expected target triple ..
    E0462, // found staticlib `..` instead of rlib or dylib
    E0464, // multiple matching crates for `..`
    E0465, // multiple .. candidates for `..` found
    E0519, // local crate and dependency have same (crate-name, disambiguator)
    E0523, // two dependencies have same (crate-name, disambiguator) but different SVH
}
<commit_msg>Ignore this block code because of OSX failure<commit_after>// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![allow(non_snake_case)]

register_long_diagnostics! {
E0454: r##"
A link name was given with an empty name. Erroneous code example:

```compile_fail,E0454
#[link(name = "")] extern {} // error: #[link(name = "")] given with empty name
```

The rust compiler cannot link to an external library if you don't give it its
name. Example:

```ignore
#[link(name = "some_lib")] extern {} // ok!
```
"##,

E0455: r##"
Linking with `kind=framework` is only supported when targeting OS X,
as frameworks are specific to that operating system.

Erroneous code example:

```ignore
#[link(name = "FooCoreServices", kind = "framework")] extern {}
// OS used to compile is Linux for example
```

To solve this error you can use conditional compilation:

```
#[cfg_attr(target="macos", link(name = "FooCoreServices", kind = "framework"))]
extern {}
```

See more: https://doc.rust-lang.org/book/conditional-compilation.html
"##,

E0458: r##"
An unknown "kind" was specified for a link attribute. Erroneous code example:

```compile_fail,E0458
#[link(kind = "wonderful_unicorn")] extern {}
// error: unknown kind: `wonderful_unicorn`
```

Please specify a valid "kind" value, from one of the following:
 * static
 * dylib
 * framework
"##,

E0459: r##"
A link was used without a name parameter. Erroneous code example:

```compile_fail,E0459
#[link(kind = "dylib")] extern {}
// error: #[link(...)] specified without `name = "foo"`
```

Please add the name parameter to allow the rust compiler to find the library
you want. Example:

```ignore
#[link(kind = "dylib", name = "some_lib")] extern {} // ok!
```
"##,

E0463: r##"
A plugin/crate was declared but cannot be found. Erroneous code example:

```compile_fail,E0463
#![feature(plugin)]
#![plugin(cookie_monster)] // error: can't find crate for `cookie_monster`
extern crate cake_is_a_lie; // error: can't find crate for `cake_is_a_lie`
```

You need to link your code to the relevant crate in order to be able to use it
(through Cargo or the `-L` option of rustc example). Plugins are crates as
well, and you link to them the same way.
"##,

E0466: r##"
Macro import declarations were malformed.

Erroneous code examples:

```compile_fail,E0466
#[macro_use(a_macro(another_macro))] // error: invalid import declaration
extern crate some_crate;

#[macro_use(i_want = "some_macros")] // error: invalid import declaration
extern crate another_crate;
```

This is a syntax error at the level of attribute declarations. The proper
syntax for macro imports is the following:

```ignore
// In some_crate:
#[macro_export]
macro_rules! get_tacos {
    ...
}

#[macro_export]
macro_rules! get_pimientos {
    ...
}

// In your crate:
#[macro_use(get_tacos, get_pimientos)] // It imports `get_tacos` and
extern crate some_crate;               // `get_pimientos` macros from some_crate
```

If you would like to import all exported macros, write `macro_use` with no
arguments.
"##,

E0467: r##"
Macro reexport declarations were empty or malformed.

Erroneous code examples:

```compile_fail,E0467
#[macro_reexport]                    // error: no macros listed for export
extern crate macros_for_good;

#[macro_reexport(fun_macro = "foo")] // error: not a macro identifier
extern crate other_macros_for_good;
```

This is a syntax error at the level of attribute declarations.

Currently, `macro_reexport` requires at least one macro name to be listed.
Unlike `macro_use`, listing no names does not reexport all macros from the
given crate.

Decide which macros you would like to export and list them properly.

These are proper reexport declarations:

```ignore
#[macro_reexport(some_macro, another_macro)]
extern crate macros_for_good;
```
"##,

E0468: r##"
A non-root module attempts to import macros from another crate.

Example of erroneous code:

```compile_fail,E0468
mod foo {
    #[macro_use(helpful_macro)] // error: must be at crate root to import
    extern crate some_crate;    //        macros from another crate
    helpful_macro!(...)
}
```

Only `extern crate` imports at the crate root level are allowed to import
macros.

Either move the macro import to crate root or do without the foreign macros.
This will work:

```ignore
#[macro_use(helpful_macro)]
extern crate some_crate;

mod foo {
    helpful_macro!(...)
}
```
"##,

E0469: r##"
A macro listed for import was not found.

Erroneous code example:

```compile_fail,E0469
#[macro_use(drink, be_merry)] // error: imported macro not found
extern crate collections;

fn main() {
    // ...
}
```

Either the listed macro is not contained in the imported crate, or it is not
exported from the given crate.

This could be caused by a typo. Did you misspell the macro's name?

Double-check the names of the macros listed for import, and that the crate
in question exports them.

A working version would be:

```ignore
// In some_crate crate:
#[macro_export]
macro_rules! eat {
    ...
}

#[macro_export]
macro_rules! drink {
    ...
}

// In your crate:
#[macro_use(eat, drink)]
extern crate some_crate; //ok!
```
"##,

E0470: r##"
A macro listed for reexport was not found.

Erroneous code example:

```compile_fail,E0470
#[macro_reexport(drink, be_merry)]
extern crate collections;

fn main() {
    // ...
}
```

Either the listed macro is not contained in the imported crate, or it is not
exported from the given crate.

This could be caused by a typo. Did you misspell the macro's name?

Double-check the names of the macros listed for reexport, and that the crate
in question exports them.

A working version:

```ignore
// In some_crate crate:
#[macro_export]
macro_rules! eat {
    ...
}

#[macro_export]
macro_rules! drink {
    ...
}

// In your_crate:
#[macro_reexport(eat, drink)]
extern crate some_crate;
```
"##,

}

register_diagnostics! {
    E0456, // plugin `..` is not available for triple `..`
    E0457, // plugin `..` only found in rlib format, but must be available...
    E0514, // metadata version mismatch
    E0460, // found possibly newer version of crate `..`
    E0461, // couldn't find crate `..` with expected target triple ..
    E0462, // found staticlib `..` instead of rlib or dylib
    E0464, // multiple matching crates for `..`
    E0465, // multiple .. candidates for `..` found
    E0519, // local crate and dependency have same (crate-name, disambiguator)
    E0523, // two dependencies have same (crate-name, disambiguator) but different SVH
}
<|endoftext|>


<commit_before>// 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 super::symbolcontext::SBSymbolContext;
use sys;

/// A list of [symbol contexts].
///
/// [symbol contexts]: struct.SBSymbolContext.html
#[derive(Debug)]
pub struct SBSymbolContextList {
    /// The underlying raw `SBSymbolContextListRef`.
    pub raw: sys::SBSymbolContextListRef,
}

impl SBSymbolContextList {
    /// Construct a new `Some(SBSymbolContextList)` or `None`.
    pub fn maybe_wrap(raw: sys::SBSymbolContextListRef) -> Option<SBSymbolContextList> {
        if unsafe { sys::SBSymbolContextListIsValid(raw) } {
            Some(SBSymbolContextList { raw })
        } else {
            None
        }
    }

    /// Check whether or not this is a valid `SBSymbolContextList`.
    pub fn is_valid(&self) -> bool {
        unsafe { sys::SBSymbolContextListIsValid(self.raw) }
    }

    #[allow(missing_docs)]
    pub fn append(&self, context: &SBSymbolContext) {
        unsafe { sys::SBSymbolContextListAppend(self.raw, context.raw) };
    }

    #[allow(missing_docs)]
    pub fn append_list(&self, contexts: &SBSymbolContextList) {
        unsafe { sys::SBSymbolContextListAppendList(self.raw, contexts.raw) };
    }

    /// Is this context list empty?
    pub fn is_empty(&self) -> bool {
        unsafe { sys::SBSymbolContextListGetSize(self.raw) == 0 }
    }

    /// Clear this context list.
    pub fn clear(&self) {
        unsafe { sys::SBSymbolContextListClear(self.raw) };
    }

    #[allow(missing_docs)]
    pub fn get_context_at_index(&self, idx: u32) -> Option<SBSymbolContext> {
        SBSymbolContext::maybe_wrap(unsafe {
            sys::SBSymbolContextListGetContextAtIndex(self.raw, idx)
        })
    }

    /// Iterate over this context list.
    pub fn iter(&self) -> SBSymbolContextListIter {
        SBSymbolContextListIter {
            context_list: self,
            idx: 0,
        }
    }
}

impl Clone for SBSymbolContextList {
    fn clone(&self) -> SBSymbolContextList {
        SBSymbolContextList {
            raw: unsafe { sys::CloneSBSymbolContextList(self.raw) },
        }
    }
}

impl Drop for SBSymbolContextList {
    fn drop(&mut self) {
        unsafe { sys::DisposeSBSymbolContextList(self.raw) };
    }
}

impl From<sys::SBSymbolContextListRef> for SBSymbolContextList {
    fn from(raw: sys::SBSymbolContextListRef) -> SBSymbolContextList {
        SBSymbolContextList { raw }
    }
}

unsafe impl Send for SBSymbolContextList {}
unsafe impl Sync for SBSymbolContextList {}

/// An iterator over the [contexts] in an [`SBSymbolContextList`].
///
/// [contexts]: struct.SBSymbolContext.html
/// [`SBSymbolContextList`]: struct.SBSymbolContextList.html
pub struct SBSymbolContextListIter<'d> {
    context_list: &'d SBSymbolContextList,
    idx: usize,
}

impl<'d> Iterator for SBSymbolContextListIter<'d> {
    type Item = SBSymbolContext;

    fn next(&mut self) -> Option<SBSymbolContext> {
        if self.idx < unsafe { sys::SBSymbolContextListGetSize(self.context_list.raw) as usize } {
            let r = SBSymbolContext::from(unsafe {
                sys::SBSymbolContextListGetContextAtIndex(self.context_list.raw, self.idx as u32)
            });
            self.idx += 1;
            Some(r)
        } else {
            None
        }
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        let sz = unsafe { sys::SBSymbolContextListGetSize(self.context_list.raw) } as usize;
        (sz - self.idx, Some(sz))
    }
}

impl<'d> ExactSizeIterator for SBSymbolContextListIter<'d> {}
<commit_msg>Remove SBSymbolContextList::get_context_at_index.<commit_after>// 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 super::symbolcontext::SBSymbolContext;
use sys;

/// A list of [symbol contexts].
///
/// [symbol contexts]: struct.SBSymbolContext.html
#[derive(Debug)]
pub struct SBSymbolContextList {
    /// The underlying raw `SBSymbolContextListRef`.
    pub raw: sys::SBSymbolContextListRef,
}

impl SBSymbolContextList {
    /// Construct a new `Some(SBSymbolContextList)` or `None`.
    pub fn maybe_wrap(raw: sys::SBSymbolContextListRef) -> Option<SBSymbolContextList> {
        if unsafe { sys::SBSymbolContextListIsValid(raw) } {
            Some(SBSymbolContextList { raw })
        } else {
            None
        }
    }

    /// Check whether or not this is a valid `SBSymbolContextList`.
    pub fn is_valid(&self) -> bool {
        unsafe { sys::SBSymbolContextListIsValid(self.raw) }
    }

    #[allow(missing_docs)]
    pub fn append(&self, context: &SBSymbolContext) {
        unsafe { sys::SBSymbolContextListAppend(self.raw, context.raw) };
    }

    #[allow(missing_docs)]
    pub fn append_list(&self, contexts: &SBSymbolContextList) {
        unsafe { sys::SBSymbolContextListAppendList(self.raw, contexts.raw) };
    }

    /// Is this context list empty?
    pub fn is_empty(&self) -> bool {
        unsafe { sys::SBSymbolContextListGetSize(self.raw) == 0 }
    }

    /// Clear this context list.
    pub fn clear(&self) {
        unsafe { sys::SBSymbolContextListClear(self.raw) };
    }

    /// Iterate over this context list.
    pub fn iter(&self) -> SBSymbolContextListIter {
        SBSymbolContextListIter {
            context_list: self,
            idx: 0,
        }
    }
}

impl Clone for SBSymbolContextList {
    fn clone(&self) -> SBSymbolContextList {
        SBSymbolContextList {
            raw: unsafe { sys::CloneSBSymbolContextList(self.raw) },
        }
    }
}

impl Drop for SBSymbolContextList {
    fn drop(&mut self) {
        unsafe { sys::DisposeSBSymbolContextList(self.raw) };
    }
}

impl From<sys::SBSymbolContextListRef> for SBSymbolContextList {
    fn from(raw: sys::SBSymbolContextListRef) -> SBSymbolContextList {
        SBSymbolContextList { raw }
    }
}

unsafe impl Send for SBSymbolContextList {}
unsafe impl Sync for SBSymbolContextList {}

/// An iterator over the [contexts] in an [`SBSymbolContextList`].
///
/// [contexts]: struct.SBSymbolContext.html
/// [`SBSymbolContextList`]: struct.SBSymbolContextList.html
pub struct SBSymbolContextListIter<'d> {
    context_list: &'d SBSymbolContextList,
    idx: usize,
}

impl<'d> Iterator for SBSymbolContextListIter<'d> {
    type Item = SBSymbolContext;

    fn next(&mut self) -> Option<SBSymbolContext> {
        if self.idx < unsafe { sys::SBSymbolContextListGetSize(self.context_list.raw) as usize } {
            let r = SBSymbolContext::from(unsafe {
                sys::SBSymbolContextListGetContextAtIndex(self.context_list.raw, self.idx as u32)
            });
            self.idx += 1;
            Some(r)
        } else {
            None
        }
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        let sz = unsafe { sys::SBSymbolContextListGetSize(self.context_list.raw) } as usize;
        (sz - self.idx, Some(sz))
    }
}

impl<'d> ExactSizeIterator for SBSymbolContextListIter<'d> {}
<|endoftext|>


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

// no-system-llvm
// compile-flags: -O
#![crate_type = "lib"]

fn search<T: Ord + Eq>(arr: &mut [T], a: &T) -> Result<usize, ()> {
    match arr.iter().position(|x| x == a) {
        Some(p) => {
            Ok(p)
        },
        None => Err(()),
    }
}

// CHECK-LABEL: @position_no_bounds_check
#[no_mangle]
pub fn position_no_bounds_check(y: &mut [u32], x: &u32, z: &u32) -> bool {
    // This contains "call assume" so we cannot just rule out all calls
    // CHECK-NOT: panic
    if let Ok(p) = search(y, x) {
      y[p] == *z
    } else {
      false
    }
}

// just to make sure that panicking really emits "panic" somewhere in the IR
// CHECK-LABEL: @test_check
#[no_mangle]
pub fn test_check() {
    // CHECK: panic
    unreachable!()
}
<commit_msg>hopefully make test pass on windows<commit_after>// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// no-system-llvm
// compile-flags: -O -C panic=abort
#![crate_type = "lib"]

fn search<T: Ord + Eq>(arr: &mut [T], a: &T) -> Result<usize, ()> {
    match arr.iter().position(|x| x == a) {
        Some(p) => {
            Ok(p)
        },
        None => Err(()),
    }
}

// CHECK-LABEL: @position_no_bounds_check
#[no_mangle]
pub fn position_no_bounds_check(y: &mut [u32], x: &u32, z: &u32) -> bool {
    // This contains "call assume" so we cannot just rule out all calls
    // CHECK-NOT: panic_bounds_check
    if let Ok(p) = search(y, x) {
      y[p] == *z
    } else {
      false
    }
}

// just to make sure that panicking really emits "panic_bounds_check" somewhere in the IR
// CHECK-LABEL: @test_check
#[no_mangle]
pub fn test_check(y: &[i32]) -> i32 {
    // CHECK: panic_bounds_check
    y[12]
}
<|endoftext|>


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

// ensure that the ThreadRng isn't/doesn't become accidentally sendable.

use std::rand; //~ ERROR: module `rand` is private

fn test_send<S: Send>() {}

pub fn main() {
    test_send::<rand::ThreadRng>();
}
<commit_msg>Fix test `compile-fail/task-rng-isnt-sendable.rs`.<commit_after>// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// ensure that the ThreadRng isn't/doesn't become accidentally sendable.

use std::__rand::ThreadRng;

fn test_send<S: Send>() {}

pub fn main() {
    test_send::<ThreadRng>(); //~ ERROR std::marker::Send` is not satisfied
}
<|endoftext|>


<commit_before>trait TraitA {
    fn method_a() -> int;
}

trait TraitB {
    fn gimme_an_a<A: TraitA>(a: A) -> int;
}

impl int: TraitB {
    fn gimme_an_a<A: TraitA>(a: A) -> int {
        a.method_a() + self
    }
}

fn call_it<B: TraitB>(b: B)  -> int {
    let y = 4u;
    b.gimme_an_a(y) //~ ERROR failed to find an implementation of trait @TraitA for uint
}

fn main() {
    let x = 3i;
    assert call_it(x) == 22;
}
<commit_msg>test: Fix error message in vtable-res-trait-param<commit_after>trait TraitA {
    fn method_a() -> int;
}

trait TraitB {
    fn gimme_an_a<A: TraitA>(a: A) -> int;
}

impl int: TraitB {
    fn gimme_an_a<A: TraitA>(a: A) -> int {
        a.method_a() + self
    }
}

fn call_it<B: TraitB>(b: B)  -> int {
    let y = 4u;
    b.gimme_an_a(y) //~ ERROR failed to find an implementation of trait @TraitA
}

fn main() {
    let x = 3i;
    assert call_it(x) == 22;
}
<|endoftext|>


<commit_before>use crate::{
    analysis::{rust_type::RustType, trampoline_parameters::Transformation},
    env::Env,
    library,
    nameutil::is_gstring,
    traits::*,
};

pub trait TrampolineFromGlib {
    fn trampoline_from_glib(&self, env: &Env, need_downcast: bool, nullable: bool) -> String;
}

impl TrampolineFromGlib for Transformation {
    fn trampoline_from_glib(&self, env: &Env, need_downcast: bool, nullable: bool) -> String {
        use crate::analysis::conversion_type::ConversionType::*;
        let need_type_name = need_downcast || is_need_type_name(env, self.typ);
        match self.conversion_type {
            Direct => self.name.clone(),
            Scalar | Option | Result { .. } => format!("from_glib({})", self.name),
            Borrow | Pointer => {
                let is_borrow = self.conversion_type == Borrow;
                let need_type_name = need_type_name || (is_borrow && nullable);
                let (mut left, mut right) = from_glib_xxx(self.transfer, is_borrow);
                let type_name = RustType::try_new(env, self.typ).into_string();
                if need_type_name {
                    if is_borrow && nullable {
                        left = format!("Option::<{}>::{}", type_name, left);
                    } else {
                        left = format!("{}::{}", type_name, left);
                    }
                }

                if !nullable {
                    left = format!(
                        "{}{}",
                        if need_downcast && is_borrow { "" } else { "&" },
                        left
                    );
                } else if nullable && is_borrow {
                    if is_gstring(&type_name) {
                        right = format!("{}.as_ref().as_ref().map(|s| s.as_str())", right);
                    } else {
                        right = format!("{}.as_ref().as_ref()", right);
                    }
                } else if is_gstring(&type_name) {
                    right = format!("{}.as_str()", right);
                } else {
                    right = format!("{}.as_ref()", right);
                }

                if need_downcast && is_borrow {
                    right = format!("{}.unsafe_cast_ref()", right);
                } else if need_downcast {
                    right = format!("{}.unsafe_cast()", right);
                }

                format!("{}{}{}", left, self.name, right)
            }
            Unknown => format!("/*Unknown conversion*/{}", self.name),
        }
    }
}

pub fn from_glib_xxx(transfer: library::Transfer, is_borrow: bool) -> (String, String) {
    use crate::library::Transfer::*;
    match transfer {
        None if is_borrow => ("from_glib_borrow(".into(), ")".into()),
        None => ("from_glib_none(".into(), ")".into()),
        Full => ("from_glib_full(".into(), ")".into()),
        Container => ("from_glib_container(".into(), ")".into()),
    }
}

fn is_need_type_name(env: &Env, type_id: library::TypeId) -> bool {
    if type_id.ns_id == library::INTERNAL_NAMESPACE {
        use crate::library::{Fundamental::*, Type::*};
        matches!(env.type_(type_id), Fundamental(Utf8 | Filename | OsString))
    } else {
        false
    }
}
<commit_msg>trampoline_from_glib: Fix non-Borrowed GString<commit_after>use crate::{
    analysis::{rust_type::RustType, trampoline_parameters::Transformation},
    env::Env,
    library,
    nameutil::is_gstring,
    traits::*,
};

pub trait TrampolineFromGlib {
    fn trampoline_from_glib(&self, env: &Env, need_downcast: bool, nullable: bool) -> String;
}

impl TrampolineFromGlib for Transformation {
    fn trampoline_from_glib(&self, env: &Env, need_downcast: bool, nullable: bool) -> String {
        use crate::analysis::conversion_type::ConversionType::*;
        let need_type_name = need_downcast || is_need_type_name(env, self.typ);
        match self.conversion_type {
            Direct => self.name.clone(),
            Scalar | Option | Result { .. } => format!("from_glib({})", self.name),
            Borrow | Pointer => {
                let is_borrow = self.conversion_type == Borrow;
                let need_type_name = need_type_name || (is_borrow && nullable);
                let (mut left, mut right) = from_glib_xxx(self.transfer, is_borrow);
                let type_name = RustType::try_new(env, self.typ).into_string();
                if need_type_name {
                    if is_borrow && nullable {
                        left = format!("Option::<{}>::{}", type_name, left);
                    } else {
                        left = format!("{}::{}", type_name, left);
                    }
                }

                if !nullable {
                    left = format!(
                        "{}{}",
                        if need_downcast && is_borrow { "" } else { "&" },
                        left
                    );
                } else if nullable && is_borrow {
                    if is_gstring(&type_name) {
                        right = format!("{}.as_ref().as_ref().map(|s| s.as_str())", right);
                    } else {
                        right = format!("{}.as_ref().as_ref()", right);
                    }
                } else if is_gstring(&type_name) {
                    right = format!("{}.as_ref().map(|s| s.as_str())", right);
                } else {
                    right = format!("{}.as_ref()", right);
                }

                if need_downcast && is_borrow {
                    right = format!("{}.unsafe_cast_ref()", right);
                } else if need_downcast {
                    right = format!("{}.unsafe_cast()", right);
                }

                format!("{}{}{}", left, self.name, right)
            }
            Unknown => format!("/*Unknown conversion*/{}", self.name),
        }
    }
}

pub fn from_glib_xxx(transfer: library::Transfer, is_borrow: bool) -> (String, String) {
    use crate::library::Transfer::*;
    match transfer {
        None if is_borrow => ("from_glib_borrow(".into(), ")".into()),
        None => ("from_glib_none(".into(), ")".into()),
        Full => ("from_glib_full(".into(), ")".into()),
        Container => ("from_glib_container(".into(), ")".into()),
    }
}

fn is_need_type_name(env: &Env, type_id: library::TypeId) -> bool {
    if type_id.ns_id == library::INTERNAL_NAMESPACE {
        use crate::library::{Fundamental::*, Type::*};
        matches!(env.type_(type_id), Fundamental(Utf8 | Filename | OsString))
    } else {
        false
    }
}
<|endoftext|>


<commit_before>use kay::{ID, Recipient, Actor, Fate};
use kay::swarm::{Swarm, SubActor, CreateWith};
use descartes::{N, Band, Curve, Into2d, FiniteCurve, Path, RoughlyComparable};
use core::geometry::{CPath, AnyShape};

use super::{SelectableStrokeRef, CurrentPlan};

#[derive(SubActor, Compact, Clone)]
pub struct Selectable {
    _id: Option<ID>,
    stroke_ref: SelectableStrokeRef,
    path: CPath,
}

impl Selectable {
    pub fn new(stroke_ref: SelectableStrokeRef, path: CPath) -> Self {
        Selectable {
            _id: None,
            stroke_ref: stroke_ref,
            path: path,
        }
    }
}

use super::InitInteractable;
use core::ui::Add;

impl Recipient<InitInteractable> for Selectable {
    fn receive(&mut self, _msg: &InitInteractable) -> Fate {
        ::core::ui::UserInterface::id() <<
        Add::Interactable3d(self.id(),
                            AnyShape::Band(Band::new(self.path.clone(), 5.0)),
                            3);
        Fate::Live
    }
}

use super::ClearInteractable;
use core::ui::Remove;

impl Recipient<ClearInteractable> for Selectable {
    fn receive(&mut self, _msg: &ClearInteractable) -> Fate {
        ::core::ui::UserInterface::id() << Remove::Interactable3d(self.id());
        Fate::Die
    }
}

use core::ui::Event3d;
use super::{ChangeIntent, Intent, IntentProgress, ContinuationMode};

const START_END_SNAP_DISTANCE: N = 10.0;
const SEGMENT_SNAP_DISTANCE: N = 5.0;
const CONTINUE_DISTANCE: N = 6.0;
const MIN_SELECTION_SIZE: N = 2.0;
const SELECTION_OVERSHOOT_TOLERANCE: N = 30.0;

impl Recipient<Event3d> for Selectable {
    fn receive(&mut self, msg: &Event3d) -> Fate {
        match *msg {
            Event3d::DragOngoing { from, to } => {
                if let (Some(selection_start), Some(selection_end)) =
                    (self.path
                         .project_with_tolerance(from.into_2d(), SELECTION_OVERSHOOT_TOLERANCE),
                     self.path.project_with_tolerance(to.into_2d(), SELECTION_OVERSHOOT_TOLERANCE)) {
                    let mut start = selection_start.min(selection_end);
                    let mut end = selection_end.max(selection_start);
                    snap_start_end(&mut start, &mut end, &self.path);
                    CurrentPlan::id() <<
                    ChangeIntent(Intent::Select(self.stroke_ref, start, end),
                                 IntentProgress::Preview);
                } else {
                    CurrentPlan::id() << ChangeIntent(Intent::None, IntentProgress::Preview);
                }
                Fate::Live
            }
            Event3d::DragFinished { from, to } => {
                if let (Some(selection_start), Some(selection_end)) =
                    (self.path
                         .project_with_tolerance(from.into_2d(), SELECTION_OVERSHOOT_TOLERANCE),
                     self.path.project_with_tolerance(to.into_2d(), SELECTION_OVERSHOOT_TOLERANCE)) {
                    let mut start = selection_start.min(selection_end);
                    let mut end = selection_end.max(selection_start);
                    if end < CONTINUE_DISTANCE {
                        CurrentPlan::id() <<
                        ChangeIntent(Intent::ContinueRoadAround(self.stroke_ref,
                                                                ContinuationMode::Prepend,
                                                                to.into_2d()),
                                     IntentProgress::Finished);
                    } else if start > self.path.length() - CONTINUE_DISTANCE {
                        CurrentPlan::id() <<
                        ChangeIntent(Intent::ContinueRoadAround(self.stroke_ref,
                                                                ContinuationMode::Append,
                                                                to.into_2d()),
                                     IntentProgress::Finished);
                    } else {
                        snap_start_end(&mut start, &mut end, &self.path);
                        start = start.min(end - MIN_SELECTION_SIZE).max(0.0);
                        end = end.max(start + MIN_SELECTION_SIZE).min(self.path.length());
                        CurrentPlan::id() <<
                        ChangeIntent(Intent::Select(self.stroke_ref, start, end),
                                     IntentProgress::Immediate);
                    }
                }
                Fate::Live
            }
            _ => Fate::Live,
        }
    }
}

fn snap_start_end(start: &mut N, end: &mut N, path: &CPath) {
    if *start < START_END_SNAP_DISTANCE {
        *start = 0.0
    }
    if *end > path.length() - START_END_SNAP_DISTANCE {
        *end = path.length()
    }
    let mut offset = 0.0;
    for segment in path.segments() {
        let next_offset = offset + segment.length();
        if start.is_roughly_within(offset, SEGMENT_SNAP_DISTANCE) {
            *start = offset
        }
        if end.is_roughly_within(next_offset, SEGMENT_SNAP_DISTANCE) {
            *end = next_offset
        }
        offset = next_offset;
    }
}

pub fn setup() {
    Swarm::<Selectable>::register_default();
    Swarm::<Selectable>::handle::<CreateWith<Selectable, InitInteractable>>();
    Swarm::<Selectable>::handle::<ClearInteractable>();
    Swarm::<Selectable>::handle::<Event3d>();
}
<commit_msg>rustfmt<commit_after>use kay::{ID, Recipient, Actor, Fate};
use kay::swarm::{Swarm, SubActor, CreateWith};
use descartes::{N, Band, Curve, Into2d, FiniteCurve, Path, RoughlyComparable};
use core::geometry::{CPath, AnyShape};

use super::{SelectableStrokeRef, CurrentPlan};

#[derive(SubActor, Compact, Clone)]
pub struct Selectable {
    _id: Option<ID>,
    stroke_ref: SelectableStrokeRef,
    path: CPath,
}

impl Selectable {
    pub fn new(stroke_ref: SelectableStrokeRef, path: CPath) -> Self {
        Selectable {
            _id: None,
            stroke_ref: stroke_ref,
            path: path,
        }
    }
}

use super::InitInteractable;
use core::ui::Add;

impl Recipient<InitInteractable> for Selectable {
    fn receive(&mut self, _msg: &InitInteractable) -> Fate {
        ::core::ui::UserInterface::id() <<
        Add::Interactable3d(self.id(),
                            AnyShape::Band(Band::new(self.path.clone(), 5.0)),
                            3);
        Fate::Live
    }
}

use super::ClearInteractable;
use core::ui::Remove;

impl Recipient<ClearInteractable> for Selectable {
    fn receive(&mut self, _msg: &ClearInteractable) -> Fate {
        ::core::ui::UserInterface::id() << Remove::Interactable3d(self.id());
        Fate::Die
    }
}

use core::ui::Event3d;
use super::{ChangeIntent, Intent, IntentProgress, ContinuationMode};

const START_END_SNAP_DISTANCE: N = 10.0;
const SEGMENT_SNAP_DISTANCE: N = 5.0;
const CONTINUE_DISTANCE: N = 6.0;
const MIN_SELECTION_SIZE: N = 2.0;
const SELECTION_OVERSHOOT_TOLERANCE: N = 30.0;

impl Recipient<Event3d> for Selectable {
    fn receive(&mut self, msg: &Event3d) -> Fate {
        match *msg {
            Event3d::DragOngoing { from, to } => {
                if let (Some(selection_start), Some(selection_end)) =
                    (self.path
                         .project_with_tolerance(from.into_2d(), SELECTION_OVERSHOOT_TOLERANCE),
                     self.path
                         .project_with_tolerance(to.into_2d(), SELECTION_OVERSHOOT_TOLERANCE)) {
                    let mut start = selection_start.min(selection_end);
                    let mut end = selection_end.max(selection_start);
                    snap_start_end(&mut start, &mut end, &self.path);
                    CurrentPlan::id() <<
                    ChangeIntent(Intent::Select(self.stroke_ref, start, end),
                                 IntentProgress::Preview);
                } else {
                    CurrentPlan::id() << ChangeIntent(Intent::None, IntentProgress::Preview);
                }
                Fate::Live
            }
            Event3d::DragFinished { from, to } => {
                if let (Some(selection_start), Some(selection_end)) =
                    (self.path
                         .project_with_tolerance(from.into_2d(), SELECTION_OVERSHOOT_TOLERANCE),
                     self.path
                         .project_with_tolerance(to.into_2d(), SELECTION_OVERSHOOT_TOLERANCE)) {
                    let mut start = selection_start.min(selection_end);
                    let mut end = selection_end.max(selection_start);
                    if end < CONTINUE_DISTANCE {
                        CurrentPlan::id() <<
                        ChangeIntent(Intent::ContinueRoadAround(self.stroke_ref,
                                                                ContinuationMode::Prepend,
                                                                to.into_2d()),
                                     IntentProgress::Finished);
                    } else if start > self.path.length() - CONTINUE_DISTANCE {
                        CurrentPlan::id() <<
                        ChangeIntent(Intent::ContinueRoadAround(self.stroke_ref,
                                                                ContinuationMode::Append,
                                                                to.into_2d()),
                                     IntentProgress::Finished);
                    } else {
                        snap_start_end(&mut start, &mut end, &self.path);
                        start = start.min(end - MIN_SELECTION_SIZE).max(0.0);
                        end = end.max(start + MIN_SELECTION_SIZE).min(self.path.length());
                        CurrentPlan::id() <<
                        ChangeIntent(Intent::Select(self.stroke_ref, start, end),
                                     IntentProgress::Immediate);
                    }
                }
                Fate::Live
            }
            _ => Fate::Live,
        }
    }
}

fn snap_start_end(start: &mut N, end: &mut N, path: &CPath) {
    if *start < START_END_SNAP_DISTANCE {
        *start = 0.0
    }
    if *end > path.length() - START_END_SNAP_DISTANCE {
        *end = path.length()
    }
    let mut offset = 0.0;
    for segment in path.segments() {
        let next_offset = offset + segment.length();
        if start.is_roughly_within(offset, SEGMENT_SNAP_DISTANCE) {
            *start = offset
        }
        if end.is_roughly_within(next_offset, SEGMENT_SNAP_DISTANCE) {
            *end = next_offset
        }
        offset = next_offset;
    }
}

pub fn setup() {
    Swarm::<Selectable>::register_default();
    Swarm::<Selectable>::handle::<CreateWith<Selectable, InitInteractable>>();
    Swarm::<Selectable>::handle::<ClearInteractable>();
    Swarm::<Selectable>::handle::<Event3d>();
}
<|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.
//
//! `x86_64` architecture-specific implementation.
// pub mod cpu;
pub mod drivers;
pub mod interrupts;

#[path = "../x86_all/bda.rs"] pub mod bda;
#[path = "../x86_all/multiboot2.rs"] pub mod multiboot2;

pub const ARCH_BITS: u8 = 64;

extern {
    // TODO: It would be really nice if there was a less ugly way of doing
    // this... (read: after the Revolution when we add memory regions to the
    // heap programmatically.)
    #[link_name = "heap_base_addr"]
    #[linkage = "external"]
    pub static HEAP_BASE: *mut u8;
    #[link_name = "heap_top_addr"]
    #[linkage = "external"]
    pub static HEAP_TOP: *mut u8;
    // Of course, we will still need to export the kernel stack addresses like
    // this, but it would be nice if they could be, i dont know, not mut u8s
    // pointers, like God intended.
    #[link_name = "stack_base"]
    pub static STACK_BASE: *mut u8;
    #[link_name = "stack_top"]
    pub static STACK_TOP: *mut u8;
}

use memory::PAddr;

/// Trampoline to ensure we have a correct stack frame for calling [`arch_init`]
///
/// I have no idea why this works, but it does.
///
/// [`arch_init`]: fn.arch_init
#[naked]
#[no_mangle]
pub unsafe extern "C" fn long_mode_init() {
    asm!("movabsq $$(stack_top), %rsp");
    asm!("mov ax, 0
          mov ss, ax
          mov ds, ax
          mov es, ax
          mov fs, ax
          mov gs, ax
          call arch_init"
        :::: "intel");

}

/// Entry point for architecture-specific kernel init
///
/// This 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.
#[no_mangle]
pub extern "C" fn arch_init(multiboot_addr: PAddr) {
    use cpu::{control_regs, msr};
    use elf;
    use params::InitParams;

    kinfoln!(dots: " . ", "Beginning `arch_init()` for x86_64");

    ::io::term::CONSOLE.lock().clear();
    ::logger::initialize()
        .expect("Could not initialize logger!");

    // -- Unpack multiboot tag ------------------------------------------------
    kinfoln!( dots: " . "
            , "trying to unpack multiboot info at {:?}"
            , multiboot_addr);

    // try to interpret the structure at the multiboot address as a multiboot
    // info struct. if it's invalid, fail.
    let boot_info
        = unsafe { multiboot2::Info::from(multiboot_addr)
                    .expect("Could not unpack multiboot2 information!") };

    // Extract the memory map tag from the multiboot info
    let mem_map = boot_info.mem_map()
                           .expect("Memory map tag required!");

    kinfoln!(dots: " . ", "Detected memory areas:");
    for area in mem_map {
        kinfoln!( dots: " . . ", "{}", area);
        // TODO: add memory map to init params here
    }

    // Extract ELF sections tag from the multiboot info
    let elf_sections_tag
        = boot_info.elf_sections()
                   .expect("ELF sections tag required!");

    kinfoln!(dots: " . ", "Detecting kernel ELF sections:");

    // Extract kernel ELF sections from  multiboot info
    let mut n_elf_sections = 0;

    let kernel_begin
        = elf_sections_tag.sections()
            .filter(|s| s.is_allocated())
            .map(|s| {
                kinfoln!( dots: " . . ", "{}", s );
                kinfoln!( dots: " . . . ", "flags: [ {:?} ]", s.flags());
                s.address() })
            .min()
            .expect("Could not find kernel start section!\
                    \nSomething is deeply wrong.");

    let kernel_end
        = elf_sections_tag.sections()
            .filter(|s| s.is_allocated())
            .map(|s| { n_elf_sections += 1; s.address() })
            .max()
            .expect("Could not find kernel end section!\
                    \nSomething is deeply wrong.");

    kinfoln!( dots: " . ", "Detected {} kernel ELF sections.", n_elf_sections);
    kinfoln!( dots: " . . ", "Kernel begins at {:#p} and ends at {:#p}."
            , kernel_begin.addr(), kernel_end.addr() );

    let multiboot_end = multiboot_addr + boot_info.length as u64;

    kinfoln!( dots: " . . ", "Multiboot info begins at {:#x} and ends at {:#x}."
            , multiboot_addr, multiboot_end);

    let params = InitParams { kernel_base: kernel_begin.addr()
                            , kernel_top: kernel_end.addr()
                            , multiboot_start: Some(multiboot_addr)
                            , multiboot_end: Some(multiboot_end)
                            , heap_base: unsafe { PAddr::from(HEAP_BASE) }
                            , heap_top: unsafe { PAddr::from(HEAP_TOP) }
                            , stack_base: unsafe { PAddr::from(STACK_BASE) }
                            , stack_top: unsafe { PAddr::from(STACK_TOP) }
                            , ..Default::default()
                            };

     // -- enable flags needed for paging ------------------------------------
     unsafe {
         control_regs::cr0::enable_write_protect(true);
         kinfoln!(dots: " . ", "Page write protect ENABED" );

         msr::enable_nxe();
         kinfoln!(dots: " . ", "Page no execute bit ENABLED");
     }

    kinfoln!(dots: " . ", "Transferring to `kernel_init()`.");
    ::kernel_init(params);
}
<commit_msg>fix(x86_64::arch_init): update to match APIs that changed on master<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.
//
//! `x86_64` architecture-specific implementation.
// pub mod cpu;
pub mod drivers;
pub mod interrupts;

#[path = "../x86_all/bda.rs"] pub mod bda;
#[path = "../x86_all/multiboot2.rs"] pub mod multiboot2;

pub const ARCH_BITS: u8 = 64;

extern {
    // TODO: It would be really nice if there was a less ugly way of doing
    // this... (read: after the Revolution when we add memory regions to the
    // heap programmatically.)
    #[link_name = "heap_base_addr"]
    #[linkage = "external"]
    pub static HEAP_BASE: *mut u8;
    #[link_name = "heap_top_addr"]
    #[linkage = "external"]
    pub static HEAP_TOP: *mut u8;
    // Of course, we will still need to export the kernel stack addresses like
    // this, but it would be nice if they could be, i dont know, not mut u8s
    // pointers, like God intended.
    #[link_name = "stack_base"]
    pub static STACK_BASE: *mut u8;
    #[link_name = "stack_top"]
    pub static STACK_TOP: *mut u8;
}

use memory::PAddr;

/// Trampoline to ensure we have a correct stack frame for calling [`arch_init`]
///
/// I have no idea why this works, but it does.
///
/// [`arch_init`]: fn.arch_init
#[naked]
#[no_mangle]
pub unsafe extern "C" fn long_mode_init() {
    asm!("movabsq $$(stack_top), %rsp");
    asm!("mov ax, 0
          mov ss, ax
          mov ds, ax
          mov es, ax
          mov fs, ax
          mov gs, ax
          call arch_init"
        :::: "intel");

}

/// Entry point for architecture-specific kernel init
///
/// This 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.
#[no_mangle]
pub extern "C" fn arch_init(multiboot_addr: PAddr) {
    use cpu::{control_regs, msr};
    use elf;
    use params::InitParams;

    kinfoln!(dots: " . ", "Beginning `arch_init()` for x86_64");

    ::io::term::CONSOLE.lock().clear();
    ::logger::initialize()
        .expect("Could not initialize logger!");

    // -- Unpack multiboot tag ------------------------------------------------
    kinfoln!( dots: " . "
            , "trying to unpack multiboot info at {:?}"
            , multiboot_addr);

    // try to interpret the structure at the multiboot address as a multiboot
    // info struct. if it's invalid, fail.
    let boot_info
        = unsafe { multiboot2::Info::from(multiboot_addr)
                    .expect("Could not unpack multiboot2 information!") };

    // Extract the memory map tag from the multiboot info
    let mem_map = boot_info.mem_map()
                           .expect("Memory map tag required!");

    kinfoln!(dots: " . ", "Detected memory areas:");
    for area in mem_map {
        kinfoln!( dots: " . . ", "{}", area);
        // TODO: add memory map to init params here
    }

    // Extract ELF sections tag from the multiboot info
    let elf_sections_tag
        = boot_info.elf_sections()
                   .expect("ELF sections tag required!");

    kinfoln!(dots: " . ", "Detecting kernel ELF sections:");

    // Extract kernel ELF sections from  multiboot info
    let mut n_elf_sections = 0;

    let kernel_begin
        = elf_sections_tag.sections()
            .filter(|s| s.is_allocated())
            .map(|s| {
                kinfoln!( dots: " . . ", "{}", s );
                kinfoln!( dots: " . . . ", "flags: [ {:?} ]", s.flags());
                s.address() })
            .min()
            .expect("Could not find kernel start section!\
                    \nSomething is deeply wrong.");

    let kernel_end
        = elf_sections_tag.sections()
            .filter(|s| s.is_allocated())
            .map(|s| { n_elf_sections += 1; s.address() })
            .max()
            .expect("Could not find kernel end section!\
                    \nSomething is deeply wrong.");

    kinfoln!( dots: " . ", "Detected {} kernel ELF sections.", n_elf_sections);
    kinfoln!( dots: " . . ", "Kernel begins at {:#p} and ends at {:#p}."
            , kernel_begin, kernel_end );

    let multiboot_end = multiboot_addr + boot_info.length as u64;

    kinfoln!( dots: " . . ", "Multiboot info begins at {:#x} and ends at {:#x}."
            , multiboot_addr, multiboot_end);

    let params = InitParams { kernel_base: kernel_begin
                            , kernel_top: kernel_end
                            , multiboot_start: Some(multiboot_addr)
                            , multiboot_end: Some(multiboot_end)
                            , heap_base: unsafe { PAddr::from(HEAP_BASE) }
                            , heap_top: unsafe { PAddr::from(HEAP_TOP) }
                            , stack_base: unsafe { PAddr::from(STACK_BASE) }
                            , stack_top: unsafe { PAddr::from(STACK_TOP) }
                            , ..Default::default()
                            };

     // -- enable flags needed for paging ------------------------------------
     unsafe {
         control_regs::cr0::enable_write_protect(true);
         kinfoln!(dots: " . ", "Page write protect ENABED" );

         msr::enable_nxe();
         kinfoln!(dots: " . ", "Page no execute bit ENABLED");
     }

    kinfoln!(dots: " . ", "Transferring to `kernel_init()`.");
    ::kernel_init(&params);
}
<|endoftext|>