<commit_before>use num::{Float, Num, FromPrimitive};
use std::ops::{Neg, AddAssign, MulAssign, SubAssign, DivAssign};
use cmp::ApproxEq;
use structure::FieldApprox;

#[allow(missing_docs)]

/// Trait shared by all approximate reals.
///
/// Approximate reals are approximate fields aquipped with funtinos that are commonly used on
/// reals. The results of those functions only have to be approximately equal to the actual
/// theoretical values.
pub trait RealApprox: Copy + Num + FieldApprox + FromPrimitive +
                      Neg<Output = Self> + AddAssign + MulAssign + SubAssign + DivAssign +
                      ApproxEq<Eps = Self> + Ord {
    fn floor(self) -> Self;
    fn ceil(self) -> Self;
    fn round(self) -> Self;
    fn trunc(self) -> Self;
    fn fract(self) -> Self;
    fn abs(self) -> Self;
    fn signum(self) -> Self;
    fn is_sign_positive(self) -> bool;
    fn is_sign_negative(self) -> bool;
    fn mul_add(self, a: Self, b: Self) -> Self;
    fn recip(self) -> Self;
    fn powi(self, n: i32) -> Self;
    fn powf(self, n: Self) -> Self;
    fn sqrt(self) -> Self;
    fn exp(self) -> Self;
    fn exp2(self) -> Self;
    fn ln(self) -> Self;
    fn log(self, base: Self) -> Self;
    fn log2(self) -> Self;
    fn log10(self) -> Self;
    fn max(self, other: Self) -> Self;
    fn min(self, other: Self) -> Self;
    fn abs_sub(self, other: Self) -> Self;
    fn cbrt(self) -> Self;
    fn hypot(self, other: Self) -> Self;
    fn sin(self) -> Self;
    fn cos(self) -> Self;
    fn tan(self) -> Self;
    fn asin(self) -> Self;
    fn acos(self) -> Self;
    fn atan(self) -> Self;
    fn atan2(self, other: Self) -> Self;
    fn sin_cos(self) -> (Self, Self);
    fn exp_m1(self) -> Self;
    fn ln_1p(self) -> Self;
    fn sinh(self) -> Self;
    fn cosh(self) -> Self;
    fn tanh(self) -> Self;
    fn asinh(self) -> Self;
    fn acosh(self) -> Self;
    fn atanh(self) -> Self;
}

impl<S> RealApprox for S
where S: Float + FieldApprox + FromPrimitive + Neg +
         AddAssign + MulAssign + SubAssign + DivAssign +
         ApproxEq<Eps = S> + Ord {
    #[inline]
    fn floor(self) -> Self {
        self.floor()
    }

    #[inline]
    fn ceil(self) -> Self {
        self.ceil()
    }

    #[inline]
    fn round(self) -> Self {
        self.round()
    }

    #[inline]
    fn trunc(self) -> Self {
        self.trunc()
    }

    #[inline]
    fn fract(self) -> Self {
        self.fract()
    }

    #[inline]
    fn abs(self) -> Self {
        self.abs()
    }

    #[inline]
    fn signum(self) -> Self {
        self.signum()
    }

    #[inline]
    fn is_sign_positive(self) -> bool {
        self.is_sign_positive()
    }

    #[inline]
    fn is_sign_negative(self) -> bool {
        self.is_sign_negative()
    }

    #[inline]
    fn mul_add(self, a: Self, b: Self) -> Self {
        self.mul_add(a, b)
    }

    #[inline]
    fn recip(self) -> Self {
        self.recip()
    }

    #[inline]
    fn powi(self, n: i32) -> Self {
        self.powi(n)
    }

    #[inline]
    fn powf(self, n: Self) -> Self {
        self.powf(n)
    }

    #[inline]
    fn sqrt(self) -> Self {
        self.sqrt()
    }

    #[inline]
    fn exp(self) -> Self {
        self.exp()
    }

    #[inline]
    fn exp2(self) -> Self {
        self.exp2()
    }

    #[inline]
    fn ln(self) -> Self {
        self.ln()
    }

    #[inline]
    fn log(self, base: Self) -> Self {
        self.log(base)
    }

    #[inline]
    fn log2(self) -> Self {
        self.log2()
    }

    #[inline]
    fn log10(self) -> Self {
        self.log10()
    }

    #[inline]
    fn max(self, other: Self) -> Self {
        self.max(other)
    }

    #[inline]
    fn min(self, other: Self) -> Self {
        self.min(other)
    }

    #[inline]
    fn abs_sub(self, other: Self) -> Self {
        self.abs_sub(other)
    }

    #[inline]
    fn cbrt(self) -> Self {
        self.cbrt()
    }

    #[inline]
    fn hypot(self, other: Self) -> Self {
        self.hypot(other)
    }

    #[inline]
    fn sin(self) -> Self {
        self.sin()
    }

    #[inline]
    fn cos(self) -> Self {
        self.cos()
    }

    #[inline]
    fn tan(self) -> Self {
        self.tan()
    }

    #[inline]
    fn asin(self) -> Self {
        self.asin()
    }

    #[inline]
    fn acos(self) -> Self {
        self.acos()
    }

    #[inline]
    fn atan(self) -> Self {
        self.atan()
    }

    #[inline]
    fn atan2(self, other: Self) -> Self {
        self.atan2(other)
    }

    #[inline]
    fn sin_cos(self) -> (Self, Self) {
        self.sin_cos()
    }

    #[inline]
    fn exp_m1(self) -> Self {
        self.exp_m1()
    }

    #[inline]
    fn ln_1p(self) -> Self {
        self.ln_1p()
    }

    #[inline]
    fn sinh(self) -> Self {
        self.sinh()
    }

    #[inline]
    fn cosh(self) -> Self {
        self.cosh()
    }

    #[inline]
    fn tanh(self) -> Self {
        self.tanh()
    }

    #[inline]
    fn asinh(self) -> Self {
        self.asinh()
    }

    #[inline]
    fn acosh(self) -> Self {
        self.acosh()
    }

    #[inline]
    fn atanh(self) -> Self {
        self.atanh()
    }
}
<commit_msg>Fix typo.<commit_after>use num::{Float, Num, FromPrimitive};
use std::ops::{Neg, AddAssign, MulAssign, SubAssign, DivAssign};
use cmp::ApproxEq;
use structure::FieldApprox;

#[allow(missing_docs)]

/// Trait shared by all approximate reals.
///
/// Approximate reals are approximate fields aquipped with functions that are commonly used on
/// reals. The results of those functions only have to be approximately equal to the actual
/// theoretical values.
pub trait RealApprox: Copy + Num + FieldApprox + FromPrimitive +
                      Neg<Output = Self> + AddAssign + MulAssign + SubAssign + DivAssign +
                      ApproxEq<Eps = Self> + Ord {
    fn floor(self) -> Self;
    fn ceil(self) -> Self;
    fn round(self) -> Self;
    fn trunc(self) -> Self;
    fn fract(self) -> Self;
    fn abs(self) -> Self;
    fn signum(self) -> Self;
    fn is_sign_positive(self) -> bool;
    fn is_sign_negative(self) -> bool;
    fn mul_add(self, a: Self, b: Self) -> Self;
    fn recip(self) -> Self;
    fn powi(self, n: i32) -> Self;
    fn powf(self, n: Self) -> Self;
    fn sqrt(self) -> Self;
    fn exp(self) -> Self;
    fn exp2(self) -> Self;
    fn ln(self) -> Self;
    fn log(self, base: Self) -> Self;
    fn log2(self) -> Self;
    fn log10(self) -> Self;
    fn max(self, other: Self) -> Self;
    fn min(self, other: Self) -> Self;
    fn abs_sub(self, other: Self) -> Self;
    fn cbrt(self) -> Self;
    fn hypot(self, other: Self) -> Self;
    fn sin(self) -> Self;
    fn cos(self) -> Self;
    fn tan(self) -> Self;
    fn asin(self) -> Self;
    fn acos(self) -> Self;
    fn atan(self) -> Self;
    fn atan2(self, other: Self) -> Self;
    fn sin_cos(self) -> (Self, Self);
    fn exp_m1(self) -> Self;
    fn ln_1p(self) -> Self;
    fn sinh(self) -> Self;
    fn cosh(self) -> Self;
    fn tanh(self) -> Self;
    fn asinh(self) -> Self;
    fn acosh(self) -> Self;
    fn atanh(self) -> Self;
}

impl<S> RealApprox for S
where S: Float + FieldApprox + FromPrimitive + Neg +
         AddAssign + MulAssign + SubAssign + DivAssign +
         ApproxEq<Eps = S> + Ord {
    #[inline]
    fn floor(self) -> Self {
        self.floor()
    }

    #[inline]
    fn ceil(self) -> Self {
        self.ceil()
    }

    #[inline]
    fn round(self) -> Self {
        self.round()
    }

    #[inline]
    fn trunc(self) -> Self {
        self.trunc()
    }

    #[inline]
    fn fract(self) -> Self {
        self.fract()
    }

    #[inline]
    fn abs(self) -> Self {
        self.abs()
    }

    #[inline]
    fn signum(self) -> Self {
        self.signum()
    }

    #[inline]
    fn is_sign_positive(self) -> bool {
        self.is_sign_positive()
    }

    #[inline]
    fn is_sign_negative(self) -> bool {
        self.is_sign_negative()
    }

    #[inline]
    fn mul_add(self, a: Self, b: Self) -> Self {
        self.mul_add(a, b)
    }

    #[inline]
    fn recip(self) -> Self {
        self.recip()
    }

    #[inline]
    fn powi(self, n: i32) -> Self {
        self.powi(n)
    }

    #[inline]
    fn powf(self, n: Self) -> Self {
        self.powf(n)
    }

    #[inline]
    fn sqrt(self) -> Self {
        self.sqrt()
    }

    #[inline]
    fn exp(self) -> Self {
        self.exp()
    }

    #[inline]
    fn exp2(self) -> Self {
        self.exp2()
    }

    #[inline]
    fn ln(self) -> Self {
        self.ln()
    }

    #[inline]
    fn log(self, base: Self) -> Self {
        self.log(base)
    }

    #[inline]
    fn log2(self) -> Self {
        self.log2()
    }

    #[inline]
    fn log10(self) -> Self {
        self.log10()
    }

    #[inline]
    fn max(self, other: Self) -> Self {
        self.max(other)
    }

    #[inline]
    fn min(self, other: Self) -> Self {
        self.min(other)
    }

    #[inline]
    fn abs_sub(self, other: Self) -> Self {
        self.abs_sub(other)
    }

    #[inline]
    fn cbrt(self) -> Self {
        self.cbrt()
    }

    #[inline]
    fn hypot(self, other: Self) -> Self {
        self.hypot(other)
    }

    #[inline]
    fn sin(self) -> Self {
        self.sin()
    }

    #[inline]
    fn cos(self) -> Self {
        self.cos()
    }

    #[inline]
    fn tan(self) -> Self {
        self.tan()
    }

    #[inline]
    fn asin(self) -> Self {
        self.asin()
    }

    #[inline]
    fn acos(self) -> Self {
        self.acos()
    }

    #[inline]
    fn atan(self) -> Self {
        self.atan()
    }

    #[inline]
    fn atan2(self, other: Self) -> Self {
        self.atan2(other)
    }

    #[inline]
    fn sin_cos(self) -> (Self, Self) {
        self.sin_cos()
    }

    #[inline]
    fn exp_m1(self) -> Self {
        self.exp_m1()
    }

    #[inline]
    fn ln_1p(self) -> Self {
        self.ln_1p()
    }

    #[inline]
    fn sinh(self) -> Self {
        self.sinh()
    }

    #[inline]
    fn cosh(self) -> Self {
        self.cosh()
    }

    #[inline]
    fn tanh(self) -> Self {
        self.tanh()
    }

    #[inline]
    fn asinh(self) -> Self {
        self.asinh()
    }

    #[inline]
    fn acosh(self) -> Self {
        self.acosh()
    }

    #[inline]
    fn atanh(self) -> Self {
        self.atanh()
    }
}
<|endoftext|>


<commit_before>extern crate futures;
extern crate tokio_core;
extern crate tokio_signal;

use futures::stream::Stream;
use tokio_core::reactor::Core;

fn main() {
    // set up a Tokio event loop
    let mut core = Core::new().unwrap();

    // tokio_signal provides a convenience builder for Ctrl+C
    // this even works cross-platform, linux and windows!
    let ctrlc = tokio_signal::ctrl_c(&core.handle());
    let stream = core.run(ctrlc).unwrap();

    println!("This program is now waiting for you to press Ctrl+C");

    // Up until now, we haven't really DONE anything, just prepared
    // now it's time to actually schedule, and thus execute, the stream
    // on our event loop
    core.run(stream.for_each(|()| {
        println!("Ctrl-C received!");
        Ok(())
    })).unwrap();
}
<commit_msg>signal: Ctrl+C example: clarify control flow after receiving Ctrl+C: unreachable!()<commit_after>extern crate futures;
extern crate tokio_core;
extern crate tokio_signal;

use futures::stream::Stream;
use tokio_core::reactor::Core;

fn main() {
    // set up a Tokio event loop
    let mut core = Core::new().unwrap();

    // tokio_signal provides a convenience builder for Ctrl+C
    // this even works cross-platform, linux and windows!
    let ctrlc = tokio_signal::ctrl_c(&core.handle());
    let stream = core.run(ctrlc).unwrap();

    println!("This program is now waiting for you to press Ctrl+C");

    // Up until now, we haven't really DONE anything, just prepared
    // now it's time to actually schedule, and thus execute, the stream
    // on our event loop
    core.run(stream.for_each(|()| {
        println!("Ctrl-C received!");
        Ok(())
    })).unwrap();

    println!("this won't be printed, because the received Ctrl+C will also kill the program");
    unreachable!();
}
<|endoftext|>


<commit_before>extern crate chroniker;

use chroniker::Timer;

//To run this example: cargo run --example getting_started

fn main() {
    //Creates and starts the timer
    let timer = Timer::new();

    //Do some stuff
    chroniker::sleep(250);

    //Print the milliseconds it took to run
    println!("Time: {} ms", timer.elapsed_millis());

    //Do some more operations
    chroniker::sleep(1000);

    //Print the results
    println!("Time: {:?}", timer);

    //Now lets try to reset the results.
    //You can do this by recreating the struct
    //or calling the reset method.
    let mut timer = Timer::new();

    //Do some operations
    chroniker::sleep(250);

    println!("Time: {:?}", timer);

    //Lets reset again
    //Note: Unlike all other functions
    // this requires a mutable timer
    timer.reset();

    //Do some operations
    chroniker::sleep(1750);

    println!("Time: {:?}", timer);
}
<commit_msg>Changed Example Code<commit_after>extern crate chroniker;

use chroniker::Timer;

//To run this example: cargo run --example getting_started

fn main() {
    //Creates and starts the timer
    let timer = Timer::new();

    //Do some stuff
    chroniker::sleep(250);

    //Print the milliseconds it took to run
    println!("Time: {} ms", timer.elapsed_millis());

    //Do some more operations
    chroniker::sleep(1000);

    //Print the results
    println!("Time: {:?}", timer);

    //Now lets try to reset the results.
    //You can do this by recreating the struct
    //or calling the reset method.
    let mut timer = Timer::new();

    //Do some operations
    chroniker::sleep(250);

    println!("Time: {:?}", timer);

    //Lets reset again
    timer.reset();

    //Do some operations
    chroniker::sleep(1750);

    println!("Time: {:?}", timer);
}
<|endoftext|>


<commit_before>extern crate bindgen;
extern crate clap;
extern crate diff;
#[cfg(feature = "logging")]
extern crate env_logger;
extern crate shlex;

use bindgen::{clang_version, Builder};
use std::env;
use std::fs;
use std::io::{self, BufRead, BufReader, Error, ErrorKind, Read, Write};
use std::path::PathBuf;
use std::process;
use std::sync::{Once, ONCE_INIT};

#[path = "../src/options.rs"]
mod options;
use options::builder_from_flags;

/// The environment variable that determines if test expectations are overwritten.
static OVERWRITE_ENV_VAR: &str = "BINDGEN_OVERWRITE_EXPECTED";

// Run `rustfmt` on the given source string and return a tuple of the formatted
// bindings, and rustfmt's stderr.
fn rustfmt(source: String) -> (String, String) {
    static CHECK_RUSTFMT: Once = ONCE_INIT;

    CHECK_RUSTFMT.call_once(|| {
        let have_working_rustfmt = process::Command::new("rustup")
            .args(&["run", "nightly", "rustfmt", "--version"])
            .stdout(process::Stdio::null())
            .stderr(process::Stdio::null())
            .status()
            .ok()
            .map_or(false, |status| status.success());

        if !have_working_rustfmt {
            panic!(
                "
The latest `rustfmt` is required to run the `bindgen` test suite. Install
`rustfmt` with:

    $ rustup update nightly
    $ rustup run nightly cargo install -f rustfmt-nightly
"
            );
        }
    });

    let mut child = process::Command::new("rustup")
        .args(&[
            "run",
            "nightly",
            "rustfmt",
            "--config-path",
            concat!(env!("CARGO_MANIFEST_DIR"), "/tests/rustfmt.toml"),
        ])
        .stdin(process::Stdio::piped())
        .stdout(process::Stdio::piped())
        .stderr(process::Stdio::piped())
        .spawn()
        .expect("should spawn `rustup run nightly rustfmt`");

    let mut stdin = child.stdin.take().unwrap();
    let mut stdout = child.stdout.take().unwrap();
    let mut stderr = child.stderr.take().unwrap();

    // Write to stdin in a new thread, so that we can read from stdout on this
    // thread. This keeps the child from blocking on writing to its stdout which
    // might block us from writing to its stdin.
    let stdin_handle = ::std::thread::spawn(move || stdin.write_all(source.as_bytes()));

    // Read stderr on a new thread for similar reasons.
    let stderr_handle = ::std::thread::spawn(move || {
        let mut output = vec![];
        io::copy(&mut stderr, &mut output).map(|_| String::from_utf8_lossy(&output).to_string())
    });

    let mut output = vec![];
    io::copy(&mut stdout, &mut output).expect("Should copy stdout into vec OK");

    // Ignore actual rustfmt status because it is often non-zero for trivial
    // things.
    let _ = child.wait().expect("should wait on rustfmt child OK");

    stdin_handle
        .join()
        .expect("writer thread should not have panicked")
        .expect("should have written to child rustfmt's stdin OK");

    let bindings = String::from_utf8(output).expect("rustfmt should only emit valid utf-8");

    let stderr = stderr_handle
        .join()
        .expect("stderr reader thread should not have panicked")
        .expect("should have read child rustfmt's stderr OK");

    (bindings, stderr)
}

fn compare_generated_header(header: &PathBuf, builder: Builder) -> Result<(), Error> {
    let file_name = header.file_name().ok_or(Error::new(
        ErrorKind::Other,
        "compare_generated_header expects a file",
    ))?;

    let mut expectation = PathBuf::from(header);
    expectation.pop();
    expectation.pop();
    expectation.push("expectations");
    expectation.push("tests");

    let mut looked_at = vec![];
    let mut expectation_file;

    // Try more specific expectations first.
    {
        let mut expectation = expectation.clone();

        if cfg!(feature = "testing_only_libclang_4") {
            expectation.push("libclang-4");
        } else if cfg!(feature = "testing_only_libclang_5") {
            expectation.push("libclang-5");
        } else if cfg!(feature = "testing_only_libclang_3_9") {
            expectation.push("libclang-3.9");
        } else if cfg!(feature = "testing_only_libclang_3_8") {
            expectation.push("libclang-3.8");
        } else {
            match clang_version().parsed {
                None => {}
                Some(version) => {
                    let (maj, min) = version;
                    let version_str = if maj >= 5 {
                        "5".to_owned()
                    } else if maj == 4 {
                        "4".to_owned()
                    } else {
                        format!("{}.{}", maj, min)
                    };
                    expectation.push(format!("libclang-{}", version_str));
                }
            }
        }

        expectation.push(file_name);
        expectation.set_extension("rs");
        expectation_file = fs::File::open(&expectation).ok();
        looked_at.push(expectation);
    }

    // Try the default path otherwise.
    if expectation_file.is_none() {
        expectation.push(file_name);
        expectation.set_extension("rs");
        expectation_file = fs::File::open(&expectation).ok();
        looked_at.push(expectation);
    }

    let mut expected = String::new();
    match expectation_file {
        Some(f) => {
            BufReader::new(f).read_to_string(&mut expected)?;
        }
        None => panic!(
            "missing test expectation file and/or 'testing_only_libclang_$VERSION' \
             feature for header '{}'; looking for expectation file at '{:?}'",
            header.display(),
            looked_at,
        ),
    };

    // We skip the generate() error here so we get a full diff below
    let (actual, rustfmt_stderr) = match builder.generate() {
        Ok(bindings) => {
            let actual = bindings.to_string();
            rustfmt(actual)
        }
        Err(()) => ("<error generating bindings>".to_string(), "".to_string()),
    };
    println!("{}", rustfmt_stderr);

    let (expected, rustfmt_stderr) = rustfmt(expected);
    println!("{}", rustfmt_stderr);

    if actual == expected {
        if !actual.is_empty() {
            return Ok(());
        }
        return Err(Error::new(
            ErrorKind::Other,
            "Something's gone really wrong!",
        ));
    }

    println!("{}", rustfmt_stderr);

    println!("diff expected generated");
    println!("--- expected: {:?}", looked_at.last().unwrap());
    println!("+++ generated from: {:?}", header);

    for diff in diff::lines(&expected, &actual) {
        match diff {
            diff::Result::Left(l) => println!("-{}", l),
            diff::Result::Both(l, _) => println!(" {}", l),
            diff::Result::Right(r) => println!("+{}", r),
        }
    }

    // Overwrite the expectation with actual output.
    if env::var_os(OVERWRITE_ENV_VAR).is_some() {
        let mut expectation_file = fs::File::create(looked_at.last().unwrap())?;
        expectation_file.write_all(actual.as_bytes())?;
    }

    Err(Error::new(ErrorKind::Other, "Header and binding differ! Run with BINDGEN_OVERWRITE_EXPECTED=1 in the environment to automatically overwrite the expectation."))
}

fn builder() -> Builder {
    #[cfg(feature = "logging")]
    let _ = env_logger::try_init();

    bindgen::builder()
}

fn create_bindgen_builder(header: &PathBuf) -> Result<Option<Builder>, Error> {
    #[cfg(feature = "logging")]
    let _ = env_logger::try_init();

    let source = fs::File::open(header)?;
    let reader = BufReader::new(source);

    // Scoop up bindgen-flags from test header
    let mut flags = Vec::with_capacity(2);

    for line in reader.lines() {
        let line = line?;
        if !line.starts_with("// bindgen") {
            continue;
        }

        if line.contains("bindgen-flags: ") {
            let extra_flags = line
                .split("bindgen-flags: ")
                .last()
                .and_then(shlex::split)
                .unwrap();
            flags.extend(extra_flags.into_iter());
        } else if line.contains("bindgen-osx-only") {
            let prepend_flags = ["--raw-line", "#![cfg(target_os=\"macos\")]"];
            flags = prepend_flags
                .into_iter()
                .map(ToString::to_string)
                .chain(flags)
                .collect();
        } else if line.contains("bindgen-generate-bindings-on-linux-only")
            && !cfg!(target_os = "linux")
        {
            return Ok(None);
        }
    }

    // Different platforms have various different conventions like struct padding, mangling, etc.
    // We make the default target as x86_64-unknown-linux
    if flags.iter().all(|flag| !flag.starts_with("--target=")) {
        if !flags.iter().any(|flag| flag == "--") {
            flags.push("--".into());
        }
        flags.push("--target=x86_64-unknown-linux".into());
    }

    // Fool builder_from_flags() into believing it has real env::args_os...
    // - add "bindgen" as executable name 0th element
    // - add header filename as 1st element
    // - prepend raw lines so they're in the right order for expected output
    // - append the test header's bindgen flags
    let header_str = header
        .to_str()
        .ok_or(Error::new(ErrorKind::Other, "Invalid header file name"))?;

    let prepend = [
        "bindgen",
        // We format in `compare_generated_header` ourselves to have a little
        // more control.
        "--no-rustfmt-bindings",
        "--with-derive-default",
        header_str,
        "--raw-line",
        "",
        "--raw-line",
        "#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)]",
        "--raw-line",
        "",
    ];

    let args = prepend
        .into_iter()
        .map(ToString::to_string)
        .chain(flags.into_iter());

    builder_from_flags(args).map(|(builder, _, _)| Some(builder))
}

macro_rules! test_header {
    ($function:ident, $header:expr) => {
        #[test]
        fn $function() {
            let header = PathBuf::from($header);
            let result = create_bindgen_builder(&header).and_then(|builder| {
                if let Some(builder) = builder {
                    compare_generated_header(&header, builder)
                } else {
                    Ok(())
                }
            });

            if let Err(err) = result {
                panic!("{}", err);
            }
        }
    };
}

// This file is generated by build.rs
include!(concat!(env!("OUT_DIR"), "/tests.rs"));

#[test]
fn test_clang_env_args() {
    std::env::set_var(
        "BINDGEN_EXTRA_CLANG_ARGS",
        "-D_ENV_ONE=1 -D_ENV_TWO=\"2 -DNOT_THREE=1\"",
    );
    let actual = builder()
        .header_contents(
            "test.hpp",
            "#ifdef _ENV_ONE\nextern const int x[] = { 42 };\n#endif\n\
             #ifdef _ENV_TWO\nextern const int y[] = { 42 };\n#endif\n\
             #ifdef NOT_THREE\nextern const int z[] = { 42 };\n#endif\n",
        )
        .generate()
        .unwrap()
        .to_string();

    let (actual, stderr) = rustfmt(actual);
    println!("{}", stderr);

    let (expected, _) = rustfmt(
        "/* automatically generated by rust-bindgen */

extern \"C\" {
    pub static mut x: [::std::os::raw::c_int; 1usize];
}
extern \"C\" {
    pub static mut y: [::std::os::raw::c_int; 1usize];
}
"
        .to_string(),
    );

    assert_eq!(expected, actual);
}

#[test]
fn test_header_contents() {
    let actual = builder()
        .header_contents("test.h", "int foo(const char* a);")
        .clang_arg("--target=x86_64-unknown-linux")
        .generate()
        .unwrap()
        .to_string();

    let (actual, stderr) = rustfmt(actual);
    println!("{}", stderr);

    let (expected, _) = rustfmt(
        "/* automatically generated by rust-bindgen */

extern \"C\" {
    pub fn foo(a: *const ::std::os::raw::c_char) -> ::std::os::raw::c_int;
}
"
        .to_string(),
    );

    assert_eq!(expected, actual);
}

#[test]
fn test_multiple_header_calls_in_builder() {
    let actual = builder()
        .header(concat!(
            env!("CARGO_MANIFEST_DIR"),
            "/tests/headers/func_ptr.h"
        ))
        .header(concat!(env!("CARGO_MANIFEST_DIR"), "/tests/headers/char.h"))
        .clang_arg("--target=x86_64-unknown-linux")
        .generate()
        .unwrap()
        .to_string();

    let (actual, stderr) = rustfmt(actual);
    println!("{}", stderr);

    let expected = include_str!(concat!(
        env!("CARGO_MANIFEST_DIR"),
        "/tests/expectations/tests/test_multiple_header_calls_in_builder.rs"
    ));
    let (expected, _) = rustfmt(expected.to_string());

    if actual != expected {
        println!("Generated bindings differ from expected!");

        for diff in diff::lines(&actual, &expected) {
            match diff {
                diff::Result::Left(l) => println!("-{}", l),
                diff::Result::Both(l, _) => println!(" {}", l),
                diff::Result::Right(r) => println!("+{}", r),
            }
        }

        panic!();
    }
}

#[test]
// Doesn't support executing sh file on Windows.
// We may want to implement it in Rust so that we support all systems.
#[cfg(not(target_os = "windows"))]
fn no_system_header_includes() {
    use std::process::Command;
    assert!(Command::new("./ci/no-includes.sh")
        .current_dir(env!("CARGO_MANIFEST_DIR"))
        .spawn()
        .expect("should spawn ./ci/no-includes.sh OK")
        .wait()
        .expect("should wait for ./ci/no-includes OK")
        .success());
}

#[test]
fn dump_preprocessed_input() {
    let arg_keyword = concat!(env!("CARGO_MANIFEST_DIR"), "/tests/headers/arg_keyword.hpp");
    let empty_layout = concat!(
        env!("CARGO_MANIFEST_DIR"),
        "/tests/headers/cpp-empty-layout.hpp"
    );

    builder()
        .header(arg_keyword)
        .header(empty_layout)
        .dump_preprocessed_input()
        .expect("should dump preprocessed input");

    fn slurp(p: &str) -> String {
        let mut contents = String::new();
        let mut file = fs::File::open(p).unwrap();
        file.read_to_string(&mut contents).unwrap();
        contents
    }

    let bindgen_ii = slurp("__bindgen.ii");
    let arg_keyword = slurp(arg_keyword);
    let empty_layout = slurp(empty_layout);

    assert!(
        bindgen_ii.find(&arg_keyword).is_some(),
        "arg_keyword.hpp is in the preprocessed file"
    );
    assert!(
        bindgen_ii.find(&empty_layout).is_some(),
        "cpp-empty-layout.hpp is in the preprocessed file"
    );
}
<commit_msg>tests: Look at expectations/tests/libclang-9 expectations.<commit_after>extern crate bindgen;
extern crate clap;
extern crate diff;
#[cfg(feature = "logging")]
extern crate env_logger;
extern crate shlex;

use bindgen::{clang_version, Builder};
use std::env;
use std::fs;
use std::io::{self, BufRead, BufReader, Error, ErrorKind, Read, Write};
use std::path::PathBuf;
use std::process;
use std::sync::{Once, ONCE_INIT};

#[path = "../src/options.rs"]
mod options;
use options::builder_from_flags;

/// The environment variable that determines if test expectations are overwritten.
static OVERWRITE_ENV_VAR: &str = "BINDGEN_OVERWRITE_EXPECTED";

// Run `rustfmt` on the given source string and return a tuple of the formatted
// bindings, and rustfmt's stderr.
fn rustfmt(source: String) -> (String, String) {
    static CHECK_RUSTFMT: Once = ONCE_INIT;

    CHECK_RUSTFMT.call_once(|| {
        let have_working_rustfmt = process::Command::new("rustup")
            .args(&["run", "nightly", "rustfmt", "--version"])
            .stdout(process::Stdio::null())
            .stderr(process::Stdio::null())
            .status()
            .ok()
            .map_or(false, |status| status.success());

        if !have_working_rustfmt {
            panic!(
                "
The latest `rustfmt` is required to run the `bindgen` test suite. Install
`rustfmt` with:

    $ rustup update nightly
    $ rustup run nightly cargo install -f rustfmt-nightly
"
            );
        }
    });

    let mut child = process::Command::new("rustup")
        .args(&[
            "run",
            "nightly",
            "rustfmt",
            "--config-path",
            concat!(env!("CARGO_MANIFEST_DIR"), "/tests/rustfmt.toml"),
        ])
        .stdin(process::Stdio::piped())
        .stdout(process::Stdio::piped())
        .stderr(process::Stdio::piped())
        .spawn()
        .expect("should spawn `rustup run nightly rustfmt`");

    let mut stdin = child.stdin.take().unwrap();
    let mut stdout = child.stdout.take().unwrap();
    let mut stderr = child.stderr.take().unwrap();

    // Write to stdin in a new thread, so that we can read from stdout on this
    // thread. This keeps the child from blocking on writing to its stdout which
    // might block us from writing to its stdin.
    let stdin_handle = ::std::thread::spawn(move || stdin.write_all(source.as_bytes()));

    // Read stderr on a new thread for similar reasons.
    let stderr_handle = ::std::thread::spawn(move || {
        let mut output = vec![];
        io::copy(&mut stderr, &mut output).map(|_| String::from_utf8_lossy(&output).to_string())
    });

    let mut output = vec![];
    io::copy(&mut stdout, &mut output).expect("Should copy stdout into vec OK");

    // Ignore actual rustfmt status because it is often non-zero for trivial
    // things.
    let _ = child.wait().expect("should wait on rustfmt child OK");

    stdin_handle
        .join()
        .expect("writer thread should not have panicked")
        .expect("should have written to child rustfmt's stdin OK");

    let bindings = String::from_utf8(output).expect("rustfmt should only emit valid utf-8");

    let stderr = stderr_handle
        .join()
        .expect("stderr reader thread should not have panicked")
        .expect("should have read child rustfmt's stderr OK");

    (bindings, stderr)
}

fn compare_generated_header(header: &PathBuf, builder: Builder) -> Result<(), Error> {
    let file_name = header.file_name().ok_or(Error::new(
        ErrorKind::Other,
        "compare_generated_header expects a file",
    ))?;

    let mut expectation = PathBuf::from(header);
    expectation.pop();
    expectation.pop();
    expectation.push("expectations");
    expectation.push("tests");

    let mut looked_at = vec![];
    let mut expectation_file;

    // Try more specific expectations first.
    {
        let mut expectation = expectation.clone();

        if cfg!(feature = "testing_only_libclang_4") {
            expectation.push("libclang-4");
        } else if cfg!(feature = "testing_only_libclang_5") {
            expectation.push("libclang-5");
        } else if cfg!(feature = "testing_only_libclang_3_9") {
            expectation.push("libclang-3.9");
        } else if cfg!(feature = "testing_only_libclang_3_8") {
            expectation.push("libclang-3.8");
        } else {
            match clang_version().parsed {
                None => {}
                Some(version) => {
                    let (maj, min) = version;
                    let version_str = if maj >= 9 {
                        "9".to_owned()
                    } else if maj >= 5 {
                        "5".to_owned()
                    } else if maj == 4 {
                        "4".to_owned()
                    } else {
                        format!("{}.{}", maj, min)
                    };
                    expectation.push(format!("libclang-{}", version_str));
                }
            }
        }

        expectation.push(file_name);
        expectation.set_extension("rs");
        expectation_file = fs::File::open(&expectation).ok();
        looked_at.push(expectation);
    }

    // Try the default path otherwise.
    if expectation_file.is_none() {
        expectation.push(file_name);
        expectation.set_extension("rs");
        expectation_file = fs::File::open(&expectation).ok();
        looked_at.push(expectation);
    }

    let mut expected = String::new();
    match expectation_file {
        Some(f) => {
            BufReader::new(f).read_to_string(&mut expected)?;
        }
        None => panic!(
            "missing test expectation file and/or 'testing_only_libclang_$VERSION' \
             feature for header '{}'; looking for expectation file at '{:?}'",
            header.display(),
            looked_at,
        ),
    };

    // We skip the generate() error here so we get a full diff below
    let (actual, rustfmt_stderr) = match builder.generate() {
        Ok(bindings) => {
            let actual = bindings.to_string();
            rustfmt(actual)
        }
        Err(()) => ("<error generating bindings>".to_string(), "".to_string()),
    };
    println!("{}", rustfmt_stderr);

    let (expected, rustfmt_stderr) = rustfmt(expected);
    println!("{}", rustfmt_stderr);

    if actual == expected {
        if !actual.is_empty() {
            return Ok(());
        }
        return Err(Error::new(
            ErrorKind::Other,
            "Something's gone really wrong!",
        ));
    }

    println!("{}", rustfmt_stderr);

    println!("diff expected generated");
    println!("--- expected: {:?}", looked_at.last().unwrap());
    println!("+++ generated from: {:?}", header);

    for diff in diff::lines(&expected, &actual) {
        match diff {
            diff::Result::Left(l) => println!("-{}", l),
            diff::Result::Both(l, _) => println!(" {}", l),
            diff::Result::Right(r) => println!("+{}", r),
        }
    }

    // Overwrite the expectation with actual output.
    if env::var_os(OVERWRITE_ENV_VAR).is_some() {
        let mut expectation_file = fs::File::create(looked_at.last().unwrap())?;
        expectation_file.write_all(actual.as_bytes())?;
    }

    Err(Error::new(ErrorKind::Other, "Header and binding differ! Run with BINDGEN_OVERWRITE_EXPECTED=1 in the environment to automatically overwrite the expectation."))
}

fn builder() -> Builder {
    #[cfg(feature = "logging")]
    let _ = env_logger::try_init();

    bindgen::builder()
}

fn create_bindgen_builder(header: &PathBuf) -> Result<Option<Builder>, Error> {
    #[cfg(feature = "logging")]
    let _ = env_logger::try_init();

    let source = fs::File::open(header)?;
    let reader = BufReader::new(source);

    // Scoop up bindgen-flags from test header
    let mut flags = Vec::with_capacity(2);

    for line in reader.lines() {
        let line = line?;
        if !line.starts_with("// bindgen") {
            continue;
        }

        if line.contains("bindgen-flags: ") {
            let extra_flags = line
                .split("bindgen-flags: ")
                .last()
                .and_then(shlex::split)
                .unwrap();
            flags.extend(extra_flags.into_iter());
        } else if line.contains("bindgen-osx-only") {
            let prepend_flags = ["--raw-line", "#![cfg(target_os=\"macos\")]"];
            flags = prepend_flags
                .into_iter()
                .map(ToString::to_string)
                .chain(flags)
                .collect();
        } else if line.contains("bindgen-generate-bindings-on-linux-only")
            && !cfg!(target_os = "linux")
        {
            return Ok(None);
        }
    }

    // Different platforms have various different conventions like struct padding, mangling, etc.
    // We make the default target as x86_64-unknown-linux
    if flags.iter().all(|flag| !flag.starts_with("--target=")) {
        if !flags.iter().any(|flag| flag == "--") {
            flags.push("--".into());
        }
        flags.push("--target=x86_64-unknown-linux".into());
    }

    // Fool builder_from_flags() into believing it has real env::args_os...
    // - add "bindgen" as executable name 0th element
    // - add header filename as 1st element
    // - prepend raw lines so they're in the right order for expected output
    // - append the test header's bindgen flags
    let header_str = header
        .to_str()
        .ok_or(Error::new(ErrorKind::Other, "Invalid header file name"))?;

    let prepend = [
        "bindgen",
        // We format in `compare_generated_header` ourselves to have a little
        // more control.
        "--no-rustfmt-bindings",
        "--with-derive-default",
        header_str,
        "--raw-line",
        "",
        "--raw-line",
        "#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)]",
        "--raw-line",
        "",
    ];

    let args = prepend
        .into_iter()
        .map(ToString::to_string)
        .chain(flags.into_iter());

    builder_from_flags(args).map(|(builder, _, _)| Some(builder))
}

macro_rules! test_header {
    ($function:ident, $header:expr) => {
        #[test]
        fn $function() {
            let header = PathBuf::from($header);
            let result = create_bindgen_builder(&header).and_then(|builder| {
                if let Some(builder) = builder {
                    compare_generated_header(&header, builder)
                } else {
                    Ok(())
                }
            });

            if let Err(err) = result {
                panic!("{}", err);
            }
        }
    };
}

// This file is generated by build.rs
include!(concat!(env!("OUT_DIR"), "/tests.rs"));

#[test]
fn test_clang_env_args() {
    std::env::set_var(
        "BINDGEN_EXTRA_CLANG_ARGS",
        "-D_ENV_ONE=1 -D_ENV_TWO=\"2 -DNOT_THREE=1\"",
    );
    let actual = builder()
        .header_contents(
            "test.hpp",
            "#ifdef _ENV_ONE\nextern const int x[] = { 42 };\n#endif\n\
             #ifdef _ENV_TWO\nextern const int y[] = { 42 };\n#endif\n\
             #ifdef NOT_THREE\nextern const int z[] = { 42 };\n#endif\n",
        )
        .generate()
        .unwrap()
        .to_string();

    let (actual, stderr) = rustfmt(actual);
    println!("{}", stderr);

    let (expected, _) = rustfmt(
        "/* automatically generated by rust-bindgen */

extern \"C\" {
    pub static mut x: [::std::os::raw::c_int; 1usize];
}
extern \"C\" {
    pub static mut y: [::std::os::raw::c_int; 1usize];
}
"
        .to_string(),
    );

    assert_eq!(expected, actual);
}

#[test]
fn test_header_contents() {
    let actual = builder()
        .header_contents("test.h", "int foo(const char* a);")
        .clang_arg("--target=x86_64-unknown-linux")
        .generate()
        .unwrap()
        .to_string();

    let (actual, stderr) = rustfmt(actual);
    println!("{}", stderr);

    let (expected, _) = rustfmt(
        "/* automatically generated by rust-bindgen */

extern \"C\" {
    pub fn foo(a: *const ::std::os::raw::c_char) -> ::std::os::raw::c_int;
}
"
        .to_string(),
    );

    assert_eq!(expected, actual);
}

#[test]
fn test_multiple_header_calls_in_builder() {
    let actual = builder()
        .header(concat!(
            env!("CARGO_MANIFEST_DIR"),
            "/tests/headers/func_ptr.h"
        ))
        .header(concat!(env!("CARGO_MANIFEST_DIR"), "/tests/headers/char.h"))
        .clang_arg("--target=x86_64-unknown-linux")
        .generate()
        .unwrap()
        .to_string();

    let (actual, stderr) = rustfmt(actual);
    println!("{}", stderr);

    let expected = include_str!(concat!(
        env!("CARGO_MANIFEST_DIR"),
        "/tests/expectations/tests/test_multiple_header_calls_in_builder.rs"
    ));
    let (expected, _) = rustfmt(expected.to_string());

    if actual != expected {
        println!("Generated bindings differ from expected!");

        for diff in diff::lines(&actual, &expected) {
            match diff {
                diff::Result::Left(l) => println!("-{}", l),
                diff::Result::Both(l, _) => println!(" {}", l),
                diff::Result::Right(r) => println!("+{}", r),
            }
        }

        panic!();
    }
}

#[test]
// Doesn't support executing sh file on Windows.
// We may want to implement it in Rust so that we support all systems.
#[cfg(not(target_os = "windows"))]
fn no_system_header_includes() {
    use std::process::Command;
    assert!(Command::new("./ci/no-includes.sh")
        .current_dir(env!("CARGO_MANIFEST_DIR"))
        .spawn()
        .expect("should spawn ./ci/no-includes.sh OK")
        .wait()
        .expect("should wait for ./ci/no-includes OK")
        .success());
}

#[test]
fn dump_preprocessed_input() {
    let arg_keyword = concat!(env!("CARGO_MANIFEST_DIR"), "/tests/headers/arg_keyword.hpp");
    let empty_layout = concat!(
        env!("CARGO_MANIFEST_DIR"),
        "/tests/headers/cpp-empty-layout.hpp"
    );

    builder()
        .header(arg_keyword)
        .header(empty_layout)
        .dump_preprocessed_input()
        .expect("should dump preprocessed input");

    fn slurp(p: &str) -> String {
        let mut contents = String::new();
        let mut file = fs::File::open(p).unwrap();
        file.read_to_string(&mut contents).unwrap();
        contents
    }

    let bindgen_ii = slurp("__bindgen.ii");
    let arg_keyword = slurp(arg_keyword);
    let empty_layout = slurp(empty_layout);

    assert!(
        bindgen_ii.find(&arg_keyword).is_some(),
        "arg_keyword.hpp is in the preprocessed file"
    );
    assert!(
        bindgen_ii.find(&empty_layout).is_some(),
        "cpp-empty-layout.hpp is in the preprocessed file"
    );
}
<|endoftext|>


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

#![allow(unstable_features)]

#![feature(collections)]
#![feature(core)]
#![feature(io)]
#![feature(libc)]
#![feature(test)]

#[macro_use]
extern crate c_string;

extern crate test;
extern crate libc;

use std::error::FromError;
use std::ffi::CStr;
use std::io::Error as IoError;
use std::io::ErrorKind::InvalidInput;
use std::iter::Iterator;
use std::ptr;

use c_string::{CStrBuf, OwnedCString, CChars};
use c_string::{libc_free, parse_c_multistring};

pub fn check_c_str(c_str: &CStr, expected: &[u8]) {
    let buf = c_str.as_ptr();
    let len = expected.len();
    for i in (0 .. len) {
        let byte = unsafe { *buf.offset(i as isize) as u8 };
        assert_eq!(byte, expected[i]);
    }
    let term = unsafe { *buf.offset(len as isize) as u8 };
    assert_eq!(term, 0);
}

unsafe fn bytes_dup_raw(s: &[u8]) -> *const libc::c_char {
    let len = s.len();
    let dup = libc::malloc((len + 1) as libc::size_t) as *mut u8;
    ptr::copy_nonoverlapping(dup, s.as_ptr(), len);
    *dup.offset(len as isize) = 0;
    dup as *const libc::c_char
}

fn bytes_dup(s: &[u8]) -> OwnedCString {
    unsafe {
        OwnedCString::new(bytes_dup_raw(s), libc_free)
    }
}

fn str_dup(s: &str) -> OwnedCString {
    bytes_dup(s.as_bytes())
}

#[test]
fn test_parse_c_multistring() {
    unsafe {
        let input = b"zero\0one\0\0";
        let ptr = input.as_ptr();
        let expected = ["zero", "one"];
        let mut it = expected.iter();
        let result = parse_c_multistring(ptr as *const libc::c_char, None,
            |cbytes| {
                assert_eq!(cbytes, it.next().unwrap().as_bytes());
            });
        assert_eq!(result, 2);
        assert!(it.next().is_none());
    }
}

#[test]
fn test_c_str_macro() {
    let c_str = c_str!("hello");
    check_c_str(c_str, b"hello");
}

#[test]
fn test_owned_c_string_deref() {
    let c_str = str_dup("hello");
    check_c_str(&c_str, b"hello");
}

#[test]
fn test_owned_c_string_as_ptr() {
    let c_str = str_dup("hello");
    let len = unsafe { libc::strlen(c_str.as_ptr()) };
    assert_eq!(len, 5);
}

#[test]
fn test_iterator() {
    let c_string = str_dup("");
    let mut iter = CChars::from_c_str(&c_string);
    assert_eq!(iter.next(), None);

    let c_string = str_dup("hello");
    let mut iter = CChars::from_c_str(&c_string);
    assert_eq!(iter.next(), Some('h' as libc::c_char));
    assert_eq!(iter.next(), Some('e' as libc::c_char));
    assert_eq!(iter.next(), Some('l' as libc::c_char));
    assert_eq!(iter.next(), Some('l' as libc::c_char));
    assert_eq!(iter.next(), Some('o' as libc::c_char));
    assert_eq!(iter.next(), None);
}

#[test]
fn test_c_str_buf_from_iter() {
    let test_strings = [
        b"",
        b"foo\xFF",
        b"Mary had a little \xD0\x0D, Little \xD0\x0D"  // Exercises the owned variant
    ];
    for bytes in test_strings.iter() {
        let c_str = CStrBuf::from_iter(bytes.iter().cloned()).unwrap();
        check_c_str(&c_str, bytes);
    }

    let test_strings = [
        b"got\0nul",
        b"Mary had a little lamb, Little \0"  // Exercises the owned variant
    ];
    for bytes in test_strings.iter() {
        let res = CStrBuf::from_iter(bytes.iter().cloned());
        let err = res.err().unwrap();
        assert_eq!(err.nul_position(), bytes.position_elem(&0u8).unwrap());
        let vec = err.into_bytes();
        assert_eq!(&vec, bytes);
    }
}

#[test]
fn test_c_str_buf_from_str() {
    let c_str = CStrBuf::from_str("").unwrap();
    check_c_str(&c_str, b"");

    let c_str = CStrBuf::from_str("hello").unwrap();
    check_c_str(&c_str, b"hello");

    // Owned variant
    let c_str = CStrBuf::from_str("Mary had a little lamb, Little lamb").unwrap();
    check_c_str(&c_str, b"Mary had a little lamb, Little lamb");

    let res = CStrBuf::from_str("got\0nul");
    let err = res.err().unwrap();
    assert_eq!(err.nul_position(), 3);
    let bytes = err.into_bytes();
    assert_eq!(bytes, b"got\0nul");
}

#[test]
fn test_io_error_from_nul_error() {
    let res = CStrBuf::from_str("got\0nul");
    let err = res.err().unwrap();
    let io_err: IoError = FromError::from_error(err);
    assert_eq!(io_err.kind(), InvalidInput);
}

#[test]
fn test_c_str_buf_from_vec() {
    let test_strings = [
        b"",
        b"foo\xFF",
        b"Mary had a little \xD0\x0D, Little \xD0\x0D"  // Exercises the owned variant
    ];
    for bytes in test_strings.iter() {
        let c_str = CStrBuf::from_vec(bytes.to_vec()).unwrap();
        check_c_str(&c_str, bytes);
    }

    let test_strings = [
        b"got\0nul",
        b"Mary had a little lamb, Little \0"  // Exercises the owned variant
    ];
    for bytes in test_strings.iter() {
        let res = CStrBuf::from_vec(bytes.to_vec());
        let err = res.err().unwrap();
        assert_eq!(err.nul_position(), bytes.position_elem(&0u8).unwrap());
        let vec = err.into_bytes();
        assert_eq!(&vec, bytes);
    }
}

#[test]
fn test_io_error_from_into_c_str_error() {
    let res = CStrBuf::from_vec(b"got\0nul".to_vec());
    let err = res.err().unwrap();
    let io_err: IoError = FromError::from_error(err);
    assert_eq!(io_err.kind(), InvalidInput);
}

#[test]
fn test_c_str_buf_into_vec() {
    let c_str = CStrBuf::from_str("").unwrap();
    let vec = c_str.into_vec();
    assert_eq!(&vec[..], b"");
    let c_str = CStrBuf::from_str("hello").unwrap();
    let vec = c_str.into_vec();
    assert_eq!(&vec[..], b"hello");
    let bytes = b"foo\xFF";
    let c_str = CStrBuf::from_iter(bytes.iter().cloned()).unwrap();
    let vec = c_str.into_vec();
    assert_eq!(&vec[..], bytes);

    // Owned variant
    let c_str = CStrBuf::from_str("Mary had a little lamb, Little lamb").unwrap();
    let vec = c_str.into_vec();
    assert_eq!(&vec[..], b"Mary had a little lamb, Little lamb");
    let bytes = b"Mary had a little \xD0\x0D, Little \xD0\x0D";
    let c_str = CStrBuf::from_iter(bytes.iter().cloned()).unwrap();
    let vec = c_str.into_vec();
    assert_eq!(&vec[..], bytes);
}

#[test]
fn test_owned_c_string_to_bytes() {
    let c_str = str_dup("hello");
    assert_eq!(c_str.to_bytes(), b"hello");
    let c_str = str_dup("");
    assert_eq!(c_str.to_bytes(), b"");
    let c_str = bytes_dup(b"foo\xFF");
    assert_eq!(c_str.to_bytes(), b"foo\xFF");
}

#[test]
fn test_owned_c_string_debug() {
    let c_str = str_dup("hello");
    let msg = format!("{:?}", c_str);
    assert_eq!(msg, "\"hello\"");
    let c_str = str_dup("");
    let msg = format!("{:?}", c_str);
    assert_eq!(msg, "\"\"");
    let c_str = bytes_dup(b"foo\xFF");
    let msg = format!("{:?}", c_str);
    assert_eq!(msg, r#""foo\xff""#);
}

#[test]
#[should_panic]
fn test_c_string_new_fail() {
    let _c_str: OwnedCString = unsafe {
        OwnedCString::new(ptr::null(), libc_free)
    };
}
<commit_msg>Update tests for rustc 1.0.0-nightly (e2fa53e59 2015-03-20)<commit_after>// Copyright 2014, 2015 Mikhail Zabaluev <mikhail.zabaluev@gmail.com>
// Copyright 2012 The Rust Project Developers
// See the COPYRIGHT file at the top-level directory of this distribution
// and at http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![allow(unstable_features)]

#![feature(collections)]
#![feature(libc)]
#![feature(test)]

#[macro_use]
extern crate c_string;

extern crate test;
extern crate libc;

use std::error::FromError;
use std::ffi::CStr;
use std::io::Error as IoError;
use std::io::ErrorKind::InvalidInput;
use std::iter::Iterator;
use std::ptr;

use c_string::{CStrBuf, OwnedCString, CChars};
use c_string::{libc_free, parse_c_multistring};

pub fn check_c_str(c_str: &CStr, expected: &[u8]) {
    let buf = c_str.as_ptr();
    let len = expected.len();
    for i in (0 .. len) {
        let byte = unsafe { *buf.offset(i as isize) as u8 };
        assert_eq!(byte, expected[i]);
    }
    let term = unsafe { *buf.offset(len as isize) as u8 };
    assert_eq!(term, 0);
}

unsafe fn bytes_dup_raw(s: &[u8]) -> *const libc::c_char {
    let len = s.len();
    let dup = libc::malloc((len + 1) as libc::size_t) as *mut u8;
    ptr::copy_nonoverlapping(dup, s.as_ptr(), len);
    *dup.offset(len as isize) = 0;
    dup as *const libc::c_char
}

fn bytes_dup(s: &[u8]) -> OwnedCString {
    unsafe {
        OwnedCString::new(bytes_dup_raw(s), libc_free)
    }
}

fn str_dup(s: &str) -> OwnedCString {
    bytes_dup(s.as_bytes())
}

#[test]
fn test_parse_c_multistring() {
    unsafe {
        let input = b"zero\0one\0\0";
        let ptr = input.as_ptr();
        let expected = ["zero", "one"];
        let mut it = expected.iter();
        let result = parse_c_multistring(ptr as *const libc::c_char, None,
            |cbytes| {
                assert_eq!(cbytes, it.next().unwrap().as_bytes());
            });
        assert_eq!(result, 2);
        assert!(it.next().is_none());
    }
}

#[test]
fn test_c_str_macro() {
    let c_str = c_str!("hello");
    check_c_str(c_str, b"hello");
}

#[test]
fn test_owned_c_string_deref() {
    let c_str = str_dup("hello");
    check_c_str(&c_str, b"hello");
}

#[test]
fn test_owned_c_string_as_ptr() {
    let c_str = str_dup("hello");
    let len = unsafe { libc::strlen(c_str.as_ptr()) };
    assert_eq!(len, 5);
}

#[test]
fn test_iterator() {
    let c_string = str_dup("");
    let mut iter = CChars::from_c_str(&c_string);
    assert_eq!(iter.next(), None);

    let c_string = str_dup("hello");
    let mut iter = CChars::from_c_str(&c_string);
    assert_eq!(iter.next(), Some('h' as libc::c_char));
    assert_eq!(iter.next(), Some('e' as libc::c_char));
    assert_eq!(iter.next(), Some('l' as libc::c_char));
    assert_eq!(iter.next(), Some('l' as libc::c_char));
    assert_eq!(iter.next(), Some('o' as libc::c_char));
    assert_eq!(iter.next(), None);
}

#[test]
fn test_c_str_buf_from_iter() {
    let test_strings: &[&'static [u8]] = &[
        b"",
        b"foo\xFF",
        b"Mary had a little \xD0\x0D, Little \xD0\x0D"  // Exercises the owned variant
    ];
    for bytes in test_strings.iter() {
        let c_str = CStrBuf::from_iter(bytes.iter().cloned()).unwrap();
        check_c_str(&c_str, bytes);
    }

    let test_strings: &[&'static [u8]] = &[
        b"got\0nul",
        b"Mary had a little lamb, Little \0"  // Exercises the owned variant
    ];
    for bytes in test_strings.iter() {
        let res = CStrBuf::from_iter(bytes.iter().cloned());
        let err = res.err().unwrap();
        assert_eq!(err.nul_position(), bytes.position_elem(&0u8).unwrap());
        let vec = err.into_bytes();
        assert_eq!(&vec, bytes);
    }
}

#[test]
fn test_c_str_buf_from_str() {
    let c_str = CStrBuf::from_str("").unwrap();
    check_c_str(&c_str, b"");

    let c_str = CStrBuf::from_str("hello").unwrap();
    check_c_str(&c_str, b"hello");

    // Owned variant
    let c_str = CStrBuf::from_str("Mary had a little lamb, Little lamb").unwrap();
    check_c_str(&c_str, b"Mary had a little lamb, Little lamb");

    let res = CStrBuf::from_str("got\0nul");
    let err = res.err().unwrap();
    assert_eq!(err.nul_position(), 3);
    let bytes = err.into_bytes();
    assert_eq!(bytes, b"got\0nul");
}

#[test]
fn test_io_error_from_nul_error() {
    let res = CStrBuf::from_str("got\0nul");
    let err = res.err().unwrap();
    let io_err: IoError = FromError::from_error(err);
    assert_eq!(io_err.kind(), InvalidInput);
}

#[test]
fn test_c_str_buf_from_vec() {
    let test_strings: &[&'static [u8]] = &[
        b"",
        b"foo\xFF",
        b"Mary had a little \xD0\x0D, Little \xD0\x0D"  // Exercises the owned variant
    ];
    for bytes in test_strings.iter() {
        let c_str = CStrBuf::from_vec(bytes.to_vec()).unwrap();
        check_c_str(&c_str, bytes);
    }

    let test_strings: &[&'static [u8]] = &[
        b"got\0nul",
        b"Mary had a little lamb, Little \0"  // Exercises the owned variant
    ];
    for bytes in test_strings.iter() {
        let res = CStrBuf::from_vec(bytes.to_vec());
        let err = res.err().unwrap();
        assert_eq!(err.nul_position(), bytes.position_elem(&0u8).unwrap());
        let vec = err.into_bytes();
        assert_eq!(&vec, bytes);
    }
}

#[test]
fn test_io_error_from_into_c_str_error() {
    let res = CStrBuf::from_vec(b"got\0nul".to_vec());
    let err = res.err().unwrap();
    let io_err: IoError = FromError::from_error(err);
    assert_eq!(io_err.kind(), InvalidInput);
}

#[test]
fn test_c_str_buf_into_vec() {
    let c_str = CStrBuf::from_str("").unwrap();
    let vec = c_str.into_vec();
    assert_eq!(&vec[..], b"");
    let c_str = CStrBuf::from_str("hello").unwrap();
    let vec = c_str.into_vec();
    assert_eq!(&vec[..], b"hello");
    let bytes = b"foo\xFF";
    let c_str = CStrBuf::from_iter(bytes.iter().cloned()).unwrap();
    let vec = c_str.into_vec();
    assert_eq!(&vec[..], bytes);

    // Owned variant
    let c_str = CStrBuf::from_str("Mary had a little lamb, Little lamb").unwrap();
    let vec = c_str.into_vec();
    assert_eq!(&vec[..], &b"Mary had a little lamb, Little lamb"[..]);
    let bytes = b"Mary had a little \xD0\x0D, Little \xD0\x0D";
    let c_str = CStrBuf::from_iter(bytes.iter().cloned()).unwrap();
    let vec = c_str.into_vec();
    assert_eq!(&vec[..], bytes);
}

#[test]
fn test_owned_c_string_to_bytes() {
    let c_str = str_dup("hello");
    assert_eq!(c_str.to_bytes(), b"hello");
    let c_str = str_dup("");
    assert_eq!(c_str.to_bytes(), b"");
    let c_str = bytes_dup(b"foo\xFF");
    assert_eq!(c_str.to_bytes(), b"foo\xFF");
}

#[test]
fn test_owned_c_string_debug() {
    let c_str = str_dup("hello");
    let msg = format!("{:?}", c_str);
    assert_eq!(msg, "\"hello\"");
    let c_str = str_dup("");
    let msg = format!("{:?}", c_str);
    assert_eq!(msg, "\"\"");
    let c_str = bytes_dup(b"foo\xFF");
    let msg = format!("{:?}", c_str);
    assert_eq!(msg, r#""foo\xff""#);
}

#[test]
#[should_panic]
fn test_c_string_new_fail() {
    let _c_str: OwnedCString = unsafe {
        OwnedCString::new(ptr::null(), libc_free)
    };
}
<|endoftext|>


<commit_before>extern crate rspgod;
extern crate postgres;
extern crate rustc_serialize;

use postgres::{Connection, SslMode};
use rspgod::types::{Change};
use rustc_serialize::json;

#[derive(Debug)]
struct TestRecord {
    id:   i32,
    name: String,
}

#[test]
fn sanity_test() {
    with_clean_database(|c| {
        let records = vec![
            TestRecord { id: 1, name: "Michael Baker".to_string() },
            TestRecord { id: 2, name: "Josh Cheek".to_string(),   },
        ];

        for record in records.iter() {
            create_record(c, &record);
        }

        fetch_records(c);
    });
}

#[test]
fn basic_insert() {
    with_slot(|c| {
        let record = TestRecord {id: 1, name: "Michael Baker".to_string(), };
        create_record(c, &record);
        let updates = fetch_updates(c);
        assert_eq!(updates.len(), 1);
        let change:Change = json::decode(&updates[0][..]).unwrap();
        assert!(match change {
            Change::Insert {..} => { true },
            _                   => { false },
        });
    });
}

//
// [TODO] I want to move a lot of these into a utility module when I can figure out how to do that
//

fn fetch_updates(c: &Connection) -> Vec<String> {
    let stmt = c.prepare("SELECT * FROM pg_logical_slot_peek_changes('slot', NULL, NULL)").unwrap();
    let mut result = vec![];
    for r in stmt.query(&[]).unwrap() {
        result.push(r.get(2));
    }
    result
}

fn create_slot(c: &Connection) {
    let stmt = c.prepare("select * from pg_create_logical_replication_slot('slot', 'thingy')").unwrap();
    stmt.execute(&[]).unwrap();
}

fn drop_slot(c: &Connection) {
    let stmt = c.prepare("select pg_drop_replication_slot('slot')").unwrap();
    match stmt.execute(&[]) {
        _ => {},
    }
}

fn with_slot<F>(f: F) where F:Fn(&Connection) -> () {
    with_clean_database(|c| {
        drop_slot(c);
        create_slot(c);
        f(c);
        drop_slot(c);
    });
}

fn with_clean_database<F>(f: F) where F:Fn(&Connection) -> () {
    let c = connection();
    reset_database(&c);
    f(&c);
    drop_database(&c);
}

fn reset_database(c: &Connection) {
    drop_database(&c);
    create_database(&c);
}

fn create_database(c: &Connection) {
    let stmt = c.prepare("create table test_table (id int primary key, name text)").unwrap();
    stmt.execute(&[]).unwrap();
}

fn fetch_records(c: &Connection) -> Vec<TestRecord> {
    let stmt = c.prepare("select id, name from test_table").unwrap();
    let results = stmt.query(&[]).unwrap();
    results.iter().map(|r| {
        TestRecord {
            id:   r.get(0),
            name: r.get(1),
        }
    }).collect()
}

fn create_record(c: &Connection, r: &TestRecord) {
    let stmt = c.prepare("insert into test_table (id, name) values ($1, $2)").unwrap();
    stmt.execute(&[
        &r.id,
        &r.name,
    ]).unwrap();
}

fn drop_database(c: &Connection) {
    let stmt = c.prepare("drop table if exists test_table").unwrap();
    stmt.execute(&[]).unwrap();
}

fn connection_string() -> String {
    match std::env::var("POSTGRES_URL") {
        Ok(val) => val,
        Err(e)  => panic!(format!("You must set the POSTGRES_URL environment variable to point to a running Postgres test database when running automated tests: {}", e)),
    }
}

fn connection() -> Connection {
    match Connection::connect(&connection_string()[..], &SslMode::None) {
        Ok(c)  => c,
        Err(e) => panic!(format!("Could not connect to the test database: {}", e)),
    }
}
<commit_msg>Adds a delete test<commit_after>extern crate rspgod;
extern crate postgres;
extern crate rustc_serialize;

use postgres::{Connection, SslMode};
use rspgod::types::{Change};
use rustc_serialize::json;

#[derive(Debug)]
struct TestRecord {
    id:   i32,
    name: String,
}

#[test]
fn sanity_test() {
    with_clean_database(|c| {
        let records = vec![
            TestRecord { id: 1, name: "Michael Baker".to_string() },
            TestRecord { id: 2, name: "Josh Cheek".to_string(),   },
        ];

        for record in records.iter() {
            create_record(c, &record);
        }

        fetch_records(c);
    });
}

#[test]
fn basic_insert() {
    with_slot(|c| {
        let record = TestRecord {id: 1, name: "Michael Baker".to_string(), };
        create_record(c, &record);
        let updates = fetch_updates(c);
        assert_eq!(updates.len(), 1);
        let change:Change = json::decode(&updates[0][..]).unwrap();
        assert!(match change {
            Change::Insert {..} => { true },
            _                   => { false },
        });
    });
}

#[test]
fn basic_delete() {
    with_slot(|c| {
        let record = TestRecord {id: 1, name: "Michael Baker".to_string(), };
        create_record(c, &record);
        delete_record(c, 1);
        let updates = fetch_updates(c);
        assert_eq!(updates.len(), 2);
        let change:Change = json::decode(&updates[1][..]).unwrap();
        assert!(match change {
            Change::Delete {..} => { true },
            _                   => { false },
        });
    });
}

//
// [TODO] I want to move a lot of these into a utility module when I can figure out how to do that
//

fn fetch_updates(c: &Connection) -> Vec<String> {
    let stmt = c.prepare("SELECT * FROM pg_logical_slot_peek_changes('slot', NULL, NULL)").unwrap();
    let mut result = vec![];
    for r in stmt.query(&[]).unwrap() {
        result.push(r.get(2));
    }
    result
}

fn create_slot(c: &Connection) {
    let stmt = c.prepare("select * from pg_create_logical_replication_slot('slot', 'thingy')").unwrap();
    stmt.execute(&[]).unwrap();
}

fn drop_slot(c: &Connection) {
    let stmt = c.prepare("select pg_drop_replication_slot('slot')").unwrap();
    match stmt.execute(&[]) {
        _ => {},
    }
}

fn with_slot<F>(f: F) where F:Fn(&Connection) -> () {
    with_clean_database(|c| {
        drop_slot(c);
        create_slot(c);
        f(c);
        drop_slot(c);
    });
}

fn with_clean_database<F>(f: F) where F:Fn(&Connection) -> () {
    let c = connection();
    reset_database(&c);
    f(&c);
    drop_database(&c);
}

fn reset_database(c: &Connection) {
    drop_database(&c);
    create_database(&c);
}

fn create_database(c: &Connection) {
    let stmt = c.prepare("create table test_table (id int primary key, name text)").unwrap();
    stmt.execute(&[]).unwrap();
}

fn fetch_records(c: &Connection) -> Vec<TestRecord> {
    let stmt = c.prepare("select id, name from test_table").unwrap();
    let results = stmt.query(&[]).unwrap();
    results.iter().map(|r| {
        TestRecord {
            id:   r.get(0),
            name: r.get(1),
        }
    }).collect()
}

fn create_record(c: &Connection, r: &TestRecord) {
    let stmt = c.prepare("insert into test_table (id, name) values ($1, $2)").unwrap();
    stmt.execute(&[
        &r.id,
        &r.name,
    ]).unwrap();
}

fn delete_record(c: &Connection, id: i32) {
    let stmt = c.prepare("delete from test_table where id = $1").unwrap();
    stmt.execute(&[&id]).unwrap();
}

fn drop_database(c: &Connection) {
    let stmt = c.prepare("drop table if exists test_table").unwrap();
    stmt.execute(&[]).unwrap();
}

fn connection_string() -> String {
    match std::env::var("POSTGRES_URL") {
        Ok(val) => val,
        Err(e)  => panic!(format!("You must set the POSTGRES_URL environment variable to point to a running Postgres test database when running automated tests: {}", e)),
    }
}

fn connection() -> Connection {
    match Connection::connect(&connection_string()[..], &SslMode::None) {
        Ok(c)  => c,
        Err(e) => panic!(format!("Could not connect to the test database: {}", e)),
    }
}
<|endoftext|>


<commit_before>use std::f64::consts::PI;
use turtle::Turtle;

pub fn a(turtle: &mut Turtle, font_size: f64) {
    turtle.right(30.0);
    turtle.forward(1.25_f64.sqrt() * font_size);
    turtle.right(120.0);
    turtle.forward(1.25_f64.sqrt() * font_size);
    turtle.pen_up();
    turtle.backward(1.25_f64.sqrt() * font_size / 2.0);
    turtle.right(120.0);
    turtle.pen_down();
    turtle.forward(font_size * 0.56);
    turtle.pen_up();
    turtle.backward(font_size * 1.56);
    turtle.right(90.0);
    turtle.backward(font_size / 2.0);
}

pub fn b(turtle: &mut Turtle, font_size: f64) {
    turtle.forward(font_size);
    turtle.right(90.0);
    turtle.forward(font_size / 2.0);
    for _ in 0..50 {
        turtle.forward(PI / 200.0 * font_size);
        turtle.right(3.6);
    }
    turtle.forward(font_size / 2.0);
    turtle.backward(font_size / 2.0);
    turtle.right(180.0);
    for _ in 0..50 {
        turtle.forward(PI / 200.0 * font_size);
        turtle.right(3.6);
    }
    turtle.forward(font_size / 2.0);
    turtle.pen_up();
    turtle.backward(font_size * 1.5);
    turtle.right(90.0);
}

pub fn c(turtle: &mut Turtle, font_size: f64) {
    turtle.pen_up();
    turtle.forward(font_size);
    turtle.right(90.0);
    turtle.forward(0.5 * font_size);
    turtle.pen_down();
    for _ in 0..50 {
        turtle.backward(PI / 100.0 * font_size);
        turtle.left(3.6);
    }
    turtle.pen_up();
    turtle.backward(font_size / 2.0);
    turtle.right(90.0);
}

pub fn d(turtle: &mut Turtle, font_size: f64) {
    turtle.forward(font_size);
    turtle.right(90.0);
    for _ in 0..50 {
        turtle.forward(PI / 100.0 * font_size);
        turtle.right(3.6);
    }
    turtle.pen_up();
    turtle.backward(font_size);
    turtle.right(90.0);
}

pub fn e(turtle: &mut Turtle, font_size: f64) {
    turtle.forward(font_size);
    turtle.right(90.0);
    turtle.forward(font_size);
    turtle.right(90.0);
    turtle.pen_up();
    turtle.forward(font_size / 2.0);
    turtle.pen_down();
    turtle.right(90.0);
    turtle.forward(font_size);
    turtle.right(90.0);
    turtle.pen_up();
    turtle.backward(font_size / 2.0);
    turtle.right(90.0);
    turtle.pen_down();
    turtle.forward(font_size);
    turtle.pen_up();
    turtle.forward(font_size / 2.0);
    turtle.left(90.0);
}

pub fn f(turtle: &mut Turtle, font_size: f64) {
    turtle.forward(font_size);
    turtle.right(90.0);
    turtle.forward(font_size);
    turtle.right(90.0);
    turtle.pen_up();
    turtle.forward(font_size / 2.0);
    turtle.pen_down();
    turtle.right(90.0);
    turtle.forward(font_size);
    turtle.right(90.0);
    turtle.pen_up();
    turtle.backward(font_size / 2.0);
    turtle.right(90.0);
    turtle.pen_up();
    turtle.forward(font_size * 1.5);
    turtle.left(90.0);
}

pub fn g(turtle: &mut Turtle, font_size: f64) {
    turtle.pen_up();
    turtle.forward(0.5 * font_size);
    turtle.right(90.0);
    turtle.forward(0.5 * font_size);
    turtle.pen_down();
    turtle.forward(0.5 * font_size);
    turtle.right(90.0);
    for i in 0..100 {
        if i == 87 {
            turtle.pen_up()
        }
        turtle.forward(PI / 100.0 * font_size);
        turtle.right(3.6);
    }
    turtle.forward(font_size / 2.0);
    turtle.left(90.0);
    turtle.forward(font_size / 2.0);
    turtle.left(90.0);
}

pub fn h(turtle: &mut Turtle, font_size: f64) {
    turtle.forward(font_size);
    turtle.pen_up();
    turtle.right(90.0);
    turtle.forward(font_size);
    turtle.pen_down();
    turtle.right(90.0);
    turtle.forward(font_size);
    turtle.backward(font_size / 2.0);
    turtle.right(90.0);
    turtle.forward(font_size);
    turtle.right(180.0);
    turtle.pen_up();
    turtle.forward(font_size * 1.5);
    turtle.left(90.0);
    turtle.backward(font_size / 2.0);
}

pub fn i(turtle: &mut Turtle, font_size: f64) {
    turtle.forward(font_size * 0.8);
    turtle.pen_up();
    turtle.forward(font_size * 0.1);
    turtle.pen_down();
    turtle.forward(font_size * 0.1);
    turtle.pen_up();
    turtle.backward(font_size);
    turtle.right(90.0);
    turtle.forward(font_size / 2.0);
    turtle.left(90.0);
}

pub fn j(turtle: &mut Turtle, font_size: f64) {
    turtle.pen_up();
    turtle.forward(font_size / 2.0);
    turtle.pen_down();
    turtle.left(180.0);
    for _ in 0..50 {
        turtle.forward(PI / 100.0 * font_size);
        turtle.left(3.6);
    }
    turtle.forward(font_size / 2.0);
    turtle.pen_up();
    turtle.backward(font_size);
    turtle.right(90.0);
    turtle.forward(font_size / 2.0);
    turtle.left(90.0);
}

pub fn k(turtle: &mut Turtle, font_size: f64) {
    turtle.forward(font_size);
    turtle.right(90.0);
    turtle.pen_up();
    turtle.forward(font_size * 0.88);
    turtle.pen_down();
    turtle.left(30.0);
    turtle.backward(1.25_f64.sqrt() * font_size * 0.9);
    turtle.right(60.0);
    turtle.forward(1.25_f64.sqrt() * font_size * 0.9);
    turtle.left(30.0);
    turtle.pen_up();
    turtle.forward(font_size / 2.0);
    turtle.left(90.0);
}

pub fn l(turtle: &mut Turtle, font_size: f64) {
    turtle.forward(font_size);
    turtle.backward(font_size);
    turtle.right(90.0);
    turtle.forward(font_size / 2.0);
    turtle.pen_up();
    turtle.forward(font_size / 2.0);
    turtle.left(90.0);
}

pub fn m(turtle: &mut Turtle, font_size: f64) {
    turtle.forward(font_size);
    turtle.left(30.0);
    turtle.backward(1.25_f64.sqrt() * font_size);
    turtle.right(60.0);
    turtle.forward(1.25_f64.sqrt() * font_size);
    turtle.left(30.0);
    turtle.backward(font_size);
    turtle.right(90.0);
    turtle.pen_up();
    turtle.forward(font_size / 2.0);
    turtle.left(90.0);
}

pub fn n(turtle: &mut Turtle, font_size: f64) {
    turtle.forward(font_size);
    turtle.left(45.0);
    turtle.backward(2_f64.sqrt() * font_size);
    turtle.right(45.0);
    turtle.forward(font_size);
    turtle.pen_up();
    turtle.backward(font_size);
    turtle.right(90.0);
    turtle.forward(font_size / 2.0);
    turtle.left(90.0);
}

pub fn o(turtle: &mut Turtle, font_size: f64) {
    turtle.right(90.0);
    turtle.pen_up();
    turtle.forward(0.5 * font_size);
    turtle.pen_down();
    for _ in 0..100 {
        turtle.forward(PI / 100.0 * font_size);
        turtle.left(3.6);
    }
    turtle.pen_up();
    turtle.forward(font_size);
    turtle.left(90.0);
}

pub fn p(turtle: &mut Turtle, font_size: f64) {
    turtle.forward(font_size);
    turtle.right(90.0);
    turtle.forward(font_size / 2.0);
    for _ in 0..50 {
        turtle.forward(PI / 200.0 * font_size);
        turtle.right(3.6);
    }
    turtle.forward(font_size / 2.0);
    turtle.pen_up();
    turtle.backward(font_size * 1.25);
    turtle.right(90.0);
    turtle.backward(font_size / 2.0);
}

pub fn r(turtle: &mut Turtle, font_size: f64) {
    turtle.forward(font_size);
    turtle.right(90.0);
    turtle.forward(font_size / 3.0);
    for _ in 0..50 {
        turtle.forward(PI / 200.0 * font_size);
        turtle.right(3.6);
    }
    turtle.forward(font_size / 3.0);
    turtle.left(135.0);
    turtle.forward(1.25_f64.sqrt() * font_size * 0.625);
    turtle.right(135.0);
    turtle.pen_up();
    turtle.backward(font_size * 0.5);
    turtle.right(90.0);
}

pub fn u(turtle: &mut Turtle, font_size: f64) {
    turtle.pen_up();
    turtle.forward(font_size);
    turtle.pen_down();
    turtle.backward(font_size / 2.0);
    turtle.left(180.0);
    for _ in 0..50 {
        turtle.forward(PI / 100.0 * font_size);
        turtle.left(3.6);
    }
    turtle.forward(font_size / 2.0);
    turtle.pen_up();
    turtle.left(180.0);
    turtle.forward(font_size);
    turtle.left(90.0);
    turtle.forward(font_size / 2.0);
    turtle.left(90.0);
}

pub fn w(turtle: &mut Turtle, font_size: f64) {
    turtle.pen_up();
    turtle.forward(font_size);
    turtle.pen_down();
    turtle.backward(font_size * 2.0 / 3.0);
    turtle.left(180.0);
    for _ in 0..50 {
        turtle.forward(PI / 200.0 * font_size);
        turtle.left(3.6);
    }
    turtle.left(180.0);
    for _ in 0..50 {
        turtle.forward(PI / 200.0 * font_size);
        turtle.left(3.6);
    }
    turtle.forward(font_size * 2.0 / 3.0);
    turtle.pen_up();
    turtle.left(180.0);
    turtle.forward(font_size);
    turtle.left(90.0);
    turtle.forward(font_size / 2.0);
    turtle.left(90.0);
}
<commit_msg>chore: delete old file<commit_after><|endoftext|>


<commit_before>extern crate user32;
extern crate winapi;
extern crate kernel32;
extern crate libc;
extern crate gdi32;
use std::ffi::OsStr;
// use std::io::Error;
use std::iter::once;
use std::os::windows::ffi::OsStrExt;
// use std::ptr::null_mut;
use std::mem;
use self::winapi::winuser::{WNDCLASSW,CS_HREDRAW,CS_VREDRAW,WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,MSG,WS_VISIBLE,PM_REMOVE,WM_PAINT,WM_SIZE,WM_CLOSE,WM_ACTIVATEAPP,WM_DESTROY,PAINTSTRUCT};
use self::winapi::windef::{HWND,HBRUSH,HMENU};
use self::winapi::minwindef::{UINT,WPARAM,LPARAM,LRESULT,LPVOID};
use self::winapi::wingdi::{WHITENESS,BLACKNESS, PATINVERT};

static mut GLOBAL_RUNNING: bool = true; //TODO: Whats the correct way to scope something like this?

pub fn main() {

    let window_class_name = to_wide_string("RustHeroWindowClass").as_ptr();
    let h_instance = unsafe {
        kernel32::GetModuleHandleW(0 as winapi::winnt::LPCWSTR)
    };

    let mut window = WNDCLASSW {
        style: CS_HREDRAW | CS_VREDRAW,
        lpfnWndProc: Some(winproc),
        cbClsExtra: 0,
        cbWndExtra: 0,
        hInstance: h_instance,
        hIcon: unsafe { user32::LoadIconW(h_instance, winapi::winuser::IDI_APPLICATION) },
        hCursor: unsafe { user32::LoadCursorW(h_instance, winapi::winuser::IDI_APPLICATION) },
        hbrBackground: 0 as HBRUSH,
        lpszMenuName: to_wide_string("RustHeroMenu").as_ptr(),
        lpszClassName: window_class_name
    };

    let ret = unsafe { //TODO: Can we use Options to get rid of all these unsafes?
        user32::RegisterClassW(&mut window)
    };

    if ret == 0 {
        println!("Registering the window class failed.");
        return
    }

    unsafe {
         let window_handle = user32::CreateWindowExW(
            0,
            window_class_name,
            to_wide_string("Rust Hero").as_ptr(),
            WS_VISIBLE|WS_OVERLAPPEDWINDOW,
            CW_USEDEFAULT,
            CW_USEDEFAULT,
            CW_USEDEFAULT,
            CW_USEDEFAULT,
            0 as HWND,
            0 as HMENU,
            h_instance,
            0 as LPVOID
        );

        if window_handle.is_null() {
            println!("Failed to create window.");
            return;
        }

        while GLOBAL_RUNNING {
            let mut msg: MSG = mem::uninitialized();
            while user32::PeekMessageW(&mut msg, window_handle,0,0,PM_REMOVE) != 0 {
                user32::TranslateMessage(&mut msg);
                user32::DispatchMessageW(&mut msg);
            }
        }
    }
}

fn to_wide_string(str: &str) -> Vec<u16> {
    OsStr::new(str).encode_wide().chain(once(0)).collect()
}

 pub unsafe extern "system" fn winproc(hwnd :HWND, msg :UINT, w_param :WPARAM, l_param :LPARAM) -> LRESULT {
        match msg {
            WM_SIZE => { println!("WM_SIZE"); },
            WM_CLOSE => {  GLOBAL_RUNNING = false;  },
            WM_DESTROY => { GLOBAL_RUNNING = false; },
            WM_ACTIVATEAPP => { println!("WM_ACTIVATEAPP"); },
            WM_PAINT => {
                let mut paint: PAINTSTRUCT = mem::uninitialized();
                let hdc = user32::BeginPaint(hwnd, &mut paint);
                let x = paint.rcPaint.left;
                let y = paint.rcPaint.top;
                let width = paint.rcPaint.right - paint.rcPaint.left;
                let height = paint.rcPaint.bottom - paint.rcPaint.top;
                gdi32::PatBlt(hdc, x, y, width, height, PATINVERT);
            },
            _ => { return user32::DefWindowProcW(hwnd, msg, w_param, l_param); }
        };
        0
    }<commit_msg>Awww yiss weird gradient<commit_after>extern crate user32;
extern crate winapi;
extern crate kernel32;
extern crate libc;
extern crate gdi32;
use std::ffi::OsStr;
use std::iter::once;
use std::os::windows::ffi::OsStrExt;
use std::mem;

use self::winapi::winuser::*;
use self::winapi::windef::*;
use self::winapi::minwindef::*;
use self::winapi::wingdi::*;
use self::winapi::winnt::*;

struct MyBitmapType {
    info: BITMAPINFO
}

static mut GLOBAL_RUNNING: bool = true;
static mut WIN32_BITMAP_INFO: MyBitmapType = MyBitmapType {
    info: BITMAPINFO {
        bmiHeader: BITMAPINFOHEADER {
            biSize: 0,
            biWidth: 0,
            biHeight: 0,
            biPlanes: 1,
            biBitCount: 32,
            biCompression: BI_RGB,
            biSizeImage: 0,
            biXPelsPerMeter: 0,
            biYPelsPerMeter: 0,
            biClrUsed: 0,
            biClrImportant: 0
        } ,
        bmiColors: []
    }
};

static mut BITMAP_MEMORY: LPVOID = 0 as LPVOID;

unsafe fn win32_resize_dib_section(width: i32, height: i32) -> () {

    WIN32_BITMAP_INFO.info.bmiHeader.biSize = mem::size_of::<BITMAPINFOHEADER>() as u32;
    WIN32_BITMAP_INFO.info.bmiHeader.biWidth = width;
    WIN32_BITMAP_INFO.info.bmiHeader.biHeight = -height; //Top-down coord

    let bytes_per_pixel = 4;
    let bitmap_memory_size = (width*height)*bytes_per_pixel;

    if BITMAP_MEMORY != 0 as LPVOID {
        kernel32::VirtualFree(BITMAP_MEMORY, 0 as u64, MEM_RELEASE);
    }

    BITMAP_MEMORY = kernel32::VirtualAlloc(0 as LPVOID, bitmap_memory_size as u64, MEM_COMMIT, PAGE_READWRITE);

    let pitch = width*bytes_per_pixel;
    let mut row: *mut u8 = BITMAP_MEMORY as *mut u8;
    for y in 0..height {
        let mut pixel: *mut u32 = row as *mut u32;
        for x in 0..width {
            //*pixel = 255 << 16; //red
            *pixel = ((x as u32) << 0) + ((y as u32) << 8);  //green
            // *pixel = 255 << 0; //blue
            pixel = pixel.offset(1);

        };
        row = row.offset(pitch as isize);
    };

}

unsafe fn win32_update_window(device_context: HDC, window_width: i32, window_height: i32) {
    gdi32::StretchDIBits(device_context,
        0, 0, WIN32_BITMAP_INFO.info.bmiHeader.biWidth, WIN32_BITMAP_INFO.info.bmiHeader.biHeight.abs(), //We have a negative value for this to specify top-down bitmap
        0, 0, window_width, window_height,
        BITMAP_MEMORY,
        &WIN32_BITMAP_INFO.info,
        DIB_RGB_COLORS,
        SRCCOPY);
}

pub fn main() {

    unsafe {
        WIN32_BITMAP_INFO.info.bmiHeader.biWidth = 1080;
        WIN32_BITMAP_INFO.info.bmiHeader.biHeight = 640;
    }

    let window_class_name = to_wide_string("RustHeroWindowClass").as_ptr();
    let h_instance = unsafe {
        kernel32::GetModuleHandleW(0 as winapi::winnt::LPCWSTR)
    };

    let mut window = WNDCLASSW {
        style: CS_HREDRAW | CS_VREDRAW | CS_OWNDC,
        lpfnWndProc: Some(winproc),
        cbClsExtra: 0,
        cbWndExtra: 0,
        hInstance: h_instance,
        hIcon: unsafe { user32::LoadIconW(h_instance, winapi::winuser::IDI_APPLICATION) },
        hCursor: unsafe { user32::LoadCursorW(h_instance, winapi::winuser::IDI_APPLICATION) },
        hbrBackground: 0 as HBRUSH,
        lpszMenuName: to_wide_string("RustHeroMenu").as_ptr(),
        lpszClassName: window_class_name
    };

    let ret = unsafe { //TODO: Can we use Options to get rid of all these unsafes?
        user32::RegisterClassW(&mut window)
    };

    if ret == 0 {
        println!("Registering the window class failed.");
        return
    }

    unsafe {
         let window_handle = user32::CreateWindowExW(
            0,
            window_class_name,
            to_wide_string("Rust Hero").as_ptr(),
            WS_VISIBLE|WS_OVERLAPPEDWINDOW,
            CW_USEDEFAULT,
            CW_USEDEFAULT,
            CW_USEDEFAULT,
            CW_USEDEFAULT,
            0 as HWND,
            0 as HMENU,
            h_instance,
            0 as LPVOID
        );

        if window_handle.is_null() {
            println!("Failed to create window.");
            return;
        }

        let device_context = user32::GetDC(window_handle);

        while GLOBAL_RUNNING {
            let mut msg: MSG = mem::uninitialized();
            while user32::PeekMessageW(&mut msg, window_handle,0,0,PM_REMOVE) != 0 {
                user32::TranslateMessage(&mut msg);
                user32::DispatchMessageW(&mut msg);
            }

            // win32_update_window(device_context, )
        }
    }
}

fn to_wide_string(str: &str) -> Vec<u16> {
    OsStr::new(str).encode_wide().chain(once(0)).collect()
}

 pub unsafe extern "system" fn winproc(hwnd :HWND, msg :UINT, w_param :WPARAM, l_param :LPARAM) -> LRESULT {
        match msg {
            WM_SIZE => {
                println!("WM_SIZE");
                let mut client_rect: RECT = mem::uninitialized();
                user32::GetClientRect(hwnd, &mut client_rect);
                win32_resize_dib_section(client_rect.right - client_rect.left, client_rect.bottom - client_rect.top);
            },
            WM_CLOSE => {  GLOBAL_RUNNING = false;  },
            WM_DESTROY => { GLOBAL_RUNNING = false; },
            WM_ACTIVATEAPP => { println!("WM_ACTIVATEAPP"); },
            WM_PAINT => {
                let mut paint: PAINTSTRUCT = mem::uninitialized();
                let hdc = user32::BeginPaint(hwnd, &mut paint);
                let mut client_rect: RECT = mem::uninitialized();
                user32::GetClientRect(hwnd, &mut client_rect);
                win32_update_window(hdc, client_rect.right, client_rect.bottom);
                user32::EndPaint(hwnd, &paint);
            },
            _ => { return user32::DefWindowProcW(hwnd, msg, w_param, l_param); }
        };
        0
    }<|endoftext|>


<commit_before>use crate::prelude::*;
use winapi::shared::guiddef;

#[cfg(feature = "guid")]
impl Uuid {
    /// Attempts to create a [`Uuid`] from a little endian winapi `GUID`
    ///
    /// [`Uuid`]: ../struct.Uuid.html
    pub fn from_guid(guid: guiddef::GUID) -> Self {
        let Ok(uuid) = Uuid::from_fields_le(
            guid.Data1 as u32,
            guid.Data2 as u16,
            guid.Data3 as u16,
            &(guid.Data4 as [u8; 8]),
        );

        uuid
    }

    /// Converts a [`Uuid`] into a little endian winapi `GUID`
    ///
    /// [`Uuid`]: ../struct.Uuid.html
    pub fn to_guid(&self) -> guiddef::GUID {
        let (data1, data2, data3, data4) = self.to_fields_le();

        guiddef::GUID {
            Data1: data1,
            Data2: data2,
            Data3: data3,
            Data4: *data4,
        }
    }
}

#[cfg(feature = "guid")]
#[cfg(test)]
mod tests {
    use super::*;

    use crate::std::string::ToString;
    use winapi::shared::guiddef;

    #[test]
    fn test_from_guid() {
        let guid = guiddef::GUID {
            Data1: 0x4a35229d,
            Data2: 0x5527,
            Data3: 0x4f30,
            Data4: [0x86, 0x47, 0x9d, 0xc5, 0x4e, 0x1e, 0xe1, 0xe8],
        };

        let uuid = Uuid::from_guid(guid).unwrap();
        assert_eq!(
            "9d22354a-2755-304f-8647-9dc54e1ee1e8",
            uuid.to_hyphenated().to_string()
        );
    }

    #[test]
    fn test_guid_roundtrip() {
        let guid_in = guiddef::GUID {
            Data1: 0x4a35229d,
            Data2: 0x5527,
            Data3: 0x4f30,
            Data4: [0x86, 0x47, 0x9d, 0xc5, 0x4e, 0x1e, 0xe1, 0xe8],
        };

        let uuid = Uuid::from_guid(guid_in).unwrap();
        let guid_out = uuid.to_guid();

        assert_eq!(
            (guid_in.Data1, guid_in.Data2, guid_in.Data3, guid_in.Data4),
            (
                guid_out.Data1,
                guid_out.Data2,
                guid_out.Data3,
                guid_out.Data4
            )
        );
    }
}
<commit_msg>fix error<commit_after>use crate::prelude::*;
use winapi::shared::guiddef;

#[cfg(feature = "guid")]
impl Uuid {
    /// Converts a little endian winapi `GUID` into a [`Uuid`]
    ///
    /// [`Uuid`]: ../struct.Uuid.html
    pub fn from_guid(guid: guiddef::GUID) -> Self {
        Uuid::from_fields_le(
            guid.Data1 as u32,
            guid.Data2 as u16,
            guid.Data3 as u16,
            &(guid.Data4 as [u8; 8]),
        ).unwrap() // Note: The result in this particular instance is always Ok, so we can
                   //       safely unwrap.
    }

    /// Converts a [`Uuid`] into a little endian winapi `GUID`
    ///
    /// [`Uuid`]: ../struct.Uuid.html
    pub fn to_guid(&self) -> guiddef::GUID {
        let (data1, data2, data3, data4) = self.to_fields_le();

        guiddef::GUID {
            Data1: data1,
            Data2: data2,
            Data3: data3,
            Data4: *data4,
        }
    }
}

#[cfg(feature = "guid")]
#[cfg(test)]
mod tests {
    use super::*;

    use crate::std::string::ToString;
    use winapi::shared::guiddef;

    #[test]
    fn test_from_guid() {
        let guid = guiddef::GUID {
            Data1: 0x4a35229d,
            Data2: 0x5527,
            Data3: 0x4f30,
            Data4: [0x86, 0x47, 0x9d, 0xc5, 0x4e, 0x1e, 0xe1, 0xe8],
        };

        let uuid = Uuid::from_guid(guid).unwrap();
        assert_eq!(
            "9d22354a-2755-304f-8647-9dc54e1ee1e8",
            uuid.to_hyphenated().to_string()
        );
    }

    #[test]
    fn test_guid_roundtrip() {
        let guid_in = guiddef::GUID {
            Data1: 0x4a35229d,
            Data2: 0x5527,
            Data3: 0x4f30,
            Data4: [0x86, 0x47, 0x9d, 0xc5, 0x4e, 0x1e, 0xe1, 0xe8],
        };

        let uuid = Uuid::from_guid(guid_in).unwrap();
        let guid_out = uuid.to_guid();

        assert_eq!(
            (guid_in.Data1, guid_in.Data2, guid_in.Data3, guid_in.Data4),
            (
                guid_out.Data1,
                guid_out.Data2,
                guid_out.Data3,
                guid_out.Data4
            )
        );
    }
}
<|endoftext|>