<commit_before>// Claxon -- A FLAC decoding library in Rust
// Copyright 2014 Ruud van Asseldonk
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// A copy of the License has been included in the root of the repository.

extern crate claxon;
extern crate hound;
extern crate walkdir;

use std::fs;
use std::io;
use std::path::Path;

fn run_metaflac_streaminfo<P: AsRef<Path>>(fname: P) -> String {
    use std::process::Command;

    // Run metaflac on the specified file and print all streaminfo data.
    let output = Command::new("metaflac")
        .arg("--show-min-blocksize")
        .arg("--show-max-blocksize")
        .arg("--show-min-framesize")
        .arg("--show-max-framesize")
        .arg("--show-sample-rate")
        .arg("--show-channels")
        .arg("--show-bps")
        .arg("--show-total-samples")
        .arg("--show-md5sum")
        .arg(fname.as_ref().to_str().expect("unsupported filename"))
        .output()
        .expect("failed to run metaflac");
    String::from_utf8(output.stdout).expect("metaflac wrote invalid UTF-8")
}

fn run_metaflac_vorbis_comment<P: AsRef<Path>>(fname: P) -> String {
    use std::process::Command;

    // Run metaflac on the specified file and print all Vorbis comment data.
    let output = Command::new("metaflac")
        .arg("--block-type=VORBIS_COMMENT")
        .arg("--list")
        .arg(fname.as_ref().to_str().expect("unsupported filename"))
        .output()
        .expect("failed to run metaflac");
    String::from_utf8(output.stdout).expect("metaflac wrote invalid UTF-8")
}

fn decode_file<P: AsRef<Path>>(fname: P) -> Vec<u8> {
    use std::process::Command;

    // Run the the reference flac decoder on the file.
    let output = Command::new("flac")
        .arg("--decode")
        .arg("--silent")
        .arg("--stdout")
        .arg(fname.as_ref().to_str().expect("unsupported filename"))
        .output()
        .expect("failed to run flac");

    assert!(output.status.success());
    output.stdout
}

fn print_hex(seq: &[u8]) -> String {
    let vec: Vec<String> = seq.iter().map(|x| format!("{:0>2x}", *x)).collect();
    vec.concat()
}

fn read_streaminfo<P: AsRef<Path>>(fname: P) -> String {
    // Use a buffered reader, this speeds up the test by 120%.
    let file = fs::File::open(fname).unwrap();
    let reader = io::BufReader::new(file);
    let stream = claxon::FlacReader::new(reader).unwrap();
    let streaminfo = stream.streaminfo();

    // Format the streaminfo in the same way that metaflac prints it.
    format!("{}\n{}\n{}\n{}\n{}\n{}\n{}\n{}\n{}\n",
            streaminfo.min_block_size,
            streaminfo.max_block_size,
            streaminfo.min_frame_size.unwrap_or(0),
            streaminfo.max_frame_size.unwrap_or(0),
            streaminfo.sample_rate,
            streaminfo.channels,
            streaminfo.bits_per_sample,
            streaminfo.samples.unwrap_or(0),
            print_hex(&streaminfo.md5sum)) // TODO implement LowerHex for &[u8] and submit a PR.
}

fn compare_metaflac_streaminfo<P: AsRef<Path>>(fname: P) {
    let metaflac = run_metaflac_streaminfo(&fname);
    let streaminfo = read_streaminfo(&fname);
    let mut mf_lines = metaflac.lines();
    let mut si_lines = streaminfo.lines();
    while let (Some(mf), Some(si)) = (mf_lines.next(), si_lines.next()) {
        if mf != si {
            println!("metaflac\n--------\n{}", metaflac);
            println!("streaminfo\n----------\n{}", streaminfo);
            panic!("metaflac disagrees on parsed streaminfo");
        }
    }
}

fn compare_metaflac_vorbis_comment<P: AsRef<Path>>(fname: P) {
    let metaflac = run_metaflac_vorbis_comment(&fname);

    // Use a buffered reader, this speeds up the test by 120%.
    let file = fs::File::open(fname).unwrap();
    let reader = io::BufReader::new(file);
    let stream = claxon::FlacReader::new(reader).unwrap();

    let mut mf_lines = metaflac.lines();

    // Search for the vendor string in the metaflac output.
    while let Some(line) = mf_lines.next() {
        let prefix = "  vendor string: ";
        if line.starts_with(prefix) {
            let mf_vendor_string = &line[prefix.len()..];
            assert_eq!(stream.vendor(), Some(mf_vendor_string));
            break
        }
    }
}

fn compare_decoded_stream<P: AsRef<Path>>(fname: P) {
    let wav = decode_file(&fname);
    let cursor = io::Cursor::new(wav);

    // Compare the reference decoded by the 'flac' program (stored as wav, which
    // we read with Hound) to how Claxon decodes it, sample by sample.
    let mut ref_wav_reader = hound::WavReader::new(cursor).unwrap();

    let try_file = fs::File::open(fname).unwrap();
    let try_buf_reader = io::BufReader::new(try_file);
    let mut try_flac_reader = claxon::FlacReader::new(try_buf_reader).unwrap();

    // The streaminfo test will ensure that things like bit depth and
    // sample rate match, only the actual samples are compared here.
    let mut ref_samples = ref_wav_reader.samples::<i32>();

    let samples = try_flac_reader.streaminfo().samples.unwrap();
    let n_channels = try_flac_reader.streaminfo().channels;
    let mut blocks = try_flac_reader.blocks();
    let mut sample = 0u64;
    let mut b = 0u64;
    let mut buffer = Vec::new();

    while sample < samples {
        let block = blocks.read_next_or_eof(buffer).unwrap().unwrap();
        {
            let mut channels: Vec<_> = (0..n_channels)
                                           .map(|i| block.channel(i).iter().cloned())
                                           .collect();
            for i in 0..block.duration() {
                for ch in 0..n_channels as usize {
                    let ref_sample = ref_samples.next().map(|r| r.ok().unwrap());
                    let try_sample = channels[ch].next();
                    if ref_sample != try_sample {
                        println!("disagreement at sample {} of block {} in channel {}: \
                                  reference is {} but decoded is {}",
                                 i,
                                 b,
                                 ch,
                                 ref_sample.unwrap(),
                                 try_sample.unwrap());
                        panic!("decoding differs from reference decoder");
                    }
                }
            }
            sample = sample + block.duration() as u64;
        }
        b = b + 1;
        buffer = block.into_buffer();
    }
}

// Hard-coded tests for the test samples added py populate.sh.
// This allows us to run these tests in parallel and follow progress without
// enabling --nocapture.

#[test]
fn verify_streaminfo_p0() {
    compare_metaflac_streaminfo("testsamples/p0.flac");
}

#[test]
fn verify_streaminfo_p1() {
    compare_metaflac_streaminfo("testsamples/p1.flac");
}

#[test]
fn verify_streaminfo_p2() {
    compare_metaflac_streaminfo("testsamples/p2.flac");
}

#[test]
fn verify_streaminfo_p3() {
    compare_metaflac_streaminfo("testsamples/p3.flac");
}

#[test]
fn verify_streaminfo_p4() {
    compare_metaflac_streaminfo("testsamples/p4.flac");
}

#[test]
fn verify_streaminfo_pop() {
    compare_metaflac_streaminfo("testsamples/pop.flac");
}

#[test]
fn verify_streaminfo_short() {
    compare_metaflac_streaminfo("testsamples/short.flac");
}

#[test]
fn verify_streaminfo_wasted_bits() {
    compare_metaflac_streaminfo("testsamples/wasted_bits.flac");
}

#[test]
fn verify_vorbis_comment_p0() {
    compare_metaflac_vorbis_comment("testsamples/p0.flac");
}

#[test]
fn verify_vorbis_comment_p1() {
    compare_metaflac_vorbis_comment("testsamples/p1.flac");
}

#[test]
fn verify_vorbis_comment_p2() {
    compare_metaflac_vorbis_comment("testsamples/p2.flac");
}

#[test]
fn verify_vorbis_comment_p3() {
    compare_metaflac_vorbis_comment("testsamples/p3.flac");
}

#[test]
fn verify_vorbis_comment_p4() {
    compare_metaflac_vorbis_comment("testsamples/p4.flac");
}

#[test]
fn verify_decoded_stream_p0() {
    compare_decoded_stream("testsamples/p0.flac");
}

#[test]
fn verify_decoded_stream_p1() {
    compare_decoded_stream("testsamples/p1.flac");
}

#[test]
fn verify_decoded_stream_p2() {
    compare_decoded_stream("testsamples/p2.flac");
}

#[test]
fn verify_decoded_stream_p3() {
    compare_decoded_stream("testsamples/p3.flac");
}

#[test]
fn verify_decoded_stream_p4() {
    compare_decoded_stream("testsamples/p4.flac");
}

#[test]
fn verify_decoded_stream_pop() {
    compare_decoded_stream("testsamples/pop.flac");
}

#[test]
fn verify_decoded_stream_short() {
    // The short sample has only 4 samples, even less than pop.flac.
    compare_decoded_stream("testsamples/short.flac");
}

#[test]
fn verify_decoded_stream_wasted_bits() {
    // This sample has subframes where the number of wasted bits is not 0.
    compare_decoded_stream("testsamples/wasted_bits.flac");
}

#[test]
fn verify_limits_on_vendor_string() {
    // This file claims to have a vendor string which would not fit in the
    // block.
    let file = fs::File::open("testsamples/large_vendor_string.flac").unwrap();
    match claxon::FlacReader::new(file) {
        Ok(..) => panic!("This file should fail to load"),
        Err(err) => {
            assert_eq!(err, claxon::Error::FormatError("vendor string too long"))
        }
    }
}

#[test]
fn verify_limits_on_vorbis_comment_block() {
    // This file claims to have a very large Vorbis comment block, which could
    // make the decoder go OOM.
    let file = fs::File::open("testsamples/large_vorbis_comment_block.flac").unwrap();
    match claxon::FlacReader::new(file) {
        Ok(..) => panic!("This file should fail to load"),
        Err(claxon::Error::Unsupported(..)) => { }
        Err(..) => panic!("Expected 'Unsupported' error."),
    }
}

#[test]
fn verify_extra_samples() {
    use std::ffi::OsStr;

    if !Path::new("testsamples/extra").exists() {
        return
    }

    let wd = walkdir::WalkDir::new("testsamples/extra")
        .follow_links(true)
        .into_iter()
        .filter_map(|e| e.ok());

    // Recursively enumerate all the flac files in the testsamples/extra
    // directory, and compare the streaminfo and stream itself for those.
    for entry in wd {
        let path = entry.path();
        if path.is_file() && path.extension() == Some(OsStr::new("flac")) {
            print!("    comparing {} ...", path.to_str()
                                               .expect("unsupported filename"));
            compare_metaflac_streaminfo(&path);
            compare_metaflac_vorbis_comment(&path);
            compare_decoded_stream(&path);
            println!(" ok");
        }
    }
}

#[test]
fn regression_test_fuzz_samples() {
    use std::ffi::OsStr;

    // Enumerate all the flac files in the testsamples/fuzz directory,
    // and ensure that they can be decoded without panic.
    let dir = fs::read_dir("testsamples/fuzz")
                 .ok().expect("failed to enumerate flac files");
    for path in dir {
        let path = path.ok().expect("failed to obtain path info").path();
        if path.is_file() && path.extension() == Some(OsStr::new("flac")) {
            print!("    regression testing {} ...", path.to_str()
                   .expect("unsupported filename"));

            if let Ok(mut reader) = claxon::FlacReader::open(&path) {
                let mut buffer = Vec::new();
                while let Ok(Some(block)) = reader.blocks().read_next_or_eof(buffer) {
                    buffer = block.into_buffer();
                }
            }
            println!(" ok");
        }
    }
}
<commit_msg>Verify tag reading against metaflac<commit_after>// Claxon -- A FLAC decoding library in Rust
// Copyright 2014 Ruud van Asseldonk
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// A copy of the License has been included in the root of the repository.

extern crate claxon;
extern crate hound;
extern crate walkdir;

use std::fs;
use std::io;
use std::path::Path;

fn run_metaflac_streaminfo<P: AsRef<Path>>(fname: P) -> String {
    use std::process::Command;

    // Run metaflac on the specified file and print all streaminfo data.
    let output = Command::new("metaflac")
        .arg("--show-min-blocksize")
        .arg("--show-max-blocksize")
        .arg("--show-min-framesize")
        .arg("--show-max-framesize")
        .arg("--show-sample-rate")
        .arg("--show-channels")
        .arg("--show-bps")
        .arg("--show-total-samples")
        .arg("--show-md5sum")
        .arg(fname.as_ref().to_str().expect("unsupported filename"))
        .output()
        .expect("failed to run metaflac");
    String::from_utf8(output.stdout).expect("metaflac wrote invalid UTF-8")
}

fn run_metaflac_vorbis_comment<P: AsRef<Path>>(fname: P) -> String {
    use std::process::Command;

    // Run metaflac on the specified file and print all Vorbis comment data.
    let output = Command::new("metaflac")
        .arg("--block-type=VORBIS_COMMENT")
        .arg("--list")
        .arg(fname.as_ref().to_str().expect("unsupported filename"))
        .output()
        .expect("failed to run metaflac");
    String::from_utf8(output.stdout).expect("metaflac wrote invalid UTF-8")
}

fn decode_file<P: AsRef<Path>>(fname: P) -> Vec<u8> {
    use std::process::Command;

    // Run the the reference flac decoder on the file.
    let output = Command::new("flac")
        .arg("--decode")
        .arg("--silent")
        .arg("--stdout")
        .arg(fname.as_ref().to_str().expect("unsupported filename"))
        .output()
        .expect("failed to run flac");

    assert!(output.status.success());
    output.stdout
}

fn print_hex(seq: &[u8]) -> String {
    let vec: Vec<String> = seq.iter().map(|x| format!("{:0>2x}", *x)).collect();
    vec.concat()
}

fn read_streaminfo<P: AsRef<Path>>(fname: P) -> String {
    // Use a buffered reader, this speeds up the test by 120%.
    let file = fs::File::open(fname).unwrap();
    let reader = io::BufReader::new(file);
    let stream = claxon::FlacReader::new(reader).unwrap();
    let streaminfo = stream.streaminfo();

    // Format the streaminfo in the same way that metaflac prints it.
    format!("{}\n{}\n{}\n{}\n{}\n{}\n{}\n{}\n{}\n",
            streaminfo.min_block_size,
            streaminfo.max_block_size,
            streaminfo.min_frame_size.unwrap_or(0),
            streaminfo.max_frame_size.unwrap_or(0),
            streaminfo.sample_rate,
            streaminfo.channels,
            streaminfo.bits_per_sample,
            streaminfo.samples.unwrap_or(0),
            print_hex(&streaminfo.md5sum)) // TODO implement LowerHex for &[u8] and submit a PR.
}

fn compare_metaflac_streaminfo<P: AsRef<Path>>(fname: P) {
    let metaflac = run_metaflac_streaminfo(&fname);
    let streaminfo = read_streaminfo(&fname);
    let mut mf_lines = metaflac.lines();
    let mut si_lines = streaminfo.lines();
    while let (Some(mf), Some(si)) = (mf_lines.next(), si_lines.next()) {
        if mf != si {
            println!("metaflac\n--------\n{}", metaflac);
            println!("streaminfo\n----------\n{}", streaminfo);
            panic!("metaflac disagrees on parsed streaminfo");
        }
    }
}

fn compare_metaflac_vorbis_comment<P: AsRef<Path>>(fname: P) {
    let metaflac = run_metaflac_vorbis_comment(&fname);

    // Use a buffered reader, this speeds up the test by 120%.
    let file = fs::File::open(fname).unwrap();
    let buf_reader = io::BufReader::new(file);
    let reader = claxon::FlacReader::new(buf_reader).unwrap();

    let mut mf_lines = metaflac.lines();

    // Search for the vendor string in the metaflac output.
    while let Some(line) = mf_lines.next() {
        let prefix = "  vendor string: ";
        if line.starts_with(prefix) {
            let mf_vendor_string = &line[prefix.len()..];
            assert_eq!(reader.vendor(), Some(mf_vendor_string));
            break
        }
    }

    let mut tags = reader.tags().iter();

    // Loop through all of the comments.
    while let Some(line) = mf_lines.next() {
        let prefix = "    comment[";
        if line.starts_with(prefix) {
            let mf_line = &line[prefix.len()..];
            let prefix_sep_index = mf_line.find(' ').unwrap();
            let mf_pair = &mf_line[prefix_sep_index + 1..];

            let sep_index = mf_pair.find('=').unwrap();
            let mf_name = &mf_pair[..sep_index];
            let mf_value = &mf_pair[sep_index + 1..];

            let &(ref name, ref value) = tags.next().unwrap();

            assert_eq!(name, mf_name);
            assert_eq!(value, mf_value);
        }
    }
}

fn compare_decoded_stream<P: AsRef<Path>>(fname: P) {
    let wav = decode_file(&fname);
    let cursor = io::Cursor::new(wav);

    // Compare the reference decoded by the 'flac' program (stored as wav, which
    // we read with Hound) to how Claxon decodes it, sample by sample.
    let mut ref_wav_reader = hound::WavReader::new(cursor).unwrap();

    let try_file = fs::File::open(fname).unwrap();
    let try_buf_reader = io::BufReader::new(try_file);
    let mut try_flac_reader = claxon::FlacReader::new(try_buf_reader).unwrap();

    // The streaminfo test will ensure that things like bit depth and
    // sample rate match, only the actual samples are compared here.
    let mut ref_samples = ref_wav_reader.samples::<i32>();

    let samples = try_flac_reader.streaminfo().samples.unwrap();
    let n_channels = try_flac_reader.streaminfo().channels;
    let mut blocks = try_flac_reader.blocks();
    let mut sample = 0u64;
    let mut b = 0u64;
    let mut buffer = Vec::new();

    while sample < samples {
        let block = blocks.read_next_or_eof(buffer).unwrap().unwrap();
        {
            let mut channels: Vec<_> = (0..n_channels)
                                           .map(|i| block.channel(i).iter().cloned())
                                           .collect();
            for i in 0..block.duration() {
                for ch in 0..n_channels as usize {
                    let ref_sample = ref_samples.next().map(|r| r.ok().unwrap());
                    let try_sample = channels[ch].next();
                    if ref_sample != try_sample {
                        println!("disagreement at sample {} of block {} in channel {}: \
                                  reference is {} but decoded is {}",
                                 i,
                                 b,
                                 ch,
                                 ref_sample.unwrap(),
                                 try_sample.unwrap());
                        panic!("decoding differs from reference decoder");
                    }
                }
            }
            sample = sample + block.duration() as u64;
        }
        b = b + 1;
        buffer = block.into_buffer();
    }
}

// Hard-coded tests for the test samples added py populate.sh.
// This allows us to run these tests in parallel and follow progress without
// enabling --nocapture.

#[test]
fn verify_streaminfo_p0() {
    compare_metaflac_streaminfo("testsamples/p0.flac");
}

#[test]
fn verify_streaminfo_p1() {
    compare_metaflac_streaminfo("testsamples/p1.flac");
}

#[test]
fn verify_streaminfo_p2() {
    compare_metaflac_streaminfo("testsamples/p2.flac");
}

#[test]
fn verify_streaminfo_p3() {
    compare_metaflac_streaminfo("testsamples/p3.flac");
}

#[test]
fn verify_streaminfo_p4() {
    compare_metaflac_streaminfo("testsamples/p4.flac");
}

#[test]
fn verify_streaminfo_pop() {
    compare_metaflac_streaminfo("testsamples/pop.flac");
}

#[test]
fn verify_streaminfo_short() {
    compare_metaflac_streaminfo("testsamples/short.flac");
}

#[test]
fn verify_streaminfo_wasted_bits() {
    compare_metaflac_streaminfo("testsamples/wasted_bits.flac");
}

#[test]
fn verify_vorbis_comment_p0() {
    compare_metaflac_vorbis_comment("testsamples/p0.flac");
}

#[test]
fn verify_vorbis_comment_p1() {
    compare_metaflac_vorbis_comment("testsamples/p1.flac");
}

#[test]
fn verify_vorbis_comment_p2() {
    compare_metaflac_vorbis_comment("testsamples/p2.flac");
}

#[test]
fn verify_vorbis_comment_p3() {
    compare_metaflac_vorbis_comment("testsamples/p3.flac");
}

#[test]
fn verify_vorbis_comment_p4() {
    compare_metaflac_vorbis_comment("testsamples/p4.flac");
}

#[test]
fn verify_decoded_stream_p0() {
    compare_decoded_stream("testsamples/p0.flac");
}

#[test]
fn verify_decoded_stream_p1() {
    compare_decoded_stream("testsamples/p1.flac");
}

#[test]
fn verify_decoded_stream_p2() {
    compare_decoded_stream("testsamples/p2.flac");
}

#[test]
fn verify_decoded_stream_p3() {
    compare_decoded_stream("testsamples/p3.flac");
}

#[test]
fn verify_decoded_stream_p4() {
    compare_decoded_stream("testsamples/p4.flac");
}

#[test]
fn verify_decoded_stream_pop() {
    compare_decoded_stream("testsamples/pop.flac");
}

#[test]
fn verify_decoded_stream_short() {
    // The short sample has only 4 samples, even less than pop.flac.
    compare_decoded_stream("testsamples/short.flac");
}

#[test]
fn verify_decoded_stream_wasted_bits() {
    // This sample has subframes where the number of wasted bits is not 0.
    compare_decoded_stream("testsamples/wasted_bits.flac");
}

#[test]
fn verify_limits_on_vendor_string() {
    // This file claims to have a vendor string which would not fit in the
    // block.
    let file = fs::File::open("testsamples/large_vendor_string.flac").unwrap();
    match claxon::FlacReader::new(file) {
        Ok(..) => panic!("This file should fail to load"),
        Err(err) => {
            assert_eq!(err, claxon::Error::FormatError("vendor string too long"))
        }
    }
}

#[test]
fn verify_limits_on_vorbis_comment_block() {
    // This file claims to have a very large Vorbis comment block, which could
    // make the decoder go OOM.
    let file = fs::File::open("testsamples/large_vorbis_comment_block.flac").unwrap();
    match claxon::FlacReader::new(file) {
        Ok(..) => panic!("This file should fail to load"),
        Err(claxon::Error::Unsupported(..)) => { }
        Err(..) => panic!("Expected 'Unsupported' error."),
    }
}

#[test]
fn verify_extra_samples() {
    use std::ffi::OsStr;

    if !Path::new("testsamples/extra").exists() {
        return
    }

    let wd = walkdir::WalkDir::new("testsamples/extra")
        .follow_links(true)
        .into_iter()
        .filter_map(|e| e.ok());

    // Recursively enumerate all the flac files in the testsamples/extra
    // directory, and compare the streaminfo and stream itself for those.
    for entry in wd {
        let path = entry.path();
        if path.is_file() && path.extension() == Some(OsStr::new("flac")) {
            print!("    comparing {} ...", path.to_str()
                                               .expect("unsupported filename"));
            compare_metaflac_streaminfo(&path);
            compare_metaflac_vorbis_comment(&path);
            compare_decoded_stream(&path);
            println!(" ok");
        }
    }
}

#[test]
fn regression_test_fuzz_samples() {
    use std::ffi::OsStr;

    // Enumerate all the flac files in the testsamples/fuzz directory,
    // and ensure that they can be decoded without panic.
    let dir = fs::read_dir("testsamples/fuzz")
                 .ok().expect("failed to enumerate flac files");
    for path in dir {
        let path = path.ok().expect("failed to obtain path info").path();
        if path.is_file() && path.extension() == Some(OsStr::new("flac")) {
            print!("    regression testing {} ...", path.to_str()
                   .expect("unsupported filename"));

            if let Ok(mut reader) = claxon::FlacReader::open(&path) {
                let mut buffer = Vec::new();
                while let Ok(Some(block)) = reader.blocks().read_next_or_eof(buffer) {
                    buffer = block.into_buffer();
                }
            }
            println!(" ok");
        }
    }
}
<|endoftext|>


<commit_before>use std::io;
use std::str::FromStr;
use std::collections::HashMap;

pub struct VM {
	op_stack: Vec<Operator>,
	data_stack: Vec<Operator>,
	words: HashMap<String, Vec<Operator>>,
}

impl VM {
	pub fn pop_data <'a> (&'a mut self) -> Operator {
		return self.data_stack.pop().expect("data stack is empty!");
	}

	pub fn push_data <'a> (&'a mut self, op: Operator) {
		self.data_stack.push(op);
	}

	pub fn pop_op <'a> (&'a mut self) -> Operator {
		return self.op_stack.pop().expect("operand stack is empty!");
	}

	pub fn push_op <'a> (&'a mut self, op: Operator) {
		self.op_stack.push(op);
	}

	pub fn eval <'a> (&'a mut self) {
		let op = self.pop_op();
		match op {
			Operator::Add => self.add(),
			Operator::Subtract => self.subtract(),
			Operator::Multiply => self.multiply(),
			Operator::Divide => self.divide(),
			Operator::Modulus => self.modulus(),
			Operator::And => self.and(),
			Operator::Or => self.or(),
			Operator::Xor => self.xor(),
			Operator::Lshift => self.lshift(),
			Operator::Rshift => self.rshift(),
			Operator::Abs => self.abs(),
			Operator::Max => self.max(),
			Operator::Min => self.min(),
			Operator::Invert => self.invert(),
			Operator::Negate => self.negate(),
			Operator::Dup => self.dup(),
			Operator::Drop => self.drop(),
			Operator::Swap => self.swap(),
			Operator::Over => self.over(),
			Operator::Rot => self.rot(),
			Operator::Value(i) => self.push_data(Operator::Value(i)),
			Operator::Print => self.print(),
			x => panic!("soon {}", x.stringify())
		}
	}

	// Math Functions
	pub fn add <'a> (&'a mut self) {
		let x = self.pop_data();
		let y = self.pop_data();
		let z = match x{
			Operator::Value(i) => match y{
				Operator::Value(j) => i+j,
				_ => panic!("can only add ints"),
			},
			_ => panic!("can only add ints"),
		};
		self.push_data(Operator::Value(z));
	}

	pub fn subtract <'a> (&'a mut self) {
		let x = self.pop_data();
		let y = self.pop_data();
		let z = match x{
			Operator::Value(i) => match y{
				Operator::Value(j) => i-j,
				_ => panic!("can only subtract ints"),
			},
			_ => panic!("can only subtract ints"),
		};
		self.push_data(Operator::Value(z));
	}

	pub fn multiply <'a> (&'a mut self) {
		let x = self.pop_data();
		let y = self.pop_data();
		let z = match x{
			Operator::Value(i) => match y{
				Operator::Value(j) => i*j,
				_ => panic!("can only multiply ints"),
			},
			_ => panic!("can only multiply ints"),
		};
		self.push_data(Operator::Value(z));
	}

	pub fn divide <'a> (&'a mut self) {
		let x = self.pop_data();
		let y = self.pop_data();
		let z = match x{
			Operator::Value(i) => match y{
				Operator::Value(j) => j/i,
				_ => panic!("can only divide ints"),
			},
			_ => panic!("can only divide ints"),
		};
		self.push_data(Operator::Value(z));
	}

	pub fn modulus <'a> (&'a mut self) {
		let x = self.pop_data();
		let y = self.pop_data();
		let z = match x{
			Operator::Value(i) => match y{
				Operator::Value(j) => i % j,
				_ => panic!("can only mod ints"),
			},
			_ => panic!("can only mod ints"),
		};
		self.push_data(Operator::Value(z));
	}

	pub fn and <'a> (&'a mut self) {
		let x = self.pop_data();
		let y = self.pop_data();
		let z = match x{
			Operator::Value(i) => match y{
				Operator::Value(j) => i & j,
				_ => panic!("can only and ints"),
			},
			_ => panic!("can only and ints"),
		};
		self.push_data(Operator::Value(z));
	}

	pub fn or <'a> (&'a mut self) {
		let x = self.pop_data();
		let y = self.pop_data();
		let z = match x{
			Operator::Value(i) => match y{
				Operator::Value(j) => i | j,
				_ => panic!("can only or ints"),
			},
			_ => panic!("can only or ints"),
		};
		self.push_data(Operator::Value(z));
	}

	pub fn xor <'a> (&'a mut self) {
		let x = self.pop_data();
		let y = self.pop_data();
		let z = match x{
			Operator::Value(i) => match y{
				Operator::Value(j) => i ^ j,
				_ => panic!("can only xor ints"),
			},
			_ => panic!("can only xor ints"),
		};
		self.push_data(Operator::Value(z));
	}

	pub fn lshift <'a> (&'a mut self) {
		let x = self.pop_data();
		let y = self.pop_data();
		let z = match x{
			Operator::Value(i) => match y{
				Operator::Value(j) => i << j,
				_ => panic!("can only lshift ints"),
			},
			_ => panic!("can only lshift ints"),
		};
		self.push_data(Operator::Value(z));
	}

	pub fn rshift <'a> (&'a mut self) {
		let x = self.pop_data();
		let y = self.pop_data();
		let z = match x{
			Operator::Value(i) => match y{
				Operator::Value(j) => i >> j,
				_ => panic!("can only rshift ints"),
			},
			_ => panic!("can only rshift ints"),
		};
		self.push_data(Operator::Value(z));
	}

	pub fn abs <'a> (&'a mut self) {
		let x = self.pop_data();
		let z = match x{
			Operator::Value(i) => if i < 0{-i} else {i},
			_ => panic!("can only abs an int"),
		};
		self.push_data(Operator::Value(z));
	}

	pub fn max <'a> (&'a mut self) {
		let x = self.pop_data();
		let y = self.pop_data();
		let z = match x{
			Operator::Value(i) => match y{
				Operator::Value(j) => if j > i {j} else{i},
				_ => panic!("can only max ints"),
			},
			_ => panic!("can only max ints"),
		};
		self.push_data(Operator::Value(z));
	}

	pub fn min <'a> (&'a mut self) {
		let x = self.pop_data();
		let y = self.pop_data();
		let z = match x{
			Operator::Value(i) => match y{
				Operator::Value(j) => if j < i {j} else {i},
				_ => panic!("can only min ints"),
			},
			_ => panic!("can only min ints"),
		};
		self.push_data(Operator::Value(z));
	}

	pub fn invert <'a> (&'a mut self) {
		let x = self.pop_data();
		let z = match x{
			Operator::Value(i) => !i,
			_ => panic!("can only invert an int"),
		};
		self.push_data(Operator::Value(z));
	}

	pub fn negate <'a> (&'a mut self) {
		let x = self.pop_data();
		let z = match x{
			Operator::Value(i) => -i,
			_ => panic!("can only negate an int"),
		};
		self.push_data(Operator::Value(z));
	}

	//Stack Functions
	pub fn dup <'a> (&'a mut self) {
		let x = self.pop_data();
		let y = x.clone();
		self.push_data(x);
		self.push_data(y);
	}

	pub fn drop <'a> (&'a mut self) {
		self.pop_data();
	}

	pub fn swap <'a> (&'a mut self) {
		let x = self.pop_data();
		let y = self.pop_data();
		self.push_data(x);
		self.push_data(y);
	}

	pub fn over <'a> (&'a mut self) {
		let x = self.pop_data();
		let y = self.pop_data();
		let z = x.clone();
		self.push_data(x);
		self.push_data(y);
		self.push_data(z);
	}

	pub fn rot <'a> (&'a mut self) {
		let x = self.pop_data();
		let y = self.pop_data();
		let z = self.pop_data();
		self.push_data(x);
		self.push_data(z);
		self.push_data(y);
	}

	//Debug Functions
	pub fn print <'a> (&'a mut self) {
		let x = self.pop_data();
		println!("{}",match x{
			Operator::Value(i) => i,
			_ => panic!("tried to print something other than a value"),
		});
	}

}

#[derive(Clone)]
pub enum Operator {
	//stack
	Dup,
	Drop,
	Swap,
	Over,
	Rot,

	//debug
	Print,

	//math
	Add,
	Subtract,
	Multiply,
	Divide,
	Modulus,
	And,
	Or,
	Xor,
	Lshift,
	Rshift,
	Abs,
	Max,
	Min,
	Invert,
	Negate,

	//custom
	Define,

	//values and custom calls
	Value(i32),
	Other,
}

impl Operator {
	fn stringify(&self) -> String {
		match *self{
			Operator::Add => format!("+"),
			Operator::Subtract => format!("-"),
			Operator::Multiply => format!("*"),
			Operator::Divide => format!("/"),
			Operator::Modulus => format!("mod"),
			Operator::And => format!("and"),
			Operator::Or => format!("or"),
			Operator::Xor => format!("xor"),
			Operator::Lshift => format!("<<"),
			Operator::Rshift => format!(">>"),
			Operator::Abs => format!("abs"),
			Operator::Max => format!("max"),
			Operator::Min => format!("min"),
			Operator::Invert => format!("invert"),
			Operator::Negate => format!("negate"),
			Operator::Dup => format!("dup"),
			Operator::Drop => format!("drop"),
			Operator::Swap => format!("swap"),
			Operator::Over => format!("over"),
			Operator::Rot => format!("rot"),
			Operator::Value(i) => format!("{}", i),
			Operator::Print => format!("."),
			Operator::Define => format!(":"),
			Operator::Other => format!("other"),
		}
	}
}

fn parse(s: &str) -> Operator {
	match s {
		//stack operations:
		"dup" => Operator::Dup,
		"drop" => Operator::Drop,
		"swap" => Operator::Swap,
		"over" => Operator::Over,
		"rot" => Operator::Rot,

		//debug operations:
		"." => Operator::Print,

		//math operations:
		"+" => Operator::Add,
		"-" => Operator::Subtract,
		"*" => Operator::Multiply,
		"/" => Operator::Divide,
		"mod" => Operator::Modulus,
		"and" => Operator::And,
		"or" => Operator::Or,
		"xor" => Operator::Xor,
		"lshift" => Operator::Lshift,
		"<<" => Operator::Lshift,
		"rshift" => Operator::Rshift,
		">>" => Operator::Rshift,
		"abs" => Operator::Abs,
		"max" => Operator::Max,
		"min" => Operator::Min,
		"invert" => Operator::Invert,
		"negate" => Operator::Negate,

		//custom definitions
		":" => Operator::Define,

		//value or custom operator
		x => {
			let y: Option<i32> = FromStr::from_str(x).ok();
			match y{
				Some(i) => Operator::Value(i),
				None => Operator::Other,
			}
		},
	}
}

fn main() {
	let mut x = io::stdin();
	let mut vm = VM {op_stack: vec![],
					 data_stack: vec![],
					 words: HashMap::new()};

	loop{
		let mut line: String = "".to_string();
		let _ = x.read_line(&mut line);

		if line.trim() == "" {break;}

		for o in line.rsplit(" "){
			let b = parse(o.trim());
			vm.push_op(b);
		}

		while vm.op_stack.len() > 0 {
			vm.eval();
		}
	}
}
<commit_msg>refactoring math functions for conciseness<commit_after>use std::io;
use std::str::FromStr;
use std::collections::HashMap;

pub struct VM {
	op_stack: Vec<Operator>,
	data_stack: Vec<Operator>,
	words: HashMap<String, Vec<Operator>>,
}

impl VM {
	pub fn pop_data <'a> (&'a mut self) -> Operator {
		return self.data_stack.pop().expect("data stack is empty!");
	}

	pub fn push_data <'a> (&'a mut self, op: Operator) {
		self.data_stack.push(op);
	}

	pub fn pop_op <'a> (&'a mut self) -> Operator {
		return self.op_stack.pop().expect("operand stack is empty!");
	}

	pub fn push_op <'a> (&'a mut self, op: Operator) {
		self.op_stack.push(op);
	}

	pub fn eval <'a> (&'a mut self) {
		let op = self.pop_op();
		match op {
			Operator::Add => self.add(),
			Operator::Subtract => self.subtract(),
			Operator::Multiply => self.multiply(),
			Operator::Divide => self.divide(),
			Operator::Modulus => self.modulus(),
			Operator::And => self.and(),
			Operator::Or => self.or(),
			Operator::Xor => self.xor(),
			Operator::Lshift => self.lshift(),
			Operator::Rshift => self.rshift(),
			Operator::Abs => self.abs(),
			Operator::Max => self.max(),
			Operator::Min => self.min(),
			Operator::Invert => self.invert(),
			Operator::Negate => self.negate(),
			Operator::Dup => self.dup(),
			Operator::Drop => self.drop(),
			Operator::Swap => self.swap(),
			Operator::Over => self.over(),
			Operator::Rot => self.rot(),
			Operator::Value(i) => self.push_data(Operator::Value(i)),
			Operator::Print => self.print(),
			x => panic!("soon {}", x.stringify())
		}
	}

	fn pop_two_ints <'a> (&'a mut self) -> (i32, i32){
		let a = self.pop_one_int();
		let b = self.pop_one_int();
		(a, b)
	}

	fn pop_one_int <'a> (&'a mut self) -> i32 {
		let a = self.pop_data();
		match a {
			Operator::Value(j) => j,
			_ => panic!("can only add ints"),
		}
	}

	// Math Functions
	pub fn add <'a> (&'a mut self) {
		let (x, y) = self.pop_two_ints();
		self.push_data(Operator::Value(x + y));
	}

	pub fn subtract <'a> (&'a mut self) {
		let (x, y) = self.pop_two_ints();
		self.push_data(Operator::Value(x - y));
	}

	pub fn multiply <'a> (&'a mut self) {
		let (x, y) = self.pop_two_ints();
		self.push_data(Operator::Value(x * y));
	}

	pub fn divide <'a> (&'a mut self) {
		let (x, y) = self.pop_two_ints();
		self.push_data(Operator::Value(y / x));
	}

	pub fn modulus <'a> (&'a mut self) {
		let (x, y) = self.pop_two_ints();
		self.push_data(Operator::Value(x % y));
	}

	pub fn and <'a> (&'a mut self) {
		let (x, y) = self.pop_two_ints();
		self.push_data(Operator::Value(x & y));
	}

	pub fn or <'a> (&'a mut self) {
		let (x, y) = self.pop_two_ints();
		self.push_data(Operator::Value(x | y));
	}

	pub fn xor <'a> (&'a mut self) {
		let (x, y) = self.pop_two_ints();
		self.push_data(Operator::Value(x ^ y));
	}

	pub fn lshift <'a> (&'a mut self) {
		let (x, y) = self.pop_two_ints();
		self.push_data(Operator::Value(x << y));
	}

	pub fn rshift <'a> (&'a mut self) {
		let (x, y) = self.pop_two_ints();
		self.push_data(Operator::Value(x >> y));
	}

	pub fn abs <'a> (&'a mut self) {
		let x = self.pop_one_int();
		self.push_data(Operator::Value(if x < 0 {-x} else {x}));
	}

	pub fn max <'a> (&'a mut self) {
		let (x, y) = self.pop_two_ints();
		self.push_data(Operator::Value(if y > x {y} else {x}));
	}

	pub fn min <'a> (&'a mut self) {
		let (x, y) = self.pop_two_ints();
		self.push_data(Operator::Value(if y < x {y} else {x}));
	}

	pub fn invert <'a> (&'a mut self) {
		let x = self.pop_one_int();
		self.push_data(Operator::Value(!x));
	}

	pub fn negate <'a> (&'a mut self) {
		let x = self.pop_one_int();
		self.push_data(Operator::Value(-x));
	}

	//Stack Functions
	pub fn dup <'a> (&'a mut self) {
		let x = self.pop_data();
		let y = x.clone();
		self.push_data(x);
		self.push_data(y);
	}

	pub fn drop <'a> (&'a mut self) {
		self.pop_data();
	}

	pub fn swap <'a> (&'a mut self) {
		let x = self.pop_data();
		let y = self.pop_data();
		self.push_data(x);
		self.push_data(y);
	}

	pub fn over <'a> (&'a mut self) {
		let x = self.pop_data();
		let y = self.pop_data();
		let z = x.clone();
		self.push_data(x);
		self.push_data(y);
		self.push_data(z);
	}

	pub fn rot <'a> (&'a mut self) {
		let x = self.pop_data();
		let y = self.pop_data();
		let z = self.pop_data();
		self.push_data(x);
		self.push_data(z);
		self.push_data(y);
	}

	//Debug Functions
	pub fn print <'a> (&'a mut self) {
		let x = self.pop_data();
		println!("{}",match x{
			Operator::Value(i) => i,
			_ => panic!("tried to print something other than a value"),
		});
	}
}

#[derive(Clone)]
pub enum Operator {
	//stack
	Dup,
	Drop,
	Swap,
	Over,
	Rot,

	//debug
	Print,

	//math
	Add,
	Subtract,
	Multiply,
	Divide,
	Modulus,
	And,
	Or,
	Xor,
	Lshift,
	Rshift,
	Abs,
	Max,
	Min,
	Invert,
	Negate,

	//custom
	Define,

	//values and custom calls
	Value(i32),
	Other,
}

impl Operator {
	fn stringify(&self) -> String {
		match *self{
			Operator::Add => format!("+"),
			Operator::Subtract => format!("-"),
			Operator::Multiply => format!("*"),
			Operator::Divide => format!("/"),
			Operator::Modulus => format!("mod"),
			Operator::And => format!("and"),
			Operator::Or => format!("or"),
			Operator::Xor => format!("xor"),
			Operator::Lshift => format!("<<"),
			Operator::Rshift => format!(">>"),
			Operator::Abs => format!("abs"),
			Operator::Max => format!("max"),
			Operator::Min => format!("min"),
			Operator::Invert => format!("invert"),
			Operator::Negate => format!("negate"),
			Operator::Dup => format!("dup"),
			Operator::Drop => format!("drop"),
			Operator::Swap => format!("swap"),
			Operator::Over => format!("over"),
			Operator::Rot => format!("rot"),
			Operator::Value(i) => format!("{}", i),
			Operator::Print => format!("."),
			Operator::Define => format!(":"),
			Operator::Other => format!("other"),
		}
	}
}

fn parse(s: &str) -> Operator {
	match s {
		//stack operations:
		"dup" => Operator::Dup,
		"drop" => Operator::Drop,
		"swap" => Operator::Swap,
		"over" => Operator::Over,
		"rot" => Operator::Rot,

		//debug operations:
		"." => Operator::Print,

		//math operations:
		"+" => Operator::Add,
		"-" => Operator::Subtract,
		"*" => Operator::Multiply,
		"/" => Operator::Divide,
		"mod" => Operator::Modulus,
		"and" => Operator::And,
		"or" => Operator::Or,
		"xor" => Operator::Xor,
		"lshift" => Operator::Lshift,
		"<<" => Operator::Lshift,
		"rshift" => Operator::Rshift,
		">>" => Operator::Rshift,
		"abs" => Operator::Abs,
		"max" => Operator::Max,
		"min" => Operator::Min,
		"invert" => Operator::Invert,
		"negate" => Operator::Negate,

		//custom definitions
		":" => Operator::Define,

		//value or custom operator
		x => {
			let y: Option<i32> = FromStr::from_str(x).ok();
			match y{
				Some(i) => Operator::Value(i),
				None => Operator::Other,
			}
		},
	}
}

fn main() {
	let x = io::stdin();
	let mut vm = VM {op_stack: vec![],
					 data_stack: vec![],
					 words: HashMap::new()};

	loop{
		let mut line: String = "".to_string();
		let _ = x.read_line(&mut line);

		if line.trim() == "" {break;}

		for o in line.rsplit(" "){
			let b = parse(o.trim());
			vm.push_op(b);
		}

		while vm.op_stack.len() > 0 {
			vm.eval();
		}
	}
}
<|endoftext|>


<commit_before>use crate::support::{basic_lib_manifest, project};

#[cargo_test]
fn missing_inherits() {
    let p = project()
        .file(
            "Cargo.toml",
            r#"
            cargo-features = ["named-profiles"]

            [package]
            name = "foo"
            version = "0.0.1"
            authors = []

            [profile.release-lto]
            codegen-units = 7
        "#,
        )
        .file("src/lib.rs", "")
        .build();

    p.cargo("build")
        .masquerade_as_nightly_cargo()
        .with_status(101)
        .with_stderr(
            "\
[ERROR] failed to parse manifest at [..]

Caused by:
  An 'inherits' directive is needed for all profiles that are not 'dev' or 'release'. Here it is missing from 'release-lto'",
        )
        .run();
}

#[cargo_test]
fn non_existent_inherits() {
    let p = project()
        .file(
            "Cargo.toml",
            r#"
            cargo-features = ["named-profiles"]

            [package]
            name = "foo"
            version = "0.0.1"
            authors = []

            [profile.release-lto]
            codegen-units = 7
            inherits = "non-existent"
        "#,
        )
        .file("src/lib.rs", "")
        .build();

    p.cargo("build")
        .masquerade_as_nightly_cargo()
        .with_status(101)
        .with_stderr(
            "\
[ERROR] failed to parse manifest at [..]

Caused by:
  Profile 'non-existent' not found in Cargo.toml",
        )
        .run();
}

#[cargo_test]
fn self_inherits() {
    let p = project()
        .file(
            "Cargo.toml",
            r#"
            cargo-features = ["named-profiles"]

            [package]
            name = "foo"
            version = "0.0.1"
            authors = []

            [profile.release-lto]
            codegen-units = 7
            inherits = "release-lto"
        "#,
        )
        .file("src/lib.rs", "")
        .build();

    p.cargo("build")
        .masquerade_as_nightly_cargo()
        .with_status(101)
        .with_stderr(
            "\
[ERROR] failed to parse manifest at [..]

Caused by:
  Inheritance loop of profiles cycles with profile 'release-lto'",
        )
        .run();
}

#[cargo_test]
fn inherits_loop() {
    let p = project()
        .file(
            "Cargo.toml",
            r#"
            cargo-features = ["named-profiles"]

            [package]
            name = "foo"
            version = "0.0.1"
            authors = []

            [profile.release-lto]
            codegen-units = 7
            inherits = "release-lto2"

            [profile.release-lto2]
            codegen-units = 7
            inherits = "release-lto"
        "#,
        )
        .file("src/lib.rs", "")
        .build();

    p.cargo("build")
        .masquerade_as_nightly_cargo()
        .with_status(101)
        .with_stderr(
            "\
[ERROR] failed to parse manifest at [..]

Caused by:
  Inheritance loop of profiles cycles with profile 'release-lto'",
        )
        .run();
}

#[cargo_test]
fn overrides_with_custom() {
    let p = project()
        .file(
            "Cargo.toml",
            r#"
            cargo-features = ["profile-overrides", "named-profiles"]

            [package]
            name = "foo"
            version = "0.0.1"
            authors = []

            [dependencies]
            xxx = {path = "xxx"}
            yyy = {path = "yyy"}

            [profile.dev]
            codegen-units = 7

            [profile.dev.overrides.xxx]
            codegen-units = 5
            [profile.dev.overrides.yyy]
            codegen-units = 3

            [profile.other]
            inherits = "dev"
            codegen-units = 2

            [profile.other.overrides.yyy]
            codegen-units = 6
        "#,
        )
        .file("src/lib.rs", "")
        .file("xxx/Cargo.toml", &basic_lib_manifest("xxx"))
        .file("xxx/src/lib.rs", "")
        .file("yyy/Cargo.toml", &basic_lib_manifest("yyy"))
        .file("yyy/src/lib.rs", "")
        .build();

    // profile overrides are inherited between profiles using inherits and have a
    // higher priority than profile options provided by custom profiles
    p.cargo("build -v")
        .masquerade_as_nightly_cargo()
        .with_stderr_unordered(
            "\
[COMPILING] xxx [..]
[COMPILING] yyy [..]
[COMPILING] foo [..]
[RUNNING] `rustc --crate-name xxx [..] -C codegen-units=5 [..]`
[RUNNING] `rustc --crate-name yyy [..] -C codegen-units=3 [..]`
[RUNNING] `rustc --crate-name foo [..] -C codegen-units=7 [..]`
[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
",
        )
        .run();

    // This also verifies that the custom profile names appears in the finished line.
    p.cargo("build --profile=other -Z unstable-options -v")
        .masquerade_as_nightly_cargo()
        .with_stderr_unordered(
            "\
[COMPILING] xxx [..]
[COMPILING] yyy [..]
[COMPILING] foo [..]
[RUNNING] `rustc --crate-name xxx [..] -C codegen-units=5 [..]`
[RUNNING] `rustc --crate-name yyy [..] -C codegen-units=6 [..]`
[RUNNING] `rustc --crate-name foo [..] -C codegen-units=2 [..]`
[FINISHED] other [unoptimized + debuginfo] target(s) in [..]
",
        )
        .run();
}
<commit_msg>testsuite: profile_custom - add conflicting_usage<commit_after>use crate::support::{basic_lib_manifest, project};

#[cargo_test]
fn missing_inherits() {
    let p = project()
        .file(
            "Cargo.toml",
            r#"
            cargo-features = ["named-profiles"]

            [package]
            name = "foo"
            version = "0.0.1"
            authors = []

            [profile.release-lto]
            codegen-units = 7
        "#,
        )
        .file("src/lib.rs", "")
        .build();

    p.cargo("build")
        .masquerade_as_nightly_cargo()
        .with_status(101)
        .with_stderr(
            "\
[ERROR] failed to parse manifest at [..]

Caused by:
  An 'inherits' directive is needed for all profiles that are not 'dev' or 'release'. Here it is missing from 'release-lto'",
        )
        .run();
}

#[cargo_test]
fn non_existent_inherits() {
    let p = project()
        .file(
            "Cargo.toml",
            r#"
            cargo-features = ["named-profiles"]

            [package]
            name = "foo"
            version = "0.0.1"
            authors = []

            [profile.release-lto]
            codegen-units = 7
            inherits = "non-existent"
        "#,
        )
        .file("src/lib.rs", "")
        .build();

    p.cargo("build")
        .masquerade_as_nightly_cargo()
        .with_status(101)
        .with_stderr(
            "\
[ERROR] failed to parse manifest at [..]

Caused by:
  Profile 'non-existent' not found in Cargo.toml",
        )
        .run();
}

#[cargo_test]
fn self_inherits() {
    let p = project()
        .file(
            "Cargo.toml",
            r#"
            cargo-features = ["named-profiles"]

            [package]
            name = "foo"
            version = "0.0.1"
            authors = []

            [profile.release-lto]
            codegen-units = 7
            inherits = "release-lto"
        "#,
        )
        .file("src/lib.rs", "")
        .build();

    p.cargo("build")
        .masquerade_as_nightly_cargo()
        .with_status(101)
        .with_stderr(
            "\
[ERROR] failed to parse manifest at [..]

Caused by:
  Inheritance loop of profiles cycles with profile 'release-lto'",
        )
        .run();
}

#[cargo_test]
fn inherits_loop() {
    let p = project()
        .file(
            "Cargo.toml",
            r#"
            cargo-features = ["named-profiles"]

            [package]
            name = "foo"
            version = "0.0.1"
            authors = []

            [profile.release-lto]
            codegen-units = 7
            inherits = "release-lto2"

            [profile.release-lto2]
            codegen-units = 7
            inherits = "release-lto"
        "#,
        )
        .file("src/lib.rs", "")
        .build();

    p.cargo("build")
        .masquerade_as_nightly_cargo()
        .with_status(101)
        .with_stderr(
            "\
[ERROR] failed to parse manifest at [..]

Caused by:
  Inheritance loop of profiles cycles with profile 'release-lto'",
        )
        .run();
}

#[cargo_test]
fn overrides_with_custom() {
    let p = project()
        .file(
            "Cargo.toml",
            r#"
            cargo-features = ["profile-overrides", "named-profiles"]

            [package]
            name = "foo"
            version = "0.0.1"
            authors = []

            [dependencies]
            xxx = {path = "xxx"}
            yyy = {path = "yyy"}

            [profile.dev]
            codegen-units = 7

            [profile.dev.overrides.xxx]
            codegen-units = 5
            [profile.dev.overrides.yyy]
            codegen-units = 3

            [profile.other]
            inherits = "dev"
            codegen-units = 2

            [profile.other.overrides.yyy]
            codegen-units = 6
        "#,
        )
        .file("src/lib.rs", "")
        .file("xxx/Cargo.toml", &basic_lib_manifest("xxx"))
        .file("xxx/src/lib.rs", "")
        .file("yyy/Cargo.toml", &basic_lib_manifest("yyy"))
        .file("yyy/src/lib.rs", "")
        .build();

    // profile overrides are inherited between profiles using inherits and have a
    // higher priority than profile options provided by custom profiles
    p.cargo("build -v")
        .masquerade_as_nightly_cargo()
        .with_stderr_unordered(
            "\
[COMPILING] xxx [..]
[COMPILING] yyy [..]
[COMPILING] foo [..]
[RUNNING] `rustc --crate-name xxx [..] -C codegen-units=5 [..]`
[RUNNING] `rustc --crate-name yyy [..] -C codegen-units=3 [..]`
[RUNNING] `rustc --crate-name foo [..] -C codegen-units=7 [..]`
[FINISHED] dev [unoptimized + debuginfo] target(s) in [..]
",
        )
        .run();

    // This also verifies that the custom profile names appears in the finished line.
    p.cargo("build --profile=other -Z unstable-options -v")
        .masquerade_as_nightly_cargo()
        .with_stderr_unordered(
            "\
[COMPILING] xxx [..]
[COMPILING] yyy [..]
[COMPILING] foo [..]
[RUNNING] `rustc --crate-name xxx [..] -C codegen-units=5 [..]`
[RUNNING] `rustc --crate-name yyy [..] -C codegen-units=6 [..]`
[RUNNING] `rustc --crate-name foo [..] -C codegen-units=2 [..]`
[FINISHED] other [unoptimized + debuginfo] target(s) in [..]
",
        )
        .run();
}

#[cargo_test]
fn conflicting_usage() {
    let p = project()
        .file(
            "Cargo.toml",
            r#"
            [package]
            name = "foo"
            version = "0.0.1"
            authors = []
        "#,
        )
        .file("src/lib.rs", "")
        .build();

    p.cargo("build -Z unstable-options --profile=dev --release")
        .masquerade_as_nightly_cargo()
        .with_status(101)
        .with_stderr_unordered("error: Conflicting usage of --profile and --release")
        .run();

    p.cargo("install -Z unstable-options --profile=release --debug")
        .masquerade_as_nightly_cargo()
        .with_status(101)
        .with_stderr_unordered("error: Conflicting usage of --profile and --debug")
        .run();
}
<|endoftext|>


<commit_before>use anyhow::ensure;
use protobuf::descriptor::field_descriptor_proto;

use crate::gen::scope::FieldWithContext;
use crate::gen::scope::MessageWithScope;

/// Pair of (key, value) if this message is map entry
pub(crate) fn map_entry<'a>(
    d: &'a MessageWithScope,
) -> anyhow::Result<Option<(FieldWithContext<'a>, FieldWithContext<'a>)>> {
    if d.message.is_map_entry() {
        // Must be consistent with
        // DescriptorBuilder::ValidateMapEntry

        // TODO: error, not panic
        ensure!(d.message.proto().name().ends_with("Entry"));

        ensure!(d.message.proto().extension.is_empty());
        ensure!(d.message.proto().extension_range.is_empty());
        ensure!(d.message.proto().nested_type.is_empty());
        ensure!(d.message.proto().enum_type.is_empty());

        ensure!(
            d.message.fields().count() == 2,
            "expecting two fields, got: {}",
            d.message
                .fields()
                .map(|f| format!("{}", f.name()))
                .collect::<Vec<_>>()
                .join(", ")
        );
        let key = d.fields()[0].clone();
        let value = d.fields()[1].clone();

        ensure!(
            "key" == key.name(),
            "first field must be named 'key', got: '{}'",
            key.name()
        );
        ensure!(
            "value" == value.name(),
            "second field must be named 'value', got: '{}'",
            value.name()
        );

        ensure!(
            1 == key.number(),
            "key field number must be 1, got: {}",
            key.number()
        );
        ensure!(
            2 == value.number(),
            "value field number must be 2, got: {}",
            value.number()
        );

        ensure!(
            field_descriptor_proto::Label::LABEL_OPTIONAL == key.field.proto().label(),
            "key field must be optional, got: {:?}",
            key.field.proto().label()
        );
        ensure!(
            field_descriptor_proto::Label::LABEL_OPTIONAL == value.field.proto().label(),
            "value field must be optional, got: {:?}",
            value.field.proto().label()
        );

        Ok(Some((key, value)))
    } else {
        Ok(None)
    }
}
<commit_msg>outdated todo<commit_after>use anyhow::ensure;
use protobuf::descriptor::field_descriptor_proto;

use crate::gen::scope::FieldWithContext;
use crate::gen::scope::MessageWithScope;

/// Pair of (key, value) if this message is map entry
pub(crate) fn map_entry<'a>(
    d: &'a MessageWithScope,
) -> anyhow::Result<Option<(FieldWithContext<'a>, FieldWithContext<'a>)>> {
    if d.message.is_map_entry() {
        // Must be consistent with
        // DescriptorBuilder::ValidateMapEntry

        ensure!(d.message.proto().name().ends_with("Entry"));

        ensure!(d.message.proto().extension.is_empty());
        ensure!(d.message.proto().extension_range.is_empty());
        ensure!(d.message.proto().nested_type.is_empty());
        ensure!(d.message.proto().enum_type.is_empty());

        ensure!(
            d.message.fields().count() == 2,
            "expecting two fields, got: {}",
            d.message
                .fields()
                .map(|f| format!("{}", f.name()))
                .collect::<Vec<_>>()
                .join(", ")
        );
        let key = d.fields()[0].clone();
        let value = d.fields()[1].clone();

        ensure!(
            "key" == key.name(),
            "first field must be named 'key', got: '{}'",
            key.name()
        );
        ensure!(
            "value" == value.name(),
            "second field must be named 'value', got: '{}'",
            value.name()
        );

        ensure!(
            1 == key.number(),
            "key field number must be 1, got: {}",
            key.number()
        );
        ensure!(
            2 == value.number(),
            "value field number must be 2, got: {}",
            value.number()
        );

        ensure!(
            field_descriptor_proto::Label::LABEL_OPTIONAL == key.field.proto().label(),
            "key field must be optional, got: {:?}",
            key.field.proto().label()
        );
        ensure!(
            field_descriptor_proto::Label::LABEL_OPTIONAL == value.field.proto().label(),
            "value field must be optional, got: {:?}",
            value.field.proto().label()
        );

        Ok(Some((key, value)))
    } else {
        Ok(None)
    }
}
<|endoftext|>


<commit_before>//  Copyright (C) 2020 Éloïs SANCHEZ.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program.  If not, see <https://www.gnu.org/licenses/>.

use anyhow::Result;
use std::process::{Command, Output};
use structopt::StructOpt;

const MIN_RUST_VERSION: &str = "1.51.0";
const NODE_VERSION: &str = "10.22.1";

#[derive(StructOpt)]
struct DuniterXTask {
    #[structopt(long)]
    skip_npm: bool,
    #[structopt(subcommand)]
    command: DuniterXTaskCommand,
}

#[derive(StructOpt)]
enum DuniterXTaskCommand {
    Build {
        #[structopt(long)]
        production: bool,
    },
    Test,
}

fn main() -> Result<()> {
    let args = DuniterXTask::from_args();

    if !version_check::is_min_version(MIN_RUST_VERSION).unwrap_or(false)
        && exec_should_success(Command::new("rustup").args(&["update", "stable"])).is_err()
    {
        eprintln!(
                "Duniter requires Rust {} or higher. If you installed the Rust toolchain via rustup, please execute the command `rustup update stable`.",
                MIN_RUST_VERSION
            );
        std::process::exit(1);
    }
    Command::new("rustc").arg("--version").status()?;
    Command::new("cargo").arg("--version").status()?;

    if !args.skip_npm {
        println!("Check node version …");
        if exec_and_get_stdout(Command::new("node").arg("-v"))
            .unwrap_or_default()
            .trim_end()
            != format!("v{}", NODE_VERSION)
        {
            eprintln!(
                "Duniter requires node v{} exactly. Please install node v{} (you can use nvm).",
                NODE_VERSION, NODE_VERSION
            );
            std::process::exit(1);
        } else {
            println!("Node v{} already installed ✔", NODE_VERSION);
        }
    }
    match args.command {
        DuniterXTaskCommand::Build { production } => build(args.skip_npm, production),
        DuniterXTaskCommand::Test => test(args.skip_npm),
    }
}

fn exec_and_get_stdout(command: &mut Command) -> Result<String> {
    let Output {
        status,
        stdout,
        stderr,
    } = command.output()?;

    if status.success() {
        Ok(String::from_utf8(stdout)
            .unwrap_or_else(|_| "Output is not a valid utf8 string".to_owned()))
    } else {
        eprintln!(
            "{}",
            String::from_utf8(stderr)
                .unwrap_or_else(|_| "Error message is not a valid utf8 string".to_owned())
        );
        std::process::exit(1);
    }
}

fn exec_should_success(command: &mut Command) -> Result<()> {
    if !command.status()?.success() {
        std::process::exit(1);
    } else {
        Ok(())
    }
}

fn build(skip_npm: bool, production: bool) -> Result<()> {
    if !skip_npm {
        exec_should_success(Command::new("npm").args(&["add", "duniter-ui"]))?;
        exec_should_success(
            Command::new("npm")
                .env("NEON_BUILD_RELEASE", "true")
                .arg("install"),
        )?;
        if production {
            exec_should_success(Command::new("npm").args(&["prune", "--production"]))?;
        }
    }
    println!("Build duniter-cli …");
    exec_should_success(Command::new("cargo").args(&["build", "--release"]))?;
    std::fs::copy("target/release/duniter", "bin/duniter")?;
    Ok(())
}

fn test(skip_npm: bool) -> Result<()> {
    exec_should_success(Command::new("cargo").args(&["test", "--all"]))?;
    if !skip_npm {
        exec_should_success(Command::new("npm").arg("test"))?;
    }
    Ok(())
}
<commit_msg>[build] fix xtask build script: use npm ci instead of npm i<commit_after>//  Copyright (C) 2020 Éloïs SANCHEZ.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program.  If not, see <https://www.gnu.org/licenses/>.

use anyhow::Result;
use std::process::{Command, Output};
use structopt::StructOpt;

const MIN_RUST_VERSION: &str = "1.51.0";
const NODE_VERSION: &str = "10.22.1";

#[derive(StructOpt)]
struct DuniterXTask {
    #[structopt(long)]
    skip_npm: bool,
    #[structopt(subcommand)]
    command: DuniterXTaskCommand,
}

#[derive(StructOpt)]
enum DuniterXTaskCommand {
    Build {
        #[structopt(long)]
        production: bool,
    },
    Test,
}

fn main() -> Result<()> {
    let args = DuniterXTask::from_args();

    if !version_check::is_min_version(MIN_RUST_VERSION).unwrap_or(false)
        && exec_should_success(Command::new("rustup").args(&["update", "stable"])).is_err()
    {
        eprintln!(
                "Duniter requires Rust {} or higher. If you installed the Rust toolchain via rustup, please execute the command `rustup update stable`.",
                MIN_RUST_VERSION
            );
        std::process::exit(1);
    }
    Command::new("rustc").arg("--version").status()?;
    Command::new("cargo").arg("--version").status()?;

    if !args.skip_npm {
        println!("Check node version …");
        if exec_and_get_stdout(Command::new("node").arg("-v"))
            .unwrap_or_default()
            .trim_end()
            != format!("v{}", NODE_VERSION)
        {
            eprintln!(
                "Duniter requires node v{} exactly. Please install node v{} (you can use nvm).",
                NODE_VERSION, NODE_VERSION
            );
            std::process::exit(1);
        } else {
            println!("Node v{} already installed ✔", NODE_VERSION);
        }
    }
    match args.command {
        DuniterXTaskCommand::Build { production } => build(args.skip_npm, production),
        DuniterXTaskCommand::Test => test(args.skip_npm),
    }
}

fn exec_and_get_stdout(command: &mut Command) -> Result<String> {
    let Output {
        status,
        stdout,
        stderr,
    } = command.output()?;

    if status.success() {
        Ok(String::from_utf8(stdout)
            .unwrap_or_else(|_| "Output is not a valid utf8 string".to_owned()))
    } else {
        eprintln!(
            "{}",
            String::from_utf8(stderr)
                .unwrap_or_else(|_| "Error message is not a valid utf8 string".to_owned())
        );
        std::process::exit(1);
    }
}

fn exec_should_success(command: &mut Command) -> Result<()> {
    if !command.status()?.success() {
        std::process::exit(1);
    } else {
        Ok(())
    }
}

fn build(skip_npm: bool, production: bool) -> Result<()> {
    if !skip_npm {
        exec_should_success(Command::new("npm").args(&["add", "duniter-ui"]))?;
        exec_should_success(
            Command::new("npm")
                .env("NEON_BUILD_RELEASE", "true")
                .arg("ci"),
        )?;
        if production {
            exec_should_success(Command::new("npm").args(&["prune", "--production"]))?;
        }
    }
    println!("Build duniter-cli …");
    exec_should_success(Command::new("cargo").args(&["build", "--release"]))?;
    std::fs::copy("target/release/duniter", "bin/duniter")?;
    Ok(())
}

fn test(skip_npm: bool) -> Result<()> {
    exec_should_success(Command::new("cargo").args(&["test", "--all"]))?;
    if !skip_npm {
        exec_should_success(Command::new("npm").arg("test"))?;
    }
    Ok(())
}
<|endoftext|>


<commit_before>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use eutil::slice_to_str;
use libc::{size_t, c_int, c_ushort,c_void};
use libc::types::os::arch::c95::wchar_t;
use mem::{new0,newarray0,delete,deletearray};
use std::mem;
use std::ptr;
use std::slice;
use std::string;
use types::{cef_string_utf16_t, cef_string_utf8_t, cef_string_wide_t};
use types::{cef_string_userfree_utf16_t, cef_string_userfree_utf8_t, cef_string_userfree_wide_t};

//cef_string

#[no_mangle]
extern "C" fn string_wide_dtor(str: *mut wchar_t) {
  deletearray(str as *mut c_void)
}

#[no_mangle]
extern "C" fn string_utf8_dtor(str: *mut u8) {
  deletearray(str as *mut c_void)
}

#[no_mangle]
extern "C" fn string_utf16_dtor(str: *mut c_ushort) {
  deletearray(str as *mut c_void)
}

#[no_mangle]
pub extern "C" fn cef_string_userfree_wide_free(cs: *mut cef_string_userfree_wide_t) {
   cef_string_wide_clear(cs);
   delete(cs as *mut c_void)
}

#[no_mangle]
pub extern "C" fn cef_string_userfree_utf8_free(cs: *mut cef_string_userfree_utf8_t) {
   cef_string_utf8_clear(cs);
   delete(cs as *mut c_void)
}

#[no_mangle]
pub extern "C" fn cef_string_userfree_utf16_free(cs: *mut cef_string_userfree_utf16_t) {
   cef_string_utf16_clear(cs);
   delete(cs as *mut c_void)
}

#[no_mangle]
pub extern "C" fn cef_string_utf8_clear(cs: *mut cef_string_utf8_t) {
    unsafe {
        (*cs).dtor.map(|dtor| dtor((*cs).str));
        (*cs).length = 0;
        (*cs).str = 0 as *mut u8;
        (*cs).dtor = mem::transmute(0 as *const u8);
    }
}

#[no_mangle]
pub extern "C" fn cef_string_userfree_utf8_alloc() -> *mut cef_string_utf8_t {
    #![inline(never)]
    new0::<cef_string_utf8_t>(1)
}

#[no_mangle]
pub extern "C" fn cef_string_utf8_set(src: *const u8, src_len: size_t, output: *mut cef_string_utf8_t, copy: c_int) -> c_int {
    cef_string_utf8_clear(output);
    unsafe {
       if copy != 0 {
           if !src.is_null() && src_len > 0 {
             (*output).str = newarray0::<u8>(src_len + 1);
             if (*output).str.is_null() {
                 return 0;
             }

             ptr::copy_memory((*output).str, src, src_len as uint);
             (*output).length = src_len;
             (*output).dtor = Some(string_utf8_dtor);
           }
       } else {
         (*output).str = mem::transmute(src);
         (*output).length = src_len;
         (*output).dtor = mem::transmute(0 as *const u8);
       }
    }
    return 1;
}

#[no_mangle]
pub extern "C" fn cef_string_utf8_cmp(a: *const cef_string_utf8_t, b: *const cef_string_utf8_t) -> c_int {
    unsafe {
       slice::raw::buf_as_slice((*a).str as *const u8, (*a).length as uint, |astr:&[u8]| {
            slice::raw::buf_as_slice((*b).str as *const u8, (*b).length as uint, |bstr:&[u8]| {
                  match astr.cmp(bstr) {
                       Less => -1,
                       Equal => 0,
                       Greater => 1
                  }
            })
       })
    }
}

#[no_mangle]
pub extern "C" fn cef_string_utf8_to_utf16(src: *const u8, src_len: size_t, output: *mut cef_string_utf16_t) -> c_int {
    slice_to_str(src, src_len as uint, |result| {
        let conv = result.utf16_units().collect::<Vec<u16>>();
        cef_string_utf16_set(conv.as_ptr(), conv.len() as size_t, output, 1);
        1
    })
}

#[no_mangle]
pub extern "C" fn cef_string_utf16_to_utf8(src: *const u16, src_len: size_t, output: *mut cef_string_utf8_t) -> c_int {
    unsafe {
       slice::raw::buf_as_slice(src, src_len as uint, |ustr| {
            match string::String::from_utf16(ustr) {
                Some(str) => {
                    cef_string_utf8_set(str.as_bytes().as_ptr(), str.len() as size_t, output, 1);
                    1 as c_int
                },
                None =>  0 as c_int
            }
       })
    }
}

#[no_mangle]
pub extern "C" fn cef_string_utf16_clear(cs: *mut cef_string_utf16_t) {
    unsafe {
        (*cs).dtor.map(|dtor| dtor((*cs).str));
        (*cs).length = 0;
        (*cs).str = 0 as *mut c_ushort;
        (*cs).dtor = mem::transmute(0 as *const u8);
    }
}

#[no_mangle]
pub extern "C" fn cef_string_userfree_utf16_alloc() -> *mut cef_string_utf16_t {
    #![inline(never)]
    new0::<cef_string_utf16_t>(1)
}

#[no_mangle]
pub extern "C" fn cef_string_utf16_set(src: *const c_ushort, src_len: size_t, output: *mut cef_string_utf16_t, copy: c_int) -> c_int {
    cef_string_utf16_clear(output);
    unsafe {
       if copy != 0 {
           if !src.is_null() && src_len > 0 {
             (*output).str = newarray0::<c_ushort>(src_len + 1);
             if (*output).str.is_null() {
                 return 0;
             }

             ptr::copy_memory((*output).str, src, src_len as uint);
             (*output).length = src_len;
             (*output).dtor = Some(string_utf16_dtor);
           }
       } else {
         (*output).str = mem::transmute(src);
         (*output).length = src_len;
         (*output).dtor = mem::transmute(0 as *const u8);
       }
    }
    return 1;
}

#[no_mangle]
pub extern "C" fn cef_string_utf16_cmp(a: *const cef_string_utf16_t, b: *const cef_string_utf16_t) -> c_int {
    unsafe {
       slice::raw::buf_as_slice(mem::transmute((*a).str), (*a).length as uint, |astr:&[u16]| {
            slice::raw::buf_as_slice(mem::transmute((*b).str), (*b).length as uint, |bstr:&[u16]| {
                  match astr.cmp(bstr) {
                       Less => -1,
                       Equal => 0,
                       Greater => 1
                  }
            })
       })
    }
}

#[no_mangle]
pub extern "C" fn cef_string_wide_clear(cs: *mut cef_string_wide_t) {
    unsafe {
        (*cs).dtor.map(|dtor| dtor((*cs).str));
        (*cs).length = 0;
        (*cs).str = 0 as *mut wchar_t;
        (*cs).dtor = mem::transmute(0 as *const u8);
    }
}

#[no_mangle]
pub extern "C" fn cef_string_userfree_wide_alloc() -> *mut cef_string_wide_t {
    #![inline(never)]
    new0::<cef_string_wide_t>(1)
}

#[no_mangle]
pub extern "C" fn cef_string_wide_set(src: *const wchar_t, src_len: size_t, output: *mut cef_string_wide_t, copy: c_int) -> c_int {
    cef_string_wide_clear(output);
    unsafe {
       if copy != 0 {
           if !src.is_null() && src_len > 0 {
             (*output).str = newarray0::<wchar_t>(src_len + 1);
             if (*output).str.is_null() {
                 return 0;
             }

             ptr::copy_memory((*output).str, src, src_len as uint);
             (*output).length = src_len;
             (*output).dtor = Some(string_wide_dtor);
           }
       } else {
         (*output).str = mem::transmute(src);
         (*output).length = src_len;
         (*output).dtor = mem::transmute(0 as *const u8);
       }
    }
    return 1;
}

#[no_mangle]
pub extern "C" fn cef_string_wide_cmp(a: *const cef_string_wide_t, b: *const cef_string_wide_t) -> c_int {
    unsafe {
       slice::raw::buf_as_slice((*a).str as *const wchar_t, (*a).length as uint, |astr:&[wchar_t]| {
            slice::raw::buf_as_slice((*b).str as *const wchar_t, (*b).length as uint, |bstr:&[wchar_t]| {
                  match astr.cmp(bstr) {
                       Less => -1,
                       Equal => 0,
                       Greater => 1
                  }
            })
       })
    }
}
<commit_msg>embedding: cef_string_utf8_to_wide()<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use eutil::slice_to_str;
use libc::{size_t, c_int, c_ushort,c_void};
use libc::types::os::arch::c95::wchar_t;
use mem::{new0,newarray0,delete,deletearray};
use std::mem;
use std::ptr;
use std::slice;
use std::string;
use types::{cef_string_utf16_t, cef_string_utf8_t, cef_string_wide_t};
use types::{cef_string_userfree_utf16_t, cef_string_userfree_utf8_t, cef_string_userfree_wide_t};

//cef_string

#[no_mangle]
extern "C" fn string_wide_dtor(str: *mut wchar_t) {
  deletearray(str as *mut c_void)
}

#[no_mangle]
extern "C" fn string_utf8_dtor(str: *mut u8) {
  deletearray(str as *mut c_void)
}

#[no_mangle]
extern "C" fn string_utf16_dtor(str: *mut c_ushort) {
  deletearray(str as *mut c_void)
}

#[no_mangle]
pub extern "C" fn cef_string_userfree_wide_free(cs: *mut cef_string_userfree_wide_t) {
   cef_string_wide_clear(cs);
   delete(cs as *mut c_void)
}

#[no_mangle]
pub extern "C" fn cef_string_userfree_utf8_free(cs: *mut cef_string_userfree_utf8_t) {
   cef_string_utf8_clear(cs);
   delete(cs as *mut c_void)
}

#[no_mangle]
pub extern "C" fn cef_string_userfree_utf16_free(cs: *mut cef_string_userfree_utf16_t) {
   cef_string_utf16_clear(cs);
   delete(cs as *mut c_void)
}

#[no_mangle]
pub extern "C" fn cef_string_utf8_clear(cs: *mut cef_string_utf8_t) {
    unsafe {
        (*cs).dtor.map(|dtor| dtor((*cs).str));
        (*cs).length = 0;
        (*cs).str = 0 as *mut u8;
        (*cs).dtor = mem::transmute(0 as *const u8);
    }
}

#[no_mangle]
pub extern "C" fn cef_string_userfree_utf8_alloc() -> *mut cef_string_utf8_t {
    #![inline(never)]
    new0::<cef_string_utf8_t>(1)
}

#[no_mangle]
pub extern "C" fn cef_string_utf8_set(src: *const u8, src_len: size_t, output: *mut cef_string_utf8_t, copy: c_int) -> c_int {
    cef_string_utf8_clear(output);
    unsafe {
       if copy != 0 {
           if !src.is_null() && src_len > 0 {
             (*output).str = newarray0::<u8>(src_len + 1);
             if (*output).str.is_null() {
                 return 0;
             }

             ptr::copy_memory((*output).str, src, src_len as uint);
             (*output).length = src_len;
             (*output).dtor = Some(string_utf8_dtor);
           }
       } else {
         (*output).str = mem::transmute(src);
         (*output).length = src_len;
         (*output).dtor = mem::transmute(0 as *const u8);
       }
    }
    return 1;
}

#[no_mangle]
pub extern "C" fn cef_string_utf8_cmp(a: *const cef_string_utf8_t, b: *const cef_string_utf8_t) -> c_int {
    unsafe {
       slice::raw::buf_as_slice((*a).str as *const u8, (*a).length as uint, |astr:&[u8]| {
            slice::raw::buf_as_slice((*b).str as *const u8, (*b).length as uint, |bstr:&[u8]| {
                  match astr.cmp(bstr) {
                       Less => -1,
                       Equal => 0,
                       Greater => 1
                  }
            })
       })
    }
}

#[no_mangle]
pub extern "C" fn cef_string_utf8_to_utf16(src: *const u8, src_len: size_t, output: *mut cef_string_utf16_t) -> c_int {
    slice_to_str(src, src_len as uint, |result| {
        let conv = result.utf16_units().collect::<Vec<u16>>();
        cef_string_utf16_set(conv.as_ptr(), conv.len() as size_t, output, 1);
        1
    })
}

#[no_mangle]
pub extern "C" fn cef_string_utf16_to_utf8(src: *const u16, src_len: size_t, output: *mut cef_string_utf8_t) -> c_int {
    unsafe {
       slice::raw::buf_as_slice(src, src_len as uint, |ustr| {
            match string::String::from_utf16(ustr) {
                Some(str) => {
                    cef_string_utf8_set(str.as_bytes().as_ptr(), str.len() as size_t, output, 1);
                    1 as c_int
                },
                None =>  0 as c_int
            }
       })
    }
}

#[no_mangle]
pub extern "C" fn cef_string_utf16_clear(cs: *mut cef_string_utf16_t) {
    unsafe {
        (*cs).dtor.map(|dtor| dtor((*cs).str));
        (*cs).length = 0;
        (*cs).str = 0 as *mut c_ushort;
        (*cs).dtor = mem::transmute(0 as *const u8);
    }
}

#[no_mangle]
pub extern "C" fn cef_string_userfree_utf16_alloc() -> *mut cef_string_utf16_t {
    #![inline(never)]
    new0::<cef_string_utf16_t>(1)
}

#[no_mangle]
pub extern "C" fn cef_string_utf16_set(src: *const c_ushort, src_len: size_t, output: *mut cef_string_utf16_t, copy: c_int) -> c_int {
    cef_string_utf16_clear(output);
    unsafe {
       if copy != 0 {
           if !src.is_null() && src_len > 0 {
             (*output).str = newarray0::<c_ushort>(src_len + 1);
             if (*output).str.is_null() {
                 return 0;
             }

             ptr::copy_memory((*output).str, src, src_len as uint);
             (*output).length = src_len;
             (*output).dtor = Some(string_utf16_dtor);
           }
       } else {
         (*output).str = mem::transmute(src);
         (*output).length = src_len;
         (*output).dtor = mem::transmute(0 as *const u8);
       }
    }
    return 1;
}

#[no_mangle]
pub extern "C" fn cef_string_utf16_cmp(a: *const cef_string_utf16_t, b: *const cef_string_utf16_t) -> c_int {
    unsafe {
       slice::raw::buf_as_slice(mem::transmute((*a).str), (*a).length as uint, |astr:&[u16]| {
            slice::raw::buf_as_slice(mem::transmute((*b).str), (*b).length as uint, |bstr:&[u16]| {
                  match astr.cmp(bstr) {
                       Less => -1,
                       Equal => 0,
                       Greater => 1
                  }
            })
       })
    }
}

#[no_mangle]
pub extern "C" fn cef_string_wide_clear(cs: *mut cef_string_wide_t) {
    unsafe {
        (*cs).dtor.map(|dtor| dtor((*cs).str));
        (*cs).length = 0;
        (*cs).str = 0 as *mut wchar_t;
        (*cs).dtor = mem::transmute(0 as *const u8);
    }
}

#[no_mangle]
pub extern "C" fn cef_string_userfree_wide_alloc() -> *mut cef_string_wide_t {
    #![inline(never)]
    new0::<cef_string_wide_t>(1)
}

#[no_mangle]
pub extern "C" fn cef_string_wide_set(src: *const wchar_t, src_len: size_t, output: *mut cef_string_wide_t, copy: c_int) -> c_int {
    cef_string_wide_clear(output);
    unsafe {
       if copy != 0 {
           if !src.is_null() && src_len > 0 {
             (*output).str = newarray0::<wchar_t>(src_len + 1);
             if (*output).str.is_null() {
                 return 0;
             }

             ptr::copy_memory((*output).str, src, src_len as uint);
             (*output).length = src_len;
             (*output).dtor = Some(string_wide_dtor);
           }
       } else {
         (*output).str = mem::transmute(src);
         (*output).length = src_len;
         (*output).dtor = mem::transmute(0 as *const u8);
       }
    }
    return 1;
}

#[no_mangle]
pub extern "C" fn cef_string_wide_cmp(a: *const cef_string_wide_t, b: *const cef_string_wide_t) -> c_int {
    unsafe {
       slice::raw::buf_as_slice((*a).str as *const wchar_t, (*a).length as uint, |astr:&[wchar_t]| {
            slice::raw::buf_as_slice((*b).str as *const wchar_t, (*b).length as uint, |bstr:&[wchar_t]| {
                  match astr.cmp(bstr) {
                       Less => -1,
                       Equal => 0,
                       Greater => 1
                  }
            })
       })
    }
}

#[no_mangle]
pub extern "C" fn cef_string_utf8_to_wide(src: *const u8, src_len: size_t, output: *mut cef_string_wide_t) -> c_int {
    if mem::size_of::<wchar_t>() == mem::size_of::<u16>() {
         return cef_string_utf8_to_utf16(src, src_len, output as *mut cef_string_utf16_t);
    }
    slice_to_str(src, src_len as uint, |result| {
        let conv = result.chars().map(|c| c as u32).collect::<Vec<u32>>();
        cef_string_wide_set(conv.as_ptr() as *const wchar_t, conv.len() as size_t, output, 1)
    })
}
<|endoftext|>


<commit_before>use crate::common::util::*;
use regex::Regex;
use std::os::unix::process::ExitStatusExt;
use std::process::{Child, Command};

// A child process the tests will try to kill.
struct Target {
    child: Child,
    killed: bool,
}

impl Target {
    // Creates a target that will naturally die after some time if not killed
    // fast enough.
    // This timeout avoids hanging failing tests.
    fn new() -> Target {
        Target {
            child: Command::new("sleep")
                .arg("30")
                .spawn()
                .expect("cannot spawn target"),
            killed: false,
        }
    }

    // Waits for the target to complete and returns the signal it received if any.
    fn wait_for_signal(&mut self) -> Option<i32> {
        let sig = self.child.wait().expect("cannot wait on target").signal();
        self.killed = true;
        sig
    }

    fn pid(&self) -> u32 {
        self.child.id()
    }
}

impl Drop for Target {
    // Terminates this target to avoid littering test boxes with zombi processes
    // when a test fails after creating a target but before killing it.
    fn drop(&mut self) {
        if !self.killed {
            self.child.kill().expect("cannot kill target");
        }
    }
}

#[test]
fn test_kill_list_all_signals() {
    // Check for a few signals.  Do not try to be comprehensive.
    new_ucmd!()
        .arg("-l")
        .succeeds()
        .stdout_contains("KILL")
        .stdout_contains("TERM")
        .stdout_contains("HUP");
}

#[test]
fn test_kill_list_all_signals_as_table() {
    // Check for a few signals.  Do not try to be comprehensive.
    new_ucmd!()
        .arg("-t")
        .succeeds()
        .stdout_contains("KILL")
        .stdout_contains("TERM")
        .stdout_contains("HUP");
}

#[test]
fn test_kill_list_one_signal_from_name() {
    // Use SIGKILL because it is 9 on all unixes.
    new_ucmd!()
        .arg("-l")
        .arg("KILL")
        .succeeds()
        .stdout_matches(&Regex::new("\\b9\\b").unwrap());
}

#[test]
fn test_kill_set_bad_signal_name() {
    // spell-checker:disable-line
    new_ucmd!()
        .arg("-s")
        .arg("IAMNOTASIGNAL") // spell-checker:disable-line
        .fails()
        .stderr_contains("unknown signal");
}

#[test]
fn test_kill_with_default_signal() {
    let mut target = Target::new();
    new_ucmd!().arg(format!("{}", target.pid())).succeeds();
    assert_eq!(target.wait_for_signal(), Some(libc::SIGTERM));
}

#[test]
fn test_kill_with_signal_number_old_form() {
    let mut target = Target::new();
    new_ucmd!()
        .arg("-9")
        .arg(format!("{}", target.pid()))
        .succeeds();
    assert_eq!(target.wait_for_signal(), Some(9));
}

#[test]
fn test_kill_with_signal_number_new_form() {
    let mut target = Target::new();
    new_ucmd!()
        .arg("-s")
        .arg("9")
        .arg(format!("{}", target.pid()))
        .succeeds();
    assert_eq!(target.wait_for_signal(), Some(9));
}

#[test]
fn test_kill_with_signal_name_new_form() {
    let mut target = Target::new();
    new_ucmd!()
        .arg("-s")
        .arg("KILL")
        .arg(format!("{}", target.pid()))
        .succeeds();
    assert_eq!(target.wait_for_signal(), Some(libc::SIGKILL));
}
<commit_msg>tests/kill: test old form args with signal name<commit_after>use crate::common::util::*;
use regex::Regex;
use std::os::unix::process::ExitStatusExt;
use std::process::{Child, Command};

// A child process the tests will try to kill.
struct Target {
    child: Child,
    killed: bool,
}

impl Target {
    // Creates a target that will naturally die after some time if not killed
    // fast enough.
    // This timeout avoids hanging failing tests.
    fn new() -> Target {
        Target {
            child: Command::new("sleep")
                .arg("30")
                .spawn()
                .expect("cannot spawn target"),
            killed: false,
        }
    }

    // Waits for the target to complete and returns the signal it received if any.
    fn wait_for_signal(&mut self) -> Option<i32> {
        let sig = self.child.wait().expect("cannot wait on target").signal();
        self.killed = true;
        sig
    }

    fn pid(&self) -> u32 {
        self.child.id()
    }
}

impl Drop for Target {
    // Terminates this target to avoid littering test boxes with zombi processes
    // when a test fails after creating a target but before killing it.
    fn drop(&mut self) {
        if !self.killed {
            self.child.kill().expect("cannot kill target");
        }
    }
}

#[test]
fn test_kill_list_all_signals() {
    // Check for a few signals.  Do not try to be comprehensive.
    new_ucmd!()
        .arg("-l")
        .succeeds()
        .stdout_contains("KILL")
        .stdout_contains("TERM")
        .stdout_contains("HUP");
}

#[test]
fn test_kill_list_all_signals_as_table() {
    // Check for a few signals.  Do not try to be comprehensive.
    new_ucmd!()
        .arg("-t")
        .succeeds()
        .stdout_contains("KILL")
        .stdout_contains("TERM")
        .stdout_contains("HUP");
}

#[test]
fn test_kill_list_one_signal_from_name() {
    // Use SIGKILL because it is 9 on all unixes.
    new_ucmd!()
        .arg("-l")
        .arg("KILL")
        .succeeds()
        .stdout_matches(&Regex::new("\\b9\\b").unwrap());
}

#[test]
fn test_kill_set_bad_signal_name() {
    // spell-checker:disable-line
    new_ucmd!()
        .arg("-s")
        .arg("IAMNOTASIGNAL") // spell-checker:disable-line
        .fails()
        .stderr_contains("unknown signal");
}

#[test]
fn test_kill_with_default_signal() {
    let mut target = Target::new();
    new_ucmd!().arg(format!("{}", target.pid())).succeeds();
    assert_eq!(target.wait_for_signal(), Some(libc::SIGTERM));
}

#[test]
fn test_kill_with_signal_number_old_form() {
    let mut target = Target::new();
    new_ucmd!()
        .arg("-9")
        .arg(format!("{}", target.pid()))
        .succeeds();
    assert_eq!(target.wait_for_signal(), Some(9));
}

#[test]
fn test_kill_with_signal_name_old_form() {
    let mut target = Target::new();
    new_ucmd!()
        .arg("-KILL")
        .arg(format!("{}", target.pid()))
        .succeeds();
    assert_eq!(target.wait_for_signal(), Some(libc::SIGKILL));
}

#[test]
fn test_kill_with_signal_prefixed_name_old_form() {
    let mut target = Target::new();
    new_ucmd!()
        .arg("-SIGKILL")
        .arg(format!("{}", target.pid()))
        .succeeds();
    assert_eq!(target.wait_for_signal(), Some(libc::SIGKILL));
}

#[test]
fn test_kill_with_signal_number_new_form() {
    let mut target = Target::new();
    new_ucmd!()
        .arg("-s")
        .arg("9")
        .arg(format!("{}", target.pid()))
        .succeeds();
    assert_eq!(target.wait_for_signal(), Some(9));
}

#[test]
fn test_kill_with_signal_name_new_form() {
    let mut target = Target::new();
    new_ucmd!()
        .arg("-s")
        .arg("KILL")
        .arg(format!("{}", target.pid()))
        .succeeds();
    assert_eq!(target.wait_for_signal(), Some(libc::SIGKILL));
}

#[test]
fn test_kill_with_signal_prefixed_name_new_form() {
    let mut target = Target::new();
    new_ucmd!()
        .arg("-s")
        .arg("SIGKILL")
        .arg(format!("{}", target.pid()))
        .succeeds();
    assert_eq!(target.wait_for_signal(), Some(libc::SIGKILL));
}
<|endoftext|>


<commit_before>#![allow(ctypes)]
#![no_std]
#![no_main]
#![feature(globs)]
#![feature(asm)]

extern crate core;

use con::Console;
use con::Writer;
use con::con;
use start32::MultiBootInfo;
//use start32::OrigMultiBootInfo;
use start32::PhysAddr;
use start32::MutPhysAddr;
use x86::idt;

mod con;
mod mboot;
mod mem;
mod start32;
mod util;
mod x86;

static mut idt_table : [idt::Entry, ..48] = [idt::null_entry, ..48];

fn writeMBInfo(infop : *mboot::Info) {
	let &mut con = con::get();
	con.write("Multiboot info at ");
	con.writePtr(infop);
	con.putc('\n');

	let &info = unsafe { &*infop };
	con.write("Flags: ");
	con.writeHex(info.flags as uint);
	con.newline();

	if info.has(mboot::MemorySize) {
		con.writeUInt(info.mem_lower as uint);
		con.write("kB lower memory, ");
		con.writeUInt(info.mem_upper as uint);
		con.write("kB upper memory, ");
		con.writeUInt(((info.mem_lower + info.mem_upper + 1023) / 1024) as uint);
		con.write("MB total.\n");
	}
	// FIXME start32 doesn't copy this
	if info.has(mboot::CommandLine) {
		let cmdline : *u8 = PhysAddr(info.cmdline as uint);
		con.write("Command line @");
		con.writePtr(cmdline);
		con.write(" (");
		con.writeHex(info.cmdline as uint);
		con.write(") \"");
		con.writeCStr(cmdline);
		con.write("\"\n");
	}
}

pub fn generic_irq_handler(vec : u8) {
}

pub fn page_fault(error : u64) {
}

pub fn idle() -> ! {
	loop { unsafe { asm!("hlt"); } }
}

struct PerCpu {
	memory : mem::PerCpu,
}

impl PerCpu {
	fn new() -> PerCpu {
		PerCpu { memory : mem::PerCpu::new() }
	}

	fn run(&mut self) -> ! {
		// TODO: Pop something from run queue, run it
		idle();
	}
}

#[no_mangle]
pub unsafe fn start64() -> ! {
	con::init(MutPhysAddr(0xb8000), 80, 25);
	con.clear();
	con.write("Hello World!\n");

	x86::lgdt(start32::Gdtr());

	let handlers = [(14, idt::Error(page_fault))];
	idt::build(&mut idt_table, handlers, generic_irq_handler);
	idt::load(&idt_table);

	let &mut memory = &mut mem::global;
	memory.init(&*start32::MultiBootInfo(), start32::memory_start as uint);
	con.write("Memory initialized. ");
	memory.stat();

	let mut cpu = PerCpu::new();
	cpu.memory.test();
	memory.stat();

//	let mut i = 0;
//	loop {
//		con.writeUInt(i);
//		con.putc('\n');
//		i += 1;
//	}
	idle();
}
<commit_msg>Poke the console into scrolling a bit... (It fails.)<commit_after>#![allow(ctypes)]
#![no_std]
#![no_main]
#![feature(globs)]
#![feature(asm)]

extern crate core;

use core::iter::*;
use core::option::*;

use con::Console;
use con::Writer;
use con::con;
use start32::MultiBootInfo;
//use start32::OrigMultiBootInfo;
use start32::PhysAddr;
use start32::MutPhysAddr;
use x86::idt;

mod con;
mod mboot;
mod mem;
mod start32;
mod util;
mod x86;

static mut idt_table : [idt::Entry, ..48] = [idt::null_entry, ..48];

fn writeMBInfo(infop : *mboot::Info) {
	let &mut con = con::get();
	con.write("Multiboot info at ");
	con.writePtr(infop);
	con.putc('\n');

	let &info = unsafe { &*infop };
	con.write("Flags: ");
	con.writeHex(info.flags as uint);
	con.newline();

	if info.has(mboot::MemorySize) {
		con.writeUInt(info.mem_lower as uint);
		con.write("kB lower memory, ");
		con.writeUInt(info.mem_upper as uint);
		con.write("kB upper memory, ");
		con.writeUInt(((info.mem_lower + info.mem_upper + 1023) / 1024) as uint);
		con.write("MB total.\n");
	}
	// FIXME start32 doesn't copy this
	if info.has(mboot::CommandLine) {
		let cmdline : *u8 = PhysAddr(info.cmdline as uint);
		con.write("Command line @");
		con.writePtr(cmdline);
		con.write(" (");
		con.writeHex(info.cmdline as uint);
		con.write(") \"");
		con.writeCStr(cmdline);
		con.write("\"\n");
	}
}

pub fn generic_irq_handler(vec : u8) {
}

pub fn page_fault(error : u64) {
}

pub fn idle() -> ! {
	loop { unsafe { asm!("hlt"); } }
}

struct PerCpu {
	memory : mem::PerCpu,
}

impl PerCpu {
	fn new() -> PerCpu {
		PerCpu { memory : mem::PerCpu::new() }
	}

	fn run(&mut self) -> ! {
		// TODO: Pop something from run queue, run it
		idle();
	}
}

#[no_mangle]
pub unsafe fn start64() -> ! {
	con::init(MutPhysAddr(0xb8000), 80, 25);
	con.clear();
	con.write("Hello World!\n");
	for i in range(0,35) {
		con.writeUInt(i as uint);
		con.newline();
	}

	x86::lgdt(start32::Gdtr());

	let handlers = [(14, idt::Error(page_fault))];
	idt::build(&mut idt_table, handlers, generic_irq_handler);
	idt::load(&idt_table);

	let &mut memory = &mut mem::global;
	memory.init(&*start32::MultiBootInfo(), start32::memory_start as uint);
	con.write("Memory initialized. ");
	memory.stat();

	let mut cpu = PerCpu::new();
	cpu.memory.test();
	memory.stat();

//	let mut i = 0;
//	loop {
//		con.writeUInt(i);
//		con.putc('\n');
//		i += 1;
//	}
	idle();
}
<|endoftext|>


<commit_before>use std::libc::{c_char, c_int, c_void, c_uint, c_ushort};

#[link_args = "-lnspr4"]
#[nolink]
extern "C" { }

pub type PRBool = c_int;
pub type PRStatus = c_int;

pub static PRTrue: PRBool = 1;
pub static PRFalse: PRBool = 0;

pub static PRSuccess: PRStatus = 0;
pub static PRFailure: PRStatus = -1;

pub static PR_AF_INET: c_ushort = 2;

pub struct PRNetAddr {
     family: c_ushort,
     port: c_ushort,
     ip: c_uint,
     pad: [c_char, ..8],

}

externfn!(fn PR_OpenTCPSocket(af: c_ushort) -> *c_void)
externfn!(fn PR_Connect(fd: *c_void, addr: *PRNetAddr, timout: c_uint) -> PRStatus)
externfn!(fn PR_Close(fd: *c_void) -> PRStatus)
externfn!(fn PR_StringToNetAddr(string: *c_char, addr: *c_void) -> PRStatus)
externfn!(fn PR_GetError() -> c_int)
externfn!(fn PR_ErrorToName(error: c_int) -> *c_char)
externfn!(fn PR_htons(conversion: c_ushort) -> c_ushort)
externfn!(fn PR_htonl(conversion: c_uint) -> c_uint)
externfn!(fn PR_Write(fd: *c_void, buf: *c_void, amount: c_int) -> c_int)
externfn!(fn PR_Read(fd: *c_void, buf: *c_void, amount: c_int) -> c_int)

<commit_msg>No more externfn! macro<commit_after>use std::libc::{c_char, c_int, c_void, c_uint, c_ushort};

#[link_args = "-lnspr4"]
#[nolink]

pub type PRBool = c_int;
pub type PRStatus = c_int;

pub static PRTrue: PRBool = 1;
pub static PRFalse: PRBool = 0;

pub static PRSuccess: PRStatus = 0;
pub static PRFailure: PRStatus = -1;

pub static PR_AF_INET: c_ushort = 2;

pub struct PRNetAddr {
     family: c_ushort,
     port: c_ushort,
     ip: c_uint,
     pad: [c_char, ..8],

}
extern "C" {
fn PR_OpenTCPSocket(af: c_ushort) -> *c_void;
fn PR_Connect(fd: *c_void, addr: *PRNetAddr, timout: c_uint) -> PRStatus;
fn PR_Close(fd: *c_void) -> PRStatus;
fn PR_StringToNetAddr(string: *c_char, addr: *c_void) -> PRStatus;
fn PR_GetError() -> c_int;
fn PR_ErrorToName(error: c_int) -> *c_char;
fn PR_htons(conversion: c_ushort) -> c_ushort;
fn PR_htonl(conversion: c_uint) -> c_uint;
fn PR_Write(fd: *c_void, buf: *c_void, amount: c_int) -> c_int;
fn PR_Read(fd: *c_void, buf: *c_void, amount: c_int) -> c_int;
}
<|endoftext|>


<commit_before>use std::any::Any;
use { Deps, Parent };

/// Registers core dependencies between parents and childs.
pub trait OnMany {
    fn on_2<P1, P2, C, F>(&mut self, constructor: F)
        where
            P1: 'static + Any,
            P2: 'static + Any,
            C: 'static + Any,
            F: for<'r> Fn(Parent<P1>, Parent<P2>) -> C + 'static;
}

impl OnMany for Deps {
    fn on_2<P1, P2, C, F>(&mut self, constructor: F)
        where
            P1: 'static + Any,
            P2: 'static + Any,
            C: 'static + Any,
            F: for<'r> Fn(Parent<P1>, Parent<P2>) -> C + 'static
    {
        //self.register_child_constructor::<P>(into_constructor(constructor));
    }
}
<commit_msg>Shared state design attempt.<commit_after>use std::any::Any;
use std::collections::VecDeque;
use std::sync::mpsc::channel;

use { Deps, Parent };

/// Registers core dependencies between parents and childs.
pub trait OnMany {
    fn on_2<P1, P2, C, F>(&mut self, constructor: F)
        where
            P1: 'static + Any,
            P2: 'static + Any,
            C: 'static + Any,
            F: for<'r> Fn(Parent<P1>, Parent<P2>) -> C + 'static;
}

impl OnMany for Deps {
    fn on_2<P1, P2, C, F>(&mut self, constructor: F)
        where
            P1: 'static + Any,
            P2: 'static + Any,
            C: 'static + Any,
            F: for<'r> Fn(Parent<P1>, Parent<P2>) -> C + 'static
    {
        let inceptions: VecDeque<Group2<P1, P2>> = VecDeque::new();

        self.register_child_constructor::<P1>(Box::new(move |deps: &Deps, parent: &mut Any| -> Option<Box<Any>> {
            let concrete_parent = parent.downcast_mut::<P1>().unwrap();
            //let child_obj = constructor(Parent::<P1> { obj: concrete_parent });
            //let child = deps.create_deps(child_obj);
            //Some(Box::new(child))
            Some(Box::new(()))
        }));

        self.register_child_constructor::<P2>(Box::new(move |deps: &Deps, parent: &mut Any| -> Option<Box<Any>> {
            let concrete_parent = parent.downcast_mut::<P2>().unwrap();
            //let child_obj = constructor(Parent::<P1> { obj: concrete_parent });
            //let child = deps.create_deps(child_obj);
            //Some(Box::new(child))
            Some(Box::new(()))
        }));
    }
}

struct Group2<P1, P2> {
    pub p1: Option<P1>,
    pub p2: Option<P2>,
}
<|endoftext|>