<commit_before>extern crate crossbeam;
extern crate clap;
#[macro_use] extern crate version;
#[macro_use] extern crate log;
extern crate walkdir;

extern crate libimagrt;
extern crate libimagerror;

use std::env;
use std::process::exit;
use std::process::Command;
use std::process::Stdio;
use std::io::ErrorKind;

use walkdir::WalkDir;
use crossbeam::*;
use clap::{Arg, AppSettings, SubCommand};

use libimagrt::runtime::Runtime;
use libimagerror::trace::trace_error;

fn help_text(cmds: Vec<String>) -> String {
    let text = format!(r#"

     _
    (_)_ __ ___   __ _  __ _
    | | '_ \` _ \/ _\`|/ _\`|
    | | | | | | | (_| | (_| |
    |_|_| |_| |_|\__,_|\__, |
                       |___/
    -------------------------

    Usage: imag [--version | --versions | -h | --help] <command> <args...>

    imag - the personal information management suite for the commandline

    imag is a PIM suite for the commandline. It consists of several commands,
    called "modules". Each module implements one PIM aspect and all of these
    modules can be used independently.

    Available commands:

    {imagbins}

    Call a command with 'imag <command> <args>'
    Each command can be called with "--help" to get the respective helptext.

    Please visit https://github.com/matthiasbeyer/imag to view the source code,
    follow the development of imag or maybe even contribute to imag.

    imag is free software. It is released under the terms of LGPLv2.1

    (c) 2016 Matthias Beyer and contributors"#, imagbins = cmds.into_iter()
        .map(|cmd| format!("\t{}\n", cmd))
        .fold(String::new(), |s, c| {
            let s = s + c.as_str();
            s
        }));
    text
}

fn get_commands() -> Vec<String> {
    let path = env::var("PATH");
    if path.is_err() {
        println!("PATH error: {:?}", path);
        exit(1);
    }
    let pathelements = path.unwrap();
    let pathelements = pathelements.split(":");

    let joinhandles : Vec<ScopedJoinHandle<Vec<String>>> = pathelements
        .map(|elem| {
            crossbeam::scope(|scope| {
                scope.spawn(|| {
                    WalkDir::new(elem)
                        .max_depth(1)
                        .into_iter()
                        .filter(|path| {
                            match path {
                                &Ok(ref p) => p.file_name()
                                    .to_str()
                                    .map_or(false, |filename| filename.starts_with("imag-")),
                                &Err(_)   => false,
                            }
                        })
                        .filter_map(|x| x.ok())
                        .filter_map(|path| {
                           path.file_name()
                               .to_str()
                               .and_then(|s| s.splitn(2, "-").nth(1).map(String::from))
                        })
                        .collect()
                })
            })
        })
        .collect();

    let mut execs = vec![];
    for joinhandle in joinhandles.into_iter() {
        let mut v = joinhandle.join();
        execs.append(&mut v);
    }

    execs
}

fn main() {
    let appname  = "imag";
    let version  = &version!();
    let about    = "imag - the PIM suite for the commandline";
    let commands = get_commands();
    let helptext = help_text(commands);
    let app      = Runtime::get_default_cli_builder(appname, version, about)
        .settings(&[AppSettings::AllowExternalSubcommands])
        .arg(Arg::with_name("version")
             .long("version")
             .takes_value(false)
             .required(false)
             .multiple(false)
             .help("Get the version of imag"))
        .arg(Arg::with_name("versions")
             .long("versions")
             .takes_value(false)
             .required(false)
             .multiple(false)
             .help("Get the versions of the imag commands"))
        .subcommand(SubCommand::with_name("help").help("Show help"))
        .help(helptext.as_str());
    let rt = Runtime::new(app)
        .unwrap_or_else(|e| {
            println!("Runtime couldn't be setup. Exiting");
            trace_error(&e);
            exit(1);
        });
    let matches = rt.cli();

    debug!("matches: {:?}", matches);

    if matches.is_present("version") {
        debug!("Showing version");
        println!("imag {}", &version!()[..]);
        exit(0);
    }

    if matches.is_present("versions") {
        debug!("Showing versions");
        let mut result = vec![];
        for command in get_commands().iter() {
            result.push(crossbeam::scope(|scope| {
                scope.spawn(|| {
                    let v = Command::new(command).arg("--version").output();
                    match v {
                        Ok(v) => match String::from_utf8(v.stdout) {
                            Ok(s) => format!("{} -> {}", command, s),
                            Err(e) => format!("Failed calling {} -> {:?}", command, e),
                        },
                        Err(e) => format!("Failed calling {} -> {:?}", command, e),
                    }
                })
            }))
        }

        for versionstring in result.into_iter().map(|handle| handle.join()) {
            println!("{}", versionstring);
        }
    }

    match matches.subcommand() {
        (subcommand, Some(scmd)) => {
            debug!("Calling with subcommand: {}", subcommand);
            let subcommand_args : Vec<&str> = match scmd.values_of("") {
                Some(values) => values.collect(),
                None => Vec::new()
            };
            debug!("Calling 'imag-{}' with args: {:?}", subcommand, subcommand_args);

            match Command::new(format!("imag-{}", subcommand))
                .stdin(Stdio::inherit())
                .stdout(Stdio::inherit())
                .stderr(Stdio::inherit())
                .args(&subcommand_args[..])
                .spawn()
                .and_then(|mut handle| handle.wait())
            {
                Ok(exit_status) => {
                    if !exit_status.success() {
                        debug!("{} exited with non-zero exit code: {:?}", subcommand, exit_status);
                        println!("{} exited with non-zero exit code", subcommand);
                        exit(exit_status.code().unwrap_or(42));
                    }
                    debug!("Successful exit!");
                },

                Err(e) => {
                    debug!("Error calling the subcommand");
                    match e.kind() {
                        ErrorKind::NotFound => {
                            println!("No such command: 'imag-{}'", subcommand);
                            println!("See 'imag --help' for available subcommands");
                            exit(2);
                        },
                        ErrorKind::PermissionDenied => {
                            println!("No permission to execute: 'imag-{}'", subcommand);
                            exit(1);
                        },
                        _ => {
                            println!("Error spawning: {:?}", e);
                            exit(1337);
                        }
                    }
                }
            }
        },
        // clap ensures we have valid input by exiting if not.
        // The above case is a catch-all for subcommands,
        // so nothing else needs to be expexted.
        _ => unreachable!(),
    }
}
<commit_msg>Fix exit codes<commit_after>extern crate crossbeam;
extern crate clap;
#[macro_use] extern crate version;
#[macro_use] extern crate log;
extern crate walkdir;

extern crate libimagrt;
extern crate libimagerror;

use std::env;
use std::process::exit;
use std::process::Command;
use std::process::Stdio;
use std::io::ErrorKind;

use walkdir::WalkDir;
use crossbeam::*;
use clap::{Arg, AppSettings, SubCommand};

use libimagrt::runtime::Runtime;
use libimagerror::trace::trace_error;

fn help_text(cmds: Vec<String>) -> String {
    let text = format!(r#"

     _
    (_)_ __ ___   __ _  __ _
    | | '_ \` _ \/ _\`|/ _\`|
    | | | | | | | (_| | (_| |
    |_|_| |_| |_|\__,_|\__, |
                       |___/
    -------------------------

    Usage: imag [--version | --versions | -h | --help] <command> <args...>

    imag - the personal information management suite for the commandline

    imag is a PIM suite for the commandline. It consists of several commands,
    called "modules". Each module implements one PIM aspect and all of these
    modules can be used independently.

    Available commands:

    {imagbins}

    Call a command with 'imag <command> <args>'
    Each command can be called with "--help" to get the respective helptext.

    Please visit https://github.com/matthiasbeyer/imag to view the source code,
    follow the development of imag or maybe even contribute to imag.

    imag is free software. It is released under the terms of LGPLv2.1

    (c) 2016 Matthias Beyer and contributors"#, imagbins = cmds.into_iter()
        .map(|cmd| format!("\t{}\n", cmd))
        .fold(String::new(), |s, c| {
            let s = s + c.as_str();
            s
        }));
    text
}

fn get_commands() -> Vec<String> {
    let path = env::var("PATH");
    if path.is_err() {
        println!("PATH error: {:?}", path);
        exit(1);
    }
    let pathelements = path.unwrap();
    let pathelements = pathelements.split(":");

    let joinhandles : Vec<ScopedJoinHandle<Vec<String>>> = pathelements
        .map(|elem| {
            crossbeam::scope(|scope| {
                scope.spawn(|| {
                    WalkDir::new(elem)
                        .max_depth(1)
                        .into_iter()
                        .filter(|path| {
                            match path {
                                &Ok(ref p) => p.file_name()
                                    .to_str()
                                    .map_or(false, |filename| filename.starts_with("imag-")),
                                &Err(_)   => false,
                            }
                        })
                        .filter_map(|x| x.ok())
                        .filter_map(|path| {
                           path.file_name()
                               .to_str()
                               .and_then(|s| s.splitn(2, "-").nth(1).map(String::from))
                        })
                        .collect()
                })
            })
        })
        .collect();

    let mut execs = vec![];
    for joinhandle in joinhandles.into_iter() {
        let mut v = joinhandle.join();
        execs.append(&mut v);
    }

    execs
}

fn main() {
    let appname  = "imag";
    let version  = &version!();
    let about    = "imag - the PIM suite for the commandline";
    let commands = get_commands();
    let helptext = help_text(commands);
    let app      = Runtime::get_default_cli_builder(appname, version, about)
        .settings(&[AppSettings::AllowExternalSubcommands])
        .arg(Arg::with_name("version")
             .long("version")
             .takes_value(false)
             .required(false)
             .multiple(false)
             .help("Get the version of imag"))
        .arg(Arg::with_name("versions")
             .long("versions")
             .takes_value(false)
             .required(false)
             .multiple(false)
             .help("Get the versions of the imag commands"))
        .subcommand(SubCommand::with_name("help").help("Show help"))
        .help(helptext.as_str());
    let rt = Runtime::new(app)
        .unwrap_or_else(|e| {
            println!("Runtime couldn't be setup. Exiting");
            trace_error(&e);
            exit(1);
        });
    let matches = rt.cli();

    debug!("matches: {:?}", matches);

    if matches.is_present("version") {
        debug!("Showing version");
        println!("imag {}", &version!()[..]);
        exit(0);
    }

    if matches.is_present("versions") {
        debug!("Showing versions");
        let mut result = vec![];
        for command in get_commands().iter() {
            result.push(crossbeam::scope(|scope| {
                scope.spawn(|| {
                    let v = Command::new(command).arg("--version").output();
                    match v {
                        Ok(v) => match String::from_utf8(v.stdout) {
                            Ok(s) => format!("{} -> {}", command, s),
                            Err(e) => format!("Failed calling {} -> {:?}", command, e),
                        },
                        Err(e) => format!("Failed calling {} -> {:?}", command, e),
                    }
                })
            }))
        }

        for versionstring in result.into_iter().map(|handle| handle.join()) {
            println!("{}", versionstring);
        }
    }

    match matches.subcommand() {
        (subcommand, Some(scmd)) => {
            debug!("Calling with subcommand: {}", subcommand);
            let subcommand_args : Vec<&str> = match scmd.values_of("") {
                Some(values) => values.collect(),
                None => Vec::new()
            };
            debug!("Calling 'imag-{}' with args: {:?}", subcommand, subcommand_args);

            match Command::new(format!("imag-{}", subcommand))
                .stdin(Stdio::inherit())
                .stdout(Stdio::inherit())
                .stderr(Stdio::inherit())
                .args(&subcommand_args[..])
                .spawn()
                .and_then(|mut handle| handle.wait())
            {
                Ok(exit_status) => {
                    if !exit_status.success() {
                        debug!("{} exited with non-zero exit code: {:?}", subcommand, exit_status);
                        println!("{} exited with non-zero exit code", subcommand);
                        exit(exit_status.code().unwrap_or(1));
                    }
                    debug!("Successful exit!");
                },

                Err(e) => {
                    debug!("Error calling the subcommand");
                    match e.kind() {
                        ErrorKind::NotFound => {
                            println!("No such command: 'imag-{}'", subcommand);
                            println!("See 'imag --help' for available subcommands");
                            exit(2);
                        },
                        ErrorKind::PermissionDenied => {
                            println!("No permission to execute: 'imag-{}'", subcommand);
                            exit(1);
                        },
                        _ => {
                            println!("Error spawning: {:?}", e);
                            exit(1);
                        }
                    }
                }
            }
        },
        // clap ensures we have valid input by exiting if not.
        // The above case is a catch-all for subcommands,
        // so nothing else needs to be expexted.
        _ => unreachable!(),
    }
}
<|endoftext|>


<commit_before><commit_msg>[No-auto] bin/core/tag: Fix Clippy warnings<commit_after><|endoftext|>


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

extern crate rustfmt;

use std::collections::HashMap;
use std::fs;
use std::io::Read;
use std::thread;
use rustfmt::*;

// For now, the only supported regression tests are idempotent tests - the input and
// output must match exactly.
// FIXME(#28) would be good to check for error messages and fail on them, or at least report.
#[test]
fn idempotent_tests() {
    println!("Idempotent tests:");

    // Get all files in the tests/idem directory
    let files = fs::read_dir("tests/idem").unwrap();
    let files = files.chain(fs::read_dir("tests").unwrap());
    let files = files.chain(fs::read_dir("src/bin").unwrap());
    // turn a DirEntry into a String that represents the relative path to the file
    let files = files.map(|e| e.unwrap().path().to_str().unwrap().to_owned());
    // hack because there's no `IntoIterator` impl for `[T; N]`
    let files = files.chain(Some("src/lib.rs".to_owned()).into_iter());

    // For each file, run rustfmt and collect the output
    let mut count = 0;
    let mut fails = 0;
    for file_name in files.filter(|f| f.ends_with(".rs")) {
        println!("Testing '{}'...", file_name);
        match idempotent_check(file_name) {
            Ok(()) => {},
            Err(m) => {
                print_mismatches(m);
                fails += 1;
            },
        }
        count += 1;
    }

    // Display results
    println!("Ran {} idempotent tests; {} failures.", count, fails);
    assert!(fails == 0, "{} idempotent tests failed", fails);
}

// Compare output to input.
fn print_mismatches(result: HashMap<String, String>) {
    for (file_name, fmt_text) in result {
        println!("Mismatch in {}.", file_name);
        println!("{}", fmt_text);
    }
}

// Ick, just needed to get a &'static to handle_result.
static HANDLE_RESULT: &'static Fn(HashMap<String, String>) = &handle_result;

pub fn idempotent_check(filename: String) -> Result<(), HashMap<String, String>> {
    let args = vec!["rustfmt".to_owned(), filename];
    // this thread is not used for concurrency, but rather to workaround the issue that the passed
    // function handle needs to have static lifetime. Instead of using a global RefCell, we use
    // panic to return a result in case of failure. This has the advantage of smoothing the road to
    // multithreaded rustfmt
    thread::spawn(move || {
        run(args, WriteMode::Return(HANDLE_RESULT));
    }).join().map_err(|any|
        // i know it is a hashmap
        *any.downcast().unwrap()
    )
}

// Compare output to input.
fn handle_result(result: HashMap<String, String>) {
    let mut failures = HashMap::new();

    for (file_name, fmt_text) in result {
        let mut f = fs::File::open(&file_name).unwrap();
        let mut text = String::new();
        // TODO: speedup by running through bytes iterator
        f.read_to_string(&mut text).unwrap();
        if fmt_text != text {
            failures.insert(file_name, fmt_text);
        }
    }
    if !failures.is_empty() {
        panic!(failures);
    }
}
<commit_msg>don't create a thread just for panic-isolation<commit_after>// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![feature(catch_panic)]

extern crate rustfmt;

use std::collections::HashMap;
use std::fs;
use std::io::Read;
use std::thread;
use rustfmt::*;

// For now, the only supported regression tests are idempotent tests - the input and
// output must match exactly.
// FIXME(#28) would be good to check for error messages and fail on them, or at least report.
#[test]
fn idempotent_tests() {
    println!("Idempotent tests:");

    // Get all files in the tests/idem directory
    let files = fs::read_dir("tests/idem").unwrap();
    let files = files.chain(fs::read_dir("tests").unwrap());
    let files = files.chain(fs::read_dir("src/bin").unwrap());
    // turn a DirEntry into a String that represents the relative path to the file
    let files = files.map(|e| e.unwrap().path().to_str().unwrap().to_owned());
    // hack because there's no `IntoIterator` impl for `[T; N]`
    let files = files.chain(Some("src/lib.rs".to_owned()).into_iter());

    // For each file, run rustfmt and collect the output
    let mut count = 0;
    let mut fails = 0;
    for file_name in files.filter(|f| f.ends_with(".rs")) {
        println!("Testing '{}'...", file_name);
        match idempotent_check(file_name) {
            Ok(()) => {},
            Err(m) => {
                print_mismatches(m);
                fails += 1;
            },
        }
        count += 1;
    }

    // Display results
    println!("Ran {} idempotent tests; {} failures.", count, fails);
    assert!(fails == 0, "{} idempotent tests failed", fails);
}

// Compare output to input.
fn print_mismatches(result: HashMap<String, String>) {
    for (file_name, fmt_text) in result {
        println!("Mismatch in {}.", file_name);
        println!("{}", fmt_text);
    }
}

// Ick, just needed to get a &'static to handle_result.
static HANDLE_RESULT: &'static Fn(HashMap<String, String>) = &handle_result;

pub fn idempotent_check(filename: String) -> Result<(), HashMap<String, String>> {
    let args = vec!["rustfmt".to_owned(), filename];
    // this thread is not used for concurrency, but rather to workaround the issue that the passed
    // function handle needs to have static lifetime. Instead of using a global RefCell, we use
    // panic to return a result in case of failure. This has the advantage of smoothing the road to
    // multithreaded rustfmt
    thread::catch_panic(move || {
        run(args, WriteMode::Return(HANDLE_RESULT));
    }).map_err(|any|
        // i know it is a hashmap
        *any.downcast().unwrap()
    )
}

// Compare output to input.
fn handle_result(result: HashMap<String, String>) {
    let mut failures = HashMap::new();

    for (file_name, fmt_text) in result {
        let mut f = fs::File::open(&file_name).unwrap();
        let mut text = String::new();
        // TODO: speedup by running through bytes iterator
        f.read_to_string(&mut text).unwrap();
        if fmt_text != text {
            failures.insert(file_name, fmt_text);
        }
    }
    if !failures.is_empty() {
        panic!(failures);
    }
}
<|endoftext|>


<commit_before>#![feature(core, io)]
extern crate hyper;
#[macro_use] extern crate log;

use std::old_io::util::copy;
use std::old_io::net::ip::Ipv4Addr;

use hyper::{Get, Post};
use hyper::header::ContentLength;
use hyper::server::{Server, Request, Response};
use hyper::uri::RequestUri::AbsolutePath;

macro_rules! try_return(
    ($e:expr) => {{
        match $e {
            Ok(v) => v,
            Err(e) => { error!("Error: {}", e); return; }
        }
    }}
);

fn echo(mut req: Request, mut res: Response) {
    match req.uri {
        AbsolutePath(ref path) => match (&req.method, &path[]) {
            (&Get, "/") | (&Get, "/echo") => {
                let out = b"Try POST /echo";

                res.headers_mut().set(ContentLength(out.len() as u64));
                let mut res = try_return!(res.start());
                try_return!(res.write_all(out));
                try_return!(res.end());
                return;
            },
            (&Post, "/echo") => (), // fall through, fighting mutable borrows
            _ => {
                *res.status_mut() = hyper::NotFound;
                try_return!(res.start().and_then(|res| res.end()));
                return;
            }
        },
        _ => {
            try_return!(res.start().and_then(|res| res.end()));
            return;
        }
    };

    let mut res = try_return!(res.start());
    try_return!(copy(&mut req, &mut res));
    try_return!(res.end());
}

fn main() {
    let server = Server::http(Ipv4Addr(127, 0, 0, 1), 1337);
    let mut listening = server.listen(echo).unwrap();
    println!("Listening on http://127.0.0.1:1337");
    listening.await();
}
<commit_msg>fix(rustup): fix unused_feature warning in example server<commit_after>#![feature(io)]
extern crate hyper;
#[macro_use] extern crate log;

use std::old_io::util::copy;
use std::old_io::net::ip::Ipv4Addr;

use hyper::{Get, Post};
use hyper::header::ContentLength;
use hyper::server::{Server, Request, Response};
use hyper::uri::RequestUri::AbsolutePath;

macro_rules! try_return(
    ($e:expr) => {{
        match $e {
            Ok(v) => v,
            Err(e) => { error!("Error: {}", e); return; }
        }
    }}
);

fn echo(mut req: Request, mut res: Response) {
    match req.uri {
        AbsolutePath(ref path) => match (&req.method, &path[]) {
            (&Get, "/") | (&Get, "/echo") => {
                let out = b"Try POST /echo";

                res.headers_mut().set(ContentLength(out.len() as u64));
                let mut res = try_return!(res.start());
                try_return!(res.write_all(out));
                try_return!(res.end());
                return;
            },
            (&Post, "/echo") => (), // fall through, fighting mutable borrows
            _ => {
                *res.status_mut() = hyper::NotFound;
                try_return!(res.start().and_then(|res| res.end()));
                return;
            }
        },
        _ => {
            try_return!(res.start().and_then(|res| res.end()));
            return;
        }
    };

    let mut res = try_return!(res.start());
    try_return!(copy(&mut req, &mut res));
    try_return!(res.end());
}

fn main() {
    let server = Server::http(Ipv4Addr(127, 0, 0, 1), 1337);
    let mut listening = server.listen(echo).unwrap();
    println!("Listening on http://127.0.0.1:1337");
    listening.await();
}
<|endoftext|>


<commit_before><commit_msg>show all elements<commit_after><|endoftext|>


<commit_before>pub mod path;
pub mod file;
pub mod parser;
pub mod json;
<commit_msg>Add Store type<commit_after>use std::cell::RefCell;
use std::collections::HashMap;

pub mod path;
pub mod file;
pub mod parser;
pub mod json;

use storage::file::File;
use storage::file::id::FileID;

type Cache<'a> = HashMap<FileID, RefCell<File<'a>>>;

pub struct Store<'a> {
    cache : RefCell<Cache<'a>>,
}

impl<'a> Store<'a> {

    pub fn new() -> Store<'a> {
        Store {
            cache: RefCell::new(HashMap::new()),
        }
    }

}
<|endoftext|>


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

#![cfg_attr(stage0, feature(custom_attribute))]
#![crate_name = "alloc_system"]
#![crate_type = "rlib"]
#![no_std]
#![cfg_attr(not(stage0), allocator)]
#![unstable(feature = "alloc_system",
            reason = "this library is unlikely to be stabilized in its current \
                      form or name",
            issue = "27783")]
#![feature(allocator)]
#![feature(asm)]
#![feature(no_std)]
#![feature(staged_api)]

// The minimum alignment guaranteed by the architecture. This value is used to
// add fast paths for low alignment values. In practice, the alignment is a
// constant at the call site and the branch will be optimized out.
#[cfg(all(any(target_arch = "arm",
              target_arch = "mips",
              target_arch = "mipsel",
              target_arch = "powerpc")))]
const MIN_ALIGN: usize = 8;
#[cfg(all(any(target_arch = "x86",
              target_arch = "x86_64",
              target_arch = "aarch64")))]
const MIN_ALIGN: usize = 16;

extern {
    fn memmove(dst: *mut u8, src: *const u8, size: usize);
    fn __rust_allocate(size: usize, align: usize) -> *mut u8;
    fn __rust_deallocate(ptr: *mut u8, old_size: usize, align: usize);
    fn __rust_reallocate(ptr: *mut u8, old_size: usize, size: usize, align: usize) -> *mut u8;
    fn __rust_reallocate_inplace(ptr: *mut u8, old_size: usize, size: usize, align: usize) -> usize;
    fn __rust_usable_size(size: usize, align: usize) -> usize;
 }
<commit_msg>feature(no_std) no longer required<commit_after>// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![cfg_attr(stage0, feature(custom_attribute))]
#![crate_name = "alloc_system"]
#![crate_type = "rlib"]
#![no_std]
#![cfg_attr(not(stage0), allocator)]
#![unstable(feature = "alloc_system",
            reason = "this library is unlikely to be stabilized in its current \
                      form or name",
            issue = "27783")]
#![feature(allocator)]
#![feature(asm)]
#![feature(staged_api)]

// The minimum alignment guaranteed by the architecture. This value is used to
// add fast paths for low alignment values. In practice, the alignment is a
// constant at the call site and the branch will be optimized out.
#[cfg(all(any(target_arch = "arm",
              target_arch = "mips",
              target_arch = "mipsel",
              target_arch = "powerpc")))]
const MIN_ALIGN: usize = 8;
#[cfg(all(any(target_arch = "x86",
              target_arch = "x86_64",
              target_arch = "aarch64")))]
const MIN_ALIGN: usize = 16;

extern {
    fn memmove(dst: *mut u8, src: *const u8, size: usize);
    fn __rust_allocate(size: usize, align: usize) -> *mut u8;
    fn __rust_deallocate(ptr: *mut u8, old_size: usize, align: usize);
    fn __rust_reallocate(ptr: *mut u8, old_size: usize, size: usize, align: usize) -> *mut u8;
    fn __rust_reallocate_inplace(ptr: *mut u8, old_size: usize, size: usize, align: usize) -> usize;
    fn __rust_usable_size(size: usize, align: usize) -> usize;
 }
<|endoftext|>


<commit_before>use std::collections::BTreeMap;
use std::ops::{Deref, DerefMut};
use std::io::BufRead;
use std::result::Result as RResult;

use toml::Value;
use uuid::Uuid;

use task_hookrs::task::Task as TTask;
use task_hookrs::import::{import_task, import_tasks};

use libimagstore::store::{FileLockEntry, Store};
use libimagstore::storeid::{IntoStoreId, StoreIdIterator, StoreId};
use module_path::ModuleEntryPath;

use error::{TodoError, TodoErrorKind, MapErrInto};
use result::Result;

/// Task struct containing a `FileLockEntry`
#[derive(Debug)]
pub struct Task<'a>(FileLockEntry<'a>);

impl<'a> Task<'a> {

    /// Concstructs a new `Task` with a `FileLockEntry`
    pub fn new(fle: FileLockEntry<'a>) -> Task<'a> {
        Task(fle)
    }

    pub fn import<R: BufRead>(store: &'a Store, mut r: R) -> Result<(Task<'a>, Uuid)> {
        let mut line = String::new();
        r.read_line(&mut line);
        import_task(&line.as_str())
            .map_err_into(TodoErrorKind::ImportError)
            .and_then(|t| {
                let uuid = t.uuid().clone();
                t.into_task(store).map(|t| (t, uuid))
            })
    }

    /// Get a task from an import string. That is: read the imported string, get the UUID from it
    /// and try to load this UUID from store.
    ///
    /// Possible return values are:
    ///
    /// * Ok(Ok(Task))
    /// * Ok(Err(String)) - where the String is the String read from the `r` parameter
    /// * Err(_)          - where the error is an error that happened during evaluation
    ///
    pub fn get_from_import<R: BufRead>(store: &'a Store, mut r: R) -> Result<RResult<Task<'a>, String>>
    {
        let mut line = String::new();
        r.read_line(&mut line);
        Task::get_from_string(store, line)
    }

    /// Get a task from a String. The String is expected to contain the JSON-representation of the
    /// Task to get from the store (only the UUID really matters in this case)
    ///
    /// For an explanation on the return values see `Task::get_from_import()`.
    pub fn get_from_string(store: &'a Store, s: String) -> Result<RResult<Task<'a>, String>> {
        import_task(s.as_str())
            .map_err_into(TodoErrorKind::ImportError)
            .map(|t| t.uuid().clone())
            .and_then(|uuid| Task::get_from_uuid(store, uuid))
            .and_then(|o| match o {
                None    => Ok(Err(s)),
                Some(t) => Ok(Ok(t)),
            })
    }

    /// Get a task from an UUID.
    ///
    /// If there is no task with this UUID, this returns `Ok(None)`.
    pub fn get_from_uuid(store: &'a Store, uuid: Uuid) -> Result<Option<Task<'a>>> {
        let store_id = ModuleEntryPath::new(format!("taskwarrior/{}", uuid)).into_storeid();

        store.get(store_id)
            .map(|o| o.map(Task::new))
            .map_err_into(TodoErrorKind::StoreError)
    }

    /// Same as Task::get_from_import() but uses Store::retrieve() rather than Store::get(), to
    /// implicitely create the task if it does not exist.
    pub fn retrieve_from_import<R: BufRead>(store: &'a Store, mut r: R) -> Result<Task<'a>> {
        let mut line = String::new();
        r.read_line(&mut line);
        Task::retrieve_from_string(store, line)
    }

    /// Retrieve a task from a String. The String is expected to contain the JSON-representation of
    /// the Task to retrieve from the store (only the UUID really matters in this case)
    pub fn retrieve_from_string(store: &'a Store, s: String) -> Result<Task<'a>> {
        Task::get_from_string(store, s)
            .and_then(|opt| match opt {
                Ok(task)    => Ok(task),
                Err(string) => import_task(string.as_str())
                    .map_err_into(TodoErrorKind::ImportError)
                    .and_then(|t| t.into_task(store)),
            })
    }

    pub fn delete_by_uuid(store: &Store, uuid: Uuid) -> Result<()> {
        store.delete(ModuleEntryPath::new(format!("taskwarrior/{}", uuid)).into_storeid())
            .map_err(|e| TodoError::new(TodoErrorKind::StoreError, Some(Box::new(e))))
    }

    pub fn all_as_ids(store: &Store) -> Result<StoreIdIterator> {
        store.retrieve_for_module("todo/taskwarrior")
            .map_err(|e| TodoError::new(TodoErrorKind::StoreError, Some(Box::new(e))))
    }

    pub fn all(store: &Store) -> Result<TaskIterator> {
        Task::all_as_ids(store)
            .map(|iter| TaskIterator::new(store, iter))
    }

}

impl<'a> Deref for Task<'a> {
    type Target = FileLockEntry<'a>;

    fn deref(&self) -> &FileLockEntry<'a> {
        &self.0
    }

}

impl<'a> DerefMut for Task<'a> {

    fn deref_mut(&mut self) -> &mut FileLockEntry<'a> {
        &mut self.0
    }

}

/// A trait to get a `libimagtodo::task::Task` out of the implementing object.
/// This Task struct is merely a wrapper for a `FileLockEntry`, therefore the function name
/// `into_filelockentry`.
pub trait IntoTask<'a> {

    /// # Usage
    /// ```ignore
    /// use std::io::stdin;
    ///
    /// use task_hookrs::task::Task;
    /// use task_hookrs::import::import;
    /// use libimagstore::store::{Store, FileLockEntry};
    ///
    /// if let Ok(task_hookrs_task) = import(stdin()) {
    ///     // Store is given at runtime
    ///     let task = task_hookrs_task.into_filelockentry(store);
    ///     println!("Task with uuid: {}", task.flentry.get_header().get("todo.uuid"));
    /// }
    /// ```
    fn into_task(self, store : &'a Store) -> Result<Task<'a>>;

}

impl<'a> IntoTask<'a> for TTask {

    fn into_task(self, store : &'a Store) -> Result<Task<'a>> {
        let uuid     = self.uuid();
        let store_id = ModuleEntryPath::new(format!("taskwarrior/{}", uuid)).into_storeid();

        match store.retrieve(store_id) {
            Err(e) => return Err(TodoError::new(TodoErrorKind::StoreError, Some(Box::new(e)))),
            Ok(mut fle) => {
                {
                    let mut header = fle.get_header_mut();
                    match header.read("todo") {
                        Ok(None) => {
                            if let Err(e) = header.set("todo", Value::Table(BTreeMap::new())) {
                                return Err(TodoError::new(TodoErrorKind::StoreError, Some(Box::new(e))))
                            }
                        }
                        Ok(Some(_)) => { }
                        Err(e) => {
                            return Err(TodoError::new(TodoErrorKind::StoreError, Some(Box::new(e))))
                        }
                    }

                    if let Err(e) = header.set("todo.uuid", Value::String(format!("{}",uuid))) {
                        return Err(TodoError::new(TodoErrorKind::StoreError, Some(Box::new(e))))
                    }
                }

                // If none of the errors above have returned the function, everything is fine
                Ok(Task::new(fle))
            }
        }
    }

}

trait FromStoreId {
    fn from_storeid<'a>(&'a Store, StoreId) -> Result<Task<'a>>;
}

impl<'a> FromStoreId for Task<'a> {

    fn from_storeid<'b>(store: &'b Store, id: StoreId) -> Result<Task<'b>> {
        match store.retrieve(id) {
            Err(e) => Err(TodoError::new(TodoErrorKind::StoreError, Some(Box::new(e)))),
            Ok(c)  => Ok(Task::new( c )),
        }
    }
}

pub struct TaskIterator<'a> {
    store: &'a Store,
    iditer: StoreIdIterator,
}

impl<'a> TaskIterator<'a> {

    pub fn new(store: &'a Store, iditer: StoreIdIterator) -> TaskIterator<'a> {
        TaskIterator {
            store: store,
            iditer: iditer,
        }
    }

}

impl<'a> Iterator for TaskIterator<'a> {
    type Item = Result<Task<'a>>;

    fn next(&mut self) -> Option<Result<Task<'a>>> {
        self.iditer.next().map(|id| Task::from_storeid(self.store, id))
    }
}

<commit_msg>Return the imported string as well<commit_after>use std::collections::BTreeMap;
use std::ops::{Deref, DerefMut};
use std::io::BufRead;
use std::result::Result as RResult;

use toml::Value;
use uuid::Uuid;

use task_hookrs::task::Task as TTask;
use task_hookrs::import::{import_task, import_tasks};

use libimagstore::store::{FileLockEntry, Store};
use libimagstore::storeid::{IntoStoreId, StoreIdIterator, StoreId};
use module_path::ModuleEntryPath;

use error::{TodoError, TodoErrorKind, MapErrInto};
use result::Result;

/// Task struct containing a `FileLockEntry`
#[derive(Debug)]
pub struct Task<'a>(FileLockEntry<'a>);

impl<'a> Task<'a> {

    /// Concstructs a new `Task` with a `FileLockEntry`
    pub fn new(fle: FileLockEntry<'a>) -> Task<'a> {
        Task(fle)
    }

    pub fn import<R: BufRead>(store: &'a Store, mut r: R) -> Result<(Task<'a>, String, Uuid)> {
        let mut line = String::new();
        r.read_line(&mut line);
        import_task(&line.as_str())
            .map_err_into(TodoErrorKind::ImportError)
            .and_then(|t| {
                let uuid = t.uuid().clone();
                t.into_task(store).map(|t| (t, line, uuid))
            })
    }

    /// Get a task from an import string. That is: read the imported string, get the UUID from it
    /// and try to load this UUID from store.
    ///
    /// Possible return values are:
    ///
    /// * Ok(Ok(Task))
    /// * Ok(Err(String)) - where the String is the String read from the `r` parameter
    /// * Err(_)          - where the error is an error that happened during evaluation
    ///
    pub fn get_from_import<R: BufRead>(store: &'a Store, mut r: R) -> Result<RResult<Task<'a>, String>>
    {
        let mut line = String::new();
        r.read_line(&mut line);
        Task::get_from_string(store, line)
    }

    /// Get a task from a String. The String is expected to contain the JSON-representation of the
    /// Task to get from the store (only the UUID really matters in this case)
    ///
    /// For an explanation on the return values see `Task::get_from_import()`.
    pub fn get_from_string(store: &'a Store, s: String) -> Result<RResult<Task<'a>, String>> {
        import_task(s.as_str())
            .map_err_into(TodoErrorKind::ImportError)
            .map(|t| t.uuid().clone())
            .and_then(|uuid| Task::get_from_uuid(store, uuid))
            .and_then(|o| match o {
                None    => Ok(Err(s)),
                Some(t) => Ok(Ok(t)),
            })
    }

    /// Get a task from an UUID.
    ///
    /// If there is no task with this UUID, this returns `Ok(None)`.
    pub fn get_from_uuid(store: &'a Store, uuid: Uuid) -> Result<Option<Task<'a>>> {
        let store_id = ModuleEntryPath::new(format!("taskwarrior/{}", uuid)).into_storeid();

        store.get(store_id)
            .map(|o| o.map(Task::new))
            .map_err_into(TodoErrorKind::StoreError)
    }

    /// Same as Task::get_from_import() but uses Store::retrieve() rather than Store::get(), to
    /// implicitely create the task if it does not exist.
    pub fn retrieve_from_import<R: BufRead>(store: &'a Store, mut r: R) -> Result<Task<'a>> {
        let mut line = String::new();
        r.read_line(&mut line);
        Task::retrieve_from_string(store, line)
    }

    /// Retrieve a task from a String. The String is expected to contain the JSON-representation of
    /// the Task to retrieve from the store (only the UUID really matters in this case)
    pub fn retrieve_from_string(store: &'a Store, s: String) -> Result<Task<'a>> {
        Task::get_from_string(store, s)
            .and_then(|opt| match opt {
                Ok(task)    => Ok(task),
                Err(string) => import_task(string.as_str())
                    .map_err_into(TodoErrorKind::ImportError)
                    .and_then(|t| t.into_task(store)),
            })
    }

    pub fn delete_by_uuid(store: &Store, uuid: Uuid) -> Result<()> {
        store.delete(ModuleEntryPath::new(format!("taskwarrior/{}", uuid)).into_storeid())
            .map_err(|e| TodoError::new(TodoErrorKind::StoreError, Some(Box::new(e))))
    }

    pub fn all_as_ids(store: &Store) -> Result<StoreIdIterator> {
        store.retrieve_for_module("todo/taskwarrior")
            .map_err(|e| TodoError::new(TodoErrorKind::StoreError, Some(Box::new(e))))
    }

    pub fn all(store: &Store) -> Result<TaskIterator> {
        Task::all_as_ids(store)
            .map(|iter| TaskIterator::new(store, iter))
    }

}

impl<'a> Deref for Task<'a> {
    type Target = FileLockEntry<'a>;

    fn deref(&self) -> &FileLockEntry<'a> {
        &self.0
    }

}

impl<'a> DerefMut for Task<'a> {

    fn deref_mut(&mut self) -> &mut FileLockEntry<'a> {
        &mut self.0
    }

}

/// A trait to get a `libimagtodo::task::Task` out of the implementing object.
/// This Task struct is merely a wrapper for a `FileLockEntry`, therefore the function name
/// `into_filelockentry`.
pub trait IntoTask<'a> {

    /// # Usage
    /// ```ignore
    /// use std::io::stdin;
    ///
    /// use task_hookrs::task::Task;
    /// use task_hookrs::import::import;
    /// use libimagstore::store::{Store, FileLockEntry};
    ///
    /// if let Ok(task_hookrs_task) = import(stdin()) {
    ///     // Store is given at runtime
    ///     let task = task_hookrs_task.into_filelockentry(store);
    ///     println!("Task with uuid: {}", task.flentry.get_header().get("todo.uuid"));
    /// }
    /// ```
    fn into_task(self, store : &'a Store) -> Result<Task<'a>>;

}

impl<'a> IntoTask<'a> for TTask {

    fn into_task(self, store : &'a Store) -> Result<Task<'a>> {
        let uuid     = self.uuid();
        let store_id = ModuleEntryPath::new(format!("taskwarrior/{}", uuid)).into_storeid();

        match store.retrieve(store_id) {
            Err(e) => return Err(TodoError::new(TodoErrorKind::StoreError, Some(Box::new(e)))),
            Ok(mut fle) => {
                {
                    let mut header = fle.get_header_mut();
                    match header.read("todo") {
                        Ok(None) => {
                            if let Err(e) = header.set("todo", Value::Table(BTreeMap::new())) {
                                return Err(TodoError::new(TodoErrorKind::StoreError, Some(Box::new(e))))
                            }
                        }
                        Ok(Some(_)) => { }
                        Err(e) => {
                            return Err(TodoError::new(TodoErrorKind::StoreError, Some(Box::new(e))))
                        }
                    }

                    if let Err(e) = header.set("todo.uuid", Value::String(format!("{}",uuid))) {
                        return Err(TodoError::new(TodoErrorKind::StoreError, Some(Box::new(e))))
                    }
                }

                // If none of the errors above have returned the function, everything is fine
                Ok(Task::new(fle))
            }
        }
    }

}

trait FromStoreId {
    fn from_storeid<'a>(&'a Store, StoreId) -> Result<Task<'a>>;
}

impl<'a> FromStoreId for Task<'a> {

    fn from_storeid<'b>(store: &'b Store, id: StoreId) -> Result<Task<'b>> {
        match store.retrieve(id) {
            Err(e) => Err(TodoError::new(TodoErrorKind::StoreError, Some(Box::new(e)))),
            Ok(c)  => Ok(Task::new( c )),
        }
    }
}

pub struct TaskIterator<'a> {
    store: &'a Store,
    iditer: StoreIdIterator,
}

impl<'a> TaskIterator<'a> {

    pub fn new(store: &'a Store, iditer: StoreIdIterator) -> TaskIterator<'a> {
        TaskIterator {
            store: store,
            iditer: iditer,
        }
    }

}

impl<'a> Iterator for TaskIterator<'a> {
    type Item = Result<Task<'a>>;

    fn next(&mut self) -> Option<Result<Task<'a>>> {
        self.iditer.next().map(|id| Task::from_storeid(self.store, id))
    }
}

<|endoftext|>


<commit_before><commit_msg>Suppress a warning when compiling the Rust code<commit_after><|endoftext|>


<commit_before>use scaly::containers::Ref;
use scaly::io::Stream;
use scaly::memory::Region;
use scaly::Equal;
use scaly::{Page, String, StringBuilder};

pub struct Lexer {
    pub token: Ref<Token>,
    character: char,
    stream: *mut Stream,
    is_at_end: bool,
    previous_line: usize,
    previous_column: usize,
    pub line: usize,
    pub column: usize,
}

impl Lexer {
    pub fn new(_pr: &Region, _rp: *mut Page, stream: *mut Stream) -> Ref<Lexer> {
        let _r = Region::create(_pr);
        let _token_page = unsafe { (*_rp).allocate_exclusive_page() };
        unsafe { (*_token_page).reset() };
        let mut lexer = Ref::new(
            _rp,
            Lexer {
                stream: stream,
                is_at_end: false,
                token: Ref::new(_token_page, Token::InvalidToken),
                character: 0 as char,
                previous_line: 1,
                previous_column: 0,
                line: 1,
                column: 0,
            },
        );
        lexer.read_character();
        lexer.advance(&_r);
        lexer
    }

    fn read_character(&mut self) {
        unsafe {
            let read_result: i32 = (*self.stream).read_byte();
            if read_result == -1 {
                self.is_at_end = true;
                self.character = 0 as char;
            } else {
                self.character = read_result as u8 as char;
            }
        }
    }

    pub fn advance(&mut self, _pr: &Region) {
        let _r = Region::create(_pr);
        self.skip_whitespace();
        self.previous_line = self.line;
        self.previous_column = self.previous_column;
        if self.is_at_end {
            return;
        }

        let c = self.character;

        if ((c >= 'a') && (c <= 'z')) || ((c >= 'A') && (c <= 'Z')) {
            {
                let _token_page = Page::own(&self.token);
                unsafe {
                    (*_token_page).reset();
                }
                self.token = self.scan_identifier(&_r, _token_page);
            }
            return;
        }

        if (c >= '0') && (c <= '9') {
            {
                let _token_page = Page::own(&self.token);
                unsafe {
                    (*_token_page).reset();
                }
                self.token = self.scan_numeric_literal(&_r, _token_page);
            }
            return;
        }

        match c {
            '+' | '-' | '*' | '/' | '=' | '%' | '&' | '|' | '^' | '~' | '<' | '>' => {
                let _token_page = Page::own(&self.token);
                unsafe {
                    (*_token_page).reset();
                }
                self.token = self.scan_operator(&_r, _token_page);
            }

            '\"' => {
                let _token_page = Page::own(&self.token);
                unsafe {
                    (*_token_page).reset();
                }
                self.token = self.scan_string_literal(&_r, _token_page);
            }

            '\'' => {
                let _token_page = Page::own(&self.token);
                unsafe {
                    (*_token_page).reset();
                }
                self.token = self.scan_character_literal(&_r, _token_page);
            }

            '{' | '}' | '(' | ')' | '[' | ']' | '.' | ',' | ':' | ';' | '?' | '!' | '@' | '#'
            | '$' | '_' | '`' => {
                {
                    let _token_page = Page::own(&self.token);
                    unsafe {
                        (*_token_page).reset();
                    }
                    self.token = Ref::new(
                        _token_page,
                        Token::Punctuation(String::from_character(Page::own(self), c)),
                    );
                }
                self.read_character();
                self.column = self.column + 1;
            }

            _ => {
                let _token_page = Page::own(&self.token);
                unsafe {
                    (*_token_page).reset();
                }
                self.token = Ref::new(_token_page, Token::InvalidToken);
            }
        }
    }

    fn scan_identifier(&mut self, _pr: &Region, _rp: *mut Page) -> Ref<Token> {
        let _r = Region::create(_pr);
        let mut name: Ref<StringBuilder> = StringBuilder::from_character(_r.page, self.character);

        loop {
            self.read_character();
            self.column = self.column + 1;

            if self.is_at_end() {
                return Ref::new(_rp, Token::Identifier(name.to_string(_rp)));
            }

            let c = self.character;
            if ((c >= 'a') && (c <= 'z'))
                || ((c >= 'A') && (c <= 'Z'))
                || ((c >= '0') && (c <= '9'))
                || (c == '_')
            {
                name.append_character(c);
            } else {
                return Ref::new(_rp, Token::Identifier(name.to_string(_rp)));
            }
        }
    }

    fn scan_operator(&mut self, _pr: &Region, _rp: *mut Page) -> Ref<Token> {
        let _r = Region::create(_pr);
        let mut operation: Ref<StringBuilder> =
            StringBuilder::from_character(_r.page, self.character);

        loop {
            self.read_character();
            self.column = self.column + 1;

            if self.is_at_end() {
                return Ref::new(_rp, Token::Identifier(operation.to_string(_rp)));
            }

            match self.character {
                '+' | '-' | '*' | '/' | '=' | '%' | '&' | '|' | '^' | '~' | '<' | '>' => {
                    operation.append_character(self.character)
                }

                _ => return Ref::new(_rp, Token::Identifier(operation.to_string(_rp))),
            }
        }
    }

    fn scan_string_literal(&mut self, _pr: &Region, _rp: *mut Page) -> Ref<Token> {
        let _r = Region::create(_pr);
        let mut value: Ref<StringBuilder> = StringBuilder::new(_r.page);

        loop {
            self.read_character();
            self.column = self.column + 1;

            if self.is_at_end() {
                return Ref::new(_rp, Token::InvalidToken);
            }

            match self.character {
                '\"' => {
                    self.read_character();
                    self.column = self.column + 1;
                    return Ref::new(_rp, Token::Literal(Literal::String(value.to_string(_rp))));
                }

                '\\' => {
                    self.read_character();
                    self.column = self.column + 1;
                    match self.character {
                        '\"' | '\\' | '\'' => {
                            value.append_character('\\');
                            value.append_character(self.character);
                        }
                        'n' => {
                            value.append_character('\\');
                            value.append_character('n');
                        }
                        'r' => {
                            value.append_character('\\');
                            value.append_character('r');
                        }
                        't' => {
                            value.append_character('\\');
                            value.append_character('t');
                        }
                        '0' => {
                            value.append_character('\\');
                            value.append_character('0');
                        }
                        _ => return Ref::new(_rp, Token::InvalidToken),
                    }
                }
                _ => value.append_character(self.character),
            }
        }
    }

    fn scan_character_literal(&mut self, _pr: &Region, _rp: *mut Page) -> Ref<Token> {
        let _r = Region::create(_pr);
        let mut value: Ref<StringBuilder> = StringBuilder::new(_r.page);

        loop {
            self.read_character();
            self.column = self.column + 1;

            if self.is_at_end() {
                return Ref::new(_rp, Token::InvalidToken);
            }

            match self.character {
                '\'' => {
                    self.read_character();
                    self.column = self.column + 1;
                    return Ref::new(
                        _rp,
                        Token::Literal(Literal::Character(value.to_string(_rp))),
                    );
                }

                '\\' => {
                    self.read_character();
                    self.column = self.column + 1;
                    match self.character {
                        '\"' | '\\' | '\'' => {
                            value.append_character('\\');
                            value.append_character(self.character);
                        }
                        'n' => {
                            value.append_character('\\');
                            value.append_character('n');
                        }
                        'r' => {
                            value.append_character('\\');
                            value.append_character('r');
                        }
                        't' => {
                            value.append_character('\\');
                            value.append_character('t');
                        }
                        '0' => {
                            value.append_character('\\');
                            value.append_character('0');
                        }
                        _ => return Ref::new(_rp, Token::InvalidToken),
                    }
                }
                _ => value.append_character(self.character),
            }
        }
    }

    fn scan_numeric_literal(&mut self, _pr: &Region, _rp: *mut Page) -> Ref<Token> {
        let _r = Region::create(_pr);
        let mut value: Ref<StringBuilder> = StringBuilder::from_character(_rp, self.character);

        self.read_character();
        self.column = self.column + 1;

        if self.is_at_end() {
            return Ref::new(_rp, Token::Literal(Literal::Numeric(value.to_string(_rp))));
        }
        if self.character == 'x' {
            return self.scan_hex_literal(&_r, _rp);
        } else {
            self.read_character();
            self.column = self.column + 1;
        }

        loop {
            self.read_character();
            self.column = self.column + 1;

            if self.is_at_end() {
                return Ref::new(_rp, Token::Literal(Literal::Numeric(value.to_string(_rp))));
            }

            let c = self.character;
            if (c >= '0') && (c <= '9') {
                value.append_character(self.character)
            } else {
                return Ref::new(_rp, Token::Literal(Literal::Numeric(value.to_string(_rp))));
            }
        }
    }

    fn scan_hex_literal(&mut self, _pr: &Region, _rp: *mut Page) -> Ref<Token> {
        let _r = Region::create(_pr);
        let mut value: Ref<StringBuilder> = StringBuilder::from_character(_rp, self.character);

        loop {
            self.read_character();
            self.column = self.column + 1;

            if self.is_at_end() {
                return Ref::new(_rp, Token::Literal(Literal::Hex(value.to_string(_rp))));
            }

            let c = self.character;
            if ((c >= '0') && (c <= '9'))
                || ((c >= 'a') && (c <= 'f'))
                || ((c >= 'A') && (c <= 'F'))
            {
                value.append_character(self.character)
            } else {
                return Ref::new(_rp, Token::Literal(Literal::Hex(value.to_string(_rp))));
            }
        }
    }

    fn skip_whitespace(&mut self) {
        loop {
            if self.is_at_end {
                return;
            }

            match self.character {
                ' ' => {
                    self.read_character();;
                    self.column = self.column + 1;
                    continue;
                }

                '\t' => {
                    self.read_character();
                    self.column = self.column + 4;
                    continue;
                }

                '\r' => {
                    self.read_character();
                    continue;
                }

                '\n' => {
                    self.read_character();
                    self.column = 1;
                    self.line = self.line + 1;
                    continue;
                }

                '/' => {
                    self.read_character();
                    self.column = self.column + 1;

                    if self.is_at_end {
                        return;
                    }

                    if self.character == '/' {
                        self.handle_single_line_comment();
                    } else {
                        if self.character == '*' {
                            self.handle_multi_line_comment();
                        } else {
                            return;
                        }
                    }
                }

                _ => return,
            }
        }
    }

    fn handle_single_line_comment(&mut self) {
        loop {
            if self.is_at_end() {
                return;
            }

            match self.character {
                '\t' => {
                    self.read_character();
                    self.column = self.column + 4;
                    continue;
                }

                '\r' => {
                    self.read_character();
                    continue;
                }

                '\n' => {
                    self.read_character();
                    self.column = 1;
                    self.line = self.line + 1;
                    return;
                }

                _ => {
                    self.read_character();
                    self.column = self.column + 1;
                    continue;
                }
            }
        }
    }

    fn handle_multi_line_comment(&mut self) {
        loop {
            if self.is_at_end() {
                return;
            }

            match self.character {
                '/' => {
                    self.read_character();
                    self.column = self.column + 1;

                    if self.is_at_end() {
                        return;
                    } else {
                        if self.character == '*' {
                            self.handle_multi_line_comment();
                        } else {
                            return;
                        }
                    }
                }

                '*' => {
                    self.read_character();
                    self.column = self.column + 1;

                    if self.is_at_end() {
                        return;
                    } else {
                        if self.character == '/' {
                            self.read_character();
                            self.column = self.column + 1;
                            return;
                        }
                    }
                }

                '\t' => {
                    self.read_character();
                    self.column = self.column + 4;
                    continue;
                }

                '\r' => {
                    self.read_character();
                    continue;
                }

                '\n' => {
                    self.read_character();
                    self.column = 1;
                    self.line = self.line + 1;
                    return;
                }

                _ => {
                    self.read_character();
                    self.column = self.column + 1;
                    continue;
                }
            }
        }
    }

    pub fn parse_keyword(&self, fixed_string: String) -> bool {
        match *self.token {
            Token::Identifier(name) => return name.equals(&fixed_string),
            _ => return false,
        }
    }

    pub fn parse_identifier(&self, _rp: *mut Page) -> Option<String> {
        match *self.token {
            Token::Identifier(name) => return Some(String::copy(_rp, name)),
            _ => return None,
        }
    }

    pub fn parse_punctuation(&self, fixed_string: String) -> bool {
        match *self.token {
            Token::Punctuation(name) => return name.equals(&fixed_string),
            _ => return false,
        }
    }

    pub fn parse_literal(&self, _rp: *mut Page) -> Option<Literal> {
        match *self.token {
            Token::Literal(Literal::String(name)) => Some(Literal::String(String::copy(_rp, name))),
            Token::Literal(Literal::Character(name)) => {
                Some(Literal::Character(String::copy(_rp, name)))
            }
            Token::Literal(Literal::Numeric(name)) => {
                Some(Literal::Numeric(String::copy(_rp, name)))
            }
            Token::Literal(Literal::Hex(name)) => Some(Literal::Hex(String::copy(_rp, name))),
            _ => None,
        }
    }

    pub fn is_at_end(&self) -> bool {
        self.is_at_end
    }

    pub fn get_position(&self) -> Position {
        Position {
            line: self.line,
            column: self.column,
        }
    }

    pub fn get_previous_position(&self) -> Position {
        Position {
            line: self.previous_line,
            column: self.previous_column,
        }
    }
}

#[derive(Copy, Clone)]
pub struct Position {
    pub line: usize,
    pub column: usize,
}

#[derive(Copy, Clone)]
pub enum Token {
    InvalidToken,
    Identifier(String),
    Literal(Literal),
    Punctuation(String),
}

#[derive(Copy, Clone)]
pub enum Literal {
    String(String),
    Character(String),
    Numeric(String),
    Hex(String),
}
<commit_msg>small lexer fixes<commit_after>use scaly::containers::Ref;
use scaly::io::Stream;
use scaly::memory::Region;
use scaly::Equal;
use scaly::{Page, String, StringBuilder};

pub struct Lexer {
    pub token: Ref<Token>,
    character: char,
    stream: *mut Stream,
    is_at_end: bool,
    previous_line: usize,
    previous_column: usize,
    pub line: usize,
    pub column: usize,
}

impl Lexer {
    pub fn new(_pr: &Region, _rp: *mut Page, stream: *mut Stream) -> Ref<Lexer> {
        let _r = Region::create(_pr);
        let _token_page = unsafe { (*_rp).allocate_exclusive_page() };
        unsafe { (*_token_page).reset() };
        let mut lexer = Ref::new(
            _rp,
            Lexer {
                stream: stream,
                is_at_end: false,
                token: Ref::new(_token_page, Token::InvalidToken),
                character: 0 as char,
                previous_line: 1,
                previous_column: 0,
                line: 1,
                column: 0,
            },
        );
        lexer.read_character();
        lexer.advance(&_r);
        lexer
    }

    fn read_character(&mut self) {
        unsafe {
            let read_result: i32 = (*self.stream).read_byte();
            if read_result == -1 {
                self.is_at_end = true;
                self.character = 0 as char;
            } else {
                self.character = read_result as u8 as char;
            }
        }
    }

    pub fn advance(&mut self, _pr: &Region) {
        let _r = Region::create(_pr);
        self.skip_whitespace();
        self.previous_line = self.line;
        self.previous_column = self.column;
        if self.is_at_end {
            return;
        }

        let c = self.character;

        if ((c >= 'a') && (c <= 'z')) || ((c >= 'A') && (c <= 'Z')) {
            {
                let _token_page = Page::own(&self.token);
                unsafe {
                    (*_token_page).reset();
                }
                self.token = self.scan_identifier(&_r, _token_page);
            }
            return;
        }

        if (c >= '0') && (c <= '9') {
            {
                let _token_page = Page::own(&self.token);
                unsafe {
                    (*_token_page).reset();
                }
                self.token = self.scan_numeric_literal(&_r, _token_page);
            }
            return;
        }

        match c {
            '+' | '-' | '*' | '/' | '=' | '%' | '&' | '|' | '^' | '~' | '<' | '>' => {
                let _token_page = Page::own(&self.token);
                unsafe {
                    (*_token_page).reset();
                }
                self.token = self.scan_operator(&_r, _token_page);
            }

            '\"' => {
                let _token_page = Page::own(&self.token);
                unsafe {
                    (*_token_page).reset();
                }
                self.token = self.scan_string_literal(&_r, _token_page);
            }

            '\'' => {
                let _token_page = Page::own(&self.token);
                unsafe {
                    (*_token_page).reset();
                }
                self.token = self.scan_character_literal(&_r, _token_page);
            }

            '{' | '}' | '(' | ')' | '[' | ']' | '.' | ',' | ':' | ';' | '?' | '!' | '@' | '#'
            | '$' | '_' | '`' => {
                {
                    let _token_page = Page::own(&self.token);
                    unsafe {
                        (*_token_page).reset();
                    }
                    self.token = Ref::new(
                        _token_page,
                        Token::Punctuation(String::from_character(Page::own(self), c)),
                    );
                }
                self.read_character();
                self.column = self.column + 1;
            }

            _ => {
                let _token_page = Page::own(&self.token);
                unsafe {
                    (*_token_page).reset();
                }
                self.token = Ref::new(_token_page, Token::InvalidToken);
            }
        }
    }

    fn scan_identifier(&mut self, _pr: &Region, _rp: *mut Page) -> Ref<Token> {
        let _r = Region::create(_pr);
        let mut name: Ref<StringBuilder> = StringBuilder::from_character(_r.page, self.character);

        loop {
            self.read_character();
            self.column = self.column + 1;

            if self.is_at_end() {
                return Ref::new(_rp, Token::Identifier(name.to_string(_rp)));
            }

            let c = self.character;
            if ((c >= 'a') && (c <= 'z'))
                || ((c >= 'A') && (c <= 'Z'))
                || ((c >= '0') && (c <= '9'))
                || (c == '_')
            {
                name.append_character(c);
            } else {
                return Ref::new(_rp, Token::Identifier(name.to_string(_rp)));
            }
        }
    }

    fn scan_operator(&mut self, _pr: &Region, _rp: *mut Page) -> Ref<Token> {
        let _r = Region::create(_pr);
        let mut operation: Ref<StringBuilder> =
            StringBuilder::from_character(_r.page, self.character);

        loop {
            self.read_character();
            self.column = self.column + 1;

            if self.is_at_end() {
                return Ref::new(_rp, Token::Identifier(operation.to_string(_rp)));
            }

            match self.character {
                '+' | '-' | '*' | '/' | '=' | '%' | '&' | '|' | '^' | '~' | '<' | '>' => {
                    operation.append_character(self.character)
                }

                _ => return Ref::new(_rp, Token::Identifier(operation.to_string(_rp))),
            }
        }
    }

    fn scan_string_literal(&mut self, _pr: &Region, _rp: *mut Page) -> Ref<Token> {
        let _r = Region::create(_pr);
        let mut value: Ref<StringBuilder> = StringBuilder::new(_r.page);

        loop {
            self.read_character();
            self.column = self.column + 1;

            if self.is_at_end() {
                return Ref::new(_rp, Token::InvalidToken);
            }

            match self.character {
                '\"' => {
                    self.read_character();
                    self.column = self.column + 1;
                    return Ref::new(_rp, Token::Literal(Literal::String(value.to_string(_rp))));
                }

                '\\' => {
                    self.read_character();
                    self.column = self.column + 1;
                    match self.character {
                        '\"' | '\\' | '\'' => {
                            value.append_character('\\');
                            value.append_character(self.character);
                        }
                        'n' => {
                            value.append_character('\\');
                            value.append_character('n');
                        }
                        'r' => {
                            value.append_character('\\');
                            value.append_character('r');
                        }
                        't' => {
                            value.append_character('\\');
                            value.append_character('t');
                        }
                        '0' => {
                            value.append_character('\\');
                            value.append_character('0');
                        }
                        _ => return Ref::new(_rp, Token::InvalidToken),
                    }
                }
                _ => value.append_character(self.character),
            }
        }
    }

    fn scan_character_literal(&mut self, _pr: &Region, _rp: *mut Page) -> Ref<Token> {
        let _r = Region::create(_pr);
        let mut value: Ref<StringBuilder> = StringBuilder::new(_r.page);

        loop {
            self.read_character();
            self.column = self.column + 1;

            if self.is_at_end() {
                return Ref::new(_rp, Token::InvalidToken);
            }

            match self.character {
                '\'' => {
                    self.read_character();
                    self.column = self.column + 1;
                    return Ref::new(
                        _rp,
                        Token::Literal(Literal::Character(value.to_string(_rp))),
                    );
                }

                '\\' => {
                    self.read_character();
                    self.column = self.column + 1;
                    match self.character {
                        '\"' | '\\' | '\'' => {
                            value.append_character('\\');
                            value.append_character(self.character);
                        }
                        'n' => {
                            value.append_character('\\');
                            value.append_character('n');
                        }
                        'r' => {
                            value.append_character('\\');
                            value.append_character('r');
                        }
                        't' => {
                            value.append_character('\\');
                            value.append_character('t');
                        }
                        '0' => {
                            value.append_character('\\');
                            value.append_character('0');
                        }
                        _ => return Ref::new(_rp, Token::InvalidToken),
                    }
                }
                _ => value.append_character(self.character),
            }
        }
    }

    fn scan_numeric_literal(&mut self, _pr: &Region, _rp: *mut Page) -> Ref<Token> {
        let _r = Region::create(_pr);
        let mut value: Ref<StringBuilder> = StringBuilder::from_character(_rp, self.character);

        self.read_character();
        self.column = self.column + 1;

        if self.is_at_end() {
            return Ref::new(_rp, Token::Literal(Literal::Numeric(value.to_string(_rp))));
        }
        if self.character == 'x' {
            return self.scan_hex_literal(&_r, _rp);
        }

        loop {
            let c = self.character;
            if (c >= '0') && (c <= '9') {
                value.append_character(self.character)
            } else {
                return Ref::new(_rp, Token::Literal(Literal::Numeric(value.to_string(_rp))));
            }
            self.read_character();
            self.column = self.column + 1;

            if self.is_at_end() {
                return Ref::new(_rp, Token::Literal(Literal::Numeric(value.to_string(_rp))));
            }
        }
    }

    fn scan_hex_literal(&mut self, _pr: &Region, _rp: *mut Page) -> Ref<Token> {
        let _r = Region::create(_pr);
        let mut value: Ref<StringBuilder> = StringBuilder::from_character(_rp, self.character);

        loop {
            self.read_character();
            self.column = self.column + 1;

            if self.is_at_end() {
                return Ref::new(_rp, Token::Literal(Literal::Hex(value.to_string(_rp))));
            }

            let c = self.character;
            if ((c >= '0') && (c <= '9'))
                || ((c >= 'a') && (c <= 'f'))
                || ((c >= 'A') && (c <= 'F'))
            {
                value.append_character(self.character)
            } else {
                return Ref::new(_rp, Token::Literal(Literal::Hex(value.to_string(_rp))));
            }
        }
    }

    fn skip_whitespace(&mut self) {
        loop {
            if self.is_at_end {
                return;
            }

            match self.character {
                ' ' => {
                    self.read_character();;
                    self.column = self.column + 1;
                    continue;
                }

                '\t' => {
                    self.read_character();
                    self.column = self.column + 4;
                    continue;
                }

                '\r' => {
                    self.read_character();
                    continue;
                }

                '\n' => {
                    self.read_character();
                    self.column = 1;
                    self.line = self.line + 1;
                    continue;
                }

                '/' => {
                    self.read_character();
                    self.column = self.column + 1;

                    if self.is_at_end {
                        return;
                    }

                    if self.character == '/' {
                        self.handle_single_line_comment();
                    } else {
                        if self.character == '*' {
                            self.handle_multi_line_comment();
                        } else {
                            return;
                        }
                    }
                }

                _ => return,
            }
        }
    }

    fn handle_single_line_comment(&mut self) {
        loop {
            if self.is_at_end() {
                return;
            }

            match self.character {
                '\t' => {
                    self.read_character();
                    self.column = self.column + 4;
                    continue;
                }

                '\r' => {
                    self.read_character();
                    continue;
                }

                '\n' => {
                    self.read_character();
                    self.column = 1;
                    self.line = self.line + 1;
                    return;
                }

                _ => {
                    self.read_character();
                    self.column = self.column + 1;
                    continue;
                }
            }
        }
    }

    fn handle_multi_line_comment(&mut self) {
        loop {
            if self.is_at_end() {
                return;
            }

            match self.character {
                '/' => {
                    self.read_character();
                    self.column = self.column + 1;

                    if self.is_at_end() {
                        return;
                    } else {
                        if self.character == '*' {
                            self.handle_multi_line_comment();
                        } else {
                            return;
                        }
                    }
                }

                '*' => {
                    self.read_character();
                    self.column = self.column + 1;

                    if self.is_at_end() {
                        return;
                    } else {
                        if self.character == '/' {
                            self.read_character();
                            self.column = self.column + 1;
                            return;
                        }
                    }
                }

                '\t' => {
                    self.read_character();
                    self.column = self.column + 4;
                    continue;
                }

                '\r' => {
                    self.read_character();
                    continue;
                }

                '\n' => {
                    self.read_character();
                    self.column = 1;
                    self.line = self.line + 1;
                    return;
                }

                _ => {
                    self.read_character();
                    self.column = self.column + 1;
                    continue;
                }
            }
        }
    }

    pub fn parse_keyword(&self, fixed_string: String) -> bool {
        match *self.token {
            Token::Identifier(name) => return name.equals(&fixed_string),
            _ => return false,
        }
    }

    pub fn parse_identifier(&self, _rp: *mut Page) -> Option<String> {
        match *self.token {
            Token::Identifier(name) => return Some(String::copy(_rp, name)),
            _ => return None,
        }
    }

    pub fn parse_punctuation(&self, fixed_string: String) -> bool {
        match *self.token {
            Token::Punctuation(name) => return name.equals(&fixed_string),
            _ => return false,
        }
    }

    pub fn parse_literal(&self, _rp: *mut Page) -> Option<Literal> {
        match *self.token {
            Token::Literal(Literal::String(name)) => Some(Literal::String(String::copy(_rp, name))),
            Token::Literal(Literal::Character(name)) => {
                Some(Literal::Character(String::copy(_rp, name)))
            }
            Token::Literal(Literal::Numeric(name)) => {
                Some(Literal::Numeric(String::copy(_rp, name)))
            }
            Token::Literal(Literal::Hex(name)) => Some(Literal::Hex(String::copy(_rp, name))),
            _ => None,
        }
    }

    pub fn is_at_end(&self) -> bool {
        self.is_at_end
    }

    pub fn get_position(&self) -> Position {
        Position {
            line: self.line,
            column: self.column,
        }
    }

    pub fn get_previous_position(&self) -> Position {
        Position {
            line: self.previous_line,
            column: self.previous_column,
        }
    }
}

#[derive(Copy, Clone)]
pub struct Position {
    pub line: usize,
    pub column: usize,
}

#[derive(Copy, Clone)]
pub enum Token {
    InvalidToken,
    Identifier(String),
    Literal(Literal),
    Punctuation(String),
}

#[derive(Copy, Clone)]
pub enum Literal {
    String(String),
    Character(String),
    Numeric(String),
    Hex(String),
}
<|endoftext|>