<commit_before>use std::fmt::Debug;
use std::net::SocketAddr;

use outcome::{self, IntoOutcome};
use request::Request;
use outcome::Outcome::*;

use http::{Status, ContentType, Method, Cookies, Session};
use http::uri::URI;

/// Type alias for the `Outcome` of a `FromRequest` conversion.
pub type Outcome<S, E> = outcome::Outcome<S, (Status, E), ()>;

impl<S, E> IntoOutcome<S, (Status, E), ()> for Result<S, E> {
    fn into_outcome(self) -> Outcome<S, E> {
        match self {
            Ok(val) => Success(val),
            Err(val) => Failure((Status::BadRequest, val))
        }
    }
}

/// Trait used to derive an object from incoming request metadata.
///
/// An arbitrary number of types that implement this trait can appear as
/// parameters in a route handler, as illustrated below:
///
/// ```rust,ignore
/// #[get("/")]
/// fn index(a: A, b: B, c: C) -> ... { ... }
/// ```
///
/// In this example, `A`, `B`, and `C` can be any types that implements
/// `FromRequest`. There can be any number of `FromRequest` types in the
/// function signature. Note that unlike every other derived object in Rocket,
/// `FromRequest` parameter names do not need to be declared in the route
/// attribute.
///
/// Derivation of `FromRequest` arguments is always attemped in left-to-right
/// declaration order. In the example above, for instance, the order will be `a`
/// followed by `b` followed by `c`. If a deriviation fails, the following
/// aren't attempted.
///
/// # Outcomes
///
/// The returned [Outcome](/rocket/outcome/index.html) of a `from_request` call
/// determines how the incoming request will be processed.
///
/// * **Success**(S)
///
///   If the `Outcome` is `Success`, then the `Success` value will be used as
///   the value for the corresponding parameter.  As long as all other parsed
///   types succeed, the request will be handled.
///
/// * **Failure**(Status, E)
///
///   If the `Outcome` is `Failure`, the request will fail with the given status
///   code and error. The designated error
///   [Catcher](/rocket/struct.Catcher.html) will be used to respond to the
///   request. Note that users can request types of `Result<S, E>` and
///   `Option<S>` to catch `Failure`s and retrieve the error value.
///
/// * **Forward**
///
///   If the `Outcome` is `Forward`, the request will be forwarded to the next
///   matching request. Note that users can request an `Option<S>` to catch
///   `Forward`s.
///
/// # Provided Implementations
///
/// Rocket implements `FromRequest` for several built-in types. Their behavior
/// is documented here.
///
///   * **&URI**
///
///     Extracts the [URI](/rocket/http/uri/struct.URI.html) from the incoming
///     request.
///
///     _This implementation always returns successfully._
///
///   * **Method**
///
///     Extracts the [Method](/rocket/http/enum.Method.html) from the incoming
///     request.
///
///     _This implementation always returns successfully._
///
///   * **Cookies**
///
///     Returns a borrow to the [Cookies](/rocket/http/type.Cookies.html) in the
///     incoming request. Note that `Cookies` implements internal mutability, so
///     a handle to `Cookies` allows you to get _and_ set cookies in the
///     request.
///
///     _This implementation always returns successfully._
///
///   * **ContentType**
///
///     Extracts the [ContentType](/rocket/http/struct.ContentType.html) from
///     the incoming request. If the request didn't specify a Content-Type, the
///     request is forwarded.
///
///   * **SocketAddr**
///
///     Extracts the remote address of the incoming request as a `SocketAddr`.
///     If the remote address is not known, the request is forwarded.
///
///     _This implementation always returns successfully._
///
///   * **Option<T>** _where_ **T: FromRequest**
///
///     The type `T` is derived from the incoming request using `T`'s
///     `FromRequest` implementation. If the derivation is a `Success`, the
///     dervived value is returned in `Some`. Otherwise, a `None` is returned.
///
///     _This implementation always returns successfully._
///
///   * **Result<T, T::Error>** _where_ **T: FromRequest**
///
///     The type `T` is derived from the incoming request using `T`'s
///     `FromRequest` implementation. If derivation is a `Success`, the value is
///     returned in `Ok`. If the derivation is a `Failure`, the error value is
///     returned in `Err`. If the derivation is a `Forward`, the request is
///     forwarded.
///
/// # Example
///
/// Imagine you're running an authenticated API service that requires that some
/// requests be sent along with a valid API key in a header field. You want to
/// ensure that the handlers corresponding to these requests don't get called
/// unless there is an API key in the request and the key is valid. The
/// following example implements this using an `APIKey` type and a `FromRequest`
/// implementation for that type. The `APIKey` type is then used in the
/// `senstive` handler.
///
/// ```rust
/// # #![feature(plugin)]
/// # #![plugin(rocket_codegen)]
/// # extern crate rocket;
/// #
/// use rocket::Outcome;
/// use rocket::http::Status;
/// use rocket::request::{self, Request, FromRequest};
///
/// struct APIKey(String);
///
/// /// Returns true if `key` is a valid API key string.
/// fn is_valid(key: &str) -> bool {
///     key == "valid_api_key"
/// }
///
/// impl<'a, 'r> FromRequest<'a, 'r> for APIKey {
///     type Error = ();
///
///     fn from_request(request: &'a Request<'r>) -> request::Outcome<APIKey, ()> {
///         let keys: Vec<_> = request.headers().get("x-api-key").collect();
///         if keys.len() != 1 {
///             return Outcome::Failure((Status::BadRequest, ()));
///         }
///
///         let key = keys[0];
///         if !is_valid(keys[0]) {
///             return Outcome::Forward(());
///         }
///
///         return Outcome::Success(APIKey(key.to_string()));
///     }
/// }
///
/// #[get("/sensitive")]
/// fn sensitive(key: APIKey) -> &'static str {
/// #   let _key = key;
///     "Sensitive data."
/// }
///
/// # fn main() { }
/// ```
pub trait FromRequest<'a, 'r>: Sized {
    /// The associated error to be returned if derivation fails.
    type Error: Debug;

    /// Derives an instance of `Self` from the incoming request metadata.
    ///
    /// If the derivation is successful, an outcome of `Success` is returned. If
    /// the derivation fails in an unrecoverable fashion, `Failure` is returned.
    /// `Forward` is returned to indicate that the request should be forwarded
    /// to other matching routes, if any.
    fn from_request(request: &'a Request<'r>) -> Outcome<Self, Self::Error>;
}

impl<'a, 'r> FromRequest<'a, 'r> for &'a URI<'a> {
    type Error = ();

    fn from_request(request: &'a Request<'r>) -> Outcome<Self, Self::Error> {
        Success(request.uri())
    }
}

impl<'a, 'r> FromRequest<'a, 'r> for Method {
    type Error = ();

    fn from_request(request: &'a Request<'r>) -> Outcome<Self, Self::Error> {
        Success(request.method())
    }
}

impl<'a, 'r> FromRequest<'a, 'r> for Cookies<'a> {
    type Error = ();

    fn from_request(request: &'a Request<'r>) -> Outcome<Self, Self::Error> {
        Success(request.cookies())
    }
}

impl<'a, 'r> FromRequest<'a, 'r> for Session<'a> {
    type Error = ();

    fn from_request(request: &'a Request<'r>) -> Outcome<Self, Self::Error> {
        Success(request.session())
    }
}

impl<'a, 'r> FromRequest<'a, 'r> for ContentType {
    type Error = ();

    fn from_request(request: &'a Request<'r>) -> Outcome<Self, Self::Error> {
        match request.content_type() {
            Some(content_type) => Success(content_type),
            None => Forward(())
        }
    }
}

impl<'a, 'r> FromRequest<'a, 'r> for SocketAddr {
    type Error = ();

    fn from_request(request: &'a Request<'r>) -> Outcome<Self, Self::Error> {
        match request.remote() {
            Some(addr) => Success(addr),
            None => Forward(())
        }
    }
}

impl<'a, 'r, T: FromRequest<'a, 'r>> FromRequest<'a, 'r> for Result<T, T::Error> {
    type Error = ();

    fn from_request(request: &'a Request<'r>) -> Outcome<Self, Self::Error> {
        match T::from_request(request) {
            Success(val) => Success(Ok(val)),
            Failure((_, e)) => Success(Err(e)),
            Forward(_) => Forward(()),
        }
    }
}

impl<'a, 'r, T: FromRequest<'a, 'r>> FromRequest<'a, 'r> for Option<T> {
    type Error = ();

    fn from_request(request: &'a Request<'r>) -> Outcome<Self, Self::Error> {
        match T::from_request(request) {
            Success(val) => Success(Some(val)),
            Failure(_) | Forward(_) => Success(None),
        }
    }
}

<commit_msg>Implement FromRequest for Accept.<commit_after>use std::fmt::Debug;
use std::net::SocketAddr;

use outcome::{self, IntoOutcome};
use request::Request;
use outcome::Outcome::*;

use http::{Status, ContentType, Accept, Method, Cookies, Session};
use http::uri::URI;

/// Type alias for the `Outcome` of a `FromRequest` conversion.
pub type Outcome<S, E> = outcome::Outcome<S, (Status, E), ()>;

impl<S, E> IntoOutcome<S, (Status, E), ()> for Result<S, E> {
    fn into_outcome(self) -> Outcome<S, E> {
        match self {
            Ok(val) => Success(val),
            Err(val) => Failure((Status::BadRequest, val))
        }
    }
}

/// Trait used to derive an object from incoming request metadata.
///
/// An arbitrary number of types that implement this trait can appear as
/// parameters in a route handler, as illustrated below:
///
/// ```rust,ignore
/// #[get("/")]
/// fn index(a: A, b: B, c: C) -> ... { ... }
/// ```
///
/// In this example, `A`, `B`, and `C` can be any types that implements
/// `FromRequest`. There can be any number of `FromRequest` types in the
/// function signature. Note that unlike every other derived object in Rocket,
/// `FromRequest` parameter names do not need to be declared in the route
/// attribute.
///
/// Derivation of `FromRequest` arguments is always attemped in left-to-right
/// declaration order. In the example above, for instance, the order will be `a`
/// followed by `b` followed by `c`. If a deriviation fails, the following
/// aren't attempted.
///
/// # Outcomes
///
/// The returned [Outcome](/rocket/outcome/index.html) of a `from_request` call
/// determines how the incoming request will be processed.
///
/// * **Success**(S)
///
///   If the `Outcome` is `Success`, then the `Success` value will be used as
///   the value for the corresponding parameter.  As long as all other parsed
///   types succeed, the request will be handled.
///
/// * **Failure**(Status, E)
///
///   If the `Outcome` is `Failure`, the request will fail with the given status
///   code and error. The designated error
///   [Catcher](/rocket/struct.Catcher.html) will be used to respond to the
///   request. Note that users can request types of `Result<S, E>` and
///   `Option<S>` to catch `Failure`s and retrieve the error value.
///
/// * **Forward**
///
///   If the `Outcome` is `Forward`, the request will be forwarded to the next
///   matching request. Note that users can request an `Option<S>` to catch
///   `Forward`s.
///
/// # Provided Implementations
///
/// Rocket implements `FromRequest` for several built-in types. Their behavior
/// is documented here.
///
///   * **&URI**
///
///     Extracts the [URI](/rocket/http/uri/struct.URI.html) from the incoming
///     request.
///
///     _This implementation always returns successfully._
///
///   * **Method**
///
///     Extracts the [Method](/rocket/http/enum.Method.html) from the incoming
///     request.
///
///     _This implementation always returns successfully._
///
///   * **Cookies**
///
///     Returns a borrow to the [Cookies](/rocket/http/type.Cookies.html) in the
///     incoming request. Note that `Cookies` implements internal mutability, so
///     a handle to `Cookies` allows you to get _and_ set cookies in the
///     request.
///
///     _This implementation always returns successfully._
///
///   * **ContentType**
///
///     Extracts the [ContentType](/rocket/http/struct.ContentType.html) from
///     the incoming request. If the request didn't specify a Content-Type, the
///     request is forwarded.
///
///   * **SocketAddr**
///
///     Extracts the remote address of the incoming request as a `SocketAddr`.
///     If the remote address is not known, the request is forwarded.
///
///     _This implementation always returns successfully._
///
///   * **Option<T>** _where_ **T: FromRequest**
///
///     The type `T` is derived from the incoming request using `T`'s
///     `FromRequest` implementation. If the derivation is a `Success`, the
///     dervived value is returned in `Some`. Otherwise, a `None` is returned.
///
///     _This implementation always returns successfully._
///
///   * **Result<T, T::Error>** _where_ **T: FromRequest**
///
///     The type `T` is derived from the incoming request using `T`'s
///     `FromRequest` implementation. If derivation is a `Success`, the value is
///     returned in `Ok`. If the derivation is a `Failure`, the error value is
///     returned in `Err`. If the derivation is a `Forward`, the request is
///     forwarded.
///
/// # Example
///
/// Imagine you're running an authenticated API service that requires that some
/// requests be sent along with a valid API key in a header field. You want to
/// ensure that the handlers corresponding to these requests don't get called
/// unless there is an API key in the request and the key is valid. The
/// following example implements this using an `APIKey` type and a `FromRequest`
/// implementation for that type. The `APIKey` type is then used in the
/// `senstive` handler.
///
/// ```rust
/// # #![feature(plugin)]
/// # #![plugin(rocket_codegen)]
/// # extern crate rocket;
/// #
/// use rocket::Outcome;
/// use rocket::http::Status;
/// use rocket::request::{self, Request, FromRequest};
///
/// struct APIKey(String);
///
/// /// Returns true if `key` is a valid API key string.
/// fn is_valid(key: &str) -> bool {
///     key == "valid_api_key"
/// }
///
/// impl<'a, 'r> FromRequest<'a, 'r> for APIKey {
///     type Error = ();
///
///     fn from_request(request: &'a Request<'r>) -> request::Outcome<APIKey, ()> {
///         let keys: Vec<_> = request.headers().get("x-api-key").collect();
///         if keys.len() != 1 {
///             return Outcome::Failure((Status::BadRequest, ()));
///         }
///
///         let key = keys[0];
///         if !is_valid(keys[0]) {
///             return Outcome::Forward(());
///         }
///
///         return Outcome::Success(APIKey(key.to_string()));
///     }
/// }
///
/// #[get("/sensitive")]
/// fn sensitive(key: APIKey) -> &'static str {
/// #   let _key = key;
///     "Sensitive data."
/// }
///
/// # fn main() { }
/// ```
pub trait FromRequest<'a, 'r>: Sized {
    /// The associated error to be returned if derivation fails.
    type Error: Debug;

    /// Derives an instance of `Self` from the incoming request metadata.
    ///
    /// If the derivation is successful, an outcome of `Success` is returned. If
    /// the derivation fails in an unrecoverable fashion, `Failure` is returned.
    /// `Forward` is returned to indicate that the request should be forwarded
    /// to other matching routes, if any.
    fn from_request(request: &'a Request<'r>) -> Outcome<Self, Self::Error>;
}

impl<'a, 'r> FromRequest<'a, 'r> for &'a URI<'a> {
    type Error = ();

    fn from_request(request: &'a Request<'r>) -> Outcome<Self, Self::Error> {
        Success(request.uri())
    }
}

impl<'a, 'r> FromRequest<'a, 'r> for Method {
    type Error = ();

    fn from_request(request: &'a Request<'r>) -> Outcome<Self, Self::Error> {
        Success(request.method())
    }
}

impl<'a, 'r> FromRequest<'a, 'r> for Cookies<'a> {
    type Error = ();

    fn from_request(request: &'a Request<'r>) -> Outcome<Self, Self::Error> {
        Success(request.cookies())
    }
}

impl<'a, 'r> FromRequest<'a, 'r> for Session<'a> {
    type Error = ();

    fn from_request(request: &'a Request<'r>) -> Outcome<Self, Self::Error> {
        Success(request.session())
    }
}

impl<'a, 'r> FromRequest<'a, 'r> for Accept {
    type Error = ();

    fn from_request(request: &'a Request<'r>) -> Outcome<Self, Self::Error> {
        match request.accept() {
            Some(accept) => Success(accept),
            None => Forward(())
        }
    }
}

impl<'a, 'r> FromRequest<'a, 'r> for ContentType {
    type Error = ();

    fn from_request(request: &'a Request<'r>) -> Outcome<Self, Self::Error> {
        match request.content_type() {
            Some(content_type) => Success(content_type),
            None => Forward(())
        }
    }
}

impl<'a, 'r> FromRequest<'a, 'r> for SocketAddr {
    type Error = ();

    fn from_request(request: &'a Request<'r>) -> Outcome<Self, Self::Error> {
        match request.remote() {
            Some(addr) => Success(addr),
            None => Forward(())
        }
    }
}

impl<'a, 'r, T: FromRequest<'a, 'r>> FromRequest<'a, 'r> for Result<T, T::Error> {
    type Error = ();

    fn from_request(request: &'a Request<'r>) -> Outcome<Self, Self::Error> {
        match T::from_request(request) {
            Success(val) => Success(Ok(val)),
            Failure((_, e)) => Success(Err(e)),
            Forward(_) => Forward(()),
        }
    }
}

impl<'a, 'r, T: FromRequest<'a, 'r>> FromRequest<'a, 'r> for Option<T> {
    type Error = ();

    fn from_request(request: &'a Request<'r>) -> Outcome<Self, Self::Error> {
        match T::from_request(request) {
            Success(val) => Success(Some(val)),
            Failure(_) | Forward(_) => Success(None),
        }
    }
}

<|endoftext|>


<commit_before>/// A simple syntax-highlighter for pest
extern crate pest;
extern crate pest_meta;
extern crate colored;

use std::io::{self, Read};
use std::rc::Rc;

use colored::Colorize;
use pest::Parser;
use pest::inputs::StringInput;
use pest::inputs::Input;
use pest_meta::parser::{PestParser, PestRule};

fn main() {
    // Read a pest grammar definition from stdin
    let input = Rc::new(StringInput::new({
        let input = io::stdin();
        let mut code = String::new();
        input.lock().read_to_string(&mut code).unwrap();
        code
    }));

    // Parse the input into a flattened Abstract Syntax Tree (AST). A flattened AST tree is the
    // list of all subtrees of an AST tree in depth-first pre-order of their root nodes (parents
    // occur before children and siblings occur in the same order that their spans occur in the
    // input).
    let ast = match PestParser::parse(PestRule::grammar_rules, input.clone()) {
        Ok(pairs) => pairs,
        Err(err) => {
            println!("{}:\n\n{}", "Parsing error".red(), err);
            return;
        }
    }.flatten();

    // If we limit our tool to not do any nested styles (e.g. no italicized word within a bold
    // sentence), then we can simply select a subsequence of non-overlapping elements from the
    // flattened AST and print their content with the desired style. In between, we print the
    // remaining text (straight from the input, without any special styling).

    // We keep track of the number of code points (characters) from the input that have been
    // processed (styled), in order to:
    // - skip sub-trees which overlap with already styled ones to avoid duplicating the text
    // - print the input spans between the styled sub-trees
    // .
    let mut processed = 0;
    let input = input.as_ref();
    // We traverse the flattened AST tree,
    for sub_tree in ast {
        let span = sub_tree.clone().into_span();
        // and we choose which of the sub-trees we want to style.

        // We skip sub-trees which overlap with the already processed part of the input.
        if span.start() < processed {
            continue
        }

        let style = match sub_tree.as_rule() {
            // We choose a style for the sub-trees we want to style
            PestRule::string => <&str>::magenta,
            PestRule::identifier => <&str>::cyan,
            PestRule::opening_brace | PestRule::closing_brace => <&str>::bold,
            PestRule::character => <&str>::blue,
            // and skip over the sub-trees that we don't really care about styling.
            _ => continue
        };
        // Now, we print everything between the last processed code point and the beginning of the
        // current sub-tree span using the default text output style. Then we print the span of the
        // sub-tree itself using the selected style.
        print!("{}{}", unsafe {input.slice(processed, span.start())}, style(span.as_str()));
        // We update the record of the last code point we processed.
        processed = span.end();
    }
    // To finish up, we print whatever is left from the input using the default style.
    println!("{}", unsafe {input.slice(processed, input.len())});
}
<commit_msg>Put spaces inside braces in all the unsafe places<commit_after>/// A simple syntax-highlighter for pest
extern crate pest;
extern crate pest_meta;
extern crate colored;

use std::io::{self, Read};
use std::rc::Rc;

use colored::Colorize;
use pest::Parser;
use pest::inputs::StringInput;
use pest::inputs::Input;
use pest_meta::parser::{PestParser, PestRule};

fn main() {
    // Read a pest grammar definition from stdin
    let input = Rc::new(StringInput::new({
        let input = io::stdin();
        let mut code = String::new();
        input.lock().read_to_string(&mut code).unwrap();
        code
    }));

    // Parse the input into a flattened Abstract Syntax Tree (AST). A flattened AST tree is the
    // list of all subtrees of an AST tree in depth-first pre-order of their root nodes (parents
    // occur before children and siblings occur in the same order that their spans occur in the
    // input).
    let ast = match PestParser::parse(PestRule::grammar_rules, input.clone()) {
        Ok(pairs) => pairs,
        Err(err) => {
            println!("{}:\n\n{}", "Parsing error".red(), err);
            return;
        }
    }.flatten();

    // If we limit our tool to not do any nested styles (e.g. no italicized word within a bold
    // sentence), then we can simply select a subsequence of non-overlapping elements from the
    // flattened AST and print their content with the desired style. In between, we print the
    // remaining text (straight from the input, without any special styling).

    // We keep track of the number of code points (characters) from the input that have been
    // processed (styled), in order to:
    // - skip sub-trees which overlap with already styled ones to avoid duplicating the text
    // - print the input spans between the styled sub-trees
    let mut processed = 0;
    let input = input.as_ref();
    // We traverse the flattened AST tree,
    for sub_tree in ast {
        let span = sub_tree.clone().into_span();
        // and we choose which of the sub-trees we want to style.

        // We skip sub-trees which overlap with the already processed part of the input.
        if span.start() < processed {
            continue
        }

        let style = match sub_tree.as_rule() {
            // We choose a style for the sub-trees we want to style
            PestRule::string => <&str>::magenta,
            PestRule::identifier => <&str>::cyan,
            PestRule::opening_brace | PestRule::closing_brace => <&str>::bold,
            PestRule::character => <&str>::blue,
            // and skip over the sub-trees that we don't really care about styling.
            _ => continue
        };
        // Now, we print everything between the last processed code point and the beginning of the
        // current sub-tree span using the default text output style. Then we print the span of the
        // sub-tree itself using the selected style.
        print!("{}{}", unsafe { input.slice(processed, span.start()) }, style(span.as_str()));
        // We update the record of the last code point we processed.
        processed = span.end();
    }
    // To finish up, we print whatever is left from the input using the default style.
    println!("{}", unsafe { input.slice(processed, input.len()) });
}
<|endoftext|>


<commit_before>
/*
 * Interpreter for Basic C like language
 * Lexer Module
 */

#[derive(Debug)]
pub enum Token {
    Keyword(String),    // like int, string or let
    Identifier(String), // like variable names
    Char(String),       // Char variables, inside " ' "
    String(String),     // String variables, inside quotes
    Number(String),     // Number variable
    True,               // Boolean true
    False,              // Boolean false
    Equals,             // =
    Plus,               // +
    Minus,              // -
    Multiple,           // *
    Divide,             // /
    Mod,                // %
    Greater,            // >
    Lesser,             // <
    GreaterEqual,       // >=
    LesserEqual,        // <=
    LParen,             // (
    RParen,             // )
    LBrace,             // {
    RBrace,             // }
    LBracket,           // [
    RBracket,           // ]
    Comma,              // ,
    Semicolon,          // ;
    Comment             // '//'
}

impl Token {
    pub fn toString(&self) -> String {
        match *self {
            Token::Keyword(ref x) => format!("Keyword({})", x),
            Token::Identifier(ref x) => format!("Identifier({})", x),
            Token::Char(ref x) => format!("Char({})", x),
            Token::String(ref x) => format!("String({})", x),
            Token::Number(ref x) => format!("Number({})", x),
            Token::True => "True".to_string(),
            Token::False => "False".to_string(),
            Token::Equals => "Equals".to_string(),
            Token::Plus => "Plus".to_string(),
            Token::Minus => "Minus".to_string(),
            Token::Multiple => "Multiple".to_string(),
            Token::Divide => "Divide".to_string(),
            Token::Mod => "Mod".to_string(),
            Token::Greater => "Greater".to_string(),
            Token::Lesser => "Lesser".to_string(),
            Token::GreaterEqual => "GreaterEqual".to_string(),
            Token::LesserEqual => "LesserEqual".to_string(),
            Token::LParen => "LParen".to_string(),
            Token::RParen => "RParen".to_string(),
            Token::LBrace => "LBrace".to_string(),
            Token::RBrace => "RBrace".to_string(),
            Token::LBracket => "LBracket".to_string(),
            Token::RBracket => "RBracket".to_string(),
            Token::Comma => "Comma".to_string(),
            Token::Semicolon => "Semicolon".to_string(),
            Token::Comment => "Comment".to_string()
        }
    }
}

pub fn Initiate(code: String) -> Vec<Token> {
    lexIt(code)
}

fn lexIt(code: String) -> Vec<Token> {
    let mut tokens : Vec<Token> = vec![]; // OR Vec::new();
    let charCount = code.chars().count();
    let mut i = 0;

    while i <  charCount {
        let mut currentChar = code.chars().nth(i).unwrap();

        // If char is whitespace, just pass the current char
        if currentChar.is_whitespace() {
            i += 1;
        }
        // If char starts with alphabetic characters
        else if currentChar.is_alphabetic() {
            let mut tmp = "".to_string();

            // If current char is not out of our code scope and char starts with alphanumeric (alphabetic or numeric) characters
            while i < charCount && code.chars().nth(i).unwrap().is_alphanumeric() {

                tmp = tmp + &*code.chars().nth(i).unwrap().to_string();
                i += 1;
            }

            //We have the word, now we need to find what it is and tokenize it.
            let tmpStr = tmp.to_lowercase();
            if isKeyword(&tmpStr) {
                tokens.push(Token::Keyword(tmpStr));
            } else if tmpStr == "true" {
                tokens.push(Token::True);
            } else if tmpStr == "false" {
                tokens.push(Token::False);
            } else {
                tokens.push(Token::Identifier(tmpStr));
            }
        }
        // If current char is a numerical character
        else if currentChar.is_numeric() {
            let mut tmp = "".to_string();

            while i < charCount && code.chars().nth(i).unwrap().is_numeric() {
                tmp = tmp + &*code.chars().nth(i).unwrap().to_string();
                i += 1;
            }

            tokens.push(Token::Number(tmp));
        }
        // If current char is a starting of a string
        else if currentChar == '"' {
            let mut tmp = "".to_string();
            i += 1;

            while i < charCount && code.chars().nth(i).unwrap() != '"'  {
                tmp = tmp + &*code.chars().nth(i).unwrap().to_string();
                i += 1;
            }

            i += 1;
            tokens.push(Token::String(tmp));
        }
        // If current char is a real char
        else if currentChar == '\'' {
            let tmp = code.chars().nth(i + 1).unwrap();
            i += 2;

            if code.chars().nth(i).unwrap() == '\'' {
                tokens.push(Token::Char(tmp.to_string()));
                i += 1;
            } else {
                unexpectedToken(code.chars().nth(i).unwrap(), i);
            }
        }
        // If current char is an equals (=)
        else if currentChar == '=' {
            tokens.push(Token::Equals);
            i += 1;
        }
        // If current char is a plus (+)
        else if currentChar == '+' {
            tokens.push(Token::Plus);
            i += 1;
        }
        // If current char is a minus (-)
        else if currentChar == '-' {
            tokens.push(Token::Minus);
            i += 1;
        }
        // If current char is a multiple (*)
        else if currentChar == '*' {
            tokens.push(Token::Multiple);
            i += 1;
        }
        // If current char is a divide (/) or comment ( starts with // )
        else if currentChar == '/' {

            i += 1;
            if i < charCount && code.chars().nth(i).unwrap() == '/' {
                while i < charCount && code.chars().nth(i).unwrap() != '\n' {
                    i += 1;
                }

                i += 1;
                tokens.push(Token::Comment);
            } else {
                tokens.push(Token::Divide);
            }
        }
        // If current char is a mod (%)
        else if currentChar == '%' {
            tokens.push(Token::Mod);
            i += 1;
        }
        // If current char is a greater than (>) or greater than or equal to (>=)
        else if currentChar == '>' {
            if i + 1 < charCount && code.chars().nth(i + 1).unwrap() == '=' {
                tokens.push(Token::GreaterEqual);
                i += 1;
            } else {
                tokens.push(Token::Greater);
            }

            i += 1;
        }
        // If current char is a lesser than (<) or lesser than or equal to (<=)
        else if currentChar == '<' {
            if i < charCount && code.chars().nth(i + 1).unwrap() == '=' {
                tokens.push(Token::LesserEqual);
                i += 1;
            } else {
                tokens.push(Token::Lesser);
            }
            i += 1;
        }
        // If current char is an Open Paranthesis ( ( )
        else if currentChar == '(' {
            tokens.push(Token::LParen);
            i += 1;
        }
        // If current char is a Close Paranthesis ( ) )
        else if currentChar == ')' {
            tokens.push(Token::RParen);
            i += 1;
        }
        // If current char is an Open Braces ( { )
        else if currentChar == '{' {
            tokens.push(Token::LBrace);
            i += 1;
        }
        // If current char is a Close Braces ( } )
        else if currentChar == '}' {
            tokens.push(Token::RBrace);
            i += 1;
        }
        // If current char is an Open Brackets ( [ )
        else if currentChar == '[' {
            tokens.push(Token::LBracket);
            i += 1;
        }
        // If current char is a Close Brackets ( ] )
        else if currentChar == ']' {
            tokens.push(Token::RBracket);
            i += 1;
        }
        // If current char is an semicolon ( ; )
        else if currentChar == ',' {
            tokens.push(Token::Comma);
            i += 1;
        }
        // If current char is an semicolon ( ; )
        else if currentChar == ';' {
            tokens.push(Token::Semicolon);
            i += 1;
        }
        // Else throw an exception
        else {
            unexpectedToken(currentChar, i);
        }
    }

    tokens
}

fn isKeyword(value: &String) -> bool {
    let valueStr = &*value;
    value == "main" || value == "int" || value == "string" || value == "bool" || value == "print" || value == "get" || value == "return"
}

fn unexpectedToken(c: char, i: usize) {
    panic!("Unexpected token: {:?} at {:?}th letter!", c, i);
}
<commit_msg>unexpectedToken Function Improvements<commit_after>
/*
 * Interpreter for Basic C like language
 * Lexer Module
 */

#[derive(Debug)]
pub enum Token {
    Keyword(String),    // like int, string or let
    Identifier(String), // like variable names
    Char(String),       // Char variables, inside " ' "
    String(String),     // String variables, inside quotes
    Number(String),     // Number variable
    True,               // Boolean true
    False,              // Boolean false
    Equals,             // =
    Plus,               // +
    Minus,              // -
    Multiple,           // *
    Divide,             // /
    Mod,                // %
    Greater,            // >
    Lesser,             // <
    GreaterEqual,       // >=
    LesserEqual,        // <=
    LParen,             // (
    RParen,             // )
    LBrace,             // {
    RBrace,             // }
    LBracket,           // [
    RBracket,           // ]
    Comma,              // ,
    Semicolon,          // ;
    Comment             // '//'
}

impl Token {
    pub fn toString(&self) -> String {
        match *self {
            Token::Keyword(ref x) => format!("Keyword({})", x),
            Token::Identifier(ref x) => format!("Identifier({})", x),
            Token::Char(ref x) => format!("Char({})", x),
            Token::String(ref x) => format!("String({})", x),
            Token::Number(ref x) => format!("Number({})", x),
            Token::True => "True".to_string(),
            Token::False => "False".to_string(),
            Token::Equals => "Equals".to_string(),
            Token::Plus => "Plus".to_string(),
            Token::Minus => "Minus".to_string(),
            Token::Multiple => "Multiple".to_string(),
            Token::Divide => "Divide".to_string(),
            Token::Mod => "Mod".to_string(),
            Token::Greater => "Greater".to_string(),
            Token::Lesser => "Lesser".to_string(),
            Token::GreaterEqual => "GreaterEqual".to_string(),
            Token::LesserEqual => "LesserEqual".to_string(),
            Token::LParen => "LParen".to_string(),
            Token::RParen => "RParen".to_string(),
            Token::LBrace => "LBrace".to_string(),
            Token::RBrace => "RBrace".to_string(),
            Token::LBracket => "LBracket".to_string(),
            Token::RBracket => "RBracket".to_string(),
            Token::Comma => "Comma".to_string(),
            Token::Semicolon => "Semicolon".to_string(),
            Token::Comment => "Comment".to_string()
        }
    }
}

pub fn Initiate(code: String) -> Vec<Token> {
    lexIt(code)
}

fn lexIt(code: String) -> Vec<Token> {
    let mut tokens : Vec<Token> = vec![]; // OR Vec::new();
    let charCount = code.chars().count();
    let mut i = 0;

    while i <  charCount {
        let mut currentChar = code.chars().nth(i).unwrap();

        // If char is whitespace, just pass the current char
        if currentChar.is_whitespace() {
            i += 1;
        }
        // If char starts with alphabetic characters
        else if currentChar.is_alphabetic() {
            let mut tmp = "".to_string();

            // If current char is not out of our code scope and char starts with alphanumeric (alphabetic or numeric) characters
            while i < charCount && code.chars().nth(i).unwrap().is_alphanumeric() {

                tmp = tmp + &*code.chars().nth(i).unwrap().to_string();
                i += 1;
            }

            //We have the word, now we need to find what it is and tokenize it.
            let tmpStr = tmp.to_lowercase();
            if isKeyword(&tmpStr) {
                tokens.push(Token::Keyword(tmpStr));
            } else if tmpStr == "true" {
                tokens.push(Token::True);
            } else if tmpStr == "false" {
                tokens.push(Token::False);
            } else {
                tokens.push(Token::Identifier(tmpStr));
            }
        }
        // If current char is a numerical character
        else if currentChar.is_numeric() {
            let mut tmp = "".to_string();

            while i < charCount && code.chars().nth(i).unwrap().is_numeric() {
                tmp = tmp + &*code.chars().nth(i).unwrap().to_string();
                i += 1;
            }

            tokens.push(Token::Number(tmp));
        }
        // If current char is a starting of a string
        else if currentChar == '"' {
            let mut tmp = "".to_string();
            i += 1;

            while i < charCount && code.chars().nth(i).unwrap() != '"'  {
                tmp = tmp + &*code.chars().nth(i).unwrap().to_string();
                i += 1;
            }

            i += 1;
            tokens.push(Token::String(tmp));
        }
        // If current char is a real char
        else if currentChar == '\'' {
            let tmp = code.chars().nth(i + 1).unwrap();
            i += 2;

            if code.chars().nth(i).unwrap() == '\'' {
                tokens.push(Token::Char(tmp.to_string()));
                i += 1;
            } else {
                unexpectedToken(code.chars().nth(i).unwrap(), &code, i);
            }
        }
        // If current char is an equals (=)
        else if currentChar == '=' {
            tokens.push(Token::Equals);
            i += 1;
        }
        // If current char is a plus (+)
        else if currentChar == '+' {
            tokens.push(Token::Plus);
            i += 1;
        }
        // If current char is a minus (-)
        else if currentChar == '-' {
            tokens.push(Token::Minus);
            i += 1;
        }
        // If current char is a multiple (*)
        else if currentChar == '*' {
            tokens.push(Token::Multiple);
            i += 1;
        }
        // If current char is a divide (/) or comment ( starts with // )
        else if currentChar == '/' {

            i += 1;
            if i < charCount && code.chars().nth(i).unwrap() == '/' {
                while i < charCount && code.chars().nth(i).unwrap() != '\n' {
                    i += 1;
                }

                i += 1;
                tokens.push(Token::Comment);
            } else {
                tokens.push(Token::Divide);
            }
        }
        // If current char is a mod (%)
        else if currentChar == '%' {
            tokens.push(Token::Mod);
            i += 1;
        }
        // If current char is a greater than (>) or greater than or equal to (>=)
        else if currentChar == '>' {
            if i + 1 < charCount && code.chars().nth(i + 1).unwrap() == '=' {
                tokens.push(Token::GreaterEqual);
                i += 1;
            } else {
                tokens.push(Token::Greater);
            }

            i += 1;
        }
        // If current char is a lesser than (<) or lesser than or equal to (<=)
        else if currentChar == '<' {
            if i < charCount && code.chars().nth(i + 1).unwrap() == '=' {
                tokens.push(Token::LesserEqual);
                i += 1;
            } else {
                tokens.push(Token::Lesser);
            }
            i += 1;
        }
        // If current char is an Open Paranthesis ( ( )
        else if currentChar == '(' {
            tokens.push(Token::LParen);
            i += 1;
        }
        // If current char is a Close Paranthesis ( ) )
        else if currentChar == ')' {
            tokens.push(Token::RParen);
            i += 1;
        }
        // If current char is an Open Braces ( { )
        else if currentChar == '{' {
            tokens.push(Token::LBrace);
            i += 1;
        }
        // If current char is a Close Braces ( } )
        else if currentChar == '}' {
            tokens.push(Token::RBrace);
            i += 1;
        }
        // If current char is an Open Brackets ( [ )
        else if currentChar == '[' {
            tokens.push(Token::LBracket);
            i += 1;
        }
        // If current char is a Close Brackets ( ] )
        else if currentChar == ']' {
            tokens.push(Token::RBracket);
            i += 1;
        }
        // If current char is an semicolon ( ; )
        else if currentChar == ',' {
            tokens.push(Token::Comma);
            i += 1;
        }
        // If current char is an semicolon ( ; )
        else if currentChar == ';' {
            tokens.push(Token::Semicolon);
            i += 1;
        }
        // Else throw an exception
        else {
            unexpectedToken(currentChar, &code, i);
        }
    }

    tokens
}

fn isKeyword(value: &String) -> bool {
    let valueStr = &*value;
    value == "main" || value == "int" || value == "string" || value == "bool" || value == "print" || value == "get" || value == "return"
}

fn unexpectedToken(c: char, code: &String, i: usize) {
    let mut lineCount = 1;
    let mut column : usize = 0;
    let mut isFirstLine = true;

    for currIndex in (0..i).rev() {
        if code.chars().nth(currIndex).unwrap() == '\n' {
            if isFirstLine {
                column = i - currIndex;
                isFirstLine = false;
            }
            lineCount += 1;
        }
    }

    panic!("Unexpected token: {:?} at line {:?}, column {:?}!", c, lineCount, column);
}
<|endoftext|>


<commit_before>use crate::backtrace_rs::{self, BacktraceFmt, BytesOrWideString, PrintFmt};
use crate::borrow::Cow;
/// Common code for printing the backtrace in the same way across the different
/// supported platforms.
use crate::env;
use crate::fmt;
use crate::io;
use crate::io::prelude::*;
use crate::path::{self, Path, PathBuf};
use crate::sync::atomic::{self, Ordering};
use crate::sys_common::mutex::StaticMutex;

/// Max number of frames to print.
const MAX_NB_FRAMES: usize = 100;

// SAFETY: Don't attempt to lock this reentrantly.
pub unsafe fn lock() -> impl Drop {
    static LOCK: StaticMutex = StaticMutex::new();
    LOCK.lock()
}

/// Prints the current backtrace.
pub fn print(w: &mut dyn Write, format: PrintFmt) -> io::Result<()> {
    // There are issues currently linking libbacktrace into tests, and in
    // general during libstd's own unit tests we're not testing this path. In
    // test mode immediately return here to optimize away any references to the
    // libbacktrace symbols
    if cfg!(test) {
        return Ok(());
    }

    // Use a lock to prevent mixed output in multithreading context.
    // Some platforms also requires it, like `SymFromAddr` on Windows.
    unsafe {
        let _lock = lock();
        _print(w, format)
    }
}

unsafe fn _print(w: &mut dyn Write, format: PrintFmt) -> io::Result<()> {
    struct DisplayBacktrace {
        format: PrintFmt,
    }
    impl fmt::Display for DisplayBacktrace {
        fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
            unsafe { _print_fmt(fmt, self.format) }
        }
    }
    write!(w, "{}", DisplayBacktrace { format })
}

unsafe fn _print_fmt(fmt: &mut fmt::Formatter<'_>, print_fmt: PrintFmt) -> fmt::Result {
    // Always 'fail' to get the cwd when running under Miri -
    // this allows Miri to display backtraces in isolation mode
    let cwd = if !cfg!(miri) { env::current_dir().ok() } else { None };

    let mut print_path = move |fmt: &mut fmt::Formatter<'_>, bows: BytesOrWideString<'_>| {
        output_filename(fmt, bows, print_fmt, cwd.as_ref())
    };
    writeln!(fmt, "stack backtrace:")?;
    let mut bt_fmt = BacktraceFmt::new(fmt, print_fmt, &mut print_path);
    bt_fmt.add_context()?;
    let mut idx = 0;
    let mut res = Ok(());
    // Start immediately if we're not using a short backtrace.
    let mut start = print_fmt != PrintFmt::Short;
    backtrace_rs::trace_unsynchronized(|frame| {
        if print_fmt == PrintFmt::Short && idx > MAX_NB_FRAMES {
            return false;
        }

        let mut hit = false;
        let mut stop = false;
        backtrace_rs::resolve_frame_unsynchronized(frame, |symbol| {
            hit = true;
            if print_fmt == PrintFmt::Short {
                if let Some(sym) = symbol.name().and_then(|s| s.as_str()) {
                    if sym.contains("__rust_begin_short_backtrace") {
                        stop = true;
                        return;
                    }
                    if sym.contains("__rust_end_short_backtrace") {
                        start = true;
                        return;
                    }
                }
            }

            if start {
                res = bt_fmt.frame().symbol(frame, symbol);
            }
        });
        if stop {
            return false;
        }
        if !hit {
            if start {
                res = bt_fmt.frame().print_raw(frame.ip(), None, None, None);
            }
        }

        idx += 1;
        res.is_ok()
    });
    res?;
    bt_fmt.finish()?;
    if print_fmt == PrintFmt::Short {
        writeln!(
            fmt,
            "note: Some details are omitted, \
             run with `RUST_BACKTRACE=full` for a verbose backtrace."
        )?;
    }
    Ok(())
}

/// Fixed frame used to clean the backtrace with `RUST_BACKTRACE=1`. Note that
/// this is only inline(never) when backtraces in libstd are enabled, otherwise
/// it's fine to optimize away.
#[cfg_attr(feature = "backtrace", inline(never))]
pub fn __rust_begin_short_backtrace<F, T>(f: F) -> T
where
    F: FnOnce() -> T,
{
    let result = f();

    // prevent this frame from being tail-call optimised away
    crate::hint::black_box(());

    result
}

/// Fixed frame used to clean the backtrace with `RUST_BACKTRACE=1`. Note that
/// this is only inline(never) when backtraces in libstd are enabled, otherwise
/// it's fine to optimize away.
#[cfg_attr(feature = "backtrace", inline(never))]
pub fn __rust_end_short_backtrace<F, T>(f: F) -> T
where
    F: FnOnce() -> T,
{
    let result = f();

    // prevent this frame from being tail-call optimised away
    crate::hint::black_box(());

    result
}

pub enum RustBacktrace {
    Print(PrintFmt),
    Disabled,
    RuntimeDisabled,
}

// For now logging is turned off by default, and this function checks to see
// whether the magical environment variable is present to see if it's turned on.
pub fn rust_backtrace_env() -> RustBacktrace {
    // If the `backtrace` feature of this crate isn't enabled quickly return
    // `None` so this can be constant propagated all over the place to turn
    // optimize away callers.
    if !cfg!(feature = "backtrace") {
        return RustBacktrace::Disabled;
    }

    // Setting environment variables for Fuchsia components isn't a standard
    // or easily supported workflow. For now, always display backtraces.
    if cfg!(target_os = "fuchsia") {
        return RustBacktrace::Print(PrintFmt::Full);
    }

    static ENABLED: atomic::AtomicIsize = atomic::AtomicIsize::new(0);
    match ENABLED.load(Ordering::SeqCst) {
        0 => {}
        1 => return RustBacktrace::RuntimeDisabled,
        2 => return RustBacktrace::Print(PrintFmt::Short),
        _ => return RustBacktrace::Print(PrintFmt::Full),
    }

    let (format, cache) = env::var_os("RUST_BACKTRACE")
        .map(|x| {
            if &x == "0" {
                (RustBacktrace::RuntimeDisabled, 1)
            } else if &x == "full" {
                (RustBacktrace::Print(PrintFmt::Full), 3)
            } else {
                (RustBacktrace::Print(PrintFmt::Short), 2)
            }
        })
        .unwrap_or((RustBacktrace::RuntimeDisabled, 1));
    ENABLED.store(cache, Ordering::SeqCst);
    format
}

/// Prints the filename of the backtrace frame.
///
/// See also `output`.
pub fn output_filename(
    fmt: &mut fmt::Formatter<'_>,
    bows: BytesOrWideString<'_>,
    print_fmt: PrintFmt,
    cwd: Option<&PathBuf>,
) -> fmt::Result {
    let file: Cow<'_, Path> = match bows {
        #[cfg(unix)]
        BytesOrWideString::Bytes(bytes) => {
            use crate::os::unix::prelude::*;
            Path::new(crate::ffi::OsStr::from_bytes(bytes)).into()
        }
        #[cfg(not(unix))]
        BytesOrWideString::Bytes(bytes) => {
            Path::new(crate::str::from_utf8(bytes).unwrap_or("<unknown>")).into()
        }
        #[cfg(windows)]
        BytesOrWideString::Wide(wide) => {
            use crate::os::windows::prelude::*;
            Cow::Owned(crate::ffi::OsString::from_wide(wide).into())
        }
        #[cfg(not(windows))]
        BytesOrWideString::Wide(_wide) => Path::new("<unknown>").into(),
    };
    if print_fmt == PrintFmt::Short && file.is_absolute() {
        if let Some(cwd) = cwd {
            if let Ok(stripped) = file.strip_prefix(&cwd) {
                if let Some(s) = stripped.to_str() {
                    return write!(fmt, ".{}{}", path::MAIN_SEPARATOR, s);
                }
            }
        }
    }
    fmt::Display::fmt(&file.display(), fmt)
}
<commit_msg>format symbols under shared frames<commit_after>use crate::backtrace_rs::{self, BacktraceFmt, BytesOrWideString, PrintFmt};
use crate::borrow::Cow;
/// Common code for printing the backtrace in the same way across the different
/// supported platforms.
use crate::env;
use crate::fmt;
use crate::io;
use crate::io::prelude::*;
use crate::path::{self, Path, PathBuf};
use crate::sync::atomic::{self, Ordering};
use crate::sys_common::mutex::StaticMutex;

/// Max number of frames to print.
const MAX_NB_FRAMES: usize = 100;

// SAFETY: Don't attempt to lock this reentrantly.
pub unsafe fn lock() -> impl Drop {
    static LOCK: StaticMutex = StaticMutex::new();
    LOCK.lock()
}

/// Prints the current backtrace.
pub fn print(w: &mut dyn Write, format: PrintFmt) -> io::Result<()> {
    // There are issues currently linking libbacktrace into tests, and in
    // general during libstd's own unit tests we're not testing this path. In
    // test mode immediately return here to optimize away any references to the
    // libbacktrace symbols
    if cfg!(test) {
        return Ok(());
    }

    // Use a lock to prevent mixed output in multithreading context.
    // Some platforms also requires it, like `SymFromAddr` on Windows.
    unsafe {
        let _lock = lock();
        _print(w, format)
    }
}

unsafe fn _print(w: &mut dyn Write, format: PrintFmt) -> io::Result<()> {
    struct DisplayBacktrace {
        format: PrintFmt,
    }
    impl fmt::Display for DisplayBacktrace {
        fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
            unsafe { _print_fmt(fmt, self.format) }
        }
    }
    write!(w, "{}", DisplayBacktrace { format })
}

unsafe fn _print_fmt(fmt: &mut fmt::Formatter<'_>, print_fmt: PrintFmt) -> fmt::Result {
    // Always 'fail' to get the cwd when running under Miri -
    // this allows Miri to display backtraces in isolation mode
    let cwd = if !cfg!(miri) { env::current_dir().ok() } else { None };

    let mut print_path = move |fmt: &mut fmt::Formatter<'_>, bows: BytesOrWideString<'_>| {
        output_filename(fmt, bows, print_fmt, cwd.as_ref())
    };
    writeln!(fmt, "stack backtrace:")?;
    let mut bt_fmt = BacktraceFmt::new(fmt, print_fmt, &mut print_path);
    bt_fmt.add_context()?;
    let mut idx = 0;
    let mut res = Ok(());
    // Start immediately if we're not using a short backtrace.
    let mut start = print_fmt != PrintFmt::Short;
    backtrace_rs::trace_unsynchronized(|frame| {
        if print_fmt == PrintFmt::Short && idx > MAX_NB_FRAMES {
            return false;
        }

        let mut hit = false;
        let mut stop = false;
        let mut frame_fmt = bt_fmt.frame();
        backtrace_rs::resolve_frame_unsynchronized(frame, |symbol| {
            hit = true;
            if print_fmt == PrintFmt::Short {
                if let Some(sym) = symbol.name().and_then(|s| s.as_str()) {
                    if sym.contains("__rust_begin_short_backtrace") {
                        stop = true;
                        return;
                    }
                    if sym.contains("__rust_end_short_backtrace") {
                        start = true;
                        return;
                    }
                }
            }

            if start {
                res = frame_fmt.symbol(frame, symbol);
            }
        });
        if stop {
            return false;
        }
        if !hit {
            if start {
                res = frame_fmt.print_raw(frame.ip(), None, None, None);
            }
        }

        idx += 1;
        res.is_ok()
    });
    res?;
    bt_fmt.finish()?;
    if print_fmt == PrintFmt::Short {
        writeln!(
            fmt,
            "note: Some details are omitted, \
             run with `RUST_BACKTRACE=full` for a verbose backtrace."
        )?;
    }
    Ok(())
}

/// Fixed frame used to clean the backtrace with `RUST_BACKTRACE=1`. Note that
/// this is only inline(never) when backtraces in libstd are enabled, otherwise
/// it's fine to optimize away.
#[cfg_attr(feature = "backtrace", inline(never))]
pub fn __rust_begin_short_backtrace<F, T>(f: F) -> T
where
    F: FnOnce() -> T,
{
    let result = f();

    // prevent this frame from being tail-call optimised away
    crate::hint::black_box(());

    result
}

/// Fixed frame used to clean the backtrace with `RUST_BACKTRACE=1`. Note that
/// this is only inline(never) when backtraces in libstd are enabled, otherwise
/// it's fine to optimize away.
#[cfg_attr(feature = "backtrace", inline(never))]
pub fn __rust_end_short_backtrace<F, T>(f: F) -> T
where
    F: FnOnce() -> T,
{
    let result = f();

    // prevent this frame from being tail-call optimised away
    crate::hint::black_box(());

    result
}

pub enum RustBacktrace {
    Print(PrintFmt),
    Disabled,
    RuntimeDisabled,
}

// For now logging is turned off by default, and this function checks to see
// whether the magical environment variable is present to see if it's turned on.
pub fn rust_backtrace_env() -> RustBacktrace {
    // If the `backtrace` feature of this crate isn't enabled quickly return
    // `None` so this can be constant propagated all over the place to turn
    // optimize away callers.
    if !cfg!(feature = "backtrace") {
        return RustBacktrace::Disabled;
    }

    // Setting environment variables for Fuchsia components isn't a standard
    // or easily supported workflow. For now, always display backtraces.
    if cfg!(target_os = "fuchsia") {
        return RustBacktrace::Print(PrintFmt::Full);
    }

    static ENABLED: atomic::AtomicIsize = atomic::AtomicIsize::new(0);
    match ENABLED.load(Ordering::SeqCst) {
        0 => {}
        1 => return RustBacktrace::RuntimeDisabled,
        2 => return RustBacktrace::Print(PrintFmt::Short),
        _ => return RustBacktrace::Print(PrintFmt::Full),
    }

    let (format, cache) = env::var_os("RUST_BACKTRACE")
        .map(|x| {
            if &x == "0" {
                (RustBacktrace::RuntimeDisabled, 1)
            } else if &x == "full" {
                (RustBacktrace::Print(PrintFmt::Full), 3)
            } else {
                (RustBacktrace::Print(PrintFmt::Short), 2)
            }
        })
        .unwrap_or((RustBacktrace::RuntimeDisabled, 1));
    ENABLED.store(cache, Ordering::SeqCst);
    format
}

/// Prints the filename of the backtrace frame.
///
/// See also `output`.
pub fn output_filename(
    fmt: &mut fmt::Formatter<'_>,
    bows: BytesOrWideString<'_>,
    print_fmt: PrintFmt,
    cwd: Option<&PathBuf>,
) -> fmt::Result {
    let file: Cow<'_, Path> = match bows {
        #[cfg(unix)]
        BytesOrWideString::Bytes(bytes) => {
            use crate::os::unix::prelude::*;
            Path::new(crate::ffi::OsStr::from_bytes(bytes)).into()
        }
        #[cfg(not(unix))]
        BytesOrWideString::Bytes(bytes) => {
            Path::new(crate::str::from_utf8(bytes).unwrap_or("<unknown>")).into()
        }
        #[cfg(windows)]
        BytesOrWideString::Wide(wide) => {
            use crate::os::windows::prelude::*;
            Cow::Owned(crate::ffi::OsString::from_wide(wide).into())
        }
        #[cfg(not(windows))]
        BytesOrWideString::Wide(_wide) => Path::new("<unknown>").into(),
    };
    if print_fmt == PrintFmt::Short && file.is_absolute() {
        if let Some(cwd) = cwd {
            if let Ok(stripped) = file.strip_prefix(&cwd) {
                if let Some(s) = stripped.to_str() {
                    return write!(fmt, ".{}{}", path::MAIN_SEPARATOR, s);
                }
            }
        }
    }
    fmt::Display::fmt(&file.display(), fmt)
}
<|endoftext|>


<commit_before><commit_msg>add AR_SA<commit_after><|endoftext|>


<commit_before>/// Traits required for parsing
pub use crate::types::parsing::traits;
use crate::{
    frame::*,
    protocol::{basic::parse_properties, *},
    types::parsing::*,
};
use nom::{
    branch::alt,
    bytes::streaming::{tag, take},
    combinator::{all_consuming, flat_map, map, map_opt, map_res},
    error::context,
    sequence::{pair, tuple},
};
use traits::ParsableInput;

/// Parse a channel id
pub fn parse_channel<I: ParsableInput>(i: I) -> ParserResult<I, AMQPChannel> {
    context("parse_channel", map(parse_id, From::from))(i)
}

/// Parse the protocol header
pub fn parse_protocol_header<I: ParsableInput>(i: I) -> ParserResult<I, ProtocolVersion> {
    context(
        "parse_protocol_header",
        map(
            tuple((
                tag(metadata::NAME.as_bytes()),
                tag(&[0][..]),
                parse_short_short_uint,
                parse_short_short_uint,
                parse_short_short_uint,
            )),
            |(_, _, major, minor, revision)| ProtocolVersion {
                major,
                minor,
                revision,
            },
        ),
    )(i)
}

/// Parse the frame type
pub fn parse_frame_type<I: ParsableInput>(i: I) -> ParserResult<I, AMQPFrameType> {
    context(
        "parse_frame_type",
        map_opt(parse_short_short_uint, |method| match method {
            constants::FRAME_METHOD => Some(AMQPFrameType::Method),
            constants::FRAME_HEADER => Some(AMQPFrameType::Header),
            constants::FRAME_BODY => Some(AMQPFrameType::Body),
            constants::FRAME_HEARTBEAT => Some(AMQPFrameType::Heartbeat),
            _ => None,
        }),
    )(i)
}

/// Parse a full AMQP Frame (with contents)
pub fn parse_frame<I: ParsableInput>(i: I) -> ParserResult<I, AMQPFrame> {
    context(
        "parse_frame",
        alt((
            map_res(
                parse_raw_frame,
                |AMQPRawFrame {
                     channel_id,
                     frame_type,
                     payload,
                 }: AMQPRawFrame<I>| match frame_type {
                    AMQPFrameType::Method => all_consuming(parse_class)(payload)
                        .map(|(_, m)| AMQPFrame::Method(channel_id, m)),
                    AMQPFrameType::Header => all_consuming(parse_content_header)(payload)
                        .map(|(_, h)| AMQPFrame::Header(channel_id, h.class_id, Box::new(h))),
                    AMQPFrameType::Body => Ok(AMQPFrame::Body(
                        channel_id,
                        payload.iter_elements().collect(),
                    )),
                    AMQPFrameType::Heartbeat => Ok(AMQPFrame::Heartbeat(channel_id)),
                },
            ),
            map(parse_protocol_header, AMQPFrame::ProtocolHeader),
        )),
    )(i)
}

/// Parse a raw AMQP frame
pub fn parse_raw_frame<I: ParsableInput>(i: I) -> ParserResult<I, AMQPRawFrame<I>> {
    context(
        "parse_raw_frame",
        flat_map(
            tuple((parse_frame_type, parse_id, parse_long_uint)),
            move |(frame_type, channel_id, size)| {
                map(
                    pair(take(size), tag(&[constants::FRAME_END][..])),
                    move |(payload, _)| AMQPRawFrame {
                        frame_type,
                        channel_id,
                        payload,
                    },
                )
            },
        ),
    )(i)
}

/// Parse a content header frame
pub fn parse_content_header<I: ParsableInput>(i: I) -> ParserResult<I, AMQPContentHeader> {
    context(
        "parse_content_header",
        map(
            tuple((
                parse_id,
                parse_short_uint,
                parse_long_long_uint,
                context("parse_properties", parse_properties),
            )),
            |(class_id, weight, body_size, properties)| AMQPContentHeader {
                class_id,
                weight,
                body_size,
                properties,
            },
        ),
    )(i)
}

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

    #[test]
    fn test_protocol_header() {
        assert_eq!(
            parse_frame(&['A' as u8, 'M' as u8, 'Q' as u8, 'P' as u8, 0, 0, 9, 1][..]),
            Ok((
                &[][..],
                AMQPFrame::ProtocolHeader(ProtocolVersion::amqp_0_9_1())
            ))
        );
    }

    #[test]
    fn test_heartbeat() {
        assert_eq!(
            parse_frame(&[8, 0, 1, 0, 0, 0, 0, 206][..]),
            Ok((&[][..], AMQPFrame::Heartbeat(1)))
        );
    }
}
<commit_msg>frame parsing: try to add a cut<commit_after>/// Traits required for parsing
pub use crate::types::parsing::traits;
use crate::{
    frame::*,
    protocol::{basic::parse_properties, *},
    types::parsing::*,
};
use nom::{
    branch::alt,
    bytes::streaming::{tag, take},
    combinator::{all_consuming, cut, flat_map, map, map_opt, map_res},
    error::context,
    sequence::{pair, tuple},
};
use traits::ParsableInput;

/// Parse a channel id
pub fn parse_channel<I: ParsableInput>(i: I) -> ParserResult<I, AMQPChannel> {
    context("parse_channel", map(parse_id, From::from))(i)
}

/// Parse the protocol header
pub fn parse_protocol_header<I: ParsableInput>(i: I) -> ParserResult<I, ProtocolVersion> {
    context(
        "parse_protocol_header",
        map(
            tuple((
                tag(metadata::NAME.as_bytes()),
                tag(&[0][..]),
                parse_short_short_uint,
                parse_short_short_uint,
                parse_short_short_uint,
            )),
            |(_, _, major, minor, revision)| ProtocolVersion {
                major,
                minor,
                revision,
            },
        ),
    )(i)
}

/// Parse the frame type
pub fn parse_frame_type<I: ParsableInput>(i: I) -> ParserResult<I, AMQPFrameType> {
    context(
        "parse_frame_type",
        map_opt(parse_short_short_uint, |method| match method {
            constants::FRAME_METHOD => Some(AMQPFrameType::Method),
            constants::FRAME_HEADER => Some(AMQPFrameType::Header),
            constants::FRAME_BODY => Some(AMQPFrameType::Body),
            constants::FRAME_HEARTBEAT => Some(AMQPFrameType::Heartbeat),
            _ => None,
        }),
    )(i)
}

/// Parse a full AMQP Frame (with contents)
pub fn parse_frame<I: ParsableInput>(i: I) -> ParserResult<I, AMQPFrame> {
    context(
        "parse_frame",
        alt((
            map_res(
                parse_raw_frame,
                |AMQPRawFrame {
                     channel_id,
                     frame_type,
                     payload,
                 }: AMQPRawFrame<I>| match frame_type {
                    AMQPFrameType::Method => all_consuming(parse_class)(payload)
                        .map(|(_, m)| AMQPFrame::Method(channel_id, m)),
                    AMQPFrameType::Header => all_consuming(parse_content_header)(payload)
                        .map(|(_, h)| AMQPFrame::Header(channel_id, h.class_id, Box::new(h))),
                    AMQPFrameType::Body => Ok(AMQPFrame::Body(
                        channel_id,
                        payload.iter_elements().collect(),
                    )),
                    AMQPFrameType::Heartbeat => Ok(AMQPFrame::Heartbeat(channel_id)),
                },
            ),
            map(parse_protocol_header, AMQPFrame::ProtocolHeader),
        )),
    )(i)
}

/// Parse a raw AMQP frame
pub fn parse_raw_frame<I: ParsableInput>(i: I) -> ParserResult<I, AMQPRawFrame<I>> {
    context(
        "parse_raw_frame",
        flat_map(parse_frame_type, move |frame_type| {
            cut(flat_map(
                pair(parse_id, parse_long_uint),
                move |(channel_id, size)| {
                    map(
                        pair(take(size), tag(&[constants::FRAME_END][..])),
                        move |(payload, _)| AMQPRawFrame {
                            frame_type,
                            channel_id,
                            payload,
                        },
                    )
                },
            ))
        }),
    )(i)
}

/// Parse a content header frame
pub fn parse_content_header<I: ParsableInput>(i: I) -> ParserResult<I, AMQPContentHeader> {
    context(
        "parse_content_header",
        map(
            tuple((
                parse_id,
                parse_short_uint,
                parse_long_long_uint,
                context("parse_properties", parse_properties),
            )),
            |(class_id, weight, body_size, properties)| AMQPContentHeader {
                class_id,
                weight,
                body_size,
                properties,
            },
        ),
    )(i)
}

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

    #[test]
    fn test_protocol_header() {
        assert_eq!(
            parse_frame(&['A' as u8, 'M' as u8, 'Q' as u8, 'P' as u8, 0, 0, 9, 1][..]),
            Ok((
                &[][..],
                AMQPFrame::ProtocolHeader(ProtocolVersion::amqp_0_9_1())
            ))
        );
    }

    #[test]
    fn test_heartbeat() {
        assert_eq!(
            parse_frame(&[8, 0, 1, 0, 0, 0, 0, 206][..]),
            Ok((&[][..], AMQPFrame::Heartbeat(1)))
        );
    }
}
<|endoftext|>


<commit_before>extern crate ultra;

use ultra::decrypt;

#[test]
fn basic_decryption() {
    let expected = "THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG";
    let ciphertext = "NTZ NTQLZ JMWLL ART BBNOW WZQK KEQ IEVK LZO";
    let (plaintext, rotor, _, _) = decrypt(ciphertext);

    assert_eq!(plaintext, expected);
    assert_eq!(rotor, "142");
}
<commit_msg>Add additional decryption test<commit_after>extern crate ultra;

use ultra::decrypt;

macro_rules! decrypt_test {
    ($expected:tt, $ciphertext:tt) => {
        assert_eq!(decrypt($ciphertext).0, $expected);
    }
}

#[test]
fn short_decryption() {
    decrypt_test!(
        "THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG",
        "NTZ NTQLZ JMWLL ART BBNOW WZQK KEQ IEVK LZO"
    )
}

#[test]
fn longer_decryption() {
    decrypt_test!(
        "A FEW MILES SOUTH OF SOLEDAD, THE SALINAS RIVER DROPS IN CLOSE TO THE HILLSIDE BANK AND RUNS DEEP AND GREEN. THE WATER IS WARM TOO, FOR IT HAS SLIPPED TWINKLING OVER THE YELLOW SANDS IN THE SUNLIGHT BEFORE REACHING THE NARROW POOL.",
        "Q OCB ODJKE OFZDD BQ YRIRNDW, QZD BOOJHXT PUULE MKCBC FO UAIYG IL ITF ALSUDRGO IKEA LWG SWPA HACL ZDP PDSNQ. WTH OSFWJ TU DKHV VUI, KTM WZ GOR TJDKVAG FXYMZKFWE ENRH BXI PRZZWM GYIGH JL WDM TYSTZLRP EPABZL ZACPUPJY UPU TEQLCX UZBM."
    )
}
<|endoftext|>


<commit_before>// Copyright 2014-2018 The Rust Project Developers. 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.

#[test]
fn dogfood_runner() {
    dogfood();
    dogfood_tests();
}

fn dogfood() {
    if option_env!("RUSTC_TEST_SUITE").is_some() || cfg!(windows) {
        return;
    }
    let root_dir = std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR"));
    let clippy_cmd = std::path::Path::new(&root_dir).join("target/debug/cargo-clippy");

    std::env::set_current_dir(root_dir).unwrap();
    let output = std::process::Command::new(clippy_cmd)
        .arg("clippy")
        .arg("--all-targets")
        .arg("--all-features")
        .arg("--")
        .args(&["-D", "clippy::all"])
        .args(&["-D", "clippy::internal"])
        .args(&["-D", "clippy::pedantic"])
        .output()
        .unwrap();
    println!("status: {}", output.status);
    println!("stdout: {}", String::from_utf8_lossy(&output.stdout));
    println!("stderr: {}", String::from_utf8_lossy(&output.stderr));

    assert!(output.status.success());
}

fn dogfood_tests() {
    if option_env!("RUSTC_TEST_SUITE").is_some() || cfg!(windows) {
        return;
    }
    let root_dir = std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR"));

    for d in &[
        "clippy_workspace_tests",
        "clippy_workspace_tests/src",
        "clippy_workspace_tests/subcrate",
        "clippy_workspace_tests/subcrate/src",
        "clippy_dev",
        "rustc_tools_util",
    ] {
        let clippy_cmd = std::path::Path::new(&root_dir)
            .join("target/debug/cargo-clippy");
        std::env::set_current_dir(root_dir.join(d)).unwrap();
        let output = std::process::Command::new(clippy_cmd)
            .arg("clippy")
            .arg("--")
            .args(&["-D", "clippy::all"])
            .args(&["-D", "clippy::pedantic"])
            .output()
            .unwrap();
        println!("status: {}", output.status);
        println!("stdout: {}", String::from_utf8_lossy(&output.stdout));
        println!("stderr: {}", String::from_utf8_lossy(&output.stderr));

        assert!(output.status.success());
    }
}
<commit_msg>Use cargo's "PROFILE" envvar and set CLIPPY_DOGFOOD<commit_after>// Copyright 2014-2018 The Rust Project Developers. 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.

#[test]
fn dogfood_runner() {
    dogfood();
    dogfood_tests();
}

fn dogfood() {
    if option_env!("RUSTC_TEST_SUITE").is_some() || cfg!(windows) {
        return;
    }
    let root_dir = std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR"));
    let clippy_cmd = std::path::Path::new(&root_dir)
        .join("target")
        .join(env!("PROFILE"))
        .join("cargo-clippy");

    std::env::set_current_dir(root_dir).unwrap();
    let output = std::process::Command::new(clippy_cmd)
        .env("CLIPPY_DOGFOOD", "1")
        .arg("clippy")
        .arg("--all-targets")
        .arg("--all-features")
        .arg("--")
        .args(&["-D", "clippy::all"])
        .args(&["-D", "clippy::internal"])
        .args(&["-D", "clippy::pedantic"])
        .output()
        .unwrap();
    println!("status: {}", output.status);
    println!("stdout: {}", String::from_utf8_lossy(&output.stdout));
    println!("stderr: {}", String::from_utf8_lossy(&output.stderr));

    assert!(output.status.success());
}

fn dogfood_tests() {
    if option_env!("RUSTC_TEST_SUITE").is_some() || cfg!(windows) {
        return;
    }
    let root_dir = std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR"));
    let clippy_cmd = std::path::Path::new(&root_dir)
        .join("target")
        .join(env!("PROFILE"))
        .join("cargo-clippy");

    for d in &[
        "clippy_workspace_tests",
        "clippy_workspace_tests/src",
        "clippy_workspace_tests/subcrate",
        "clippy_workspace_tests/subcrate/src",
        "clippy_dev",
        "rustc_tools_util",
    ] {
        std::env::set_current_dir(root_dir.join(d)).unwrap();
        let output = std::process::Command::new(&clippy_cmd)
            .env("CLIPPY_DOGFOOD", "1")
            .arg("clippy")
            .arg("--")
            .args(&["-D", "clippy::all"])
            .args(&["-D", "clippy::pedantic"])
            .output()
            .unwrap();
        println!("status: {}", output.status);
        println!("stdout: {}", String::from_utf8_lossy(&output.stdout));
        println!("stderr: {}", String::from_utf8_lossy(&output.stderr));

        assert!(output.status.success());
    }
}
<|endoftext|>


<commit_before>use std::mem;
use std::ptr;

use runtime::{Class, Object, Sel, self};
use {encode, Encode, EncodePtr};

/*
 The Sized bound on Message is unfortunate; ideally, objc objects would not be
 treated as Sized. However, rust won't allow casting a dynamically-sized type
 pointer to an Object pointer, because dynamically-sized types can have fat
 pointers (two words) instead of real pointers.
 */
/// Types that may be sent Objective-C messages.
/// For example: objects, classes, and blocks.
pub unsafe trait Message: Sized + EncodePtr { }

unsafe impl Message for Object { }

unsafe impl Message for Class { }

/// A trait for converting to a pointer to a type that may be sent Objective-C
/// messages.
pub trait ToMessage : Encode {
    type Target: Message;

    fn as_ptr(&self) -> *mut Self::Target;

    fn is_nil(&self) -> bool {
        self.as_ptr().is_null()
    }
}

impl<T> ToMessage for *const T where T: Message {
    type Target = T;

    fn as_ptr(&self) -> *mut T {
        *self as *mut T
    }
}

impl<T> ToMessage for *mut T where T: Message {
    type Target = T;

    fn as_ptr(&self) -> *mut T {
        *self
    }
}

impl<'a, T> ToMessage for &'a T where T: Message {
    type Target = T;

    fn as_ptr(&self) -> *mut T {
        *self as *const T as *mut T
    }
}

impl<'a, T> ToMessage for &'a mut T where T: Message {
    type Target = T;

    fn as_ptr(&self) -> *mut T {
        *self
    }
}

impl<'a, T> ToMessage for Option<&'a T> where T: Message {
    type Target = T;

    fn as_ptr(&self) -> *mut T {
        match *self {
            None => ptr::null_mut(),
            Some(ref obj) => obj.as_ptr(),
        }
    }
}

impl<'a, T> ToMessage for Option<&'a mut T> where T: Message {
    type Target = T;

    fn as_ptr(&self) -> *mut T {
        match *self {
            None => ptr::null_mut(),
            Some(ref obj) => obj.as_ptr(),
        }
    }
}

fn msg_send_fn<R>() -> unsafe extern fn(*mut Object, Sel, ...) -> R {
    unsafe {
        mem::transmute(runtime::objc_msgSend)
    }
}

pub trait MessageArguments {
    unsafe fn send<T, R>(self, obj: &T, sel: Sel) -> R where T: ToMessage;
}

macro_rules! message_args_impl {
    ($($a:ident : $t:ident),*) => (
        impl<$($t),*> MessageArguments for ($($t,)*) {
            unsafe fn send<T, R>(self, obj: &T, sel: Sel) -> R where T: ToMessage {
                let msg_send_fn = msg_send_fn::<R>();
                let msg_send_fn: unsafe extern fn(*mut Object, Sel $(, $t)*) -> R =
                    mem::transmute(msg_send_fn);
                let obj_ptr = obj.as_ptr() as *mut Object;
                let ($($a,)*) = self;
                msg_send_fn(obj_ptr, sel $(, $a)*)
            }
        }
    );
}

message_args_impl!();
message_args_impl!(a: A);
message_args_impl!(a: A, b: B);
message_args_impl!(a: A, b: B, c: C);
message_args_impl!(a: A, b: B, c: C, d: D);
message_args_impl!(a: A, b: B, c: C, d: D, e: E);
message_args_impl!(a: A, b: B, c: C, d: D, e: E, f: F);
message_args_impl!(a: A, b: B, c: C, d: D, e: E, f: F, g: G);
message_args_impl!(a: A, b: B, c: C, d: D, e: E, f: F, g: G, h: H);
message_args_impl!(a: A, b: B, c: C, d: D, e: E, f: F, g: G, h: H, i: I);
message_args_impl!(a: A, b: B, c: C, d: D, e: E, f: F, g: G, h: H, i: I, j: J);
message_args_impl!(a: A, b: B, c: C, d: D, e: E, f: F, g: G, h: H, i: I, j: J, k: K);
message_args_impl!(a: A, b: B, c: C, d: D, e: E, f: F, g: G, h: H, i: I, j: J, k: K, l: L);

fn verify_message_signature<T, A, R>(obj: Option<&T>, sel: Sel, _args: &A) ->
        Result<(), String> where T: Message, A: MessageArguments, R: Encode {
    let obj = match obj {
        Some(obj) => obj,
        None => return Err(format!("Messaging {:?} to nil", sel)),
    };
    let cls = unsafe {
        let obj = &*(obj as *const _ as *const Object);
        obj.class()
    };
    let method = match cls.instance_method(sel) {
        Some(method) => method,
        None => return Err(format!("Method {:?} not found on class {:?}",
            sel, cls)),
    };

    let ret = encode::<R>();
    let expected_ret = method.return_type();
    // Allow encoding "oneway void" (Vv) as "void" (v)
    if expected_ret.as_slice() != ret && !(expected_ret.as_slice() == "Vv" && ret == "v") {
        return Err(format!("Return type code {} does not match expected {} for method {:?} on class {:?}",
            ret, expected_ret.as_slice(), sel, cls))
    }

    Ok(())
}

pub unsafe fn send_message<T, A, R>(obj: &T, sel: Sel, args: A) -> R
        where T: ToMessage, A: MessageArguments {
    args.send(obj, sel)
}

pub unsafe fn send_message_verified<T, A, R>(obj: &T, sel: Sel, args: A) ->
        Result<R, String> where T: ToMessage, A: MessageArguments, R: Encode {
    let obj_ref = obj.as_ptr().as_ref();
    verify_message_signature::<_, _, R>(obj_ref, sel, &args).and_then(
        move |()| Ok(args.send(obj, sel)))
}
<commit_msg>Added validation for self and _cmd arguments.<commit_after>use std::mem;
use std::ptr;

use runtime::{Class, Object, Sel, self};
use {encode, Encode, EncodePtr};

/*
 The Sized bound on Message is unfortunate; ideally, objc objects would not be
 treated as Sized. However, rust won't allow casting a dynamically-sized type
 pointer to an Object pointer, because dynamically-sized types can have fat
 pointers (two words) instead of real pointers.
 */
/// Types that may be sent Objective-C messages.
/// For example: objects, classes, and blocks.
pub unsafe trait Message: Sized + EncodePtr { }

unsafe impl Message for Object { }

unsafe impl Message for Class { }

/// A trait for converting to a pointer to a type that may be sent Objective-C
/// messages.
pub trait ToMessage : Encode {
    type Target: Message;

    fn as_ptr(&self) -> *mut Self::Target;

    fn is_nil(&self) -> bool {
        self.as_ptr().is_null()
    }
}

impl<T> ToMessage for *const T where T: Message {
    type Target = T;

    fn as_ptr(&self) -> *mut T {
        *self as *mut T
    }
}

impl<T> ToMessage for *mut T where T: Message {
    type Target = T;

    fn as_ptr(&self) -> *mut T {
        *self
    }
}

impl<'a, T> ToMessage for &'a T where T: Message {
    type Target = T;

    fn as_ptr(&self) -> *mut T {
        *self as *const T as *mut T
    }
}

impl<'a, T> ToMessage for &'a mut T where T: Message {
    type Target = T;

    fn as_ptr(&self) -> *mut T {
        *self
    }
}

impl<'a, T> ToMessage for Option<&'a T> where T: Message {
    type Target = T;

    fn as_ptr(&self) -> *mut T {
        match *self {
            None => ptr::null_mut(),
            Some(ref obj) => obj.as_ptr(),
        }
    }
}

impl<'a, T> ToMessage for Option<&'a mut T> where T: Message {
    type Target = T;

    fn as_ptr(&self) -> *mut T {
        match *self {
            None => ptr::null_mut(),
            Some(ref obj) => obj.as_ptr(),
        }
    }
}

fn msg_send_fn<R>() -> unsafe extern fn(*mut Object, Sel, ...) -> R {
    unsafe {
        mem::transmute(runtime::objc_msgSend)
    }
}

pub trait MessageArguments {
    unsafe fn send<T, R>(self, obj: &T, sel: Sel) -> R where T: ToMessage;
}

macro_rules! message_args_impl {
    ($($a:ident : $t:ident),*) => (
        impl<$($t),*> MessageArguments for ($($t,)*) {
            unsafe fn send<T, R>(self, obj: &T, sel: Sel) -> R where T: ToMessage {
                let msg_send_fn = msg_send_fn::<R>();
                let msg_send_fn: unsafe extern fn(*mut Object, Sel $(, $t)*) -> R =
                    mem::transmute(msg_send_fn);
                let obj_ptr = obj.as_ptr() as *mut Object;
                let ($($a,)*) = self;
                msg_send_fn(obj_ptr, sel $(, $a)*)
            }
        }
    );
}

message_args_impl!();
message_args_impl!(a: A);
message_args_impl!(a: A, b: B);
message_args_impl!(a: A, b: B, c: C);
message_args_impl!(a: A, b: B, c: C, d: D);
message_args_impl!(a: A, b: B, c: C, d: D, e: E);
message_args_impl!(a: A, b: B, c: C, d: D, e: E, f: F);
message_args_impl!(a: A, b: B, c: C, d: D, e: E, f: F, g: G);
message_args_impl!(a: A, b: B, c: C, d: D, e: E, f: F, g: G, h: H);
message_args_impl!(a: A, b: B, c: C, d: D, e: E, f: F, g: G, h: H, i: I);
message_args_impl!(a: A, b: B, c: C, d: D, e: E, f: F, g: G, h: H, i: I, j: J);
message_args_impl!(a: A, b: B, c: C, d: D, e: E, f: F, g: G, h: H, i: I, j: J, k: K);
message_args_impl!(a: A, b: B, c: C, d: D, e: E, f: F, g: G, h: H, i: I, j: J, k: K, l: L);

fn verify_message_signature<T, A, R>(obj: Option<&T>, sel: Sel, _args: &A) ->
        Result<(), String> where T: Message, A: MessageArguments, R: Encode {
    let obj = match obj {
        Some(obj) => obj,
        None => return Err(format!("Messaging {:?} to nil", sel)),
    };
    let cls = unsafe {
        let obj = &*(obj as *const _ as *const Object);
        obj.class()
    };
    let method = match cls.instance_method(sel) {
        Some(method) => method,
        None => return Err(format!("Method {:?} not found on class {:?}",
            sel, cls)),
    };

    let ret = encode::<R>();
    let expected_ret = method.return_type();
    // Allow encoding "oneway void" (Vv) as "void" (v)
    if expected_ret.as_slice() != ret && !(expected_ret.as_slice() == "Vv" && ret == "v") {
        return Err(format!("Return type code {} does not match expected {} for method {:?} on class {:?}",
            ret, expected_ret.as_slice(), sel, cls));
    }

    // I don't think either of these can happen, but just to be safe...
    let accepts_self_arg = match method.argument_type(0) {
        Some(s) => s.as_slice() == "@",
        None => false,
    };
    if !accepts_self_arg {
        return Err(format!("Method {:?} of class {:?} doesn't accept an argument for self",
            sel, cls));
    }
    let accepts_cmd_arg = match method.argument_type(1) {
        Some(s) => s.as_slice() == ":",
        None => false,
    };
    if !accepts_cmd_arg {
        return Err(format!("Method {:?} of class {:?} doesn't accept an argument for the selector",
            sel, cls));
    }

    Ok(())
}

pub unsafe fn send_message<T, A, R>(obj: &T, sel: Sel, args: A) -> R
        where T: ToMessage, A: MessageArguments {
    args.send(obj, sel)
}

pub unsafe fn send_message_verified<T, A, R>(obj: &T, sel: Sel, args: A) ->
        Result<R, String> where T: ToMessage, A: MessageArguments, R: Encode {
    let obj_ref = obj.as_ptr().as_ref();
    verify_message_signature::<_, _, R>(obj_ref, sel, &args).and_then(
        move |()| Ok(args.send(obj, sel)))
}
<|endoftext|>


<commit_before>
use regex_syntax::Expr;
use regex_syntax::Repeater;

use nfa::NFA;
use nfa::Spec;
use nfa::NFABuilder;
use nfa::Label;

struct Rule {
    regex: Expr,
    action: String,
}

fn repeater_to_spec(re: &Expr, r: &Repeater) -> Spec {
    let s1 = Box::new(regex_to_nfa_spec(re));

    match *r {
        Repeater::ZeroOrOne => Spec::Union(Spec::single(Label::Epsilon), s1),
        Repeater::ZeroOrMore => Spec::Star(s1),
        Repeater::OneOrMore => Spec::Concat(s1.clone(), Spec::star(s1)),
        Repeater::Range { min, max } => unimplemented!()
    }
}

fn regex_to_nfa_spec(re: &Expr) -> Spec {
    match *re {
        Expr::AnyChar => Spec::Single(Label::Any),
        Expr::Repeat { ref e, r, greedy } => repeater_to_spec(&*e, &r),
        _ => unimplemented!()
    }
}

#[test]
fn test_repeater_zero_or_more1() {
    let re = Expr::parse(r".*").unwrap();
    let spec = regex_to_nfa_spec(&re);

    println!("regex: {:?}", re);
    assert_eq!(spec, *Spec::star(Spec::single(Label::Any)));
}
<commit_msg>added provisional rule for AnyCharNoNL<commit_after>use regex_syntax::Expr;
use regex_syntax::Repeater;

use nfa::NFA;
use nfa::Spec;
use nfa::NFABuilder;
use nfa::Label;

struct Rule {
    regex: Expr,
    action: String,
}

fn repeater_to_spec(re: &Expr, r: &Repeater) -> Spec {
    let s1 = Box::new(regex_to_nfa_spec(re));

    match *r {
        Repeater::ZeroOrOne => Spec::Union(Spec::single(Label::Epsilon), s1),
        Repeater::ZeroOrMore => Spec::Star(s1),
        Repeater::OneOrMore => Spec::Concat(s1.clone(), Spec::star(s1)),
        Repeater::Range { min, max } => unimplemented!()
    }
}

fn regex_to_nfa_spec(re: &Expr) -> Spec {
    match *re {
        Expr::AnyChar => Spec::Single(Label::Any),
        Expr::AnyCharNoNL => Spec::Single(Label::Any),  // FIX: don't match newline
        Expr::Repeat { ref e, r, greedy } => repeater_to_spec(&*e, &r),
        _ => unimplemented!()
    }
}

#[test]
fn test_repeater_zero_or_more1() {
    let re = Expr::parse(r".*").unwrap();
    let spec = regex_to_nfa_spec(&re);

    println!("regex: {:?}", re);
    assert_eq!(spec, *Spec::star(Spec::single(Label::Any)));
}
<|endoftext|>


<commit_before>//! Defines the scene struct which contains the various objects defining the scene.
//! This includes the geometry, instances of the geometry, the camera and so on.

use std::sync::Arc;

use linalg::{Transform, Point, Vector, Ray};
use film::{Camera, Colorf};
use geometry::{Sphere, Plane, Instance};
use material::{Matte, SpecularMetal, Glass, Material};
use geometry::{Geometry, Intersection};
use integrator::{Whitted, Integrator};
use light;
use light::Light;

/// The scene containing the objects and camera configuration we'd like to render,
/// shared immutably among the ray tracing threads
pub struct Scene {
    pub camera: Arc<Camera>,
    /// TODO: Only one instance for now
    pub instances: Arc<Vec<Instance>>,
    pub integrator: Arc<Box<Integrator + Send + Sync>>,
    /// TODO: Only one light for now
    pub light: Arc<Box<Light + Send + Sync>>,
    sphere: Arc<Box<Geometry + Send + Sync>>,
}

impl Scene {
    /// Create our (currently) hard-coded scene, passing in the render target
    /// dimensions so we can set the projection matrix for the camera
    pub fn new(w: usize, h: usize) -> Scene {
        let sphere = Arc::new(Box::new(Sphere::new(2.0)) as Box<Geometry + Send + Sync>);
        let plane = Arc::new(Box::new(Plane) as Box<Geometry + Send + Sync>);
        let white_wall = Arc::new(Box::new(Matte::new(&Colorf::new(1.0, 1.0, 1.0), 1.0)) as Box<Material + Send + Sync>);
        let red_wall = Arc::new(Box::new(Matte::new(&Colorf::new(1.0, 0.2, 0.2), 1.0)) as Box<Material + Send + Sync>);
        let blue_wall = Arc::new(Box::new(Matte::new(&Colorf::new(0.2, 0.2, 1.0), 1.0)) as Box<Material + Send + Sync>);
        let instances = vec![
            // The reflective sphere
            Instance::new(sphere.clone(),
            Arc::new(Box::new(SpecularMetal::new(&Colorf::new(0.155, 0.116, 0.138),
                                                 &Colorf::new(4.828, 3.122, 2.146)))
                     as Box<Material + Send + Sync>), Transform::translate(&Vector::new(-3.0, -4.0, 6.0))),
            // The blue matte sphere
            Instance::new(sphere.clone(),
            Arc::new(Box::new(Glass::new(&Colorf::broadcast(1.0), &Colorf::broadcast(1.0), 1.52))
                     as Box<Material + Send + Sync>), Transform::translate(&Vector::new(3.0, -4.0, 3.0))),
            // The back wall
            Instance::new(plane.clone(), white_wall.clone(), Transform::translate(&Vector::new(0.0, 0.0, 10.0))
                          * Transform::scale(&Vector::broadcast(20.0))),
            // The left wall
            Instance::new(plane.clone(), red_wall.clone(), Transform::translate(&Vector::new(-6.0, 0.0, 0.0))
                          * Transform::scale(&Vector::broadcast(20.0)) * Transform::rotate_y(90.0)),
            // The right wall
            Instance::new(plane.clone(), blue_wall.clone(), Transform::translate(&Vector::new(6.0, 0.0, 0.0))
                          * Transform::scale(&Vector::broadcast(20.0)) * Transform::rotate_y(-90.0)),
            // The top wall
            Instance::new(plane.clone(), white_wall.clone(), Transform::translate(&Vector::new(0.0, 6.0, 0.0))
                          * Transform::scale(&Vector::broadcast(20.0)) * Transform::rotate_x(90.0)),
            // The bottom wall
            Instance::new(plane.clone(), white_wall.clone(), Transform::translate(&Vector::new(0.0, -6.0, 0.0))
                          * Transform::scale(&Vector::broadcast(20.0)) * Transform::rotate_x(-90.0))
        ];
        Scene {
            camera: Arc::new(Camera::new(Transform::look_at(&Point::new(0.0, 0.0, -16.0),
                &Point::new(0.0, 0.0, 0.0), &Vector::new(0.0, 1.0, 0.0)), 40.0, (w, h))),
            instances: Arc::new(instances),
            integrator: Arc::new(Box::new(Whitted::new(8)) as Box<Integrator + Send + Sync>),
            light: Arc::new(Box::new(light::Point::new(&Point::new(0.0, 5.0, 4.5), &Colorf::broadcast(40.0)))
                            as Box<Light + Send + Sync>),
            sphere: sphere.clone(),
        }
    }
    /// Test the ray for intersections against the objects in the scene.
    /// Returns Some(Intersection) if an intersection was found and None if not.
    pub fn intersect(&self, ray: &mut Ray) -> Option<Intersection> {
        // We can always return the next hit found since the ray's max_t value is updated
        // after an intersection is found. Thus if we find another hit we know that one
        // occured before any previous ones. TODO: Replace with a BVH
        self.instances.iter().fold(None, |p, ref i|
                                    match i.intersect(ray) {
                                        Some(h) => Some(h),
                                        None => p,
                                    })
    }
}

<commit_msg>Trying to match my small pt scene in tray to debug specular transmission<commit_after>//! Defines the scene struct which contains the various objects defining the scene.
//! This includes the geometry, instances of the geometry, the camera and so on.

use std::sync::Arc;

use linalg::{Transform, Point, Vector, Ray};
use film::{Camera, Colorf};
use geometry::{Sphere, Plane, Instance};
use material::{Matte, SpecularMetal, Glass, Material};
use geometry::{Geometry, Intersection};
use integrator::{Whitted, Integrator};
use light;
use light::Light;

/// The scene containing the objects and camera configuration we'd like to render,
/// shared immutably among the ray tracing threads
pub struct Scene {
    pub camera: Arc<Camera>,
    /// TODO: Only one instance for now
    pub instances: Arc<Vec<Instance>>,
    pub integrator: Arc<Box<Integrator + Send + Sync>>,
    /// TODO: Only one light for now
    pub light: Arc<Box<Light + Send + Sync>>,
    sphere: Arc<Box<Geometry + Send + Sync>>,
}

impl Scene {
    /// Create our (currently) hard-coded scene, passing in the render target
    /// dimensions so we can set the projection matrix for the camera
    pub fn new(w: usize, h: usize) -> Scene {
        let sphere = Arc::new(Box::new(Sphere::new(1.0)) as Box<Geometry + Send + Sync>);
        let plane = Arc::new(Box::new(Plane) as Box<Geometry + Send + Sync>);
        let white_wall = Arc::new(Box::new(Matte::new(&Colorf::new(1.0, 1.0, 1.0), 1.0)) as Box<Material + Send + Sync>);
        let red_wall = Arc::new(Box::new(Matte::new(&Colorf::new(1.0, 0.2, 0.2), 1.0)) as Box<Material + Send + Sync>);
        let blue_wall = Arc::new(Box::new(Matte::new(&Colorf::new(0.2, 0.2, 1.0), 1.0)) as Box<Material + Send + Sync>);
        let instances = vec![
            // The reflective sphere
            Instance::new(sphere.clone(),
            Arc::new(Box::new(SpecularMetal::new(&Colorf::new(0.155, 0.116, 0.138),
                                                 &Colorf::new(4.828, 3.122, 2.146)))
                     as Box<Material + Send + Sync>), Transform::translate(&Vector::new(-6.0, 8.0, 5.0))
                    * Transform::scale(&Vector::broadcast(5.0))),
            // The glass sphere
            Instance::new(sphere.clone(),
            Arc::new(Box::new(Glass::new(&Colorf::broadcast(0.0), &Colorf::broadcast(1.0), 1.52))
                     as Box<Material + Send + Sync>), Transform::translate(&Vector::new(6.0, -2.0, 5.0))
                    * Transform::scale(&Vector::broadcast(5.0))),
            // The back wall
            Instance::new(plane.clone(), white_wall.clone(), Transform::translate(&Vector::new(0.0, 20.0, 12.0))
                          * Transform::scale(&Vector::broadcast(32.0)) * Transform::rotate_x(90.0)),
            // The left wall
            Instance::new(plane.clone(), red_wall.clone(), Transform::translate(&Vector::new(-15.0, 0.0, 12.0))
                          * Transform::scale(&Vector::broadcast(32.0)) * Transform::rotate_y(90.0)),
            // The right wall
            Instance::new(plane.clone(), blue_wall.clone(), Transform::translate(&Vector::new(15.0, 0.0, 12.0))
                          * Transform::scale(&Vector::broadcast(32.0)) * Transform::rotate_y(-90.0)),
            // The top wall
            Instance::new(plane.clone(), white_wall.clone(), Transform::translate(&Vector::new(0.0, 0.0, 24.0))
                          * Transform::scale(&Vector::broadcast(32.0)) * Transform::rotate_x(180.0)),
            // The bottom wall
            Instance::new(plane.clone(), white_wall.clone(), Transform::translate(&Vector::new(0.0, 0.0, 0.0))
                          * Transform::scale(&Vector::broadcast(32.0)))
        ];
        Scene {
            camera: Arc::new(Camera::new(Transform::look_at(&Point::new(0.0, -60.0, 12.0),
                &Point::new(0.0, 0.0, 12.0), &Vector::new(0.0, 0.0, 1.0)), 30.0, (w, h))),
            instances: Arc::new(instances),
            integrator: Arc::new(Box::new(Whitted::new(8)) as Box<Integrator + Send + Sync>),
            light: Arc::new(Box::new(light::Point::new(&Point::new(0.0, 0.0, 22.0), &Colorf::broadcast(300.0)))
                            as Box<Light + Send + Sync>),
            sphere: sphere.clone(),
        }
    }
    /// Test the ray for intersections against the objects in the scene.
    /// Returns Some(Intersection) if an intersection was found and None if not.
    pub fn intersect(&self, ray: &mut Ray) -> Option<Intersection> {
        // We can always return the next hit found since the ray's max_t value is updated
        // after an intersection is found. Thus if we find another hit we know that one
        // occured before any previous ones. TODO: Replace with a BVH
        self.instances.iter().fold(None, |p, ref i|
                                    match i.intersect(ray) {
                                        Some(h) => Some(h),
                                        None => p,
                                    })
    }
}

<|endoftext|>