<commit_before>/// Parser input is generic over terminal type, which is usually u8 or char.
pub trait Input<T> where T: Copy {
	/// Get current position.
	fn position(&self) -> usize;

	/// Peek current symbol.
	fn current(&self) -> Option<T>;

	/// Advance to next symbol.
	fn advance(&mut self);

	/// Jump to specified position.
	fn jump_to(&mut self, position: usize);

	/// Get a segment from the input.
	fn segment(&self, start: usize, end: usize) -> Vec<T>;
}

/// Wrap &[u8] or &[char] as input to parser.
pub struct DataInput<'a, T: 'a> {
	pub data: &'a [T],
	pub position: usize,
}

impl<'a, T: Copy> DataInput<'a, T> {
	pub fn new(input: &'a [T]) -> DataInput<T> {
		DataInput {
			data: input,
			position: 0,
		}
	}
}

impl<'a, T: Copy> Input<T> for DataInput<'a, T> {
	fn position(&self) -> usize {
		self.position
	}

	fn current(&self) -> Option<T> {
		self.data.get(self.position).cloned()
	}

	fn advance(&mut self) {
		self.position += 1;
	}

	fn jump_to(&mut self, position: usize) {
		self.position = position;
	}

	fn segment(&self, start: usize, end: usize) -> Vec<T> {
		self.data[start..end].to_vec()
	}
}

/// Wrap &str as input to parser.
pub struct TextInput<'a> {
	pub text: &'a str,
	pub position: usize,
}

impl<'a> TextInput<'a> {
	pub fn new(input: &'a str) -> TextInput<'a> {
		TextInput {
			text: input,
			position: 0,
		}
	}
}

impl<'a> Input<char> for TextInput<'a> {
	fn position(&self) -> usize {
		self.position
	}

	fn current(&self) -> Option<char>
	{
		self.text[self.position..].chars().next()
	}

	fn advance(&mut self) {
		if let Some(c) = self.text[self.position..].chars().next() {
			self.position += c.len_utf8();
		}
	}

	fn jump_to(&mut self, position: usize) {
		self.position = position;
	}

	fn segment(&self, start: usize, end: usize) -> Vec<char> {
		self.text[start..end].chars().collect()
	}
}
<commit_msg>Derive Debug and Clone for DataInput and TextInput<commit_after>/// Parser input is generic over terminal type, which is usually u8 or char.
pub trait Input<T> where T: Copy {
	/// Get current position.
	fn position(&self) -> usize;

	/// Peek current symbol.
	fn current(&self) -> Option<T>;

	/// Advance to next symbol.
	fn advance(&mut self);

	/// Jump to specified position.
	fn jump_to(&mut self, position: usize);

	/// Get a segment from the input.
	fn segment(&self, start: usize, end: usize) -> Vec<T>;
}

/// Wrap &[u8] or &[char] as input to parser.
#[derive(Debug, Clone)]
pub struct DataInput<'a, T: 'a> {
	pub data: &'a [T],
	pub position: usize,
}

impl<'a, T: Copy> DataInput<'a, T> {
	pub fn new(input: &'a [T]) -> DataInput<T> {
		DataInput {
			data: input,
			position: 0,
		}
	}
}

impl<'a, T: Copy> Input<T> for DataInput<'a, T> {
	fn position(&self) -> usize {
		self.position
	}

	fn current(&self) -> Option<T> {
		self.data.get(self.position).cloned()
	}

	fn advance(&mut self) {
		self.position += 1;
	}

	fn jump_to(&mut self, position: usize) {
		self.position = position;
	}

	fn segment(&self, start: usize, end: usize) -> Vec<T> {
		self.data[start..end].to_vec()
	}
}

/// Wrap &str as input to parser.
#[derive(Debug, Clone)]
pub struct TextInput<'a> {
	pub text: &'a str,
	pub position: usize,
}

impl<'a> TextInput<'a> {
	pub fn new(input: &'a str) -> TextInput<'a> {
		TextInput {
			text: input,
			position: 0,
		}
	}
}

impl<'a> Input<char> for TextInput<'a> {
	fn position(&self) -> usize {
		self.position
	}

	fn current(&self) -> Option<char>
	{
		self.text[self.position..].chars().next()
	}

	fn advance(&mut self) {
		if let Some(c) = self.text[self.position..].chars().next() {
			self.position += c.len_utf8();
		}
	}

	fn jump_to(&mut self, position: usize) {
		self.position = position;
	}

	fn segment(&self, start: usize, end: usize) -> Vec<char> {
		self.text[start..end].chars().collect()
	}
}
<|endoftext|>


<commit_before>use godcoin::prelude::{KeyPair, Wif};

pub fn generate_keypair() {
    let pair = KeyPair::gen();
    println!("~~ Keys have been generated ~~");
    println!("Private key WIF: {}", pair.1.to_wif());
    println!("Public key WIF: {}", pair.0.to_wif());
    println!("- Make sure the keys are securely stored");
    println!("- Coins cannot be recovered if you lose your private key");
    println!("- Never give private keys to anyone");
}
<commit_msg>Print P2SH key for cli keypair gen command<commit_after>use godcoin::prelude::{KeyPair, Wif, ScriptHash};

pub fn generate_keypair() {
    let pair = KeyPair::gen();
    println!("~~ Keys have been generated ~~");
    println!("Private key WIF: {}", pair.1.to_wif());
    println!("Public key WIF: {}", pair.0.to_wif());
    println!("P2SH key WIF: {}", ScriptHash::from(pair.0).to_wif());
    println!("- Make sure the keys are securely stored");
    println!("- Coins cannot be recovered if you lose your private key");
    println!("- Never give private keys to anyone");
}
<|endoftext|>


<commit_before>extern crate comm;
extern crate env_logger;
#[macro_use]
extern crate log;
extern crate num;

use num::bigint::ToBigUint;
use std::env;
use std::thread;
use comm::address::{Address, LENGTH};
use comm::client;
use comm::network;
use comm::node;

pub fn start_multiple(host: &str, port_start: u16, port_end: u16, router_host: Option<&str>) {
    let min = 0.to_biguint().unwrap();
    let max = num::pow(2.to_biguint().unwrap(), LENGTH);

    info!("Starting nodes {}:{}..{}", host, port_start, port_end);

    for port in port_start..port_end {
        debug!("-> starting {}", port);

        let routers: Vec<Box<node::Node>> = match router_host {
            Some(host) => {
                let router_node = Box::new(node::UdpNode::new(Address::null(), host));
                vec![router_node]
            }
            None => vec![]
        };

        let address = Address::random(&min, &max);
        let socket_address = (host, port);
        let network = network::Network::new(address, socket_address, routers);
        let client = client::Client::new(address);
        client.run(network);
        thread::sleep(std::time::Duration::from_millis(100));
    }

    info!("All running :)");
    loop { thread::park(); }
}

fn main() {
    env_logger::init().unwrap();
    let args: Vec<String> = env::args().collect();

    let host = args[1].as_str();
    let port_start = args[2].clone().parse::<u16>().unwrap();
    let port_end = args[3].clone().parse::<u16>().unwrap();
    let router = args.get(4).map(|h| h.as_str());

    start_multiple(host, port_start, port_end, router);
}
<commit_msg>Add rampup arg to multi CLI<commit_after>extern crate comm;
extern crate env_logger;
#[macro_use]
extern crate log;
extern crate num;

use num::bigint::ToBigUint;
use std::env;
use std::thread;
use comm::address::{Address, LENGTH};
use comm::client;
use comm::network;
use comm::node;

pub fn start_multiple(host: &str, port_start: u16, port_end: u16, router_host: Option<&str>, rampup: u64) {
    let min = 0.to_biguint().unwrap();
    let max = num::pow(2.to_biguint().unwrap(), LENGTH);

    info!("Starting nodes {}:{}..{}", host, port_start, port_end);

    for port in port_start..port_end {
        debug!("-> starting {}", port);

        let routers: Vec<Box<node::Node>> = match router_host {
            Some(host) => {
                let router_node = Box::new(node::UdpNode::new(Address::null(), host));
                vec![router_node]
            }
            None => vec![]
        };

        let address = Address::random(&min, &max);
        let socket_address = (host, port);
        let network = network::Network::new(address, socket_address, routers);
        let client = client::Client::new(address);
        client.run(network);
        thread::sleep(std::time::Duration::from_millis(rampup));
    }

    info!("All running :)");
    loop { thread::park(); }
}

fn main() {
    env_logger::init().unwrap();
    let args: Vec<String> = env::args().collect();

    let host = args[1].as_str();
    let port_start = args[2].clone().parse::<u16>().unwrap();
    let port_end = args[3].clone().parse::<u16>().unwrap();
    let rampup = args[4].clone().parse::<u64>().unwrap();
    let router = args.get(5).map(|h| h.as_str());

    start_multiple(host, port_start, port_end, router, rampup);
}
<|endoftext|>


<commit_before>use specs::*;
use util::*;

use amq_protocol_types::AMQPType;
use handlebars::{self, Context, Handlebars, Helper, HelperDef, HelperResult, JsonValue, Output, Renderable, RenderContext, RenderError, ScopedJson, to_json};
use serde_json::{self};

use std::fs::File;
use std::io::Write;
use std::path::Path;
use std::collections::BTreeMap;

/// Type alias to avoid making our users explicitely depend on an extra dependency
pub type CodeGenerator = Handlebars;

/// Our extension for better integration with Handlebars
pub trait HandlebarsAMQPExtension {
    /// Register the various standrad helpers we'll need for AMQP codegen
    fn register_amqp_helpers(self) -> Self;
    /// Generate code using the standard representation of specs and the given template, using the
    /// given name for the variable holding the [protocol definition](../specs.AMQProtocolDefinition.html).
    fn simple_codegen(out_dir: &str, target: &str, template_name: &str, template: &str, var_name: &str);
}

impl HandlebarsAMQPExtension for CodeGenerator {
    fn register_amqp_helpers(mut self) -> CodeGenerator {
        self.register_escape_fn(handlebars::no_escape);
        self.register_helper("camel",            Box::new(CamelHelper));
        self.register_helper("snake",            Box::new(SnakeHelper));
        self.register_helper("snake_type",       Box::new(SnakeTypeHelper));
        self.register_helper("sanitize_name",    Box::new(SanitizeNameHelper));
        self.register_helper("method_has_flags", Box::new(MethodHasFlagsHelper));
        self.register_helper("each_argument",    Box::new(EachArgumentHelper));
        self.register_helper("each_flag",        Box::new(EachFlagHelper));
        self
    }

    fn simple_codegen(out_dir: &str, target: &str, template_name: &str, template: &str, var_name: &str) {
        let dest_path   = Path::new(out_dir).join(format!("{}.rs", target));
        let mut f       = File::create(&dest_path).unwrap_or_else(|_| panic!("Failed to create {}.rs", target));
        let specs       = AMQProtocolDefinition::load();
        let mut codegen = CodeGenerator::new().register_amqp_helpers();
        let mut data    = BTreeMap::new();

        codegen.set_strict_mode(true);
        codegen.register_template_string(template_name, template.to_string()).unwrap_or_else(|_| panic!("Failed to register {} template", template_name));
        data.insert(var_name.to_string(), specs);

        writeln!(f, "{}", codegen.render(template_name, &data).unwrap_or_else(|err| panic!("Failed to render {} template: {}", template_name, err))).unwrap_or_else(|_| panic!("Failed to generate {}.rs", target));
    }
}

/// Helper for converting text to camel case
pub struct CamelHelper;
impl HelperDef for CamelHelper {
    fn call<'reg: 'rc, 'rc>(&self, h: &Helper<'reg, 'rc>, _: &'reg Handlebars, _: &'rc Context, _: &mut RenderContext<'reg>, out: &mut Output) -> HelperResult {
        let value = h.param(0).ok_or_else(|| RenderError::new("Param not found for helper \"camel\""))?;
        let param = value.value().as_str().ok_or_else(|| RenderError::new("Non-string param given to helper \"camel\""))?;
        out.write(&camel_case(param))?;
        Ok(())
    }
}

/// Helper for converting text to snake case
pub struct SnakeHelper;
impl HelperDef for SnakeHelper {
    fn call<'reg: 'rc, 'rc>(&self, h: &Helper<'reg, 'rc>, _: &'reg Handlebars, _: &'rc Context, _: &mut RenderContext<'reg>, out: &mut Output) -> HelperResult {
        let value = h.param(0).ok_or_else(|| RenderError::new("Param not found for helper \"snake\""))?;
        let param = value.value().as_str().ok_or_else(|| RenderError::new("Non-string param given to helper \"snake\""))?;
        out.write(&snake_case(param))?;
        Ok(())
    }
}

/// Helper for getting the type name converted to snake case
pub struct SnakeTypeHelper;
impl HelperDef for SnakeTypeHelper {
    fn call<'reg: 'rc, 'rc>(&self, h: &Helper<'reg, 'rc>, _: &'reg Handlebars, _: &'rc Context, _: &mut RenderContext<'reg>, out: &mut Output) -> HelperResult {
        let value           = h.param(0).ok_or_else(|| RenderError::new("Param not found for helper \"snake\""))?;
        let param: AMQPType = serde_json::from_value(value.value().clone()).map_err(|_| RenderError::new("Param is not an AMQPType for helper \"snake_type\""))?;
        out.write(&snake_case(&param.to_string()))?;
        Ok(())
    }
}

/// Helper to sanitize name so the it becomes a valid identifier
pub struct SanitizeNameHelper;
impl HelperDef for SanitizeNameHelper {
    fn call<'reg: 'rc, 'rc>(&self, h: &Helper<'reg, 'rc>, _: &'reg Handlebars, _: &'rc Context, _: &mut RenderContext<'reg>, out: &mut Output) -> HelperResult {
        let value = h.param(0).ok_or_else(|| RenderError::new("Param not found for helper \"sanitize_name\""))?;
        let param = value.value().as_str().ok_or_else(|| RenderError::new("Non-string param given to helper \"sanitize_name\""))?;
        out.write(&param.replace('-', "_"))?;
        Ok(())
    }
}

/// Helper for checking is a method has some flags argument
pub struct MethodHasFlagsHelper;
impl HelperDef for MethodHasFlagsHelper {
    fn call_inner<'reg: 'rc, 'rc>(&self, h: &Helper<'reg, 'rc>, _: &'reg Handlebars, _: &'rc Context, _: &mut RenderContext<'reg>) -> Result<Option<ScopedJson<'reg, 'rc>>, RenderError> {
        let value     = h.param(0).ok_or_else(|| RenderError::new("Param not found for helper \"method_has_flags\""))?;
        let method    = serde_json::from_value::<AMQPMethod>(value.value().clone()).map_err(|_| RenderError::new("Non-AMQPMethod param given to helper \"camel\""))?;
        let has_flags = method.arguments.iter().any(|arg| match *arg {
            AMQPArgument::Value(_) => false,
            AMQPArgument::Flags(_) => true,
        });
        Ok(Some(ScopedJson::Derived(JsonValue::from(has_flags))))
    }
}

/// Helper to walk through a Vec of [AMQPArgument](../specs.AMQPArgument.html).
pub struct EachArgumentHelper;
impl HelperDef for EachArgumentHelper {
    fn call<'reg: 'rc, 'rc>(&self, h: &Helper<'reg, 'rc>, r: &'reg Handlebars, ctx: &'rc Context, rc: &mut RenderContext<'reg>, out: &mut Output) -> HelperResult {
        let value = h.param(0).ok_or_else(|| RenderError::new("Param not found for helper \"each_argument\""))?;

        if let Some(t) = h.template() {
            rc.promote_local_vars();
            let local_path_root = value.path_root().map(|p| format!("{}/{}", rc.get_path(), p));
            let arguments : Vec<AMQPArgument> = serde_json::from_value(value.value().clone()).map_err(|_| RenderError::new("Param is not a Vec<AMQPArgument> for helper \"each_argument\""))?;
            for (index, argument) in arguments.iter().enumerate() {
                let mut local_rc = rc.derive();
                if let Some(ref p) = local_path_root {
                    local_rc.push_local_path_root(p.clone());
                }
                local_rc.set_local_var("@index".to_string(), to_json(&index));
                if let Some(inner_path) = value.path() {
                    let new_path = format!("{}/{}.[{}]", local_rc.get_path(), inner_path, index);
                    local_rc.set_path(new_path.clone());
                }
                if let Some(block_param) = h.block_param() {
                    let mut map = BTreeMap::new();
                    match *argument {
                        AMQPArgument::Value(ref v) => {
                            map.insert(block_param.to_string(), to_json(v));
                            map.insert("argument_is_value".to_string(), to_json(&true));
                        },
                        AMQPArgument::Flags(ref f) => {
                            map.insert(block_param.to_string(), to_json(f));
                            map.insert("argument_is_value".to_string(), to_json(&false));
                        },
                    };
                    local_rc.push_block_context(&map)?;
                }
                t.render(r, ctx, &mut local_rc, out)?;
                if h.block_param().is_some() {
                    local_rc.pop_block_context();
                }
                if local_path_root.is_some() {
                    local_rc.pop_local_path_root();
                }
            }
            rc.demote_local_vars();
        }
        Ok(())
    }
}

/// Helper to walk through a Vec of [AMQPFlagArgument](../specs.AMQPFlagArgument.html).
pub struct EachFlagHelper;
impl HelperDef for EachFlagHelper {
    fn call<'reg: 'rc, 'rc>(&self, h: &Helper<'reg, 'rc>, r: &'reg Handlebars, ctx: &'rc Context, rc: &mut RenderContext<'reg>, out: &mut Output) -> HelperResult {
        let value = h.param(0).ok_or_else(|| RenderError::new("Param not found for helper \"each_flag\""))?;

        if let Some(t) = h.template() {
            rc.promote_local_vars();
            let local_path_root = value.path_root().map(|p| format!("{}/{}", rc.get_path(), p));
            let flags : Vec<AMQPFlagArgument> = serde_json::from_value(value.value().clone()).map_err(|_| RenderError::new("Param is not a Vec<AMQPFlagArgument> for helper \"each_flag\""))?;
            for (index, flag) in flags.iter().enumerate() {
                let mut local_rc = rc.derive();
                if let Some(ref p) = local_path_root {
                    local_rc.push_local_path_root(p.clone());
                }
                local_rc.set_local_var("@index".to_string(), to_json(&index));
                if let Some(inner_path) = value.path() {
                    let new_path = format!("{}/{}.[{}]", local_rc.get_path(), inner_path, index);
                    local_rc.set_path(new_path.clone());
                }
                if let Some(block_param) = h.block_param() {
                    let mut map = BTreeMap::new();
                    map.insert(block_param.to_string(), to_json(flag));
                    local_rc.push_block_context(&map)?;
                }
                t.render(r, ctx, &mut local_rc, out)?;
                if h.block_param().is_some() {
                    local_rc.pop_block_context();
                }
                if local_path_root.is_some() {
                    local_rc.pop_local_path_root();
                }
            }
            rc.demote_local_vars();
        }
        Ok(())
    }
}

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

    use amq_protocol_types::*;

    use std::collections::BTreeMap;

    pub const TEMPLATE: &'static str = r#"
{{protocol.name}} - {{protocol.major_version}}.{{protocol.minor_version}}.{{protocol.revision}}
{{protocol.copyright}}
port {{protocol.port}}
{{#each protocol.domains ~}}
{{@key}}: {{this}}
{{/each ~}}
{{#each protocol.constants as |constant| ~}}
{{constant.name}} = {{constant.value}}
{{/each ~}}
{{#each protocol.classes as |class| ~}}
{{class.id}} - {{class.name}}
{{#each class.properties as |property| ~}}
{{property.name}}: {{property.type}}
{{/each ~}}
{{#each class.methods as |method| ~}}
{{method.id}} - {{method.name}}
synchronous: {{method.synchronous}}
{{#each_argument method.arguments as |argument| ~}}
{{#if argument_is_value ~}}
{{argument.name}}({{argument.domain}}): {{argument.type}}
{{else}}
{{#each_flag argument as |flag| ~}}
{{flag.name}}: {{flag.default_value}}
{{/each_flag ~}}
{{/if ~}}
{{/each_argument ~}}
{{/each ~}}
{{/each ~}}
"#;

    fn specs() -> AMQProtocolDefinition {
        let mut domains = BTreeMap::new();
        domains.insert("domain1".to_string(), AMQPType::LongString);
        AMQProtocolDefinition {
            name:          "AMQP".to_string(),
            major_version: 0,
            minor_version: 9,
            revision:      1,
            port:          5672,
            copyright:     "Copyright 1\nCopyright 2".to_string(),
            domains:       domains,
            constants:     vec![
                AMQPConstant {
                    name:      "constant1".to_string(),
                    amqp_type: AMQPType::ShortUInt,
                    value:     128,
                }
            ],
            soft_errors:   Vec::new(),
            hard_errors:   Vec::new(),
            classes:       vec![
                AMQPClass {
                    id:             42,
                    methods:        vec![
                        AMQPMethod {
                            id:            64,
                            arguments:     vec![
                                AMQPArgument::Value(AMQPValueArgument {
                                    amqp_type:     AMQPType::LongString,
                                    name:          "argument1".to_string(),
                                    default_value: Some(AMQPValue::LongString("value1".to_string())),
                                    domain:        Some("domain1".to_string()),
                                }),
                                AMQPArgument::Flags(vec![
                                    AMQPFlagArgument {
                                        name:         "flag1".to_string(),
                                        default_value: true,
                                    },
                                    AMQPFlagArgument {
                                        name:         "flag2".to_string(),
                                        default_value: false,
                                    },
                                ]),
                            ],
                            name:          "method1".to_string(),
                            synchronous:   true,
                        }
                    ],
                    name:           "class1".to_string(),
                    properties:     vec![
                        AMQPProperty {
                            amqp_type: AMQPType::LongString,
                            name:      "property1".to_string(),
                        }
                    ],
                }
            ],
        }
    }

    #[test]
    fn main_template() {
        let mut data    = BTreeMap::new();
        let mut codegen = CodeGenerator::new().register_amqp_helpers();
        data.insert("protocol".to_string(), specs());
        assert!(codegen.register_template_string("main", TEMPLATE.to_string()).is_ok());
        assert_eq!(codegen.render("main", &data).unwrap(), r#"
AMQP - 0.9.1
Copyright 1
Copyright 2
port 5672
domain1: LongString
constant1 = 128
42 - class1
property1: LongString
64 - method1
synchronous: true
argument1(domain1): LongString

flag1: true
flag2: false
"#);
    }
}
<commit_msg>codegen: display templating error instead of ignoring it<commit_after>use specs::*;
use util::*;

use amq_protocol_types::AMQPType;
use handlebars::{self, Context, Handlebars, Helper, HelperDef, HelperResult, JsonValue, Output, Renderable, RenderContext, RenderError, ScopedJson, to_json};
use serde_json::{self};

use std::fs::File;
use std::io::Write;
use std::path::Path;
use std::collections::BTreeMap;

/// Type alias to avoid making our users explicitely depend on an extra dependency
pub type CodeGenerator = Handlebars;

/// Our extension for better integration with Handlebars
pub trait HandlebarsAMQPExtension {
    /// Register the various standrad helpers we'll need for AMQP codegen
    fn register_amqp_helpers(self) -> Self;
    /// Generate code using the standard representation of specs and the given template, using the
    /// given name for the variable holding the [protocol definition](../specs.AMQProtocolDefinition.html).
    fn simple_codegen(out_dir: &str, target: &str, template_name: &str, template: &str, var_name: &str);
}

impl HandlebarsAMQPExtension for CodeGenerator {
    fn register_amqp_helpers(mut self) -> CodeGenerator {
        self.register_escape_fn(handlebars::no_escape);
        self.register_helper("camel",            Box::new(CamelHelper));
        self.register_helper("snake",            Box::new(SnakeHelper));
        self.register_helper("snake_type",       Box::new(SnakeTypeHelper));
        self.register_helper("sanitize_name",    Box::new(SanitizeNameHelper));
        self.register_helper("method_has_flags", Box::new(MethodHasFlagsHelper));
        self.register_helper("each_argument",    Box::new(EachArgumentHelper));
        self.register_helper("each_flag",        Box::new(EachFlagHelper));
        self
    }

    fn simple_codegen(out_dir: &str, target: &str, template_name: &str, template: &str, var_name: &str) {
        let dest_path   = Path::new(out_dir).join(format!("{}.rs", target));
        let mut f       = File::create(&dest_path).unwrap_or_else(|_| panic!("Failed to create {}.rs", target));
        let specs       = AMQProtocolDefinition::load();
        let mut codegen = CodeGenerator::new().register_amqp_helpers();
        let mut data    = BTreeMap::new();

        codegen.set_strict_mode(true);
        codegen.register_template_string(template_name, template.to_string()).unwrap_or_else(|e| panic!("Failed to register {} template: {}", template_name, e));
        data.insert(var_name.to_string(), specs);

        writeln!(f, "{}", codegen.render(template_name, &data).unwrap_or_else(|err| panic!("Failed to render {} template: {}", template_name, err))).unwrap_or_else(|e| panic!("Failed to generate {}.rs: {}", target, e));
    }
}

/// Helper for converting text to camel case
pub struct CamelHelper;
impl HelperDef for CamelHelper {
    fn call<'reg: 'rc, 'rc>(&self, h: &Helper<'reg, 'rc>, _: &'reg Handlebars, _: &'rc Context, _: &mut RenderContext<'reg>, out: &mut Output) -> HelperResult {
        let value = h.param(0).ok_or_else(|| RenderError::new("Param not found for helper \"camel\""))?;
        let param = value.value().as_str().ok_or_else(|| RenderError::new("Non-string param given to helper \"camel\""))?;
        out.write(&camel_case(param))?;
        Ok(())
    }
}

/// Helper for converting text to snake case
pub struct SnakeHelper;
impl HelperDef for SnakeHelper {
    fn call<'reg: 'rc, 'rc>(&self, h: &Helper<'reg, 'rc>, _: &'reg Handlebars, _: &'rc Context, _: &mut RenderContext<'reg>, out: &mut Output) -> HelperResult {
        let value = h.param(0).ok_or_else(|| RenderError::new("Param not found for helper \"snake\""))?;
        let param = value.value().as_str().ok_or_else(|| RenderError::new("Non-string param given to helper \"snake\""))?;
        out.write(&snake_case(param))?;
        Ok(())
    }
}

/// Helper for getting the type name converted to snake case
pub struct SnakeTypeHelper;
impl HelperDef for SnakeTypeHelper {
    fn call<'reg: 'rc, 'rc>(&self, h: &Helper<'reg, 'rc>, _: &'reg Handlebars, _: &'rc Context, _: &mut RenderContext<'reg>, out: &mut Output) -> HelperResult {
        let value           = h.param(0).ok_or_else(|| RenderError::new("Param not found for helper \"snake\""))?;
        let param: AMQPType = serde_json::from_value(value.value().clone()).map_err(|_| RenderError::new("Param is not an AMQPType for helper \"snake_type\""))?;
        out.write(&snake_case(&param.to_string()))?;
        Ok(())
    }
}

/// Helper to sanitize name so the it becomes a valid identifier
pub struct SanitizeNameHelper;
impl HelperDef for SanitizeNameHelper {
    fn call<'reg: 'rc, 'rc>(&self, h: &Helper<'reg, 'rc>, _: &'reg Handlebars, _: &'rc Context, _: &mut RenderContext<'reg>, out: &mut Output) -> HelperResult {
        let value = h.param(0).ok_or_else(|| RenderError::new("Param not found for helper \"sanitize_name\""))?;
        let param = value.value().as_str().ok_or_else(|| RenderError::new("Non-string param given to helper \"sanitize_name\""))?;
        out.write(&param.replace('-', "_"))?;
        Ok(())
    }
}

/// Helper for checking is a method has some flags argument
pub struct MethodHasFlagsHelper;
impl HelperDef for MethodHasFlagsHelper {
    fn call_inner<'reg: 'rc, 'rc>(&self, h: &Helper<'reg, 'rc>, _: &'reg Handlebars, _: &'rc Context, _: &mut RenderContext<'reg>) -> Result<Option<ScopedJson<'reg, 'rc>>, RenderError> {
        let value     = h.param(0).ok_or_else(|| RenderError::new("Param not found for helper \"method_has_flags\""))?;
        let method    = serde_json::from_value::<AMQPMethod>(value.value().clone()).map_err(|_| RenderError::new("Non-AMQPMethod param given to helper \"camel\""))?;
        let has_flags = method.arguments.iter().any(|arg| match *arg {
            AMQPArgument::Value(_) => false,
            AMQPArgument::Flags(_) => true,
        });
        Ok(Some(ScopedJson::Derived(JsonValue::from(has_flags))))
    }
}

/// Helper to walk through a Vec of [AMQPArgument](../specs.AMQPArgument.html).
pub struct EachArgumentHelper;
impl HelperDef for EachArgumentHelper {
    fn call<'reg: 'rc, 'rc>(&self, h: &Helper<'reg, 'rc>, r: &'reg Handlebars, ctx: &'rc Context, rc: &mut RenderContext<'reg>, out: &mut Output) -> HelperResult {
        let value = h.param(0).ok_or_else(|| RenderError::new("Param not found for helper \"each_argument\""))?;

        if let Some(t) = h.template() {
            rc.promote_local_vars();
            let local_path_root = value.path_root().map(|p| format!("{}/{}", rc.get_path(), p));
            let arguments : Vec<AMQPArgument> = serde_json::from_value(value.value().clone()).map_err(|_| RenderError::new("Param is not a Vec<AMQPArgument> for helper \"each_argument\""))?;
            for (index, argument) in arguments.iter().enumerate() {
                let mut local_rc = rc.derive();
                if let Some(ref p) = local_path_root {
                    local_rc.push_local_path_root(p.clone());
                }
                local_rc.set_local_var("@index".to_string(), to_json(&index));
                if let Some(inner_path) = value.path() {
                    let new_path = format!("{}/{}.[{}]", local_rc.get_path(), inner_path, index);
                    local_rc.set_path(new_path.clone());
                }
                if let Some(block_param) = h.block_param() {
                    let mut map = BTreeMap::new();
                    match *argument {
                        AMQPArgument::Value(ref v) => {
                            map.insert(block_param.to_string(), to_json(v));
                            map.insert("argument_is_value".to_string(), to_json(&true));
                        },
                        AMQPArgument::Flags(ref f) => {
                            map.insert(block_param.to_string(), to_json(f));
                            map.insert("argument_is_value".to_string(), to_json(&false));
                        },
                    };
                    local_rc.push_block_context(&map)?;
                }
                t.render(r, ctx, &mut local_rc, out)?;
                if h.block_param().is_some() {
                    local_rc.pop_block_context();
                }
                if local_path_root.is_some() {
                    local_rc.pop_local_path_root();
                }
            }
            rc.demote_local_vars();
        }
        Ok(())
    }
}

/// Helper to walk through a Vec of [AMQPFlagArgument](../specs.AMQPFlagArgument.html).
pub struct EachFlagHelper;
impl HelperDef for EachFlagHelper {
    fn call<'reg: 'rc, 'rc>(&self, h: &Helper<'reg, 'rc>, r: &'reg Handlebars, ctx: &'rc Context, rc: &mut RenderContext<'reg>, out: &mut Output) -> HelperResult {
        let value = h.param(0).ok_or_else(|| RenderError::new("Param not found for helper \"each_flag\""))?;

        if let Some(t) = h.template() {
            rc.promote_local_vars();
            let local_path_root = value.path_root().map(|p| format!("{}/{}", rc.get_path(), p));
            let flags : Vec<AMQPFlagArgument> = serde_json::from_value(value.value().clone()).map_err(|_| RenderError::new("Param is not a Vec<AMQPFlagArgument> for helper \"each_flag\""))?;
            for (index, flag) in flags.iter().enumerate() {
                let mut local_rc = rc.derive();
                if let Some(ref p) = local_path_root {
                    local_rc.push_local_path_root(p.clone());
                }
                local_rc.set_local_var("@index".to_string(), to_json(&index));
                if let Some(inner_path) = value.path() {
                    let new_path = format!("{}/{}.[{}]", local_rc.get_path(), inner_path, index);
                    local_rc.set_path(new_path.clone());
                }
                if let Some(block_param) = h.block_param() {
                    let mut map = BTreeMap::new();
                    map.insert(block_param.to_string(), to_json(flag));
                    local_rc.push_block_context(&map)?;
                }
                t.render(r, ctx, &mut local_rc, out)?;
                if h.block_param().is_some() {
                    local_rc.pop_block_context();
                }
                if local_path_root.is_some() {
                    local_rc.pop_local_path_root();
                }
            }
            rc.demote_local_vars();
        }
        Ok(())
    }
}

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

    use amq_protocol_types::*;

    use std::collections::BTreeMap;

    pub const TEMPLATE: &'static str = r#"
{{protocol.name}} - {{protocol.major_version}}.{{protocol.minor_version}}.{{protocol.revision}}
{{protocol.copyright}}
port {{protocol.port}}
{{#each protocol.domains ~}}
{{@key}}: {{this}}
{{/each ~}}
{{#each protocol.constants as |constant| ~}}
{{constant.name}} = {{constant.value}}
{{/each ~}}
{{#each protocol.classes as |class| ~}}
{{class.id}} - {{class.name}}
{{#each class.properties as |property| ~}}
{{property.name}}: {{property.type}}
{{/each ~}}
{{#each class.methods as |method| ~}}
{{method.id}} - {{method.name}}
synchronous: {{method.synchronous}}
{{#each_argument method.arguments as |argument| ~}}
{{#if argument_is_value ~}}
{{argument.name}}({{argument.domain}}): {{argument.type}}
{{else}}
{{#each_flag argument as |flag| ~}}
{{flag.name}}: {{flag.default_value}}
{{/each_flag ~}}
{{/if ~}}
{{/each_argument ~}}
{{/each ~}}
{{/each ~}}
"#;

    fn specs() -> AMQProtocolDefinition {
        let mut domains = BTreeMap::new();
        domains.insert("domain1".to_string(), AMQPType::LongString);
        AMQProtocolDefinition {
            name:          "AMQP".to_string(),
            major_version: 0,
            minor_version: 9,
            revision:      1,
            port:          5672,
            copyright:     "Copyright 1\nCopyright 2".to_string(),
            domains:       domains,
            constants:     vec![
                AMQPConstant {
                    name:      "constant1".to_string(),
                    amqp_type: AMQPType::ShortUInt,
                    value:     128,
                }
            ],
            soft_errors:   Vec::new(),
            hard_errors:   Vec::new(),
            classes:       vec![
                AMQPClass {
                    id:             42,
                    methods:        vec![
                        AMQPMethod {
                            id:            64,
                            arguments:     vec![
                                AMQPArgument::Value(AMQPValueArgument {
                                    amqp_type:     AMQPType::LongString,
                                    name:          "argument1".to_string(),
                                    default_value: Some(AMQPValue::LongString("value1".to_string())),
                                    domain:        Some("domain1".to_string()),
                                }),
                                AMQPArgument::Flags(vec![
                                    AMQPFlagArgument {
                                        name:         "flag1".to_string(),
                                        default_value: true,
                                    },
                                    AMQPFlagArgument {
                                        name:         "flag2".to_string(),
                                        default_value: false,
                                    },
                                ]),
                            ],
                            name:          "method1".to_string(),
                            synchronous:   true,
                        }
                    ],
                    name:           "class1".to_string(),
                    properties:     vec![
                        AMQPProperty {
                            amqp_type: AMQPType::LongString,
                            name:      "property1".to_string(),
                        }
                    ],
                }
            ],
        }
    }

    #[test]
    fn main_template() {
        let mut data    = BTreeMap::new();
        let mut codegen = CodeGenerator::new().register_amqp_helpers();
        data.insert("protocol".to_string(), specs());
        assert!(codegen.register_template_string("main", TEMPLATE.to_string()).is_ok());
        assert_eq!(codegen.render("main", &data).unwrap(), r#"
AMQP - 0.9.1
Copyright 1
Copyright 2
port 5672
domain1: LongString
constant1 = 128
42 - class1
property1: LongString
64 - method1
synchronous: true
argument1(domain1): LongString

flag1: true
flag2: false
"#);
    }
}
<|endoftext|>


<commit_before>use std::marker::PhantomData;

use primitives::{ConsumedResult, Error, Info, ParseError, Parser, RangeStream};
use primitives::FastResult::*;

pub struct Range<I>(I::Range) where I: RangeStream;

impl<I> Parser for Range<I>
    where I: RangeStream,
          I::Range: PartialEq + ::primitives::Range
{
    type Input = I;
    type Output = I::Range;

    #[inline]
    fn parse_lazy(&mut self, mut input: Self::Input) -> ConsumedResult<Self::Output, Self::Input> {
        use primitives::Range;
        let position = input.position();
        match input.uncons_range(self.0.len()) {
            Ok(other) => {
                if other == self.0 {
                    ConsumedOk((other, input))
                } else {
                    EmptyErr(ParseError::empty(position))
                }
            }
            Err(err) => EmptyErr(ParseError::new(position, err)),
        }
    }
    fn add_error(&mut self, errors: &mut ParseError<Self::Input>) {
        // TODO Add unexpected message?
        errors.add_error(Error::Expected(Info::Range(self.0.clone())));
    }
}

/// ```
/// # extern crate combine;
/// # use combine::range::range;
/// # use combine::*;
/// # fn main() {
/// let mut parser = range("hello");
/// let result = parser.parse("hello world");
/// assert_eq!(result, Ok(("hello", " world")));
/// let result = parser.parse("hel world");
/// assert!(result.is_err());
/// # }
/// ```
#[inline(always)]
pub fn range<I>(i: I::Range) -> Range<I>
    where I: RangeStream,
          I::Range: PartialEq + ::primitives::Range
{
    Range(i)
}

pub struct Take<I>(usize, PhantomData<fn(I) -> I>);
impl<I> Parser for Take<I>
    where I: RangeStream,
          I::Range: ::primitives::Range
{
    type Input = I;
    type Output = I::Range;

    #[inline]
    fn parse_lazy(&mut self, mut input: Self::Input) -> ConsumedResult<Self::Output, Self::Input> {
        let position = input.position();
        match input.uncons_range(self.0) {
            Ok(x) => ConsumedOk((x, input)),
            Err(err) => EmptyErr(ParseError::new(position, err)),
        }
    }
}

/// ```
/// # extern crate combine;
/// # use combine::range::take;
/// # use combine::*;
/// # fn main() {
/// let mut parser = take(1);
/// let result = parser.parse("1");
/// assert_eq!(result, Ok(("1", "")));
/// let mut parser = take(4);
/// let result = parser.parse("123abc");
/// assert_eq!(result, Ok(("123a", "bc")));
/// let result = parser.parse("abc");
/// assert!(result.is_err());
/// # }
/// ```
#[inline(always)]
pub fn take<I>(n: usize) -> Take<I>
    where I: RangeStream,
          I::Range: ::primitives::Range
{
    Take(n, PhantomData)
}

pub struct TakeWhile<I, F>(F, PhantomData<fn(I) -> I>);
impl<I, F> Parser for TakeWhile<I, F>
    where I: RangeStream,
          I::Range: ::primitives::Range,
          F: FnMut(I::Item) -> bool
{
    type Input = I;
    type Output = I::Range;

    #[inline]
    fn parse_lazy(&mut self, input: Self::Input) -> ConsumedResult<Self::Output, Self::Input> {
        ::primitives::uncons_while(input, &mut self.0)
    }
}

/// ```
/// # extern crate combine;
/// # use combine::range::take_while;
/// # use combine::*;
/// # fn main() {
/// let mut parser = take_while(|c: char| c.is_digit(10));
/// let result = parser.parse("123abc");
/// assert_eq!(result, Ok(("123", "abc")));
/// let result = parser.parse("abc");
/// assert_eq!(result, Ok(("", "abc")));
/// # }
/// ```
#[inline(always)]
pub fn take_while<I, F>(f: F) -> TakeWhile<I, F>
    where I: RangeStream,
          F: FnMut(I::Item) -> bool
{
    TakeWhile(f, PhantomData)
}

pub struct TakeWhile1<I, F>(F, PhantomData<fn(I) -> I>);
impl<I, F> Parser for TakeWhile1<I, F>
    where I: RangeStream,
          I::Range: ::primitives::Range,
          F: FnMut(I::Item) -> bool
{
    type Input = I;
    type Output = I::Range;

    #[inline]
    fn parse_lazy(&mut self, input: Self::Input) -> ConsumedResult<Self::Output, Self::Input> {
        match ::primitives::uncons_while(input, &mut self.0) {
            ConsumedOk((v, input)) => ConsumedOk((v, input)),
            EmptyOk((_, input)) => {
                let position = input.position();
                EmptyErr(ParseError::empty(position))
            }
            EmptyErr(err) => EmptyErr(err),
            ConsumedErr(err) => ConsumedErr(err),
        }
    }
}

/// ```
/// # extern crate combine;
/// # use combine::range::take_while1;
/// # use combine::*;
/// # fn main() {
/// let mut parser = take_while1(|c: char| c.is_digit(10));
/// let result = parser.parse("123abc");
/// assert_eq!(result, Ok(("123", "abc")));
/// let result = parser.parse("abc");
/// assert!(result.is_err());
/// # }
/// ```
#[inline(always)]
pub fn take_while1<I, F>(f: F) -> TakeWhile1<I, F>
    where I: RangeStream,
          I::Range: ::primitives::Range,
          F: FnMut(I::Item) -> bool
{
    TakeWhile1(f, PhantomData)
}

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

    #[test]
    fn take_while_test() {
        let result = take_while(|c: char| c.is_digit(10)).parse("123abc");
        assert_eq!(result, Ok(("123", "abc")));
    }

    #[test]
    fn range_string_no_char_boundary_error() {
        let mut parser = range("hello");
        let result = parser.parse("hell\u{00EE} world");
        assert!(result.is_err());
    }
}
<commit_msg>Pre: Add test for take_while1.<commit_after>use std::marker::PhantomData;

use primitives::{ConsumedResult, Error, Info, ParseError, Parser, RangeStream};
use primitives::FastResult::*;

pub struct Range<I>(I::Range) where I: RangeStream;

impl<I> Parser for Range<I>
    where I: RangeStream,
          I::Range: PartialEq + ::primitives::Range
{
    type Input = I;
    type Output = I::Range;

    #[inline]
    fn parse_lazy(&mut self, mut input: Self::Input) -> ConsumedResult<Self::Output, Self::Input> {
        use primitives::Range;
        let position = input.position();
        match input.uncons_range(self.0.len()) {
            Ok(other) => {
                if other == self.0 {
                    ConsumedOk((other, input))
                } else {
                    EmptyErr(ParseError::empty(position))
                }
            }
            Err(err) => EmptyErr(ParseError::new(position, err)),
        }
    }
    fn add_error(&mut self, errors: &mut ParseError<Self::Input>) {
        // TODO Add unexpected message?
        errors.add_error(Error::Expected(Info::Range(self.0.clone())));
    }
}

/// ```
/// # extern crate combine;
/// # use combine::range::range;
/// # use combine::*;
/// # fn main() {
/// let mut parser = range("hello");
/// let result = parser.parse("hello world");
/// assert_eq!(result, Ok(("hello", " world")));
/// let result = parser.parse("hel world");
/// assert!(result.is_err());
/// # }
/// ```
#[inline(always)]
pub fn range<I>(i: I::Range) -> Range<I>
    where I: RangeStream,
          I::Range: PartialEq + ::primitives::Range
{
    Range(i)
}

pub struct Take<I>(usize, PhantomData<fn(I) -> I>);
impl<I> Parser for Take<I>
    where I: RangeStream,
          I::Range: ::primitives::Range
{
    type Input = I;
    type Output = I::Range;

    #[inline]
    fn parse_lazy(&mut self, mut input: Self::Input) -> ConsumedResult<Self::Output, Self::Input> {
        let position = input.position();
        match input.uncons_range(self.0) {
            Ok(x) => ConsumedOk((x, input)),
            Err(err) => EmptyErr(ParseError::new(position, err)),
        }
    }
}

/// ```
/// # extern crate combine;
/// # use combine::range::take;
/// # use combine::*;
/// # fn main() {
/// let mut parser = take(1);
/// let result = parser.parse("1");
/// assert_eq!(result, Ok(("1", "")));
/// let mut parser = take(4);
/// let result = parser.parse("123abc");
/// assert_eq!(result, Ok(("123a", "bc")));
/// let result = parser.parse("abc");
/// assert!(result.is_err());
/// # }
/// ```
#[inline(always)]
pub fn take<I>(n: usize) -> Take<I>
    where I: RangeStream,
          I::Range: ::primitives::Range
{
    Take(n, PhantomData)
}

pub struct TakeWhile<I, F>(F, PhantomData<fn(I) -> I>);
impl<I, F> Parser for TakeWhile<I, F>
    where I: RangeStream,
          I::Range: ::primitives::Range,
          F: FnMut(I::Item) -> bool
{
    type Input = I;
    type Output = I::Range;

    #[inline]
    fn parse_lazy(&mut self, input: Self::Input) -> ConsumedResult<Self::Output, Self::Input> {
        ::primitives::uncons_while(input, &mut self.0)
    }
}

/// ```
/// # extern crate combine;
/// # use combine::range::take_while;
/// # use combine::*;
/// # fn main() {
/// let mut parser = take_while(|c: char| c.is_digit(10));
/// let result = parser.parse("123abc");
/// assert_eq!(result, Ok(("123", "abc")));
/// let result = parser.parse("abc");
/// assert_eq!(result, Ok(("", "abc")));
/// # }
/// ```
#[inline(always)]
pub fn take_while<I, F>(f: F) -> TakeWhile<I, F>
    where I: RangeStream,
          F: FnMut(I::Item) -> bool
{
    TakeWhile(f, PhantomData)
}

pub struct TakeWhile1<I, F>(F, PhantomData<fn(I) -> I>);
impl<I, F> Parser for TakeWhile1<I, F>
    where I: RangeStream,
          I::Range: ::primitives::Range,
          F: FnMut(I::Item) -> bool
{
    type Input = I;
    type Output = I::Range;

    #[inline]
    fn parse_lazy(&mut self, input: Self::Input) -> ConsumedResult<Self::Output, Self::Input> {
        match ::primitives::uncons_while(input, &mut self.0) {
            ConsumedOk((v, input)) => ConsumedOk((v, input)),
            EmptyOk((_, input)) => {
                let position = input.position();
                EmptyErr(ParseError::empty(position))
            }
            EmptyErr(err) => EmptyErr(err),
            ConsumedErr(err) => ConsumedErr(err),
        }
    }
}

/// ```
/// # extern crate combine;
/// # use combine::range::take_while1;
/// # use combine::*;
/// # fn main() {
/// let mut parser = take_while1(|c: char| c.is_digit(10));
/// let result = parser.parse("123abc");
/// assert_eq!(result, Ok(("123", "abc")));
/// let result = parser.parse("abc");
/// assert!(result.is_err());
/// # }
/// ```
#[inline(always)]
pub fn take_while1<I, F>(f: F) -> TakeWhile1<I, F>
    where I: RangeStream,
          I::Range: ::primitives::Range,
          F: FnMut(I::Item) -> bool
{
    TakeWhile1(f, PhantomData)
}

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

    #[test]
    fn take_while_test() {
        let result = take_while(|c: char| c.is_digit(10)).parse("123abc");
        assert_eq!(result, Ok(("123", "abc")));
        let result = take_while(|c: char| c.is_digit(10)).parse("abc");
        assert_eq!(result, Ok(("", "abc")));
    }

    #[test]
    fn take_while1_test() {
        let result = take_while1(|c: char| c.is_digit(10)).parse("123abc");
        assert_eq!(result, Ok(("123", "abc")));
        let result = take_while1(|c: char| c.is_digit(10)).parse("abc");
        assert!(result.is_err());
    }

    #[test]
    fn range_string_no_char_boundary_error() {
        let mut parser = range("hello");
        let result = parser.parse("hell\u{00EE} world");
        assert!(result.is_err());
    }
}
<|endoftext|>


<commit_before>// Copyright 2014 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.

//! C definitions used by libnative that don't belong in liblibc

#![allow(dead_code)]

pub use self::select::fd_set;
pub use self::signal::{sigaction, siginfo, sigset_t};
pub use self::signal::{SA_ONSTACK, SA_RESTART, SA_RESETHAND, SA_NOCLDSTOP};
pub use self::signal::{SA_NODEFER, SA_NOCLDWAIT, SA_SIGINFO, SIGCHLD};

use libc;

#[cfg(any(target_os = "macos",
          target_os = "ios",
          target_os = "freebsd",
          target_os = "dragonfly"))]
pub static FIONBIO: libc::c_ulong = 0x8004667e;
#[cfg(any(all(target_os = "linux",
              any(target_arch = "x86",
                  target_arch = "x86_64",
                  target_arch = "arm")),
          target_os = "android"))]
pub static FIONBIO: libc::c_ulong = 0x5421;
#[cfg(all(target_os = "linux",
          any(target_arch = "mips", target_arch = "mipsel")))]
pub static FIONBIO: libc::c_ulong = 0x667e;

#[cfg(any(target_os = "macos",
          target_os = "ios",
          target_os = "freebsd",
          target_os = "dragonfly"))]
pub static FIOCLEX: libc::c_ulong = 0x20006601;
#[cfg(any(all(target_os = "linux",
              any(target_arch = "x86",
                  target_arch = "x86_64",
                  target_arch = "arm")),
          target_os = "android"))]
pub static FIOCLEX: libc::c_ulong = 0x5451;
#[cfg(all(target_os = "linux",
          any(target_arch = "mips", target_arch = "mipsel")))]
pub static FIOCLEX: libc::c_ulong = 0x6601;

#[cfg(any(target_os = "macos",
          target_os = "ios",
          target_os = "freebsd",
          target_os = "dragonfly"))]
pub static MSG_DONTWAIT: libc::c_int = 0x80;
#[cfg(any(target_os = "linux", target_os = "android"))]
pub static MSG_DONTWAIT: libc::c_int = 0x40;

pub static WNOHANG: libc::c_int = 1;

extern {
    pub fn gettimeofday(timeval: *mut libc::timeval,
                        tzp: *mut libc::c_void) -> libc::c_int;
    pub fn select(nfds: libc::c_int,
                  readfds: *mut fd_set,
                  writefds: *mut fd_set,
                  errorfds: *mut fd_set,
                  timeout: *mut libc::timeval) -> libc::c_int;
    pub fn getsockopt(sockfd: libc::c_int,
                      level: libc::c_int,
                      optname: libc::c_int,
                      optval: *mut libc::c_void,
                      optlen: *mut libc::socklen_t) -> libc::c_int;
    pub fn ioctl(fd: libc::c_int, req: libc::c_ulong, ...) -> libc::c_int;

    pub fn waitpid(pid: libc::pid_t, status: *mut libc::c_int,
                   options: libc::c_int) -> libc::pid_t;

    pub fn sigaction(signum: libc::c_int,
                     act: *const sigaction,
                     oldact: *mut sigaction) -> libc::c_int;

    pub fn sigaddset(set: *mut sigset_t, signum: libc::c_int) -> libc::c_int;
    pub fn sigdelset(set: *mut sigset_t, signum: libc::c_int) -> libc::c_int;
    pub fn sigemptyset(set: *mut sigset_t) -> libc::c_int;
}

#[cfg(any(target_os = "macos", target_os = "ios"))]
mod select {
    pub static FD_SETSIZE: uint = 1024;

    #[repr(C)]
    pub struct fd_set {
        fds_bits: [i32, ..(FD_SETSIZE / 32)]
    }

    pub fn fd_set(set: &mut fd_set, fd: i32) {
        set.fds_bits[(fd / 32) as uint] |= 1 << ((fd % 32) as uint);
    }
}

#[cfg(any(target_os = "android",
          target_os = "freebsd",
          target_os = "dragonfly",
          target_os = "linux"))]
mod select {
    use std::uint;
    use libc;

    pub static FD_SETSIZE: uint = 1024;

    #[repr(C)]
    pub struct fd_set {
        // FIXME: shouldn't this be a c_ulong?
        fds_bits: [libc::uintptr_t, ..(FD_SETSIZE / uint::BITS)]
    }

    pub fn fd_set(set: &mut fd_set, fd: i32) {
        let fd = fd as uint;
        set.fds_bits[fd / uint::BITS] |= 1 << (fd % uint::BITS);
    }
}

#[cfg(any(all(target_os = "linux",
              any(target_arch = "x86",
                  target_arch = "x86_64",
                  target_arch = "arm")),
          target_os = "android"))]
mod signal {
    use libc;

    pub static SA_NOCLDSTOP: libc::c_ulong = 0x00000001;
    pub static SA_NOCLDWAIT: libc::c_ulong = 0x00000002;
    pub static SA_NODEFER: libc::c_ulong = 0x40000000;
    pub static SA_ONSTACK: libc::c_ulong = 0x08000000;
    pub static SA_RESETHAND: libc::c_ulong = 0x80000000;
    pub static SA_RESTART: libc::c_ulong = 0x10000000;
    pub static SA_SIGINFO: libc::c_ulong = 0x00000004;
    pub static SIGCHLD: libc::c_int = 17;

    // This definition is not as accurate as it could be, {pid, uid, status} is
    // actually a giant union. Currently we're only interested in these fields,
    // however.
    #[repr(C)]
    pub struct siginfo {
        si_signo: libc::c_int,
        si_errno: libc::c_int,
        si_code: libc::c_int,
        pub pid: libc::pid_t,
        pub uid: libc::uid_t,
        pub status: libc::c_int,
    }

    #[repr(C)]
    pub struct sigaction {
        pub sa_handler: extern fn(libc::c_int),
        pub sa_mask: sigset_t,
        pub sa_flags: libc::c_ulong,
        sa_restorer: *mut libc::c_void,
    }

    #[repr(C)]
    #[cfg(target_word_size = "32")]
    pub struct sigset_t {
        __val: [libc::c_ulong, ..32],
    }

    #[repr(C)]
    #[cfg(target_word_size = "64")]
    pub struct sigset_t {
        __val: [libc::c_ulong, ..16],
    }
}

#[cfg(all(target_os = "linux",
          any(target_arch = "mips", target_arch = "mipsel")))]
mod signal {
    use libc;

    pub static SA_NOCLDSTOP: libc::c_ulong = 0x00000001;
    pub static SA_NOCLDWAIT: libc::c_ulong = 0x00010000;
    pub static SA_NODEFER: libc::c_ulong = 0x40000000;
    pub static SA_ONSTACK: libc::c_ulong = 0x08000000;
    pub static SA_RESETHAND: libc::c_ulong = 0x80000000;
    pub static SA_RESTART: libc::c_ulong = 0x10000000;
    pub static SA_SIGINFO: libc::c_ulong = 0x00000008;
    pub static SIGCHLD: libc::c_int = 18;

    // This definition is not as accurate as it could be, {pid, uid, status} is
    // actually a giant union. Currently we're only interested in these fields,
    // however.
    #[repr(C)]
    pub struct siginfo {
        si_signo: libc::c_int,
        si_code: libc::c_int,
        si_errno: libc::c_int,
        pub pid: libc::pid_t,
        pub uid: libc::uid_t,
        pub status: libc::c_int,
    }

    #[repr(C)]
    pub struct sigaction {
        pub sa_flags: libc::c_uint,
        pub sa_handler: extern fn(libc::c_int),
        pub sa_mask: sigset_t,
        sa_restorer: *mut libc::c_void,
        sa_resv: [libc::c_int, ..1],
    }

    #[repr(C)]
    pub struct sigset_t {
        __val: [libc::c_ulong, ..32],
    }
}

#[cfg(any(target_os = "macos",
          target_os = "ios",
          target_os = "freebsd",
          target_os = "dragonfly"))]
mod signal {
    use libc;

    pub static SA_ONSTACK: libc::c_int = 0x0001;
    pub static SA_RESTART: libc::c_int = 0x0002;
    pub static SA_RESETHAND: libc::c_int = 0x0004;
    pub static SA_NOCLDSTOP: libc::c_int = 0x0008;
    pub static SA_NODEFER: libc::c_int = 0x0010;
    pub static SA_NOCLDWAIT: libc::c_int = 0x0020;
    pub static SA_SIGINFO: libc::c_int = 0x0040;
    pub static SIGCHLD: libc::c_int = 20;

    #[cfg(target_os = "macos")]
    #[cfg(target_os = "ios")]
    pub type sigset_t = u32;
    #[cfg(target_os = "freebsd")]
    #[cfg(target_os = "dragonfly")]
    #[repr(C)]
    pub struct sigset_t {
        bits: [u32, ..4],
    }

    // This structure has more fields, but we're not all that interested in
    // them.
    #[repr(C)]
    pub struct siginfo {
        pub si_signo: libc::c_int,
        pub si_errno: libc::c_int,
        pub si_code: libc::c_int,
        pub pid: libc::pid_t,
        pub uid: libc::uid_t,
        pub status: libc::c_int,
    }

    #[cfg(target_os = "macos")]
    #[cfg(target_os = "ios")]
    #[repr(C)]
    pub struct sigaction {
        pub sa_handler: extern fn(libc::c_int),
        sa_tramp: *mut libc::c_void,
        pub sa_mask: sigset_t,
        pub sa_flags: libc::c_int,
    }

    #[cfg(target_os = "freebsd")]
    #[cfg(target_os = "dragonfly")]
    #[repr(C)]
    pub struct sigaction {
        pub sa_handler: extern fn(libc::c_int),
        pub sa_flags: libc::c_int,
        pub sa_mask: sigset_t,
    }
}
<commit_msg>Fix cfg syntax warnings in libnative<commit_after>// Copyright 2014 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.

//! C definitions used by libnative that don't belong in liblibc

#![allow(dead_code)]

pub use self::select::fd_set;
pub use self::signal::{sigaction, siginfo, sigset_t};
pub use self::signal::{SA_ONSTACK, SA_RESTART, SA_RESETHAND, SA_NOCLDSTOP};
pub use self::signal::{SA_NODEFER, SA_NOCLDWAIT, SA_SIGINFO, SIGCHLD};

use libc;

#[cfg(any(target_os = "macos",
          target_os = "ios",
          target_os = "freebsd",
          target_os = "dragonfly"))]
pub static FIONBIO: libc::c_ulong = 0x8004667e;
#[cfg(any(all(target_os = "linux",
              any(target_arch = "x86",
                  target_arch = "x86_64",
                  target_arch = "arm")),
          target_os = "android"))]
pub static FIONBIO: libc::c_ulong = 0x5421;
#[cfg(all(target_os = "linux",
          any(target_arch = "mips", target_arch = "mipsel")))]
pub static FIONBIO: libc::c_ulong = 0x667e;

#[cfg(any(target_os = "macos",
          target_os = "ios",
          target_os = "freebsd",
          target_os = "dragonfly"))]
pub static FIOCLEX: libc::c_ulong = 0x20006601;
#[cfg(any(all(target_os = "linux",
              any(target_arch = "x86",
                  target_arch = "x86_64",
                  target_arch = "arm")),
          target_os = "android"))]
pub static FIOCLEX: libc::c_ulong = 0x5451;
#[cfg(all(target_os = "linux",
          any(target_arch = "mips", target_arch = "mipsel")))]
pub static FIOCLEX: libc::c_ulong = 0x6601;

#[cfg(any(target_os = "macos",
          target_os = "ios",
          target_os = "freebsd",
          target_os = "dragonfly"))]
pub static MSG_DONTWAIT: libc::c_int = 0x80;
#[cfg(any(target_os = "linux", target_os = "android"))]
pub static MSG_DONTWAIT: libc::c_int = 0x40;

pub static WNOHANG: libc::c_int = 1;

extern {
    pub fn gettimeofday(timeval: *mut libc::timeval,
                        tzp: *mut libc::c_void) -> libc::c_int;
    pub fn select(nfds: libc::c_int,
                  readfds: *mut fd_set,
                  writefds: *mut fd_set,
                  errorfds: *mut fd_set,
                  timeout: *mut libc::timeval) -> libc::c_int;
    pub fn getsockopt(sockfd: libc::c_int,
                      level: libc::c_int,
                      optname: libc::c_int,
                      optval: *mut libc::c_void,
                      optlen: *mut libc::socklen_t) -> libc::c_int;
    pub fn ioctl(fd: libc::c_int, req: libc::c_ulong, ...) -> libc::c_int;

    pub fn waitpid(pid: libc::pid_t, status: *mut libc::c_int,
                   options: libc::c_int) -> libc::pid_t;

    pub fn sigaction(signum: libc::c_int,
                     act: *const sigaction,
                     oldact: *mut sigaction) -> libc::c_int;

    pub fn sigaddset(set: *mut sigset_t, signum: libc::c_int) -> libc::c_int;
    pub fn sigdelset(set: *mut sigset_t, signum: libc::c_int) -> libc::c_int;
    pub fn sigemptyset(set: *mut sigset_t) -> libc::c_int;
}

#[cfg(any(target_os = "macos", target_os = "ios"))]
mod select {
    pub static FD_SETSIZE: uint = 1024;

    #[repr(C)]
    pub struct fd_set {
        fds_bits: [i32, ..(FD_SETSIZE / 32)]
    }

    pub fn fd_set(set: &mut fd_set, fd: i32) {
        set.fds_bits[(fd / 32) as uint] |= 1 << ((fd % 32) as uint);
    }
}

#[cfg(any(target_os = "android",
          target_os = "freebsd",
          target_os = "dragonfly",
          target_os = "linux"))]
mod select {
    use std::uint;
    use libc;

    pub static FD_SETSIZE: uint = 1024;

    #[repr(C)]
    pub struct fd_set {
        // FIXME: shouldn't this be a c_ulong?
        fds_bits: [libc::uintptr_t, ..(FD_SETSIZE / uint::BITS)]
    }

    pub fn fd_set(set: &mut fd_set, fd: i32) {
        let fd = fd as uint;
        set.fds_bits[fd / uint::BITS] |= 1 << (fd % uint::BITS);
    }
}

#[cfg(any(all(target_os = "linux",
              any(target_arch = "x86",
                  target_arch = "x86_64",
                  target_arch = "arm")),
          target_os = "android"))]
mod signal {
    use libc;

    pub static SA_NOCLDSTOP: libc::c_ulong = 0x00000001;
    pub static SA_NOCLDWAIT: libc::c_ulong = 0x00000002;
    pub static SA_NODEFER: libc::c_ulong = 0x40000000;
    pub static SA_ONSTACK: libc::c_ulong = 0x08000000;
    pub static SA_RESETHAND: libc::c_ulong = 0x80000000;
    pub static SA_RESTART: libc::c_ulong = 0x10000000;
    pub static SA_SIGINFO: libc::c_ulong = 0x00000004;
    pub static SIGCHLD: libc::c_int = 17;

    // This definition is not as accurate as it could be, {pid, uid, status} is
    // actually a giant union. Currently we're only interested in these fields,
    // however.
    #[repr(C)]
    pub struct siginfo {
        si_signo: libc::c_int,
        si_errno: libc::c_int,
        si_code: libc::c_int,
        pub pid: libc::pid_t,
        pub uid: libc::uid_t,
        pub status: libc::c_int,
    }

    #[repr(C)]
    pub struct sigaction {
        pub sa_handler: extern fn(libc::c_int),
        pub sa_mask: sigset_t,
        pub sa_flags: libc::c_ulong,
        sa_restorer: *mut libc::c_void,
    }

    #[repr(C)]
    #[cfg(target_word_size = "32")]
    pub struct sigset_t {
        __val: [libc::c_ulong, ..32],
    }

    #[repr(C)]
    #[cfg(target_word_size = "64")]
    pub struct sigset_t {
        __val: [libc::c_ulong, ..16],
    }
}

#[cfg(all(target_os = "linux",
          any(target_arch = "mips", target_arch = "mipsel")))]
mod signal {
    use libc;

    pub static SA_NOCLDSTOP: libc::c_ulong = 0x00000001;
    pub static SA_NOCLDWAIT: libc::c_ulong = 0x00010000;
    pub static SA_NODEFER: libc::c_ulong = 0x40000000;
    pub static SA_ONSTACK: libc::c_ulong = 0x08000000;
    pub static SA_RESETHAND: libc::c_ulong = 0x80000000;
    pub static SA_RESTART: libc::c_ulong = 0x10000000;
    pub static SA_SIGINFO: libc::c_ulong = 0x00000008;
    pub static SIGCHLD: libc::c_int = 18;

    // This definition is not as accurate as it could be, {pid, uid, status} is
    // actually a giant union. Currently we're only interested in these fields,
    // however.
    #[repr(C)]
    pub struct siginfo {
        si_signo: libc::c_int,
        si_code: libc::c_int,
        si_errno: libc::c_int,
        pub pid: libc::pid_t,
        pub uid: libc::uid_t,
        pub status: libc::c_int,
    }

    #[repr(C)]
    pub struct sigaction {
        pub sa_flags: libc::c_uint,
        pub sa_handler: extern fn(libc::c_int),
        pub sa_mask: sigset_t,
        sa_restorer: *mut libc::c_void,
        sa_resv: [libc::c_int, ..1],
    }

    #[repr(C)]
    pub struct sigset_t {
        __val: [libc::c_ulong, ..32],
    }
}

#[cfg(any(target_os = "macos",
          target_os = "ios",
          target_os = "freebsd",
          target_os = "dragonfly"))]
mod signal {
    use libc;

    pub static SA_ONSTACK: libc::c_int = 0x0001;
    pub static SA_RESTART: libc::c_int = 0x0002;
    pub static SA_RESETHAND: libc::c_int = 0x0004;
    pub static SA_NOCLDSTOP: libc::c_int = 0x0008;
    pub static SA_NODEFER: libc::c_int = 0x0010;
    pub static SA_NOCLDWAIT: libc::c_int = 0x0020;
    pub static SA_SIGINFO: libc::c_int = 0x0040;
    pub static SIGCHLD: libc::c_int = 20;

    #[cfg(any(target_os = "macos", target_os = "ios"))]
    pub type sigset_t = u32;
    #[cfg(any(target_os = "freebsd", target_os = "dragonfly"))]
    #[repr(C)]
    pub struct sigset_t {
        bits: [u32, ..4],
    }

    // This structure has more fields, but we're not all that interested in
    // them.
    #[repr(C)]
    pub struct siginfo {
        pub si_signo: libc::c_int,
        pub si_errno: libc::c_int,
        pub si_code: libc::c_int,
        pub pid: libc::pid_t,
        pub uid: libc::uid_t,
        pub status: libc::c_int,
    }

    #[cfg(any(target_os = "macos", target_os = "ios"))]
    #[repr(C)]
    pub struct sigaction {
        pub sa_handler: extern fn(libc::c_int),
        sa_tramp: *mut libc::c_void,
        pub sa_mask: sigset_t,
        pub sa_flags: libc::c_int,
    }

    #[cfg(any(target_os = "freebsd", target_os = "dragonfly"))]
    #[repr(C)]
    pub struct sigaction {
        pub sa_handler: extern fn(libc::c_int),
        pub sa_flags: libc::c_int,
        pub sa_mask: sigset_t,
    }
}
<|endoftext|>


<commit_before>use std::io::{self, Read, BufRead, Write};

pub struct Converter { output_state: State, blank_line_count: usize }
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
enum State { MarkdownFirstLine, MarkdownLines, Rust, }
impl Converter {
    pub fn new() -> Converter {
        Converter { output_state: State::MarkdownFirstLine,
                    blank_line_count: 0 }
    }
}

#[derive(Debug)]
enum Effect<'a> {
    BlankLn,
    WriteLn(&'a str),
    StartCodeBlock,
    FinisCodeBlock,
    BlankLitComment,
}

impl Converter {
    pub fn convert<R:io::Read, W:io::Write>(&mut self, r:R, mut w:W) -> io::Result<()> {
        let source = io::BufReader::new(r);
        for line in source.lines() {
            let line = try!(line);
            try!(self.handle(&line, &mut w));
        }
        self.finalize(&mut w)
    }

    pub fn finalize(&mut self, w: &mut Write) -> io::Result<()> {
        match self.output_state {
            State::Rust =>
                self.effect(Effect::FinisCodeBlock, w),
            State::MarkdownFirstLine |
            State::MarkdownLines =>
                Ok(())
        }
    }

    pub fn handle(&mut self, line: &str, w: &mut Write) -> io::Result<()> {
        let line_right = line.trim_left();
        if line_right.len() == 0 {
            self.blank_line(w)
        } else if line_right.starts_with("//@ ") {
            let line = &line_right[4..];
            match self.output_state {
                State::Rust =>
                    try!(self.transition(w, State::MarkdownFirstLine)),
                State::MarkdownFirstLine =>
                    try!(self.transition(w, State::MarkdownLines)),
                State::MarkdownLines =>
                    {}
            }
            if line.trim().len() == 0 {
                self.blank_line(w)
            } else {
                self.nonblank_line(line, w)
            }
        } else if line_right.starts_with("//@") {
            let line = &line_right[3..];
            match self.output_state {
                State::Rust =>
                    try!(self.transition(w, State::MarkdownFirstLine)),
                State::MarkdownFirstLine =>
                    try!(self.transition(w, State::MarkdownLines)),
                State::MarkdownLines =>
                {}
            }
            if line.trim().len() == 0 {
                self.blank_line(w)
            } else {
                self.nonblank_line(line, w)
            }
        } else {
            match self.output_state {
                State::MarkdownFirstLine |
                State::MarkdownLines =>
                    try!(self.transition(w, State::Rust)),
                _ => {}
            }
            self.nonblank_line(line, w)
        }
    }

    fn effect(&mut self, e: Effect, w: &mut Write) -> io::Result<()> {
        match e {
            Effect::BlankLn => writeln!(w, ""),
            Effect::WriteLn(line) => writeln!(w, "{}", line),
            Effect::StartCodeBlock => writeln!(w, "```rust"),
            Effect::FinisCodeBlock => writeln!(w, "```"),
            Effect::BlankLitComment => writeln!(w, "//@"),
        }
    }

    fn nonblank_line(&mut self, line: &str, w: &mut Write) -> io::Result<()> {
        for _ in 0..self.blank_line_count {
            try!(self.effect(Effect::BlankLn, w));
        }
        self.blank_line_count = 0;
        self.effect(Effect::WriteLn(line), w)
    }

    fn blank_line(&mut self, _w: &mut Write) -> io::Result<()> {
        self.blank_line_count += 1;
        Ok(())
    }

    fn finish_section(&mut self, _w: &mut Write) -> io::Result<()> {
        Ok(())
    }

    fn transition(&mut self, w: &mut Write, s: State) -> io::Result<()> {
        match s {
            State::MarkdownFirstLine => {
                assert_eq!(self.output_state, State::Rust);
                try!(self.effect(Effect::FinisCodeBlock, w));
                for _ in 0..self.blank_line_count {
                    try!(self.effect(Effect::BlankLn, w));
                }
                self.blank_line_count = 0;
            }
            State::MarkdownLines => {
                assert_eq!(self.output_state, State::MarkdownFirstLine);
                for _ in 0..self.blank_line_count {
                    try!(self.effect(Effect::BlankLitComment, w));
                }
                self.blank_line_count = 0;
            }
            State::Rust => {
                assert!(self.output_state != State::Rust);
                try!(self.finish_section(w));
                for _ in 0..self.blank_line_count {
                    try!(self.effect(Effect::BlankLn, w));
                }
                self.blank_line_count = 0;
                try!(self.effect(Effect::StartCodeBlock, w));
            }
        }
        self.output_state = s;
        Ok(())
    }
}
<commit_msg>Some commented-out instrumentation.<commit_after>use std::io::{self, Read, BufRead, Write};

#[derive(Debug)]
pub struct Converter { output_state: State, blank_line_count: usize }
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
enum State { MarkdownFirstLine, MarkdownLines, Rust, }
impl Converter {
    pub fn new() -> Converter {
        Converter { output_state: State::MarkdownFirstLine,
                    blank_line_count: 0 }
    }
}

#[derive(Debug)]
enum Effect<'a> {
    BlankLn,
    WriteLn(&'a str),
    StartCodeBlock,
    FinisCodeBlock,
    BlankLitComment,
}

#[derive(Debug)]
enum EffectContext<'a> {
    Finalize,
    NonblankLine(&'a str),
    Transition(State),
}

impl Converter {
    pub fn convert<R:io::Read, W:io::Write>(&mut self, r:R, mut w:W) -> io::Result<()> {
        let source = io::BufReader::new(r);
        for line in source.lines() {
            let line = try!(line);
            try!(self.handle(&line, &mut w));
        }
        self.finalize(&mut w)
    }

    pub fn finalize(&mut self, w: &mut Write) -> io::Result<()> {
        match self.output_state {
            State::Rust =>
                self.effect(EffectContext::Finalize, Effect::FinisCodeBlock, w),
            State::MarkdownFirstLine |
            State::MarkdownLines =>
                Ok(())
        }
    }

    pub fn handle(&mut self, line: &str, w: &mut Write) -> io::Result<()> {
        let line_right = line.trim_left();
        if line_right.len() == 0 {
            self.blank_line(w)
        } else if line_right.starts_with("//@ ") {
            let line = &line_right[4..];
            match self.output_state {
                State::Rust =>
                    try!(self.transition(w, State::MarkdownFirstLine)),
                State::MarkdownFirstLine =>
                    try!(self.transition(w, State::MarkdownLines)),
                State::MarkdownLines =>
                    {}
            }
            if line.trim().len() == 0 {
                self.blank_line(w)
            } else {
                self.nonblank_line(line, w)
            }
        } else if line_right.starts_with("//@") {
            let line = &line_right[3..];
            match self.output_state {
                State::Rust =>
                    try!(self.transition(w, State::MarkdownFirstLine)),
                State::MarkdownFirstLine =>
                    try!(self.transition(w, State::MarkdownLines)),
                State::MarkdownLines =>
                {}
            }
            if line.trim().len() == 0 {
                self.blank_line(w)
            } else {
                self.nonblank_line(line, w)
            }
        } else {
            match self.output_state {
                State::MarkdownFirstLine |
                State::MarkdownLines =>
                    try!(self.transition(w, State::Rust)),
                _ => {}
            }
            self.nonblank_line(line, w)
        }
    }

    fn effect(&mut self, _c: EffectContext, e: Effect, w: &mut Write) -> io::Result<()> {
        // println!("effect _c: {:?} e: {:?}", _c, e);
        match e {
            Effect::BlankLn => writeln!(w, ""),
            Effect::WriteLn(line) => writeln!(w, "{}", line),
            Effect::StartCodeBlock => writeln!(w, "```rust"),
            Effect::FinisCodeBlock => writeln!(w, "```"),
            Effect::BlankLitComment => writeln!(w, "//@"),
        }
    }

    fn nonblank_line(&mut self, line: &str, w: &mut Write) -> io::Result<()> {
        for _ in 0..self.blank_line_count {
            try!(self.effect(EffectContext::NonblankLine(line), Effect::BlankLn, w));
        }
        self.blank_line_count = 0;
        self.effect(EffectContext::NonblankLine(line), Effect::WriteLn(line), w)
    }

    fn blank_line(&mut self, _w: &mut Write) -> io::Result<()> {
        self.blank_line_count += 1;
        Ok(())
    }

    fn finish_section(&mut self, _w: &mut Write) -> io::Result<()> {
        Ok(())
    }

    fn transition(&mut self, w: &mut Write, s: State) -> io::Result<()> {
        match s {
            State::MarkdownFirstLine => {
                assert_eq!(self.output_state, State::Rust);
                try!(self.effect(EffectContext::Transition(s), Effect::FinisCodeBlock, w));
                for _ in 0..self.blank_line_count {
                    try!(self.effect(EffectContext::Transition(s), Effect::BlankLn, w));
                }
                self.blank_line_count = 0;
            }
            State::MarkdownLines => {
                assert_eq!(self.output_state, State::MarkdownFirstLine);
                for _ in 0..self.blank_line_count {
                    try!(self.effect(EffectContext::Transition(s), Effect::BlankLitComment, w));
                }
                self.blank_line_count = 0;
            }
            State::Rust => {
                assert!(self.output_state != State::Rust);
                try!(self.finish_section(w));
                for _ in 0..self.blank_line_count {
                    try!(self.effect(EffectContext::Transition(s), Effect::BlankLn, w));
                }
                self.blank_line_count = 0;
                try!(self.effect(EffectContext::Transition(s), Effect::StartCodeBlock, w));
            }
        }
        self.output_state = s;
        Ok(())
    }
}
<|endoftext|>


<commit_before>use ty;
use hir::map::definitions::FIRST_FREE_HIGH_DEF_INDEX;
use rustc_data_structures::indexed_vec::Idx;
use serialize;
use std::fmt;
use std::u32;

newtype_index! {
    pub struct CrateId {
        ENCODABLE = custom
    }
}

#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum CrateNum {
    /// Virtual crate for builtin macros
    // FIXME(jseyfried): this is also used for custom derives until proc-macro crates get
    // `CrateNum`s.
    BuiltinMacros,
    /// A CrateNum value that indicates that something is wrong.
    Invalid,
    /// A special CrateNum that we use for the tcx.rcache when decoding from
    /// the incr. comp. cache.
    ReservedForIncrCompCache,
    Index(CrateId),
}

impl ::std::fmt::Debug for CrateNum {
    fn fmt(&self, fmt: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
        match self {
            CrateNum::Index(id) => write!(fmt, "crate{}", id.private),
            CrateNum::Invalid => write!(fmt, "invalid crate"),
            CrateNum::BuiltinMacros => write!(fmt, "builtin macros crate"),
            CrateNum::ReservedForIncrCompCache => write!(fmt, "crate for decoding incr comp cache"),
        }
    }
}

/// Item definitions in the currently-compiled crate would have the CrateNum
/// LOCAL_CRATE in their DefId.
pub const LOCAL_CRATE: CrateNum = CrateNum::Index(CrateId::from_u32_const(0));

impl Idx for CrateNum {
    #[inline]
    fn new(value: usize) -> Self {
        CrateNum::Index(Idx::new(value))
    }

    #[inline]
    fn index(self) -> usize {
        match self {
            CrateNum::Index(idx) => Idx::index(idx),
            _ => bug!("Tried to get crate index of {:?}", self),
        }
    }
}

impl CrateNum {
    pub fn new(x: usize) -> CrateNum {
        CrateNum::from_usize(x)
    }

    pub fn from_usize(x: usize) -> CrateNum {
        CrateNum::Index(CrateId::from_usize(x))
    }

    pub fn from_u32(x: u32) -> CrateNum {
        CrateNum::Index(CrateId::from_u32(x))
    }

    pub fn as_usize(self) -> usize {
        match self {
            CrateNum::Index(id) => id.as_usize(),
            _ => bug!("tried to get index of nonstandard crate {:?}", self),
        }
    }

    pub fn as_u32(self) -> u32 {
        match self {
            CrateNum::Index(id) => id.as_u32(),
            _ => bug!("tried to get index of nonstandard crate {:?}", self),
        }
    }

    pub fn as_def_id(&self) -> DefId { DefId { krate: *self, index: CRATE_DEF_INDEX } }
}

impl fmt::Display for CrateNum {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            CrateNum::Index(id) => fmt::Display::fmt(&id.private, f),
            CrateNum::Invalid => write!(f, "invalid crate"),
            CrateNum::BuiltinMacros => write!(f, "builtin macros crate"),
            CrateNum::ReservedForIncrCompCache => write!(f, "crate for decoding incr comp cache"),
        }
    }
}

impl serialize::UseSpecializedEncodable for CrateNum {}
impl serialize::UseSpecializedDecodable for CrateNum {}

/// A DefIndex is an index into the hir-map for a crate, identifying a
/// particular definition. It should really be considered an interned
/// shorthand for a particular DefPath.
///
/// At the moment we are allocating the numerical values of DefIndexes from two
/// address spaces: DefIndexAddressSpace::Low and DefIndexAddressSpace::High.
/// This allows us to allocate the DefIndexes of all item-likes
/// (Items, TraitItems, and ImplItems) into one of these spaces and
/// consequently use a simple array for lookup tables keyed by DefIndex and
/// known to be densely populated. This is especially important for the HIR map.
///
/// Since the DefIndex is mostly treated as an opaque ID, you probably
/// don't have to care about these address spaces.

#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Copy)]
pub struct DefIndex(u32);

/// The crate root is always assigned index 0 by the AST Map code,
/// thanks to `NodeCollector::new`.
pub const CRATE_DEF_INDEX: DefIndex = DefIndex(0);

impl fmt::Debug for DefIndex {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f,
               "DefIndex({}:{})",
               self.address_space().index(),
               self.as_array_index())
    }
}

impl DefIndex {
    #[inline]
    pub fn address_space(&self) -> DefIndexAddressSpace {
        match self.0 & 1 {
            0 => DefIndexAddressSpace::Low,
            1 => DefIndexAddressSpace::High,
            _ => unreachable!()
        }
    }

    /// Converts this DefIndex into a zero-based array index.
    /// This index is the offset within the given DefIndexAddressSpace.
    #[inline]
    pub fn as_array_index(&self) -> usize {
        (self.0 >> 1) as usize
    }

    #[inline]
    pub fn from_array_index(i: usize, address_space: DefIndexAddressSpace) -> DefIndex {
        DefIndex::from_raw_u32(((i << 1) | (address_space as usize)) as u32)
    }

    // Proc macros from a proc-macro crate have a kind of virtual DefIndex. This
    // function maps the index of the macro within the crate (which is also the
    // index of the macro in the CrateMetadata::proc_macros array) to the
    // corresponding DefIndex.
    pub fn from_proc_macro_index(proc_macro_index: usize) -> DefIndex {
        // DefIndex for proc macros start from FIRST_FREE_HIGH_DEF_INDEX,
        // because the first FIRST_FREE_HIGH_DEF_INDEX indexes are reserved
        // for internal use.
        let def_index = DefIndex::from_array_index(
            proc_macro_index.checked_add(FIRST_FREE_HIGH_DEF_INDEX)
                .expect("integer overflow adding `proc_macro_index`"),
            DefIndexAddressSpace::High);
        assert!(def_index != CRATE_DEF_INDEX);
        def_index
    }

    // This function is the reverse of from_proc_macro_index() above.
    pub fn to_proc_macro_index(self: DefIndex) -> usize {
        assert_eq!(self.address_space(), DefIndexAddressSpace::High);

        self.as_array_index().checked_sub(FIRST_FREE_HIGH_DEF_INDEX)
            .unwrap_or_else(|| {
                bug!("using local index {:?} as proc-macro index", self)
            })
    }

    // Don't use this if you don't know about the DefIndex encoding.
    pub fn from_raw_u32(x: u32) -> DefIndex {
        DefIndex(x)
    }

    // Don't use this if you don't know about the DefIndex encoding.
    pub fn as_raw_u32(&self) -> u32 {
        self.0
    }
}

impl serialize::UseSpecializedEncodable for DefIndex {}
impl serialize::UseSpecializedDecodable for DefIndex {}

#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
pub enum DefIndexAddressSpace {
    Low = 0,
    High = 1,
}

impl DefIndexAddressSpace {
    #[inline]
    pub fn index(&self) -> usize {
        *self as usize
    }
}

/// A `DefId` identifies a particular *definition*, by combining a crate
/// index and a def index.
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Copy)]
pub struct DefId {
    pub krate: CrateNum,
    pub index: DefIndex,
}

impl fmt::Debug for DefId {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "DefId({}/{}:{}",
               self.krate,
               self.index.address_space().index(),
               self.index.as_array_index())?;

        ty::tls::with_opt(|opt_tcx| {
            if let Some(tcx) = opt_tcx {
                write!(f, " ~ {}", tcx.def_path_debug_str(*self))?;
            }
            Ok(())
        })?;

        write!(f, ")")
    }
}

impl DefId {
    /// Make a local `DefId` with the given index.
    #[inline]
    pub fn local(index: DefIndex) -> DefId {
        DefId { krate: LOCAL_CRATE, index: index }
    }

    #[inline]
    pub fn is_local(self) -> bool {
        self.krate == LOCAL_CRATE
    }

    #[inline]
    pub fn to_local(self) -> LocalDefId {
        LocalDefId::from_def_id(self)
    }
}

impl serialize::UseSpecializedEncodable for DefId {}
impl serialize::UseSpecializedDecodable for DefId {}

/// A LocalDefId is equivalent to a DefId with `krate == LOCAL_CRATE`. Since
/// we encode this information in the type, we can ensure at compile time that
/// no DefIds from upstream crates get thrown into the mix. There are quite a
/// few cases where we know that only DefIds from the local crate are expected
/// and a DefId from a different crate would signify a bug somewhere. This
/// is when LocalDefId comes in handy.
#[derive(Clone, Copy, PartialEq, Eq, Hash)]
pub struct LocalDefId(DefIndex);

impl LocalDefId {
    #[inline]
    pub fn from_def_id(def_id: DefId) -> LocalDefId {
        assert!(def_id.is_local());
        LocalDefId(def_id.index)
    }

    #[inline]
    pub fn to_def_id(self) -> DefId {
        DefId {
            krate: LOCAL_CRATE,
            index: self.0
        }
    }
}

impl fmt::Debug for LocalDefId {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        self.to_def_id().fmt(f)
    }
}

impl serialize::UseSpecializedEncodable for LocalDefId {}
impl serialize::UseSpecializedDecodable for LocalDefId {}
<commit_msg>Remove `CrateNum::Invalid`.<commit_after>use ty;
use hir::map::definitions::FIRST_FREE_HIGH_DEF_INDEX;
use rustc_data_structures::indexed_vec::Idx;
use serialize;
use std::fmt;
use std::u32;

newtype_index! {
    pub struct CrateId {
        ENCODABLE = custom
    }
}

#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum CrateNum {
    /// Virtual crate for builtin macros
    // FIXME(jseyfried): this is also used for custom derives until proc-macro crates get
    // `CrateNum`s.
    BuiltinMacros,
    /// A special CrateNum that we use for the tcx.rcache when decoding from
    /// the incr. comp. cache.
    ReservedForIncrCompCache,
    Index(CrateId),
}

impl ::std::fmt::Debug for CrateNum {
    fn fmt(&self, fmt: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
        match self {
            CrateNum::Index(id) => write!(fmt, "crate{}", id.private),
            CrateNum::BuiltinMacros => write!(fmt, "builtin macros crate"),
            CrateNum::ReservedForIncrCompCache => write!(fmt, "crate for decoding incr comp cache"),
        }
    }
}

/// Item definitions in the currently-compiled crate would have the CrateNum
/// LOCAL_CRATE in their DefId.
pub const LOCAL_CRATE: CrateNum = CrateNum::Index(CrateId::from_u32_const(0));

impl Idx for CrateNum {
    #[inline]
    fn new(value: usize) -> Self {
        CrateNum::Index(Idx::new(value))
    }

    #[inline]
    fn index(self) -> usize {
        match self {
            CrateNum::Index(idx) => Idx::index(idx),
            _ => bug!("Tried to get crate index of {:?}", self),
        }
    }
}

impl CrateNum {
    pub fn new(x: usize) -> CrateNum {
        CrateNum::from_usize(x)
    }

    pub fn from_usize(x: usize) -> CrateNum {
        CrateNum::Index(CrateId::from_usize(x))
    }

    pub fn from_u32(x: u32) -> CrateNum {
        CrateNum::Index(CrateId::from_u32(x))
    }

    pub fn as_usize(self) -> usize {
        match self {
            CrateNum::Index(id) => id.as_usize(),
            _ => bug!("tried to get index of nonstandard crate {:?}", self),
        }
    }

    pub fn as_u32(self) -> u32 {
        match self {
            CrateNum::Index(id) => id.as_u32(),
            _ => bug!("tried to get index of nonstandard crate {:?}", self),
        }
    }

    pub fn as_def_id(&self) -> DefId { DefId { krate: *self, index: CRATE_DEF_INDEX } }
}

impl fmt::Display for CrateNum {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            CrateNum::Index(id) => fmt::Display::fmt(&id.private, f),
            CrateNum::BuiltinMacros => write!(f, "builtin macros crate"),
            CrateNum::ReservedForIncrCompCache => write!(f, "crate for decoding incr comp cache"),
        }
    }
}

impl serialize::UseSpecializedEncodable for CrateNum {}
impl serialize::UseSpecializedDecodable for CrateNum {}

/// A DefIndex is an index into the hir-map for a crate, identifying a
/// particular definition. It should really be considered an interned
/// shorthand for a particular DefPath.
///
/// At the moment we are allocating the numerical values of DefIndexes from two
/// address spaces: DefIndexAddressSpace::Low and DefIndexAddressSpace::High.
/// This allows us to allocate the DefIndexes of all item-likes
/// (Items, TraitItems, and ImplItems) into one of these spaces and
/// consequently use a simple array for lookup tables keyed by DefIndex and
/// known to be densely populated. This is especially important for the HIR map.
///
/// Since the DefIndex is mostly treated as an opaque ID, you probably
/// don't have to care about these address spaces.

#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Copy)]
pub struct DefIndex(u32);

/// The crate root is always assigned index 0 by the AST Map code,
/// thanks to `NodeCollector::new`.
pub const CRATE_DEF_INDEX: DefIndex = DefIndex(0);

impl fmt::Debug for DefIndex {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f,
               "DefIndex({}:{})",
               self.address_space().index(),
               self.as_array_index())
    }
}

impl DefIndex {
    #[inline]
    pub fn address_space(&self) -> DefIndexAddressSpace {
        match self.0 & 1 {
            0 => DefIndexAddressSpace::Low,
            1 => DefIndexAddressSpace::High,
            _ => unreachable!()
        }
    }

    /// Converts this DefIndex into a zero-based array index.
    /// This index is the offset within the given DefIndexAddressSpace.
    #[inline]
    pub fn as_array_index(&self) -> usize {
        (self.0 >> 1) as usize
    }

    #[inline]
    pub fn from_array_index(i: usize, address_space: DefIndexAddressSpace) -> DefIndex {
        DefIndex::from_raw_u32(((i << 1) | (address_space as usize)) as u32)
    }

    // Proc macros from a proc-macro crate have a kind of virtual DefIndex. This
    // function maps the index of the macro within the crate (which is also the
    // index of the macro in the CrateMetadata::proc_macros array) to the
    // corresponding DefIndex.
    pub fn from_proc_macro_index(proc_macro_index: usize) -> DefIndex {
        // DefIndex for proc macros start from FIRST_FREE_HIGH_DEF_INDEX,
        // because the first FIRST_FREE_HIGH_DEF_INDEX indexes are reserved
        // for internal use.
        let def_index = DefIndex::from_array_index(
            proc_macro_index.checked_add(FIRST_FREE_HIGH_DEF_INDEX)
                .expect("integer overflow adding `proc_macro_index`"),
            DefIndexAddressSpace::High);
        assert!(def_index != CRATE_DEF_INDEX);
        def_index
    }

    // This function is the reverse of from_proc_macro_index() above.
    pub fn to_proc_macro_index(self: DefIndex) -> usize {
        assert_eq!(self.address_space(), DefIndexAddressSpace::High);

        self.as_array_index().checked_sub(FIRST_FREE_HIGH_DEF_INDEX)
            .unwrap_or_else(|| {
                bug!("using local index {:?} as proc-macro index", self)
            })
    }

    // Don't use this if you don't know about the DefIndex encoding.
    pub fn from_raw_u32(x: u32) -> DefIndex {
        DefIndex(x)
    }

    // Don't use this if you don't know about the DefIndex encoding.
    pub fn as_raw_u32(&self) -> u32 {
        self.0
    }
}

impl serialize::UseSpecializedEncodable for DefIndex {}
impl serialize::UseSpecializedDecodable for DefIndex {}

#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
pub enum DefIndexAddressSpace {
    Low = 0,
    High = 1,
}

impl DefIndexAddressSpace {
    #[inline]
    pub fn index(&self) -> usize {
        *self as usize
    }
}

/// A `DefId` identifies a particular *definition*, by combining a crate
/// index and a def index.
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Copy)]
pub struct DefId {
    pub krate: CrateNum,
    pub index: DefIndex,
}

impl fmt::Debug for DefId {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "DefId({}/{}:{}",
               self.krate,
               self.index.address_space().index(),
               self.index.as_array_index())?;

        ty::tls::with_opt(|opt_tcx| {
            if let Some(tcx) = opt_tcx {
                write!(f, " ~ {}", tcx.def_path_debug_str(*self))?;
            }
            Ok(())
        })?;

        write!(f, ")")
    }
}

impl DefId {
    /// Make a local `DefId` with the given index.
    #[inline]
    pub fn local(index: DefIndex) -> DefId {
        DefId { krate: LOCAL_CRATE, index: index }
    }

    #[inline]
    pub fn is_local(self) -> bool {
        self.krate == LOCAL_CRATE
    }

    #[inline]
    pub fn to_local(self) -> LocalDefId {
        LocalDefId::from_def_id(self)
    }
}

impl serialize::UseSpecializedEncodable for DefId {}
impl serialize::UseSpecializedDecodable for DefId {}

/// A LocalDefId is equivalent to a DefId with `krate == LOCAL_CRATE`. Since
/// we encode this information in the type, we can ensure at compile time that
/// no DefIds from upstream crates get thrown into the mix. There are quite a
/// few cases where we know that only DefIds from the local crate are expected
/// and a DefId from a different crate would signify a bug somewhere. This
/// is when LocalDefId comes in handy.
#[derive(Clone, Copy, PartialEq, Eq, Hash)]
pub struct LocalDefId(DefIndex);

impl LocalDefId {
    #[inline]
    pub fn from_def_id(def_id: DefId) -> LocalDefId {
        assert!(def_id.is_local());
        LocalDefId(def_id.index)
    }

    #[inline]
    pub fn to_def_id(self) -> DefId {
        DefId {
            krate: LOCAL_CRATE,
            index: self.0
        }
    }
}

impl fmt::Debug for LocalDefId {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        self.to_def_id().fmt(f)
    }
}

impl serialize::UseSpecializedEncodable for LocalDefId {}
impl serialize::UseSpecializedDecodable for LocalDefId {}
<|endoftext|>