<commit_before>#![feature(async_await, await_macro, futures_api, arbitrary_self_types)]

#[cfg(test)]
mod tests {
    use std::future::Future;
    use std::pin::Pin;
    use std::task::{Waker, Poll};
    use std::time::{Duration, Instant};

    use futures::compat::Future01CompatExt;
    use futures::executor::{block_on, ThreadPoolBuilder};
    use futures::prelude::{FutureExt, TryFutureExt};
    use tokio::timer::Delay;

    use timer::{Guard, Timer};

    struct Myfuture {
        timer: Timer,
        guard: Option<Guard>,
    }

    impl Future for Myfuture {
        type Output = bool;

        fn poll(self: Pin<&mut Self>, waker: &Waker) -> Poll<Self::Output> {
            if self.guard.is_some() {
                println!("\nMyfuture: I am ready");
                return Poll::Ready(true);
            } else {
                println!("\nMyfuture: I am not ready");
                let waker = waker.clone();
                Pin::get_mut(self).guard = Some(self.timer.schedule_with_delay(
                    chrono::Duration::seconds(1),
                    move || {
                        waker.wake();
                    },
                ));
                return Poll::Pending;
            }
        }
    }

    #[test]
    fn executor_current_thread() {
        assert_eq!(
            true,
            block_on(
                async {
                    await!(Myfuture {
                        timer: Timer::new(),
                        guard: None,
                    })
                }
            )
        );
    }

    #[test]
    fn executor_threadpool() {
        let mut pool = ThreadPoolBuilder::new().pool_size(1).create().unwrap();
        assert_eq!(
            true,
            pool.run(Myfuture {
                timer: Timer::new(),
                guard: None,
            })
        );
    }

    #[test]
    fn executor_eventloop() {
        tokio::run(
            Myfuture {
                timer: Timer::new(),
                guard: None,
            }
            .map(|x| {
                assert_eq!(true, x);
                ()
            })
            .unit_error()
            // convert futures 0.3 into 0.1 with TryFuture
            .compat(),
        );
    }

    #[test]
    #[should_panic]
    fn job_on_time() {
        let when = Instant::now() + Duration::from_millis(100);
        assert_eq!(
            1,
            // Tokio 0.1's Future doesn't work in Futures 0.3's executor now.
            block_on(Delay::new(when).compat().map(|x| {
                assert_eq!((), x.unwrap());
                1
            }))
        );
    }
}
//[cfg(test)]
<commit_msg>the new future api<commit_after>#![feature(async_await, await_macro, futures_api, arbitrary_self_types)]

#[cfg(test)]
mod tests {
    use std::future::Future;
    use std::pin::Pin;
    use std::task::{Context, Poll};
    use std::time::{Duration, Instant};

    use futures::compat::Future01CompatExt;
    use futures::executor::{block_on, ThreadPoolBuilder};
    use futures::prelude::{FutureExt, TryFutureExt};
    use tokio::timer::Delay;

    use timer::{Guard, Timer};

    struct Myfuture {
        timer: Timer,
        guard: Option<Guard>,
    }

    impl Future for Myfuture {
        type Output = bool;

        fn poll(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Self::Output> {
            if self.guard.is_some() {
                println!("\nMyfuture: I am ready");
                return Poll::Ready(true);
            } else {
                println!("\nMyfuture: I am not ready");
                let waker = cx.waker().clone();
                Pin::get_mut(self).guard = Some(self.timer.schedule_with_delay(
                    chrono::Duration::seconds(1),
                    move || {
                        waker.clone().wake();
                    },
                ));
                return Poll::Pending;
            }
        }
    }

    #[test]
    fn executor_current_thread() {
        assert_eq!(
            true,
            block_on(
                async {
                    await!(Myfuture {
                        timer: Timer::new(),
                        guard: None,
                    })
                }
            )
        );
    }

    #[test]
    fn executor_threadpool() {
        let mut pool = ThreadPoolBuilder::new().pool_size(1).create().unwrap();
        assert_eq!(
            true,
            pool.run(Myfuture {
                timer: Timer::new(),
                guard: None,
            })
        );
    }

    #[test]
    fn executor_eventloop() {
        tokio::run(
            Myfuture {
                timer: Timer::new(),
                guard: None,
            }
            .map(|x| {
                assert_eq!(true, x);
                ()
            })
            .unit_error()
            // convert futures 0.3 into 0.1 with TryFuture
            .compat(),
        );
    }

    #[test]
    #[should_panic]
    fn job_on_time() {
        let when = Instant::now() + Duration::from_millis(100);
        assert_eq!(
            1,
            // Tokio 0.1's Future doesn't work in Futures 0.3's executor now.
            block_on(Delay::new(when).compat().map(|x| {
                assert_eq!((), x.unwrap());
                1
            }))
        );
    }
}
//[cfg(test)]
<|endoftext|>


<commit_before>//! # The Redox OS Kernel, version 2
//!
//! The Redox OS Kernel is a hybrid kernel that supports X86 systems and
//! provides Unix-like syscalls for primarily Rust applications
//!
//! ## Syscalls
//! Syscalls in Redox are often handled by userspace `schemes`.
//! The essential syscalls in Redox are as follows:
//!
//! ### Open
//! `open(path: &str, flags: usize) -> Result<file_descriptor: usize>`
//!
//! Open a file, providing a path as a `&str` and flags, defined elsewhere.
//!
//! Returns a number, known as a file descriptor, that is passed to other syscalls
//!
//! ### Close
//! `close(file_descriptor: usize) -> Result<()>`
//!
//! Close a file descriptor, providing the file descriptor from `open`
//!
//! Returns an error, `EBADF`, if the file descriptor was not found.
//!
//! This potential error is often ignored by userspace
//!
//! ### Duplicate
//! `dup(file_descriptor: usize) -> Result<file_descriptor: usize>`
//!
//! Duplicate a file descriptor, providing the file descriptor from `open`
//!
//! Returns a new file descriptor, or an error
//!
//! ### Read
//! `read(file_descriptor: usize, buffer: &mut [u8]) -> Result<count: usize>`
//!
//! Read from a file descriptor, providing the file descriptor from `open` and a mutable buffer
//!
//! Returns the number of bytes actually read, or an error
//!
//! ### Write
//! `write(file_descriptor: usize, buffer: &[u8]) -> Result<count: usize>`
//!
//! Write to a file descriptor, providing the file descriptor from `open` and a const buffer
//!
//! Returns the number of bytes actually written, or an error
//!
//! ### Stat
//! `fstat(file_descriptor: usize, stat: &mut Stat) -> Result<()>`
//!
//! Get information from a file descriptor, providing the file descriptor from `open`
//! and a mutable Stat struct, defined elsewhere.
//!
//! Returns an error if the operation failed
//!
//! ### Path
//! `fpath(file_descriptor: usize, buffer: &mut [u8]) -> Result<count: usize>`
//!
//! Read the path of a file descriptor, providing the file descriptor from `open` and
//! a mutable buffer.
//!
//! Returns the number of bytes actually read, or an error
//!
//! The buffer should be 4096 bytes, to ensure that the entire path will fit.
//! An error will be returned, `ENOBUFS`, if the buffer is not long enough for the name.
//! In this case, it is recommended to add one page, 4096 bytes, to the buffer and retry.

#![feature(alloc)]
#![feature(collections)]
#![feature(const_fn)]
#![feature(question_mark)]
#![no_std]

#[macro_use]
extern crate bitflags;

use arch::interrupt::{enable_interrupts, halt};

/// Architecture specific items (test)
#[cfg(test)]
#[macro_use]
extern crate arch_test as arch;

/// Architecture specific items (x86_64)
#[cfg(all(not(test), target_arch = "x86_64"))]
#[macro_use]
extern crate arch_x86_64 as arch;

/// Bump allocator
#[cfg(all(not(test), target_arch = "x86_64"))]
extern crate bump_allocator;

extern crate alloc;
#[macro_use]
extern crate collections;

/// Context management
pub mod context;

/// Schemes, filesystem handlers
pub mod scheme;

/// Syscall handlers
pub mod syscall;

/// Tests
#[cfg(test)]
pub mod tests;

#[no_mangle]
pub extern fn kmain() {
    println!("TEST");

    println!("{:?}", syscall::open(b"debug:", 0));
    println!("{:?}", syscall::open(b"debug:", 0));
    println!("{:?}", syscall::open(b"debug:", 0));

    loop {
        unsafe {
            enable_interrupts();
            halt();
        }
        println!("{:?}", syscall::write(1, b"HALT\n"));
    }
}
<commit_msg>Cleanup, use spinlock for allocator<commit_after>//! # The Redox OS Kernel, version 2
//!
//! The Redox OS Kernel is a hybrid kernel that supports X86 systems and
//! provides Unix-like syscalls for primarily Rust applications
//!
//! ## Syscalls
//! Syscalls in Redox are often handled by userspace `schemes`.
//! The essential syscalls in Redox are as follows:
//!
//! ### Open
//! `open(path: &str, flags: usize) -> Result<file_descriptor: usize>`
//!
//! Open a file, providing a path as a `&str` and flags, defined elsewhere.
//!
//! Returns a number, known as a file descriptor, that is passed to other syscalls
//!
//! ### Close
//! `close(file_descriptor: usize) -> Result<()>`
//!
//! Close a file descriptor, providing the file descriptor from `open`
//!
//! Returns an error, `EBADF`, if the file descriptor was not found.
//!
//! This potential error is often ignored by userspace
//!
//! ### Duplicate
//! `dup(file_descriptor: usize) -> Result<file_descriptor: usize>`
//!
//! Duplicate a file descriptor, providing the file descriptor from `open`
//!
//! Returns a new file descriptor, or an error
//!
//! ### Read
//! `read(file_descriptor: usize, buffer: &mut [u8]) -> Result<count: usize>`
//!
//! Read from a file descriptor, providing the file descriptor from `open` and a mutable buffer
//!
//! Returns the number of bytes actually read, or an error
//!
//! ### Write
//! `write(file_descriptor: usize, buffer: &[u8]) -> Result<count: usize>`
//!
//! Write to a file descriptor, providing the file descriptor from `open` and a const buffer
//!
//! Returns the number of bytes actually written, or an error
//!
//! ### Stat
//! `fstat(file_descriptor: usize, stat: &mut Stat) -> Result<()>`
//!
//! Get information from a file descriptor, providing the file descriptor from `open`
//! and a mutable Stat struct, defined elsewhere.
//!
//! Returns an error if the operation failed
//!
//! ### Path
//! `fpath(file_descriptor: usize, buffer: &mut [u8]) -> Result<count: usize>`
//!
//! Read the path of a file descriptor, providing the file descriptor from `open` and
//! a mutable buffer.
//!
//! Returns the number of bytes actually read, or an error
//!
//! The buffer should be 4096 bytes, to ensure that the entire path will fit.
//! An error will be returned, `ENOBUFS`, if the buffer is not long enough for the name.
//! In this case, it is recommended to add one page, 4096 bytes, to the buffer and retry.

#![feature(alloc)]
#![feature(collections)]
#![feature(const_fn)]
#![feature(question_mark)]
#![no_std]

#[macro_use]
extern crate bitflags;

use arch::interrupt::{enable_interrupts, halt};

/// Architecture specific items (test)
#[cfg(test)]
#[macro_use]
extern crate arch_test as arch;

/// Architecture specific items (x86_64)
#[cfg(all(not(test), target_arch = "x86_64"))]
#[macro_use]
extern crate arch_x86_64 as arch;

extern crate alloc;
#[macro_use]
extern crate collections;

/// Context management
pub mod context;

/// Schemes, filesystem handlers
pub mod scheme;

/// Syscall handlers
pub mod syscall;

/// Tests
#[cfg(test)]
pub mod tests;

#[no_mangle]
pub extern fn kmain() {
    println!("TEST");

    println!("{:?}", syscall::open(b"debug:", 0));
    println!("{:?}", syscall::open(b"debug:", 0));
    println!("{:?}", syscall::open(b"debug:", 0));

    loop {
        unsafe {
            enable_interrupts();
            halt();
        }
        println!("{:?}", syscall::write(1, b"HALT\n"));
    }
}
<|endoftext|>


<commit_before>extern crate piston;
extern crate graphics;
extern crate glutin_window;
extern crate opengl_graphics;

use piston::window::WindowSettings;
use piston::event_loop::*;
use piston::input::*;
use glutin_window::GlutinWindow as Window;
use opengl_graphics::{ GlGraphics, OpenGL };

struct App {
    gl: GlGraphics,
    triangles: Vec<[[f64; 2]; 4]>
}

impl App {
    fn render(&mut self, args: &RenderArgs) {
        use graphics::*;

        const WHITE: [f32; 4] = [1.0, 1.0, 1.0, 1.0];
        const BLACK: [f32; 4] = [0.0, 0.0, 0.0, 1.0];

        let triangles = &self.triangles;

        self.gl.draw(args.viewport(), |c, gl| {
            clear(WHITE, gl);

            let transform = c.transform.trans(0.0, 0.0);

            for t in triangles {
              polygon(BLACK, t, transform, gl);
            }
        });
    }
}

fn sub_triangles(v: [[f64; 2]; 4]) -> Vec<[[f64; 2]; 4]> {
    let (a, b, c, d) = (v[0], v[1], v[2], v[3]); // Vector destructuring is not yet stable.

    vec![
        [[a[0] + ((b[0] - a[0]) / 2.0), a[1]],
         [b[0] - ((b[0] - c[0]) / 2.0), b[1] - ((b[1] - c[1]) / 2.0)],
         [a[0] + ((c[0] - a[0]) / 2.0), a[1] - ((a[1] - c[1]) / 2.0)],
         [a[0] + ((b[0] - a[0]) / 2.0), a[1]]],
        [[a[0], a[1]],
         [a[0] + ((b[0] - a[0]) / 2.0), a[1]],
         [a[0] + ((c[0] - a[0]) / 2.0), a[1] - ((a[1] - c[1]) / 2.0)],
         [a[0], a[1]]],
        [[a[0] + ((b[0] - a[0]) / 2.0), a[1]],
         [b[0], b[1]],
         [b[0] - ((b[0] - c[0]) / 2.0), b[1] - ((b[1] - c[1]) / 2.0)],
         [a[0] + ((b[0] - a[0]) / 2.0), a[1]]],
        [
         [a[0] + ((c[0] - a[0]) / 2.0), a[1] - ((a[1] - c[1]) / 2.0)],
         [b[0] - ((b[0] - c[0]) / 2.0), b[1] - ((b[1] - c[1]) / 2.0)],
         [c[0], c[1]],
         [a[0] + ((c[0] - a[0]) / 2.0), a[1] - ((a[1] - c[1]) / 2.0)]]]
}

fn sierpinski(depth: i32, vertices: [[f64; 2]; 4]) -> Vec<[[f64; 2]; 4]> {
    let mut triangles = vec![];

    match depth {
        0 => triangles,
        d @ _ => {
            let sub_tris = sub_triangles(vertices);

            triangles.push(sub_tris[0]);

            for sub_tri in &sub_tris[1..] {
                for t in sierpinski(d - 1, *sub_tri) {
                    triangles.push(t);
                }
            }

            triangles
        },
    }
}

fn main() {
    let opengl = OpenGL::V3_2;

    let window: Window = WindowSettings::new(
        "Sierpinski-Triangle",
        [1000, 800])
        .opengl(opengl)
        .exit_on_esc(true)
        .build()
        .unwrap();

    let triangles = sierpinski(8, [[50.0, 750.0], [950.0, 750.0],
                                   [500.0, 50.0], [50.0, 750.0]]);

    let mut app = App{gl: GlGraphics::new(opengl), triangles: triangles};

    for e in window.events().max_fps(1) {
        if let Some(r) = e.render_args() {
            app.render(&r);
        }
    }
}
<commit_msg>Refactored vertice calculation<commit_after>extern crate piston;
extern crate graphics;
extern crate glutin_window;
extern crate opengl_graphics;

use piston::window::WindowSettings;
use piston::event_loop::*;
use piston::input::*;
use glutin_window::GlutinWindow as Window;
use opengl_graphics::{ GlGraphics, OpenGL };

struct App {
    gl: GlGraphics,
    triangles: Vec<[[f64; 2]; 4]>
}

impl App {
    fn render(&mut self, args: &RenderArgs) {
        use graphics::*;

        const WHITE: [f32; 4] = [1.0, 1.0, 1.0, 1.0];
        const BLACK: [f32; 4] = [0.0, 0.0, 0.0, 1.0];

        let triangles = &self.triangles;

        self.gl.draw(args.viewport(), |c, gl| {
            clear(WHITE, gl);

            let transform = c.transform.trans(0.0, 0.0);

            for t in triangles {
              polygon(BLACK, t, transform, gl);
            }
        });
    }
}

fn sub_triangles(v: [[f64; 2]; 4]) -> Vec<[[f64; 2]; 4]> {
    let (a, b, c, d) = (v[0], v[1], v[2], v[3]); // Vector destructuring is not yet stable.
    let (sax, say, sbx, sby, scx, scy) = (
            a[0] + ((b[0] - a[0]) / 2.0),
            a[1],
            b[0] - ((b[0] - c[0]) / 2.0),
            b[1] - ((b[1] - c[1]) / 2.0),
            a[0] + ((c[0] - a[0]) / 2.0),
            a[1] - ((a[1] - c[1]) / 2.0));

    vec![
        [[sax, say],
         [sbx, sby],
         [scx, scy],
         [sax, say]],
        [[a[0], a[1]],
         [sax, say],
         [scx, scy],
         [a[0], a[1]]],
        [[sax, say],
         [b[0], b[1]],
         [sbx, sby],
         [sax, say]],
        [[scx, scy],
         [sbx, sby],
         [c[0], c[1]],
         [scx, scy]]]
}

fn sierpinski(depth: i32, vertices: [[f64; 2]; 4]) -> Vec<[[f64; 2]; 4]> {
    let mut triangles = vec![];

    match depth {
        0 => triangles,
        d @ _ => {
            let sub_tris = sub_triangles(vertices);

            triangles.push(sub_tris[0]);

            for sub_tri in &sub_tris[1..] {
                for t in sierpinski(d - 1, *sub_tri) {
                    triangles.push(t);
                }
            }

            triangles
        },
    }
}

fn main() {
    let opengl = OpenGL::V3_2;

    let window: Window = WindowSettings::new(
        "Sierpinski-Triangle",
        [1000, 800])
        .opengl(opengl)
        .exit_on_esc(true)
        .build()
        .unwrap();

    let triangles = sierpinski(8, [[50.0, 750.0], [950.0, 750.0],
                                   [500.0, 50.0], [50.0, 750.0]]);

    let mut app = App{gl: GlGraphics::new(opengl), triangles: triangles};

    for e in window.events().max_fps(1) {
        if let Some(r) = e.render_args() {
            app.render(&r);
        }
    }
}
<|endoftext|>


<commit_before>use std::rand::{Rng, SeedableRng};

static LCG_MULTIPLIER: u32 = 1103515245;
static LCG_INCREMENT: u32 = 12345;
static LCG_MODULOUS: u32 = 2147483647; // 2 ** 31 - 1
static LCG_DEFAULT_SEED: u32 = 1;

struct LinearCongruentialPRNG {
    seed: u32,
    rand_state: u32
}

impl LinearCongruentialPRNG {
    fn new_unseeded() -> LinearCongruentialPRNG {
        LinearCongruentialPRNG { seed: LCG_DEFAULT_SEED, rand_state: LCG_DEFAULT_SEED }
    }
}

impl Rng for LinearCongruentialPRNG {
    fn next_u32(&mut self) -> u32 {
        let next_rand = ((self.rand_state * LCG_MULTIPLIER) + LCG_INCREMENT) & LCG_MODULOUS;
        self.rand_state = next_rand;
        next_rand
    }
}

impl SeedableRng<u32> for LinearCongruentialPRNG {
    fn reseed(&mut self, seed: u32) {
        self.seed =
            if seed == 0 {
                1
            } else {
                seed
            }
    }

    fn from_seed(seed: u32) -> LinearCongruentialPRNG {
        LinearCongruentialPRNG { seed: seed, rand_state: seed }
    }
}

struct LinearFeedbackShiftRegisterPRNG {
    front_ptr: *mut u32,
    rear_ptr:  *mut u32,
    end_ptr: *mut u32,
    iv: Vec<u32>
}

impl LinearFeedbackShiftRegisterPRNG {
    fn init_seed_info(seed: &Vec<u32>) -> (*mut u32, *mut u32, *mut u32, Vec<u32>, u32) {
        let mut iv = seed.clone();

        let (deg, shift_sep) = match std::mem::size_of_val(&iv) {
            // x ** 7 + x** 3 + 1
            x if x < 64 => (7u, 3u),
            // x**15 + x + 1.
            x if x < 128 => (15u, 1u),
            // x**31 + x**3 + 1.
            x if x < 256 => (31u, 3u),
            // x**63 + x + 1.
            _ => (63u, 1u)
        };

        for i in range(1u, deg + 1u) {
            let word = (16807 * iv[i-1]) % 2147483647;
            *iv.get_mut(i) = word as u32;
        }

        let front_ptr = unsafe{ iv.as_mut_ptr().offset(shift_sep as int) };
        let rear_ptr = unsafe{ iv.as_mut_ptr().offset(0) };
        let end_ptr = unsafe{ iv.as_mut_ptr().offset(deg as int) };
        (front_ptr, rear_ptr, end_ptr, iv, deg as u32)
    }
}

impl Rng for LinearFeedbackShiftRegisterPRNG {
    fn next_u32(&mut self) -> u32 {
        let (mut front_ptr, mut rear_ptr, end_ptr) = (self.front_ptr, self.rear_ptr, self.end_ptr);

        let next_rand: u32 = unsafe{ ((*front_ptr + *rear_ptr) >> 1) & 0x7fffffff };

        front_ptr = unsafe{ front_ptr.offset(1) };
        if front_ptr >= end_ptr {
            front_ptr = self.iv.as_mut_ptr();
            rear_ptr = unsafe{ rear_ptr.offset(1) };
        } else {
            rear_ptr = unsafe{ rear_ptr.offset(1) };
            if rear_ptr >= end_ptr {
                rear_ptr = self.iv.as_mut_ptr();
            }
        }

        self.front_ptr = front_ptr;
        self.rear_ptr = rear_ptr;

        next_rand
    }
}

impl SeedableRng<Vec<u32>> for LinearFeedbackShiftRegisterPRNG {
    fn reseed(&mut self, seed: Vec<u32>) {
        let reseed_info = LinearFeedbackShiftRegisterPRNG::init_seed_info(&seed);
        self.front_ptr = reseed_info.clone().val0();
        self.rear_ptr = reseed_info.clone().val1();
        self.end_ptr = reseed_info.clone().val2();
        self.iv = reseed_info.clone().val3();

        let deg = reseed_info.clone().val4();

        for _ in range(0, (deg + 1) * 10) {
            let _ = self.next_u32();
        }
    }

    fn from_seed(seed: Vec<u32>) -> LinearFeedbackShiftRegisterPRNG {
        let (front_ptr, rear_ptr, end_ptr, iv, deg) = LinearFeedbackShiftRegisterPRNG::init_seed_info(&seed);

        let mut rng = LinearFeedbackShiftRegisterPRNG{
            front_ptr: front_ptr, rear_ptr: rear_ptr, end_ptr: end_ptr, iv: iv
        };

        for _ in range(0, (deg + 1) * 10) {
            rng.next_u32();
        }

        rng
    }
}

enum PRNG {
    LinearCongruentialPRNG,
    LinearFeedbackShiftRegisterPRNG
}

fn main() {
    let mut rng: LinearCongruentialPRNG = SeedableRng::from_seed(5);
    for _ in range(0u, 10) {
        println!("Rand num {}", rng.next_u32() % 100);
    }

    println!("\n");

    rng.reseed(434);
    for _ in range(0u, 10) {
        println!("Rand num {}", rng.next_u32() % 100);
    }

    println!("\n\n");

    let seed: Vec<u32> = range(9, 43).collect();
    let mut rng: LinearFeedbackShiftRegisterPRNG = SeedableRng::from_seed(seed);
    for _ in range(0u, 10) {
        println!("Rand num {}", rng.next_u32() % 100);
    }
}

#[test]
fn LCG_test() {
}
<commit_msg>Refactor primitive polynomial selection. Add more randomness...<commit_after>use std::rand::{Rng, SeedableRng};

static LCG_MULTIPLIER: u32 = 1103515245;
static LCG_INCREMENT: u32 = 12345;
static LCG_MODULOUS: u32 = 2147483647; // 2 ** 31 - 1
static LCG_DEFAULT_SEED: u32 = 1;

struct LinearCongruentialPRNG {
    seed: u32,
    rand_state: u32
}

impl LinearCongruentialPRNG {
    fn new_unseeded() -> LinearCongruentialPRNG {
        LinearCongruentialPRNG { seed: LCG_DEFAULT_SEED, rand_state: LCG_DEFAULT_SEED }
    }
}

impl Rng for LinearCongruentialPRNG {
    fn next_u32(&mut self) -> u32 {
        let next_rand = ((self.rand_state * LCG_MULTIPLIER) + LCG_INCREMENT) & LCG_MODULOUS;
        self.rand_state = next_rand;
        next_rand
    }
}

impl SeedableRng<u32> for LinearCongruentialPRNG {
    fn reseed(&mut self, seed: u32) {
        self.seed =
            if seed == 0 {
                1
            } else {
                seed
            }
    }

    fn from_seed(seed: u32) -> LinearCongruentialPRNG {
        LinearCongruentialPRNG { seed: seed, rand_state: seed }
    }
}

struct LinearFeedbackShiftRegisterPRNG {
    front_ptr: *mut u32,
    rear_ptr:  *mut u32,
    end_ptr: *mut u32,
    iv: Vec<u32>
}

impl LinearFeedbackShiftRegisterPRNG {
    fn init_seed_info(seed: &Vec<u32>) -> (*mut u32, *mut u32, *mut u32, Vec<u32>, u32) {
        let mut iv = seed.clone();

        let (deg, shift_sep) = match iv.len() {
            // x**63 + x + 1.
            x if x >= 64 => (63u, 1u),
            // x**31 + x**3 + 1.
            x if x >= 32 => (31u, 3u),
            // x**15 + x + 1.
            x if x >= 16 => (15u, 1u),
            // x ** 7 + x** 3 + 1
            x if x >= 8 => (7u, 3u),
            _ => (iv.len() - 1, 0),
        };

        for i in range(1u, deg + 1u) {
            let word = (16807 * iv[i-1]) % 2147483647;
            *iv.get_mut(i) = word as u32;
        }

        let front_ptr = unsafe{ iv.as_mut_ptr().offset(deg as int) };
        let rear_ptr = unsafe{ iv.as_mut_ptr().offset(shift_sep as int) };
        let end_ptr = unsafe{ iv.as_mut_ptr().offset((iv.len() - 1) as int)};
        (front_ptr, rear_ptr, end_ptr, iv, deg as u32)
    }
}

impl Rng for LinearFeedbackShiftRegisterPRNG {
    fn next_u32(&mut self) -> u32 {
        let (mut front_ptr, mut rear_ptr, end_ptr) = (self.front_ptr, self.rear_ptr, self.end_ptr);

        let next_rand: u32;
        unsafe {
            *front_ptr += *rear_ptr;
            next_rand = (*front_ptr >> 1) & 0x7fffffff;
        }

        front_ptr = unsafe{ front_ptr.offset(1) };
        if front_ptr >= end_ptr {
            front_ptr = self.iv.as_mut_ptr();
            rear_ptr = unsafe{ rear_ptr.offset(1) };
        } else {
            rear_ptr = unsafe{ rear_ptr.offset(1) };
            if rear_ptr >= end_ptr {
                rear_ptr = self.iv.as_mut_ptr();
            }
        }

        self.front_ptr = front_ptr;
        self.rear_ptr = rear_ptr;

        next_rand
    }
}

impl SeedableRng<Vec<u32>> for LinearFeedbackShiftRegisterPRNG {
    fn reseed(&mut self, seed: Vec<u32>) {
        let reseed_info = LinearFeedbackShiftRegisterPRNG::init_seed_info(&seed);
        self.front_ptr = reseed_info.clone().val0();
        self.rear_ptr = reseed_info.clone().val1();
        self.end_ptr = reseed_info.clone().val2();
        self.iv = reseed_info.clone().val3();

        let deg = reseed_info.clone().val4();

        for _ in range(0, (deg + 1) * 10) {
            let _ = self.next_u32();
        }
    }

    fn from_seed(seed: Vec<u32>) -> LinearFeedbackShiftRegisterPRNG {
        let (front_ptr, rear_ptr, end_ptr, iv, deg) = LinearFeedbackShiftRegisterPRNG::init_seed_info(&seed);

        let mut rng = LinearFeedbackShiftRegisterPRNG{
            front_ptr: front_ptr, rear_ptr: rear_ptr, end_ptr: end_ptr, iv: iv
        };

        for _ in range(0, (deg + 1) * 10) {
            rng.next_u32();
        }

        rng
    }
}

enum PRNG {
    LinearCongruentialPRNG,
    LinearFeedbackShiftRegisterPRNG
}

fn main() {
    let mut rng: LinearCongruentialPRNG = SeedableRng::from_seed(5);
    for _ in range(0u, 10) {
        println!("Rand num {}", rng.next_u32() % 100);
    }

    println!("\n");

    rng.reseed(434);
    for _ in range(0u, 10) {
        println!("Rand num {}", rng.next_u32() % 100);
    }

    println!("\n\n");

    let mut seed = vec![3, 434, 545,45, 5454, 6454, 4545, 232424, 52345235, 35434534, 2342341];
    let mut rng: LinearFeedbackShiftRegisterPRNG = SeedableRng::from_seed(seed);
    for _ in range(3u, 20) {
        println!("Rand num {}", rng.next_u32() % 100);
    }
}

#[test]
fn LCG_test() {
}
<|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 https://mozilla.org/MPL/2.0/. */

//! DOM bindings for `CharacterData`.

use crate::dom::bindings::cell::{DomRefCell, Ref};
use crate::dom::bindings::codegen::Bindings::CharacterDataBinding::CharacterDataMethods;
use crate::dom::bindings::codegen::Bindings::NodeBinding::NodeBinding::NodeMethods;
use crate::dom::bindings::codegen::Bindings::ProcessingInstructionBinding::ProcessingInstructionMethods;
use crate::dom::bindings::codegen::InheritTypes::{CharacterDataTypeId, NodeTypeId, TextTypeId};
use crate::dom::bindings::codegen::UnionTypes::NodeOrString;
use crate::dom::bindings::error::{Error, ErrorResult, Fallible};
use crate::dom::bindings::inheritance::Castable;
use crate::dom::bindings::root::{DomRoot, LayoutDom};
use crate::dom::bindings::str::DOMString;
use crate::dom::cdatasection::CDATASection;
use crate::dom::comment::Comment;
use crate::dom::document::Document;
use crate::dom::element::Element;
use crate::dom::mutationobserver::{Mutation, MutationObserver};
use crate::dom::node::{ChildrenMutation, Node, NodeDamage};
use crate::dom::processinginstruction::ProcessingInstruction;
use crate::dom::text::Text;
use crate::dom::virtualmethods::vtable_for;
use dom_struct::dom_struct;

// https://dom.spec.whatwg.org/#characterdata
#[dom_struct]
pub struct CharacterData {
    node: Node,
    data: DomRefCell<DOMString>,
}

impl CharacterData {
    pub fn new_inherited(data: DOMString, document: &Document) -> CharacterData {
        CharacterData {
            node: Node::new_inherited(document),
            data: DomRefCell::new(data),
        }
    }

    pub fn clone_with_data(&self, data: DOMString, document: &Document) -> DomRoot<Node> {
        match self.upcast::<Node>().type_id() {
            NodeTypeId::CharacterData(CharacterDataTypeId::Comment) => {
                DomRoot::upcast(Comment::new(data, &document))
            },
            NodeTypeId::CharacterData(CharacterDataTypeId::ProcessingInstruction) => {
                let pi = self.downcast::<ProcessingInstruction>().unwrap();
                DomRoot::upcast(ProcessingInstruction::new(pi.Target(), data, &document))
            },
            NodeTypeId::CharacterData(CharacterDataTypeId::Text(TextTypeId::CDATASection)) => {
                DomRoot::upcast(CDATASection::new(data, &document))
            },
            NodeTypeId::CharacterData(CharacterDataTypeId::Text(TextTypeId::Text)) => {
                DomRoot::upcast(Text::new(data, &document))
            },
            _ => unreachable!(),
        }
    }

    #[inline]
    pub fn data(&self) -> Ref<DOMString> {
        self.data.borrow()
    }

    #[inline]
    pub fn append_data(&self, data: &str) {
        self.queue_mutation_record();
        self.data.borrow_mut().push_str(data);
        self.content_changed();
    }

    fn content_changed(&self) {
        let node = self.upcast::<Node>();
        node.dirty(NodeDamage::OtherNodeDamage);

        // If this is a Text node, we might need to re-parse (say, if our parent
        // is a <style> element.) We don't need to if this is a Comment or
        // ProcessingInstruction.
        if self.is::<Text>() {
            if let Some(parent_node) = node.GetParentNode() {
                let mutation = ChildrenMutation::ChangeText;
                vtable_for(&parent_node).children_changed(&mutation);
            }
        }
    }

    // Queue a MutationObserver record before changing the content.
    fn queue_mutation_record(&self) {
        let mutation = Mutation::CharacterData {
            old_value: self.data.borrow().clone(),
        };
        MutationObserver::queue_a_mutation_record(self.upcast::<Node>(), mutation);
    }
}

impl CharacterDataMethods for CharacterData {
    // https://dom.spec.whatwg.org/#dom-characterdata-data
    fn Data(&self) -> DOMString {
        self.data.borrow().clone()
    }

    // https://dom.spec.whatwg.org/#dom-characterdata-data
    fn SetData(&self, data: DOMString) {
        self.queue_mutation_record();
        let old_length = self.Length();
        let new_length = data.encode_utf16().count() as u32;
        *self.data.borrow_mut() = data;
        self.content_changed();
        let node = self.upcast::<Node>();
        node.ranges()
            .replace_code_units(node, 0, old_length, new_length);
    }

    // https://dom.spec.whatwg.org/#dom-characterdata-length
    fn Length(&self) -> u32 {
        self.data.borrow().encode_utf16().count() as u32
    }

    // https://dom.spec.whatwg.org/#dom-characterdata-substringdata
    fn SubstringData(&self, offset: u32, count: u32) -> Fallible<DOMString> {
        let replace_surrogates = self
            .upcast::<Node>()
            .owner_doc()
            .window()
            .replace_surrogates();
        let data = self.data.borrow();
        // Step 1.
        let mut substring = String::new();
        let remaining;
        match split_at_utf16_code_unit_offset(&data, offset, replace_surrogates) {
            Ok((_, astral, s)) => {
                // As if we had split the UTF-16 surrogate pair in half
                // and then transcoded that to UTF-8 lossily,
                // since our DOMString is currently strict UTF-8.
                if astral.is_some() {
                    substring = substring + "\u{FFFD}";
                }
                remaining = s;
            },
            // Step 2.
            Err(()) => return Err(Error::IndexSize),
        }
        match split_at_utf16_code_unit_offset(remaining, count, replace_surrogates) {
            // Steps 3.
            Err(()) => substring = substring + remaining,
            // Steps 4.
            Ok((s, astral, _)) => {
                substring = substring + s;
                // As if we had split the UTF-16 surrogate pair in half
                // and then transcoded that to UTF-8 lossily,
                // since our DOMString is currently strict UTF-8.
                if astral.is_some() {
                    substring = substring + "\u{FFFD}";
                }
            },
        };
        Ok(DOMString::from(substring))
    }

    // https://dom.spec.whatwg.org/#dom-characterdata-appenddatadata
    fn AppendData(&self, data: DOMString) {
        // FIXME(ajeffrey): Efficient append on DOMStrings?
        self.append_data(&*data);
    }

    // https://dom.spec.whatwg.org/#dom-characterdata-insertdataoffset-data
    fn InsertData(&self, offset: u32, arg: DOMString) -> ErrorResult {
        self.ReplaceData(offset, 0, arg)
    }

    // https://dom.spec.whatwg.org/#dom-characterdata-deletedataoffset-count
    fn DeleteData(&self, offset: u32, count: u32) -> ErrorResult {
        self.ReplaceData(offset, count, DOMString::new())
    }

    // https://dom.spec.whatwg.org/#dom-characterdata-replacedata
    fn ReplaceData(&self, offset: u32, count: u32, arg: DOMString) -> ErrorResult {
        let mut new_data;
        {
            let replace_surrogates = self
                .upcast::<Node>()
                .owner_doc()
                .window()
                .replace_surrogates();
            let data = self.data.borrow();
            let prefix;
            let replacement_before;
            let remaining;
            match split_at_utf16_code_unit_offset(&data, offset, replace_surrogates) {
                Ok((p, astral, r)) => {
                    prefix = p;
                    // As if we had split the UTF-16 surrogate pair in half
                    // and then transcoded that to UTF-8 lossily,
                    // since our DOMString is currently strict UTF-8.
                    replacement_before = if astral.is_some() { "\u{FFFD}" } else { "" };
                    remaining = r;
                },
                // Step 2.
                Err(()) => return Err(Error::IndexSize),
            };
            let replacement_after;
            let suffix;
            match split_at_utf16_code_unit_offset(remaining, count, replace_surrogates) {
                // Steps 3.
                Err(()) => {
                    replacement_after = "";
                    suffix = "";
                },
                Ok((_, astral, s)) => {
                    // As if we had split the UTF-16 surrogate pair in half
                    // and then transcoded that to UTF-8 lossily,
                    // since our DOMString is currently strict UTF-8.
                    replacement_after = if astral.is_some() { "\u{FFFD}" } else { "" };
                    suffix = s;
                },
            };
            // Step 4: Mutation observers.
            self.queue_mutation_record();

            // Step 5 to 7.
            new_data = String::with_capacity(
                prefix.len() +
                    replacement_before.len() +
                    arg.len() +
                    replacement_after.len() +
                    suffix.len(),
            );
            new_data.push_str(prefix);
            new_data.push_str(replacement_before);
            new_data.push_str(&arg);
            new_data.push_str(replacement_after);
            new_data.push_str(suffix);
        }
        *self.data.borrow_mut() = DOMString::from(new_data);
        self.content_changed();
        // Steps 8-11.
        let node = self.upcast::<Node>();
        node.ranges()
            .replace_code_units(node, offset, count, arg.encode_utf16().count() as u32);
        Ok(())
    }

    // https://dom.spec.whatwg.org/#dom-childnode-before
    fn Before(&self, nodes: Vec<NodeOrString>) -> ErrorResult {
        self.upcast::<Node>().before(nodes)
    }

    // https://dom.spec.whatwg.org/#dom-childnode-after
    fn After(&self, nodes: Vec<NodeOrString>) -> ErrorResult {
        self.upcast::<Node>().after(nodes)
    }

    // https://dom.spec.whatwg.org/#dom-childnode-replacewith
    fn ReplaceWith(&self, nodes: Vec<NodeOrString>) -> ErrorResult {
        self.upcast::<Node>().replace_with(nodes)
    }

    // https://dom.spec.whatwg.org/#dom-childnode-remove
    fn Remove(&self) {
        let node = self.upcast::<Node>();
        node.remove_self();
    }

    // https://dom.spec.whatwg.org/#dom-nondocumenttypechildnode-previouselementsibling
    fn GetPreviousElementSibling(&self) -> Option<DomRoot<Element>> {
        self.upcast::<Node>()
            .preceding_siblings()
            .filter_map(DomRoot::downcast)
            .next()
    }

    // https://dom.spec.whatwg.org/#dom-nondocumenttypechildnode-nextelementsibling
    fn GetNextElementSibling(&self) -> Option<DomRoot<Element>> {
        self.upcast::<Node>()
            .following_siblings()
            .filter_map(DomRoot::downcast)
            .next()
    }
}

#[allow(unsafe_code)]
pub trait LayoutCharacterDataHelpers {
    unsafe fn data_for_layout(&self) -> &str;
}

#[allow(unsafe_code)]
impl LayoutCharacterDataHelpers for LayoutDom<'_, CharacterData> {
    #[inline]
    unsafe fn data_for_layout(&self) -> &str {
        &(*self.unsafe_get()).data.borrow_for_layout()
    }
}

/// Split the given string at the given position measured in UTF-16 code units from the start.
///
/// * `Err(())` indicates that `offset` if after the end of the string
/// * `Ok((before, None, after))` indicates that `offset` is between Unicode code points.
///   The two string slices are such that:
///   `before == s.to_utf16()[..offset].to_utf8()` and
///   `after == s.to_utf16()[offset..].to_utf8()`
/// * `Ok((before, Some(ch), after))` indicates that `offset` is "in the middle"
///   of a single Unicode code point that would be represented in UTF-16 by a surrogate pair
///   of two 16-bit code units.
///   `ch` is that code point.
///   The two string slices are such that:
///   `before == s.to_utf16()[..offset - 1].to_utf8()` and
///   `after == s.to_utf16()[offset + 1..].to_utf8()`
///
/// # Panics
///
/// Note that the third variant is only ever returned when the `-Z replace-surrogates`
/// command-line option is specified.
/// When it *would* be returned but the option is *not* specified, this function panics.
fn split_at_utf16_code_unit_offset(
    s: &str,
    offset: u32,
    replace_surrogates: bool,
) -> Result<(&str, Option<char>, &str), ()> {
    let mut code_units = 0;
    for (i, c) in s.char_indices() {
        if code_units == offset {
            let (a, b) = s.split_at(i);
            return Ok((a, None, b));
        }
        code_units += 1;
        if c > '\u{FFFF}' {
            if code_units == offset {
                if replace_surrogates {
                    debug_assert_eq!(c.len_utf8(), 4);
                    return Ok((&s[..i], Some(c), &s[i + c.len_utf8()..]));
                }
                panic!(
                    "\n\n\
                     Would split a surrogate pair in CharacterData API.\n\
                     If you see this in real content, please comment with the URL\n\
                     on https://github.com/servo/servo/issues/6873\n\
                     \n"
                );
            }
            code_units += 1;
        }
    }
    if code_units == offset {
        Ok((s, None, ""))
    } else {
        Err(())
    }
}
<commit_msg>Give a lifetime parameter to LayoutCharacterDataHelpers<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 https://mozilla.org/MPL/2.0/. */

//! DOM bindings for `CharacterData`.

use crate::dom::bindings::cell::{DomRefCell, Ref};
use crate::dom::bindings::codegen::Bindings::CharacterDataBinding::CharacterDataMethods;
use crate::dom::bindings::codegen::Bindings::NodeBinding::NodeBinding::NodeMethods;
use crate::dom::bindings::codegen::Bindings::ProcessingInstructionBinding::ProcessingInstructionMethods;
use crate::dom::bindings::codegen::InheritTypes::{CharacterDataTypeId, NodeTypeId, TextTypeId};
use crate::dom::bindings::codegen::UnionTypes::NodeOrString;
use crate::dom::bindings::error::{Error, ErrorResult, Fallible};
use crate::dom::bindings::inheritance::Castable;
use crate::dom::bindings::root::{DomRoot, LayoutDom};
use crate::dom::bindings::str::DOMString;
use crate::dom::cdatasection::CDATASection;
use crate::dom::comment::Comment;
use crate::dom::document::Document;
use crate::dom::element::Element;
use crate::dom::mutationobserver::{Mutation, MutationObserver};
use crate::dom::node::{ChildrenMutation, Node, NodeDamage};
use crate::dom::processinginstruction::ProcessingInstruction;
use crate::dom::text::Text;
use crate::dom::virtualmethods::vtable_for;
use dom_struct::dom_struct;

// https://dom.spec.whatwg.org/#characterdata
#[dom_struct]
pub struct CharacterData {
    node: Node,
    data: DomRefCell<DOMString>,
}

impl CharacterData {
    pub fn new_inherited(data: DOMString, document: &Document) -> CharacterData {
        CharacterData {
            node: Node::new_inherited(document),
            data: DomRefCell::new(data),
        }
    }

    pub fn clone_with_data(&self, data: DOMString, document: &Document) -> DomRoot<Node> {
        match self.upcast::<Node>().type_id() {
            NodeTypeId::CharacterData(CharacterDataTypeId::Comment) => {
                DomRoot::upcast(Comment::new(data, &document))
            },
            NodeTypeId::CharacterData(CharacterDataTypeId::ProcessingInstruction) => {
                let pi = self.downcast::<ProcessingInstruction>().unwrap();
                DomRoot::upcast(ProcessingInstruction::new(pi.Target(), data, &document))
            },
            NodeTypeId::CharacterData(CharacterDataTypeId::Text(TextTypeId::CDATASection)) => {
                DomRoot::upcast(CDATASection::new(data, &document))
            },
            NodeTypeId::CharacterData(CharacterDataTypeId::Text(TextTypeId::Text)) => {
                DomRoot::upcast(Text::new(data, &document))
            },
            _ => unreachable!(),
        }
    }

    #[inline]
    pub fn data(&self) -> Ref<DOMString> {
        self.data.borrow()
    }

    #[inline]
    pub fn append_data(&self, data: &str) {
        self.queue_mutation_record();
        self.data.borrow_mut().push_str(data);
        self.content_changed();
    }

    fn content_changed(&self) {
        let node = self.upcast::<Node>();
        node.dirty(NodeDamage::OtherNodeDamage);

        // If this is a Text node, we might need to re-parse (say, if our parent
        // is a <style> element.) We don't need to if this is a Comment or
        // ProcessingInstruction.
        if self.is::<Text>() {
            if let Some(parent_node) = node.GetParentNode() {
                let mutation = ChildrenMutation::ChangeText;
                vtable_for(&parent_node).children_changed(&mutation);
            }
        }
    }

    // Queue a MutationObserver record before changing the content.
    fn queue_mutation_record(&self) {
        let mutation = Mutation::CharacterData {
            old_value: self.data.borrow().clone(),
        };
        MutationObserver::queue_a_mutation_record(self.upcast::<Node>(), mutation);
    }
}

impl CharacterDataMethods for CharacterData {
    // https://dom.spec.whatwg.org/#dom-characterdata-data
    fn Data(&self) -> DOMString {
        self.data.borrow().clone()
    }

    // https://dom.spec.whatwg.org/#dom-characterdata-data
    fn SetData(&self, data: DOMString) {
        self.queue_mutation_record();
        let old_length = self.Length();
        let new_length = data.encode_utf16().count() as u32;
        *self.data.borrow_mut() = data;
        self.content_changed();
        let node = self.upcast::<Node>();
        node.ranges()
            .replace_code_units(node, 0, old_length, new_length);
    }

    // https://dom.spec.whatwg.org/#dom-characterdata-length
    fn Length(&self) -> u32 {
        self.data.borrow().encode_utf16().count() as u32
    }

    // https://dom.spec.whatwg.org/#dom-characterdata-substringdata
    fn SubstringData(&self, offset: u32, count: u32) -> Fallible<DOMString> {
        let replace_surrogates = self
            .upcast::<Node>()
            .owner_doc()
            .window()
            .replace_surrogates();
        let data = self.data.borrow();
        // Step 1.
        let mut substring = String::new();
        let remaining;
        match split_at_utf16_code_unit_offset(&data, offset, replace_surrogates) {
            Ok((_, astral, s)) => {
                // As if we had split the UTF-16 surrogate pair in half
                // and then transcoded that to UTF-8 lossily,
                // since our DOMString is currently strict UTF-8.
                if astral.is_some() {
                    substring = substring + "\u{FFFD}";
                }
                remaining = s;
            },
            // Step 2.
            Err(()) => return Err(Error::IndexSize),
        }
        match split_at_utf16_code_unit_offset(remaining, count, replace_surrogates) {
            // Steps 3.
            Err(()) => substring = substring + remaining,
            // Steps 4.
            Ok((s, astral, _)) => {
                substring = substring + s;
                // As if we had split the UTF-16 surrogate pair in half
                // and then transcoded that to UTF-8 lossily,
                // since our DOMString is currently strict UTF-8.
                if astral.is_some() {
                    substring = substring + "\u{FFFD}";
                }
            },
        };
        Ok(DOMString::from(substring))
    }

    // https://dom.spec.whatwg.org/#dom-characterdata-appenddatadata
    fn AppendData(&self, data: DOMString) {
        // FIXME(ajeffrey): Efficient append on DOMStrings?
        self.append_data(&*data);
    }

    // https://dom.spec.whatwg.org/#dom-characterdata-insertdataoffset-data
    fn InsertData(&self, offset: u32, arg: DOMString) -> ErrorResult {
        self.ReplaceData(offset, 0, arg)
    }

    // https://dom.spec.whatwg.org/#dom-characterdata-deletedataoffset-count
    fn DeleteData(&self, offset: u32, count: u32) -> ErrorResult {
        self.ReplaceData(offset, count, DOMString::new())
    }

    // https://dom.spec.whatwg.org/#dom-characterdata-replacedata
    fn ReplaceData(&self, offset: u32, count: u32, arg: DOMString) -> ErrorResult {
        let mut new_data;
        {
            let replace_surrogates = self
                .upcast::<Node>()
                .owner_doc()
                .window()
                .replace_surrogates();
            let data = self.data.borrow();
            let prefix;
            let replacement_before;
            let remaining;
            match split_at_utf16_code_unit_offset(&data, offset, replace_surrogates) {
                Ok((p, astral, r)) => {
                    prefix = p;
                    // As if we had split the UTF-16 surrogate pair in half
                    // and then transcoded that to UTF-8 lossily,
                    // since our DOMString is currently strict UTF-8.
                    replacement_before = if astral.is_some() { "\u{FFFD}" } else { "" };
                    remaining = r;
                },
                // Step 2.
                Err(()) => return Err(Error::IndexSize),
            };
            let replacement_after;
            let suffix;
            match split_at_utf16_code_unit_offset(remaining, count, replace_surrogates) {
                // Steps 3.
                Err(()) => {
                    replacement_after = "";
                    suffix = "";
                },
                Ok((_, astral, s)) => {
                    // As if we had split the UTF-16 surrogate pair in half
                    // and then transcoded that to UTF-8 lossily,
                    // since our DOMString is currently strict UTF-8.
                    replacement_after = if astral.is_some() { "\u{FFFD}" } else { "" };
                    suffix = s;
                },
            };
            // Step 4: Mutation observers.
            self.queue_mutation_record();

            // Step 5 to 7.
            new_data = String::with_capacity(
                prefix.len() +
                    replacement_before.len() +
                    arg.len() +
                    replacement_after.len() +
                    suffix.len(),
            );
            new_data.push_str(prefix);
            new_data.push_str(replacement_before);
            new_data.push_str(&arg);
            new_data.push_str(replacement_after);
            new_data.push_str(suffix);
        }
        *self.data.borrow_mut() = DOMString::from(new_data);
        self.content_changed();
        // Steps 8-11.
        let node = self.upcast::<Node>();
        node.ranges()
            .replace_code_units(node, offset, count, arg.encode_utf16().count() as u32);
        Ok(())
    }

    // https://dom.spec.whatwg.org/#dom-childnode-before
    fn Before(&self, nodes: Vec<NodeOrString>) -> ErrorResult {
        self.upcast::<Node>().before(nodes)
    }

    // https://dom.spec.whatwg.org/#dom-childnode-after
    fn After(&self, nodes: Vec<NodeOrString>) -> ErrorResult {
        self.upcast::<Node>().after(nodes)
    }

    // https://dom.spec.whatwg.org/#dom-childnode-replacewith
    fn ReplaceWith(&self, nodes: Vec<NodeOrString>) -> ErrorResult {
        self.upcast::<Node>().replace_with(nodes)
    }

    // https://dom.spec.whatwg.org/#dom-childnode-remove
    fn Remove(&self) {
        let node = self.upcast::<Node>();
        node.remove_self();
    }

    // https://dom.spec.whatwg.org/#dom-nondocumenttypechildnode-previouselementsibling
    fn GetPreviousElementSibling(&self) -> Option<DomRoot<Element>> {
        self.upcast::<Node>()
            .preceding_siblings()
            .filter_map(DomRoot::downcast)
            .next()
    }

    // https://dom.spec.whatwg.org/#dom-nondocumenttypechildnode-nextelementsibling
    fn GetNextElementSibling(&self) -> Option<DomRoot<Element>> {
        self.upcast::<Node>()
            .following_siblings()
            .filter_map(DomRoot::downcast)
            .next()
    }
}

#[allow(unsafe_code)]
pub trait LayoutCharacterDataHelpers<'dom> {
    unsafe fn data_for_layout(self) -> &'dom str;
}

#[allow(unsafe_code)]
impl<'dom> LayoutCharacterDataHelpers<'dom> for LayoutDom<'dom, CharacterData> {
    #[inline]
    unsafe fn data_for_layout(self) -> &'dom str {
        &(*self.unsafe_get()).data.borrow_for_layout()
    }
}

/// Split the given string at the given position measured in UTF-16 code units from the start.
///
/// * `Err(())` indicates that `offset` if after the end of the string
/// * `Ok((before, None, after))` indicates that `offset` is between Unicode code points.
///   The two string slices are such that:
///   `before == s.to_utf16()[..offset].to_utf8()` and
///   `after == s.to_utf16()[offset..].to_utf8()`
/// * `Ok((before, Some(ch), after))` indicates that `offset` is "in the middle"
///   of a single Unicode code point that would be represented in UTF-16 by a surrogate pair
///   of two 16-bit code units.
///   `ch` is that code point.
///   The two string slices are such that:
///   `before == s.to_utf16()[..offset - 1].to_utf8()` and
///   `after == s.to_utf16()[offset + 1..].to_utf8()`
///
/// # Panics
///
/// Note that the third variant is only ever returned when the `-Z replace-surrogates`
/// command-line option is specified.
/// When it *would* be returned but the option is *not* specified, this function panics.
fn split_at_utf16_code_unit_offset(
    s: &str,
    offset: u32,
    replace_surrogates: bool,
) -> Result<(&str, Option<char>, &str), ()> {
    let mut code_units = 0;
    for (i, c) in s.char_indices() {
        if code_units == offset {
            let (a, b) = s.split_at(i);
            return Ok((a, None, b));
        }
        code_units += 1;
        if c > '\u{FFFF}' {
            if code_units == offset {
                if replace_surrogates {
                    debug_assert_eq!(c.len_utf8(), 4);
                    return Ok((&s[..i], Some(c), &s[i + c.len_utf8()..]));
                }
                panic!(
                    "\n\n\
                     Would split a surrogate pair in CharacterData API.\n\
                     If you see this in real content, please comment with the URL\n\
                     on https://github.com/servo/servo/issues/6873\n\
                     \n"
                );
            }
            code_units += 1;
        }
    }
    if code_units == offset {
        Ok((s, None, ""))
    } else {
        Err(())
    }
}
<|endoftext|>


<commit_before>use rustc::lint::*;
use std::collections::HashMap;
use std::char;
use syntax::ast::*;
use syntax::codemap::Span;
use syntax::visit::FnKind;
use utils::{constants, in_external_macro, snippet, snippet_opt, span_help_and_lint, span_lint, span_lint_and_then};

/// **What it does:** Checks for structure field patterns bound to wildcards.
///
/// **Why is this bad?** Using `..` instead is shorter and leaves the focus on
/// the fields that are actually bound.
///
/// **Known problems:** None.
///
/// **Example:**
/// ```rust
/// let { a: _, b: ref b, c: _ } = ..
/// ```
declare_lint! {
    pub UNNEEDED_FIELD_PATTERN,
    Warn,
    "struct fields bound to a wildcard instead of using `..`"
}

/// **What it does:** Checks for function arguments having the similar names
/// differing by an underscore.
///
/// **Why is this bad?** It affects code readability.
///
/// **Known problems:** None.
///
/// **Example:**
/// ```rust
/// fn foo(a: i32, _a: i32) {}
/// ```
declare_lint! {
    pub DUPLICATE_UNDERSCORE_ARGUMENT,
    Warn,
    "function arguments having names which only differ by an underscore"
}

/// **What it does:** Detects closures called in the same expression where they
/// are defined.
///
/// **Why is this bad?** It is unnecessarily adding to the expression's
/// complexity.
///
/// **Known problems:** None.
///
/// **Example:**
/// ```rust
/// (|| 42)()
/// ```
declare_lint! {
    pub REDUNDANT_CLOSURE_CALL,
    Warn,
    "throwaway closures called in the expression they are defined"
}

/// **What it does:** Detects expressions of the form `--x`.
///
/// **Why is this bad?** It can mislead C/C++ programmers to think `x` was
/// decremented.
///
/// **Known problems:** None.
///
/// **Example:**
/// ```rust
/// --x;
/// ```
declare_lint! {
    pub DOUBLE_NEG,
    Warn,
    "`--x`, which is a double negation of `x` and not a pre-decrement as in C/C++"
}

/// **What it does:** Warns on hexadecimal literals with mixed-case letter
/// digits.
///
/// **Why is this bad?** It looks confusing.
///
/// **Known problems:** None.
///
/// **Example:**
/// ```rust
/// let y = 0x1a9BAcD;
/// ```
declare_lint! {
    pub MIXED_CASE_HEX_LITERALS,
    Warn,
    "hex literals whose letter digits are not consistently upper- or lowercased"
}

/// **What it does:** Warns if literal suffixes are not separated by an
/// underscore.
///
/// **Why is this bad?** It is much less readable.
///
/// **Known problems:** None.
///
/// **Example:**
/// ```rust
/// let y = 123832i32;
/// ```
declare_lint! {
    pub UNSEPARATED_LITERAL_SUFFIX,
    Allow,
    "literals whose suffix is not separated by an underscore"
}

/// **What it does:** Warns if an integral constant literal starts with `0`.
///
/// **Why is this bad?** In some languages (including the infamous C language
/// and most of its
/// family), this marks an octal constant. In Rust however, this is a decimal
/// constant. This could
/// be confusing for both the writer and a reader of the constant.
///
/// **Known problems:** None.
///
/// **Example:**
///
/// In Rust:
/// ```rust
/// fn main() {
///     let a = 0123;
///     println!("{}", a);
/// }
/// ```
///
/// prints `123`, while in C:
///
/// ```c
/// #include <stdio.h>
///
/// int main() {
///     int a = 0123;
///     printf("%d\n", a);
/// }
/// ```
///
/// prints `83` (as `83 == 0o123` while `123 == 0o173`).
declare_lint! {
    pub ZERO_PREFIXED_LITERAL,
    Warn,
    "integer literals starting with `0`"
}

/// **What it does:** Warns if a generic shadows a built-in type.
///
/// **Why is this bad?** This gives surprising type errors.
///
/// **Known problems:** None.
///
/// **Example:**
///
/// ```rust
/// impl<u32> Foo<u32> {
///     fn impl_func(&self) -> u32 {
///         42
///     }
/// }
/// ```
declare_lint! {
    pub BUILTIN_TYPE_SHADOW,
    Warn,
    "shadowing a builtin type"
}

#[derive(Copy, Clone)]
pub struct MiscEarly;

impl LintPass for MiscEarly {
    fn get_lints(&self) -> LintArray {
        lint_array!(
            UNNEEDED_FIELD_PATTERN,
            DUPLICATE_UNDERSCORE_ARGUMENT,
            REDUNDANT_CLOSURE_CALL,
            DOUBLE_NEG,
            MIXED_CASE_HEX_LITERALS,
            UNSEPARATED_LITERAL_SUFFIX,
            ZERO_PREFIXED_LITERAL,
            BUILTIN_TYPE_SHADOW
        )
    }
}

impl EarlyLintPass for MiscEarly {
    fn check_generics(&mut self, cx: &EarlyContext, gen: &Generics) {
        for param in &gen.params {
            if let GenericParam::Type(ref ty) = *param {
                let name = ty.ident.name.as_str();
                if constants::BUILTIN_TYPES.contains(&&*name) {
                    span_lint(
                        cx,
                        BUILTIN_TYPE_SHADOW,
                        ty.span,
                        &format!("This generic shadows the built-in type `{}`", name),
                    );
                }
            }
        }
    }

    fn check_pat(&mut self, cx: &EarlyContext, pat: &Pat) {
        if let PatKind::Struct(ref npat, ref pfields, _) = pat.node {
            let mut wilds = 0;
            let type_name = npat.segments
                .last()
                .expect("A path must have at least one segment")
                .identifier
                .name;

            for field in pfields {
                if field.node.pat.node == PatKind::Wild {
                    wilds += 1;
                }
            }
            if !pfields.is_empty() && wilds == pfields.len() {
                span_help_and_lint(
                    cx,
                    UNNEEDED_FIELD_PATTERN,
                    pat.span,
                    "All the struct fields are matched to a wildcard pattern, consider using `..`.",
                    &format!("Try with `{} {{ .. }}` instead", type_name),
                );
                return;
            }
            if wilds > 0 {
                let mut normal = vec![];

                for field in pfields {
                    if field.node.pat.node != PatKind::Wild {
                        if let Ok(n) = cx.sess().codemap().span_to_snippet(field.span) {
                            normal.push(n);
                        }
                    }
                }
                for field in pfields {
                    if field.node.pat.node == PatKind::Wild {
                        wilds -= 1;
                        if wilds > 0 {
                            span_lint(
                                cx,
                                UNNEEDED_FIELD_PATTERN,
                                field.span,
                                "You matched a field with a wildcard pattern. Consider using `..` instead",
                            );
                        } else {
                            span_help_and_lint(
                                cx,
                                UNNEEDED_FIELD_PATTERN,
                                field.span,
                                "You matched a field with a wildcard pattern. Consider using `..` \
                                 instead",
                                &format!("Try with `{} {{ {}, .. }}`", type_name, normal[..].join(", ")),
                            );
                        }
                    }
                }
            }
        }
    }

    fn check_fn(&mut self, cx: &EarlyContext, _: FnKind, decl: &FnDecl, _: Span, _: NodeId) {
        let mut registered_names: HashMap<String, Span> = HashMap::new();

        for arg in &decl.inputs {
            if let PatKind::Ident(_, sp_ident, None) = arg.pat.node {
                let arg_name = sp_ident.node.to_string();

                if arg_name.starts_with('_') {
                    if let Some(correspondence) = registered_names.get(&arg_name[1..]) {
                        span_lint(
                            cx,
                            DUPLICATE_UNDERSCORE_ARGUMENT,
                            *correspondence,
                            &format!(
                                "`{}` already exists, having another argument having almost the same \
                                 name makes code comprehension and documentation more difficult",
                                arg_name[1..].to_owned()
                            ),
                        );;
                    }
                } else {
                    registered_names.insert(arg_name, arg.pat.span);
                }
            }
        }
    }

    fn check_expr(&mut self, cx: &EarlyContext, expr: &Expr) {
        if in_external_macro(cx, expr.span) {
            return;
        }
        match expr.node {
            ExprKind::Call(ref paren, _) => if let ExprKind::Paren(ref closure) = paren.node {
                if let ExprKind::Closure(_, ref decl, ref block, _) = closure.node {
                    span_lint_and_then(
                        cx,
                        REDUNDANT_CLOSURE_CALL,
                        expr.span,
                        "Try not to call a closure in the expression where it is declared.",
                        |db| if decl.inputs.is_empty() {
                            let hint = snippet(cx, block.span, "..").into_owned();
                            db.span_suggestion(expr.span, "Try doing something like: ", hint);
                        },
                    );
                }
            },
            ExprKind::Unary(UnOp::Neg, ref inner) => if let ExprKind::Unary(UnOp::Neg, _) = inner.node {
                span_lint(
                    cx,
                    DOUBLE_NEG,
                    expr.span,
                    "`--x` could be misinterpreted as pre-decrement by C programmers, is usually a no-op",
                );
            },
            ExprKind::Lit(ref lit) => self.check_lit(cx, lit),
            _ => (),
        }
    }

    fn check_block(&mut self, cx: &EarlyContext, block: &Block) {
        for w in block.stmts.windows(2) {
            if_chain! {
                if let StmtKind::Local(ref local) = w[0].node;
                if let Option::Some(ref t) = local.init;
                if let ExprKind::Closure(_, _, _, _) = t.node;
                if let PatKind::Ident(_, sp_ident, _) = local.pat.node;
                if let StmtKind::Semi(ref second) = w[1].node;
                if let ExprKind::Assign(_, ref call) = second.node;
                if let ExprKind::Call(ref closure, _) = call.node;
                if let ExprKind::Path(_, ref path) = closure.node;
                then {
                    if sp_ident.node == (&path.segments[0]).identifier {
                        span_lint(
                            cx,
                            REDUNDANT_CLOSURE_CALL,
                            second.span,
                            "Closure called just once immediately after it was declared",
                        );
                    }
                }
            }
        }
    }
}

impl MiscEarly {
    fn check_lit(&self, cx: &EarlyContext, lit: &Lit) {
        if_chain! {
            if let LitKind::Int(value, ..) = lit.node;
            if let Some(src) = snippet_opt(cx, lit.span);
            if let Some(firstch) = src.chars().next();
            if char::to_digit(firstch, 10).is_some();
            then {
                let mut prev = '\0';
                for ch in src.chars() {
                    if ch == 'i' || ch == 'u' {
                        if prev != '_' {
                            span_lint(cx, UNSEPARATED_LITERAL_SUFFIX, lit.span,
                                        "integer type suffix should be separated by an underscore");
                        }
                        break;
                    }
                    prev = ch;
                }
                if src.starts_with("0x") {
                    let mut seen = (false, false);
                    for ch in src.chars() {
                        match ch {
                            'a' ... 'f' => seen.0 = true,
                            'A' ... 'F' => seen.1 = true,
                            'i' | 'u'   => break,   // start of suffix already
                            _ => ()
                        }
                    }
                    if seen.0 && seen.1 {
                        span_lint(cx, MIXED_CASE_HEX_LITERALS, lit.span,
                                    "inconsistent casing in hexadecimal literal");
                    }
                } else if src.starts_with("0b") || src.starts_with("0o") {
                    /* nothing to do */
                } else if value != 0 && src.starts_with('0') {
                    span_lint_and_then(cx,
                                        ZERO_PREFIXED_LITERAL,
                                        lit.span,
                                        "this is a decimal constant",
                                        |db| {
                        db.span_suggestion(
                            lit.span,
                            "if you mean to use a decimal constant, remove the `0` to remove confusion",
                            src.trim_left_matches(|c| c == '_' || c == '0').to_string(),
                        );
                        db.span_suggestion(
                            lit.span,
                            "if you mean to use an octal constant, use `0o`",
                            format!("0o{}", src.trim_left_matches(|c| c == '_' || c == '0')),
                        );
                    });
                }
            }
        }
        if_chain! {
            if let LitKind::Float(..) = lit.node;
            if let Some(src) = snippet_opt(cx, lit.span);
            if let Some(firstch) = src.chars().next();
            if char::to_digit(firstch, 10).is_some();
            then {
                let mut prev = '\0';
                for ch in src.chars() {
                    if ch == 'f' {
                        if prev != '_' {
                            span_lint(cx, UNSEPARATED_LITERAL_SUFFIX, lit.span,
                                        "float type suffix should be separated by an underscore");
                        }
                        break;
                    }
                    prev = ch;
                }
            }
        }
    }
}
<commit_msg>Rustup to rustc 1.25.0-nightly (a0dcecff9 2018-01-24)<commit_after>use rustc::lint::*;
use std::collections::HashMap;
use std::char;
use syntax::ast::*;
use syntax::codemap::Span;
use syntax::visit::FnKind;
use utils::{constants, in_external_macro, snippet, snippet_opt, span_help_and_lint, span_lint, span_lint_and_then};

/// **What it does:** Checks for structure field patterns bound to wildcards.
///
/// **Why is this bad?** Using `..` instead is shorter and leaves the focus on
/// the fields that are actually bound.
///
/// **Known problems:** None.
///
/// **Example:**
/// ```rust
/// let { a: _, b: ref b, c: _ } = ..
/// ```
declare_lint! {
    pub UNNEEDED_FIELD_PATTERN,
    Warn,
    "struct fields bound to a wildcard instead of using `..`"
}

/// **What it does:** Checks for function arguments having the similar names
/// differing by an underscore.
///
/// **Why is this bad?** It affects code readability.
///
/// **Known problems:** None.
///
/// **Example:**
/// ```rust
/// fn foo(a: i32, _a: i32) {}
/// ```
declare_lint! {
    pub DUPLICATE_UNDERSCORE_ARGUMENT,
    Warn,
    "function arguments having names which only differ by an underscore"
}

/// **What it does:** Detects closures called in the same expression where they
/// are defined.
///
/// **Why is this bad?** It is unnecessarily adding to the expression's
/// complexity.
///
/// **Known problems:** None.
///
/// **Example:**
/// ```rust
/// (|| 42)()
/// ```
declare_lint! {
    pub REDUNDANT_CLOSURE_CALL,
    Warn,
    "throwaway closures called in the expression they are defined"
}

/// **What it does:** Detects expressions of the form `--x`.
///
/// **Why is this bad?** It can mislead C/C++ programmers to think `x` was
/// decremented.
///
/// **Known problems:** None.
///
/// **Example:**
/// ```rust
/// --x;
/// ```
declare_lint! {
    pub DOUBLE_NEG,
    Warn,
    "`--x`, which is a double negation of `x` and not a pre-decrement as in C/C++"
}

/// **What it does:** Warns on hexadecimal literals with mixed-case letter
/// digits.
///
/// **Why is this bad?** It looks confusing.
///
/// **Known problems:** None.
///
/// **Example:**
/// ```rust
/// let y = 0x1a9BAcD;
/// ```
declare_lint! {
    pub MIXED_CASE_HEX_LITERALS,
    Warn,
    "hex literals whose letter digits are not consistently upper- or lowercased"
}

/// **What it does:** Warns if literal suffixes are not separated by an
/// underscore.
///
/// **Why is this bad?** It is much less readable.
///
/// **Known problems:** None.
///
/// **Example:**
/// ```rust
/// let y = 123832i32;
/// ```
declare_lint! {
    pub UNSEPARATED_LITERAL_SUFFIX,
    Allow,
    "literals whose suffix is not separated by an underscore"
}

/// **What it does:** Warns if an integral constant literal starts with `0`.
///
/// **Why is this bad?** In some languages (including the infamous C language
/// and most of its
/// family), this marks an octal constant. In Rust however, this is a decimal
/// constant. This could
/// be confusing for both the writer and a reader of the constant.
///
/// **Known problems:** None.
///
/// **Example:**
///
/// In Rust:
/// ```rust
/// fn main() {
///     let a = 0123;
///     println!("{}", a);
/// }
/// ```
///
/// prints `123`, while in C:
///
/// ```c
/// #include <stdio.h>
///
/// int main() {
///     int a = 0123;
///     printf("%d\n", a);
/// }
/// ```
///
/// prints `83` (as `83 == 0o123` while `123 == 0o173`).
declare_lint! {
    pub ZERO_PREFIXED_LITERAL,
    Warn,
    "integer literals starting with `0`"
}

/// **What it does:** Warns if a generic shadows a built-in type.
///
/// **Why is this bad?** This gives surprising type errors.
///
/// **Known problems:** None.
///
/// **Example:**
///
/// ```rust
/// impl<u32> Foo<u32> {
///     fn impl_func(&self) -> u32 {
///         42
///     }
/// }
/// ```
declare_lint! {
    pub BUILTIN_TYPE_SHADOW,
    Warn,
    "shadowing a builtin type"
}

#[derive(Copy, Clone)]
pub struct MiscEarly;

impl LintPass for MiscEarly {
    fn get_lints(&self) -> LintArray {
        lint_array!(
            UNNEEDED_FIELD_PATTERN,
            DUPLICATE_UNDERSCORE_ARGUMENT,
            REDUNDANT_CLOSURE_CALL,
            DOUBLE_NEG,
            MIXED_CASE_HEX_LITERALS,
            UNSEPARATED_LITERAL_SUFFIX,
            ZERO_PREFIXED_LITERAL,
            BUILTIN_TYPE_SHADOW
        )
    }
}

impl EarlyLintPass for MiscEarly {
    fn check_generics(&mut self, cx: &EarlyContext, gen: &Generics) {
        for param in &gen.params {
            if let GenericParam::Type(ref ty) = *param {
                let name = ty.ident.name.as_str();
                if constants::BUILTIN_TYPES.contains(&&*name) {
                    span_lint(
                        cx,
                        BUILTIN_TYPE_SHADOW,
                        ty.span,
                        &format!("This generic shadows the built-in type `{}`", name),
                    );
                }
            }
        }
    }

    fn check_pat(&mut self, cx: &EarlyContext, pat: &Pat) {
        if let PatKind::Struct(ref npat, ref pfields, _) = pat.node {
            let mut wilds = 0;
            let type_name = npat.segments
                .last()
                .expect("A path must have at least one segment")
                .identifier
                .name;

            for field in pfields {
                if field.node.pat.node == PatKind::Wild {
                    wilds += 1;
                }
            }
            if !pfields.is_empty() && wilds == pfields.len() {
                span_help_and_lint(
                    cx,
                    UNNEEDED_FIELD_PATTERN,
                    pat.span,
                    "All the struct fields are matched to a wildcard pattern, consider using `..`.",
                    &format!("Try with `{} {{ .. }}` instead", type_name),
                );
                return;
            }
            if wilds > 0 {
                let mut normal = vec![];

                for field in pfields {
                    if field.node.pat.node != PatKind::Wild {
                        if let Ok(n) = cx.sess().codemap().span_to_snippet(field.span) {
                            normal.push(n);
                        }
                    }
                }
                for field in pfields {
                    if field.node.pat.node == PatKind::Wild {
                        wilds -= 1;
                        if wilds > 0 {
                            span_lint(
                                cx,
                                UNNEEDED_FIELD_PATTERN,
                                field.span,
                                "You matched a field with a wildcard pattern. Consider using `..` instead",
                            );
                        } else {
                            span_help_and_lint(
                                cx,
                                UNNEEDED_FIELD_PATTERN,
                                field.span,
                                "You matched a field with a wildcard pattern. Consider using `..` \
                                 instead",
                                &format!("Try with `{} {{ {}, .. }}`", type_name, normal[..].join(", ")),
                            );
                        }
                    }
                }
            }
        }
    }

    fn check_fn(&mut self, cx: &EarlyContext, _: FnKind, decl: &FnDecl, _: Span, _: NodeId) {
        let mut registered_names: HashMap<String, Span> = HashMap::new();

        for arg in &decl.inputs {
            if let PatKind::Ident(_, sp_ident, None) = arg.pat.node {
                let arg_name = sp_ident.node.to_string();

                if arg_name.starts_with('_') {
                    if let Some(correspondence) = registered_names.get(&arg_name[1..]) {
                        span_lint(
                            cx,
                            DUPLICATE_UNDERSCORE_ARGUMENT,
                            *correspondence,
                            &format!(
                                "`{}` already exists, having another argument having almost the same \
                                 name makes code comprehension and documentation more difficult",
                                arg_name[1..].to_owned()
                            ),
                        );;
                    }
                } else {
                    registered_names.insert(arg_name, arg.pat.span);
                }
            }
        }
    }

    fn check_expr(&mut self, cx: &EarlyContext, expr: &Expr) {
        if in_external_macro(cx, expr.span) {
            return;
        }
        match expr.node {
            ExprKind::Call(ref paren, _) => if let ExprKind::Paren(ref closure) = paren.node {
                if let ExprKind::Closure(_, _, ref decl, ref block, _) = closure.node {
                    span_lint_and_then(
                        cx,
                        REDUNDANT_CLOSURE_CALL,
                        expr.span,
                        "Try not to call a closure in the expression where it is declared.",
                        |db| if decl.inputs.is_empty() {
                            let hint = snippet(cx, block.span, "..").into_owned();
                            db.span_suggestion(expr.span, "Try doing something like: ", hint);
                        },
                    );
                }
            },
            ExprKind::Unary(UnOp::Neg, ref inner) => if let ExprKind::Unary(UnOp::Neg, _) = inner.node {
                span_lint(
                    cx,
                    DOUBLE_NEG,
                    expr.span,
                    "`--x` could be misinterpreted as pre-decrement by C programmers, is usually a no-op",
                );
            },
            ExprKind::Lit(ref lit) => self.check_lit(cx, lit),
            _ => (),
        }
    }

    fn check_block(&mut self, cx: &EarlyContext, block: &Block) {
        for w in block.stmts.windows(2) {
            if_chain! {
                if let StmtKind::Local(ref local) = w[0].node;
                if let Option::Some(ref t) = local.init;
                if let ExprKind::Closure(_, _, _, _, _) = t.node;
                if let PatKind::Ident(_, sp_ident, _) = local.pat.node;
                if let StmtKind::Semi(ref second) = w[1].node;
                if let ExprKind::Assign(_, ref call) = second.node;
                if let ExprKind::Call(ref closure, _) = call.node;
                if let ExprKind::Path(_, ref path) = closure.node;
                then {
                    if sp_ident.node == (&path.segments[0]).identifier {
                        span_lint(
                            cx,
                            REDUNDANT_CLOSURE_CALL,
                            second.span,
                            "Closure called just once immediately after it was declared",
                        );
                    }
                }
            }
        }
    }
}

impl MiscEarly {
    fn check_lit(&self, cx: &EarlyContext, lit: &Lit) {
        if_chain! {
            if let LitKind::Int(value, ..) = lit.node;
            if let Some(src) = snippet_opt(cx, lit.span);
            if let Some(firstch) = src.chars().next();
            if char::to_digit(firstch, 10).is_some();
            then {
                let mut prev = '\0';
                for ch in src.chars() {
                    if ch == 'i' || ch == 'u' {
                        if prev != '_' {
                            span_lint(cx, UNSEPARATED_LITERAL_SUFFIX, lit.span,
                                        "integer type suffix should be separated by an underscore");
                        }
                        break;
                    }
                    prev = ch;
                }
                if src.starts_with("0x") {
                    let mut seen = (false, false);
                    for ch in src.chars() {
                        match ch {
                            'a' ... 'f' => seen.0 = true,
                            'A' ... 'F' => seen.1 = true,
                            'i' | 'u'   => break,   // start of suffix already
                            _ => ()
                        }
                    }
                    if seen.0 && seen.1 {
                        span_lint(cx, MIXED_CASE_HEX_LITERALS, lit.span,
                                    "inconsistent casing in hexadecimal literal");
                    }
                } else if src.starts_with("0b") || src.starts_with("0o") {
                    /* nothing to do */
                } else if value != 0 && src.starts_with('0') {
                    span_lint_and_then(cx,
                                        ZERO_PREFIXED_LITERAL,
                                        lit.span,
                                        "this is a decimal constant",
                                        |db| {
                        db.span_suggestion(
                            lit.span,
                            "if you mean to use a decimal constant, remove the `0` to remove confusion",
                            src.trim_left_matches(|c| c == '_' || c == '0').to_string(),
                        );
                        db.span_suggestion(
                            lit.span,
                            "if you mean to use an octal constant, use `0o`",
                            format!("0o{}", src.trim_left_matches(|c| c == '_' || c == '0')),
                        );
                    });
                }
            }
        }
        if_chain! {
            if let LitKind::Float(..) = lit.node;
            if let Some(src) = snippet_opt(cx, lit.span);
            if let Some(firstch) = src.chars().next();
            if char::to_digit(firstch, 10).is_some();
            then {
                let mut prev = '\0';
                for ch in src.chars() {
                    if ch == 'f' {
                        if prev != '_' {
                            span_lint(cx, UNSEPARATED_LITERAL_SUFFIX, lit.span,
                                        "float type suffix should be separated by an underscore");
                        }
                        break;
                    }
                    prev = ch;
                }
            }
        }
    }
}
<|endoftext|>


<commit_before>// Copyright 2017 PingCAP, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// See the License for the specific language governing permissions and
// limitations under the License.

extern crate gcc;
extern crate cmake;
extern crate pkg_config;

const GRPC_VERSION: &'static str = "1.2.5";

#[cfg(not(feature = "static-link"))]
mod imp {
    use super::GRPC_VERSION;

    pub fn build_or_link_grpc(cc: &mut ::gcc::Config) {
        if let Ok(lib) = ::pkg_config::Config::new()
            .atleast_version(GRPC_VERSION)
            .statik(true)
            .probe("grpc_unsecure") {
            for inc_path in lib.include_paths {
                cc.include(inc_path);
            }
        } else {
            panic!("can't find dynamic grpc library");
        }
    }
}

#[cfg(feature = "static-link")]
mod imp {
    use std::path::Path;
    use std::process::Command;

    use super::GRPC_VERSION;

    const ZLIB_VERSION: &'static str = "1.2.8";
    const BORINGSSL_GIT_HASH: &'static str = "78684e5b222645828ca302e56b40b9daff2b2d27";

    fn wget(url: &str, out: &str) -> Result<(), String> {
        Command::new("wget")
            .args(&["-q", "-c", "-O", out, url])
            .status()
            .map_err(|err| format!("wget execute failed: {}", err))
            .and_then(|status| {
                if status.success() {
                    Ok(())
                } else {
                    Err(format!("wget exit with {}", status))
                }
            })
    }

    fn tar_xf(file: &str) -> Result<(), String> {
        Command::new("tar")
            .args(&["zxf", file])
            .status()
            .map_err(|err| format!("tar execute failed: {}", err))
            .and_then(|status| {
                if status.success() {
                    Ok(())
                } else {
                    Err(format!("tar exit with {}", status))
                }
            })
    }

    pub fn build_or_link_grpc(cc: &mut ::gcc::Config) {

        if !Path::new(&format!("grpc-{}", GRPC_VERSION)).exists() {
            wget(&format!("https://github.com/grpc/grpc/archive/v{}.tar.gz",
                          GRPC_VERSION),
                 "grpc.tar.gz")
                .and_then(|_| tar_xf("grpc.tar.gz"))
                .unwrap();
        }

        if !Path::new(&format!("zlib-{}", ZLIB_VERSION)).exists() {
            wget(&format!("https://github.com/madler/zlib/archive/v{}.tar.gz",
                          ZLIB_VERSION),
                 "zlib.tar.gz")
                .and_then(|_| tar_xf("zlib.tar.gz"))
                .unwrap();
        }

        if !Path::new(&format!("boringssl-{}", BORINGSSL_GIT_HASH)).exists() {
            wget(&format!("https://github.com/google/boringssl/archive/{}.tar.gz",
                          BORINGSSL_GIT_HASH),
                 "boringssl.tar.gz")
                .and_then(|_| tar_xf("boringssl.tar.gz"))
                .unwrap();
        }

        let dst = ::cmake::Config::new(format!("zlib-{}", ZLIB_VERSION)).build();

        println!("cargo:rustc-link-search=native={}/lib", dst.display());

        let dst = ::cmake::Config::new(format!("grpc-{}", GRPC_VERSION))
        .define("ZLIB_ROOT_DIR", format!("../zlib-{}", ZLIB_VERSION)) // relative to grpc dir
        .define("BORINGSSL_ROOT_DIR", format!("../boringssl-{}", BORINGSSL_GIT_HASH))
        .build_target("grpc_unsecure")
        .build();

        cc.include(format!("grpc-{}/include", GRPC_VERSION));

        println!("cargo:rustc-link-search=native={}/build", dst.display());
        println!("cargo:rustc-link-search=native={}/build/third_party/zlib",
                 dst.display());

        println!("cargo:rustc-link-lib=static=z");
        println!("cargo:rustc-link-lib=static=gpr");
        println!("cargo:rustc-link-lib=static=grpc_unsecure");
    }
}

fn main() {
    println!("cargo:rerun-if-changed=build.rs");

    let mut cc = ::gcc::Config::new();

    imp::build_or_link_grpc(&mut cc);

    cc.file("grpc_wrap.c")
        .flag("-fPIC")
        .flag("-O2")
        .compile("libgrpc_wrap.a");
}
<commit_msg>*: address commit<commit_after>// Copyright 2017 PingCAP, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// See the License for the specific language governing permissions and
// limitations under the License.

extern crate gcc;
extern crate cmake;
extern crate pkg_config;

const GRPC_VERSION: &'static str = "1.2.5";

#[cfg(not(feature = "static-link"))]
mod imp {
    use super::GRPC_VERSION;

    pub fn build_or_link_grpc(cc: &mut ::gcc::Config) {
        if let Ok(lib) = ::pkg_config::Config::new()
            .atleast_version(GRPC_VERSION)
            .statik(true)
            .probe("grpc_unsecure") {
            for inc_path in lib.include_paths {
                cc.include(inc_path);
            }
        } else {
            panic!("can't find dynamic grpc library");
        }
    }
}

#[cfg(feature = "static-link")]
mod imp {
    use std::path::Path;
    use std::process::Command;

    use super::GRPC_VERSION;

    const ZLIB_VERSION: &'static str = "1.2.8";
    const BORINGSSL_GIT_HASH: &'static str = "78684e5b222645828ca302e56b40b9daff2b2d27";

    fn wget(url: &str, out: &str) -> Result<(), String> {
        Command::new("wget")
            .args(&["-q", "-c", "-O", out, url])
            .status()
            .map_err(|err| format!("wget execute failed: {}", err))
            .and_then(|status| {
                if status.success() {
                    Ok(())
                } else {
                    Err(format!("wget exit with {}", status))
                }
            })
    }

    fn tar_xf(file: &str) -> Result<(), String> {
        Command::new("tar")
            .args(&["zxf", file])
            .status()
            .map_err(|err| format!("tar execute failed: {}", err))
            .and_then(|status| {
                if status.success() {
                    Ok(())
                } else {
                    Err(format!("tar exit with {}", status))
                }
            })
    }

    pub fn build_or_link_grpc(cc: &mut ::gcc::Config) {

        if !Path::new(&format!("grpc-{}", GRPC_VERSION)).exists() {
            wget(&format!("https://github.com/grpc/grpc/archive/v{}.tar.gz",
                          GRPC_VERSION),
                 "grpc.tar.gz")
                .and_then(|_| tar_xf("grpc.tar.gz"))
                .unwrap();
        }

        if !Path::new(&format!("zlib-{}", ZLIB_VERSION)).exists() {
            wget(&format!("https://github.com/madler/zlib/archive/v{}.tar.gz",
                          ZLIB_VERSION),
                 "zlib.tar.gz")
                .and_then(|_| tar_xf("zlib.tar.gz"))
                .unwrap();
        }

        if !Path::new(&format!("boringssl-{}", BORINGSSL_GIT_HASH)).exists() {
            wget(&format!("https://github.com/google/boringssl/archive/{}.tar.gz",
                          BORINGSSL_GIT_HASH),
                 "boringssl.tar.gz")
                .and_then(|_| tar_xf("boringssl.tar.gz"))
                .unwrap();
        }

        let dst = ::cmake::Config::new(format!("zlib-{}", ZLIB_VERSION)).build();

        println!("cargo:rustc-link-search=native={}/lib", dst.display());

        let dst = ::cmake::Config::new(format!("grpc-{}", GRPC_VERSION))
        .define("ZLIB_ROOT_DIR", format!("../zlib-{}", ZLIB_VERSION)) // relative to grpc dir
        .define("BORINGSSL_ROOT_DIR", format!("../boringssl-{}", BORINGSSL_GIT_HASH))
        .build_target("grpc_unsecure")
        .build();

        cc.include(format!("grpc-{}/include", GRPC_VERSION));

        println!("cargo:rustc-link-search=native={}/build", dst.display());
        println!("cargo:rustc-link-search=native={}/build/third_party/zlib",
                 dst.display());

        println!("cargo:rustc-link-lib=static=z");
        println!("cargo:rustc-link-lib=static=gpr");
        println!("cargo:rustc-link-lib=static=grpc_unsecure");
    }
}

fn main() {
    println!("cargo:rerun-if-changed=build.rs");

    let mut cc = ::gcc::Config::new();

    imp::build_or_link_grpc(&mut cc);

    cc.file("grpc_wrap.c")
        .flag("-fPIC")
        .flag("-O2")
        .compile("libgrpc_wrap.a");
}
<|endoftext|>


<commit_before>use anyhow::{anyhow, Result};
use chumsky::prelude::*;
use chumsky::text::*;
use nalgebra::{vector, Vector2};

type Vec2 = Vector2<i64>;

fn parser() -> impl Parser<char, Vec<Vec2>, Error = Simple<char>> {
    let direction = choice((
        just("up").to((|n: i64| vector![0, -n]) as fn(i64) -> Vec2),
        just("down").to((|n: i64| vector![0, n]) as fn(_) -> _),
        just("forward").to((|n: i64| vector![n, 0]) as fn(_) -> _),
    ));

    direction
        .then_ignore(whitespace())
        .then(int(10).map(|s: String| s.parse::<i64>().unwrap()))
        .map(|(f, n): (fn(i64) -> Vec2, i64)| f(n))
        .separated_by(just("\n"))
        .allow_trailing()
        .then_ignore(end())
}

/// parses input into list of offsets
/// right and down are positive directions
pub fn parse(input: &str) -> Result<Vec<Vector2<i64>>> {
    parser()
        .parse(input)
        .map_err(|errs| errs.into_iter().reduce(|acc, err| acc.merge(err)).unwrap())
        .map_err(|err| anyhow!("error parsing day 2 input: {:?}", err))
}

pub fn part1(input: &[Vector2<i64>]) -> Result<i64> {
    Ok(input.iter().sum::<Vector2<i64>>().iter().product())
}

pub fn part2(input: &[Vector2<i64>]) -> Result<String> {
    Ok("Not Implemented".into())
}

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

    #[test]
    fn test_parser() {
        assert_eq!(
            parse("up 1\ndown 2\nforward 3\n").unwrap(),
            vec![
                vector![0, -1],
                vector![0, 2],
                vector![3, 0],
            ]
        )
    }

    #[test]
    fn test_part1() {
        let input = parse(
            r"forward 5
down 5
forward 8
up 3
down 8
forward 2",
        )
        .expect("failed to parse input");
        assert_eq!(part1(&input).unwrap(), 150)
    }
}
<commit_msg>2021 day 02 part 2<commit_after>use anyhow::{anyhow, Result};
use chumsky::prelude::*;
use chumsky::text::*;

#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum Direction {
    Up(i64),
    Down(i64),
    Forward(i64),
}

fn parser() -> impl Parser<char, Vec<Direction>, Error = Simple<char>> {
    let direction = choice((
        keyword("up").to(Direction::Up as fn(i64) -> Direction),
        keyword("down").to(Direction::Down as fn(i64) -> Direction),
        keyword("forward").to(Direction::Forward as fn(i64) -> Direction),
    ));

    direction
        .then_ignore(whitespace())
        .then(int(10).map(|s: String| s.parse::<i64>().unwrap()))
        .map(|(f, n): (fn(i64) -> Direction, i64)| f(n))
        .separated_by(just("\n"))
        .allow_trailing()
        .then_ignore(end())
}

/// parses input into list of offsets
/// right and down are positive directions
pub fn parse(input: &str) -> Result<Vec<Direction>> {
    parser()
        .parse(input)
        .map_err(|errs| errs.into_iter().reduce(|acc, err| acc.merge(err)).unwrap())
        .map_err(|err| anyhow!("error parsing day 2 input: {:?}", err))
}

pub fn part1(input: &[Direction]) -> Result<i64> {
    let mut pos = (0, 0);
    for dir in input.iter() {
        match dir {
            Direction::Up(y) => pos.1 -= y,
            Direction::Down(y) => pos.1 += y,
            Direction::Forward(x) => pos.0 += x,
        }
    }

    Ok(pos.0 * pos.1)
}

pub fn part2(input: &[Direction]) -> Result<i64> {
    let mut aim = 0;
    let mut pos = (0, 0);
    for dir in input.iter() {
        match dir {
            Direction::Up(y) => aim -= y,
            Direction::Down(y) => aim += y,
            Direction::Forward(x) => {
                pos.0 += x;
                pos.1 += x * aim;
            }
        }
    }

    Ok(pos.0 * pos.1)
}

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

    const INPUT : &str =
            r"forward 5
down 5
forward 8
up 3
down 8
forward 2";

    #[test]
    fn test_parser() {
        use Direction::*;
        assert_eq!(
            parse("up 1\ndown 2\nforward 3\n").unwrap(),
            vec![
                Up(1), Down(2), Forward(3)
            ]
        )
    }

    #[test]
    fn test_part1() {
        let input = parse(
            INPUT
        )
        .expect("failed to parse input");
        assert_eq!(part1(&input).unwrap(), 150)
    }

    #[test]
    fn test_part2() {
        let input = parse(
            INPUT
        )
        .expect("failed to parse input");
        assert_eq!(part2(&input).unwrap(), 900)
    }
}
<|endoftext|>