<commit_before>use base64;
use r2pipe::{R2Pipe, R2};
use radeco_lib::analysis::analyzer::{FuncAnalyzer, ModuleAnalyzer};
use radeco_lib::analysis::cse::cse::CSE;
use radeco_lib::analysis::inst_combine::Combiner;
use radeco_lib::analysis::functions::infer_regusage::Inferer;
use radeco_lib::analysis::functions::fix_ssa_opcalls::CallSiteFixer;
use radeco_lib::analysis::interproc::fixcall::CallFixer;
use radeco_lib::analysis::dce::DCE;
use radeco_lib::analysis::sccp::SCCP;
use radeco_lib::backend::lang_c::c_cfg::ctrl_flow_struct;
use radeco_lib::backend::lang_c::c_cfg::CCFGVerifier;
use radeco_lib::backend::lang_c::c_cfg_builder;
use radeco_lib::frontend::radeco_containers::*;
use radeco_lib::middle::ir_writer;
use radeco_lib::middle::regfile::SubRegisterFile;
use radeco_lib::middle::ssa::ssastorage::SSAStorage;
use radeco_lib::middle::ssa::verifier;
use radeco_lib::middle::dot;
use std::cell::RefCell;
use std::collections::HashMap;
use std::panic;
use std::rc::Rc;
use std::str;
use std::sync::Arc;

thread_local!(pub static PROJ: RefCell<Option<RadecoProject>> = RefCell::new(None););

pub fn fn_list(proj: &RadecoProject) -> Vec<String> {
    proj.iter()
        .map(|i| i.module)
        .flat_map(|rmod| rmod.functions.values())
        .map(|s| s.name.to_string())
        .collect()
}

pub fn get_function<'a>(name: &str, proj: &'a RadecoProject) -> Option<&'a RadecoFunction> {
    proj.iter()
        .map(|i| i.module)
        .flat_map(|rmod| rmod.functions.values())
        .filter(|rfn| rfn.name == name)
        .next()
}

pub fn get_function_mut<'a>(
    name: &str,
    proj: &'a mut RadecoProject,
) -> Option<&'a mut RadecoFunction> {
    proj.iter_mut()
        .map(|i| i.module)
        .flat_map(|rmod| rmod.functions.values_mut())
        .filter(|rfn| rfn.name == name)
        .next()
}

pub fn fn_rename(old_f: &str, new_f: &str, proj: &mut RadecoProject) {
    if let Some(_) = get_function(new_f, proj) {
        println!("there is already a function called: {}", new_f);
        return;
    }

    let mut found = false;

    for module in proj.iter_mut() {
        let module = module.module;
        let off = module.iter()
            .find(|rfn| rfn.function.1.name == old_f)
            .map(|rfn| rfn.function.1.offset);

        if let Some(off) = off {
            module.function_rename(off, new_f);
            found = true;
        }
    }

    if !found {
        println!("function not found: {}", old_f);
    }
}

pub fn analyze_mod(regfile: Arc<SubRegisterFile>, rmod: &mut RadecoModule) {
    // Analyze preserved for all functions.
    {
        eprintln!("[*] Fixing Callee Information");
        let bp_name = regfile.get_name_by_alias(&"BP".to_string());
        let bp_name = bp_name.map(|s| s.to_owned());
        let sp_name = regfile.get_name_by_alias(&"SP".to_string());
        let sp_name = sp_name.map(|s| s.to_owned());
        let mut callfixer = CallFixer::new(rmod, bp_name, sp_name);
        callfixer.rounded_analysis();
    }

    // Fix call sites
    let mut call_site_fixer = CallSiteFixer::new();
    call_site_fixer.analyze(rmod);

    // Infer calling conventions
    let mut inferer = Inferer::new((*regfile).clone());
    inferer.analyze(rmod);
}

pub fn analyze(rfn: &mut RadecoFunction) {
    eprintln!("[+] Analyzing: {} @ {:#x}", rfn.name, rfn.offset);
    {
        eprintln!("  [*] Eliminating Dead Code");
        let mut dce = DCE::new();
        dce.analyze(rfn);
    }
    {
        // Constant Propagation (sccp)
        eprintln!("  [*] Propagating Constants");
        let mut sccp = SCCP::new();
        sccp.analyze(rfn);
    }
    {
        eprintln!("  [*] Eliminating More DeadCode");
        let mut dce = DCE::new();
        dce.analyze(rfn);
    }
    {
        // Instruction combiner
        let mut combiner = Combiner::new();
        combiner.analyze(rfn);
    }
    {
        // Common SubExpression Elimination (cse)
        eprintln!("  [*] Eliminating Common SubExpressions");
        let mut cse = CSE::new();
        cse.analyze(rfn);
    }
    {
        // Verify SSA
        eprintln!("  [*] Verifying SSA's Validity");
        match verifier::verify(rfn.ssa()) {
            Err(e) => {
                eprintln!("  [*] Found Error: {}", e);
            }
            Ok(_) => {}
        }
    }
}

pub fn analyze_all_functions<'a>(proj: &'a mut RadecoProject) {
    let rfns = proj
        .iter_mut()
        .map(|i| i.module)
        .flat_map(|rmod| rmod.functions.values_mut());
    for rfn in rfns {
        analyze(rfn);
    }
}

pub fn emit_ir(rfn: &RadecoFunction) -> String {
    eprintln!("  [*] Writing out IR");
    let mut res = String::new();
    ir_writer::emit_il(&mut res, Some(rfn.name.to_string()), rfn.ssa()).unwrap();
    res
}

pub fn emit_dot(ssa: &SSAStorage) -> String {
    dot::emit_dot(ssa)
}

pub fn decompile_all_functions<'a>(proj: &'a RadecoProject) -> String {
    let mut decompiled_funcs = Vec::new();
    let funcs = fn_list(&proj);
    for f in &funcs {
        match decompile(f, &proj) {
            Ok(res) => {
                decompiled_funcs.push(res);
            }
            Err(err) => {
                eprintln!("{}", err);
            }
        };
    }
    decompiled_funcs.join("\n")
}

pub fn decompile<'a>(name: &str, proj: &'a RadecoProject) -> Result<String, String> {
    if let Some(rfn) = get_function(name, &proj) {
        let rmod = proj.iter().map(|i| i.module).next().unwrap();
        let func_name_map = func_names(&rmod);
        let strings = strings(&rmod);
        decompile_priv(rfn, &func_name_map, &strings)
    } else {
        Err(format!("{} is not found.", name))
    }
}

fn decompile_priv(
    rfn: &RadecoFunction,
    func_name_map: &HashMap<u64, String>,
    strings: &HashMap<u64, String>,
) -> Result<String, String> {
    let c_cfg_result =
        panic::catch_unwind(|| c_cfg_builder::recover_c_cfg(rfn, func_name_map, strings));

    if c_cfg_result.is_err() {
        return Err("Failed to recover C control flow graph".to_string());
    };

    let c_cfg = c_cfg_result.unwrap();

    if let Err(err) = CCFGVerifier::verify(&c_cfg) {
        eprintln!("CCFG verification failed {}", err);
    }

    let result = panic::catch_unwind(|| {
        ctrl_flow_struct::structure_and_convert(c_cfg.clone())
            .map(|s| s.print())
            .map_err(|e| e.to_string())
    });
    match result {
        Ok(code) => code,
        Err(_) => {
            println!("Control flow structuring failed");
            Ok(c_cfg.to_c_ast().print())
        }
    }
}

pub fn load_proj_by_path(path: &str) -> RadecoProject {
    let mut p = ProjectLoader::new().path(path).load();
    let regfile = p.regfile().clone();
    for mut xy in p.iter_mut() {
        analyze_mod(regfile.clone(), xy.module);
    }
    p
}

pub fn load_proj_tcp(url: &str) -> Result<RadecoProject, &'static str> {
    let r2p = R2Pipe::tcp(url)?;
    Ok(load_project_by_r2pipe(r2p))
}

pub fn load_proj_http(url: &str) -> Result<RadecoProject, &'static str> {
    let r2p = R2Pipe::http(url)?;
    Ok(load_project_by_r2pipe(r2p))
}

pub fn load_project_by_r2pipe(r2p: R2Pipe) -> RadecoProject {
    let r2 = R2::from(r2p);
    let r2w = Rc::new(RefCell::new(r2));
    let mut p = ProjectLoader::new().source(Rc::new(r2w)).load();
    let regfile = p.regfile().clone();
    for mut xy in p.iter_mut() {
        analyze_mod(regfile.clone(), xy.module);
    }
    p
}

pub fn func_names(rmod: &RadecoModule) -> HashMap<u64, String> {
    rmod.functions
        .iter()
        .map(|(&addr, f)| (addr, f.name.to_string()))
        .collect()
}

pub fn strings(rmod: &RadecoModule) -> HashMap<u64, String> {
    rmod.strings()
        .iter()
        .filter(|ref s| s.paddr.is_some() && s.string.is_some())
        .cloned()
        .map(|s| {
            let (addr, _s) = (s.vaddr.unwrap(), s.string.unwrap());
            let bytes = base64::decode(&_s).unwrap_or(Vec::new());
            let ret_string = match str::from_utf8(bytes.as_slice()) {
                Ok(v) => v.to_string(),
                Err(_e) => _s,
            };
            (addr, ret_string)
        })
        .collect()
}
<commit_msg>Update to the new analyzer's api<commit_after>use base64;
use r2pipe::{R2Pipe, R2};
use radeco_lib::analysis::analyzer::{FuncAnalyzer, ModuleAnalyzer, all};
use radeco_lib::analysis::cse::cse::CSE;
use radeco_lib::analysis::inst_combine::Combiner;
use radeco_lib::analysis::functions::infer_regusage::Inferer;
use radeco_lib::analysis::functions::fix_ssa_opcalls::CallSiteFixer;
use radeco_lib::analysis::interproc::fixcall::CallFixer;
use radeco_lib::analysis::dce::DCE;
use radeco_lib::analysis::sccp::SCCP;
use radeco_lib::backend::lang_c::c_cfg::ctrl_flow_struct;
use radeco_lib::backend::lang_c::c_cfg::CCFGVerifier;
use radeco_lib::backend::lang_c::c_cfg_builder;
use radeco_lib::frontend::radeco_containers::*;
use radeco_lib::middle::ir_writer;
use radeco_lib::middle::regfile::SubRegisterFile;
use radeco_lib::middle::ssa::ssastorage::SSAStorage;
use radeco_lib::middle::ssa::verifier;
use radeco_lib::middle::dot;
use std::cell::RefCell;
use std::collections::HashMap;
use std::panic;
use std::rc::Rc;
use std::str;
use std::sync::Arc;

thread_local!(pub static PROJ: RefCell<Option<RadecoProject>> = RefCell::new(None););

pub fn fn_list(proj: &RadecoProject) -> Vec<String> {
    proj.iter()
        .map(|i| i.module)
        .flat_map(|rmod| rmod.functions.values())
        .map(|s| s.name.to_string())
        .collect()
}

pub fn get_function<'a>(name: &str, proj: &'a RadecoProject) -> Option<&'a RadecoFunction> {
    proj.iter()
        .map(|i| i.module)
        .flat_map(|rmod| rmod.functions.values())
        .filter(|rfn| rfn.name == name)
        .next()
}

pub fn get_function_mut<'a>(
    name: &str,
    proj: &'a mut RadecoProject,
) -> Option<&'a mut RadecoFunction> {
    proj.iter_mut()
        .map(|i| i.module)
        .flat_map(|rmod| rmod.functions.values_mut())
        .filter(|rfn| rfn.name == name)
        .next()
}

pub fn fn_rename(old_f: &str, new_f: &str, proj: &mut RadecoProject) {
    if let Some(_) = get_function(new_f, proj) {
        println!("there is already a function called: {}", new_f);
        return;
    }

    let mut found = false;

    for module in proj.iter_mut() {
        let module = module.module;
        let off = module.iter()
            .find(|rfn| rfn.function.1.name == old_f)
            .map(|rfn| rfn.function.1.offset);

        if let Some(off) = off {
            module.function_rename(off, new_f);
            found = true;
        }
    }

    if !found {
        println!("function not found: {}", old_f);
    }
}

pub fn analyze_mod(regfile: Arc<SubRegisterFile>, rmod: &mut RadecoModule) {
    // Analyze preserved for all functions.
    {
        eprintln!("[*] Fixing Callee Information");
        let bp_name = regfile.get_name_by_alias(&"BP".to_string());
        let bp_name = bp_name.map(|s| s.to_owned());
        let sp_name = regfile.get_name_by_alias(&"SP".to_string());
        let sp_name = sp_name.map(|s| s.to_owned());
        let mut callfixer = CallFixer::new(rmod, bp_name, sp_name);
        callfixer.rounded_analysis();
    }

    // Fix call sites
    let mut call_site_fixer = CallSiteFixer::new();
    call_site_fixer.analyze(rmod, Some(all));

    // Infer calling conventions
    let mut inferer = Inferer::new((*regfile).clone());
    inferer.analyze(rmod, Some(all));
}

pub fn analyze(rfn: &mut RadecoFunction) {
    eprintln!("[+] Analyzing: {} @ {:#x}", rfn.name, rfn.offset);
    {
        eprintln!("  [*] Eliminating Dead Code");
        let mut dce = DCE::new();
        dce.analyze(rfn, Some(all));
    }
    {
        // Constant Propagation (sccp)
        eprintln!("  [*] Propagating Constants");
        let mut sccp = SCCP::new();
        sccp.analyze(rfn, Some(all));
    }
    {
        eprintln!("  [*] Eliminating More DeadCode");
        let mut dce = DCE::new();
        dce.analyze(rfn, Some(all));
    }
    {
        // Instruction combiner
        let mut combiner = Combiner::new();
        combiner.analyze(rfn, Some(all));
    }
    {
        // Common SubExpression Elimination (cse)
        eprintln!("  [*] Eliminating Common SubExpressions");
        let mut cse = CSE::new();
        cse.analyze(rfn, Some(all));
    }
    {
        // Verify SSA
        eprintln!("  [*] Verifying SSA's Validity");
        match verifier::verify(rfn.ssa()) {
            Err(e) => {
                eprintln!("  [*] Found Error: {}", e);
            }
            Ok(_) => {}
        }
    }
}

pub fn analyze_all_functions<'a>(proj: &'a mut RadecoProject) {
    let rfns = proj
        .iter_mut()
        .map(|i| i.module)
        .flat_map(|rmod| rmod.functions.values_mut());
    for rfn in rfns {
        analyze(rfn);
    }
}

pub fn emit_ir(rfn: &RadecoFunction) -> String {
    eprintln!("  [*] Writing out IR");
    let mut res = String::new();
    ir_writer::emit_il(&mut res, Some(rfn.name.to_string()), rfn.ssa()).unwrap();
    res
}

pub fn emit_dot(ssa: &SSAStorage) -> String {
    dot::emit_dot(ssa)
}

pub fn decompile_all_functions<'a>(proj: &'a RadecoProject) -> String {
    let mut decompiled_funcs = Vec::new();
    let funcs = fn_list(&proj);
    for f in &funcs {
        match decompile(f, &proj) {
            Ok(res) => {
                decompiled_funcs.push(res);
            }
            Err(err) => {
                eprintln!("{}", err);
            }
        };
    }
    decompiled_funcs.join("\n")
}

pub fn decompile<'a>(name: &str, proj: &'a RadecoProject) -> Result<String, String> {
    if let Some(rfn) = get_function(name, &proj) {
        let rmod = proj.iter().map(|i| i.module).next().unwrap();
        let func_name_map = func_names(&rmod);
        let strings = strings(&rmod);
        decompile_priv(rfn, &func_name_map, &strings)
    } else {
        Err(format!("{} is not found.", name))
    }
}

fn decompile_priv(
    rfn: &RadecoFunction,
    func_name_map: &HashMap<u64, String>,
    strings: &HashMap<u64, String>,
) -> Result<String, String> {
    let c_cfg_result =
        panic::catch_unwind(|| c_cfg_builder::recover_c_cfg(rfn, func_name_map, strings));

    if c_cfg_result.is_err() {
        return Err("Failed to recover C control flow graph".to_string());
    };

    let c_cfg = c_cfg_result.unwrap();

    if let Err(err) = CCFGVerifier::verify(&c_cfg) {
        eprintln!("CCFG verification failed {}", err);
    }

    let result = panic::catch_unwind(|| {
        ctrl_flow_struct::structure_and_convert(c_cfg.clone())
            .map(|s| s.print())
            .map_err(|e| e.to_string())
    });
    match result {
        Ok(code) => code,
        Err(_) => {
            println!("Control flow structuring failed");
            Ok(c_cfg.to_c_ast().print())
        }
    }
}

pub fn load_proj_by_path(path: &str) -> RadecoProject {
    let mut p = ProjectLoader::new().path(path).load();
    let regfile = p.regfile().clone();
    for mut xy in p.iter_mut() {
        analyze_mod(regfile.clone(), xy.module);
    }
    p
}

pub fn load_proj_tcp(url: &str) -> Result<RadecoProject, &'static str> {
    let r2p = R2Pipe::tcp(url)?;
    Ok(load_project_by_r2pipe(r2p))
}

pub fn load_proj_http(url: &str) -> Result<RadecoProject, &'static str> {
    let r2p = R2Pipe::http(url)?;
    Ok(load_project_by_r2pipe(r2p))
}

pub fn load_project_by_r2pipe(r2p: R2Pipe) -> RadecoProject {
    let r2 = R2::from(r2p);
    let r2w = Rc::new(RefCell::new(r2));
    let mut p = ProjectLoader::new().source(Rc::new(r2w)).load();
    let regfile = p.regfile().clone();
    for mut xy in p.iter_mut() {
        analyze_mod(regfile.clone(), xy.module);
    }
    p
}

pub fn func_names(rmod: &RadecoModule) -> HashMap<u64, String> {
    rmod.functions
        .iter()
        .map(|(&addr, f)| (addr, f.name.to_string()))
        .collect()
}

pub fn strings(rmod: &RadecoModule) -> HashMap<u64, String> {
    rmod.strings()
        .iter()
        .filter(|ref s| s.paddr.is_some() && s.string.is_some())
        .cloned()
        .map(|s| {
            let (addr, _s) = (s.vaddr.unwrap(), s.string.unwrap());
            let bytes = base64::decode(&_s).unwrap_or(Vec::new());
            let ret_string = match str::from_utf8(bytes.as_slice()) {
                Ok(v) => v.to_string(),
                Err(_e) => _s,
            };
            (addr, ret_string)
        })
        .collect()
}
<|endoftext|>


<commit_before>use super::*;

#[test]
fn test_glibc_version() {
    // This mostly just tests that the weak linkage doesn't panic wildly...
    glibc_version();
}

#[test]
fn test_parse_glibc_version() {
    let cases = [
        ("0.0", Some((0, 0))),
        ("01.+2", Some((1, 2))),
        ("3.4.5.six", Some((3, 4))),
        ("1", None),
        ("1.-2", None),
        ("1.foo", None),
        ("foo.1", None),
    ];
    for &(version_str, parsed) in cases.iter() {
        assert_eq!(parsed, parse_glibc_version(version_str));
    }
}
<commit_msg>Disable glibc tests on vxworks<commit_after>use super::*;

#[test]
#[cfg(not(target_os = "vxworks"))]
fn test_glibc_version() {
    // This mostly just tests that the weak linkage doesn't panic wildly...
    glibc_version();
}

#[test]
#[cfg(not(target_os = "vxworks"))]
fn test_parse_glibc_version() {
    let cases = [
        ("0.0", Some((0, 0))),
        ("01.+2", Some((1, 2))),
        ("3.4.5.six", Some((3, 4))),
        ("1", None),
        ("1.-2", None),
        ("1.foo", None),
        ("foo.1", None),
    ];
    for &(version_str, parsed) in cases.iter() {
        assert_eq!(parsed, parse_glibc_version(version_str));
    }
}
<|endoftext|>


<commit_before>use std::num::Float;
use std::collections::binary_heap::BinaryHeap; // pq
use std::cmp::Ordering;

type float = f64;
type time = u64;

const TIME_RESOLUTION: time = 1000_000; // in micro seconds.

#[derive(Debug)]
struct Config {
    arp:       time,
    tau_m:     float,
    tau_r:     float,
    weight_r:  float,
    threshold: float,
}

#[derive(Debug)]
struct Neuron {
    /// End of absolute refractory period
    arp_end:         time,
    last_spike_time: time,
    mem_pot:         float,
}

#[derive(Debug)]
enum NeuronResult {
    InArp,
    NoFire,
    Fire
}

impl Neuron {
    fn new() -> Neuron {
        Neuron {
            arp_end: 0,
            last_spike_time: 0,
            mem_pot: 0.0
        }
    }

    fn spike(&mut self, timestamp: time, weight: float, cfg: &Config) -> NeuronResult {
        assert!(timestamp >= self.last_spike_time);

        // Return early if still in absolute refractory period (arp)
        if timestamp < self.arp_end {
            return NeuronResult::InArp;
        }

        // Time since end of last absolute refractory period (arp)
        assert!(timestamp >= self.arp_end);
        let delta = timestamp - self.arp_end;

        // Convert delta to float
        let delta: float = (delta as float) / TIME_RESOLUTION as float;

        // Calculate dynamic threshold
        let dyn_threshold = cfg.threshold +
                            cfg.weight_r * (-delta / cfg.tau_r).exp();

        // Update memory potential
        if cfg.tau_m > 0.0 {

            let d = timestamp - self.last_spike_time;
            // Convert delta to float
            let d: float = (d as float) / TIME_RESOLUTION as float;

            let decay = (-d / cfg.tau_m).exp();
            self.mem_pot *= decay;
            self.mem_pot += weight;
        }
        else {
            self.mem_pot = weight;
        }

        // Update last spike time
        self.last_spike_time = timestamp;

        if self.mem_pot >= dyn_threshold {
            self.arp_end = timestamp + cfg.arp;
            NeuronResult::Fire
        }
        else {
            NeuronResult::NoFire
        }
    }
}

#[derive(Debug)]
struct Event {
    time:   time,
    weight: float,
    target: u64
}

impl PartialEq for Event {
    fn eq(&self, other: &Self) -> bool {
        self.time == other.time
    }
}

impl Eq for Event {}

impl PartialOrd for Event {
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
        self.time.partial_cmp(&other.time).map(|o| o.reverse())
    }
}

impl Ord for Event {
    fn cmp(&self, other: &Self) -> Ordering {
        self.time.cmp(&other.time).reverse()
    }
}

fn ms(n: time) -> time { n * 1000 }
fn us(n: time) -> time { n }

fn main() {

    // Koinzidenz neurons
    let cfg_k = Config {
        arp: us(500), // 0.5 ms = 500 us
        tau_m: 0.04,
        tau_r: 0.5,
        weight_r: 0.0,
        threshold: 1.1,
    };

    // Input neurons
    let cfg_i = Config {
        arp: ms(1),
        tau_m: 0.0,
        tau_r: 0.5,
        weight_r: 0.0,
        threshold: 0.6,
    };

    let mut n1 = Neuron::new();
    let mut neurons = vec![n1];
    let mut neurons = neurons.as_mut_slice();

    let mut pq: BinaryHeap<Event> = BinaryHeap::new();

    // Fill event queue with events
    for i in 1..100 {
        let ev = Event {
            time:   ms(i) / 10,
            weight: 0.6,
            target: 0
        };

        pq.push(ev);
    }

    loop {
        println!("-------------------------------------");

        if let Some(ev) = pq.pop() {
            println!("{:?}", ev);
            let neuron = &mut neurons[ev.target as usize];
            let fire = neuron.spike(ev.time, ev.weight, &cfg_i);
            println!("{:?}", fire);
            println!("{:?}", neuron);
        }
        else {
            break;
        }
    }

}
<commit_msg>Store configuration information for Neurons as id<commit_after>use std::num::Float;
use std::collections::binary_heap::BinaryHeap; // pq
use std::cmp::Ordering;

type float = f64;
type time = u64;

const TIME_RESOLUTION: time = 1000_000; // in micro seconds.

#[derive(Debug)]
struct Config {
    arp:       time,
    tau_m:     float,
    tau_r:     float,
    weight_r:  float,
    threshold: float,
}

#[derive(Debug)]
struct Neuron {
    /// End of absolute refractory period
    arp_end:         time,
    last_spike_time: time,
    mem_pot:         float,

    /// An index into a [Config] table.
    config_id:       usize,
}

#[derive(Debug)]
enum NeuronResult {
    InArp,
    NoFire,
    Fire
}

impl Neuron {
    fn new(config_id: usize) -> Neuron {
        Neuron {
            arp_end: 0,
            last_spike_time: 0,
            mem_pot: 0.0,
            config_id: config_id,
        }
    }

    fn spike(&mut self, timestamp: time, weight: float, cfg: &Config) -> NeuronResult {
        assert!(timestamp >= self.last_spike_time);

        // Return early if still in absolute refractory period (arp)
        if timestamp < self.arp_end {
            return NeuronResult::InArp;
        }

        // Time since end of last absolute refractory period (arp)
        assert!(timestamp >= self.arp_end);
        let delta = timestamp - self.arp_end;

        // Convert delta to float
        let delta: float = (delta as float) / TIME_RESOLUTION as float;

        // Calculate dynamic threshold
        let dyn_threshold = cfg.threshold +
                            cfg.weight_r * (-delta / cfg.tau_r).exp();

        // Update memory potential
        if cfg.tau_m > 0.0 {

            let d = timestamp - self.last_spike_time;
            // Convert delta to float
            let d: float = (d as float) / TIME_RESOLUTION as float;

            let decay = (-d / cfg.tau_m).exp();
            self.mem_pot *= decay;
            self.mem_pot += weight;
        }
        else {
            self.mem_pot = weight;
        }

        // Update last spike time
        self.last_spike_time = timestamp;

        if self.mem_pot >= dyn_threshold {
            self.arp_end = timestamp + cfg.arp;
            NeuronResult::Fire
        }
        else {
            NeuronResult::NoFire
        }
    }
}

#[derive(Debug)]
struct Event {
    time:   time,
    weight: float,
    target: u64
}

impl PartialEq for Event {
    fn eq(&self, other: &Self) -> bool {
        self.time == other.time
    }
}

impl Eq for Event {}

impl PartialOrd for Event {
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
        self.time.partial_cmp(&other.time).map(|o| o.reverse())
    }
}

impl Ord for Event {
    fn cmp(&self, other: &Self) -> Ordering {
        self.time.cmp(&other.time).reverse()
    }
}

fn ms(n: time) -> time { n * 1000 }
fn us(n: time) -> time { n }

fn main() {

    // Koinzidenz neurons
    let cfg_k = Config {
        arp: us(500), // 0.5 ms = 500 us
        tau_m: 0.04,
        tau_r: 0.5,
        weight_r: 0.0,
        threshold: 1.1,
    };

    // Input neurons
    let cfg_i = Config {
        arp: ms(1),
        tau_m: 0.0,
        tau_r: 0.5,
        weight_r: 0.0,
        threshold: 0.6,
    };

    let mut configs = vec![/* 0 */cfg_k, /* 1 */cfg_i];

    let mut n1 = Neuron::new(1);

    let mut neurons = vec![n1];
    let mut neurons = neurons.as_mut_slice();

    let mut pq: BinaryHeap<Event> = BinaryHeap::new();

    // Fill event queue with events
    for i in 1..100 {
        let ev = Event {
            time:   ms(i) / 10,
            weight: 0.6,
            target: 0
        };

        pq.push(ev);
    }

    loop {
        println!("-------------------------------------");

        if let Some(ev) = pq.pop() {
            println!("{:?}", ev);
            let neuron = &mut neurons[ev.target as usize];
            let cfg = &(configs.as_slice())[neuron.config_id];
            let fire = neuron.spike(ev.time, ev.weight, cfg);
            println!("{:?}", fire);
            println!("{:?}", neuron);
        }
        else {
            break;
        }
    }

}
<|endoftext|>


<commit_before>// Copyright 2019 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

use std::fs::File;
use std::io::BufRead;
use std::io::BufReader;

use crate::fdt::{begin_node, end_node, property_string, Error, Result};

fn parse_fstab_line(line: &str) -> Result<Vec<String>> {
    let vec: Vec<&str> = line.split_whitespace().collect();
    if vec.len() != 5 {
        return Err(Error::FdtFileParseError);
    }
    Ok(vec.iter().map(|s| s.to_string()).collect())
}

/// Creates a flattened device tree containing all of the parameters used
/// by Android.
///
/// # Arguments
///
/// * `fdt` - The DTB to modify. The top-most node should be open.
/// * `android-fstab` - A text file of Android fstab entries to add to the DTB
pub fn create_android_fdt(fdt: &mut Vec<u8>, fstab: File) -> Result<()> {
    let vecs = BufReader::new(fstab)
        .lines()
        .map(|l| parse_fstab_line(&l.map_err(Error::FdtIoError)?))
        .collect::<Result<Vec<Vec<String>>>>()?;
    begin_node(fdt, "firmware")?;
    begin_node(fdt, "android")?;
    property_string(fdt, "compatible", "android,firmware")?;

    let (dtprop, fstab): (_, Vec<_>) = vecs.into_iter().partition(|x| x[0] == "#dt-vendor");
    begin_node(fdt, "vendor")?;
    for vec in dtprop {
        let content = std::fs::read_to_string(&vec[2]).map_err(Error::FdtIoError)?;
        property_string(fdt, &vec[1], &content);
    }
    end_node(fdt)?; // vendor
    begin_node(fdt, "fstab")?;
    property_string(fdt, "compatible", "android,fstab")?;
    for vec in fstab {
        let partition = &vec[1][1..];
        begin_node(fdt, partition)?;
        property_string(fdt, "compatible", &("android,".to_owned() + partition))?;
        property_string(fdt, "dev", &vec[0])?;
        property_string(fdt, "type", &vec[2])?;
        property_string(fdt, "mnt_flags", &vec[3])?;
        property_string(fdt, "fsmgr_flags", &vec[4])?;
        end_node(fdt)?;
    }
    end_node(fdt)?; // fstab
    end_node(fdt)?; // android
    end_node(fdt)?; // firmware
    Ok(())
}
<commit_msg>arch: check property_string result in create_android_fdt<commit_after>// Copyright 2019 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

use std::fs::File;
use std::io::BufRead;
use std::io::BufReader;

use crate::fdt::{begin_node, end_node, property_string, Error, Result};

fn parse_fstab_line(line: &str) -> Result<Vec<String>> {
    let vec: Vec<&str> = line.split_whitespace().collect();
    if vec.len() != 5 {
        return Err(Error::FdtFileParseError);
    }
    Ok(vec.iter().map(|s| s.to_string()).collect())
}

/// Creates a flattened device tree containing all of the parameters used
/// by Android.
///
/// # Arguments
///
/// * `fdt` - The DTB to modify. The top-most node should be open.
/// * `android-fstab` - A text file of Android fstab entries to add to the DTB
pub fn create_android_fdt(fdt: &mut Vec<u8>, fstab: File) -> Result<()> {
    let vecs = BufReader::new(fstab)
        .lines()
        .map(|l| parse_fstab_line(&l.map_err(Error::FdtIoError)?))
        .collect::<Result<Vec<Vec<String>>>>()?;
    begin_node(fdt, "firmware")?;
    begin_node(fdt, "android")?;
    property_string(fdt, "compatible", "android,firmware")?;

    let (dtprop, fstab): (_, Vec<_>) = vecs.into_iter().partition(|x| x[0] == "#dt-vendor");
    begin_node(fdt, "vendor")?;
    for vec in dtprop {
        let content = std::fs::read_to_string(&vec[2]).map_err(Error::FdtIoError)?;
        property_string(fdt, &vec[1], &content)?;
    }
    end_node(fdt)?; // vendor
    begin_node(fdt, "fstab")?;
    property_string(fdt, "compatible", "android,fstab")?;
    for vec in fstab {
        let partition = &vec[1][1..];
        begin_node(fdt, partition)?;
        property_string(fdt, "compatible", &("android,".to_owned() + partition))?;
        property_string(fdt, "dev", &vec[0])?;
        property_string(fdt, "type", &vec[2])?;
        property_string(fdt, "mnt_flags", &vec[3])?;
        property_string(fdt, "fsmgr_flags", &vec[4])?;
        end_node(fdt)?;
    }
    end_node(fdt)?; // fstab
    end_node(fdt)?; // android
    end_node(fdt)?; // firmware
    Ok(())
}
<|endoftext|>


<commit_before>#[feature(macro_rules)];

use base::{ParseState, ParseResult, NotEx, Dot, Expression, Literal, Or,
WrapEx, Sequence, Star};

// macro_escape makes macros from annotated module visible in the "super"
// module... and thus in the children of the "super" module as well.
#[macro_escape]
mod macros;

#[macro_escape]
mod base;

macro_rules! rule(
  (
    $name:ident <- $body:expr
  ) => (
    fn $name<'a>( parse_state: &ParseState<'a> ) -> Option< ParseResult<'a> > {
      $body.apply( parse_state )
    }
  );
)

rule!( Comment <- seq!( lit!( "#" ),
                        star!( seq!( not!( ex!( EndOfLine ) ), Dot ) ),
                        ex!( EndOfLine ) ) )
rule!( Space <- or!( lit!( " " ), lit!( "\t" ), ex!( EndOfLine ) ) )
rule!( EndOfLine <- or!( lit!( "\r\n" ), lit!( "\n" ), lit!( "\r" ) ) )
rule!( EndOfFile <- not!( Dot ) )

#[cfg(test)]
mod tests {
  use base::test_utils::ToParseState;
  use base::{ParseResult};
  use super::{EndOfFile, EndOfLine, Space, Comment};

  macro_rules! consumes(
    (
      $name:ident, $input:expr
    ) => (
      {
        byte_var!( input = $input )
        match $name( &ToParseState( input ) ) {
          Some( ParseResult{ nodes: _,
                             parse_state: parse_state } ) => {
            parse_state.input.is_empty()
          }
          _ => false
        }
      }
    );
  )

  macro_rules! matches(
    (
      $name:ident, $input:expr
    ) => (
      {
        byte_var!( input = $input )
        $name( &ToParseState( input ) ).is_some()
      }
    );
  )

  #[test]
  fn Comment_Works() {
    assert!( consumes!( Comment, "#\n" ) );
    assert!( consumes!( Comment, "# foo! \n" ) );
    assert!( !matches!( Comment, "\n" ) );
    assert!( !matches!( Comment, "a" ) );
  }

  #[test]
  fn Space_Works() {
    assert!( consumes!( Space, " " ) );
    assert!( consumes!( Space, "\t" ) );
    assert!( consumes!( Space, "\n" ) );
    assert!( !matches!( Space, "a" ) );
  }

  #[test]
  fn EndOfLine_Works() {
    assert!( consumes!( EndOfLine, "\n" ) );
    assert!( consumes!( EndOfLine, "\r" ) );
    assert!( consumes!( EndOfLine, "\r\n" ) );
    assert!( !matches!( EndOfLine, "a" ) );
  }

  #[test]
  fn EndOfFile_Works() {
    assert!( consumes!( EndOfFile, "" ) );
    assert!( !matches!( EndOfFile, "a" ) );
  }
}
<commit_msg>Added more rule implementations<commit_after>#[feature(macro_rules)];

use base::{ParseState, ParseResult, NotEx, Dot, Expression, Literal, Or,
WrapEx, Sequence, Star};

// macro_escape makes macros from annotated module visible in the "super"
// module... and thus in the children of the "super" module as well.
#[macro_escape]
mod macros;

#[macro_escape]
mod base;

macro_rules! rule(
  (
    $name:ident <- $body:expr
  ) => (
    fn $name<'a>( parse_state: &ParseState<'a> ) -> Option< ParseResult<'a> > {
      $body.apply( parse_state )
    }
  );
)

rule!( LEFTARROW <- seq!( lit!( "<-" ), ex!( Spacing ) ) )
rule!( SLASH <- seq!( lit!( "/" ), ex!( Spacing ) ) )
rule!( NOT <- seq!( lit!( "!" ), ex!( Spacing ) ) )
rule!( QUESTION <- seq!( lit!( "?" ), ex!( Spacing ) ) )
rule!( STAR <- seq!( lit!( "*" ), ex!( Spacing ) ) )
rule!( PLUS <- seq!( lit!( "+" ), ex!( Spacing ) ) )
rule!( OPEN <- seq!( lit!( "(" ), ex!( Spacing ) ) )
rule!( CLOSE <- seq!( lit!( ")" ), ex!( Spacing ) ) )
rule!( DOT <- seq!( lit!( "." ), ex!( Spacing ) ) )
rule!( Spacing <- star!( or!( ex!( Space ), ex!( Comment ) ) ) )
rule!( Comment <- seq!( lit!( "#" ),
                        star!( seq!( not!( ex!( EndOfLine ) ), Dot ) ),
                        ex!( EndOfLine ) ) )
rule!( Space <- or!( lit!( " " ), lit!( "\t" ), ex!( EndOfLine ) ) )
rule!( EndOfLine <- or!( lit!( "\r\n" ), lit!( "\n" ), lit!( "\r" ) ) )
rule!( EndOfFile <- not!( Dot ) )

#[cfg(test)]
mod tests {
  use base::test_utils::ToParseState;
  use base::{ParseResult};
  use super::{EndOfFile, EndOfLine, Space, Comment, Spacing};

  macro_rules! consumes(
    (
      $name:ident, $input:expr
    ) => (
      {
        byte_var!( input = $input )
        match $name( &ToParseState( input ) ) {
          Some( ParseResult{ nodes: _,
                             parse_state: parse_state } ) => {
            parse_state.input.is_empty()
          }
          _ => false
        }
      }
    );
  )

  macro_rules! matches(
    (
      $name:ident, $input:expr
    ) => (
      {
        byte_var!( input = $input )
        $name( &ToParseState( input ) ).is_some()
      }
    );
  )

  #[test]
  fn Spacing_Works() {
    assert!( consumes!( Spacing, "  \t #g\n" ) );
    assert!( consumes!( Spacing, "#a\n  #1\n" ) );

    // Spacing DOES match here because at the top level, it is a star expression
    // which can match consuming nothing.
    assert!( matches!( Spacing, "" ) );
    assert!( !consumes!( Spacing, "#" ) );
    assert!( !consumes!( Spacing, "a" ) );
  }

  #[test]
  fn Comment_Works() {
    assert!( consumes!( Comment, "#\n" ) );
    assert!( consumes!( Comment, "# foo! \n" ) );
    assert!( !matches!( Comment, "\n" ) );
    assert!( !matches!( Comment, "#" ) );
    assert!( !matches!( Comment, "a" ) );
  }

  #[test]
  fn Space_Works() {
    assert!( consumes!( Space, " " ) );
    assert!( consumes!( Space, "\t" ) );
    assert!( consumes!( Space, "\n" ) );
    assert!( !matches!( Space, "a" ) );
  }

  #[test]
  fn EndOfLine_Works() {
    assert!( consumes!( EndOfLine, "\n" ) );
    assert!( consumes!( EndOfLine, "\r" ) );
    assert!( consumes!( EndOfLine, "\r\n" ) );
    assert!( !matches!( EndOfLine, "a" ) );
  }

  #[test]
  fn EndOfFile_Works() {
    assert!( consumes!( EndOfFile, "" ) );
    assert!( !matches!( EndOfFile, "a" ) );
  }
}
<|endoftext|>


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

use driver::config;
use driver::session::Session;

use syntax::ast;
use syntax::attr;
use syntax::codemap::DUMMY_SP;
use syntax::codemap;
use syntax::fold::Folder;
use syntax::fold;
use syntax::owned_slice::OwnedSlice;
use syntax::parse::token::InternedString;
use syntax::parse::token;
use syntax::util::small_vector::SmallVector;

use std::mem;
use std::gc::{Gc, GC};

pub fn maybe_inject_crates_ref(sess: &Session, krate: ast::Crate)
                               -> ast::Crate {
    if use_std(&krate) {
        inject_crates_ref(sess, krate)
    } else {
        krate
    }
}

pub fn maybe_inject_prelude(sess: &Session, krate: ast::Crate) -> ast::Crate {
    if use_std(&krate) {
        inject_prelude(sess, krate)
    } else {
        krate
    }
}

fn use_std(krate: &ast::Crate) -> bool {
    !attr::contains_name(krate.attrs.as_slice(), "no_std")
}

fn use_start(krate: &ast::Crate) -> bool {
    !attr::contains_name(krate.attrs.as_slice(), "no_start")
}

fn no_prelude(attrs: &[ast::Attribute]) -> bool {
    attr::contains_name(attrs, "no_implicit_prelude")
}

struct StandardLibraryInjector<'a> {
    sess: &'a Session,
}

impl<'a> fold::Folder for StandardLibraryInjector<'a> {
    fn fold_crate(&mut self, mut krate: ast::Crate) -> ast::Crate {

        // The name to use in `extern crate std = "name";`
        let actual_crate_name = match self.sess.opts.alt_std_name {
            Some(ref s) => token::intern_and_get_ident(s.as_slice()),
            None => token::intern_and_get_ident("std"),
        };

        let mut vis = vec!(ast::ViewItem {
            node: ast::ViewItemExternCrate(token::str_to_ident("std"),
                                           Some((actual_crate_name, ast::CookedStr)),
                                           ast::DUMMY_NODE_ID),
            attrs: vec!(
                attr::mk_attr_outer(attr::mk_attr_id(), attr::mk_list_item(
                        InternedString::new("phase"),
                        vec!(
                            attr::mk_word_item(InternedString::new("plugin")),
                            attr::mk_word_item(InternedString::new("link")
                        ))))),
            vis: ast::Inherited,
            span: DUMMY_SP
        });

        let any_exe = self.sess.crate_types.borrow().iter().any(|ty| {
            *ty == config::CrateTypeExecutable
        });
        if use_start(&krate) && any_exe {
            vis.push(ast::ViewItem {
                node: ast::ViewItemExternCrate(token::str_to_ident("native"),
                                               None,
                                               ast::DUMMY_NODE_ID),
                attrs: Vec::new(),
                vis: ast::Inherited,
                span: DUMMY_SP
            });
        }

        // `extern crate` must be precede `use` items
        mem::swap(&mut vis, &mut krate.module.view_items);
        krate.module.view_items.push_all_move(vis);

        // don't add #![no_std] here, that will block the prelude injection later.
        // Add it during the prelude injection instead.

        // Add #![feature(phase)] here, because we use #[phase] on extern crate std.
        let feat_phase_attr = attr::mk_attr_inner(attr::mk_attr_id(),
                                                  attr::mk_list_item(
                                  InternedString::new("feature"),
                                  vec![attr::mk_word_item(InternedString::new("phase"))],
                              ));
        // std_inject runs after feature checking so manually mark this attr
        attr::mark_used(&feat_phase_attr);
        krate.attrs.push(feat_phase_attr);

        krate
    }
}

fn inject_crates_ref(sess: &Session, krate: ast::Crate) -> ast::Crate {
    let mut fold = StandardLibraryInjector {
        sess: sess,
    };
    fold.fold_crate(krate)
}

struct PreludeInjector<'a>;

impl<'a> fold::Folder for PreludeInjector<'a> {
    fn fold_crate(&mut self, mut krate: ast::Crate) -> ast::Crate {
        // Add #![no_std] here, so we don't re-inject when compiling pretty-printed source.
        // This must happen here and not in StandardLibraryInjector because this
        // fold happens second.

        let no_std_attr = attr::mk_attr_inner(attr::mk_attr_id(),
                                              attr::mk_word_item(InternedString::new("no_std")));
        // std_inject runs after feature checking so manually mark this attr
        attr::mark_used(&no_std_attr);
        krate.attrs.push(no_std_attr);

        if !no_prelude(krate.attrs.as_slice()) {
            // only add `use std::prelude::*;` if there wasn't a
            // `#![no_implicit_prelude]` at the crate level.

            // fold_mod() will insert glob path.
            let globs_attr = attr::mk_attr_inner(attr::mk_attr_id(),
                                                 attr::mk_list_item(
                InternedString::new("feature"),
                vec!(
                    attr::mk_word_item(InternedString::new("globs")),
                )));
            // std_inject runs after feature checking so manually mark this attr
            attr::mark_used(&globs_attr);
            krate.attrs.push(globs_attr);

            krate.module = self.fold_mod(&krate.module);
        }
        krate
    }

    fn fold_item(&mut self, item: Gc<ast::Item>) -> SmallVector<Gc<ast::Item>> {
        if !no_prelude(item.attrs.as_slice()) {
            // only recur if there wasn't `#![no_implicit_prelude]`
            // on this item, i.e. this means that the prelude is not
            // implicitly imported though the whole subtree
            fold::noop_fold_item(&*item, self)
        } else {
            SmallVector::one(item)
        }
    }

    fn fold_mod(&mut self, module: &ast::Mod) -> ast::Mod {
        let prelude_path = ast::Path {
            span: DUMMY_SP,
            global: false,
            segments: vec!(
                ast::PathSegment {
                    identifier: token::str_to_ident("std"),
                    lifetimes: Vec::new(),
                    types: OwnedSlice::empty(),
                },
                ast::PathSegment {
                    identifier: token::str_to_ident("prelude"),
                    lifetimes: Vec::new(),
                    types: OwnedSlice::empty(),
                }),
        };

        let vp = box(GC) codemap::dummy_spanned(ast::ViewPathGlob(prelude_path,
                                                                  ast::DUMMY_NODE_ID));
        let vi2 = ast::ViewItem {
            node: ast::ViewItemUse(vp),
            attrs: Vec::new(),
            vis: ast::Inherited,
            span: DUMMY_SP,
        };

        let (crates, uses) = module.view_items.partitioned(|x| {
            match x.node {
                ast::ViewItemExternCrate(..) => true,
                _ => false,
            }
        });

        // add vi2 after any `extern crate` but before any `use`
        let mut view_items = crates;
        view_items.push(vi2);
        view_items.push_all_move(uses);

        let new_module = ast::Mod {
            view_items: view_items,
            ..(*module).clone()
        };
        fold::noop_fold_mod(&new_module, self)
    }
}

fn inject_prelude(_: &Session, krate: ast::Crate) -> ast::Crate {
    let mut fold = PreludeInjector;
    fold.fold_crate(krate)
}
<commit_msg>rustc: Future proof runtime injection<commit_after>// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use driver::config;
use driver::session::Session;

use syntax::ast;
use syntax::attr;
use syntax::codemap::DUMMY_SP;
use syntax::codemap;
use syntax::fold::Folder;
use syntax::fold;
use syntax::owned_slice::OwnedSlice;
use syntax::parse::token::InternedString;
use syntax::parse::token;
use syntax::util::small_vector::SmallVector;

use std::mem;
use std::gc::{Gc, GC};

pub fn maybe_inject_crates_ref(sess: &Session, krate: ast::Crate)
                               -> ast::Crate {
    if use_std(&krate) {
        inject_crates_ref(sess, krate)
    } else {
        krate
    }
}

pub fn maybe_inject_prelude(sess: &Session, krate: ast::Crate) -> ast::Crate {
    if use_std(&krate) {
        inject_prelude(sess, krate)
    } else {
        krate
    }
}

fn use_std(krate: &ast::Crate) -> bool {
    !attr::contains_name(krate.attrs.as_slice(), "no_std")
}

fn use_start(krate: &ast::Crate) -> bool {
    !attr::contains_name(krate.attrs.as_slice(), "no_start")
}

fn no_prelude(attrs: &[ast::Attribute]) -> bool {
    attr::contains_name(attrs, "no_implicit_prelude")
}

struct StandardLibraryInjector<'a> {
    sess: &'a Session,
}

impl<'a> fold::Folder for StandardLibraryInjector<'a> {
    fn fold_crate(&mut self, mut krate: ast::Crate) -> ast::Crate {

        // The name to use in `extern crate std = "name";`
        let actual_crate_name = match self.sess.opts.alt_std_name {
            Some(ref s) => token::intern_and_get_ident(s.as_slice()),
            None => token::intern_and_get_ident("std"),
        };

        let mut vis = vec!(ast::ViewItem {
            node: ast::ViewItemExternCrate(token::str_to_ident("std"),
                                           Some((actual_crate_name, ast::CookedStr)),
                                           ast::DUMMY_NODE_ID),
            attrs: vec!(
                attr::mk_attr_outer(attr::mk_attr_id(), attr::mk_list_item(
                        InternedString::new("phase"),
                        vec!(
                            attr::mk_word_item(InternedString::new("plugin")),
                            attr::mk_word_item(InternedString::new("link")
                        ))))),
            vis: ast::Inherited,
            span: DUMMY_SP
        });

        let any_exe = self.sess.crate_types.borrow().iter().any(|ty| {
            *ty == config::CrateTypeExecutable
        });
        if use_start(&krate) && any_exe {
            let visible_rt_name = "rt";
            let actual_rt_name = "native";
            // Gensym the ident so it can't be named
            let visible_rt_name = token::gensym_ident(visible_rt_name);
            let actual_rt_name = token::intern_and_get_ident(actual_rt_name);

            vis.push(ast::ViewItem {
                node: ast::ViewItemExternCrate(visible_rt_name,
                                               Some((actual_rt_name, ast::CookedStr)),
                                               ast::DUMMY_NODE_ID),
                attrs: Vec::new(),
                vis: ast::Inherited,
                span: DUMMY_SP
            });
        }

        // `extern crate` must be precede `use` items
        mem::swap(&mut vis, &mut krate.module.view_items);
        krate.module.view_items.push_all_move(vis);

        // don't add #![no_std] here, that will block the prelude injection later.
        // Add it during the prelude injection instead.

        // Add #![feature(phase)] here, because we use #[phase] on extern crate std.
        let feat_phase_attr = attr::mk_attr_inner(attr::mk_attr_id(),
                                                  attr::mk_list_item(
                                  InternedString::new("feature"),
                                  vec![attr::mk_word_item(InternedString::new("phase"))],
                              ));
        // std_inject runs after feature checking so manually mark this attr
        attr::mark_used(&feat_phase_attr);
        krate.attrs.push(feat_phase_attr);

        krate
    }
}

fn inject_crates_ref(sess: &Session, krate: ast::Crate) -> ast::Crate {
    let mut fold = StandardLibraryInjector {
        sess: sess,
    };
    fold.fold_crate(krate)
}

struct PreludeInjector<'a>;

impl<'a> fold::Folder for PreludeInjector<'a> {
    fn fold_crate(&mut self, mut krate: ast::Crate) -> ast::Crate {
        // Add #![no_std] here, so we don't re-inject when compiling pretty-printed source.
        // This must happen here and not in StandardLibraryInjector because this
        // fold happens second.

        let no_std_attr = attr::mk_attr_inner(attr::mk_attr_id(),
                                              attr::mk_word_item(InternedString::new("no_std")));
        // std_inject runs after feature checking so manually mark this attr
        attr::mark_used(&no_std_attr);
        krate.attrs.push(no_std_attr);

        if !no_prelude(krate.attrs.as_slice()) {
            // only add `use std::prelude::*;` if there wasn't a
            // `#![no_implicit_prelude]` at the crate level.

            // fold_mod() will insert glob path.
            let globs_attr = attr::mk_attr_inner(attr::mk_attr_id(),
                                                 attr::mk_list_item(
                InternedString::new("feature"),
                vec!(
                    attr::mk_word_item(InternedString::new("globs")),
                )));
            // std_inject runs after feature checking so manually mark this attr
            attr::mark_used(&globs_attr);
            krate.attrs.push(globs_attr);

            krate.module = self.fold_mod(&krate.module);
        }
        krate
    }

    fn fold_item(&mut self, item: Gc<ast::Item>) -> SmallVector<Gc<ast::Item>> {
        if !no_prelude(item.attrs.as_slice()) {
            // only recur if there wasn't `#![no_implicit_prelude]`
            // on this item, i.e. this means that the prelude is not
            // implicitly imported though the whole subtree
            fold::noop_fold_item(&*item, self)
        } else {
            SmallVector::one(item)
        }
    }

    fn fold_mod(&mut self, module: &ast::Mod) -> ast::Mod {
        let prelude_path = ast::Path {
            span: DUMMY_SP,
            global: false,
            segments: vec!(
                ast::PathSegment {
                    identifier: token::str_to_ident("std"),
                    lifetimes: Vec::new(),
                    types: OwnedSlice::empty(),
                },
                ast::PathSegment {
                    identifier: token::str_to_ident("prelude"),
                    lifetimes: Vec::new(),
                    types: OwnedSlice::empty(),
                }),
        };

        let vp = box(GC) codemap::dummy_spanned(ast::ViewPathGlob(prelude_path,
                                                                  ast::DUMMY_NODE_ID));
        let vi2 = ast::ViewItem {
            node: ast::ViewItemUse(vp),
            attrs: Vec::new(),
            vis: ast::Inherited,
            span: DUMMY_SP,
        };

        let (crates, uses) = module.view_items.partitioned(|x| {
            match x.node {
                ast::ViewItemExternCrate(..) => true,
                _ => false,
            }
        });

        // add vi2 after any `extern crate` but before any `use`
        let mut view_items = crates;
        view_items.push(vi2);
        view_items.push_all_move(uses);

        let new_module = ast::Mod {
            view_items: view_items,
            ..(*module).clone()
        };
        fold::noop_fold_mod(&new_module, self)
    }
}

fn inject_prelude(_: &Session, krate: ast::Crate) -> ast::Crate {
    let mut fold = PreludeInjector;
    fold.fold_crate(krate)
}
<|endoftext|>


<commit_before>extern crate scaproust;

use std::io;

use scaproust::*;

#[test]
fn test_pipeline_connected_to_bound() {
	let session = Session::new().unwrap();
	let mut pull = session.create_socket(SocketType::Pull).unwrap();
	let mut push = session.create_socket(SocketType::Push).unwrap();

	pull.bind("tcp://127.0.0.1:5454").unwrap();
	push.connect("tcp://127.0.0.1:5454").unwrap();

	let sent = vec![65, 66, 67];
	push.send(sent).unwrap();
	let received = pull.recv().unwrap();

	assert_eq!(vec![65, 66, 67], received)
}

#[test]
fn test_pipeline_bound_to_connected() {
	let session = Session::new().unwrap();
	let mut pull = session.create_socket(SocketType::Pull).unwrap();
	let mut push = session.create_socket(SocketType::Push).unwrap();

	push.bind("tcp://127.0.0.1:5455").unwrap();
	pull.connect("tcp://127.0.0.1:5455").unwrap();

	let sent = vec![65, 66, 67];
	push.send(sent).unwrap();
	let received = pull.recv().unwrap();

	assert_eq!(vec![65, 66, 67], received)
}

#[test]
fn test_send_while_not_connected() {
	let session = Session::new().unwrap();
	let mut push = session.create_socket(SocketType::Push).unwrap();

	push.connect("tcp://127.0.0.1:5456").unwrap();

	let err = push.send(vec![65, 66, 67]).unwrap_err();

	assert_eq!(io::ErrorKind::NotConnected, err.kind());
}

#[test]
fn test_send_timeout() {
	let session = Session::new().unwrap();
	let mut pull = session.create_socket(SocketType::Pull).unwrap();
	let mut push = session.create_socket(SocketType::Push).unwrap();

	pull.bind("tcp://127.0.0.1:5457").unwrap();
	push.connect("tcp://127.0.0.1:5457").unwrap();

	let err = push.send(vec![0; 5 * 1024 * 1024]).unwrap_err();

	assert_eq!(io::ErrorKind::TimedOut, err.kind());
}

#[test]
fn test_recv_while_not_connected() {
	let session = Session::new().unwrap();
	let mut pull = session.create_socket(SocketType::Pull).unwrap();

	pull.bind("tcp://127.0.0.1:5458").unwrap();

	let err = pull.recv().unwrap_err();

	assert_eq!(io::ErrorKind::NotConnected, err.kind());
}

#[test]
fn test_recv_timeout() {
	let session = Session::new().unwrap();
	let mut pull = session.create_socket(SocketType::Pull).unwrap();
	let mut push = session.create_socket(SocketType::Push).unwrap();

	pull.bind("tcp://127.0.0.1:5459").unwrap();
	push.connect("tcp://127.0.0.1:5459").unwrap();

	let err = pull.recv().unwrap_err();

	assert_eq!(io::ErrorKind::TimedOut, err.kind());
}

#[test]
fn test_pair_connected_to_bound() {
	let session = Session::new().unwrap();
	let mut bound = session.create_socket(SocketType::Pair).unwrap();
	let mut connected = session.create_socket(SocketType::Pair).unwrap();

	bound.bind("tcp://127.0.0.1:5460").unwrap();
	connected.connect("tcp://127.0.0.1:5460").unwrap();

	let sent = vec![65, 66, 67];
	connected.send(sent).unwrap();
	let received = bound.recv().unwrap();

	assert_eq!(vec![65, 66, 67], received)
}

#[test]
fn test_pair_bound_to_connected() {
	let session = Session::new().unwrap();
	let mut bound = session.create_socket(SocketType::Pair).unwrap();
	let mut connected = session.create_socket(SocketType::Pair).unwrap();

	bound.bind("tcp://127.0.0.1:5461").unwrap();
	connected.connect("tcp://127.0.0.1:5461").unwrap();

	let sent = vec![65, 66, 67];
	bound.send(sent).unwrap();
	let received = connected.recv().unwrap();

	assert_eq!(vec![65, 66, 67], received)
}

#[test]
fn test_req_rep() {
	let session = Session::new().unwrap();
	let mut server = session.create_socket(SocketType::Rep).unwrap();
	let mut client = session.create_socket(SocketType::Req).unwrap();

	server.bind("tcp://127.0.0.1:5462").unwrap();
	client.connect("tcp://127.0.0.1:5462").unwrap();

	let client_request = vec!(65, 66, 67);
	client.send(client_request).unwrap();

	let server_request = server.recv().unwrap();
	assert_eq!(vec!(65, 66, 67), server_request);

	let server_reply = vec!(67, 66, 65);
	server.send(server_reply).unwrap();

	let client_reply = client.recv().unwrap();

	assert_eq!(vec!(67, 66, 65), client_reply);
}

#[test]
fn test_pub_sub() {
	let session = Session::new().unwrap();
	let mut server = session.create_socket(SocketType::Pub).unwrap();
	let mut client = session.create_socket(SocketType::Sub).unwrap();

	server.bind("tcp://127.0.0.1:5463").unwrap();
	client.connect("tcp://127.0.0.1:5463").unwrap();

	let sent = vec![65, 66, 67];
	server.send(sent).unwrap();
	let received = client.recv().unwrap();

	assert_eq!(vec![65, 66, 67], received);
}

#[test]
fn test_bus() {
	let session = Session::new().unwrap();
	let mut server = session.create_socket(SocketType::Bus).unwrap();
	let mut client1 = session.create_socket(SocketType::Bus).unwrap();
	let mut client2 = session.create_socket(SocketType::Bus).unwrap();

	server.bind("tcp://127.0.0.1:5464").unwrap();
	client1.connect("tcp://127.0.0.1:5464").unwrap();
	client2.connect("tcp://127.0.0.1:5464").unwrap();

	let sent = vec![65, 66, 67];
	server.send(sent).unwrap();
	let received1 = client1.recv().unwrap();
	assert_eq!(vec![65, 66, 67], received1);
	let received2 = client2.recv().unwrap();
	assert_eq!(vec![65, 66, 67], received2);
}

#[test]
fn test_survey() {
	let session = Session::new().unwrap();
	let mut server = session.create_socket(SocketType::Surveyor).unwrap();
	let mut client1 = session.create_socket(SocketType::Respondent).unwrap();
	let mut client2 = session.create_socket(SocketType::Respondent).unwrap();

	server.bind("tcp://127.0.0.1:5463").unwrap();
	client1.connect("tcp://127.0.0.1:5463").unwrap();
	client2.connect("tcp://127.0.0.1:5463").unwrap();

	let server_survey = vec!(65, 66, 67);
	server.send(server_survey).unwrap();

	let client1_survey = client1.recv().unwrap();
	assert_eq!(vec!(65, 66, 67), client1_survey);

	let client2_survey = client2.recv().unwrap();
	assert_eq!(vec!(65, 66, 67), client2_survey);

	client1.send(vec!(65, 66, 65)).unwrap();
	let server_resp1 = server.recv().unwrap();
	assert_eq!(vec!(65, 66, 65), server_resp1);

	client2.send(vec!(67, 66, 67)).unwrap();
	let server_resp2 = server.recv().unwrap();
	assert_eq!(vec!(67, 66, 67), server_resp2);
}

#[test]
fn test_send_reply_before_send_request() {
	let session = Session::new().unwrap();
	let mut server = session.create_socket(SocketType::Rep).unwrap();

	server.bind("tcp://127.0.0.1:5464").unwrap();
	server.send(vec!(67, 66, 65)).unwrap_err();
}

#[test]
fn test_recv_reply_before_send_request() {
	let session = Session::new().unwrap();
	let mut server = session.create_socket(SocketType::Rep).unwrap();
	let mut client = session.create_socket(SocketType::Req).unwrap();

	server.bind("tcp://127.0.0.1:5465").unwrap();
	client.connect("tcp://127.0.0.1:5465").unwrap();

	let err = client.recv().unwrap_err();
	assert_eq!(io::ErrorKind::Other, err.kind());
}
<commit_msg>Fixes bug port number in integration tests<commit_after>extern crate scaproust;

use std::io;

use scaproust::*;

#[test]
fn test_pipeline_connected_to_bound() {
	let session = Session::new().unwrap();
	let mut pull = session.create_socket(SocketType::Pull).unwrap();
	let mut push = session.create_socket(SocketType::Push).unwrap();

	pull.bind("tcp://127.0.0.1:5454").unwrap();
	push.connect("tcp://127.0.0.1:5454").unwrap();

	let sent = vec![65, 66, 67];
	push.send(sent).unwrap();
	let received = pull.recv().unwrap();

	assert_eq!(vec![65, 66, 67], received)
}

#[test]
fn test_pipeline_bound_to_connected() {
	let session = Session::new().unwrap();
	let mut pull = session.create_socket(SocketType::Pull).unwrap();
	let mut push = session.create_socket(SocketType::Push).unwrap();

	push.bind("tcp://127.0.0.1:5455").unwrap();
	pull.connect("tcp://127.0.0.1:5455").unwrap();

	let sent = vec![65, 66, 67];
	push.send(sent).unwrap();
	let received = pull.recv().unwrap();

	assert_eq!(vec![65, 66, 67], received)
}

#[test]
fn test_send_while_not_connected() {
	let session = Session::new().unwrap();
	let mut push = session.create_socket(SocketType::Push).unwrap();

	push.connect("tcp://127.0.0.1:5456").unwrap();

	let err = push.send(vec![65, 66, 67]).unwrap_err();

	assert_eq!(io::ErrorKind::NotConnected, err.kind());
}

#[test]
fn test_send_timeout() {
	let session = Session::new().unwrap();
	let mut pull = session.create_socket(SocketType::Pull).unwrap();
	let mut push = session.create_socket(SocketType::Push).unwrap();

	pull.bind("tcp://127.0.0.1:5457").unwrap();
	push.connect("tcp://127.0.0.1:5457").unwrap();

	let err = push.send(vec![0; 5 * 1024 * 1024]).unwrap_err();

	assert_eq!(io::ErrorKind::TimedOut, err.kind());
}

#[test]
fn test_recv_while_not_connected() {
	let session = Session::new().unwrap();
	let mut pull = session.create_socket(SocketType::Pull).unwrap();

	pull.bind("tcp://127.0.0.1:5458").unwrap();

	let err = pull.recv().unwrap_err();

	assert_eq!(io::ErrorKind::NotConnected, err.kind());
}

#[test]
fn test_recv_timeout() {
	let session = Session::new().unwrap();
	let mut pull = session.create_socket(SocketType::Pull).unwrap();
	let mut push = session.create_socket(SocketType::Push).unwrap();

	pull.bind("tcp://127.0.0.1:5459").unwrap();
	push.connect("tcp://127.0.0.1:5459").unwrap();

	let err = pull.recv().unwrap_err();

	assert_eq!(io::ErrorKind::TimedOut, err.kind());
}

#[test]
fn test_pair_connected_to_bound() {
	let session = Session::new().unwrap();
	let mut bound = session.create_socket(SocketType::Pair).unwrap();
	let mut connected = session.create_socket(SocketType::Pair).unwrap();

	bound.bind("tcp://127.0.0.1:5460").unwrap();
	connected.connect("tcp://127.0.0.1:5460").unwrap();

	let sent = vec![65, 66, 67];
	connected.send(sent).unwrap();
	let received = bound.recv().unwrap();

	assert_eq!(vec![65, 66, 67], received)
}

#[test]
fn test_pair_bound_to_connected() {
	let session = Session::new().unwrap();
	let mut bound = session.create_socket(SocketType::Pair).unwrap();
	let mut connected = session.create_socket(SocketType::Pair).unwrap();

	bound.bind("tcp://127.0.0.1:5461").unwrap();
	connected.connect("tcp://127.0.0.1:5461").unwrap();

	let sent = vec![65, 66, 67];
	bound.send(sent).unwrap();
	let received = connected.recv().unwrap();

	assert_eq!(vec![65, 66, 67], received)
}

#[test]
fn test_req_rep() {
	let session = Session::new().unwrap();
	let mut server = session.create_socket(SocketType::Rep).unwrap();
	let mut client = session.create_socket(SocketType::Req).unwrap();

	server.bind("tcp://127.0.0.1:5462").unwrap();
	client.connect("tcp://127.0.0.1:5462").unwrap();

	let client_request = vec!(65, 66, 67);
	client.send(client_request).unwrap();

	let server_request = server.recv().unwrap();
	assert_eq!(vec!(65, 66, 67), server_request);

	let server_reply = vec!(67, 66, 65);
	server.send(server_reply).unwrap();

	let client_reply = client.recv().unwrap();

	assert_eq!(vec!(67, 66, 65), client_reply);
}

#[test]
fn test_pub_sub() {
	let session = Session::new().unwrap();
	let mut server = session.create_socket(SocketType::Pub).unwrap();
	let mut client = session.create_socket(SocketType::Sub).unwrap();

	server.bind("tcp://127.0.0.1:5463").unwrap();
	client.connect("tcp://127.0.0.1:5463").unwrap();

	let sent = vec![65, 66, 67];
	server.send(sent).unwrap();
	let received = client.recv().unwrap();

	assert_eq!(vec![65, 66, 67], received);
}

#[test]
fn test_bus() {
	let session = Session::new().unwrap();
	let mut server = session.create_socket(SocketType::Bus).unwrap();
	let mut client1 = session.create_socket(SocketType::Bus).unwrap();
	let mut client2 = session.create_socket(SocketType::Bus).unwrap();

	server.bind("tcp://127.0.0.1:5464").unwrap();
	client1.connect("tcp://127.0.0.1:5464").unwrap();
	client2.connect("tcp://127.0.0.1:5464").unwrap();

	let sent = vec![65, 66, 67];
	server.send(sent).unwrap();
	let received1 = client1.recv().unwrap();
	assert_eq!(vec![65, 66, 67], received1);
	let received2 = client2.recv().unwrap();
	assert_eq!(vec![65, 66, 67], received2);
}

#[test]
fn test_survey() {
	let session = Session::new().unwrap();
	let mut server = session.create_socket(SocketType::Surveyor).unwrap();
	let mut client1 = session.create_socket(SocketType::Respondent).unwrap();
	let mut client2 = session.create_socket(SocketType::Respondent).unwrap();

	server.bind("tcp://127.0.0.1:5465").unwrap();
	client1.connect("tcp://127.0.0.1:5465").unwrap();
	client2.connect("tcp://127.0.0.1:5465").unwrap();

	let server_survey = vec!(65, 66, 67);
	server.send(server_survey).unwrap();

	let client1_survey = client1.recv().unwrap();
	assert_eq!(vec!(65, 66, 67), client1_survey);

	let client2_survey = client2.recv().unwrap();
	assert_eq!(vec!(65, 66, 67), client2_survey);

	client1.send(vec!(65, 66, 65)).unwrap();
	let server_resp1 = server.recv().unwrap();
	assert_eq!(vec!(65, 66, 65), server_resp1);

	client2.send(vec!(67, 66, 67)).unwrap();
	let server_resp2 = server.recv().unwrap();
	assert_eq!(vec!(67, 66, 67), server_resp2);
}

#[test]
fn test_send_reply_before_send_request() {
	let session = Session::new().unwrap();
	let mut server = session.create_socket(SocketType::Rep).unwrap();

	server.bind("tcp://127.0.0.1:5466").unwrap();
	server.send(vec!(67, 66, 65)).unwrap_err();
}

#[test]
fn test_recv_reply_before_send_request() {
	let session = Session::new().unwrap();
	let mut server = session.create_socket(SocketType::Rep).unwrap();
	let mut client = session.create_socket(SocketType::Req).unwrap();

	server.bind("tcp://127.0.0.1:5467").unwrap();
	client.connect("tcp://127.0.0.1:5467").unwrap();

	let err = client.recv().unwrap_err();
	assert_eq!(io::ErrorKind::Other, err.kind());
}
<|endoftext|>


<commit_before>fn print_number(x: i32)
{
    println!("x is: {}", x);
}

fn main ()
{
    let x: i32 = 40;

    print_number(x);
}
<commit_msg>more functions added<commit_after>fn print_number(x: i32)
{
    println!("x is: {}", x);
}

fn print_sum(x: i32, y: i32) {
    println!("sum is: {}", x + y);
}

/*
This reveals two interesting things about Rust: it is an expression-based language, and semicolons are different from semicolons in other ‘curly brace and semicolon’-based languages. These two things are related.
 */
fn add_one(x: i32) -> i32 {
    x + 1 //no semi-colon here
}

fn main ()
{
    let x: i32 = 40;

    print_number(x);

    print_sum(5, 6);

    let x: i32 = add_one(x);

    print_number(x);
}
<|endoftext|>


<commit_before>use eyre::{bail, Result};
use once_cell::sync::Lazy;
use serde::{Deserialize, Serialize};
use std::sync::{Mutex, MutexGuard};

pub type Subscriber = fn(topic: String, event: serde_json::Value) -> ();

struct Subscription {
    topic: String,
    subscriber: Subscriber,
}

static SUBSCRIPTIONS: Lazy<Mutex<Vec<Subscription>>> = Lazy::new(|| Mutex::new(Vec::new()));

/// Obtain the subscriptions store
fn obtain() -> Result<MutexGuard<'static, Vec<Subscription>>> {
    match SUBSCRIPTIONS.try_lock() {
        Ok(guard) => Ok(guard),
        Err(error) => bail!(
            "When attempting to obtain subscriptions: {}",
            error.to_string()
        ),
    }
}

/// Subscribe to a topic
pub fn subscribe(topic: &str, subscriber: Subscriber) -> Result<()> {
    let mut subscriptions = obtain()?;
    subscriptions.push(Subscription {
        topic: topic.to_string(),
        subscriber,
    });
    Ok(())
}

/// Publish an event for a topic
pub fn publish(topic: &str, event: serde_json::Value) -> Result<()> {
    let subscriptions = obtain()?;
    for subscription in &*subscriptions {
        if subscription.topic == "*" || subscription.topic == topic {
            (subscription.subscriber)(topic.into(), event.clone())
        }
    }
    Ok(())
}

/// A progress event
///
/// This is the expected structure of events published on the
/// "progress" topic channel. Although all events are simply `serde_json::Value`,
/// this `struct` provides expectations around the shape of those values
/// bot for publishers and subscribers.
#[derive(Default, Debug, Deserialize, Serialize)]
pub struct ProgressEvent {
    /// The id of the task that this progress event relates to
    pub id: Option<String>,

    /// The id of the parent task (if any)
    pub parent: Option<String>,

    /// The event message
    pub message: Option<String>,

    /// The current value
    pub current: Option<i64>,

    /// The expected value when complete
    pub expected: Option<i64>,

    // Whether or not the task is complete
    pub complete: bool,
}

/// Publish an event on the "progress" topic channel
pub fn publish_progress(event: ProgressEvent) -> Result<()> {
    return publish("progress", serde_json::to_value(event)?);
}
<commit_msg>chore(Rust): Linting<commit_after>use eyre::{bail, Result};
use once_cell::sync::Lazy;
use serde::{Deserialize, Serialize};
use std::sync::{Mutex, MutexGuard};

pub type Subscriber = fn(topic: String, event: serde_json::Value) -> ();

struct Subscription {
    topic: String,
    subscriber: Subscriber,
}

static SUBSCRIPTIONS: Lazy<Mutex<Vec<Subscription>>> = Lazy::new(|| Mutex::new(Vec::new()));

/// Obtain the subscriptions store
fn obtain() -> Result<MutexGuard<'static, Vec<Subscription>>> {
    match SUBSCRIPTIONS.try_lock() {
        Ok(guard) => Ok(guard),
        Err(error) => bail!(
            "When attempting to obtain subscriptions: {}",
            error.to_string()
        ),
    }
}

/// Subscribe to a topic
pub fn subscribe(topic: &str, subscriber: Subscriber) -> Result<()> {
    let mut subscriptions = obtain()?;
    subscriptions.push(Subscription {
        topic: topic.to_string(),
        subscriber,
    });
    Ok(())
}

/// Publish an event for a topic
pub fn publish(topic: &str, event: serde_json::Value) -> Result<()> {
    let subscriptions = obtain()?;
    for subscription in &*subscriptions {
        if subscription.topic == "*" || subscription.topic == topic {
            (subscription.subscriber)(topic.into(), event.clone())
        }
    }
    Ok(())
}

/// A progress event
///
/// This is the expected structure of events published on the
/// "progress" topic channel. Although all events are simply `serde_json::Value`,
/// this `struct` provides expectations around the shape of those values
/// bot for publishers and subscribers.
#[derive(Default, Debug, Deserialize, Serialize)]
pub struct ProgressEvent {
    /// The id of the task that this progress event relates to
    pub id: Option<String>,

    /// The id of the parent task (if any)
    pub parent: Option<String>,

    /// The event message
    pub message: Option<String>,

    /// The current value
    pub current: Option<i64>,

    /// The expected value when complete
    pub expected: Option<i64>,

    // Whether or not the task is complete
    pub complete: bool,
}

/// Publish an event on the "progress" topic channel
pub fn publish_progress(event: ProgressEvent) -> Result<()> {
    publish("progress", serde_json::to_value(event)?)
}
<|endoftext|>


<commit_before>use std::fmt;

use crate::yaml::Yaml;

#[allow(dead_code)]
#[derive(Copy, Clone, Eq, PartialEq)]
pub enum Env {
    WindowsLatest,
    UbuntuLatest,
    MacosLatest,
}

impl Default for Env {
    fn default() -> Self {
        Env::UbuntuLatest
    }
}

impl fmt::Display for Env {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            Env::WindowsLatest => write!(f, "windows-latest"),
            Env::UbuntuLatest => write!(f, "ubuntu-latest"),
            Env::MacosLatest => write!(f, "macos-latest"),
        }
    }
}

/// Github workflow step
#[derive(Default)]
pub struct Step {
    pub name: String,
    pub uses: Option<String>,
    pub with: Option<Yaml>,
    pub run: Option<String>,
    pub shell: Option<String>,
    pub env: Vec<(String, String)>,
}

impl Step {
    pub fn uses(name: &str, uses: &str) -> Step {
        Step {
            name: name.to_owned(),
            uses: Some(uses.to_owned()),
            ..Default::default()
        }
    }

    pub fn uses_with(name: &str, uses: &str, with: Yaml) -> Step {
        Step {
            name: name.to_owned(),
            uses: Some(uses.to_owned()),
            with: Some(with),
            ..Default::default()
        }
    }

    pub fn uses_env_with(name: &str, uses: &str, env: &[(&str, &str)], with: Yaml) -> Step {
        Step {
            name: name.to_owned(),
            uses: Some(uses.to_owned()),
            env: env
                .into_iter()
                .map(|(k, v)| (String::from(*k), String::from(*v)))
                .collect(),
            with: Some(with),
            ..Default::default()
        }
    }

    pub fn run(name: &str, run: &str) -> Step {
        Step {
            name: name.to_owned(),
            run: Some(run.to_owned()),
            shell: Some("bash".to_owned()),
            ..Default::default()
        }
    }
}

impl Step {
    pub fn env(mut self, name: &str, value: &str) -> Self {
        self.env.push((name.to_owned(), value.to_owned()));
        self
    }
}

impl Into<Yaml> for Step {
    fn into(self) -> Yaml {
        let Step {
            name,
            uses,
            with,
            run,
            shell,
            env,
        } = self;
        let mut entries = Vec::new();
        entries.push(("name", Yaml::string(name)));
        if let Some(uses) = uses {
            entries.push(("uses", Yaml::string(uses)));
        }
        if let Some(with) = with {
            entries.push(("with", with));
        }
        if let Some(run) = run {
            entries.push(("run", Yaml::string(run)));
        }
        if let Some(shell) = shell {
            entries.push(("shell", Yaml::string(shell)));
        }
        if !env.is_empty() {
            entries.push(("env", Yaml::map(env)));
        }
        Yaml::map(entries)
    }
}

#[derive(Default)]
pub struct Job {
    pub id: String,
    pub name: String,
    pub runs_on: Env,
    pub steps: Vec<Step>,
    pub timeout_minutes: Option<u64>,
    pub env: Vec<(String, String)>,
}

impl Job {
    #[allow(dead_code)]
    pub fn step(mut self, step: Step) -> Self {
        self.steps.push(step);
        self
    }
}

impl Into<(String, Yaml)> for Job {
    fn into(self) -> (String, Yaml) {
        assert!(!self.id.is_empty());
        let mut entries = vec![
            ("name", Yaml::string(self.name)),
            ("runs-on", Yaml::string(format!("{}", self.runs_on))),
        ];
        if let Some(timeout_minutes) = self.timeout_minutes {
            entries.push(("timeout-minutes", Yaml::string(format!("{}", timeout_minutes))));
        }
        if !self.env.is_empty() {
            entries.push(("env", Yaml::map(self.env)));
        }
        entries.push(("steps", Yaml::list(self.steps)));
        (self.id, Yaml::map(entries))
    }
}
<commit_msg>cargo fmt<commit_after>use std::fmt;

use crate::yaml::Yaml;

#[allow(dead_code)]
#[derive(Copy, Clone, Eq, PartialEq)]
pub enum Env {
    WindowsLatest,
    UbuntuLatest,
    MacosLatest,
}

impl Default for Env {
    fn default() -> Self {
        Env::UbuntuLatest
    }
}

impl fmt::Display for Env {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            Env::WindowsLatest => write!(f, "windows-latest"),
            Env::UbuntuLatest => write!(f, "ubuntu-latest"),
            Env::MacosLatest => write!(f, "macos-latest"),
        }
    }
}

/// Github workflow step
#[derive(Default)]
pub struct Step {
    pub name: String,
    pub uses: Option<String>,
    pub with: Option<Yaml>,
    pub run: Option<String>,
    pub shell: Option<String>,
    pub env: Vec<(String, String)>,
}

impl Step {
    pub fn uses(name: &str, uses: &str) -> Step {
        Step {
            name: name.to_owned(),
            uses: Some(uses.to_owned()),
            ..Default::default()
        }
    }

    pub fn uses_with(name: &str, uses: &str, with: Yaml) -> Step {
        Step {
            name: name.to_owned(),
            uses: Some(uses.to_owned()),
            with: Some(with),
            ..Default::default()
        }
    }

    pub fn uses_env_with(name: &str, uses: &str, env: &[(&str, &str)], with: Yaml) -> Step {
        Step {
            name: name.to_owned(),
            uses: Some(uses.to_owned()),
            env: env
                .into_iter()
                .map(|(k, v)| (String::from(*k), String::from(*v)))
                .collect(),
            with: Some(with),
            ..Default::default()
        }
    }

    pub fn run(name: &str, run: &str) -> Step {
        Step {
            name: name.to_owned(),
            run: Some(run.to_owned()),
            shell: Some("bash".to_owned()),
            ..Default::default()
        }
    }
}

impl Step {
    pub fn env(mut self, name: &str, value: &str) -> Self {
        self.env.push((name.to_owned(), value.to_owned()));
        self
    }
}

impl Into<Yaml> for Step {
    fn into(self) -> Yaml {
        let Step {
            name,
            uses,
            with,
            run,
            shell,
            env,
        } = self;
        let mut entries = Vec::new();
        entries.push(("name", Yaml::string(name)));
        if let Some(uses) = uses {
            entries.push(("uses", Yaml::string(uses)));
        }
        if let Some(with) = with {
            entries.push(("with", with));
        }
        if let Some(run) = run {
            entries.push(("run", Yaml::string(run)));
        }
        if let Some(shell) = shell {
            entries.push(("shell", Yaml::string(shell)));
        }
        if !env.is_empty() {
            entries.push(("env", Yaml::map(env)));
        }
        Yaml::map(entries)
    }
}

#[derive(Default)]
pub struct Job {
    pub id: String,
    pub name: String,
    pub runs_on: Env,
    pub steps: Vec<Step>,
    pub timeout_minutes: Option<u64>,
    pub env: Vec<(String, String)>,
}

impl Job {
    #[allow(dead_code)]
    pub fn step(mut self, step: Step) -> Self {
        self.steps.push(step);
        self
    }
}

impl Into<(String, Yaml)> for Job {
    fn into(self) -> (String, Yaml) {
        assert!(!self.id.is_empty());
        let mut entries = vec![
            ("name", Yaml::string(self.name)),
            ("runs-on", Yaml::string(format!("{}", self.runs_on))),
        ];
        if let Some(timeout_minutes) = self.timeout_minutes {
            entries.push((
                "timeout-minutes",
                Yaml::string(format!("{}", timeout_minutes)),
            ));
        }
        if !self.env.is_empty() {
            entries.push(("env", Yaml::map(self.env)));
        }
        entries.push(("steps", Yaml::list(self.steps)));
        (self.id, Yaml::map(entries))
    }
}
<|endoftext|>


<commit_before>extern crate bytes;

use self::bytes::{BufMut, BytesMut};
use super::ethereum_types::H256;
use super::{Encodable, SszStream};

/*
 * Note: there is a "to_bytes" function for integers
 * in Rust nightly. When it is in stable, we should
 * use it instead.
 */
macro_rules! impl_encodable_for_uint {
    ($type: ident, $bit_size: expr) => {
        impl Encodable for $type {
            #[allow(cast_lossless)]
            fn ssz_append(&self, s: &mut SszStream) {
                // Ensure bit size is valid
                assert!(
                    (0 < $bit_size)
                        && ($bit_size % 8 == 0)
                        && (2_u128.pow($bit_size) > *self as u128)
                );

                // Serialize to bytes
                let mut buf = BytesMut::with_capacity($bit_size / 8);

                // Match bit size with encoding
                match $bit_size {
                    8 => buf.put_u8(*self as u8),
                    16 => buf.put_u16_be(*self as u16),
                    32 => buf.put_u32_be(*self as u32),
                    64 => buf.put_u64_be(*self as u64),
                    _ => {}
                }

                // Append bytes to the SszStream
                s.append_encoded_raw(&buf.to_vec());
            }
        }
    };
}

impl_encodable_for_uint!(u8, 8);
impl_encodable_for_uint!(u16, 16);
impl_encodable_for_uint!(u32, 32);
impl_encodable_for_uint!(u64, 64);
impl_encodable_for_uint!(usize, 64);

impl Encodable for H256 {
    fn ssz_append(&self, s: &mut SszStream) {
        s.append_encoded_raw(&self.to_vec());
    }
}

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

    #[test]
    fn test_ssz_encode_h256() {
        let h = H256::zero();
        let mut ssz = SszStream::new();
        ssz.append(&h);
        assert_eq!(ssz.drain(), vec![0; 32]);
    }

    #[test]
    fn test_ssz_encode_u8() {
        let x: u8 = 0;
        let mut ssz = SszStream::new();
        ssz.append(&x);
        assert_eq!(ssz.drain(), vec![0]);

        let x: u8 = 1;
        let mut ssz = SszStream::new();
        ssz.append(&x);
        assert_eq!(ssz.drain(), vec![1]);

        let x: u8 = 100;
        let mut ssz = SszStream::new();
        ssz.append(&x);
        assert_eq!(ssz.drain(), vec![100]);

        let x: u8 = 255;
        let mut ssz = SszStream::new();
        ssz.append(&x);
        assert_eq!(ssz.drain(), vec![255]);
    }

    #[test]
    fn test_ssz_encode_u16() {
        let x: u16 = 1;
        let mut ssz = SszStream::new();
        ssz.append(&x);
        assert_eq!(ssz.drain(), vec![0, 1]);

        let x: u16 = 100;
        let mut ssz = SszStream::new();
        ssz.append(&x);
        assert_eq!(ssz.drain(), vec![0, 100]);

        let x: u16 = 1 << 8;
        let mut ssz = SszStream::new();
        ssz.append(&x);
        assert_eq!(ssz.drain(), vec![1, 0]);

        let x: u16 = 65535;
        let mut ssz = SszStream::new();
        ssz.append(&x);
        assert_eq!(ssz.drain(), vec![255, 255]);
    }

    #[test]
    fn test_ssz_encode_u32() {
        let x: u32 = 1;
        let mut ssz = SszStream::new();
        ssz.append(&x);
        assert_eq!(ssz.drain(), vec![0, 0, 0, 1]);

        let x: u32 = 100;
        let mut ssz = SszStream::new();
        ssz.append(&x);
        assert_eq!(ssz.drain(), vec![0, 0, 0, 100]);

        let x: u32 = 1 << 16;
        let mut ssz = SszStream::new();
        ssz.append(&x);
        assert_eq!(ssz.drain(), vec![0, 1, 0, 0]);

        let x: u32 = 1 << 24;
        let mut ssz = SszStream::new();
        ssz.append(&x);
        assert_eq!(ssz.drain(), vec![1, 0, 0, 0]);

        let x: u32 = !0;
        let mut ssz = SszStream::new();
        ssz.append(&x);
        assert_eq!(ssz.drain(), vec![255, 255, 255, 255]);
    }

    #[test]
    fn test_ssz_encode_u64() {
        let x: u64 = 1;
        let mut ssz = SszStream::new();
        ssz.append(&x);
        assert_eq!(ssz.drain(), vec![0, 0, 0, 0, 0, 0, 0, 1]);

        let x: u64 = 100;
        let mut ssz = SszStream::new();
        ssz.append(&x);
        assert_eq!(ssz.drain(), vec![0, 0, 0, 0, 0, 0, 0, 100]);

        let x: u64 = 1 << 32;
        let mut ssz = SszStream::new();
        ssz.append(&x);
        assert_eq!(ssz.drain(), vec![0, 0, 0, 1, 0, 0, 0, 0]);

        let x: u64 = !0;
        let mut ssz = SszStream::new();
        ssz.append(&x);
        assert_eq!(ssz.drain(), vec![255, 255, 255, 255, 255, 255, 255, 255]);
    }

    #[test]
    fn test_ssz_encode_usize() {
        let x: usize = 1;
        let mut ssz = SszStream::new();
        ssz.append(&x);
        assert_eq!(ssz.drain(), vec![0, 0, 0, 0, 0, 0, 0, 1]);

        let x: usize = 100;
        let mut ssz = SszStream::new();
        ssz.append(&x);
        assert_eq!(ssz.drain(), vec![0, 0, 0, 0, 0, 0, 0, 100]);

        let x: usize = 1 << 32;
        let mut ssz = SszStream::new();
        ssz.append(&x);
        assert_eq!(ssz.drain(), vec![0, 0, 0, 1, 0, 0, 0, 0]);

        let x: usize = !0;
        let mut ssz = SszStream::new();
        ssz.append(&x);
        assert_eq!(ssz.drain(), vec![255, 255, 255, 255, 255, 255, 255, 255]);
    }
}
<commit_msg>Fix clippy lint in ssz<commit_after>extern crate bytes;

use self::bytes::{BufMut, BytesMut};
use super::ethereum_types::H256;
use super::{Encodable, SszStream};

/*
 * Note: there is a "to_bytes" function for integers
 * in Rust nightly. When it is in stable, we should
 * use it instead.
 */
macro_rules! impl_encodable_for_uint {
    ($type: ident, $bit_size: expr) => {
        impl Encodable for $type {
            #[allow(clippy::cast_lossless)]
            fn ssz_append(&self, s: &mut SszStream) {
                // Ensure bit size is valid
                assert!(
                    (0 < $bit_size)
                        && ($bit_size % 8 == 0)
                        && (2_u128.pow($bit_size) > *self as u128)
                );

                // Serialize to bytes
                let mut buf = BytesMut::with_capacity($bit_size / 8);

                // Match bit size with encoding
                match $bit_size {
                    8 => buf.put_u8(*self as u8),
                    16 => buf.put_u16_be(*self as u16),
                    32 => buf.put_u32_be(*self as u32),
                    64 => buf.put_u64_be(*self as u64),
                    _ => {}
                }

                // Append bytes to the SszStream
                s.append_encoded_raw(&buf.to_vec());
            }
        }
    };
}

impl_encodable_for_uint!(u8, 8);
impl_encodable_for_uint!(u16, 16);
impl_encodable_for_uint!(u32, 32);
impl_encodable_for_uint!(u64, 64);
impl_encodable_for_uint!(usize, 64);

impl Encodable for H256 {
    fn ssz_append(&self, s: &mut SszStream) {
        s.append_encoded_raw(&self.to_vec());
    }
}

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

    #[test]
    fn test_ssz_encode_h256() {
        let h = H256::zero();
        let mut ssz = SszStream::new();
        ssz.append(&h);
        assert_eq!(ssz.drain(), vec![0; 32]);
    }

    #[test]
    fn test_ssz_encode_u8() {
        let x: u8 = 0;
        let mut ssz = SszStream::new();
        ssz.append(&x);
        assert_eq!(ssz.drain(), vec![0]);

        let x: u8 = 1;
        let mut ssz = SszStream::new();
        ssz.append(&x);
        assert_eq!(ssz.drain(), vec![1]);

        let x: u8 = 100;
        let mut ssz = SszStream::new();
        ssz.append(&x);
        assert_eq!(ssz.drain(), vec![100]);

        let x: u8 = 255;
        let mut ssz = SszStream::new();
        ssz.append(&x);
        assert_eq!(ssz.drain(), vec![255]);
    }

    #[test]
    fn test_ssz_encode_u16() {
        let x: u16 = 1;
        let mut ssz = SszStream::new();
        ssz.append(&x);
        assert_eq!(ssz.drain(), vec![0, 1]);

        let x: u16 = 100;
        let mut ssz = SszStream::new();
        ssz.append(&x);
        assert_eq!(ssz.drain(), vec![0, 100]);

        let x: u16 = 1 << 8;
        let mut ssz = SszStream::new();
        ssz.append(&x);
        assert_eq!(ssz.drain(), vec![1, 0]);

        let x: u16 = 65535;
        let mut ssz = SszStream::new();
        ssz.append(&x);
        assert_eq!(ssz.drain(), vec![255, 255]);
    }

    #[test]
    fn test_ssz_encode_u32() {
        let x: u32 = 1;
        let mut ssz = SszStream::new();
        ssz.append(&x);
        assert_eq!(ssz.drain(), vec![0, 0, 0, 1]);

        let x: u32 = 100;
        let mut ssz = SszStream::new();
        ssz.append(&x);
        assert_eq!(ssz.drain(), vec![0, 0, 0, 100]);

        let x: u32 = 1 << 16;
        let mut ssz = SszStream::new();
        ssz.append(&x);
        assert_eq!(ssz.drain(), vec![0, 1, 0, 0]);

        let x: u32 = 1 << 24;
        let mut ssz = SszStream::new();
        ssz.append(&x);
        assert_eq!(ssz.drain(), vec![1, 0, 0, 0]);

        let x: u32 = !0;
        let mut ssz = SszStream::new();
        ssz.append(&x);
        assert_eq!(ssz.drain(), vec![255, 255, 255, 255]);
    }

    #[test]
    fn test_ssz_encode_u64() {
        let x: u64 = 1;
        let mut ssz = SszStream::new();
        ssz.append(&x);
        assert_eq!(ssz.drain(), vec![0, 0, 0, 0, 0, 0, 0, 1]);

        let x: u64 = 100;
        let mut ssz = SszStream::new();
        ssz.append(&x);
        assert_eq!(ssz.drain(), vec![0, 0, 0, 0, 0, 0, 0, 100]);

        let x: u64 = 1 << 32;
        let mut ssz = SszStream::new();
        ssz.append(&x);
        assert_eq!(ssz.drain(), vec![0, 0, 0, 1, 0, 0, 0, 0]);

        let x: u64 = !0;
        let mut ssz = SszStream::new();
        ssz.append(&x);
        assert_eq!(ssz.drain(), vec![255, 255, 255, 255, 255, 255, 255, 255]);
    }

    #[test]
    fn test_ssz_encode_usize() {
        let x: usize = 1;
        let mut ssz = SszStream::new();
        ssz.append(&x);
        assert_eq!(ssz.drain(), vec![0, 0, 0, 0, 0, 0, 0, 1]);

        let x: usize = 100;
        let mut ssz = SszStream::new();
        ssz.append(&x);
        assert_eq!(ssz.drain(), vec![0, 0, 0, 0, 0, 0, 0, 100]);

        let x: usize = 1 << 32;
        let mut ssz = SszStream::new();
        ssz.append(&x);
        assert_eq!(ssz.drain(), vec![0, 0, 0, 1, 0, 0, 0, 0]);

        let x: usize = !0;
        let mut ssz = SszStream::new();
        ssz.append(&x);
        assert_eq!(ssz.drain(), vec![255, 255, 255, 255, 255, 255, 255, 255]);
    }
}
<|endoftext|>


<commit_before>#[macro_use]
extern crate cpp;
extern crate libc;

#[macro_use]
extern crate uucore;

use libc::{c_char, c_int, size_t, FILE, _IOFBF, _IOLBF, _IONBF};
use std::env;
use std::ptr;

cpp! {{
    #include <cstdio>

    extern "C" {
        void __stdbuf(void);

        void __attribute((constructor))
        __stdbuf_init(void) {
            __stdbuf();
        }

        FILE *__stdbuf_get_stdin() { return stdin; }
        FILE *__stdbuf_get_stdout() { return stdout; }
        FILE *__stdbuf_get_stderr() { return stderr; }
    }
}}

extern "C" {
    fn __stdbuf_get_stdin() -> *mut FILE;
    fn __stdbuf_get_stdout() -> *mut FILE;
    fn __stdbuf_get_stderr() -> *mut FILE;
}

fn set_buffer(stream: *mut FILE, value: &str) {
    let (mode, size): (c_int, size_t) = match value {
        "0" => (_IONBF, 0 as size_t),
        "L" => (_IOLBF, 0 as size_t),
        input => {
            let buff_size: usize = match input.parse() {
                Ok(num) => num,
                Err(e) => crash!(1, "incorrect size of buffer!: {}", e),
            };
            (_IOFBF, buff_size as size_t)
        }
    };
    let res: c_int;
    unsafe {
        let buffer: *mut c_char = ptr::null_mut();
        assert!(buffer.is_null());
        res = libc::setvbuf(stream, buffer, mode, size);
    }
    if res != 0 {
        crash!(res, "error while calling setvbuf!");
    }
}

#[no_mangle]
pub unsafe extern "C" fn __stdbuf() {
    if let Ok(val) = env::var("_STDBUF_E") {
        set_buffer(__stdbuf_get_stderr(), &val);
    }
    if let Ok(val) = env::var("_STDBUF_I") {
        set_buffer(__stdbuf_get_stdin(), &val);
    }
    if let Ok(val) = env::var("_STDBUF_O") {
        set_buffer(__stdbuf_get_stdout(), &val);
    }
}
<commit_msg>refactor/polish ~ fix `cargo clippy` complaints (missing_safety_doc; with ToDO for safety note)<commit_after>#[macro_use]
extern crate cpp;
extern crate libc;

#[macro_use]
extern crate uucore;

use libc::{c_char, c_int, size_t, FILE, _IOFBF, _IOLBF, _IONBF};
use std::env;
use std::ptr;

cpp! {{
    #include <cstdio>

    extern "C" {
        void __stdbuf(void);

        void __attribute((constructor))
        __stdbuf_init(void) {
            __stdbuf();
        }

        FILE *__stdbuf_get_stdin() { return stdin; }
        FILE *__stdbuf_get_stdout() { return stdout; }
        FILE *__stdbuf_get_stderr() { return stderr; }
    }
}}

extern "C" {
    fn __stdbuf_get_stdin() -> *mut FILE;
    fn __stdbuf_get_stdout() -> *mut FILE;
    fn __stdbuf_get_stderr() -> *mut FILE;
}

fn set_buffer(stream: *mut FILE, value: &str) {
    let (mode, size): (c_int, size_t) = match value {
        "0" => (_IONBF, 0 as size_t),
        "L" => (_IOLBF, 0 as size_t),
        input => {
            let buff_size: usize = match input.parse() {
                Ok(num) => num,
                Err(e) => crash!(1, "incorrect size of buffer!: {}", e),
            };
            (_IOFBF, buff_size as size_t)
        }
    };
    let res: c_int;
    unsafe {
        let buffer: *mut c_char = ptr::null_mut();
        assert!(buffer.is_null());
        res = libc::setvbuf(stream, buffer, mode, size);
    }
    if res != 0 {
        crash!(res, "error while calling setvbuf!");
    }
}

/// # Safety
/// ToDO ... (safety note)
#[no_mangle]
pub unsafe extern "C" fn __stdbuf() {
    if let Ok(val) = env::var("_STDBUF_E") {
        set_buffer(__stdbuf_get_stderr(), &val);
    }
    if let Ok(val) = env::var("_STDBUF_I") {
        set_buffer(__stdbuf_get_stdin(), &val);
    }
    if let Ok(val) = env::var("_STDBUF_O") {
        set_buffer(__stdbuf_get_stdout(), &val);
    }
}
<|endoftext|>