<commit_before>// CarbonReporter sends a message to a carbon end point at a regular basis.
use registry::{Registry, StdRegistry};
use std::time::Duration;
use std::thread;
use std::sync::Arc;
use reporter::base::Reporter;
use metrics::counter::StdCounter;
use metrics::gauge::StdGauge;
use metrics::meter::MeterSnapshot;
use histogram::Histogram;
use time;
use time::Timespec;
use std::net::TcpStream;
use std::io::Write;
use std::io::Error;

struct CarbonStream {
    graphite_stream: Option<TcpStream>,
    host_and_port: String,
}

// TODO perhaps we autodiscover the host and port
//
pub struct CarbonReporter {
    host_and_port: String,
    prefix: &'static str,
    registry: Arc<StdRegistry<'static>>,
    reporter_name: &'static str,
}

impl CarbonStream {
    pub fn new(host_and_port: String) -> CarbonStream {
        CarbonStream {
            host_and_port: host_and_port,
            graphite_stream: None,
        }
    }

    pub fn connect(&mut self) -> Result<String, Error> {
        let graphite_stream = try!(TcpStream::connect(&*self.host_and_port));
        self.graphite_stream = Some(graphite_stream);
        Ok(String::from(""))
    }

    pub fn write(&mut self, metric_path: String, value: String, timespec: Timespec) -> Result<String, Error> {
        let seconds_in_ms = (timespec.sec * 1000) as u32;
        let nseconds_in_ms = (timespec.nsec / 1000) as u32;
        let timestamp = seconds_in_ms + nseconds_in_ms;
        match self.graphite_stream {
            Some(ref mut stream) => {
                let carbon_command = format!("{} {} {}\n", metric_path, value, timestamp)
                    .into_bytes();
                try!(stream.write_all(&carbon_command));
            }
            None => {
                try!(self.reconnect_stream());
                try!(self.write(metric_path, value, timespec));
            }
        }
        Ok(String::from(""))
    }
    fn reconnect_stream(&mut self) -> Result<String, Error> {
        // TODO 123 is made up
        println!("Waiting 123ms and then reconnecting");
        thread::sleep(Duration::from_millis(123));
        self.connect()
    }
}

impl Reporter for CarbonReporter {
    fn get_unique_reporter_name(&self) -> &'static str {
        self.reporter_name
    }
}

fn prefix(metric_line: String, prefix_str: &'static str) -> String {
    format!("{}.{}", prefix_str, metric_line)
}

fn send_meter_metric(metric_name: &str,
                     meter: MeterSnapshot,
                     carbon: &mut CarbonStream,
                     prefix_str: &'static str,
                     ts: Timespec) {

    let count = meter.count.to_string();
    let m1_rate = meter.rates[0].to_string();
    let m5_rate = meter.rates[1].to_string();
    let m15_rate = meter.rates[2].to_string();
    let mean_rate = meter.mean.to_string();
    carbon.write(prefix(format!("{}.count", metric_name), prefix_str),
                 count,
                 ts);
    carbon.write(prefix(format!("{}.m1", metric_name), prefix_str),
                 m1_rate,
                 ts);
    carbon.write(prefix(format!("{}.m5", metric_name), prefix_str),
                 m5_rate,
                 ts);
    carbon.write(prefix(format!("{}.m15", metric_name), prefix_str),
                 m15_rate,
                 ts);
    carbon.write(prefix(format!("{}.mean", metric_name), prefix_str),
                 mean_rate,
                 ts);
}

fn send_gauge_metric(metric_name: &str,
                     gauge: StdGauge,
                     carbon: &mut CarbonStream,
                     prefix_str: &'static str,
                     ts: Timespec) {
    carbon.write(prefix(format!("{}", metric_name), prefix_str),
                 gauge.value.to_string(),
                 ts);
}

fn send_counter_metric(metric_name: &str,
                       counter: StdCounter,
                       carbon: &mut CarbonStream,
                       prefix_str: &'static str,
                       ts: Timespec) {
    carbon.write(prefix(format!("{}", metric_name), prefix_str),
                 counter.value.to_string(),
                 ts);
}
fn send_histogram_metric(metric_name: &str,
                         histogram: &mut Histogram,
                         carbon: &mut CarbonStream,
                         prefix_str: &'static str,
                         ts: Timespec) {
    let count = histogram.count();
    // let sum = histogram.sum();
    // let mean = sum / count;
    let max = histogram.percentile(100.0).unwrap();
    let min = histogram.percentile(0.0).unwrap();

    let p50 = histogram.percentile(50.0).unwrap();
    let p75 = histogram.percentile(75.0).unwrap();
    let p95 = histogram.percentile(95.0).unwrap();
    let p98 = histogram.percentile(98.0).unwrap();
    let p99 = histogram.percentile(99.0).unwrap();
    let p999 = histogram.percentile(99.9).unwrap();
    let p9999 = histogram.percentile(99.99).unwrap();
    let p99999 = histogram.percentile(99.999).unwrap();

    carbon.write(prefix(format!("{}.count", metric_name), prefix_str),
                 count.to_string(),
                 ts);

    carbon.write(prefix(format!("{}.max", metric_name), prefix_str),
                 max.to_string(),
                 ts);

    // carbon
    // .write(prefix(format!("{}.mean", metric_name), prefix_str),
    // mean.into_string(),
    // ts);

    carbon.write(prefix(format!("{}.min", metric_name), prefix_str),
                 min.to_string(),
                 ts);

    carbon.write(prefix(format!("{}.p50", metric_name), prefix_str),
                 p50.to_string(),
                 ts);

    carbon.write(prefix(format!("{}.p75", metric_name), prefix_str),
                 p75.to_string(),
                 ts);

    carbon.write(prefix(format!("{}.p95", metric_name), prefix_str),
                 p95.to_string(),
                 ts);

    carbon.write(prefix(format!("{}.p98", metric_name), prefix_str),
                 p98.to_string(),
                 ts);

    carbon.write(prefix(format!("{}.p99", metric_name), prefix_str),
                 p99.to_string(),
                 ts);

    carbon.write(prefix(format!("{}.p999", metric_name), prefix_str),
                 p999.to_string(),
                 ts);

    carbon.write(prefix(format!("{}.p9999", metric_name), prefix_str),
                 p9999.to_string(),
                 ts);

    carbon.write(prefix(format!("{}.p99999", metric_name), prefix_str),
                 p99999.to_string(),
                 ts);
}

impl CarbonReporter {
    pub fn new(registry: Arc<StdRegistry<'static>>,
               reporter_name: &'static str,
               host_and_port: String,
               prefix: &'static str)
               -> CarbonReporter {
        CarbonReporter {
            host_and_port: host_and_port,
            prefix: prefix,
            registry: registry,
            reporter_name: reporter_name,
        }
    }

    fn report_to_carbon_continuously(self, delay_ms: u32) -> thread::JoinHandle<()> {
        use metrics::metric::MetricValue::{Counter, Gauge, Histogram, Meter};

        let prefix = self.prefix;
        let host_and_port = self.host_and_port.clone();
        let mut carbon = CarbonStream::new(host_and_port);
        let registry = self.registry.clone();
        thread::spawn(move || {
            loop {
                let ts = time::now().to_timespec();
                for metric_name in &registry.get_metrics_names() {
                    let metric = registry.get(metric_name);
                    match metric.export_metric() {
                        Meter(x) => send_meter_metric(metric_name, x, &mut carbon, prefix, ts),
                        Gauge(x) => send_gauge_metric(metric_name, x, &mut carbon, prefix, ts),
                        Counter(x) => send_counter_metric(metric_name, x, &mut carbon, prefix, ts),
                        Histogram(mut x) => {
                            send_histogram_metric(metric_name, &mut x, &mut carbon, prefix, ts)
                        }
                    }
                }
                thread::sleep(Duration::from_millis(delay_ms as u64));
            }
        })
    }

    pub fn start(self, delay_ms: u32) {
        self.report_to_carbon_continuously(delay_ms);
    }
}

#[cfg(test)]
mod test {
    use metrics::meter::{Meter, StdMeter};
    use metrics::counter::{Counter, StdCounter};
    use metrics::gauge::{Gauge, StdGauge};
    use registry::{Registry, StdRegistry};
    use reporter::carbon::CarbonReporter;
    use std::sync::Arc;
    use std::thread;
    use histogram::*;

    #[test]
    fn meter() {
        let m = StdMeter::new();
        m.mark(100);

        let mut c: StdCounter = StdCounter::new();
        c.inc();

        let mut g: StdGauge = StdGauge { value: 0f64 };
        g.set(1.2);

        let mut hc = HistogramConfig::new();
        hc.max_value(100).precision(1);
        let mut h = Histogram::configured(hc).unwrap();

        h.record(1, 1);

        let mut r = StdRegistry::new();
        r.insert("meter1", m);
        r.insert("counter1", c);
        r.insert("gauge1", g);
        r.insert("histogram", h);

        let arc_registry = Arc::new(r);
        CarbonReporter::new(arc_registry.clone(),
                            "test",
                            "localhost:0".to_string(),
                            "asd.asdf");
    }
}
<commit_msg>Fix unwrapping behavior in carbon<commit_after>// CarbonReporter sends a message to a carbon end point at a regular basis.
use registry::{Registry, StdRegistry};
use std::time::Duration;
use std::thread;
use std::sync::Arc;
use reporter::base::Reporter;
use metrics::counter::StdCounter;
use metrics::gauge::StdGauge;
use metrics::meter::MeterSnapshot;
use histogram::Histogram;
use time;
use time::Timespec;
use std::net::TcpStream;
use std::io::Write;
use std::io::Error;

struct CarbonStream {
    graphite_stream: Option<TcpStream>,
    host_and_port: String,
}

// TODO perhaps we autodiscover the host and port
//
pub struct CarbonReporter {
    host_and_port: String,
    prefix: &'static str,
    registry: Arc<StdRegistry<'static>>,
    reporter_name: &'static str,
}

impl CarbonStream {
    pub fn new(host_and_port: String) -> CarbonStream {
        CarbonStream {
            host_and_port: host_and_port,
            graphite_stream: None,
        }
    }

    pub fn connect(&mut self) -> Result<String, Error> {
        let graphite_stream = try!(TcpStream::connect(&*self.host_and_port));
        self.graphite_stream = Some(graphite_stream);
        Ok(String::from(""))
    }

    pub fn write(&mut self, metric_path: String, value: String, timespec: Timespec) -> Result<String, Error> {
        let seconds_in_ms = (timespec.sec * 1000) as u32;
        let nseconds_in_ms = (timespec.nsec / 1000) as u32;
        let timestamp = seconds_in_ms + nseconds_in_ms;
        match self.graphite_stream {
            Some(ref mut stream) => {
                let carbon_command = format!("{} {} {}\n", metric_path, value, timestamp)
                    .into_bytes();
                try!(stream.write_all(&carbon_command));
            }
            None => {
                try!(self.reconnect_stream());
                try!(self.write(metric_path, value, timespec));
            }
        }
        Ok(String::from(""))
    }
    fn reconnect_stream(&mut self) -> Result<String, Error> {
        // TODO 123 is made up
        println!("Waiting 123ms and then reconnecting");
        thread::sleep(Duration::from_millis(123));
        self.connect()
    }
}

impl Reporter for CarbonReporter {
    fn get_unique_reporter_name(&self) -> &'static str {
        self.reporter_name
    }
}

fn prefix(metric_line: String, prefix_str: &'static str) -> String {
    format!("{}.{}", prefix_str, metric_line)
}

fn send_meter_metric(metric_name: &str,
                     meter: MeterSnapshot,
                     carbon: &mut CarbonStream,
                     prefix_str: &'static str,
                     ts: Timespec) -> Result<String, Error> {

    let count = meter.count.to_string();
    let m1_rate = meter.rates[0].to_string();
    let m5_rate = meter.rates[1].to_string();
    let m15_rate = meter.rates[2].to_string();
    let mean_rate = meter.mean.to_string();
    try!(carbon.write(prefix(format!("{}.count", metric_name), prefix_str),
                 count,
                 ts));
    try!(carbon.write(prefix(format!("{}.m1", metric_name), prefix_str),
                 m1_rate,
                 ts));
    try!(carbon.write(prefix(format!("{}.m5", metric_name), prefix_str),
                 m5_rate,
                 ts));
    try!(carbon.write(prefix(format!("{}.m15", metric_name), prefix_str),
                 m15_rate,
                 ts));
    try!(carbon.write(prefix(format!("{}.mean", metric_name), prefix_str),
                 mean_rate,
                 ts));
    Ok(String::from(""))
}

fn send_gauge_metric(metric_name: &str,
                     gauge: StdGauge,
                     carbon: &mut CarbonStream,
                     prefix_str: &'static str,
                     ts: Timespec) -> Result<String, Error> {
    try!(carbon.write(prefix(format!("{}", metric_name), prefix_str),
                 gauge.value.to_string(),
                 ts));
    Ok(String::from(""))
}

fn send_counter_metric(metric_name: &str,
                       counter: StdCounter,
                       carbon: &mut CarbonStream,
                       prefix_str: &'static str,
                       ts: Timespec) -> Result<String, Error> {
    try!(carbon.write(prefix(format!("{}", metric_name), prefix_str),
                 counter.value.to_string(),
                 ts));
    Ok(String::from(""))
}
fn send_histogram_metric(metric_name: &str,
                         histogram: &mut Histogram,
                         carbon: &mut CarbonStream,
                         prefix_str: &'static str,
                         ts: Timespec) -> Result<String, Error> {
    let count = histogram.count();
    // let sum = histogram.sum();
    // let mean = sum / count;
    let max = histogram.percentile(100.0).unwrap();
    let min = histogram.percentile(0.0).unwrap();

    let p50 = histogram.percentile(50.0).unwrap();
    let p75 = histogram.percentile(75.0).unwrap();
    let p95 = histogram.percentile(95.0).unwrap();
    let p98 = histogram.percentile(98.0).unwrap();
    let p99 = histogram.percentile(99.0).unwrap();
    let p999 = histogram.percentile(99.9).unwrap();
    let p9999 = histogram.percentile(99.99).unwrap();
    let p99999 = histogram.percentile(99.999).unwrap();

    try!(carbon.write(prefix(format!("{}.count", metric_name), prefix_str),
                 count.to_string(),
                 ts));

    try!(carbon.write(prefix(format!("{}.max", metric_name), prefix_str),
                 max.to_string(),
                 ts));

    // carbon
    // .write(prefix(format!("{}.mean", metric_name), prefix_str),
    // mean.into_string(),
    // ts);

    try!(carbon.write(prefix(format!("{}.min", metric_name), prefix_str),
                 min.to_string(),
                 ts));

    try!(carbon.write(prefix(format!("{}.p50", metric_name), prefix_str),
                 p50.to_string(),
                 ts));

    try!(carbon.write(prefix(format!("{}.p75", metric_name), prefix_str),
                 p75.to_string(),
                 ts));

    try!(carbon.write(prefix(format!("{}.p95", metric_name), prefix_str),
                 p95.to_string(),
                 ts));

    try!(carbon.write(prefix(format!("{}.p98", metric_name), prefix_str),
                 p98.to_string(),
                 ts));

    try!(carbon.write(prefix(format!("{}.p99", metric_name), prefix_str),
                 p99.to_string(),
                 ts));

    try!(carbon.write(prefix(format!("{}.p999", metric_name), prefix_str),
                 p999.to_string(),
                 ts));

    try!(carbon.write(prefix(format!("{}.p9999", metric_name), prefix_str),
                 p9999.to_string(),
                 ts));

    try!(carbon.write(prefix(format!("{}.p99999", metric_name), prefix_str),
                 p99999.to_string(),
                 ts));
    Ok(String::from(""))
}

impl CarbonReporter {
    pub fn new(registry: Arc<StdRegistry<'static>>,
               reporter_name: &'static str,
               host_and_port: String,
               prefix: &'static str)
               -> CarbonReporter {
        CarbonReporter {
            host_and_port: host_and_port,
            prefix: prefix,
            registry: registry,
            reporter_name: reporter_name,
        }
    }

    fn report_to_carbon_continuously(self, delay_ms: u32)
        -> thread::JoinHandle<Result<String, Error>> {
        use metrics::metric::MetricValue::{Counter, Gauge, Histogram, Meter};

        let prefix = self.prefix;
        let host_and_port = self.host_and_port.clone();
        let mut carbon = CarbonStream::new(host_and_port);
        let registry = self.registry.clone();
        thread::spawn(move || {
            loop {
                let ts = time::now().to_timespec();
                for metric_name in &registry.get_metrics_names() {
                    let metric = registry.get(metric_name);
                    try!(match metric.export_metric() {
                        Meter(x) => {
                            send_meter_metric(metric_name, x, &mut carbon, prefix, ts)
                        }
                        Gauge(x) => {
                            send_gauge_metric(metric_name, x, &mut carbon, prefix, ts)
                        }
                        Counter(x) => {
                            send_counter_metric(metric_name, x, &mut carbon, prefix, ts)
                        }
                        Histogram(mut x) => {
                            send_histogram_metric(metric_name, &mut x, &mut carbon, prefix, ts)
                        }
                    });
                }
                thread::sleep(Duration::from_millis(delay_ms as u64));
            }
        })
    }

    pub fn start(self, delay_ms: u32) {
        self.report_to_carbon_continuously(delay_ms);
    }
}

#[cfg(test)]
mod test {
    use metrics::meter::{Meter, StdMeter};
    use metrics::counter::{Counter, StdCounter};
    use metrics::gauge::{Gauge, StdGauge};
    use registry::{Registry, StdRegistry};
    use reporter::carbon::CarbonReporter;
    use std::sync::Arc;
    use std::thread;
    use histogram::*;

    #[test]
    fn meter() {
        let m = StdMeter::new();
        m.mark(100);

        let mut c: StdCounter = StdCounter::new();
        c.inc();

        let mut g: StdGauge = StdGauge { value: 0f64 };
        g.set(1.2);

        let mut hc = HistogramConfig::new();
        hc.max_value(100).precision(1);
        let mut h = Histogram::configured(hc).unwrap();

        h.record(1, 1);

        let mut r = StdRegistry::new();
        r.insert("meter1", m);
        r.insert("counter1", c);
        r.insert("gauge1", g);
        r.insert("histogram", h);

        let arc_registry = Arc::new(r);
        CarbonReporter::new(arc_registry.clone(),
                            "test",
                            "localhost:0".to_string(),
                            "asd.asdf");
    }
}
<|endoftext|>


<commit_before>import rustc::syntax::ast;
import rustc::syntax::visit;

export extract;

#[doc = "Converts the Rust AST to the rustdoc document model"]
fn extract(
    crate: @ast::crate
) -> doc::cratedoc {
    ~{
        topmod: top_moddoc_from_crate(crate),
    }
}

fn top_moddoc_from_crate(
    crate: @ast::crate
) -> doc::moddoc {
    moddoc_from_mod(crate.node.module, "crate", crate.node.attrs)
}

fn moddoc_from_mod(
    module: ast::_mod,
    name: ast::ident,
    _attrs: [ast::attribute]

) -> doc::moddoc {
    ~{
        name: name,
        mods: doc::modlist(
            vec::filter_map(module.items) {|item|
                alt item.node {
                  ast::item_mod(m) {
                    some(moddoc_from_mod(m, item.ident, item.attrs))
                  }
                  _ {
                    none
                  }
                }
            }),
        fns: doc::fnlist(
            vec::filter_map(module.items) {|item|
                alt item.node {
                  ast::item_fn(decl, typarams, _) {
                    some(fndoc_from_fn(
                        decl, typarams, item.ident, item.id, item.attrs))
                  }
                  _ {
                    none
                  }
                }
            })
    }
}

fn fndoc_from_fn(
    _decl: ast::fn_decl,
    _typarams: [ast::ty_param],
    name: ast::ident,
    id: ast::node_id,
    attrs: [ast::attribute]
) -> doc::fndoc {
    attr_parser::parse_fn(name, id, attrs)
}

#[cfg(test)]
mod tests {

    #[test]
    fn extract_empty_crate() {
        let source = ""; // empty crate
        let ast = parse::from_str(source);
        let doc = extract(ast);
        // FIXME #1535: These are boxed to prevent a crash
        assert ~doc.topmod.mods == ~doc::modlist([]);
        assert ~doc.topmod.fns == ~doc::fnlist([]);
    }

    #[test]
    fn extract_mods() {
        let source = "mod a { mod b { } mod c { } }";
        let ast = parse::from_str(source);
        let doc = extract(ast);
        assert doc.topmod.mods[0].name == "a";
        assert doc.topmod.mods[0].mods[0].name == "b";
        assert doc.topmod.mods[0].mods[1].name == "c";
    }

    #[test]
    fn extract_mods_deep() {
        let source = "mod a { mod b { mod c { } } }";
        let ast = parse::from_str(source);
        let doc = extract(ast);
        assert doc.topmod.mods[0].mods[0].mods[0].name == "c";
    }

    #[test]
    fn extract_fns() {
        let source =
            "fn a() { } \
             mod b { fn c() { } }";
        let ast = parse::from_str(source);
        let doc = extract(ast);
        assert doc.topmod.fns[0].name == "a";
        assert doc.topmod.mods[0].fns[0].name == "c";
    }

    #[test]
    fn extract_should_set_fn_ast_id() {
        let source = "fn a() { }";
        let ast = parse::from_str(source);
        let doc = extract(ast);
        assert doc.topmod.fns[0].id != 0;
    }
}<commit_msg>rustdoc: Set the crate name in the top module<commit_after>import rustc::syntax::ast;
import rustc::syntax::visit;

export extract;

#[doc = "Converts the Rust AST to the rustdoc document model"]
fn extract(
    crate: @ast::crate,
    default_name: str
) -> doc::cratedoc {
    ~{
        topmod: top_moddoc_from_crate(crate, default_name),
    }
}

fn top_moddoc_from_crate(
    crate: @ast::crate,
    default_name: str
) -> doc::moddoc {
    moddoc_from_mod(crate.node.module, default_name, crate.node.attrs)
}

fn moddoc_from_mod(
    module: ast::_mod,
    name: ast::ident,
    _attrs: [ast::attribute]

) -> doc::moddoc {
    ~{
        name: name,
        mods: doc::modlist(
            vec::filter_map(module.items) {|item|
                alt item.node {
                  ast::item_mod(m) {
                    some(moddoc_from_mod(m, item.ident, item.attrs))
                  }
                  _ {
                    none
                  }
                }
            }),
        fns: doc::fnlist(
            vec::filter_map(module.items) {|item|
                alt item.node {
                  ast::item_fn(decl, typarams, _) {
                    some(fndoc_from_fn(
                        decl, typarams, item.ident, item.id, item.attrs))
                  }
                  _ {
                    none
                  }
                }
            })
    }
}

fn fndoc_from_fn(
    _decl: ast::fn_decl,
    _typarams: [ast::ty_param],
    name: ast::ident,
    id: ast::node_id,
    attrs: [ast::attribute]
) -> doc::fndoc {
    attr_parser::parse_fn(name, id, attrs)
}

#[cfg(test)]
mod tests {

    #[test]
    fn extract_empty_crate() {
        let source = ""; // empty crate
        let ast = parse::from_str(source);
        let doc = extract(ast, "");
        // FIXME #1535: These are boxed to prevent a crash
        assert ~doc.topmod.mods == ~doc::modlist([]);
        assert ~doc.topmod.fns == ~doc::fnlist([]);
    }

    #[test]
    fn extract_mods() {
        let source = "mod a { mod b { } mod c { } }";
        let ast = parse::from_str(source);
        let doc = extract(ast, "");
        assert doc.topmod.mods[0].name == "a";
        assert doc.topmod.mods[0].mods[0].name == "b";
        assert doc.topmod.mods[0].mods[1].name == "c";
    }

    #[test]
    fn extract_mods_deep() {
        let source = "mod a { mod b { mod c { } } }";
        let ast = parse::from_str(source);
        let doc = extract(ast, "");
        assert doc.topmod.mods[0].mods[0].mods[0].name == "c";
    }

    #[test]
    fn extract_fns() {
        let source =
            "fn a() { } \
             mod b { fn c() { } }";
        let ast = parse::from_str(source);
        let doc = extract(ast, "");
        assert doc.topmod.fns[0].name == "a";
        assert doc.topmod.mods[0].fns[0].name == "c";
    }

    #[test]
    fn extract_should_set_fn_ast_id() {
        let source = "fn a() { }";
        let ast = parse::from_str(source);
        let doc = extract(ast, "");
        assert doc.topmod.fns[0].id != 0;
    }

    #[test]
    fn extract_should_use_default_crate_name_if_no_link_name_exists() {
        let source = "";
        let ast = parse::from_str(source);
        let doc = extract(ast, "burp");
        assert doc.topmod.name == "burp";
    }
}<|endoftext|>


<commit_before>use std::iter::repeat;

use set1::challenge2::fixed_xor;
use set1::utils::bytes_to_hex;

fn repeating_xor(text: &[u8], key: &[u8]) -> String {
    bytes_to_hex(&fixed_xor(text,
                            &(repeat(key)
                                .take(text.len() / 3 + 1)
                                .flat_map(|x| x.iter().cloned())
                                .collect::<Vec<_>>())))

}

#[test]
fn test_repeating_xor() {
    assert_eq!(repeating_xor("Burning 'em, if you ain't quick and nimble\nI go crazy when I hear a cymbal".as_bytes(),
                             "ICE".as_bytes()),
               "0b3637272a2b2e63622c2e69692a23693a2a3c6324202d623d63343c2a26226324272765272a282b2f20430a652e2c652a31\
               24333a653e2b2027630c692b20283165286326302e27282f")
}
<commit_msg>set1: Use len of key when figuring out nr of repeats<commit_after>use std::iter::repeat;

use set1::challenge2::fixed_xor;
use set1::utils::bytes_to_hex;

fn repeating_xor(text: &[u8], key: &[u8]) -> String {
    bytes_to_hex(&fixed_xor(text,
                            &(repeat(key)
                                .take(text.len() / key.len() + 1)
                                .flat_map(|x| x.iter().cloned())
                                .collect::<Vec<_>>())))

}

#[test]
fn test_repeating_xor() {
    assert_eq!(repeating_xor("Burning 'em, if you ain't quick and nimble\nI go crazy when I hear a cymbal".as_bytes(),
                             "ICE".as_bytes()),
               "0b3637272a2b2e63622c2e69692a23693a2a3c6324202d623d63343c2a26226324272765272a282b2f20430a652e2c652a31\
               24333a653e2b2027630c692b20283165286326302e27282f")
}
<|endoftext|>


<commit_before>use std::sync::mpsc::{channel, Sender};
use std::thread::Thread;

use search;

use super::types::{Cmd, Response};
use super::state::{State, Mode};

mod go_param;

pub fn process(state: &mut State, cmd: Cmd, output: &Sender<Response>) {
    match cmd {
        Cmd::Debug(val) => {
            state.search_state.as_mut().map(|x| { x.is_debug = val; } );
            state.search_tx.as_mut().map(|tx| { let _ = tx.send(search::Cmd::Stop); } );
        },
        Cmd::IsReady => {
            // TODO implement IsReady
            unimplemented!();
        },
        Cmd::Register(ref param) => {
            // TODO register
            unimplemented!();
        },
        cmd => {
            match state.mode {
                Mode::Init => {
                    if cmd == Cmd::Uci {
                        // TODO print id/option/uciok
                        state.mode = Mode::Wait;
                        unimplemented!();
                    }
                },
                Mode::Wait => {
                    match cmd {
                        Cmd::SetOption(ref name, ref val_opt) => {
                            // TODO maybe initialize
                            // TODO set options
                            unimplemented!();
                        },
                        Cmd::UciNewGame => {
                            // TODO note that ucinewgame supported
                            // TODO reset game status
                            state.mode = Mode::NewGame;
                            unimplemented!();
                        },
                        cmd @Cmd::SetupPosition(..) => {
                            if state.ucinewgame_support {
                                // TODO set up position for same game
                                state.mode = Mode::Ready;
                                unimplemented!();
                            } else {
                                process(state, Cmd::UciNewGame, output);
                                state.ucinewgame_support = false;
                                process(state, cmd, output);
                            }
                        },
                        _ => {},
                    }
                },
                Mode::NewGame => {
                    if let Cmd::SetupPosition(ref pos, ref from_to_vec) = cmd {
                        // TODO setup position for new game
                        state.mode = Mode::Ready;
                        unimplemented!();
                    }
                },
                Mode::Ready => {
                    if let Cmd::Go(param) = cmd {
                        go_param::setup(state, param);
                        let (search_tx, search_rx) = channel::<search::Cmd>();
                        let search_state = state.search_state.as_ref().unwrap().clone();
                        let output = output.clone();
                        let temp = Thread::spawn(move ||
                                                 search::start(search_state, search_rx, output));
                        state.search_tx = Some(search_tx);
                        state.search_guard = Some(temp);
                        // TODO start timer
                        state.mode = Mode::Search;
                        unimplemented!();
                    }
                },
                Mode::Search => {
                    match cmd {
                        Cmd::PonderHit => {
                            // TODO ponder hit
                            unimplemented!();
                        },
                        Cmd::Stop => {
                            // TODO stop search
                            // Also if time is out
                            unimplemented!();
                        },
                        _ => {},
                    }
                },
            }
        },
    }
}
<commit_msg>Use timer.<commit_after>use std::sync::mpsc::{channel, Sender};
use std::thread::Thread;

use search;
use timer;

use super::types::{Cmd, Response};
use super::state::{State, Mode};

mod go_param;

pub fn process(state: &mut State, cmd: Cmd, output: &Sender<Response>) {
    match cmd {
        Cmd::Debug(val) => {
            state.search_state.as_mut().map(|x| { x.is_debug = val; } );
            state.search_tx.as_mut().map(|tx| { let _ = tx.send(search::Cmd::Stop); } );
        },
        Cmd::IsReady => {
            // TODO implement IsReady
            unimplemented!();
        },
        Cmd::Register(ref param) => {
            // TODO register
            unimplemented!();
        },
        cmd => {
            match state.mode {
                Mode::Init => {
                    if cmd == Cmd::Uci {
                        // TODO print id/option/uciok
                        state.mode = Mode::Wait;
                        unimplemented!();
                    }
                },
                Mode::Wait => {
                    match cmd {
                        Cmd::SetOption(ref name, ref val_opt) => {
                            // TODO maybe initialize
                            // TODO set options
                            unimplemented!();
                        },
                        Cmd::UciNewGame => {
                            // TODO note that ucinewgame supported
                            // TODO reset game status
                            state.mode = Mode::NewGame;
                            unimplemented!();
                        },
                        cmd @Cmd::SetupPosition(..) => {
                            if state.ucinewgame_support {
                                // TODO set up position for same game
                                state.mode = Mode::Ready;
                                unimplemented!();
                            } else {
                                process(state, Cmd::UciNewGame, output);
                                state.ucinewgame_support = false;
                                process(state, cmd, output);
                            }
                        },
                        _ => {},
                    }
                },
                Mode::NewGame => {
                    if let Cmd::SetupPosition(ref pos, ref from_to_vec) = cmd {
                        // TODO setup position for new game
                        state.mode = Mode::Ready;
                        unimplemented!();
                    }
                },
                Mode::Ready => {
                    if let Cmd::Go(param) = cmd {
                        go_param::setup(state, param);
                        let (search_tx, search_rx) = channel::<search::Cmd>();
                        let search_state = state.search_state.as_ref().unwrap().clone();
                        let output = output.clone();
                        let temp = Thread::spawn(move ||
                                                 search::start(search_state, search_rx, output));

                        state.search_tx = Some(search_tx.clone());
                        state.search_guard = Some(temp);

                        let time_data = state.time_data.clone().unwrap();
                        let c = state.search_state.as_ref().unwrap().pos.side_to_move();

                        Thread::spawn(move || timer::start(time_data, c, search_tx)).detach();

                        state.mode = Mode::Search;
                    }
                },
                Mode::Search => {
                    match cmd {
                        Cmd::PonderHit => {
                            // TODO ponder hit
                            unimplemented!();
                        },
                        Cmd::Stop => {
                            // TODO stop search
                            // Also if time is out
                            unimplemented!();
                        },
                        _ => {},
                    }
                },
            }
        },
    }
}
<|endoftext|>


<commit_before>//
// Sysinfo
//
// Copyright (c) 2017 Guillaume Gomez
//

use std::collections::HashMap;

use NetworkExt;
use NetworksExt;
use NetworksIter;

/// Network interfaces.
///
/// ```no_run
/// use sysinfo::{NetworksExt, System, SystemExt};
///
/// let s = System::new_all();
/// let networks = s.get_networks();
/// ```
pub struct Networks {
    interfaces: HashMap<String, NetworkData>,
}

impl Networks {
    pub(crate) fn new() -> Networks {
        Networks {
            interfaces: HashMap::new(),
        }
    }
}

impl NetworksExt for Networks {
    fn iter<'a>(&'a self) -> NetworksIter<'a> {
        NetworksIter::new(self.interfaces.iter())
    }

    fn refresh_networks_list(&mut self) {}

    fn refresh(&mut self) {}
}

/// Contains network information.
#[derive(Debug)]
pub struct NetworkData;

impl NetworkExt for NetworkData {
    fn get_income(&self) -> u64 {
        0
    }

    fn get_outcome(&self) -> u64 {
        0
    }

    fn get_total_income(&self) -> u64 {
        0
    }

    fn get_total_outcome(&self) -> u64 {
        0
    }
}
<commit_msg>Extend unknown network interface<commit_after>//
// Sysinfo
//
// Copyright (c) 2017 Guillaume Gomez
//

use std::collections::HashMap;

use NetworkExt;
use NetworksExt;
use NetworksIter;

/// Network interfaces.
///
/// ```no_run
/// use sysinfo::{NetworksExt, System, SystemExt};
///
/// let s = System::new_all();
/// let networks = s.get_networks();
/// ```
pub struct Networks {
    interfaces: HashMap<String, NetworkData>,
}

impl Networks {
    pub(crate) fn new() -> Networks {
        Networks {
            interfaces: HashMap::new(),
        }
    }
}

impl NetworksExt for Networks {
    fn iter<'a>(&'a self) -> NetworksIter<'a> {
        NetworksIter::new(self.interfaces.iter())
    }

    fn refresh_networks_list(&mut self) {}

    fn refresh(&mut self) {}
}

/// Contains network information.
#[derive(Debug)]
pub struct NetworkData;

impl NetworkExt for NetworkData {
    fn get_income(&self) -> u64 {
        0
    }

    fn get_total_income(&self) -> u64 {
        0
    }

    fn get_outcome(&self) -> u64 {
        0
    }

    fn get_total_outcome(&self) -> u64 {
        0
    }

    fn get_packets_income(&self) -> u64 {
        0
    }

    fn get_total_packets_income(&self) -> u64 {
        0
    }

    fn get_packets_outcome(&self) -> u64 {
        0
    }

    fn get_total_packets_outcome(&self) -> u64 {
        0
    }

    fn get_errors_income(&self) -> u64 {
        0
    }

    fn get_total_errors_income(&self) -> u64 {
        0
    }

    fn get_errors_outcome(&self) -> u64 {
        0
    }

    fn get_total_errors_outcome(&self) -> u64 {
        0
    }
}
<|endoftext|>


<commit_before>use super::{
    child_properties::ChildProperties, imports::Imports, info_base::InfoBase,
    signatures::Signatures, *,
};
use crate::{
    config::gobjects::{GObject, GStatus},
    env::Env,
    library::{self, FunctionKind},
    nameutil::*,
    traits::*,
};
use log::info;
use std::{borrow::Cow, ops::Deref};

/// The location of an item within the object
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum LocationInObject {
    Impl,
    Ext,
    ExtManual,
    Builder,
}

#[derive(Debug, Default)]
pub struct Info {
    pub base: InfoBase,
    pub c_type: String,
    pub c_class_type: Option<String>,
    pub get_type: String,
    pub is_interface: bool,
    pub is_fundamental: bool,
    pub supertypes: Vec<general::StatusedTypeId>,
    pub final_type: bool,
    pub generate_trait: bool,
    pub trait_name: String,
    pub has_constructors: bool,
    pub has_functions: bool,
    pub signals: Vec<signals::Info>,
    pub notify_signals: Vec<signals::Info>,
    pub properties: Vec<properties::Property>,
    pub builder_properties: Vec<(Vec<properties::Property>, TypeId)>,
    pub builder_postprocess: Option<String>,
    pub child_properties: ChildProperties,
    pub signatures: Signatures,
    /// Specific to fundamental types
    pub ref_fn: Option<String>,
    /// Specific to fundamental types
    pub unref_fn: Option<String>,
}

impl Info {
    pub fn has_signals(&self) -> bool {
        self.signals.iter().any(|s| s.trampoline.is_ok())
            || self.notify_signals.iter().any(|s| s.trampoline.is_ok())
    }

    /// Whether we should generate an impl block for this object
    /// We don't generate an impl block if the type doesn't have any of the followings:
    /// - Constructors / Functions / Builder properties (no build function)
    /// - Is a final type & doesn't have either methods / properties / child properties / signals
    pub fn should_generate_impl_block(&self) -> bool {
        self.has_constructors
            || has_builder_properties(&self.builder_properties)
            || !(self.need_generate_trait()
                && self.methods().is_empty()
                && self.properties.is_empty()
                && self.child_properties.is_empty()
                && self.signals.is_empty())
            || self.has_functions
    }

    pub fn need_generate_inherent(&self) -> bool {
        self.has_constructors
            || self.has_functions
            || !self.need_generate_trait()
            || has_builder_properties(&self.builder_properties)
    }

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

    pub fn has_action_signals(&self) -> bool {
        self.signals.iter().any(|s| s.action_emit_name.is_some())
    }

    /// Returns the location of the function within this object
    pub fn function_location(&self, fn_info: &functions::Info) -> LocationInObject {
        if self.final_type
            || matches!(
                fn_info.kind,
                FunctionKind::Constructor | FunctionKind::Function
            )
        {
            LocationInObject::Impl
        } else if fn_info.status == GStatus::Generate || self.full_name == "GObject.Object" {
            LocationInObject::Ext
        } else {
            LocationInObject::ExtManual
        }
    }

    /// Generate doc name based on function location within this object
    /// See also [`Self::function_location()`].
    /// Returns `(item/crate path including type name, just the type name)`
    pub fn generate_doc_link_info(
        &self,
        fn_info: &functions::Info,
    ) -> (Cow<'_, str>, Cow<'_, str>) {
        match self.function_location(fn_info) {
            LocationInObject::Impl => (self.name.as_str().into(), self.name.as_str().into()),
            LocationInObject::ExtManual => {
                let trait_name = format!("{}Manual", self.trait_name);
                (format!("prelude::{}", trait_name).into(), trait_name.into())
            }
            LocationInObject::Ext => (
                format!("prelude::{}", self.trait_name).into(),
                self.trait_name.as_str().into(),
            ),
            LocationInObject::Builder => {
                panic!("C documentation is not expected to link to builders (a Rust concept)!")
            }
        }
    }
}

impl Deref for Info {
    type Target = InfoBase;

    fn deref(&self) -> &InfoBase {
        &self.base
    }
}

pub fn has_builder_properties(builder_properties: &[(Vec<properties::Property>, TypeId)]) -> bool {
    builder_properties
        .iter()
        .map(|b| b.0.iter().len())
        .sum::<usize>()
        > 0
}

pub fn class(env: &Env, obj: &GObject, deps: &[library::TypeId]) -> Option<Info> {
    info!("Analyzing class {}", obj.name);
    let full_name = obj.name.clone();

    let class_tid = env.library.find_type(0, &full_name)?;

    let type_ = env.type_(class_tid);

    let name: String = split_namespace_name(&full_name).1.into();

    let klass: &library::Class = type_.maybe_ref()?;

    let version = obj.version.or(klass.version);
    let deprecated_version = klass.deprecated_version;

    let mut imports = Imports::with_defined(&env.library, &name);
    if obj.generate_display_trait {
        imports.add("std::fmt");
    }

    let supertypes = supertypes::analyze(env, class_tid, version, &mut imports);

    let final_type = klass.final_type;
    let trait_name = obj
        .trait_name
        .as_ref()
        .cloned()
        .unwrap_or_else(|| format!("{}Ext", name));
    let is_fundamental = obj.fundamental_type.unwrap_or(klass.is_fundamental);

    let mut signatures = Signatures::with_capacity(klass.functions.len());

    let mut functions = functions::analyze(
        env,
        &klass.functions,
        Some(class_tid),
        !final_type,
        false,
        obj,
        &mut imports,
        Some(&mut signatures),
        Some(deps),
    );
    let mut specials = special_functions::extract(&mut functions, type_, obj);
    // `copy` will duplicate an object while `clone` just adds a reference
    special_functions::unhide(&mut functions, &specials, special_functions::Type::Copy);
    // these are all automatically derived on objects and compare by pointer. If such functions
    // exist they will provide additional functionality
    for t in &[
        special_functions::Type::Hash,
        special_functions::Type::Equal,
        special_functions::Type::Compare,
    ] {
        special_functions::unhide(&mut functions, &specials, *t);
        specials.traits_mut().remove(t);
    }
    special_functions::analyze_imports(&specials, &mut imports);

    let signals = signals::analyze(
        env,
        &klass.signals,
        class_tid,
        !final_type,
        is_fundamental,
        obj,
        &mut imports,
    );
    let (properties, notify_signals) = properties::analyze(
        env,
        &klass.properties,
        class_tid,
        !final_type,
        is_fundamental,
        obj,
        &mut imports,
        &signatures,
        deps,
    );

    let builder_properties =
        class_builder::analyze(env, &klass.properties, class_tid, obj, &mut imports);

    let child_properties =
        child_properties::analyze(env, obj.child_properties.as_ref(), class_tid, &mut imports);

    let has_methods = functions
        .iter()
        .any(|f| f.kind == library::FunctionKind::Method && f.status.need_generate());
    let has_signals = signals.iter().any(|s| s.trampoline.is_ok())
        || notify_signals.iter().any(|s| s.trampoline.is_ok());
    // There's no point in generating a trait if there are no signals, methods, properties
    // and child properties: it would be empty
    //
    // There's also no point in generating a trait for final types: there are no possible subtypes
    let generate_trait = !final_type
        && !is_fundamental
        && (has_signals || has_methods || !properties.is_empty() || !child_properties.is_empty());

    if is_fundamental {
        imports.add("glib::StaticType");
        imports.add("glib::translate::*");
    }

    if has_builder_properties(&builder_properties) {
        imports.add("glib::object::Cast");
        imports.add("glib::StaticType");
        imports.add("glib::ToValue");
    }

    if generate_trait {
        imports.add("glib::object::IsA");
    }

    let base = InfoBase {
        full_name,
        type_id: class_tid,
        name,
        functions,
        specials,
        imports,
        version,
        deprecated_version,
        cfg_condition: obj.cfg_condition.clone(),
        concurrency: obj.concurrency,
        visibility: obj.visibility,
    };

    // patch up trait methods in the symbol table
    if generate_trait {
        let mut symbols = env.symbols.borrow_mut();
        for func in base.methods() {
            if let Some(symbol) = symbols.by_c_name_mut(&func.glib_name) {
                symbol.make_trait_method(&trait_name);
            }
        }
    }

    let has_constructors = !base.constructors().is_empty();
    let has_functions = !base.functions().is_empty();

    let info = Info {
        base,
        c_type: klass.c_type.clone(),
        c_class_type: klass.c_class_type.clone(),
        get_type: klass.glib_get_type.clone(),
        is_interface: false,
        is_fundamental,
        supertypes,
        final_type,
        generate_trait,
        trait_name,
        has_constructors,
        has_functions,
        signals,
        notify_signals,
        properties,
        builder_properties,
        builder_postprocess: obj.builder_postprocess.clone(),
        child_properties,
        signatures,
        ref_fn: klass.ref_fn.clone(),
        unref_fn: klass.unref_fn.clone(),
    };

    Some(info)
}

pub fn interface(env: &Env, obj: &GObject, deps: &[library::TypeId]) -> Option<Info> {
    info!("Analyzing interface {}", obj.name);
    let full_name = obj.name.clone();

    let iface_tid = env.library.find_type(0, &full_name)?;

    let type_ = env.type_(iface_tid);

    let name: String = split_namespace_name(&full_name).1.into();

    let iface: &library::Interface = type_.maybe_ref()?;

    let version = obj.version.or(iface.version);
    let deprecated_version = iface.deprecated_version;

    let mut imports = Imports::with_defined(&env.library, &name);
    imports.add("glib::object::IsA");
    if obj.generate_display_trait {
        imports.add("std::fmt");
    }

    let supertypes = supertypes::analyze(env, iface_tid, version, &mut imports);

    let trait_name = obj
        .trait_name
        .as_ref()
        .cloned()
        .unwrap_or_else(|| format!("{}Ext", name));

    let mut signatures = Signatures::with_capacity(iface.functions.len());

    let functions = functions::analyze(
        env,
        &iface.functions,
        Some(iface_tid),
        true,
        false,
        obj,
        &mut imports,
        Some(&mut signatures),
        Some(deps),
    );

    let signals = signals::analyze(
        env,
        &iface.signals,
        iface_tid,
        true,
        false,
        obj,
        &mut imports,
    );
    let (properties, notify_signals) = properties::analyze(
        env,
        &iface.properties,
        iface_tid,
        true,
        false,
        obj,
        &mut imports,
        &signatures,
        deps,
    );

    let base = InfoBase {
        full_name,
        type_id: iface_tid,
        name,
        functions,
        specials: Default::default(),
        imports,
        version,
        deprecated_version,
        cfg_condition: obj.cfg_condition.clone(),
        concurrency: obj.concurrency,
        visibility: obj.visibility,
    };

    let has_functions = !base.functions().is_empty();

    let info = Info {
        base,
        c_type: iface.c_type.clone(),
        c_class_type: iface.c_class_type.clone(),
        get_type: iface.glib_get_type.clone(),
        is_interface: true,
        supertypes,
        final_type: false,
        generate_trait: true,
        trait_name,
        has_functions,
        signals,
        notify_signals,
        properties,
        signatures,
        ..Default::default()
    };

    Some(info)
}
<commit_msg>docs: Don't use Ext for fundamental types<commit_after>use super::{
    child_properties::ChildProperties, imports::Imports, info_base::InfoBase,
    signatures::Signatures, *,
};
use crate::{
    config::gobjects::{GObject, GStatus},
    env::Env,
    library::{self, FunctionKind},
    nameutil::*,
    traits::*,
};
use log::info;
use std::{borrow::Cow, ops::Deref};

/// The location of an item within the object
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum LocationInObject {
    Impl,
    Ext,
    ExtManual,
    Builder,
}

#[derive(Debug, Default)]
pub struct Info {
    pub base: InfoBase,
    pub c_type: String,
    pub c_class_type: Option<String>,
    pub get_type: String,
    pub is_interface: bool,
    pub is_fundamental: bool,
    pub supertypes: Vec<general::StatusedTypeId>,
    pub final_type: bool,
    pub generate_trait: bool,
    pub trait_name: String,
    pub has_constructors: bool,
    pub has_functions: bool,
    pub signals: Vec<signals::Info>,
    pub notify_signals: Vec<signals::Info>,
    pub properties: Vec<properties::Property>,
    pub builder_properties: Vec<(Vec<properties::Property>, TypeId)>,
    pub builder_postprocess: Option<String>,
    pub child_properties: ChildProperties,
    pub signatures: Signatures,
    /// Specific to fundamental types
    pub ref_fn: Option<String>,
    /// Specific to fundamental types
    pub unref_fn: Option<String>,
}

impl Info {
    pub fn has_signals(&self) -> bool {
        self.signals.iter().any(|s| s.trampoline.is_ok())
            || self.notify_signals.iter().any(|s| s.trampoline.is_ok())
    }

    /// Whether we should generate an impl block for this object
    /// We don't generate an impl block if the type doesn't have any of the followings:
    /// - Constructors / Functions / Builder properties (no build function)
    /// - Is a final type & doesn't have either methods / properties / child properties / signals
    pub fn should_generate_impl_block(&self) -> bool {
        self.has_constructors
            || has_builder_properties(&self.builder_properties)
            || !(self.need_generate_trait()
                && self.methods().is_empty()
                && self.properties.is_empty()
                && self.child_properties.is_empty()
                && self.signals.is_empty())
            || self.has_functions
    }

    pub fn need_generate_inherent(&self) -> bool {
        self.has_constructors
            || self.has_functions
            || !self.need_generate_trait()
            || has_builder_properties(&self.builder_properties)
    }

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

    pub fn has_action_signals(&self) -> bool {
        self.signals.iter().any(|s| s.action_emit_name.is_some())
    }

    /// Returns the location of the function within this object
    pub fn function_location(&self, fn_info: &functions::Info) -> LocationInObject {
        if self.final_type
            || self.is_fundamental
            || matches!(
                fn_info.kind,
                FunctionKind::Constructor | FunctionKind::Function
            )
        {
            LocationInObject::Impl
        } else if fn_info.status == GStatus::Generate || self.full_name == "GObject.Object" {
            LocationInObject::Ext
        } else {
            LocationInObject::ExtManual
        }
    }

    /// Generate doc name based on function location within this object
    /// See also [`Self::function_location()`].
    /// Returns `(item/crate path including type name, just the type name)`
    pub fn generate_doc_link_info(
        &self,
        fn_info: &functions::Info,
    ) -> (Cow<'_, str>, Cow<'_, str>) {
        match self.function_location(fn_info) {
            LocationInObject::Impl => (self.name.as_str().into(), self.name.as_str().into()),
            LocationInObject::ExtManual => {
                let trait_name = format!("{}Manual", self.trait_name);
                (format!("prelude::{}", trait_name).into(), trait_name.into())
            }
            LocationInObject::Ext => (
                format!("prelude::{}", self.trait_name).into(),
                self.trait_name.as_str().into(),
            ),
            LocationInObject::Builder => {
                panic!("C documentation is not expected to link to builders (a Rust concept)!")
            }
        }
    }
}

impl Deref for Info {
    type Target = InfoBase;

    fn deref(&self) -> &InfoBase {
        &self.base
    }
}

pub fn has_builder_properties(builder_properties: &[(Vec<properties::Property>, TypeId)]) -> bool {
    builder_properties
        .iter()
        .map(|b| b.0.iter().len())
        .sum::<usize>()
        > 0
}

pub fn class(env: &Env, obj: &GObject, deps: &[library::TypeId]) -> Option<Info> {
    info!("Analyzing class {}", obj.name);
    let full_name = obj.name.clone();

    let class_tid = env.library.find_type(0, &full_name)?;

    let type_ = env.type_(class_tid);

    let name: String = split_namespace_name(&full_name).1.into();

    let klass: &library::Class = type_.maybe_ref()?;

    let version = obj.version.or(klass.version);
    let deprecated_version = klass.deprecated_version;

    let mut imports = Imports::with_defined(&env.library, &name);
    if obj.generate_display_trait {
        imports.add("std::fmt");
    }

    let supertypes = supertypes::analyze(env, class_tid, version, &mut imports);

    let final_type = klass.final_type;
    let trait_name = obj
        .trait_name
        .as_ref()
        .cloned()
        .unwrap_or_else(|| format!("{}Ext", name));
    let is_fundamental = obj.fundamental_type.unwrap_or(klass.is_fundamental);

    let mut signatures = Signatures::with_capacity(klass.functions.len());

    let mut functions = functions::analyze(
        env,
        &klass.functions,
        Some(class_tid),
        !final_type,
        false,
        obj,
        &mut imports,
        Some(&mut signatures),
        Some(deps),
    );
    let mut specials = special_functions::extract(&mut functions, type_, obj);
    // `copy` will duplicate an object while `clone` just adds a reference
    special_functions::unhide(&mut functions, &specials, special_functions::Type::Copy);
    // these are all automatically derived on objects and compare by pointer. If such functions
    // exist they will provide additional functionality
    for t in &[
        special_functions::Type::Hash,
        special_functions::Type::Equal,
        special_functions::Type::Compare,
    ] {
        special_functions::unhide(&mut functions, &specials, *t);
        specials.traits_mut().remove(t);
    }
    special_functions::analyze_imports(&specials, &mut imports);

    let signals = signals::analyze(
        env,
        &klass.signals,
        class_tid,
        !final_type,
        is_fundamental,
        obj,
        &mut imports,
    );
    let (properties, notify_signals) = properties::analyze(
        env,
        &klass.properties,
        class_tid,
        !final_type,
        is_fundamental,
        obj,
        &mut imports,
        &signatures,
        deps,
    );

    let builder_properties =
        class_builder::analyze(env, &klass.properties, class_tid, obj, &mut imports);

    let child_properties =
        child_properties::analyze(env, obj.child_properties.as_ref(), class_tid, &mut imports);

    let has_methods = functions
        .iter()
        .any(|f| f.kind == library::FunctionKind::Method && f.status.need_generate());
    let has_signals = signals.iter().any(|s| s.trampoline.is_ok())
        || notify_signals.iter().any(|s| s.trampoline.is_ok());
    // There's no point in generating a trait if there are no signals, methods, properties
    // and child properties: it would be empty
    //
    // There's also no point in generating a trait for final types: there are no possible subtypes
    let generate_trait = !final_type
        && !is_fundamental
        && (has_signals || has_methods || !properties.is_empty() || !child_properties.is_empty());

    if is_fundamental {
        imports.add("glib::StaticType");
        imports.add("glib::translate::*");
    }

    if has_builder_properties(&builder_properties) {
        imports.add("glib::object::Cast");
        imports.add("glib::StaticType");
        imports.add("glib::ToValue");
    }

    if generate_trait {
        imports.add("glib::object::IsA");
    }

    let base = InfoBase {
        full_name,
        type_id: class_tid,
        name,
        functions,
        specials,
        imports,
        version,
        deprecated_version,
        cfg_condition: obj.cfg_condition.clone(),
        concurrency: obj.concurrency,
        visibility: obj.visibility,
    };

    // patch up trait methods in the symbol table
    if generate_trait {
        let mut symbols = env.symbols.borrow_mut();
        for func in base.methods() {
            if let Some(symbol) = symbols.by_c_name_mut(&func.glib_name) {
                symbol.make_trait_method(&trait_name);
            }
        }
    }

    let has_constructors = !base.constructors().is_empty();
    let has_functions = !base.functions().is_empty();

    let info = Info {
        base,
        c_type: klass.c_type.clone(),
        c_class_type: klass.c_class_type.clone(),
        get_type: klass.glib_get_type.clone(),
        is_interface: false,
        is_fundamental,
        supertypes,
        final_type,
        generate_trait,
        trait_name,
        has_constructors,
        has_functions,
        signals,
        notify_signals,
        properties,
        builder_properties,
        builder_postprocess: obj.builder_postprocess.clone(),
        child_properties,
        signatures,
        ref_fn: klass.ref_fn.clone(),
        unref_fn: klass.unref_fn.clone(),
    };

    Some(info)
}

pub fn interface(env: &Env, obj: &GObject, deps: &[library::TypeId]) -> Option<Info> {
    info!("Analyzing interface {}", obj.name);
    let full_name = obj.name.clone();

    let iface_tid = env.library.find_type(0, &full_name)?;

    let type_ = env.type_(iface_tid);

    let name: String = split_namespace_name(&full_name).1.into();

    let iface: &library::Interface = type_.maybe_ref()?;

    let version = obj.version.or(iface.version);
    let deprecated_version = iface.deprecated_version;

    let mut imports = Imports::with_defined(&env.library, &name);
    imports.add("glib::object::IsA");
    if obj.generate_display_trait {
        imports.add("std::fmt");
    }

    let supertypes = supertypes::analyze(env, iface_tid, version, &mut imports);

    let trait_name = obj
        .trait_name
        .as_ref()
        .cloned()
        .unwrap_or_else(|| format!("{}Ext", name));

    let mut signatures = Signatures::with_capacity(iface.functions.len());

    let functions = functions::analyze(
        env,
        &iface.functions,
        Some(iface_tid),
        true,
        false,
        obj,
        &mut imports,
        Some(&mut signatures),
        Some(deps),
    );

    let signals = signals::analyze(
        env,
        &iface.signals,
        iface_tid,
        true,
        false,
        obj,
        &mut imports,
    );
    let (properties, notify_signals) = properties::analyze(
        env,
        &iface.properties,
        iface_tid,
        true,
        false,
        obj,
        &mut imports,
        &signatures,
        deps,
    );

    let base = InfoBase {
        full_name,
        type_id: iface_tid,
        name,
        functions,
        specials: Default::default(),
        imports,
        version,
        deprecated_version,
        cfg_condition: obj.cfg_condition.clone(),
        concurrency: obj.concurrency,
        visibility: obj.visibility,
    };

    let has_functions = !base.functions().is_empty();

    let info = Info {
        base,
        c_type: iface.c_type.clone(),
        c_class_type: iface.c_class_type.clone(),
        get_type: iface.glib_get_type.clone(),
        is_interface: true,
        supertypes,
        final_type: false,
        generate_trait: true,
        trait_name,
        has_functions,
        signals,
        notify_signals,
        properties,
        signatures,
        ..Default::default()
    };

    Some(info)
}
<|endoftext|>


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

//! Command-line interface of the rustbuild build system.
//!
//! This module implements the command-line parsing of the build system which
//! has various flags to configure how it's run.

use std::env;
use std::fs;
use std::path::PathBuf;
use std::process;

use getopts::Options;

use Build;
use config::Config;
use metadata;
use builder::Builder;

use cache::{Interned, INTERNER};

/// Deserialized version of all flags for this compile.
pub struct Flags {
    pub verbose: usize, // verbosity level: 0 == not verbose, 1 == verbose, 2 == very verbose
    pub on_fail: Option<String>,
    pub stage: Option<u32>,
    pub keep_stage: Option<u32>,
    pub build: Option<Interned<String>>,

    pub host: Vec<Interned<String>>,
    pub target: Vec<Interned<String>>,
    pub config: Option<PathBuf>,
    pub src: PathBuf,
    pub jobs: Option<u32>,
    pub cmd: Subcommand,
    pub incremental: bool,
}

pub enum Subcommand {
    Build {
        paths: Vec<PathBuf>,
    },
    Doc {
        paths: Vec<PathBuf>,
    },
    Test {
        paths: Vec<PathBuf>,
        test_args: Vec<String>,
        fail_fast: bool,
    },
    Bench {
        paths: Vec<PathBuf>,
        test_args: Vec<String>,
    },
    Clean,
    Dist {
        paths: Vec<PathBuf>,
    },
    Install {
        paths: Vec<PathBuf>,
    },
}

impl Default for Subcommand {
    fn default() -> Subcommand {
        Subcommand::Build {
            paths: vec![PathBuf::from("nowhere")],
        }
    }
}

impl Flags {
    pub fn parse(args: &[String]) -> Flags {
        let mut extra_help = String::new();
        let mut subcommand_help = format!("\
Usage: x.py <subcommand> [options] [<paths>...]

Subcommands:
    build       Compile either the compiler or libraries
    test        Build and run some test suites
    bench       Build and run some benchmarks
    doc         Build documentation
    clean       Clean out build directories
    dist        Build distribution artifacts
    install     Install distribution artifacts

To learn more about a subcommand, run `./x.py <subcommand> -h`");

        let mut opts = Options::new();
        // Options common to all subcommands
        opts.optflagmulti("v", "verbose", "use verbose output (-vv for very verbose)");
        opts.optflag("i", "incremental", "use incremental compilation");
        opts.optopt("", "config", "TOML configuration file for build", "FILE");
        opts.optopt("", "build", "build target of the stage0 compiler", "BUILD");
        opts.optmulti("", "host", "host targets to build", "HOST");
        opts.optmulti("", "target", "target targets to build", "TARGET");
        opts.optopt("", "on-fail", "command to run on failure", "CMD");
        opts.optopt("", "stage", "stage to build", "N");
        opts.optopt("", "keep-stage", "stage to keep without recompiling", "N");
        opts.optopt("", "src", "path to the root of the rust checkout", "DIR");
        opts.optopt("j", "jobs", "number of jobs to run in parallel", "JOBS");
        opts.optflag("h", "help", "print this help message");

        // fn usage()
        let usage = |exit_code: i32, opts: &Options, subcommand_help: &str, extra_help: &str| -> ! {
            println!("{}", opts.usage(subcommand_help));
            if !extra_help.is_empty() {
                println!("{}", extra_help);
            }
            process::exit(exit_code);
        };

        // We can't use getopt to parse the options until we have completed specifying which
        // options are valid, but under the current implementation, some options are conditional on
        // the subcommand. Therefore we must manually identify the subcommand first, so that we can
        // complete the definition of the options.  Then we can use the getopt::Matches object from
        // there on out.
        let subcommand = args.iter().find(|&s|
            (s == "build")
            || (s == "test")
            || (s == "bench")
            || (s == "doc")
            || (s == "clean")
            || (s == "dist")
            || (s == "install"));
        let subcommand = match subcommand {
            Some(s) => s,
            None => {
                // No subcommand -- show the general usage and subcommand help
                println!("{}\n", subcommand_help);
                process::exit(0);
            }
        };

        // Some subcommands get extra options
        match subcommand.as_str() {
            "test"  => {
                opts.optflag("", "no-fail-fast", "Run all tests regardless of failure");
                opts.optmulti("", "test-args", "extra arguments", "ARGS");
            },
            "bench" => { opts.optmulti("", "test-args", "extra arguments", "ARGS"); },
            _ => { },
        };

        // Done specifying what options are possible, so do the getopts parsing
        let matches = opts.parse(&args[..]).unwrap_or_else(|e| {
            // Invalid argument/option format
            println!("\n{}\n", e);
            usage(1, &opts, &subcommand_help, &extra_help);
        });
        // Extra sanity check to make sure we didn't hit this crazy corner case:
        //
        //     ./x.py --frobulate clean build
        //            ^-- option  ^     ^- actual subcommand
        //                        \_ arg to option could be mistaken as subcommand
        let mut pass_sanity_check = true;
        match matches.free.get(0) {
            Some(check_subcommand) => {
                if check_subcommand != subcommand {
                    pass_sanity_check = false;
                }
            },
            None => {
                pass_sanity_check = false;
            }
        }
        if !pass_sanity_check {
            println!("{}\n", subcommand_help);
            println!("Sorry, I couldn't figure out which subcommand you were trying to specify.\n\
                      You may need to move some options to after the subcommand.\n");
            process::exit(1);
        }
        // Extra help text for some commands
        match subcommand.as_str() {
            "build" => {
                subcommand_help.push_str("\n
Arguments:
    This subcommand accepts a number of paths to directories to the crates
    and/or artifacts to compile. For example:

        ./x.py build src/libcore
        ./x.py build src/libcore src/libproc_macro
        ./x.py build src/libstd --stage 1

    If no arguments are passed then the complete artifacts for that stage are
    also compiled.

        ./x.py build
        ./x.py build --stage 1

    For a quick build of a usable compiler, you can pass:

        ./x.py build --stage 1 src/libtest

    This will first build everything once (like --stage 0 without further
    arguments would), and then use the compiler built in stage 0 to build
    src/libtest and its dependencies.
    Once this is done, build/$ARCH/stage1 contains a usable compiler.");
            }
            "test" => {
                subcommand_help.push_str("\n
Arguments:
    This subcommand accepts a number of paths to directories to tests that
    should be compiled and run. For example:

        ./x.py test src/test/run-pass
        ./x.py test src/libstd --test-args hash_map
        ./x.py test src/libstd --stage 0

    If no arguments are passed then the complete artifacts for that stage are
    compiled and tested.

        ./x.py test
        ./x.py test --stage 1");
            }
            "doc" => {
                subcommand_help.push_str("\n
Arguments:
    This subcommand accepts a number of paths to directories of documentation
    to build. For example:

        ./x.py doc src/doc/book
        ./x.py doc src/doc/nomicon
        ./x.py doc src/doc/book src/libstd

    If no arguments are passed then everything is documented:

        ./x.py doc
        ./x.py doc --stage 1");
            }
            _ => { }
        };
        // Get any optional paths which occur after the subcommand
        let cwd = t!(env::current_dir());
        let paths = matches.free[1..].iter().map(|p| cwd.join(p)).collect::<Vec<_>>();

        let cfg_file = matches.opt_str("config").map(PathBuf::from).or_else(|| {
            if fs::metadata("config.toml").is_ok() {
                Some(PathBuf::from("config.toml"))
            } else {
                None
            }
        });

        // All subcommands can have an optional "Available paths" section
        if matches.opt_present("verbose") {
            let config = Config::parse(&["build".to_string()]);
            let mut build = Build::new(config);
            metadata::build(&mut build);

            let maybe_rules_help = Builder::get_help(&build, subcommand.as_str());
            extra_help.push_str(maybe_rules_help.unwrap_or_default().as_str());
        } else {
            extra_help.push_str(format!("Run `./x.py {} -h -v` to see a list of available paths.",
                     subcommand).as_str());
        }

        // User passed in -h/--help?
        if matches.opt_present("help") {
            usage(0, &opts, &subcommand_help, &extra_help);
        }

        let cmd = match subcommand.as_str() {
            "build" => {
                Subcommand::Build { paths: paths }
            }
            "test" => {
                Subcommand::Test {
                    paths,
                    test_args: matches.opt_strs("test-args"),
                    fail_fast: !matches.opt_present("no-fail-fast"),
                }
            }
            "bench" => {
                Subcommand::Bench {
                    paths,
                    test_args: matches.opt_strs("test-args"),
                }
            }
            "doc" => {
                Subcommand::Doc { paths: paths }
            }
            "clean" => {
                if paths.len() > 0 {
                    println!("\nclean takes no arguments\n");
                    usage(1, &opts, &subcommand_help, &extra_help);
                }
                Subcommand::Clean
            }
            "dist" => {
                Subcommand::Dist {
                    paths,
                }
            }
            "install" => {
                Subcommand::Install {
                    paths,
                }
            }
            _ => {
                usage(1, &opts, &subcommand_help, &extra_help);
            }
        };

        let mut stage = matches.opt_str("stage").map(|j| j.parse().unwrap());

        if matches.opt_present("incremental") && stage.is_none() {
            stage = Some(1);
        }

        let cwd = t!(env::current_dir());
        let src = matches.opt_str("src").map(PathBuf::from)
            .or_else(|| env::var_os("SRC").map(PathBuf::from))
            .unwrap_or(cwd);

        Flags {
            verbose: matches.opt_count("verbose"),
            stage,
            on_fail: matches.opt_str("on-fail"),
            keep_stage: matches.opt_str("keep-stage").map(|j| j.parse().unwrap()),
            build: matches.opt_str("build").map(|s| INTERNER.intern_string(s)),
            host: split(matches.opt_strs("host"))
                .into_iter().map(|x| INTERNER.intern_string(x)).collect::<Vec<_>>(),
            target: split(matches.opt_strs("target"))
                .into_iter().map(|x| INTERNER.intern_string(x)).collect::<Vec<_>>(),
            config: cfg_file,
            src,
            jobs: matches.opt_str("jobs").map(|j| j.parse().unwrap()),
            cmd,
            incremental: matches.opt_present("incremental"),
        }
    }
}

impl Subcommand {
    pub fn test_args(&self) -> Vec<&str> {
        match *self {
            Subcommand::Test { ref test_args, .. } |
            Subcommand::Bench { ref test_args, .. } => {
                test_args.iter().flat_map(|s| s.split_whitespace()).collect()
            }
            _ => Vec::new(),
        }
    }

    pub fn fail_fast(&self) -> bool {
        match *self {
            Subcommand::Test { fail_fast, .. } => fail_fast,
            _ => false,
        }
    }
}

fn split(s: Vec<String>) -> Vec<String> {
    s.iter().flat_map(|s| s.split(',')).map(|s| s.to_string()).collect()
}
<commit_msg>Rollup merge of #44134 - vorner:x-py-unknown-cmd, r=nikomatsakis<commit_after>// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! Command-line interface of the rustbuild build system.
//!
//! This module implements the command-line parsing of the build system which
//! has various flags to configure how it's run.

use std::env;
use std::fs;
use std::path::PathBuf;
use std::process;

use getopts::Options;

use Build;
use config::Config;
use metadata;
use builder::Builder;

use cache::{Interned, INTERNER};

/// Deserialized version of all flags for this compile.
pub struct Flags {
    pub verbose: usize, // verbosity level: 0 == not verbose, 1 == verbose, 2 == very verbose
    pub on_fail: Option<String>,
    pub stage: Option<u32>,
    pub keep_stage: Option<u32>,
    pub build: Option<Interned<String>>,

    pub host: Vec<Interned<String>>,
    pub target: Vec<Interned<String>>,
    pub config: Option<PathBuf>,
    pub src: PathBuf,
    pub jobs: Option<u32>,
    pub cmd: Subcommand,
    pub incremental: bool,
}

pub enum Subcommand {
    Build {
        paths: Vec<PathBuf>,
    },
    Doc {
        paths: Vec<PathBuf>,
    },
    Test {
        paths: Vec<PathBuf>,
        test_args: Vec<String>,
        fail_fast: bool,
    },
    Bench {
        paths: Vec<PathBuf>,
        test_args: Vec<String>,
    },
    Clean,
    Dist {
        paths: Vec<PathBuf>,
    },
    Install {
        paths: Vec<PathBuf>,
    },
}

impl Default for Subcommand {
    fn default() -> Subcommand {
        Subcommand::Build {
            paths: vec![PathBuf::from("nowhere")],
        }
    }
}

impl Flags {
    pub fn parse(args: &[String]) -> Flags {
        let mut extra_help = String::new();
        let mut subcommand_help = format!("\
Usage: x.py <subcommand> [options] [<paths>...]

Subcommands:
    build       Compile either the compiler or libraries
    test        Build and run some test suites
    bench       Build and run some benchmarks
    doc         Build documentation
    clean       Clean out build directories
    dist        Build distribution artifacts
    install     Install distribution artifacts

To learn more about a subcommand, run `./x.py <subcommand> -h`");

        let mut opts = Options::new();
        // Options common to all subcommands
        opts.optflagmulti("v", "verbose", "use verbose output (-vv for very verbose)");
        opts.optflag("i", "incremental", "use incremental compilation");
        opts.optopt("", "config", "TOML configuration file for build", "FILE");
        opts.optopt("", "build", "build target of the stage0 compiler", "BUILD");
        opts.optmulti("", "host", "host targets to build", "HOST");
        opts.optmulti("", "target", "target targets to build", "TARGET");
        opts.optopt("", "on-fail", "command to run on failure", "CMD");
        opts.optopt("", "stage", "stage to build", "N");
        opts.optopt("", "keep-stage", "stage to keep without recompiling", "N");
        opts.optopt("", "src", "path to the root of the rust checkout", "DIR");
        opts.optopt("j", "jobs", "number of jobs to run in parallel", "JOBS");
        opts.optflag("h", "help", "print this help message");

        // fn usage()
        let usage = |exit_code: i32, opts: &Options, subcommand_help: &str, extra_help: &str| -> ! {
            println!("{}", opts.usage(subcommand_help));
            if !extra_help.is_empty() {
                println!("{}", extra_help);
            }
            process::exit(exit_code);
        };

        // We can't use getopt to parse the options until we have completed specifying which
        // options are valid, but under the current implementation, some options are conditional on
        // the subcommand. Therefore we must manually identify the subcommand first, so that we can
        // complete the definition of the options.  Then we can use the getopt::Matches object from
        // there on out.
        let subcommand = args.iter().find(|&s|
            (s == "build")
            || (s == "test")
            || (s == "bench")
            || (s == "doc")
            || (s == "clean")
            || (s == "dist")
            || (s == "install"));
        let subcommand = match subcommand {
            Some(s) => s,
            None => {
                // No subcommand -- show the general usage and subcommand help
                println!("{}\n", subcommand_help);
                process::exit(1);
            }
        };

        // Some subcommands get extra options
        match subcommand.as_str() {
            "test"  => {
                opts.optflag("", "no-fail-fast", "Run all tests regardless of failure");
                opts.optmulti("", "test-args", "extra arguments", "ARGS");
            },
            "bench" => { opts.optmulti("", "test-args", "extra arguments", "ARGS"); },
            _ => { },
        };

        // Done specifying what options are possible, so do the getopts parsing
        let matches = opts.parse(&args[..]).unwrap_or_else(|e| {
            // Invalid argument/option format
            println!("\n{}\n", e);
            usage(1, &opts, &subcommand_help, &extra_help);
        });
        // Extra sanity check to make sure we didn't hit this crazy corner case:
        //
        //     ./x.py --frobulate clean build
        //            ^-- option  ^     ^- actual subcommand
        //                        \_ arg to option could be mistaken as subcommand
        let mut pass_sanity_check = true;
        match matches.free.get(0) {
            Some(check_subcommand) => {
                if check_subcommand != subcommand {
                    pass_sanity_check = false;
                }
            },
            None => {
                pass_sanity_check = false;
            }
        }
        if !pass_sanity_check {
            println!("{}\n", subcommand_help);
            println!("Sorry, I couldn't figure out which subcommand you were trying to specify.\n\
                      You may need to move some options to after the subcommand.\n");
            process::exit(1);
        }
        // Extra help text for some commands
        match subcommand.as_str() {
            "build" => {
                subcommand_help.push_str("\n
Arguments:
    This subcommand accepts a number of paths to directories to the crates
    and/or artifacts to compile. For example:

        ./x.py build src/libcore
        ./x.py build src/libcore src/libproc_macro
        ./x.py build src/libstd --stage 1

    If no arguments are passed then the complete artifacts for that stage are
    also compiled.

        ./x.py build
        ./x.py build --stage 1

    For a quick build of a usable compiler, you can pass:

        ./x.py build --stage 1 src/libtest

    This will first build everything once (like --stage 0 without further
    arguments would), and then use the compiler built in stage 0 to build
    src/libtest and its dependencies.
    Once this is done, build/$ARCH/stage1 contains a usable compiler.");
            }
            "test" => {
                subcommand_help.push_str("\n
Arguments:
    This subcommand accepts a number of paths to directories to tests that
    should be compiled and run. For example:

        ./x.py test src/test/run-pass
        ./x.py test src/libstd --test-args hash_map
        ./x.py test src/libstd --stage 0

    If no arguments are passed then the complete artifacts for that stage are
    compiled and tested.

        ./x.py test
        ./x.py test --stage 1");
            }
            "doc" => {
                subcommand_help.push_str("\n
Arguments:
    This subcommand accepts a number of paths to directories of documentation
    to build. For example:

        ./x.py doc src/doc/book
        ./x.py doc src/doc/nomicon
        ./x.py doc src/doc/book src/libstd

    If no arguments are passed then everything is documented:

        ./x.py doc
        ./x.py doc --stage 1");
            }
            _ => { }
        };
        // Get any optional paths which occur after the subcommand
        let cwd = t!(env::current_dir());
        let paths = matches.free[1..].iter().map(|p| cwd.join(p)).collect::<Vec<_>>();

        let cfg_file = matches.opt_str("config").map(PathBuf::from).or_else(|| {
            if fs::metadata("config.toml").is_ok() {
                Some(PathBuf::from("config.toml"))
            } else {
                None
            }
        });

        // All subcommands can have an optional "Available paths" section
        if matches.opt_present("verbose") {
            let config = Config::parse(&["build".to_string()]);
            let mut build = Build::new(config);
            metadata::build(&mut build);

            let maybe_rules_help = Builder::get_help(&build, subcommand.as_str());
            extra_help.push_str(maybe_rules_help.unwrap_or_default().as_str());
        } else {
            extra_help.push_str(format!("Run `./x.py {} -h -v` to see a list of available paths.",
                     subcommand).as_str());
        }

        // User passed in -h/--help?
        if matches.opt_present("help") {
            usage(0, &opts, &subcommand_help, &extra_help);
        }

        let cmd = match subcommand.as_str() {
            "build" => {
                Subcommand::Build { paths: paths }
            }
            "test" => {
                Subcommand::Test {
                    paths,
                    test_args: matches.opt_strs("test-args"),
                    fail_fast: !matches.opt_present("no-fail-fast"),
                }
            }
            "bench" => {
                Subcommand::Bench {
                    paths,
                    test_args: matches.opt_strs("test-args"),
                }
            }
            "doc" => {
                Subcommand::Doc { paths: paths }
            }
            "clean" => {
                if paths.len() > 0 {
                    println!("\nclean takes no arguments\n");
                    usage(1, &opts, &subcommand_help, &extra_help);
                }
                Subcommand::Clean
            }
            "dist" => {
                Subcommand::Dist {
                    paths,
                }
            }
            "install" => {
                Subcommand::Install {
                    paths,
                }
            }
            _ => {
                usage(1, &opts, &subcommand_help, &extra_help);
            }
        };

        let mut stage = matches.opt_str("stage").map(|j| j.parse().unwrap());

        if matches.opt_present("incremental") && stage.is_none() {
            stage = Some(1);
        }

        let cwd = t!(env::current_dir());
        let src = matches.opt_str("src").map(PathBuf::from)
            .or_else(|| env::var_os("SRC").map(PathBuf::from))
            .unwrap_or(cwd);

        Flags {
            verbose: matches.opt_count("verbose"),
            stage,
            on_fail: matches.opt_str("on-fail"),
            keep_stage: matches.opt_str("keep-stage").map(|j| j.parse().unwrap()),
            build: matches.opt_str("build").map(|s| INTERNER.intern_string(s)),
            host: split(matches.opt_strs("host"))
                .into_iter().map(|x| INTERNER.intern_string(x)).collect::<Vec<_>>(),
            target: split(matches.opt_strs("target"))
                .into_iter().map(|x| INTERNER.intern_string(x)).collect::<Vec<_>>(),
            config: cfg_file,
            src,
            jobs: matches.opt_str("jobs").map(|j| j.parse().unwrap()),
            cmd,
            incremental: matches.opt_present("incremental"),
        }
    }
}

impl Subcommand {
    pub fn test_args(&self) -> Vec<&str> {
        match *self {
            Subcommand::Test { ref test_args, .. } |
            Subcommand::Bench { ref test_args, .. } => {
                test_args.iter().flat_map(|s| s.split_whitespace()).collect()
            }
            _ => Vec::new(),
        }
    }

    pub fn fail_fast(&self) -> bool {
        match *self {
            Subcommand::Test { fail_fast, .. } => fail_fast,
            _ => false,
        }
    }
}

fn split(s: Vec<String>) -> Vec<String> {
    s.iter().flat_map(|s| s.split(',')).map(|s| s.to_string()).collect()
}
<|endoftext|>


<commit_before>extern crate regex;

#[derive(Debug)]
enum CommandOperator {
    AND,
    OR,
    ALWAYS
}

#[derive(Debug)]
struct Command {
    command: Vec<String>,
    command_operator: CommandOperator
}

fn clean_cmd(mut cmd: String) -> String {
    match cmd.chars().last() {
        Some(c) => {if c == '\n' { cmd.pop(); }},
        _ => {}
    }
    return cmd.trim().to_string();
}

fn get_all_commands(command: &String) -> Vec<Command>{
    let mut commands: Vec<Command> = vec![];
    let mut i = 0;
    let re= regex::Regex::new(r";|&&|\|\|").unwrap();
    let mut caps = re.captures_iter(command);

    for mut part in re.split(command) {
        let cmd: String = clean_cmd(part.to_string());
        let cmd_vector = cmd.split(" ").map(|x| x.to_string()).collect::<Vec<String>>();
        if i == 0 {
            commands.push(Command {
                command: cmd_vector,
                command_operator: CommandOperator::ALWAYS
            })
        } else {
            commands.push(Command {
                command: cmd_vector,
                command_operator:
                match caps.next() {
                    Some(t) => {
                        let m = t.get(0).unwrap().as_str();
                        if m == ";" {
                            CommandOperator::ALWAYS
                        } else if m == "&&" {
                            CommandOperator::AND
                        } else if m == "||" {
                            CommandOperator::OR
                        } else {
                            CommandOperator::ALWAYS
                        }
                    },
                    _ => {
                        CommandOperator::ALWAYS
                    }
                }
            });
        }
        i += 1
    }
    return commands;
}

fn command_parser(mut command_vector : Vec<String>) -> i32 {
    use cd::cd;
    use launch_bin::launch_bin;
    use env::{env, setenv, unsetenv};

    match command_vector[0].trim() {
        "cd"        => return cd(&command_vector),
        "env"       => return env(),
        "setenv"    => return setenv(&mut command_vector),
        "unsetenv"  => return unsetenv(&mut command_vector),
        ""          => {return 0},
        _           => return launch_bin(&mut command_vector)
    }
}

pub fn handle_command(command: &mut String) {
    let mut status: i32 = 0;
    let all_commands: Vec<Command> = get_all_commands(command);
    for mut cmd in all_commands {
        match cmd.command_operator {
            CommandOperator::AND => if status != 0 { return } else { status = command_parser(cmd.command) },
            CommandOperator::OR  => if status == 0 { return } else { status = command_parser(cmd.command) },
            _ => { status = command_parser(cmd.command) }
        }
    }
}
<commit_msg>better handling of && and ||<commit_after>extern crate regex;

#[derive(Debug)]
enum CommandOperator {
    AND,
    OR,
    ALWAYS,
    PIPE
}

#[derive(Debug)]
struct Command {
    command: Vec<String>,
    command_operator: CommandOperator
}

fn clean_cmd(mut cmd: String) -> String {
    match cmd.chars().last() {
        Some(c) => {if c == '\n' { cmd.pop(); }},
        _ => {}
    }
    return cmd.trim().to_string();
}

fn get_all_commands(command: &String) -> Vec<Command>{
    let mut commands: Vec<Command> = vec![];
    let re= regex::Regex::new(r";|&&|\|\||\|").unwrap();
    let mut caps = re.captures_iter(command);

    for mut part in re.split(command) {
        let cmd: String = clean_cmd(part.to_string());
        let cmd_vector = cmd.split(" ").map(|x: &str| x.to_string()).collect::<Vec<String>>();
        commands.push(Command {
            command: cmd_vector,
            command_operator:
            match caps.next() {
                Some(t) => {
                    let m = t.get(0).unwrap().as_str();
                    if m == ";" {
                        CommandOperator::ALWAYS
                    } else if m == "&&" {
                        CommandOperator::AND
                    } else if m == "||" {
                        CommandOperator::OR
                    } else if m == "|" {
                        CommandOperator::PIPE
                    } else {
                        CommandOperator::ALWAYS
                    }
                },
                _ => {
                    CommandOperator::ALWAYS
                }
            }
        });
    }
    return commands;
}

fn command_parser(mut command_vector : Vec<String>) -> i32 {
    use cd::cd;
    use launch_bin::launch_bin;
    use env::{env, setenv, unsetenv};

    match command_vector[0].trim() {
        "cd"        => return cd(&command_vector),
        "env"       => return env(),
        "setenv"    => return setenv(&mut command_vector),
        "unsetenv"  => return unsetenv(&mut command_vector),
        ""          => {return 0},
        _           => return launch_bin(&mut command_vector)
    }
}

pub fn handle_command(command: &mut String) {
    let mut status: i32 = 0;
    let all_commands: Vec<Command> = get_all_commands(command);
    let mut operator = CommandOperator::ALWAYS;

    for mut cmd in all_commands {
        match operator {
            CommandOperator::AND => if status != 0 { return } else { status = command_parser(cmd.command) },
            CommandOperator::OR  => if status == 0 { return } else { status = command_parser(cmd.command) },
            _ => { status = command_parser(cmd.command) }
        }
        operator = cmd.command_operator;
    }
}
<|endoftext|>


<commit_before>use luminance::{Dim2, Flat, Framebuffer, Mode, Pipe, Pipeline, RGBA32F, RawTexture, RenderCommand,
                ShadingCommand, Tess, TessRender, Texture, Unit, Uniform};

use compositor::{Compositor, Screen};
use resource::Res;
use scene::Scene;
use shader::Program;

pub type Texture2D<A> = Texture<Flat, Dim2, A>;

const FORWARD_SOURCE: &'static Uniform<Unit> = &Uniform::new(0);

pub struct Forward {
  program: Res<Program>,
  quad: Tess,
  w: u32,
  h: u32
}

impl Forward {
  pub fn new(w: u32, h: u32, scene: &mut Scene) -> Self {
    let program = scene.get("spectra/compositors/forward.glsl", vec![FORWARD_SOURCE.sem("source")]).unwrap();

    Forward {
      program: program,
      quad: Tess::attributeless(Mode::TriangleStrip, 4),
      w: w,
      h: h
    }
  }

  fn to_screen(&self, source: &Texture2D<RGBA32F>) {
    let back_fb = Framebuffer::default((self.w, self.h));
    let textures: &[&RawTexture] = &[source];
    let tess_render = TessRender::one_whole(&self.quad);

    Pipeline::new(&back_fb, [0., 0., 0., 0.], textures, &[], vec![
      Pipe::empty()
        .uniforms(&[FORWARD_SOURCE.alter(Unit::new(0))])
        .unwrap(ShadingCommand::new(&self.program.borrow(), vec![
          Pipe::new(RenderCommand::new(None, true, vec![
            Pipe::new(tess_render)]))
          ]))
    ]).run();
  }
}
<commit_msg>pub Forward::to_screen().<commit_after>use luminance::{Dim2, Flat, Framebuffer, Mode, Pipe, Pipeline, RGBA32F, RawTexture, RenderCommand,
                ShadingCommand, Tess, TessRender, Texture, Unit, Uniform};

use compositor::{Compositor, Screen};
use resource::Res;
use scene::Scene;
use shader::Program;

pub type Texture2D<A> = Texture<Flat, Dim2, A>;

const FORWARD_SOURCE: &'static Uniform<Unit> = &Uniform::new(0);

pub struct Forward {
  program: Res<Program>,
  quad: Tess,
  w: u32,
  h: u32
}

impl Forward {
  pub fn new(w: u32, h: u32, scene: &mut Scene) -> Self {
    let program = scene.get("spectra/compositors/forward.glsl", vec![FORWARD_SOURCE.sem("source")]).unwrap();

    Forward {
      program: program,
      quad: Tess::attributeless(Mode::TriangleStrip, 4),
      w: w,
      h: h
    }
  }

  pub fn to_screen(&self, source: &Texture2D<RGBA32F>) {
    let back_fb = Framebuffer::default((self.w, self.h));
    let textures: &[&RawTexture] = &[source];
    let tess_render = TessRender::one_whole(&self.quad);

    Pipeline::new(&back_fb, [0., 0., 0., 0.], textures, &[], vec![
      Pipe::empty()
        .uniforms(&[FORWARD_SOURCE.alter(Unit::new(0))])
        .unwrap(ShadingCommand::new(&self.program.borrow(), vec![
          Pipe::new(RenderCommand::new(None, true, vec![
            Pipe::new(tess_render)]))
          ]))
    ]).run();
  }
}
<|endoftext|>