<commit_before>#![feature(box_patterns)]
#[cfg(feature = "trace_log")]
extern crate env_logger;

extern crate radeco_lib;
extern crate r2pipe;
extern crate r2api;
extern crate base64;
extern crate rustyline;

mod cli;
mod core;

use rustyline::{Helper, CompletionType, Config, EditMode, Editor};
use rustyline::hint::Hinter;
use rustyline::highlight::Highlighter;
use rustyline::completion::{Completer, FilenameCompleter};
use rustyline::error::ReadlineError;
use std::fs;

mod scheme {
    pub const HTTP: &'static str = "http://";
    pub const TCP: &'static str = "tcp://";

    pub fn is_http(url: &str) -> bool {
        url.starts_with(HTTP)
    }

    pub fn is_tcp(url: &str) -> bool {
        url.starts_with(TCP)
    }
}

// On unix platforms you can use ANSI escape sequences
#[cfg(unix)]
const PROMPT: &'static str = "\x1b[1;32m>>\x1b[0m ";
// File seperator for *nix based platforms
#[cfg(unix)]
const FILE_SP: char = '/';

// Windows consoles typically don't support ANSI escape sequences out
// of the box
#[cfg(windows)]
const PROMPT: &'static str = ">> ";
#[cfg(windows)]
// File seperator for Windows
const FILE_SP: char = '\\';

#[derive(Default)]
struct Completes {
    file_completer: FilenameCompleter,
}

impl Helper for Completes {}

impl Hinter for Completes {
    fn hint(&self, _line: &str, _pos: usize) -> Option<String> {
        None
    }
}

impl Highlighter for Completes {}

impl Completer for Completes {
    type Candidate = String;
    fn complete(&self, line: &str, _pos: usize) -> rustyline::Result<(usize, Vec<String>)> {
        // TODO Completion for function names
        let cmds = vec![
            command::HELP,
            command::LOAD,
            command::CONNECT,
            command::FNLIST,
            command::ANALYZE,
            command::DOT,
            command::IR,
            command::DECOMPILE,
        ];
        let mut ret: Vec<String> = cmds.into_iter()
            .filter(|s| s.starts_with(line))
            .map(|s| s.to_string())
            .collect();
        match self.file_completer.complete(line, _pos) {
            Ok((n, ss)) => {
                let mut completed_lines = ss.into_iter()
                    .map(|s| {
                        if let Some (sep_loc) = line.rfind (FILE_SP) {
                            format! ("{}{}", &line[..sep_loc + 1], s.display)
                        } else {
                            format! ("{}{}", &line[..n], s.display)
                        }
                    })
                    .collect();
                ret.append(&mut completed_lines);
            }
            Err(_) => {}
        }

        Ok((0, ret))
    }
}

const SEP: &'static str = "END";
const USAGE: &'static str = "
Usage:
  radeco <bin>
  radeco [--append]
  radeco (--help | --version)

  Options:
  -h, --help        Show this screen.
  -v, --version     Show current version.
  --bin             Load a program.
  --append          Append separator to the end of every output.
";

fn main() {
    let (arg, is_append_mode) = cli::parse_args(USAGE);
    let config = Config::builder()
        .auto_add_history(true)
        .history_ignore_space(true)
        .completion_type(CompletionType::List)
        .edit_mode(EditMode::Emacs)
        .build();
    let mut rl = Editor::with_config(config);
    rl.set_helper(Some(Completes::default()));
    core::PROJ.with(move |proj| {
        *proj.borrow_mut() = arg.and_then(|ref s| {
            if scheme::is_http(s) {
                core::load_proj_http(&s[scheme::HTTP.len()..])
            } else if scheme::is_tcp(s) {
                core::load_proj_tcp(&s[scheme::TCP.len()..])
            } else if is_file(s) {
                Ok(core::load_proj_by_path(s))
            } else {
                Err("Invalid argument")
            }.ok()
        });
    });

    loop {
        let readline = rl.readline(PROMPT);
        match readline {
            Ok(line) => {
                if !line.is_empty () {
                    let mut terms = line.split_whitespace();
                    let o1 = terms.next();
                    let o2 = terms.next();
                    cmd(o1, o2);
                    if is_append_mode {
                        println!("{}", SEP);
                    }
                }
            }
            Err(ReadlineError::Interrupted) => {},
            Err(ReadlineError::Eof) => break,
            Err(err) => {
                println!("Error: {:?}", err);
                break;
            }
        }
    }
}

mod command {
    pub const HELP: &'static str = "help";
    pub const LOAD: &'static str = "load";
    pub const CONNECT: &'static str = "connect";
    pub const FNLIST: &'static str = "fn_list";
    pub const ANALYZE: &'static str = "analyze";
    pub const DOT: &'static str = "dot";
    pub const IR: &'static str = "ir";
    pub const DECOMPILE: &'static str = "decompile";

    pub fn help() {
        let width = 30;
        println!("{:width$}    Show this help", HELP, width = width);
        println!(
            "{:width$}    Load binary",
            format!("{} path", LOAD),
            width = width
        );
        println!(
            "{:width$}    Connect to radare2 server",
            format!("{} (http|tcp)://<url>", CONNECT),
            width = width
        );
        println!(
            "{:width$}    Show function list",
            FNLIST,
            width = width
        );
        println!(
            "{:width$}    Analyze <func>",
            format!("{} <func>", ANALYZE),
            width = width
        );
        println!(
            "{:width$}    Emit IR of <func>",
            format!("{} <func>", IR),
            width = width
        );
        println!(
            "{:width$}    Emit graph of the IR in Graphviz dot",
            format!("{} <func>", DOT),
            width = width
        );
        println!(
            "{:width$}    Decompile <func>",
            format!("{} <func>", DECOMPILE),
            width = width
        );
    }
}

fn cmd(op1: Option<&str>, op2: Option<&str>) {
    core::PROJ.with(|proj_opt| {
        match (op1, op2) {
            (Some(command::HELP), _) => {
                command::help();
                return;
            }
            (Some(command::LOAD), Some(path)) => {
                if is_file(path) {
                    *proj_opt.borrow_mut() = Some(core::load_proj_by_path(path));
                    return;
                } else {
                    println!("{} is not found.", path);
                    return;
                }
            }
            (Some(command::CONNECT), Some(url)) => {
                let p_opt = if scheme::is_http(&url) {
                    core::load_proj_http(&url[scheme::HTTP.len()..])
                } else if scheme::is_tcp(&url) {
                    core::load_proj_tcp(&url[scheme::TCP.len()..])
                } else {
                    Err("Invalid url")
                };
                match p_opt {
                    Ok(p) => *proj_opt.borrow_mut() = Some(p),
                    Err(msg) => println!("{}", msg),
                }
                return;
            }
            _ => {}
        };
        if proj_opt.borrow().is_none() {
            println!("Load a project first");
            return;
        }
        let mut proj_ = proj_opt.borrow_mut();
        let proj = proj_.as_mut().unwrap();
        match (op1, op2) {
            (Some(command::ANALYZE), Some("*")) => {
                let rfns = proj.iter_mut().map(|i| i.module).flat_map(|rmod| {
                    rmod.functions.values_mut()
                });
                for rfn in rfns {
                    core::analyze(rfn);
                }
            }
            (Some(command::FNLIST), _) => {
                let funcs = core::fn_list(&proj);
                println!("{}", funcs.join("\n"));
            }
            // TODO Show list of dependency information of analyses
            // TODO Add command for individual analyses
            (Some(command::ANALYZE), Some(f)) => {
                if let Some(rfn) = core::get_function_mut(f, proj) {
                    core::analyze(rfn);
                } else {
                    println!("{} is not found", f);
                }
            }
            (Some(command::DOT), Some(f)) => {
                if let Some(rfn) = core::get_function(f, &proj) {
                    println!("{}", core::emit_dot(rfn.ssa()));
                } else {
                    println!("{} is not found", f);
                }
            }
            (Some(command::IR), Some(f)) => {
                if let Some(rfn) = core::get_function(f, &proj) {
                    println!("{}", core::emit_ir(rfn));
                } else {
                    println!("{} is not found", f);
                }
            }
            (Some(command::DECOMPILE), Some(f)) => {
                if let Some(rfn) = core::get_function(f, &proj) {
                    let rmod = proj.iter().map(|i| i.module).next().unwrap();
                    let func_name_map = core::func_names(&rmod);
                    let strings = core::strings(&rmod);
                    match core::decompile(rfn, &func_name_map, &strings) {
                        Ok(res) => println!("{}", res),
                        Err(err) => println!("{}", err),
                    }
                } else {
                    println!("{} is not found", f);
                }
            }
            _ => {
                println!(
                    "Invalid command {} {}",
                    op1.unwrap_or(""),
                    op2.unwrap_or("")
                );
            }
        }
    });
}

fn is_file(path: &str) -> bool {
    fs::metadata(path).map(|f| f.is_file()).unwrap_or(false)
}
<commit_msg>added quit command to the interactive prompt, more intuitive to exit since I found myself typing q several times<commit_after>#![feature(box_patterns)]
#[cfg(feature = "trace_log")]
extern crate env_logger;

extern crate radeco_lib;
extern crate r2pipe;
extern crate r2api;
extern crate base64;
extern crate rustyline;

mod cli;
mod core;

use rustyline::{Helper, CompletionType, Config, EditMode, Editor};
use rustyline::hint::Hinter;
use rustyline::highlight::Highlighter;
use rustyline::completion::{Completer, FilenameCompleter};
use rustyline::error::ReadlineError;
use std::fs;
use std::process;

mod scheme {
    pub const HTTP: &'static str = "http://";
    pub const TCP: &'static str = "tcp://";

    pub fn is_http(url: &str) -> bool {
        url.starts_with(HTTP)
    }

    pub fn is_tcp(url: &str) -> bool {
        url.starts_with(TCP)
    }
}

// On unix platforms you can use ANSI escape sequences
#[cfg(unix)]
const PROMPT: &'static str = "\x1b[1;32m>>\x1b[0m ";
// File seperator for *nix based platforms
#[cfg(unix)]
const FILE_SP: char = '/';

// Windows consoles typically don't support ANSI escape sequences out
// of the box
#[cfg(windows)]
const PROMPT: &'static str = ">> ";
#[cfg(windows)]
// File seperator for Windows
const FILE_SP: char = '\\';

#[derive(Default)]
struct Completes {
    file_completer: FilenameCompleter,
}

impl Helper for Completes {}

impl Hinter for Completes {
    fn hint(&self, _line: &str, _pos: usize) -> Option<String> {
        None
    }
}

impl Highlighter for Completes {}

impl Completer for Completes {
    type Candidate = String;
    fn complete(&self, line: &str, _pos: usize) -> rustyline::Result<(usize, Vec<String>)> {
        // TODO Completion for function names
        let cmds = vec![
            command::HELP,
            command::LOAD,
            command::CONNECT,
            command::FNLIST,
            command::ANALYZE,
            command::DOT,
            command::IR,
            command::DECOMPILE,
            command::QUIT,
        ];
        let mut ret: Vec<String> = cmds.into_iter()
            .filter(|s| s.starts_with(line))
            .map(|s| s.to_string())
            .collect();
        match self.file_completer.complete(line, _pos) {
            Ok((n, ss)) => {
                let mut completed_lines = ss.into_iter()
                    .map(|s| {
                        if let Some (sep_loc) = line.rfind (FILE_SP) {
                            format! ("{}{}", &line[..sep_loc + 1], s.display)
                        } else {
                            format! ("{}{}", &line[..n], s.display)
                        }
                    })
                    .collect();
                ret.append(&mut completed_lines);
            }
            Err(_) => {}
        }

        Ok((0, ret))
    }
}

const SEP: &'static str = "END";
const USAGE: &'static str = "
Usage:
  radeco <bin>
  radeco [--append]
  radeco (--help | --version)

  Options:
  -h, --help        Show this screen.
  -v, --version     Show current version.
  --bin             Load a program.
  --append          Append separator to the end of every output.
";

fn main() {
    let (arg, is_append_mode) = cli::parse_args(USAGE);
    let config = Config::builder()
        .auto_add_history(true)
        .history_ignore_space(true)
        .completion_type(CompletionType::List)
        .edit_mode(EditMode::Emacs)
        .build();
    let mut rl = Editor::with_config(config);
    rl.set_helper(Some(Completes::default()));
    core::PROJ.with(move |proj| {
        *proj.borrow_mut() = arg.and_then(|ref s| {
            if scheme::is_http(s) {
                core::load_proj_http(&s[scheme::HTTP.len()..])
            } else if scheme::is_tcp(s) {
                core::load_proj_tcp(&s[scheme::TCP.len()..])
            } else if is_file(s) {
                Ok(core::load_proj_by_path(s))
            } else {
                Err("Invalid argument")
            }.ok()
        });
    });

    loop {
        let readline = rl.readline(PROMPT);
        match readline {
            Ok(line) => {
                if !line.is_empty () {
                    let mut terms = line.split_whitespace();
                    let o1 = terms.next();
                    let o2 = terms.next();
                    cmd(o1, o2);
                    if is_append_mode {
                        println!("{}", SEP);
                    }
                }
            }
            Err(ReadlineError::Interrupted) => {},
            Err(ReadlineError::Eof) => break,
            Err(err) => {
                println!("Error: {:?}", err);
                break;
            }
        }
    }
}

mod command {
    pub const HELP: &'static str = "help";
    pub const LOAD: &'static str = "load";
    pub const CONNECT: &'static str = "connect";
    pub const FNLIST: &'static str = "fn_list";
    pub const ANALYZE: &'static str = "analyze";
    pub const DOT: &'static str = "dot";
    pub const IR: &'static str = "ir";
    pub const DECOMPILE: &'static str = "decompile";
    pub const QUIT: &'static str = "quit";

    pub fn help() {
        let width = 30;
        println!("{:width$}    Show this help", HELP, width = width);
        println!(
            "{:width$}    Load binary",
            format!("{} path", LOAD),
            width = width
        );
        println!(
            "{:width$}    Connect to radare2 server",
            format!("{} (http|tcp)://<url>", CONNECT),
            width = width
        );
        println!(
            "{:width$}    Show function list",
            FNLIST,
            width = width
        );
        println!(
            "{:width$}    Analyze <func>",
            format!("{} <func>", ANALYZE),
            width = width
        );
        println!(
            "{:width$}    Emit IR of <func>",
            format!("{} <func>", IR),
            width = width
        );
        println!(
            "{:width$}    Emit graph of the IR in Graphviz dot",
            format!("{} <func>", DOT),
            width = width
        );
        println!(
            "{:width$}    Decompile <func>",
            format!("{} <func>", DECOMPILE),
            width = width
        );
        println!(
            "{:width$}    Quit interactive prompt",
            QUIT,
            width = width
        );
    }
}

fn cmd(op1: Option<&str>, op2: Option<&str>) {
    core::PROJ.with(|proj_opt| {
        match (op1, op2) {
            (Some(command::HELP), _) => {
                command::help();
                return;
            }
            (Some(command::LOAD), Some(path)) => {
                if is_file(path) {
                    *proj_opt.borrow_mut() = Some(core::load_proj_by_path(path));
                    return;
                } else {
                    println!("{} is not found.", path);
                    return;
                }
            }
            (Some(command::CONNECT), Some(url)) => {
                let p_opt = if scheme::is_http(&url) {
                    core::load_proj_http(&url[scheme::HTTP.len()..])
                } else if scheme::is_tcp(&url) {
                    core::load_proj_tcp(&url[scheme::TCP.len()..])
                } else {
                    Err("Invalid url")
                };
                match p_opt {
                    Ok(p) => *proj_opt.borrow_mut() = Some(p),
                    Err(msg) => println!("{}", msg),
                }
                return;
            }
            _ => {}
        };
        if proj_opt.borrow().is_none() {
            println!("Load a project first");
            return;
        }
        let mut proj_ = proj_opt.borrow_mut();
        let proj = proj_.as_mut().unwrap();
        match (op1, op2) {
            (Some(command::ANALYZE), Some("*")) => {
                let rfns = proj.iter_mut().map(|i| i.module).flat_map(|rmod| {
                    rmod.functions.values_mut()
                });
                for rfn in rfns {
                    core::analyze(rfn);
                }
            }
            (Some(command::FNLIST), _) => {
                let funcs = core::fn_list(&proj);
                println!("{}", funcs.join("\n"));
            }
            // TODO Show list of dependency information of analyses
            // TODO Add command for individual analyses
            (Some(command::ANALYZE), Some(f)) => {
                if let Some(rfn) = core::get_function_mut(f, proj) {
                    core::analyze(rfn);
                } else {
                    println!("{} is not found", f);
                }
            }
            (Some(command::DOT), Some(f)) => {
                if let Some(rfn) = core::get_function(f, &proj) {
                    println!("{}", core::emit_dot(rfn.ssa()));
                } else {
                    println!("{} is not found", f);
                }
            }
            (Some(command::IR), Some(f)) => {
                if let Some(rfn) = core::get_function(f, &proj) {
                    println!("{}", core::emit_ir(rfn));
                } else {
                    println!("{} is not found", f);
                }
            }
            (Some(command::DECOMPILE), Some(f)) => {
                if let Some(rfn) = core::get_function(f, &proj) {
                    let rmod = proj.iter().map(|i| i.module).next().unwrap();
                    let func_name_map = core::func_names(&rmod);
                    let strings = core::strings(&rmod);
                    match core::decompile(rfn, &func_name_map, &strings) {
                        Ok(res) => println!("{}", res),
                        Err(err) => println!("{}", err),
                    }
                } else {
                    println!("{} is not found", f);
                }
            }
            (Some(command::QUIT), _) => {
                process::exit(0);
            }
            _ => {
                println!(
                    "Invalid command {} {}",
                    op1.unwrap_or(""),
                    op2.unwrap_or("")
                );
            }
        }
    });
}

fn is_file(path: &str) -> bool {
    fs::metadata(path).map(|f| f.is_file()).unwrap_or(false)
}
<|endoftext|>


<commit_before>use toml:: { Parser, Decoder, Value };
use rustc_serialize:: { Decodable };
use std::default:: { Default };
use std::path:: { Path };
use std::fs::File;
use std::io:: { Read, Result };
use std::borrow:: { Borrow };

#[derive(RustcDecodable)]
pub struct Configuration {
    server: Server
}

#[derive(RustcDecodable)]
pub struct Server {
    host: String,
    port: i64
}

impl Configuration {
    pub fn fromFile(path: &Path) -> Self {
        from_toml_file(path).unwrap()
    }
}

impl Default for Server {
    fn default() -> Self {
        Server {
            host: "127.0.0.1".to_string(),
            port: 6767
        }
    }
}

impl Default for Configuration {
    fn default() -> Self {
        Configuration {
            server: Server::default()
        }
    }
}

pub fn from_toml_file(path: &Path) -> Result<Configuration> {
    let content = read_file(path).unwrap();
    let toml = &content[..];
    let value = Parser::new(toml).parse().unwrap();
    let mut decoder = Decoder::new(Value::Table(value));
    let configuration = Configuration::decode(&mut decoder).unwrap();
    Ok(configuration)
}

pub fn read_file(path: &Path) -> Result<String> {
    let mut file = try!(File::open(path));
    let mut buffer = String::new();
    let _ = try!(file.read_to_string(&mut buffer));
    Ok(buffer.clone())
}
<commit_msg>use From trait<commit_after>use toml:: { Parser, Decoder, Value };
use rustc_serialize:: { Decodable };
use std::default:: { Default };
use std::path:: { Path };
use std::fs::File;
use std::io:: { Read, Result };
use std::borrow:: { Borrow };
use std::convert:: { From };

#[derive(RustcDecodable)]
pub struct Configuration {
    server: Server
}

#[derive(RustcDecodable)]
pub struct Server {
    host: String,
    port: i64
}

impl<'a> From<&'a Path> for Configuration {
    fn from(path: &'a Path) -> Self {
        from_toml_file(path).unwrap()
    }
}

impl Default for Server {
    fn default() -> Self {
        Server {
            host: "127.0.0.1".to_string(),
            port: 6767
        }
    }
}

impl Default for Configuration {
    fn default() -> Self {
        Configuration {
            server: Server::default()
        }
    }
}

pub fn from_toml_file(path: &Path) -> Result<Configuration> {
    let content = read_file(path).unwrap();
    let toml = &content[..];
    let value = Parser::new(toml).parse().unwrap();
    let mut decoder = Decoder::new(Value::Table(value));
    let configuration = Configuration::decode(&mut decoder).unwrap();
    Ok(configuration)
}

pub fn read_file(path: &Path) -> Result<String> {
    let mut file = try!(File::open(path));
    let mut buffer = String::new();
    let _ = try!(file.read_to_string(&mut buffer));
    Ok(buffer.clone())
}
<|endoftext|>


<commit_before>extern crate cc;

use std::path::PathBuf;

fn build(dir: &str, files: &str) {
    let mut build = cc::Build::new();
    build.include(dir);
    for file in files.split(' ') {
        let mut path = PathBuf::from(dir);
        path.push(file);
        build.file(path);
    }
    build.flag("-Wall");
    build.flag("-fno-builtin");
    build.compile(dir);
}

fn main() {
    let dir_double = "cephes-double";
    let dir_single = "cephes-single";
    let files_double =
        "acosh.c airy.c asin.c asinh.c atan.c atanh.c bdtr.c beta.c \
         btdtr.c cbrt.c chbevl.c chdtr.c clog.c cmplx.c const.c \
         cosh.c dawsn.c drand.c ei.c ellie.c ellik.c ellpe.c ellpj.c ellpk.c \
         exp.c exp10.c exp2.c expn.c expx2.c fabs.c fac.c fdtr.c \
         fresnl.c gamma.c gdtr.c hyp2f1.c hyperg.c i0.c i1.c igami.c incbet.c \
         incbi.c igam.c isnan.c iv.c j0.c j1.c jn.c jv.c k0.c k1.c kn.c kolmogorov.c \
         log.c log2.c log10.c lrand.c nbdtr.c ndtr.c ndtri.c pdtr.c planck.c \
         polevl.c polmisc.c polylog.c polyn.c pow.c powi.c psi.c rgamma.c round.c \
         shichi.c sici.c sin.c sindg.c sinh.c spence.c stdtr.c struve.c \
         tan.c tandg.c tanh.c unity.c yn.c zeta.c zetac.c \
         sqrt.c floor.c setprec.c mtherr.c";
    let files_single =
        "acoshf.c airyf.c asinf.c asinhf.c atanf.c \
         atanhf.c bdtrf.c betaf.c cbrtf.c chbevlf.c chdtrf.c \
         clogf.c cmplxf.c constf.c coshf.c dawsnf.c ellief.c \
         ellikf.c ellpef.c ellpkf.c ellpjf.c expf.c exp2f.c \
         exp10f.c expnf.c expx2f.c facf.c fdtrf.c floorf.c fresnlf.c \
         gammaf.c gdtrf.c hypergf.c hyp2f1f.c igamf.c igamif.c \
         incbetf.c incbif.c i0f.c i1f.c ivf.c j0f.c j1f.c \
         jnf.c jvf.c k0f.c k1f.c knf.c logf.c log2f.c \
         log10f.c nbdtrf.c ndtrf.c ndtrif.c pdtrf.c polynf.c \
         powif.c powf.c psif.c rgammaf.c shichif.c sicif.c \
         sindgf.c sinf.c sinhf.c spencef.c sqrtf.c stdtrf.c \
         struvef.c tandgf.c tanf.c tanhf.c ynf.c zetaf.c \
         zetacf.c polevlf.c setprecf.c mtherrf.c";

    build(dir_double, files_double);
    build(dir_single, files_single);
}
<commit_msg>Try to fix Windows build<commit_after>extern crate cc;

use std::path::PathBuf;

fn build(dir: &str, files: &str) {
    let mut build = cc::Build::new();
    build.include(dir);
    for file in files.split(' ') {
        let mut path = PathBuf::from(dir);
        path.push(file);
        build.file(path);
    }
    build.flag("-Wall");
    build.flag_if_supported("-fno-builtin");
    build.flag_if_supported("/Oi-");
    build.compile(dir);
}

fn main() {
    let dir_double = "cephes-double";
    let dir_single = "cephes-single";
    let files_double =
        "acosh.c airy.c asin.c asinh.c atan.c atanh.c bdtr.c beta.c \
         btdtr.c cbrt.c chbevl.c chdtr.c clog.c cmplx.c const.c \
         cosh.c dawsn.c drand.c ei.c ellie.c ellik.c ellpe.c ellpj.c ellpk.c \
         exp.c exp10.c exp2.c expn.c expx2.c fabs.c fac.c fdtr.c \
         fresnl.c gamma.c gdtr.c hyp2f1.c hyperg.c i0.c i1.c igami.c incbet.c \
         incbi.c igam.c isnan.c iv.c j0.c j1.c jn.c jv.c k0.c k1.c kn.c kolmogorov.c \
         log.c log2.c log10.c lrand.c nbdtr.c ndtr.c ndtri.c pdtr.c planck.c \
         polevl.c polmisc.c polylog.c polyn.c pow.c powi.c psi.c rgamma.c round.c \
         shichi.c sici.c sin.c sindg.c sinh.c spence.c stdtr.c struve.c \
         tan.c tandg.c tanh.c unity.c yn.c zeta.c zetac.c \
         sqrt.c floor.c setprec.c mtherr.c";
    let files_single =
        "acoshf.c airyf.c asinf.c asinhf.c atanf.c \
         atanhf.c bdtrf.c betaf.c cbrtf.c chbevlf.c chdtrf.c \
         clogf.c cmplxf.c constf.c coshf.c dawsnf.c ellief.c \
         ellikf.c ellpef.c ellpkf.c ellpjf.c expf.c exp2f.c \
         exp10f.c expnf.c expx2f.c facf.c fdtrf.c floorf.c fresnlf.c \
         gammaf.c gdtrf.c hypergf.c hyp2f1f.c igamf.c igamif.c \
         incbetf.c incbif.c i0f.c i1f.c ivf.c j0f.c j1f.c \
         jnf.c jvf.c k0f.c k1f.c knf.c logf.c log2f.c \
         log10f.c nbdtrf.c ndtrf.c ndtrif.c pdtrf.c polynf.c \
         powif.c powf.c psif.c rgammaf.c shichif.c sicif.c \
         sindgf.c sinf.c sinhf.c spencef.c sqrtf.c stdtrf.c \
         struvef.c tandgf.c tanf.c tanhf.c ynf.c zetaf.c \
         zetacf.c polevlf.c setprecf.c mtherrf.c";

    build(dir_double, files_double);
    build(dir_single, files_single);
}
<|endoftext|>


<commit_before>extern crate pkg_config;
use std::process::Command;
use std::path::PathBuf;
use std::env;
use std::fs;

macro_rules! sio {
    ($expr:expr) => { format!("libsoundio-{}", $expr) }
}

macro_rules! err_exists {
    ($expr:expr, $msg:expr) => {
        match $expr {
            Ok(val) => val,
            Err(err) => {
                match err.kind() {
                    ::std::io::ErrorKind::AlreadyExists => (),
                    _ => panic!(format!("{}: {}", $msg, err)),
                }
            }
        }
    }
}

fn lib_available(name: &str) -> bool {
    match pkg_config::find_library(name) {
        Ok(_) => true,
        Err(_) => {
            let res = Command::new("ldconfig").arg("--print-cache").output().unwrap();
            if res.status.success() {
                String::from_utf8(res.stdout).unwrap().contains(name)
            } else {
                false
            }
        }
    }
}

fn windows(_: String) {
    // TODO: Use precompiled binary!
    unimplemented!();
}

fn osx(_: String) {
    // TODO: I down't own any apple hardware to test this.
    unimplemented!();
}

fn linux(target: String) {
    if !lib_available("soundio") {
        build(target);
    } else {
        // TODO: remove else branch
        build(target);
    }
}

fn main() {
    let target = env::var("TARGET").unwrap();
    if target.contains("windows") {
        windows(target)
    } else if target.contains("apple") {
        osx(target)
    } else {
        // assume the rest is linux
        linux(target)
    }
}

fn sio_url(ext: &'static str) -> String {
    match ext {
        "tar.gz" | "zip" => format!("http://libsound.io/release/{}.{}", sio!("1.1.0"), ext),
        _ => panic!(format!("No release for format: {}", ext)),
    }
}

fn build(target: String) {
    let host = env::var("HOST").unwrap();
    let dst_dir = PathBuf::from(env::var("OUT_DIR").unwrap());
    let lib_dir = dst_dir.join("lib");
    let include_dir = dst_dir.join("include");
    err_exists!(fs::create_dir(&lib_dir), &lib_dir.display());
    err_exists!(fs::create_dir(&include_dir), &include_dir.display());

    // set cargo flags
    println!("cargo:rustc-link-lib=dylib={}", "soundio"); // -l
    println!("cargo:rustc-link-search=native={}", &lib_dir.display()); // -L
    println!("cargo:include={}", &include_dir.display());
    println!("cargo:root={}", &dst_dir.display());

    // download and extract libsoundio source
    Command::new("curl")
        .current_dir(&dst_dir)
        .args(&["--location", "--remote-name"])
        .arg(sio_url("tar.gz"))
        .output()
        .unwrap();
    Command::new("tar")
        .current_dir(&dst_dir)
        .arg("-xvzf")
        .arg(format!("{}.{}", sio!("1.1.0"), "tar.gz"))
        .output()
        .unwrap();

    // create build dir
    let soundio_root = dst_dir.join(sio!("1.1.0"));
    let build_dir = soundio_root.join("build");
    err_exists!(fs::create_dir(&build_dir), &build_dir.display());

    // TODO:set build type to release for env var PROFILE={release,bench}
    // run cmake
    Command::new("cmake")
        .current_dir(&build_dir)
        .arg("-DCMAKE_BUILD_TYPE=Debug")
        .arg("-DCMAKE_INSTALL_LIBDIR:PATH=lib")
        .arg(format!("-DCMAKE_INSTALL_PREFIX:PATH={}", &dst_dir.display()))
        .arg("-DBUILD_EXAMPLE_PROGRAMS:BOOL=OFF")
        .arg("-DBUILD_TESTS:BOOL=OFF")
        .arg("-DBUILD_STATIC_LIBS:BOOL=OFF")
        .arg("-DBUILD_SHARED_LIBS:BOOL=ON")
        .arg("-DENABLE_JACK:BOOL=OFF")
        .arg("-DENABLE_PULSEAUDIO:BOOL=OFF")
        .arg("-DCMAKE_POSITION_INDEPENDENT_CODE:BOOL=ON")
        .arg("..")
        .output()
        .unwrap();

    // make install
    Command::new("make")
        .current_dir(&build_dir)
        .arg("install")
        .output()
        .unwrap();

    // remove builddir
    fs::remove_dir_all(build_dir).unwrap();
}
<commit_msg>Fix #8<commit_after>extern crate pkg_config;
use std::process::Command;
use std::path::PathBuf;
use std::env;
use std::fs;

macro_rules! sio {
    ($expr:expr) => { format!("libsoundio-{}", $expr) }
}

macro_rules! err_exists {
    ($expr:expr, $msg:expr) => {
        match $expr {
            Ok(val) => val,
            Err(err) => {
                match err.kind() {
                    ::std::io::ErrorKind::AlreadyExists => (),
                    _ => panic!(format!("{}: {}", $msg, err)),
                }
            }
        }
    }
}

fn lib_available(name: &str) -> bool {
    match pkg_config::find_library(name) {
        Ok(_) => true,
        Err(_) => {
            let res = Command::new("ldconfig").arg("--print-cache").output().unwrap();
            if res.status.success() {
                String::from_utf8(res.stdout).unwrap().contains(name)
            } else {
                false
            }
        }
    }
}

fn windows(_: String) {
    // TODO: Use precompiled binary!
    unimplemented!();
}

fn osx(_: String) {
    // TODO: I down't own any apple hardware to test this.
    unimplemented!();
}

fn linux(target: String) {
    if !lib_available("soundio") {
        build(target);
    }
}

fn main() {
    let target = env::var("TARGET").unwrap();
    if target.contains("windows") {
        windows(target)
    } else if target.contains("apple") {
        osx(target)
    } else {
        // assume the rest is linux
        linux(target)
    }
}

fn sio_url(ext: &'static str) -> String {
    match ext {
        "tar.gz" | "zip" => format!("http://libsound.io/release/{}.{}", sio!("1.1.0"), ext),
        _ => panic!(format!("No release for format: {}", ext)),
    }
}

fn build(target: String) {
    let host = env::var("HOST").unwrap();
    let dst_dir = PathBuf::from(env::var("OUT_DIR").unwrap());
    let lib_dir = dst_dir.join("lib");
    let include_dir = dst_dir.join("include");
    err_exists!(fs::create_dir(&lib_dir), &lib_dir.display());
    err_exists!(fs::create_dir(&include_dir), &include_dir.display());

    // set cargo flags
    println!("cargo:rustc-link-lib=dylib={}", "soundio"); // -l
    println!("cargo:rustc-link-search=native={}", &lib_dir.display()); // -L
    println!("cargo:include={}", &include_dir.display());
    println!("cargo:root={}", &dst_dir.display());

    // download and extract libsoundio source
    Command::new("curl")
        .current_dir(&dst_dir)
        .args(&["--location", "--remote-name"])
        .arg(sio_url("tar.gz"))
        .output()
        .unwrap();
    Command::new("tar")
        .current_dir(&dst_dir)
        .arg("-xvzf")
        .arg(format!("{}.{}", sio!("1.1.0"), "tar.gz"))
        .output()
        .unwrap();

    // create build dir
    let soundio_root = dst_dir.join(sio!("1.1.0"));
    let build_dir = soundio_root.join("build");
    err_exists!(fs::create_dir(&build_dir), &build_dir.display());

    // TODO:set build type to release for env var PROFILE={release,bench}
    // run cmake
    Command::new("cmake")
        .current_dir(&build_dir)
        .arg("-DCMAKE_BUILD_TYPE=Debug")
        .arg("-DCMAKE_INSTALL_LIBDIR:PATH=lib")
        .arg(format!("-DCMAKE_INSTALL_PREFIX:PATH={}", &dst_dir.display()))
        .arg("-DBUILD_EXAMPLE_PROGRAMS:BOOL=OFF")
        .arg("-DBUILD_TESTS:BOOL=OFF")
        .arg("-DBUILD_STATIC_LIBS:BOOL=OFF")
        .arg("-DBUILD_SHARED_LIBS:BOOL=ON")
        .arg("-DENABLE_JACK:BOOL=OFF")
        .arg("-DENABLE_PULSEAUDIO:BOOL=OFF")
        .arg("-DCMAKE_POSITION_INDEPENDENT_CODE:BOOL=ON")
        .arg("..")
        .output()
        .unwrap();

    // make install
    Command::new("make")
        .current_dir(&build_dir)
        .arg("install")
        .output()
        .unwrap();

    // remove builddir
    fs::remove_dir_all(build_dir).unwrap();
}
<|endoftext|>


<commit_before>extern crate "pkg-config" as pkg_config;

use std::io::Command;
use std::os;

#[allow(unused_must_use)]
fn main() {
    let mut build = os::getcwd().unwrap();
    build.push_many(&["ext", "libqmlrswrapper", "build"]);

    /* Ignore error, the return value is not reliable and we'll catch it when chdir'ing anyway. */
    std::io::fs::mkdir(&build, std::io::USER_RWX);

    os::change_dir(&build).ok().expect("Failed to change into build directory");

    let out = Command::new("cmake").arg("..").output();
    if out.unwrap().status != std::io::process::ProcessExit::ExitStatus(0) {
        panic!("Failed to run cmake");
    }

    let out = Command::new("make").output();
    if out.unwrap().status != std::io::process::ProcessExit::ExitStatus(0) {
        panic!("Failed to run make");
    }

    println!("cargo:rustc-flags=-L {} -l qmlrswrapper:static -l stdc++", build.display());
    pkg_config::find_library("Qt5Core Qt5Gui Qt5Qml Qt5Quick").unwrap();
}
<commit_msg>Adapt to Rust changes: io -> old_io<commit_after>extern crate "pkg-config" as pkg_config;

use std::old_io::Command;
use std::os;

#[allow(unused_must_use)]
fn main() {
    let mut build = os::getcwd().unwrap();
    build.push_many(&["ext", "libqmlrswrapper", "build"]);

    /* Ignore error, the return value is not reliable and we'll catch it when chdir'ing anyway. */
    std::old_io::fs::mkdir(&build, std::old_io::USER_RWX);

    os::change_dir(&build).ok().expect("Failed to change into build directory");

    let out = Command::new("cmake").arg("..").output();
    if out.unwrap().status != std::old_io::process::ProcessExit::ExitStatus(0) {
        panic!("Failed to run cmake");
    }

    let out = Command::new("make").output();
    if out.unwrap().status != std::old_io::process::ProcessExit::ExitStatus(0) {
        panic!("Failed to run make");
    }

    println!("cargo:rustc-flags=-L {} -l qmlrswrapper:static -l stdc++", build.display());
    pkg_config::find_library("Qt5Core Qt5Gui Qt5Qml Qt5Quick").unwrap();
}
<|endoftext|>


<commit_before>// spell-checker:ignore (vars) krate

use std::env;
use std::fs::File;
use std::io::Write;
use std::path::Path;

pub fn main() {
    // println!("cargo:warning=Running build.rs");

    if let Ok(profile) = env::var("PROFILE") {
        println!("cargo:rustc-cfg=build={:?}", profile);
    }

    let env_feature_prefix: &str = "CARGO_FEATURE_";
    let feature_prefix: &str = "feat_";
    let override_prefix: &str = "uu_";

    let out_dir = env::var("OUT_DIR").unwrap();
    // println!("cargo:warning=out_dir={}", out_dir);
    let manifest_dir = env::var("CARGO_MANIFEST_DIR").unwrap().replace("\\", "/");
    // println!("cargo:warning=manifest_dir={}", manifest_dir);
    let util_tests_dir = format!("{}/tests/by-util", manifest_dir);
    // println!("cargo:warning=util_tests_dir={}", util_tests_dir);

    let mut crates = Vec::new();
    for (key, val) in env::vars() {
        if val == "1" && key.starts_with(env_feature_prefix) {
            let krate = key[env_feature_prefix.len()..].to_lowercase();
            match krate.as_ref() {
                "default" | "macos" | "unix" | "windows" | "selinux" => continue, // common/standard feature names
                "nightly" | "test_unimplemented" => continue, // crate-local custom features
                "test" => continue, // over-ridden with 'uu_test' to avoid collision with rust core crate 'test'
                s if s.starts_with(feature_prefix) => continue, // crate feature sets
                _ => {}             // util feature name
            }
            crates.push(krate.to_string());
        }
    }
    crates.sort();

    let mut mf = File::create(Path::new(&out_dir).join("uutils_map.rs")).unwrap();
    let mut tf = File::create(Path::new(&out_dir).join("test_modules.rs")).unwrap();

    mf.write_all(
        "type UtilityMap<T> = HashMap<&'static str, (fn(T) -> i32, fn() -> App<'static, 'static>)>;\n\
         \n\
         fn util_map<T: uucore::Args>() -> UtilityMap<T> {\n\
         \tlet mut map = UtilityMap::new();\n\
         "
        .as_bytes(),
    )
    .unwrap();

    for krate in crates {
        match krate.as_ref() {
            // 'test' is named uu_test to avoid collision with rust core crate 'test'.
            // It can also be invoked by name '[' for the '[ expr ] syntax'.
            "uu_test" => {
                mf.write_all(
                    format!(
                        "\
                         \tmap.insert(\"test\", ({krate}::uumain, {krate}::uu_app));\n\
                         \t\tmap.insert(\"[\", ({krate}::uumain, {krate}::uu_app));\n\
                         ",
                        krate = krate
                    )
                    .as_bytes(),
                )
                .unwrap();
                tf.write_all(
                    format!(
                        "#[path=\"{dir}/test_test.rs\"]\nmod test_test;\n",
                        dir = util_tests_dir,
                    )
                    .as_bytes(),
                )
                .unwrap()
            }
            k if k.starts_with(override_prefix) => {
                mf.write_all(
                    format!(
                        "\tmap.insert(\"{k}\", ({krate}::uumain, {krate}::uu_app));\n",
                        k = krate[override_prefix.len()..].to_string(),
                        krate = krate
                    )
                    .as_bytes(),
                )
                .unwrap();
                tf.write_all(
                    format!(
                        "#[path=\"{dir}/test_{k}.rs\"]\nmod test_{k};\n",
                        k = krate[override_prefix.len()..].to_string(),
                        dir = util_tests_dir,
                    )
                    .as_bytes(),
                )
                .unwrap()
            }
            "false" | "true" => {
                mf.write_all(
                    format!(
                        "\tmap.insert(\"{krate}\", (r#{krate}::uumain, r#{krate}::uu_app));\n",
                        krate = krate
                    )
                    .as_bytes(),
                )
                .unwrap();
                tf.write_all(
                    format!(
                        "#[path=\"{dir}/test_{krate}.rs\"]\nmod test_{krate};\n",
                        krate = krate,
                        dir = util_tests_dir,
                    )
                    .as_bytes(),
                )
                .unwrap()
            }
            "hashsum" => {
                mf.write_all(
                    format!(
                        "\
                         \tmap.insert(\"{krate}\", ({krate}::uumain, {krate}::uu_app_custom));\n\
                         \t\tmap.insert(\"md5sum\", ({krate}::uumain, {krate}::uu_app_common));\n\
                         \t\tmap.insert(\"sha1sum\", ({krate}::uumain, {krate}::uu_app_common));\n\
                         \t\tmap.insert(\"sha224sum\", ({krate}::uumain, {krate}::uu_app_common));\n\
                         \t\tmap.insert(\"sha256sum\", ({krate}::uumain, {krate}::uu_app_common));\n\
                         \t\tmap.insert(\"sha384sum\", ({krate}::uumain, {krate}::uu_app_common));\n\
                         \t\tmap.insert(\"sha512sum\", ({krate}::uumain, {krate}::uu_app_common));\n\
                         \t\tmap.insert(\"sha3sum\", ({krate}::uumain, {krate}::uu_app_common));\n\
                         \t\tmap.insert(\"sha3-224sum\", ({krate}::uumain, {krate}::uu_app_common));\n\
                         \t\tmap.insert(\"sha3-256sum\", ({krate}::uumain, {krate}::uu_app_common));\n\
                         \t\tmap.insert(\"sha3-384sum\", ({krate}::uumain, {krate}::uu_app_common));\n\
                         \t\tmap.insert(\"sha3-512sum\", ({krate}::uumain, {krate}::uu_app_common));\n\
                         \t\tmap.insert(\"shake128sum\", ({krate}::uumain, {krate}::uu_app_common));\n\
                         \t\tmap.insert(\"shake256sum\", ({krate}::uumain, {krate}::uu_app_common));\n\
                         ",
                        krate = krate
                    )
                    .as_bytes(),
                )
                .unwrap();
                tf.write_all(
                    format!(
                        "#[path=\"{dir}/test_{krate}.rs\"]\nmod test_{krate};\n",
                        krate = krate,
                        dir = util_tests_dir,
                    )
                    .as_bytes(),
                )
                .unwrap()
            }
            _ => {
                mf.write_all(
                    format!(
                        "\tmap.insert(\"{krate}\", ({krate}::uumain, {krate}::uu_app));\n",
                        krate = krate
                    )
                    .as_bytes(),
                )
                .unwrap();
                tf.write_all(
                    format!(
                        "#[path=\"{dir}/test_{krate}.rs\"]\nmod test_{krate};\n",
                        krate = krate,
                        dir = util_tests_dir,
                    )
                    .as_bytes(),
                )
                .unwrap()
            }
        }
    }

    mf.write_all(b"map\n}\n").unwrap();

    mf.flush().unwrap();
    tf.flush().unwrap();
}
<commit_msg>build.rs: silence clippy warnings<commit_after>// spell-checker:ignore (vars) krate

use std::env;
use std::fs::File;
use std::io::Write;
use std::path::Path;

pub fn main() {
    // println!("cargo:warning=Running build.rs");

    if let Ok(profile) = env::var("PROFILE") {
        println!("cargo:rustc-cfg=build={:?}", profile);
    }

    let env_feature_prefix: &str = "CARGO_FEATURE_";
    let feature_prefix: &str = "feat_";
    let override_prefix: &str = "uu_";

    let out_dir = env::var("OUT_DIR").unwrap();
    // println!("cargo:warning=out_dir={}", out_dir);
    let manifest_dir = env::var("CARGO_MANIFEST_DIR").unwrap().replace("\\", "/");
    // println!("cargo:warning=manifest_dir={}", manifest_dir);
    let util_tests_dir = format!("{}/tests/by-util", manifest_dir);
    // println!("cargo:warning=util_tests_dir={}", util_tests_dir);

    let mut crates = Vec::new();
    for (key, val) in env::vars() {
        if val == "1" && key.starts_with(env_feature_prefix) {
            let krate = key[env_feature_prefix.len()..].to_lowercase();
            match krate.as_ref() {
                "default" | "macos" | "unix" | "windows" | "selinux" => continue, // common/standard feature names
                "nightly" | "test_unimplemented" => continue, // crate-local custom features
                "test" => continue, // over-ridden with 'uu_test' to avoid collision with rust core crate 'test'
                s if s.starts_with(feature_prefix) => continue, // crate feature sets
                _ => {}             // util feature name
            }
            crates.push(krate.to_string());
        }
    }
    crates.sort();

    let mut mf = File::create(Path::new(&out_dir).join("uutils_map.rs")).unwrap();
    let mut tf = File::create(Path::new(&out_dir).join("test_modules.rs")).unwrap();

    mf.write_all(
        "type UtilityMap<T> = HashMap<&'static str, (fn(T) -> i32, fn() -> App<'static, 'static>)>;\n\
         \n\
         fn util_map<T: uucore::Args>() -> UtilityMap<T> {\n\
         \t#[allow(unused_mut)]\n\
         \t#[allow(clippy::let_and_return)]\n\
         \tlet mut map = UtilityMap::new();\n\
         "
        .as_bytes(),
    )
    .unwrap();

    for krate in crates {
        match krate.as_ref() {
            // 'test' is named uu_test to avoid collision with rust core crate 'test'.
            // It can also be invoked by name '[' for the '[ expr ] syntax'.
            "uu_test" => {
                mf.write_all(
                    format!(
                        "\
                         \tmap.insert(\"test\", ({krate}::uumain, {krate}::uu_app));\n\
                         \t\tmap.insert(\"[\", ({krate}::uumain, {krate}::uu_app));\n\
                         ",
                        krate = krate
                    )
                    .as_bytes(),
                )
                .unwrap();
                tf.write_all(
                    format!(
                        "#[path=\"{dir}/test_test.rs\"]\nmod test_test;\n",
                        dir = util_tests_dir,
                    )
                    .as_bytes(),
                )
                .unwrap()
            }
            k if k.starts_with(override_prefix) => {
                mf.write_all(
                    format!(
                        "\tmap.insert(\"{k}\", ({krate}::uumain, {krate}::uu_app));\n",
                        k = krate[override_prefix.len()..].to_string(),
                        krate = krate
                    )
                    .as_bytes(),
                )
                .unwrap();
                tf.write_all(
                    format!(
                        "#[path=\"{dir}/test_{k}.rs\"]\nmod test_{k};\n",
                        k = krate[override_prefix.len()..].to_string(),
                        dir = util_tests_dir,
                    )
                    .as_bytes(),
                )
                .unwrap()
            }
            "false" | "true" => {
                mf.write_all(
                    format!(
                        "\tmap.insert(\"{krate}\", (r#{krate}::uumain, r#{krate}::uu_app));\n",
                        krate = krate
                    )
                    .as_bytes(),
                )
                .unwrap();
                tf.write_all(
                    format!(
                        "#[path=\"{dir}/test_{krate}.rs\"]\nmod test_{krate};\n",
                        krate = krate,
                        dir = util_tests_dir,
                    )
                    .as_bytes(),
                )
                .unwrap()
            }
            "hashsum" => {
                mf.write_all(
                    format!(
                        "\
                         \tmap.insert(\"{krate}\", ({krate}::uumain, {krate}::uu_app_custom));\n\
                         \t\tmap.insert(\"md5sum\", ({krate}::uumain, {krate}::uu_app_common));\n\
                         \t\tmap.insert(\"sha1sum\", ({krate}::uumain, {krate}::uu_app_common));\n\
                         \t\tmap.insert(\"sha224sum\", ({krate}::uumain, {krate}::uu_app_common));\n\
                         \t\tmap.insert(\"sha256sum\", ({krate}::uumain, {krate}::uu_app_common));\n\
                         \t\tmap.insert(\"sha384sum\", ({krate}::uumain, {krate}::uu_app_common));\n\
                         \t\tmap.insert(\"sha512sum\", ({krate}::uumain, {krate}::uu_app_common));\n\
                         \t\tmap.insert(\"sha3sum\", ({krate}::uumain, {krate}::uu_app_common));\n\
                         \t\tmap.insert(\"sha3-224sum\", ({krate}::uumain, {krate}::uu_app_common));\n\
                         \t\tmap.insert(\"sha3-256sum\", ({krate}::uumain, {krate}::uu_app_common));\n\
                         \t\tmap.insert(\"sha3-384sum\", ({krate}::uumain, {krate}::uu_app_common));\n\
                         \t\tmap.insert(\"sha3-512sum\", ({krate}::uumain, {krate}::uu_app_common));\n\
                         \t\tmap.insert(\"shake128sum\", ({krate}::uumain, {krate}::uu_app_common));\n\
                         \t\tmap.insert(\"shake256sum\", ({krate}::uumain, {krate}::uu_app_common));\n\
                         ",
                        krate = krate
                    )
                    .as_bytes(),
                )
                .unwrap();
                tf.write_all(
                    format!(
                        "#[path=\"{dir}/test_{krate}.rs\"]\nmod test_{krate};\n",
                        krate = krate,
                        dir = util_tests_dir,
                    )
                    .as_bytes(),
                )
                .unwrap()
            }
            _ => {
                mf.write_all(
                    format!(
                        "\tmap.insert(\"{krate}\", ({krate}::uumain, {krate}::uu_app));\n",
                        krate = krate
                    )
                    .as_bytes(),
                )
                .unwrap();
                tf.write_all(
                    format!(
                        "#[path=\"{dir}/test_{krate}.rs\"]\nmod test_{krate};\n",
                        krate = krate,
                        dir = util_tests_dir,
                    )
                    .as_bytes(),
                )
                .unwrap()
            }
        }
    }

    mf.write_all(b"map\n}\n").unwrap();

    mf.flush().unwrap();
    tf.flush().unwrap();
}
<|endoftext|>


<commit_before>use std::env;
use std::str::FromStr;

fn main() {
    // OpenSSL >= 1.1.0 can be initialized concurrently and is initialized correctly by libcurl.
    // <= 1.0.2 need locking callbacks, which are provided by openssl_sys::init().
    match env::var("DEP_OPENSSL_VERSION") {
        Ok(ver) => {
            let ver = u32::from_str(&ver).unwrap();
            if ver < 110 {
                println!("cargo:rustc-cfg=need_openssl_init");
            }
        }
        Err(env::VarError::NotPresent) => {}
        Err(e) => panic!(e),
    }

    // The system libcurl should have the default certificate paths configured.
    match env::var("DEP_CURL_STATIC") {
        Ok(_) => {
            println!("cargo:rustc-cfg=need_openssl_probe");
        }
        Err(env::VarError::NotPresent) => {}
        Err(e) => panic!(e),
    }
}
<commit_msg>Only use openssl-probe if we're using OpenSSL.<commit_after>use std::env;
use std::str::FromStr;

fn main() {
    let use_openssl;

    // OpenSSL >= 1.1.0 can be initialized concurrently and is initialized correctly by libcurl.
    // <= 1.0.2 need locking callbacks, which are provided by openssl_sys::init().
    match env::var("DEP_OPENSSL_VERSION") {
        Ok(ver) => {
            use_openssl = true;
            let ver = u32::from_str(&ver).unwrap();
            if ver < 110 {
                println!("cargo:rustc-cfg=need_openssl_init");
            }

        }
        Err(env::VarError::NotPresent) => {
            use_openssl = false;
        }
        Err(e) => panic!(e),
    }

    if use_openssl {
        // The system libcurl should have the default certificate paths configured.
        match env::var_os("DEP_CURL_STATIC") {
            Some(_) => {
                println!("cargo:rustc-cfg=need_openssl_probe");
            }
            None => {}
        }
    }
}
<|endoftext|>


<commit_before>extern crate crowbook_intl;
use crowbook_intl::{Localizer, Extractor};

use std::path::Path;
use std::env;

fn main() {
//    println!("cargo:rerun-if-changed=build.rs");
    //    println!("cargo:rerun-if-changed=lang/fr.po");
    // Extract and localize src/lib
    let mut extractor = Extractor::new();
    extractor.add_messages_from_dir(concat!(env!("CARGO_MANIFEST_DIR"), "/src/lib")).unwrap();
    extractor.write_pot_file(concat!(env!("CARGO_MANIFEST_DIR"), "/lang/lib/crowbook.pot")).unwrap();

    let mut localizer = Localizer::new(&extractor);
    localizer.add_lang("fr", include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/lang/lib/fr.po"))).unwrap();
    let dest_path = Path::new(&env::var("OUT_DIR").unwrap())
        .join("localize_macros.rs");
    localizer.write_macro_file(dest_path).unwrap();

    // Extract and localize src/bin
    let mut extractor = Extractor::new();
    extractor.add_messages_from_dir(concat!(env!("CARGO_MANIFEST_DIR"), "/src/bin")).unwrap();
    extractor.write_pot_file(concat!(env!("CARGO_MANIFEST_DIR"), "/lang/bin/crowbook.pot")).unwrap();

    let mut localizer = Localizer::new(&extractor);
    localizer.add_lang("fr", include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/lang/bin/fr.po"))).unwrap();
    let dest_path = Path::new(&env::var("OUT_DIR").unwrap())
        .join("localize_macros_bin.rs");
    localizer.write_macro_file(dest_path).unwrap();
}
<commit_msg>Comment crowbook.pot generation in build.rs so it compiles on travis(?)<commit_after>extern crate crowbook_intl;
use crowbook_intl::{Localizer, Extractor};

use std::path::Path;
use std::env;

fn main() {
//    println!("cargo:rerun-if-changed=build.rs");
    //    println!("cargo:rerun-if-changed=lang/fr.po");
    // Extract and localize src/lib
    let mut extractor = Extractor::new();
    extractor.add_messages_from_dir(concat!(env!("CARGO_MANIFEST_DIR"), "/src/lib")).unwrap();
    // Uncomment to update crowbook.pot
    // extractor.write_pot_file(concat!(env!("CARGO_MANIFEST_DIR"), "/lang/lib/crowbook.pot")).unwrap();

    let mut localizer = Localizer::new(&extractor);
    localizer.add_lang("fr", include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/lang/lib/fr.po"))).unwrap();
    let dest_path = Path::new(&env::var("OUT_DIR").unwrap())
        .join("localize_macros.rs");
    localizer.write_macro_file(dest_path).unwrap();

    // Extract and localize src/bin
    let mut extractor = Extractor::new();
    extractor.add_messages_from_dir(concat!(env!("CARGO_MANIFEST_DIR"), "/src/bin")).unwrap();
    // Uncomment to update crowbook.pot
    extractor.write_pot_file(concat!(env!("CARGO_MANIFEST_DIR"), "/lang/bin/crowbook.pot")).unwrap();

    let mut localizer = Localizer::new(&extractor);
    localizer.add_lang("fr", include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/lang/bin/fr.po"))).unwrap();
    let dest_path = Path::new(&env::var("OUT_DIR").unwrap())
        .join("localize_macros_bin.rs");
    localizer.write_macro_file(dest_path).unwrap();
}
<|endoftext|>


<commit_before>use std::env;
use std::process::Command;
use std::str::{self, FromStr};

fn main() {
    let compiler = match rustc_version() {
        Some(compiler) => compiler,
        None => return,
    };

    if compiler.minor >= 40 && compiler.nightly {
        println!("cargo:rustc-cfg=backtrace");
    }
}

struct Compiler {
    minor: u32,
    nightly: bool,
}

fn rustc_version() -> Option<Compiler> {
    let rustc = env::var_os("RUSTC")?;
    let output = Command::new(rustc).arg("--version").output().ok()?;
    let version = str::from_utf8(&output.stdout).ok()?;

    let mut pieces = version.split('.');
    if pieces.next() != Some("rustc 1") {
        return None;
    }

    let next = pieces.next()?;
    let minor = u32::from_str(next).ok()?;
    let nightly = version.contains("nightly") || version.contains("dev");
    Some(Compiler { minor, nightly })
}
<commit_msg>Replace version check with probing Backtrace api<commit_after>use std::env;
use std::fs;
use std::path::Path;
use std::process::{Command, ExitStatus};

// This code exercises the surface area that we expect of the std Backtrace
// type. If the current toolchain is able to compile it, we go ahead and use
// backtrace in anyhow.
const PROBE: &str = r#"
    #![feature(backtrace)]
    #![allow(dead_code)]

    use std::backtrace::{Backtrace, BacktraceStatus};
    use std::error::Error;
    use std::fmt::{self, Display};

    #[derive(Debug)]
    struct E;

    impl Display for E {
        fn fmt(&self, _formatter: &mut fmt::Formatter) -> fmt::Result {
            unimplemented!()
        }
    }

    impl Error for E {
        fn backtrace(&self) -> Option<&Backtrace> {
            let backtrace = Backtrace::capture();
            match backtrace.status() {
                BacktraceStatus::Captured | BacktraceStatus::Disabled | _ => {}
            }
            unimplemented!()
        }
    }
"#;

fn main() {
    match compile_probe() {
        Some(status) if status.success() => println!("cargo:rustc-cfg=backtrace"),
        _ => {}
    }
}

fn compile_probe() -> Option<ExitStatus> {
    let rustc = env::var_os("RUSTC")?;
    let out_dir = env::var_os("OUT_DIR")?;
    let probefile = Path::new(&out_dir).join("lib.rs");
    fs::write(&probefile, PROBE).ok()?;
    Command::new(rustc)
        .arg("--edition=2018")
        .arg("--crate-name=anyhow_build")
        .arg("--crate-type=lib")
        .arg("--emit=metadata")
        .arg("--out-dir")
        .arg(out_dir)
        .arg(probefile)
        .status()
        .ok()
}
<|endoftext|>


<commit_before>pub extern mod core_foundation;
pub extern mod io_surface;
pub extern mod opengles;

use mod platform::opengles::cgl;
use mod platform::opengles::gl2;

use core::cast::transmute;
use core::ptr::{null, to_unsafe_ptr};
use geom::size::Size2D;
use platform::io_surface::{IOSurface, kIOSurfaceBytesPerElement, kIOSurfaceBytesPerRow};
use platform::io_surface::{kIOSurfaceHeight, kIOSurfaceIsGlobal, kIOSurfaceWidth};
use platform::opengles::cgl::{CGLChoosePixelFormat, CGLContextObj, CGLCreateContext};
use platform::opengles::cgl::{CGLLockContext, CGLSetCurrentContext, CGLTexImageIOSurface2D};
use platform::opengles::cgl::{kCGLNoError, kCGLPFACompliant, kCGLPFADoubleBuffer};
use platform::opengles::gl2::{BGRA, CLAMP_TO_EDGE, COLOR_ATTACHMENT0, FRAMEBUFFER};
use platform::opengles::gl2::{FRAMEBUFFER_COMPLETE, GLenum, GLint, GLsizei, GLuint, LINEAR};
use platform::opengles::gl2::{NEAREST, RGBA, TEXTURE_MAG_FILTER, TEXTURE_MIN_FILTER};
use platform::opengles::gl2::{TEXTURE_RECTANGLE_ARB, TEXTURE_WRAP_S, TEXTURE_WRAP_T};
use platform::opengles::gl2::{UNSIGNED_INT_8_8_8_8_REV};

use base::ShareContext;

// FIXME: This is not good.
#[link_args="-framework IOSurface -framework CoreFoundation"]
#[nolink]
extern {}

pub type Context = MacContext;

pub struct MacContext {
    surface: IOSurface,
    framebuffer: GLuint,
    texture: GLuint

    // FIXME: Needs drop.
}

pub fn init_cgl() -> CGLContextObj {
    // FIXME: We should expose some higher-level, safe abstractions inside the CGL module.
    unsafe {
        // Choose a pixel format.
        let attributes = [ kCGLPFADoubleBuffer, kCGLPFACompliant, 0 ];
        let pixel_format = null();
        let pixel_format_count = 1;
        let gl_error = CGLChoosePixelFormat(transmute(&attributes[0]),
                                            to_unsafe_ptr(&pixel_format),
                                            to_unsafe_ptr(&pixel_format_count));
        assert gl_error == kCGLNoError;

        // Create the context.
        let cgl_context = null();
        let gl_error = CGLCreateContext(pixel_format, null(), to_unsafe_ptr(&cgl_context));
        assert gl_error == kCGLNoError;

        // Set the context.
        let gl_error = CGLSetCurrentContext(cgl_context);
        assert gl_error == kCGLNoError;

        // Lock the context.
        let gl_error = CGLLockContext(cgl_context);
        assert gl_error == kCGLNoError;

        return cgl_context;
    }
}

pub fn init_surface(+size: Size2D<int>) -> IOSurface {
    use platform::core_foundation::boolean::{CFBooleanRef, CFBoolean};
    use platform::core_foundation::number::{CFNumberRef, CFNumber};
    use number = platform::core_foundation::number::CFNumber::new;
    use string = platform::core_foundation::string::CFString::wrap_extern;

    // TODO: dictionary constructor should be less ridiculous.
    // Or, we could add bindings for mutable dictionaries.
    let k_width = string(kIOSurfaceWidth);
    let v_width = number(size.width as i32);

    let k_height = string(kIOSurfaceHeight);
    let v_height = number(size.height as i32);

    let k_bytes_per_row = string(kIOSurfaceBytesPerRow);
    let v_bytes_per_row = number(size.width as i32 * 4);

    let k_bytes_per_elem = string(kIOSurfaceBytesPerElement);
    let v_bytes_per_elem = number(4i32);

    let k_is_global = string(kIOSurfaceIsGlobal);
    let v_is_global = CFBoolean::true_value();

    io_surface::new(&platform::core_foundation::dictionary::CFDictionary::new([
        (*k_width.borrow_ref(),          *v_width.borrow_type_ref()),
        (*k_height.borrow_ref(),         *v_height.borrow_type_ref()),
        (*k_bytes_per_row.borrow_ref(),  *v_bytes_per_row.borrow_type_ref()),
        (*k_bytes_per_elem.borrow_ref(), *v_bytes_per_elem.borrow_type_ref()),
        (*k_is_global.borrow_ref(),      *v_is_global.borrow_type_ref()),
    ]))
}

pub fn init_texture() -> GLuint {
    gl2::enable(TEXTURE_RECTANGLE_ARB);

    let texture = gl2::gen_textures(1)[0];
    gl2::bind_texture(TEXTURE_RECTANGLE_ARB, texture);
    gl2::tex_parameter_i(TEXTURE_RECTANGLE_ARB, TEXTURE_WRAP_S, CLAMP_TO_EDGE as GLint);
    gl2::tex_parameter_i(TEXTURE_RECTANGLE_ARB, TEXTURE_WRAP_T, CLAMP_TO_EDGE as GLint);
    gl2::tex_parameter_i(TEXTURE_RECTANGLE_ARB, TEXTURE_MAG_FILTER, LINEAR as GLint);
    gl2::tex_parameter_i(TEXTURE_RECTANGLE_ARB, TEXTURE_MIN_FILTER, NEAREST as GLint);
    return texture;
}

// Assumes the texture is already bound via gl2::bind_texture().
pub fn bind_surface_to_texture(context: &CGLContextObj, surface: &IOSurface, +size: Size2D<int>) {
    // FIXME: There should be safe wrappers for this.
    unsafe {
        let gl_error = CGLTexImageIOSurface2D(*context,
                                              TEXTURE_RECTANGLE_ARB,
                                              RGBA as GLenum,
                                              size.width as GLsizei,
                                              size.height as GLsizei,
                                              BGRA as GLenum,
                                              UNSIGNED_INT_8_8_8_8_REV,
                                              transmute(copy surface.obj),
                                              0);
        assert gl_error == kCGLNoError;
    }
}

pub fn bind_texture_to_framebuffer(texture: GLuint) {
    gl2::bind_texture(TEXTURE_RECTANGLE_ARB, 0);
    gl2::framebuffer_texture_2d(FRAMEBUFFER, COLOR_ATTACHMENT0, TEXTURE_RECTANGLE_ARB, texture, 0);
    assert gl2::check_framebuffer_status(FRAMEBUFFER) == FRAMEBUFFER_COMPLETE;
}

impl MacContext : ShareContext {
    static fn new(size: Size2D<int>) -> MacContext {
        // Initialize CGL.
        let context = init_cgl();

        // Create the surface.
        let surface = init_surface(copy size);

        // Create a framebuffer.
        let framebuffer = gl2::gen_framebuffers(1)[0];
        gl2::bind_framebuffer(FRAMEBUFFER, framebuffer);

        // Create and bind to the texture.
        let texture = init_texture();
        bind_surface_to_texture(&context, &surface, size);

        // Bind the texture to the framebuffer.
        bind_texture_to_framebuffer(texture);

        MacContext {
            surface: move surface,
            framebuffer: framebuffer,
            texture: texture
        }
    }

    fn flush(&self) {
        gl2::finish();
    }

    fn id() -> int {
        self.surface.get_id() as int
    }
}

<commit_msg>Upgrade Rust<commit_after>pub extern mod core_foundation;
pub extern mod io_surface;
pub extern mod opengles;

use mod platform::opengles::cgl;
use mod platform::opengles::gl2;

use core::cast::transmute;
use core::ptr::{null, to_unsafe_ptr};
use geom::size::Size2D;
use platform::io_surface::{IOSurface, kIOSurfaceBytesPerElement, kIOSurfaceBytesPerRow};
use platform::io_surface::{kIOSurfaceHeight, kIOSurfaceIsGlobal, kIOSurfaceWidth};
use platform::opengles::cgl::{CGLChoosePixelFormat, CGLContextObj, CGLCreateContext};
use platform::opengles::cgl::{CGLLockContext, CGLSetCurrentContext, CGLTexImageIOSurface2D};
use platform::opengles::cgl::{kCGLNoError, kCGLPFACompliant, kCGLPFADoubleBuffer};
use platform::opengles::gl2::{BGRA, CLAMP_TO_EDGE, COLOR_ATTACHMENT0, FRAMEBUFFER};
use platform::opengles::gl2::{FRAMEBUFFER_COMPLETE, GLenum, GLint, GLsizei, GLuint, LINEAR};
use platform::opengles::gl2::{NEAREST, RGBA, TEXTURE_MAG_FILTER, TEXTURE_MIN_FILTER};
use platform::opengles::gl2::{TEXTURE_RECTANGLE_ARB, TEXTURE_WRAP_S, TEXTURE_WRAP_T};
use platform::opengles::gl2::{UNSIGNED_INT_8_8_8_8_REV};

use base::ShareContext;

// FIXME: This is not good.
#[link_args="-framework IOSurface -framework CoreFoundation"]
#[nolink]
extern {}

pub type Context = MacContext;

pub struct MacContext {
    surface: IOSurface,
    framebuffer: GLuint,
    texture: GLuint

    // FIXME: Needs drop.
}

pub fn init_cgl() -> CGLContextObj {
    // FIXME: We should expose some higher-level, safe abstractions inside the CGL module.
    unsafe {
        // Choose a pixel format.
        let attributes = [ kCGLPFADoubleBuffer, kCGLPFACompliant, 0 ];
        let pixel_format = null();
        let pixel_format_count = 1;
        let gl_error = CGLChoosePixelFormat(transmute(&attributes[0]),
                                            to_unsafe_ptr(&pixel_format),
                                            to_unsafe_ptr(&pixel_format_count));
        assert gl_error == kCGLNoError;

        // Create the context.
        let cgl_context = null();
        let gl_error = CGLCreateContext(pixel_format, null(), to_unsafe_ptr(&cgl_context));
        assert gl_error == kCGLNoError;

        // Set the context.
        let gl_error = CGLSetCurrentContext(cgl_context);
        assert gl_error == kCGLNoError;

        // Lock the context.
        let gl_error = CGLLockContext(cgl_context);
        assert gl_error == kCGLNoError;

        return cgl_context;
    }
}

pub fn init_surface(+size: Size2D<int>) -> IOSurface {
    use platform::core_foundation::boolean::{CFBooleanRef, CFBoolean};
    use platform::core_foundation::number::{CFNumberRef, CFNumber};
    use number = platform::core_foundation::number::CFNumber::new;
    use string = platform::core_foundation::string::CFString::wrap_extern;

    // TODO: dictionary constructor should be less ridiculous.
    // Or, we could add bindings for mutable dictionaries.
    let k_width = string(kIOSurfaceWidth);
    let v_width = number(size.width as i32);

    let k_height = string(kIOSurfaceHeight);
    let v_height = number(size.height as i32);

    let k_bytes_per_row = string(kIOSurfaceBytesPerRow);
    let v_bytes_per_row = number(size.width as i32 * 4);

    let k_bytes_per_elem = string(kIOSurfaceBytesPerElement);
    let v_bytes_per_elem = number(4i32);

    let k_is_global = string(kIOSurfaceIsGlobal);
    let v_is_global = CFBoolean::true_value();

    io_surface::new(&core_foundation::dictionary::CFDictionary::new([
        (*k_width.borrow_ref(),          *v_width.borrow_type_ref()),
        (*k_height.borrow_ref(),         *v_height.borrow_type_ref()),
        (*k_bytes_per_row.borrow_ref(),  *v_bytes_per_row.borrow_type_ref()),
        (*k_bytes_per_elem.borrow_ref(), *v_bytes_per_elem.borrow_type_ref()),
        (*k_is_global.borrow_ref(),      *v_is_global.borrow_type_ref()),
    ]))
}

pub fn init_texture() -> GLuint {
    gl2::enable(TEXTURE_RECTANGLE_ARB);

    let texture = gl2::gen_textures(1)[0];
    gl2::bind_texture(TEXTURE_RECTANGLE_ARB, texture);
    gl2::tex_parameter_i(TEXTURE_RECTANGLE_ARB, TEXTURE_WRAP_S, CLAMP_TO_EDGE as GLint);
    gl2::tex_parameter_i(TEXTURE_RECTANGLE_ARB, TEXTURE_WRAP_T, CLAMP_TO_EDGE as GLint);
    gl2::tex_parameter_i(TEXTURE_RECTANGLE_ARB, TEXTURE_MAG_FILTER, LINEAR as GLint);
    gl2::tex_parameter_i(TEXTURE_RECTANGLE_ARB, TEXTURE_MIN_FILTER, NEAREST as GLint);
    return texture;
}

// Assumes the texture is already bound via gl2::bind_texture().
pub fn bind_surface_to_texture(context: &CGLContextObj, surface: &IOSurface, +size: Size2D<int>) {
    // FIXME: There should be safe wrappers for this.
    unsafe {
        let gl_error = CGLTexImageIOSurface2D(*context,
                                              TEXTURE_RECTANGLE_ARB,
                                              RGBA as GLenum,
                                              size.width as GLsizei,
                                              size.height as GLsizei,
                                              BGRA as GLenum,
                                              UNSIGNED_INT_8_8_8_8_REV,
                                              transmute(copy surface.obj),
                                              0);
        assert gl_error == kCGLNoError;
    }
}

pub fn bind_texture_to_framebuffer(texture: GLuint) {
    gl2::bind_texture(TEXTURE_RECTANGLE_ARB, 0);
    gl2::framebuffer_texture_2d(FRAMEBUFFER, COLOR_ATTACHMENT0, TEXTURE_RECTANGLE_ARB, texture, 0);
    assert gl2::check_framebuffer_status(FRAMEBUFFER) == FRAMEBUFFER_COMPLETE;
}

impl MacContext : ShareContext {
    static fn new(size: Size2D<int>) -> MacContext {
        // Initialize CGL.
        let context = init_cgl();

        // Create the surface.
        let surface = init_surface(copy size);

        // Create a framebuffer.
        let framebuffer = gl2::gen_framebuffers(1)[0];
        gl2::bind_framebuffer(FRAMEBUFFER, framebuffer);

        // Create and bind to the texture.
        let texture = init_texture();
        bind_surface_to_texture(&context, &surface, size);

        // Bind the texture to the framebuffer.
        bind_texture_to_framebuffer(texture);

        MacContext {
            surface: move surface,
            framebuffer: framebuffer,
            texture: texture
        }
    }

    fn flush(&self) {
        gl2::finish();
    }

    fn id() -> int {
        self.surface.get_id() as int
    }
}

<|endoftext|>


<commit_before>extern crate id_tree;

use id_tree::NodeIdError;
use id_tree::Node;
use id_tree::TreeBuilder;
use id_tree::Tree;
use id_tree::RemoveBehavior;
use id_tree::MoveBehavior;
use id_tree::InsertBehavior;
use id_tree::SwapBehavior;

#[test]
fn test_old_node_id() {
    let mut tree: Tree<i32> = TreeBuilder::new().build();

    let root_node = Node::new(1);

    let root_id = tree.insert(root_node, InsertBehavior::AsRoot).ok().unwrap();
    let root_id_copy = root_id.clone(); // this is essential to getting the Result::Err()

    let root_node = tree.remove_node(root_id, RemoveBehavior::OrphanChildren);
    assert!(root_node.is_ok());

    let root_node_again = tree.remove_node(root_id_copy, RemoveBehavior::OrphanChildren);
    assert!(root_node_again.is_err());

    let error = root_node_again.err().unwrap();
    assert_eq!(error, NodeIdError::NodeIdNoLongerValid);
}

#[test]
fn test_get_node_from_other_tree() {
    let mut tree_a: Tree<i32> = TreeBuilder::new().build();
    let tree_b: Tree<i32> = TreeBuilder::new().build();

    let root_node_a = Node::new(1);
    let root_node_id_a = tree_a.insert(root_node_a, InsertBehavior::AsRoot).unwrap();

    let root_node_a = tree_a.get(&root_node_id_a);
    let root_node_b = tree_b.get(&root_node_id_a); //note use of wrong tree

    assert!(root_node_a.is_ok());
    assert!(root_node_b.is_err());
    assert_eq!(root_node_b.err().unwrap(),
               NodeIdError::InvalidNodeIdForTree);
}

#[test]
fn test_get_mut_node_from_other_tree() {
    let mut tree_a: Tree<i32> = TreeBuilder::new().build();
    let mut tree_b: Tree<i32> = TreeBuilder::new().build();

    let root_node_a = Node::new(1);
    let root_node_id_a = tree_a.insert(root_node_a, InsertBehavior::AsRoot).unwrap();

    let root_node_a = tree_a.get_mut(&root_node_id_a);
    let root_node_b = tree_b.get_mut(&root_node_id_a); //note use of wrong tree

    assert!(root_node_a.is_ok());
    assert!(root_node_b.is_err());
    assert_eq!(root_node_b.err().unwrap(),
               NodeIdError::InvalidNodeIdForTree);
}

#[test]
fn test_remove_node_lift_children_from_other_tree() {
    let mut tree_a: Tree<i32> = TreeBuilder::new().build();
    let mut tree_b: Tree<i32> = TreeBuilder::new().build();

    let root_node_id_a = tree_a.insert(Node::new(1), InsertBehavior::AsRoot).unwrap();

    // note use of wrong tree
    let root_node_b = tree_b.remove_node(root_node_id_a, RemoveBehavior::LiftChildren);
    assert!(root_node_b.is_err());

    let error = root_node_b.err().unwrap();
    assert_eq!(error, NodeIdError::InvalidNodeIdForTree);
}

#[test]
fn test_remove_node_orphan_children_from_other_tree() {
    let mut tree_a: Tree<i32> = TreeBuilder::new().build();
    let mut tree_b: Tree<i32> = TreeBuilder::new().build();

    let root_node_id_a = tree_a.insert(Node::new(1), InsertBehavior::AsRoot).unwrap();

    // note use of wrong tree
    let root_node_b = tree_b.remove_node(root_node_id_a, RemoveBehavior::OrphanChildren);
    assert!(root_node_b.is_err());

    let error = root_node_b.err().unwrap();
    assert_eq!(error, NodeIdError::InvalidNodeIdForTree);
}

#[test]
fn test_remove_node_remove_children_from_other_tree() {
    let mut tree_a: Tree<i32> = TreeBuilder::new().build();
    let mut tree_b: Tree<i32> = TreeBuilder::new().build();

    let root_node_id_a = tree_a.insert(Node::new(1), InsertBehavior::AsRoot).unwrap();

    // note use of wrong tree
    let root_node_b = tree_b.remove_node(root_node_id_a, RemoveBehavior::DropChildren);
    assert!(root_node_b.is_err());

    let error = root_node_b.err().unwrap();
    assert_eq!(error, NodeIdError::InvalidNodeIdForTree);
}

#[test]
fn test_move_node_into_other_tree() {
    let mut tree_a: Tree<i32> = TreeBuilder::new().build();
    let mut tree_b: Tree<i32> = TreeBuilder::new().build();

    let root_node_a = Node::new(1);
    let root_node_id_a = tree_a.insert(root_node_a, InsertBehavior::AsRoot).unwrap();

    let root_node_b = Node::new(1);
    let root_node_id_b = tree_b.insert(root_node_b, InsertBehavior::AsRoot).unwrap();

    // note use of invalid parent
    let result = tree_a.move_node(&root_node_id_a, MoveBehavior::ToParent(&root_node_id_b));
    assert!(result.is_err());

    let error = result.err().unwrap();
    assert_eq!(error, NodeIdError::InvalidNodeIdForTree);
}

#[test]
fn test_move_node_from_other_tree() {
    let mut tree_a: Tree<i32> = TreeBuilder::new().build();
    let mut tree_b: Tree<i32> = TreeBuilder::new().build();

    let root_node_a = Node::new(1);
    let root_node_id_a = tree_a.insert(root_node_a, InsertBehavior::AsRoot).unwrap();

    let root_node_b = Node::new(1);
    let root_node_id_b = tree_b.insert(root_node_b, InsertBehavior::AsRoot).unwrap();

    // note use of invalid child
    let result = tree_a.move_node(&root_node_id_b, MoveBehavior::ToParent(&root_node_id_a));
    assert!(result.is_err());

    let error = result.err().unwrap();
    assert_eq!(error, NodeIdError::InvalidNodeIdForTree);
}

#[test]
fn test_move_node_to_root_by_invalid_id() {
    let mut tree_a: Tree<i32> = TreeBuilder::new().build();
    let mut tree_b: Tree<i32> = TreeBuilder::new().build();

    let root_node_a = Node::new(1);
    let _ = tree_a.insert(root_node_a, InsertBehavior::AsRoot).unwrap();

    let root_node_b = Node::new(1);
    let root_node_id_b = tree_b.insert(root_node_b, InsertBehavior::AsRoot).unwrap();

    let result = tree_a.move_node(&root_node_id_b, MoveBehavior::ToRoot);
    assert!(result.is_err());

    let error = result.err().unwrap();
    assert_eq!(error, NodeIdError::InvalidNodeIdForTree);
}

#[test]
fn test_sort_by_invalid_id() {
    let mut tree_a: Tree<i32> = TreeBuilder::new().build();
    let mut tree_b: Tree<i32> = TreeBuilder::new().build();

    let root_node_a = Node::new(1);
    let _ = tree_a.insert(root_node_a, InsertBehavior::AsRoot).unwrap();

    let root_node_b = Node::new(1);
    let root_node_id_b = tree_b.insert(root_node_b, InsertBehavior::AsRoot).unwrap();

    let result = tree_a.sort_children_by(&root_node_id_b, |a, b| a.data().cmp(b.data()));
    assert!(result.is_err());

    let error = result.err().unwrap();
    assert_eq!(error, NodeIdError::InvalidNodeIdForTree);
}

#[test]
fn test_sort_by_data_invalid_id() {
    let mut tree_a: Tree<i32> = TreeBuilder::new().build();
    let mut tree_b: Tree<i32> = TreeBuilder::new().build();

    let root_node_a = Node::new(1);
    let _ = tree_a.insert(root_node_a, InsertBehavior::AsRoot).unwrap();

    let root_node_b = Node::new(1);
    let root_node_id_b = tree_b.insert(root_node_b, InsertBehavior::AsRoot).unwrap();

    let result = tree_a.sort_children_by_data(&root_node_id_b);
    assert!(result.is_err());

    let error = result.err().unwrap();
    assert_eq!(error, NodeIdError::InvalidNodeIdForTree);
}

#[test]
fn test_sort_by_key_invalid_id() {
    let mut tree_a: Tree<i32> = TreeBuilder::new().build();
    let mut tree_b: Tree<i32> = TreeBuilder::new().build();

    let root_node_a = Node::new(1);
    let _ = tree_a.insert(root_node_a, InsertBehavior::AsRoot).unwrap();

    let root_node_b = Node::new(1);
    let root_node_id_b = tree_b.insert(root_node_b, InsertBehavior::AsRoot).unwrap();

    let result = tree_a.sort_children_by_key(&root_node_id_b, |x| x.data().clone());
    assert!(result.is_err());

    let error = result.err().unwrap();
    assert_eq!(error, NodeIdError::InvalidNodeIdForTree);
}

#[test]
fn test_swap_sub_trees_of_different_trees() {
    let mut tree_a: Tree<i32> = TreeBuilder::new().build();
    let mut tree_b: Tree<i32> = TreeBuilder::new().build();

    let root_node_a = Node::new(1);
    let root_node_id_a = tree_a.insert(root_node_a, InsertBehavior::AsRoot).unwrap();

    let root_node_b = Node::new(1);
    let root_node_id_b = tree_b.insert(root_node_b, InsertBehavior::AsRoot).unwrap();

    // note use of invalid child
    let result = tree_a.swap_nodes(&root_node_id_b, &root_node_id_a, SwapBehavior::TakeChildren);
    assert!(result.is_err());

    let error = result.err().unwrap();
    assert_eq!(error, NodeIdError::InvalidNodeIdForTree);
}

#[test]
fn test_ancestors_different_trees() {
    let mut a = Tree::new();
    let b = Tree::<i32>::new();

    let root_id = a.insert(Node::new(1), InsertBehavior::AsRoot).unwrap();

    // note usage of `b` instead of `a`
    let ancestors = b.ancestors(&root_id);

    assert!(ancestors.is_err());
    let error = ancestors.err().unwrap();
    assert_eq!(error, NodeIdError::InvalidNodeIdForTree);
}

#[test]
fn test_ancestors_old_id() {
    let mut a = Tree::new();

    let root_id = a.insert(Node::new(1), InsertBehavior::AsRoot).unwrap();
    // `.clone()` required to get this error
    let root_id_clone = root_id.clone();
    let _ = a.remove_node(root_id, RemoveBehavior::DropChildren).unwrap();

    // note usage of cloned `NodeId`
    let ancestors = a.ancestors(&root_id_clone);

    assert!(ancestors.is_err());
    let error = ancestors.err().unwrap();
    assert_eq!(error, NodeIdError::NodeIdNoLongerValid);
}
<commit_msg>add more iterator tests<commit_after>extern crate id_tree;

use id_tree::NodeIdError;
use id_tree::Node;
use id_tree::TreeBuilder;
use id_tree::Tree;
use id_tree::RemoveBehavior;
use id_tree::MoveBehavior;
use id_tree::InsertBehavior;
use id_tree::SwapBehavior;

#[test]
fn test_old_node_id() {
    let mut tree: Tree<i32> = TreeBuilder::new().build();

    let root_node = Node::new(1);

    let root_id = tree.insert(root_node, InsertBehavior::AsRoot).ok().unwrap();
    let root_id_copy = root_id.clone(); // this is essential to getting the Result::Err()

    let root_node = tree.remove_node(root_id, RemoveBehavior::OrphanChildren);
    assert!(root_node.is_ok());

    let root_node_again = tree.remove_node(root_id_copy, RemoveBehavior::OrphanChildren);
    assert!(root_node_again.is_err());

    let error = root_node_again.err().unwrap();
    assert_eq!(error, NodeIdError::NodeIdNoLongerValid);
}

#[test]
fn test_get_node_from_other_tree() {
    let mut tree_a: Tree<i32> = TreeBuilder::new().build();
    let tree_b: Tree<i32> = TreeBuilder::new().build();

    let root_node_a = Node::new(1);
    let root_node_id_a = tree_a.insert(root_node_a, InsertBehavior::AsRoot).unwrap();

    let root_node_a = tree_a.get(&root_node_id_a);
    let root_node_b = tree_b.get(&root_node_id_a); //note use of wrong tree

    assert!(root_node_a.is_ok());
    assert!(root_node_b.is_err());
    assert_eq!(root_node_b.err().unwrap(),
               NodeIdError::InvalidNodeIdForTree);
}

#[test]
fn test_get_mut_node_from_other_tree() {
    let mut tree_a: Tree<i32> = TreeBuilder::new().build();
    let mut tree_b: Tree<i32> = TreeBuilder::new().build();

    let root_node_a = Node::new(1);
    let root_node_id_a = tree_a.insert(root_node_a, InsertBehavior::AsRoot).unwrap();

    let root_node_a = tree_a.get_mut(&root_node_id_a);
    let root_node_b = tree_b.get_mut(&root_node_id_a); //note use of wrong tree

    assert!(root_node_a.is_ok());
    assert!(root_node_b.is_err());
    assert_eq!(root_node_b.err().unwrap(),
               NodeIdError::InvalidNodeIdForTree);
}

#[test]
fn test_remove_node_lift_children_from_other_tree() {
    let mut tree_a: Tree<i32> = TreeBuilder::new().build();
    let mut tree_b: Tree<i32> = TreeBuilder::new().build();

    let root_node_id_a = tree_a.insert(Node::new(1), InsertBehavior::AsRoot).unwrap();

    // note use of wrong tree
    let root_node_b = tree_b.remove_node(root_node_id_a, RemoveBehavior::LiftChildren);
    assert!(root_node_b.is_err());

    let error = root_node_b.err().unwrap();
    assert_eq!(error, NodeIdError::InvalidNodeIdForTree);
}

#[test]
fn test_remove_node_orphan_children_from_other_tree() {
    let mut tree_a: Tree<i32> = TreeBuilder::new().build();
    let mut tree_b: Tree<i32> = TreeBuilder::new().build();

    let root_node_id_a = tree_a.insert(Node::new(1), InsertBehavior::AsRoot).unwrap();

    // note use of wrong tree
    let root_node_b = tree_b.remove_node(root_node_id_a, RemoveBehavior::OrphanChildren);
    assert!(root_node_b.is_err());

    let error = root_node_b.err().unwrap();
    assert_eq!(error, NodeIdError::InvalidNodeIdForTree);
}

#[test]
fn test_remove_node_remove_children_from_other_tree() {
    let mut tree_a: Tree<i32> = TreeBuilder::new().build();
    let mut tree_b: Tree<i32> = TreeBuilder::new().build();

    let root_node_id_a = tree_a.insert(Node::new(1), InsertBehavior::AsRoot).unwrap();

    // note use of wrong tree
    let root_node_b = tree_b.remove_node(root_node_id_a, RemoveBehavior::DropChildren);
    assert!(root_node_b.is_err());

    let error = root_node_b.err().unwrap();
    assert_eq!(error, NodeIdError::InvalidNodeIdForTree);
}

#[test]
fn test_move_node_into_other_tree() {
    let mut tree_a: Tree<i32> = TreeBuilder::new().build();
    let mut tree_b: Tree<i32> = TreeBuilder::new().build();

    let root_node_a = Node::new(1);
    let root_node_id_a = tree_a.insert(root_node_a, InsertBehavior::AsRoot).unwrap();

    let root_node_b = Node::new(1);
    let root_node_id_b = tree_b.insert(root_node_b, InsertBehavior::AsRoot).unwrap();

    // note use of invalid parent
    let result = tree_a.move_node(&root_node_id_a, MoveBehavior::ToParent(&root_node_id_b));
    assert!(result.is_err());

    let error = result.err().unwrap();
    assert_eq!(error, NodeIdError::InvalidNodeIdForTree);
}

#[test]
fn test_move_node_from_other_tree() {
    let mut tree_a: Tree<i32> = TreeBuilder::new().build();
    let mut tree_b: Tree<i32> = TreeBuilder::new().build();

    let root_node_a = Node::new(1);
    let root_node_id_a = tree_a.insert(root_node_a, InsertBehavior::AsRoot).unwrap();

    let root_node_b = Node::new(1);
    let root_node_id_b = tree_b.insert(root_node_b, InsertBehavior::AsRoot).unwrap();

    // note use of invalid child
    let result = tree_a.move_node(&root_node_id_b, MoveBehavior::ToParent(&root_node_id_a));
    assert!(result.is_err());

    let error = result.err().unwrap();
    assert_eq!(error, NodeIdError::InvalidNodeIdForTree);
}

#[test]
fn test_move_node_to_root_by_invalid_id() {
    let mut tree_a: Tree<i32> = TreeBuilder::new().build();
    let mut tree_b: Tree<i32> = TreeBuilder::new().build();

    let root_node_a = Node::new(1);
    let _ = tree_a.insert(root_node_a, InsertBehavior::AsRoot).unwrap();

    let root_node_b = Node::new(1);
    let root_node_id_b = tree_b.insert(root_node_b, InsertBehavior::AsRoot).unwrap();

    let result = tree_a.move_node(&root_node_id_b, MoveBehavior::ToRoot);
    assert!(result.is_err());

    let error = result.err().unwrap();
    assert_eq!(error, NodeIdError::InvalidNodeIdForTree);
}

#[test]
fn test_sort_by_invalid_id() {
    let mut tree_a: Tree<i32> = TreeBuilder::new().build();
    let mut tree_b: Tree<i32> = TreeBuilder::new().build();

    let root_node_a = Node::new(1);
    let _ = tree_a.insert(root_node_a, InsertBehavior::AsRoot).unwrap();

    let root_node_b = Node::new(1);
    let root_node_id_b = tree_b.insert(root_node_b, InsertBehavior::AsRoot).unwrap();

    let result = tree_a.sort_children_by(&root_node_id_b, |a, b| a.data().cmp(b.data()));
    assert!(result.is_err());

    let error = result.err().unwrap();
    assert_eq!(error, NodeIdError::InvalidNodeIdForTree);
}

#[test]
fn test_sort_by_data_invalid_id() {
    let mut tree_a: Tree<i32> = TreeBuilder::new().build();
    let mut tree_b: Tree<i32> = TreeBuilder::new().build();

    let root_node_a = Node::new(1);
    let _ = tree_a.insert(root_node_a, InsertBehavior::AsRoot).unwrap();

    let root_node_b = Node::new(1);
    let root_node_id_b = tree_b.insert(root_node_b, InsertBehavior::AsRoot).unwrap();

    let result = tree_a.sort_children_by_data(&root_node_id_b);
    assert!(result.is_err());

    let error = result.err().unwrap();
    assert_eq!(error, NodeIdError::InvalidNodeIdForTree);
}

#[test]
fn test_sort_by_key_invalid_id() {
    let mut tree_a: Tree<i32> = TreeBuilder::new().build();
    let mut tree_b: Tree<i32> = TreeBuilder::new().build();

    let root_node_a = Node::new(1);
    let _ = tree_a.insert(root_node_a, InsertBehavior::AsRoot).unwrap();

    let root_node_b = Node::new(1);
    let root_node_id_b = tree_b.insert(root_node_b, InsertBehavior::AsRoot).unwrap();

    let result = tree_a.sort_children_by_key(&root_node_id_b, |x| x.data().clone());
    assert!(result.is_err());

    let error = result.err().unwrap();
    assert_eq!(error, NodeIdError::InvalidNodeIdForTree);
}

#[test]
fn test_swap_sub_trees_of_different_trees() {
    let mut tree_a: Tree<i32> = TreeBuilder::new().build();
    let mut tree_b: Tree<i32> = TreeBuilder::new().build();

    let root_node_a = Node::new(1);
    let root_node_id_a = tree_a.insert(root_node_a, InsertBehavior::AsRoot).unwrap();

    let root_node_b = Node::new(1);
    let root_node_id_b = tree_b.insert(root_node_b, InsertBehavior::AsRoot).unwrap();

    // note use of invalid child
    let result = tree_a.swap_nodes(&root_node_id_b, &root_node_id_a, SwapBehavior::TakeChildren);
    assert!(result.is_err());

    let error = result.err().unwrap();
    assert_eq!(error, NodeIdError::InvalidNodeIdForTree);
}

#[test]
fn test_ancestors_different_trees() {
    let mut a = Tree::new();
    let b = Tree::<i32>::new();

    let root_id = a.insert(Node::new(1), InsertBehavior::AsRoot).unwrap();

    // note usage of `b` instead of `a`
    let ancestors = b.ancestors(&root_id);

    assert!(ancestors.is_err());
    let error = ancestors.err().unwrap();
    assert_eq!(error, NodeIdError::InvalidNodeIdForTree);
}

#[test]
fn test_ancestors_old_id() {
    let mut a = Tree::new();

    let root_id = a.insert(Node::new(1), InsertBehavior::AsRoot).unwrap();
    // `.clone()` required to get this error
    let root_id_clone = root_id.clone();
    let _ = a.remove_node(root_id, RemoveBehavior::DropChildren).unwrap();

    // note usage of cloned `NodeId`
    let ancestors = a.ancestors(&root_id_clone);

    assert!(ancestors.is_err());
    let error = ancestors.err().unwrap();
    assert_eq!(error, NodeIdError::NodeIdNoLongerValid);
}

#[test]
fn test_ancestor_ids_different_trees() {
    let mut a = Tree::new();
    let b = Tree::<i32>::new();

    let root_id = a.insert(Node::new(1), InsertBehavior::AsRoot).unwrap();

    // note usage of `b` instead of `a`
    let ancestors = b.ancestor_ids(&root_id);

    assert!(ancestors.is_err());
    let error = ancestors.err().unwrap();
    assert_eq!(error, NodeIdError::InvalidNodeIdForTree);
}

#[test]
fn test_ancestor_ids_old_id() {
    let mut a = Tree::new();

    let root_id = a.insert(Node::new(1), InsertBehavior::AsRoot).unwrap();
    // `.clone()` required to get this error
    let root_id_clone = root_id.clone();
    let _ = a.remove_node(root_id, RemoveBehavior::DropChildren).unwrap();

    // note usage of cloned `NodeId`
    let ancestors = a.ancestor_ids(&root_id_clone);

    assert!(ancestors.is_err());
    let error = ancestors.err().unwrap();
    assert_eq!(error, NodeIdError::NodeIdNoLongerValid);
}

#[test]
fn test_children_different_trees() {
    let mut a = Tree::new();
    let b = Tree::<i32>::new();

    let root_id = a.insert(Node::new(1), InsertBehavior::AsRoot).unwrap();

    // note usage of `b` instead of `a`
    let ancestors = b.children(&root_id);

    assert!(ancestors.is_err());
    let error = ancestors.err().unwrap();
    assert_eq!(error, NodeIdError::InvalidNodeIdForTree);
}

#[test]
fn test_children_old_id() {
    let mut a = Tree::new();

    let root_id = a.insert(Node::new(1), InsertBehavior::AsRoot).unwrap();
    // `.clone()` required to get this error
    let root_id_clone = root_id.clone();
    let _ = a.remove_node(root_id, RemoveBehavior::DropChildren).unwrap();

    // note usage of cloned `NodeId`
    let ancestors = a.children(&root_id_clone);

    assert!(ancestors.is_err());
    let error = ancestors.err().unwrap();
    assert_eq!(error, NodeIdError::NodeIdNoLongerValid);
}

#[test]
fn test_children_ids_different_trees() {
    let mut a = Tree::new();
    let b = Tree::<i32>::new();

    let root_id = a.insert(Node::new(1), InsertBehavior::AsRoot).unwrap();

    // note usage of `b` instead of `a`
    let ancestors = b.children_ids(&root_id);

    assert!(ancestors.is_err());
    let error = ancestors.err().unwrap();
    assert_eq!(error, NodeIdError::InvalidNodeIdForTree);
}

#[test]
fn test_children_ids_old_id() {
    let mut a = Tree::new();

    let root_id = a.insert(Node::new(1), InsertBehavior::AsRoot).unwrap();
    // `.clone()` required to get this error
    let root_id_clone = root_id.clone();
    let _ = a.remove_node(root_id, RemoveBehavior::DropChildren).unwrap();

    // note usage of cloned `NodeId`
    let ancestors = a.children_ids(&root_id_clone);

    assert!(ancestors.is_err());
    let error = ancestors.err().unwrap();
    assert_eq!(error, NodeIdError::NodeIdNoLongerValid);
}
<|endoftext|>