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

use core::ptr::*;

#[test]
fn test() {
    unsafe {
        struct Pair {
            fst: isize,
            snd: isize
        };
        let mut p = Pair {fst: 10, snd: 20};
        let pptr: *mut Pair = &mut p;
        let iptr: *mut isize = pptr as *mut isize;
        assert_eq!(*iptr, 10);
        *iptr = 30;
        assert_eq!(*iptr, 30);
        assert_eq!(p.fst, 30);

        *pptr = Pair {fst: 50, snd: 60};
        assert_eq!(*iptr, 50);
        assert_eq!(p.fst, 50);
        assert_eq!(p.snd, 60);

        let v0 = vec![32000u16, 32001u16, 32002u16];
        let mut v1 = vec![0u16, 0u16, 0u16];

        copy(v0.as_ptr().offset(1), v1.as_mut_ptr().offset(1), 1);
        assert!((v1[0] == 0u16 &&
                 v1[1] == 32001u16 &&
                 v1[2] == 0u16));
        copy(v0.as_ptr().offset(2), v1.as_mut_ptr(), 1);
        assert!((v1[0] == 32002u16 &&
                 v1[1] == 32001u16 &&
                 v1[2] == 0u16));
        copy(v0.as_ptr(), v1.as_mut_ptr().offset(2), 1);
        assert!((v1[0] == 32002u16 &&
                 v1[1] == 32001u16 &&
                 v1[2] == 32000u16));
    }
}

#[test]
fn test_is_null() {
    let p: *const isize = null();
    assert!(p.is_null());

    let q = unsafe { p.offset(1) };
    assert!(!q.is_null());

    let mp: *mut isize = null_mut();
    assert!(mp.is_null());

    let mq = unsafe { mp.offset(1) };
    assert!(!mq.is_null());
}

#[test]
fn test_as_ref() {
    unsafe {
        let p: *const isize = null();
        assert_eq!(p.as_ref(), None);

        let q: *const isize = &2;
        assert_eq!(q.as_ref().unwrap(), &2);

        let p: *mut isize = null_mut();
        assert_eq!(p.as_ref(), None);

        let q: *mut isize = &mut 2;
        assert_eq!(q.as_ref().unwrap(), &2);

        // Lifetime inference
        let u = 2isize;
        {
            let p = &u as *const isize;
            assert_eq!(p.as_ref().unwrap(), &2);
        }
    }
}

#[test]
fn test_as_mut() {
    unsafe {
        let p: *mut isize = null_mut();
        assert!(p.as_mut() == None);

        let q: *mut isize = &mut 2;
        assert!(q.as_mut().unwrap() == &mut 2);

        // Lifetime inference
        let mut u = 2isize;
        {
            let p = &mut u as *mut isize;
            assert!(p.as_mut().unwrap() == &mut 2);
        }
    }
}

#[test]
fn test_ptr_addition() {
    unsafe {
        let xs = vec![5; 16];
        let mut ptr = xs.as_ptr();
        let end = ptr.offset(16);

        while ptr < end {
            assert_eq!(*ptr, 5);
            ptr = ptr.offset(1);
        }

        let mut xs_mut = xs;
        let mut m_ptr = xs_mut.as_mut_ptr();
        let m_end = m_ptr.offset(16);

        while m_ptr < m_end {
            *m_ptr += 5;
            m_ptr = m_ptr.offset(1);
        }

        assert!(xs_mut == vec![10; 16]);
    }
}

#[test]
fn test_ptr_subtraction() {
    unsafe {
        let xs = vec![0,1,2,3,4,5,6,7,8,9];
        let mut idx = 9;
        let ptr = xs.as_ptr();

        while idx >= 0 {
            assert_eq!(*(ptr.offset(idx as isize)), idx as isize);
            idx = idx - 1;
        }

        let mut xs_mut = xs;
        let m_start = xs_mut.as_mut_ptr();
        let mut m_ptr = m_start.offset(9);

        while m_ptr >= m_start {
            *m_ptr += *m_ptr;
            m_ptr = m_ptr.offset(-1);
        }

        assert_eq!(xs_mut, [0,2,4,6,8,10,12,14,16,18]);
    }
}

#[test]
fn test_set_memory() {
    let mut xs = [0u8; 20];
    let ptr = xs.as_mut_ptr();
    unsafe { write_bytes(ptr, 5u8, xs.len()); }
    assert!(xs == [5u8; 20]);
}

#[test]
fn test_unsized_unique() {
    let xs: &mut [i32] = &mut [1, 2, 3];
    let ptr = unsafe { Unique::new(xs as *mut [i32]) };
    let ys = unsafe { &mut **ptr };
    let zs: &mut [i32] = &mut [1, 2, 3];
    assert!(ys == zs);
}

#[test]
fn test_variadic_fnptr() {
    use core::hash::{Hash, SipHasher};
    extern "C" {
        fn printf(_: *const u8, ...);
    }
    let p: unsafe extern "C" fn(*const u8, ...) = printf;
    let q = p.clone();
    assert_eq!(p, q);
    assert!(!(p < q));
    let mut s = SipHasher::new();
    assert_eq!(p.hash(&mut s), q.hash(&mut s));
}
<commit_msg>Rollup merge of #36118 - nagisa:windows-has-no-sprint-again, r=brson<commit_after>// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use core::ptr::*;

#[test]
fn test() {
    unsafe {
        struct Pair {
            fst: isize,
            snd: isize
        };
        let mut p = Pair {fst: 10, snd: 20};
        let pptr: *mut Pair = &mut p;
        let iptr: *mut isize = pptr as *mut isize;
        assert_eq!(*iptr, 10);
        *iptr = 30;
        assert_eq!(*iptr, 30);
        assert_eq!(p.fst, 30);

        *pptr = Pair {fst: 50, snd: 60};
        assert_eq!(*iptr, 50);
        assert_eq!(p.fst, 50);
        assert_eq!(p.snd, 60);

        let v0 = vec![32000u16, 32001u16, 32002u16];
        let mut v1 = vec![0u16, 0u16, 0u16];

        copy(v0.as_ptr().offset(1), v1.as_mut_ptr().offset(1), 1);
        assert!((v1[0] == 0u16 &&
                 v1[1] == 32001u16 &&
                 v1[2] == 0u16));
        copy(v0.as_ptr().offset(2), v1.as_mut_ptr(), 1);
        assert!((v1[0] == 32002u16 &&
                 v1[1] == 32001u16 &&
                 v1[2] == 0u16));
        copy(v0.as_ptr(), v1.as_mut_ptr().offset(2), 1);
        assert!((v1[0] == 32002u16 &&
                 v1[1] == 32001u16 &&
                 v1[2] == 32000u16));
    }
}

#[test]
fn test_is_null() {
    let p: *const isize = null();
    assert!(p.is_null());

    let q = unsafe { p.offset(1) };
    assert!(!q.is_null());

    let mp: *mut isize = null_mut();
    assert!(mp.is_null());

    let mq = unsafe { mp.offset(1) };
    assert!(!mq.is_null());
}

#[test]
fn test_as_ref() {
    unsafe {
        let p: *const isize = null();
        assert_eq!(p.as_ref(), None);

        let q: *const isize = &2;
        assert_eq!(q.as_ref().unwrap(), &2);

        let p: *mut isize = null_mut();
        assert_eq!(p.as_ref(), None);

        let q: *mut isize = &mut 2;
        assert_eq!(q.as_ref().unwrap(), &2);

        // Lifetime inference
        let u = 2isize;
        {
            let p = &u as *const isize;
            assert_eq!(p.as_ref().unwrap(), &2);
        }
    }
}

#[test]
fn test_as_mut() {
    unsafe {
        let p: *mut isize = null_mut();
        assert!(p.as_mut() == None);

        let q: *mut isize = &mut 2;
        assert!(q.as_mut().unwrap() == &mut 2);

        // Lifetime inference
        let mut u = 2isize;
        {
            let p = &mut u as *mut isize;
            assert!(p.as_mut().unwrap() == &mut 2);
        }
    }
}

#[test]
fn test_ptr_addition() {
    unsafe {
        let xs = vec![5; 16];
        let mut ptr = xs.as_ptr();
        let end = ptr.offset(16);

        while ptr < end {
            assert_eq!(*ptr, 5);
            ptr = ptr.offset(1);
        }

        let mut xs_mut = xs;
        let mut m_ptr = xs_mut.as_mut_ptr();
        let m_end = m_ptr.offset(16);

        while m_ptr < m_end {
            *m_ptr += 5;
            m_ptr = m_ptr.offset(1);
        }

        assert!(xs_mut == vec![10; 16]);
    }
}

#[test]
fn test_ptr_subtraction() {
    unsafe {
        let xs = vec![0,1,2,3,4,5,6,7,8,9];
        let mut idx = 9;
        let ptr = xs.as_ptr();

        while idx >= 0 {
            assert_eq!(*(ptr.offset(idx as isize)), idx as isize);
            idx = idx - 1;
        }

        let mut xs_mut = xs;
        let m_start = xs_mut.as_mut_ptr();
        let mut m_ptr = m_start.offset(9);

        while m_ptr >= m_start {
            *m_ptr += *m_ptr;
            m_ptr = m_ptr.offset(-1);
        }

        assert_eq!(xs_mut, [0,2,4,6,8,10,12,14,16,18]);
    }
}

#[test]
fn test_set_memory() {
    let mut xs = [0u8; 20];
    let ptr = xs.as_mut_ptr();
    unsafe { write_bytes(ptr, 5u8, xs.len()); }
    assert!(xs == [5u8; 20]);
}

#[test]
fn test_unsized_unique() {
    let xs: &mut [i32] = &mut [1, 2, 3];
    let ptr = unsafe { Unique::new(xs as *mut [i32]) };
    let ys = unsafe { &mut **ptr };
    let zs: &mut [i32] = &mut [1, 2, 3];
    assert!(ys == zs);
}

#[test]
#[allow(warnings)]
// Have a symbol for the test below. It doesn’t need to be an actual variadic function, match the
// ABI, or even point to an actual executable code, because the function itself is never invoked.
#[no_mangle]
pub fn test_variadic_fnptr() {
    use core::hash::{Hash, SipHasher};
    extern {
        fn test_variadic_fnptr(_: u64, ...) -> f64;
    }
    let p: unsafe extern fn(u64, ...) -> f64 = test_variadic_fnptr;
    let q = p.clone();
    assert_eq!(p, q);
    assert!(!(p < q));
    let mut s = SipHasher::new();
    assert_eq!(p.hash(&mut s), q.hash(&mut s));
}
<|endoftext|>


<commit_before>//
// gash.rs
//
// Starting code for PS2
// Running on Rust 0.9
//
// University of Virginia - cs4414 Spring 2014
// Weilin Xu, David Evans
// Version 0.4
//

extern mod extra;

use std::{io, run, os};
use std::io::buffered::BufferedReader;
use std::path::posix::Path;
use std::io::stdin;
use std::option::Option;
use std::io::process;
use std::io::process::ProcessExit;
use std::run::ProcessOptions;
use extra::getopts;

struct Shell {
    cmd_prompt: ~str,
    history: ~[~str],
    processes : ~[~Command],
}

struct Process {
    command: ~str,
    args: ~[~str],
    exit_status: Option<process::ProcessExit>,
}

struct BackgroundProcess {
    command: ~str,
    args: ~[~str],
    exit_status: Option<ProcessExit>,
    io_port: Option<Port<Option <ProcessExit>>>,
}

trait Command {
    fn run(&mut self);
    fn cmd_exists(&mut self) -> bool;
}

impl Process {
    fn new(program: &str, args: ~[~str]) -> Process {
        let cmd = Process {
            command: program.to_owned(),
            args: args.to_owned(),
            exit_status: None,
        };
        cmd
    }
}

impl BackgroundProcess {
    fn new(program: &str, args: ~[~str]) -> BackgroundProcess {
        let cmd = BackgroundProcess {
            command: program.to_owned(),
            args: args.to_owned(),
            exit_status: None,
            io_port: None,
        };
        cmd
    }
}

impl Command for Process {
    fn run(&mut self) {
        if self.cmd_exists() {
            println("Running process.");
            run::process_status(self.command, self.args);
        }
        else {
            println!("{:s}: command not found", self.command);
        }
    }

    fn cmd_exists(&mut self) -> bool {
        let ret = run::process_output("which", [self.command.to_owned()]);
        return ret.expect("exit code error.").status.success();
    }
}

impl Command for BackgroundProcess {
    fn run(&mut self) {
        if self.cmd_exists() {
            println!("Running {:s} in background.", self.command);
            let (port, chan) :
                (Port<Option<ProcessExit>>,
                    Chan<Option<ProcessExit>>)
                = Chan::new();
            let command = self.command.to_owned();
            let args = self.args.to_owned();
            spawn(proc() {
                let output = run::process_status(command, args);
                match output {
                    Some(ecode) => {
                        if (ecode.success()) {
                            println("Process returned success.");
                        }
                        else {
                            println("Process returned failure.");
                        }
                    }
                    None => {
                        println!("Process returned nothing.");
                    }
                };
                chan.send(output);
            });
            self.io_port = Some(port);
        }
        else {
            println!("{:s}: command not found", self.command);
        }
    }

    fn cmd_exists(&mut self) -> bool {
        let ret = run::process_output("which", [self.command.to_owned()]);
        return ret.expect("exit code error.").status.success();
    }
}

impl Shell {
    fn new(prompt_str: &str) -> Shell {
        Shell {
            cmd_prompt: prompt_str.to_owned(),
            history: ~[],
            processes: ~[],
        }
    }

    fn run(&mut self) {
        let mut stdin = BufferedReader::new(stdin());

        loop {
            print(self.cmd_prompt);
            io::stdio::flush();

            let line = stdin.read_line().unwrap();
            let cmd_line = line.trim().to_owned();
            let program = cmd_line.splitn(' ', 1).nth(0).expect("no program");

            // Push run commands onto the history stack
            match program {
                "" => {}
                _  => { self.push_hist(cmd_line) }
            }
            match program {
                ""        =>  { continue; }
                "exit"    =>  { return; }
                "history" =>  { self.show_hist(); }
                "cd"      =>  { self.chdir(cmd_line); }
                _         =>  { self.run_cmdline(cmd_line); }
            }
        }
    }

    fn push_hist(&mut self, cmd_line: &str) {
        &self.history.push(cmd_line.to_owned());
    }

    fn show_hist(&mut self) {
        println!("{:s}", self.get_hist());
    }

    fn get_hist(&mut self) -> ~str {
        let mut hist = ~"";
        for i in self.history.iter() {
            let s = i.to_owned();
            match hist {
                ~"" => { hist = s; }
                _   => { hist = hist + "\n" + s; }
            }
        }
        return hist
    }

    fn chdir(&mut self, cmd_line: &str) {
        let mut argv: ~[~str] =
            cmd_line.split(' ').filter_map(|x| if x != ""
                {
                    Some(x.to_owned())
                }
                else {
                    None
                }).to_owned_vec();
        if argv.len() > 0 {
            argv.remove(0);
            let path = Path::new(argv[0]);
            os::change_dir(&path);
        }
    }

    fn run_cmdline(&mut self, cmd_line: &str) {
        let mut argv: ~[~str] =
            cmd_line.split(' ').filter_map(|x| if x != ""
                {
                    Some(x.to_owned())
                }
                else {
                    None
                }).to_owned_vec();
        if argv.len() > 0 {
            let program: ~str = argv.remove(0);
            if argv.len() > 0 {
                let last = argv.last().to_owned();
                if last == ~"&" {
                    argv.pop();
                    let mut process = BackgroundProcess::new(program, argv);
                    process.run();
                }
                else {
                    let mut process = Process::new(program, argv);
                    process.run();
                }
            }
            else {
                self.add_process(~Process::new(program, ~[]) as ~Command);
            }
        }
    }

    fn add_process(&mut self, mut process : ~Command) {
        &process.run();
        self.processes.push(process);
    }
}

fn get_cmdline_from_args() -> Option<~str> {
    /* Begin processing program arguments and initiate the parameters. */
    let args = os::args();

    let opts = ~[
        getopts::optopt("c")
    ];

    let matches = match getopts::getopts(args.tail(), opts) {
        Ok(m) => { m }
        Err(f) => { fail!(f.to_err_msg()) }
    };

    if matches.opt_present("c") {
        let cmd_str = match matches.opt_str("c") {
                                                Some(cmd_str) => {cmd_str.to_owned()},
                                                None => {~""}
                                              };
        return Some(cmd_str);
    } else {
        return None;
    }
}

fn main() {
    let opt_cmd_line = get_cmdline_from_args();

    match opt_cmd_line {
        Some(cmd_line) => Shell::new("").run_cmdline(cmd_line),
        None           => Shell::new("gash > ").run()
    }
}
<commit_msg>cleanup background processes on exit<commit_after>//
// gash.rs
//
// Starting code for PS2
// Running on Rust 0.9
//
// University of Virginia - cs4414 Spring 2014
// Weilin Xu, David Evans
// Version 0.4
//

extern mod extra;

use std::{io, run, os};
use std::io::buffered::BufferedReader;
use std::path::posix::Path;
use std::io::stdin;
use std::option::Option;
use std::io::process;
use std::run::Process;
use std::io::process::ProcessExit;
use std::run::ProcessOptions;
use extra::getopts;

struct Shell {
    cmd_prompt: ~str,
    history: ~[~str],
    processes : ~[~BackgroundProcess],
}

struct CmdProcess {
    command: ~str,
    args: ~[~str],
    exit_status: Option<process::ProcessExit>,
}

struct BackgroundProcess {
    command: ~str,
    args: ~[~str],
    exit_status: Option<ProcessExit>,
    io_port: Option<Port<ProcessExit>>,
    kill_chan : Option<Chan<int>>,
}

trait Command {
    fn run(&mut self);
    fn cmd_exists(&mut self) -> bool;
//    fn is_running(&mut self) -> bool;
}

impl CmdProcess {
    fn new(program: &str, args: ~[~str]) -> CmdProcess {
        let cmd = CmdProcess {
            command: program.to_owned(),
            args: args.to_owned(),
            exit_status: None,
        };
        cmd
    }
}

impl BackgroundProcess {
    fn new(program: &str, args: ~[~str]) -> BackgroundProcess {
        let cmd = BackgroundProcess {
            command: program.to_owned(),
            args: args.to_owned(),
            exit_status: None,
            io_port: None,
            kill_chan: None,
        };
        cmd
    }
}

impl Command for CmdProcess {
    fn run(&mut self) {
        if self.cmd_exists() {
            println("Running process.");
            self.exit_status = run::process_status(self.command, self.args);
        }
        else {
            println!("{:s}: command not found", self.command);
        }
    }

    fn cmd_exists(&mut self) -> bool {
        let ret = run::process_output("which", [self.command.to_owned()]);
        return ret.expect("exit code error.").status.success();
    }
}

impl Command for BackgroundProcess {
    fn run(&mut self) {
        if self.cmd_exists() {
            println!("Running {:s} in background.", self.command);
            let (port, chan) : (Port<ProcessExit>, Chan<ProcessExit>)
                    = Chan::new();
            let (killport, killchan) : (Port<int>, Chan<int>) = Chan::new();
            let command = self.command.to_owned();
            let args = self.args.to_owned();
            spawn(proc() {
                let options = ProcessOptions {
                    env : None,
                    dir : None,
                    in_fd : None,
                    out_fd : None,
                    err_fd : None,
                };
                let maybe_process = Process::new(command, args, options);
                match maybe_process {
                    Some(mut process) => {
                        println!("{:?} was spawned.", process.get_id());
                        let signal = killport.recv();
                        match signal {
                            9 => {process.force_destroy();}
                            15 => {process.destroy();}
                            _ => {}
                        }
                    }
                    None => {
                    }
                }
            });
            self.io_port = Some(port);
            self.kill_chan = Some(killchan);
        }
        else {
            println!("{:s}: command not found", self.command);
        }
    }

    fn cmd_exists(&mut self) -> bool {
        let ret = run::process_output("which", [self.command.to_owned()]);
        return ret.expect("exit code error.").status.success();
    }

}

impl Shell {
    fn new(prompt_str: &str) -> Shell {
        Shell {
            cmd_prompt: prompt_str.to_owned(),
            history: ~[],
            processes: ~[],
        }
    }

    fn run(&mut self) {
        let mut stdin = BufferedReader::new(stdin());

        loop {
            print(self.cmd_prompt);
            io::stdio::flush();

            let line = stdin.read_line().unwrap();
            let cmd_line = line.trim().to_owned();
            let program = cmd_line.splitn(' ', 1).nth(0).expect("no program");
            self.kill_dead();
            match program {
                "" => {}
                _  => { self.push_hist(cmd_line) }
            }
            match program {
                ""        =>  { continue; }
                "exit"    =>  {
                    self.kill_all();
                    return;
                }
                "history" =>  { self.show_hist(); }
                "cd"      =>  { self.chdir(cmd_line); }
                _         =>  { self.run_cmdline(cmd_line); }
            }
        }
    }

    fn kill_dead(&mut self) {
        let mut dead : ~[uint];
        dead = ~[];
        let mut i = 0;
        for cmd in self.processes.iter() {
            match cmd.io_port {
                Some(ref p) => {
                    match p.try_recv() {
                        Some (exitstatus) => {
                            if (exitstatus.success()) {
                                println("Process completed successfully");
                                dead.push(i);
                            }
                        },
                        None => {}
                    }
                },
                None       => {},
            }
            i += 1;
        }
        for &p in dead.iter() {
            println!("Killing process {:u}", p);
            self.processes.remove(p);
        }
    }

    fn kill_all(&mut self) {
        for p in self.processes.iter() {
            match p.kill_chan {
                Some(ref kill_channel) => {
                    kill_channel.send(15);
                }
                None => {}
            }

        }
        /*
        loop {
            match self.processes.pop_opt() {
                None => {println("Done killing ");
                    break} ,
                Some(process)    => {
                    println("Killing one process");
                    match process.kill_chan {
                        Some (kill_channel) => {
                            kill_channel.send(15);
                        }
                        None => {}
                    }
                }
            }
        }
        */
    }

    fn push_hist(&mut self, cmd_line: &str) {
        &self.history.push(cmd_line.to_owned());
    }

    fn show_hist(&mut self) {
        println!("{:s}", self.get_hist());
    }

    fn get_hist(&mut self) -> ~str {
        let mut hist = ~"";
        for i in self.history.iter() {
            let s = i.to_owned();
            match hist {
                ~"" => { hist = s; }
                _   => { hist = hist + "\n" + s; }
            }
        }
        return hist
    }

    fn chdir(&mut self, cmd_line: &str) {
        let mut argv: ~[~str] =
            cmd_line.split(' ').filter_map(|x| if x != ""
                {
                    Some(x.to_owned())
                }
                else {
                    None
                }).to_owned_vec();
        if argv.len() > 0 {
            argv.remove(0);
            let path = Path::new(argv[0]);
            os::change_dir(&path);
        }
    }

    fn run_cmdline(&mut self, cmd_line: &str) {
        let mut argv: ~[~str] =
            cmd_line.split(' ').filter_map(|x| if x != ""
                {
                    Some(x.to_owned())
                }
                else {
                    None
                }).to_owned_vec();
        if argv.len() > 0 {
            let program: ~str = argv.remove(0);
            if argv.len() > 0 {
                let last = argv.last().to_owned();
                if last == ~"&" {
                    argv.pop();
                    self.add_process(~BackgroundProcess::new(program, argv));
                }
                else {
                    CmdProcess::new(program, argv).run();
                }
            }
            else {
                CmdProcess::new(program, argv).run();
            }
        }
    }

    fn add_process(&mut self, mut process : ~BackgroundProcess) {
        &process.run();
        self.processes.push(process);
    }
}

fn get_cmdline_from_args() -> Option<~str> {
    /* Begin processing program arguments and initiate the parameters. */
    let args = os::args();

    let opts = ~[
        getopts::optopt("c")
    ];

    let matches = match getopts::getopts(args.tail(), opts) {
        Ok(m) => { m }
        Err(f) => { fail!(f.to_err_msg()) }
    };

    if matches.opt_present("c") {
        let cmd_str = match matches.opt_str("c") {
                                                Some(cmd_str) => {cmd_str.to_owned()},
                                                None => {~""}
                                              };
        return Some(cmd_str);
    } else {
        return None;
    }
}

fn main() {
    let opt_cmd_line = get_cmdline_from_args();

    match opt_cmd_line {
        Some(cmd_line) => Shell::new("").run_cmdline(cmd_line),
        None           => Shell::new("gash > ").run()
    }
}
<|endoftext|>


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

use crate::ReferrerPolicy;
use http::HeaderMap;
use hyper::Method;
use msg::constellation_msg::PipelineId;
use servo_url::{ImmutableOrigin, ServoUrl};
use std::default::Default;

/// An [initiator](https://fetch.spec.whatwg.org/#concept-request-initiator)
#[derive(Clone, Copy, MallocSizeOf, PartialEq)]
pub enum Initiator {
    None,
    Download,
    ImageSet,
    Manifest,
    XSLT,
}

/// A request [destination](https://fetch.spec.whatwg.org/#concept-request-destination)
#[derive(Clone, Copy, Debug, Deserialize, MallocSizeOf, PartialEq, Serialize)]
pub enum Destination {
    None,
    Audio,
    Document,
    Embed,
    Font,
    Image,
    Manifest,
    Object,
    Report,
    Script,
    ServiceWorker,
    SharedWorker,
    Style,
    Track,
    Video,
    Worker,
    Xslt,
}

impl Destination {
    /// https://fetch.spec.whatwg.org/#request-destination-script-like
    #[inline]
    pub fn is_script_like(&self) -> bool {
        *self == Destination::Script ||
            *self == Destination::ServiceWorker ||
            *self == Destination::SharedWorker ||
            *self == Destination::Worker
    }
}

/// A request [origin](https://fetch.spec.whatwg.org/#concept-request-origin)
#[derive(Clone, Debug, Deserialize, MallocSizeOf, PartialEq, Serialize)]
pub enum Origin {
    Client,
    Origin(ImmutableOrigin),
}

/// A [referer](https://fetch.spec.whatwg.org/#concept-request-referrer)
#[derive(Clone, Debug, Deserialize, MallocSizeOf, PartialEq, Serialize)]
pub enum Referrer {
    NoReferrer,
    /// Default referrer if nothing is specified
    Client,
    ReferrerUrl(ServoUrl),
}

/// A [request mode](https://fetch.spec.whatwg.org/#concept-request-mode)
#[derive(Clone, Debug, Deserialize, MallocSizeOf, PartialEq, Serialize)]
pub enum RequestMode {
    Navigate,
    SameOrigin,
    NoCors,
    CorsMode,
    WebSocket { protocols: Vec<String> },
}

/// Request [credentials mode](https://fetch.spec.whatwg.org/#concept-request-credentials-mode)
#[derive(Clone, Copy, Debug, Deserialize, MallocSizeOf, PartialEq, Serialize)]
pub enum CredentialsMode {
    Omit,
    CredentialsSameOrigin,
    Include,
}

/// [Cache mode](https://fetch.spec.whatwg.org/#concept-request-cache-mode)
#[derive(Clone, Copy, Debug, Deserialize, MallocSizeOf, PartialEq, Serialize)]
pub enum CacheMode {
    Default,
    NoStore,
    Reload,
    NoCache,
    ForceCache,
    OnlyIfCached,
}

/// [Service-workers mode](https://fetch.spec.whatwg.org/#request-service-workers-mode)
#[derive(Clone, Copy, Debug, Deserialize, MallocSizeOf, PartialEq, Serialize)]
pub enum ServiceWorkersMode {
    All,
    Foreign,
    None,
}

/// [Redirect mode](https://fetch.spec.whatwg.org/#concept-request-redirect-mode)
#[derive(Clone, Copy, Debug, Deserialize, MallocSizeOf, PartialEq, Serialize)]
pub enum RedirectMode {
    Follow,
    Error,
    Manual,
}

/// [Response tainting](https://fetch.spec.whatwg.org/#concept-request-response-tainting)
#[derive(Clone, Copy, MallocSizeOf, PartialEq)]
pub enum ResponseTainting {
    Basic,
    CorsTainting,
    Opaque,
}

/// [Window](https://fetch.spec.whatwg.org/#concept-request-window)
#[derive(Clone, Copy, MallocSizeOf, PartialEq)]
pub enum Window {
    NoWindow,
    Client, // TODO: Environmental settings object
}

/// [CORS settings attribute](https://html.spec.whatwg.org/multipage/#attr-crossorigin-anonymous)
#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)]
pub enum CorsSettings {
    Anonymous,
    UseCredentials,
}

#[derive(Clone, Debug, Deserialize, MallocSizeOf, Serialize)]
pub struct RequestInit {
    #[serde(
        deserialize_with = "::hyper_serde::deserialize",
        serialize_with = "::hyper_serde::serialize"
    )]
    #[ignore_malloc_size_of = "Defined in hyper"]
    pub method: Method,
    pub url: ServoUrl,
    #[serde(
        deserialize_with = "::hyper_serde::deserialize",
        serialize_with = "::hyper_serde::serialize"
    )]
    #[ignore_malloc_size_of = "Defined in hyper"]
    pub headers: HeaderMap,
    pub unsafe_request: bool,
    pub body: Option<Vec<u8>>,
    pub service_workers_mode: ServiceWorkersMode,
    // TODO: client object
    pub destination: Destination,
    pub synchronous: bool,
    pub mode: RequestMode,
    pub cache_mode: CacheMode,
    pub use_cors_preflight: bool,
    pub credentials_mode: CredentialsMode,
    pub use_url_credentials: bool,
    pub origin: ImmutableOrigin,
    // XXXManishearth these should be part of the client object
    pub referrer_url: Option<ServoUrl>,
    pub referrer_policy: Option<ReferrerPolicy>,
    pub pipeline_id: Option<PipelineId>,
    pub redirect_mode: RedirectMode,
    pub integrity_metadata: String,
    // to keep track of redirects
    pub url_list: Vec<ServoUrl>,
}

impl Default for RequestInit {
    fn default() -> RequestInit {
        RequestInit {
            method: Method::GET,
            url: ServoUrl::parse("about:blank").unwrap(),
            headers: HeaderMap::new(),
            unsafe_request: false,
            body: None,
            service_workers_mode: ServiceWorkersMode::All,
            destination: Destination::None,
            synchronous: false,
            mode: RequestMode::NoCors,
            cache_mode: CacheMode::Default,
            use_cors_preflight: false,
            credentials_mode: CredentialsMode::Omit,
            use_url_credentials: false,
            origin: ImmutableOrigin::new_opaque(),
            referrer_url: None,
            referrer_policy: None,
            pipeline_id: None,
            redirect_mode: RedirectMode::Follow,
            integrity_metadata: "".to_owned(),
            url_list: vec![],
        }
    }
}

/// A [Request](https://fetch.spec.whatwg.org/#concept-request) as defined by
/// the Fetch spec.
#[derive(Clone, MallocSizeOf)]
pub struct Request {
    /// <https://fetch.spec.whatwg.org/#concept-request-method>
    #[ignore_malloc_size_of = "Defined in hyper"]
    pub method: Method,
    /// <https://fetch.spec.whatwg.org/#local-urls-only-flag>
    pub local_urls_only: bool,
    /// <https://fetch.spec.whatwg.org/#sandboxed-storage-area-urls-flag>
    pub sandboxed_storage_area_urls: bool,
    /// <https://fetch.spec.whatwg.org/#concept-request-header-list>
    #[ignore_malloc_size_of = "Defined in hyper"]
    pub headers: HeaderMap,
    /// <https://fetch.spec.whatwg.org/#unsafe-request-flag>
    pub unsafe_request: bool,
    /// <https://fetch.spec.whatwg.org/#concept-request-body>
    pub body: Option<Vec<u8>>,
    // TODO: client object
    pub window: Window,
    // TODO: target browsing context
    /// <https://fetch.spec.whatwg.org/#request-keepalive-flag>
    pub keep_alive: bool,
    /// <https://fetch.spec.whatwg.org/#request-service-workers-mode>
    pub service_workers_mode: ServiceWorkersMode,
    /// <https://fetch.spec.whatwg.org/#concept-request-initiator>
    pub initiator: Initiator,
    /// <https://fetch.spec.whatwg.org/#concept-request-destination>
    pub destination: Destination,
    // TODO: priority object
    /// <https://fetch.spec.whatwg.org/#concept-request-origin>
    pub origin: Origin,
    /// <https://fetch.spec.whatwg.org/#concept-request-referrer>
    pub referrer: Referrer,
    /// <https://fetch.spec.whatwg.org/#concept-request-referrer-policy>
    pub referrer_policy: Option<ReferrerPolicy>,
    pub pipeline_id: Option<PipelineId>,
    /// <https://fetch.spec.whatwg.org/#synchronous-flag>
    pub synchronous: bool,
    /// <https://fetch.spec.whatwg.org/#concept-request-mode>
    pub mode: RequestMode,
    /// <https://fetch.spec.whatwg.org/#use-cors-preflight-flag>
    pub use_cors_preflight: bool,
    /// <https://fetch.spec.whatwg.org/#concept-request-credentials-mode>
    pub credentials_mode: CredentialsMode,
    /// <https://fetch.spec.whatwg.org/#concept-request-use-url-credentials-flag>
    pub use_url_credentials: bool,
    /// <https://fetch.spec.whatwg.org/#concept-request-cache-mode>
    pub cache_mode: CacheMode,
    /// <https://fetch.spec.whatwg.org/#concept-request-redirect-mode>
    pub redirect_mode: RedirectMode,
    /// <https://fetch.spec.whatwg.org/#concept-request-integrity-metadata>
    pub integrity_metadata: String,
    // Use the last method on url_list to act as spec current url field, and
    // first method to act as spec url field
    /// <https://fetch.spec.whatwg.org/#concept-request-url-list>
    pub url_list: Vec<ServoUrl>,
    /// <https://fetch.spec.whatwg.org/#concept-request-redirect-count>
    pub redirect_count: u32,
    /// <https://fetch.spec.whatwg.org/#concept-request-response-tainting>
    pub response_tainting: ResponseTainting,
}

impl Request {
    pub fn new(url: ServoUrl, origin: Option<Origin>, pipeline_id: Option<PipelineId>) -> Request {
        Request {
            method: Method::GET,
            local_urls_only: false,
            sandboxed_storage_area_urls: false,
            headers: HeaderMap::new(),
            unsafe_request: false,
            body: None,
            window: Window::Client,
            keep_alive: false,
            service_workers_mode: ServiceWorkersMode::All,
            initiator: Initiator::None,
            destination: Destination::None,
            origin: origin.unwrap_or(Origin::Client),
            referrer: Referrer::Client,
            referrer_policy: None,
            pipeline_id: pipeline_id,
            synchronous: false,
            mode: RequestMode::NoCors,
            use_cors_preflight: false,
            credentials_mode: CredentialsMode::Omit,
            use_url_credentials: false,
            cache_mode: CacheMode::Default,
            redirect_mode: RedirectMode::Follow,
            integrity_metadata: String::new(),
            url_list: vec![url],
            redirect_count: 0,
            response_tainting: ResponseTainting::Basic,
        }
    }

    pub fn from_init(init: RequestInit) -> Request {
        let mut req = Request::new(
            init.url.clone(),
            Some(Origin::Origin(init.origin)),
            init.pipeline_id,
        );
        req.method = init.method;
        req.headers = init.headers;
        req.unsafe_request = init.unsafe_request;
        req.body = init.body;
        req.service_workers_mode = init.service_workers_mode;
        req.destination = init.destination;
        req.synchronous = init.synchronous;
        req.mode = init.mode;
        req.use_cors_preflight = init.use_cors_preflight;
        req.credentials_mode = init.credentials_mode;
        req.use_url_credentials = init.use_url_credentials;
        req.cache_mode = init.cache_mode;
        req.referrer = if let Some(url) = init.referrer_url {
            Referrer::ReferrerUrl(url)
        } else {
            Referrer::NoReferrer
        };
        req.referrer_policy = init.referrer_policy;
        req.pipeline_id = init.pipeline_id;
        req.redirect_mode = init.redirect_mode;
        let mut url_list = init.url_list;
        if url_list.is_empty() {
            url_list.push(init.url);
        }
        req.redirect_count = url_list.len() as u32 - 1;
        req.url_list = url_list;
        req.integrity_metadata = init.integrity_metadata;
        req
    }

    /// <https://fetch.spec.whatwg.org/#concept-request-url>
    pub fn url(&self) -> ServoUrl {
        self.url_list.first().unwrap().clone()
    }

    /// <https://fetch.spec.whatwg.org/#concept-request-current-url>
    pub fn current_url(&self) -> ServoUrl {
        self.url_list.last().unwrap().clone()
    }

    /// <https://fetch.spec.whatwg.org/#concept-request-current-url>
    pub fn current_url_mut(&mut self) -> &mut ServoUrl {
        self.url_list.last_mut().unwrap()
    }

    /// <https://fetch.spec.whatwg.org/#navigation-request>
    pub fn is_navigation_request(&self) -> bool {
        self.destination == Destination::Document
    }

    /// <https://fetch.spec.whatwg.org/#subresource-request>
    pub fn is_subresource_request(&self) -> bool {
        match self.destination {
            Destination::Audio |
            Destination::Font |
            Destination::Image |
            Destination::Manifest |
            Destination::Script |
            Destination::Style |
            Destination::Track |
            Destination::Video |
            Destination::Xslt |
            Destination::None => true,
            _ => false,
        }
    }
}

impl Referrer {
    pub fn to_url(&self) -> Option<&ServoUrl> {
        match *self {
            Referrer::NoReferrer | Referrer::Client => None,
            Referrer::ReferrerUrl(ref url) => Some(url),
        }
    }
}
<commit_msg>Auto merge of #22217 - yawboakye:fix-duplicate-code, r=jdm<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use crate::ReferrerPolicy;
use http::HeaderMap;
use hyper::Method;
use msg::constellation_msg::PipelineId;
use servo_url::{ImmutableOrigin, ServoUrl};
use std::default::Default;

/// An [initiator](https://fetch.spec.whatwg.org/#concept-request-initiator)
#[derive(Clone, Copy, MallocSizeOf, PartialEq)]
pub enum Initiator {
    None,
    Download,
    ImageSet,
    Manifest,
    XSLT,
}

/// A request [destination](https://fetch.spec.whatwg.org/#concept-request-destination)
#[derive(Clone, Copy, Debug, Deserialize, MallocSizeOf, PartialEq, Serialize)]
pub enum Destination {
    None,
    Audio,
    Document,
    Embed,
    Font,
    Image,
    Manifest,
    Object,
    Report,
    Script,
    ServiceWorker,
    SharedWorker,
    Style,
    Track,
    Video,
    Worker,
    Xslt,
}

impl Destination {
    /// https://fetch.spec.whatwg.org/#request-destination-script-like
    #[inline]
    pub fn is_script_like(&self) -> bool {
        *self == Destination::Script ||
            *self == Destination::ServiceWorker ||
            *self == Destination::SharedWorker ||
            *self == Destination::Worker
    }
}

/// A request [origin](https://fetch.spec.whatwg.org/#concept-request-origin)
#[derive(Clone, Debug, Deserialize, MallocSizeOf, PartialEq, Serialize)]
pub enum Origin {
    Client,
    Origin(ImmutableOrigin),
}

/// A [referer](https://fetch.spec.whatwg.org/#concept-request-referrer)
#[derive(Clone, Debug, Deserialize, MallocSizeOf, PartialEq, Serialize)]
pub enum Referrer {
    NoReferrer,
    /// Default referrer if nothing is specified
    Client,
    ReferrerUrl(ServoUrl),
}

/// A [request mode](https://fetch.spec.whatwg.org/#concept-request-mode)
#[derive(Clone, Debug, Deserialize, MallocSizeOf, PartialEq, Serialize)]
pub enum RequestMode {
    Navigate,
    SameOrigin,
    NoCors,
    CorsMode,
    WebSocket { protocols: Vec<String> },
}

/// Request [credentials mode](https://fetch.spec.whatwg.org/#concept-request-credentials-mode)
#[derive(Clone, Copy, Debug, Deserialize, MallocSizeOf, PartialEq, Serialize)]
pub enum CredentialsMode {
    Omit,
    CredentialsSameOrigin,
    Include,
}

/// [Cache mode](https://fetch.spec.whatwg.org/#concept-request-cache-mode)
#[derive(Clone, Copy, Debug, Deserialize, MallocSizeOf, PartialEq, Serialize)]
pub enum CacheMode {
    Default,
    NoStore,
    Reload,
    NoCache,
    ForceCache,
    OnlyIfCached,
}

/// [Service-workers mode](https://fetch.spec.whatwg.org/#request-service-workers-mode)
#[derive(Clone, Copy, Debug, Deserialize, MallocSizeOf, PartialEq, Serialize)]
pub enum ServiceWorkersMode {
    All,
    Foreign,
    None,
}

/// [Redirect mode](https://fetch.spec.whatwg.org/#concept-request-redirect-mode)
#[derive(Clone, Copy, Debug, Deserialize, MallocSizeOf, PartialEq, Serialize)]
pub enum RedirectMode {
    Follow,
    Error,
    Manual,
}

/// [Response tainting](https://fetch.spec.whatwg.org/#concept-request-response-tainting)
#[derive(Clone, Copy, MallocSizeOf, PartialEq)]
pub enum ResponseTainting {
    Basic,
    CorsTainting,
    Opaque,
}

/// [Window](https://fetch.spec.whatwg.org/#concept-request-window)
#[derive(Clone, Copy, MallocSizeOf, PartialEq)]
pub enum Window {
    NoWindow,
    Client, // TODO: Environmental settings object
}

/// [CORS settings attribute](https://html.spec.whatwg.org/multipage/#attr-crossorigin-anonymous)
#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)]
pub enum CorsSettings {
    Anonymous,
    UseCredentials,
}

#[derive(Clone, Debug, Deserialize, MallocSizeOf, Serialize)]
pub struct RequestInit {
    #[serde(
        deserialize_with = "::hyper_serde::deserialize",
        serialize_with = "::hyper_serde::serialize"
    )]
    #[ignore_malloc_size_of = "Defined in hyper"]
    pub method: Method,
    pub url: ServoUrl,
    #[serde(
        deserialize_with = "::hyper_serde::deserialize",
        serialize_with = "::hyper_serde::serialize"
    )]
    #[ignore_malloc_size_of = "Defined in hyper"]
    pub headers: HeaderMap,
    pub unsafe_request: bool,
    pub body: Option<Vec<u8>>,
    pub service_workers_mode: ServiceWorkersMode,
    // TODO: client object
    pub destination: Destination,
    pub synchronous: bool,
    pub mode: RequestMode,
    pub cache_mode: CacheMode,
    pub use_cors_preflight: bool,
    pub credentials_mode: CredentialsMode,
    pub use_url_credentials: bool,
    pub origin: ImmutableOrigin,
    // XXXManishearth these should be part of the client object
    pub referrer_url: Option<ServoUrl>,
    pub referrer_policy: Option<ReferrerPolicy>,
    pub pipeline_id: Option<PipelineId>,
    pub redirect_mode: RedirectMode,
    pub integrity_metadata: String,
    // to keep track of redirects
    pub url_list: Vec<ServoUrl>,
}

impl Default for RequestInit {
    fn default() -> RequestInit {
        RequestInit {
            method: Method::GET,
            url: ServoUrl::parse("about:blank").unwrap(),
            headers: HeaderMap::new(),
            unsafe_request: false,
            body: None,
            service_workers_mode: ServiceWorkersMode::All,
            destination: Destination::None,
            synchronous: false,
            mode: RequestMode::NoCors,
            cache_mode: CacheMode::Default,
            use_cors_preflight: false,
            credentials_mode: CredentialsMode::Omit,
            use_url_credentials: false,
            origin: ImmutableOrigin::new_opaque(),
            referrer_url: None,
            referrer_policy: None,
            pipeline_id: None,
            redirect_mode: RedirectMode::Follow,
            integrity_metadata: "".to_owned(),
            url_list: vec![],
        }
    }
}

/// A [Request](https://fetch.spec.whatwg.org/#concept-request) as defined by
/// the Fetch spec.
#[derive(Clone, MallocSizeOf)]
pub struct Request {
    /// <https://fetch.spec.whatwg.org/#concept-request-method>
    #[ignore_malloc_size_of = "Defined in hyper"]
    pub method: Method,
    /// <https://fetch.spec.whatwg.org/#local-urls-only-flag>
    pub local_urls_only: bool,
    /// <https://fetch.spec.whatwg.org/#sandboxed-storage-area-urls-flag>
    pub sandboxed_storage_area_urls: bool,
    /// <https://fetch.spec.whatwg.org/#concept-request-header-list>
    #[ignore_malloc_size_of = "Defined in hyper"]
    pub headers: HeaderMap,
    /// <https://fetch.spec.whatwg.org/#unsafe-request-flag>
    pub unsafe_request: bool,
    /// <https://fetch.spec.whatwg.org/#concept-request-body>
    pub body: Option<Vec<u8>>,
    // TODO: client object
    pub window: Window,
    // TODO: target browsing context
    /// <https://fetch.spec.whatwg.org/#request-keepalive-flag>
    pub keep_alive: bool,
    /// <https://fetch.spec.whatwg.org/#request-service-workers-mode>
    pub service_workers_mode: ServiceWorkersMode,
    /// <https://fetch.spec.whatwg.org/#concept-request-initiator>
    pub initiator: Initiator,
    /// <https://fetch.spec.whatwg.org/#concept-request-destination>
    pub destination: Destination,
    // TODO: priority object
    /// <https://fetch.spec.whatwg.org/#concept-request-origin>
    pub origin: Origin,
    /// <https://fetch.spec.whatwg.org/#concept-request-referrer>
    pub referrer: Referrer,
    /// <https://fetch.spec.whatwg.org/#concept-request-referrer-policy>
    pub referrer_policy: Option<ReferrerPolicy>,
    pub pipeline_id: Option<PipelineId>,
    /// <https://fetch.spec.whatwg.org/#synchronous-flag>
    pub synchronous: bool,
    /// <https://fetch.spec.whatwg.org/#concept-request-mode>
    pub mode: RequestMode,
    /// <https://fetch.spec.whatwg.org/#use-cors-preflight-flag>
    pub use_cors_preflight: bool,
    /// <https://fetch.spec.whatwg.org/#concept-request-credentials-mode>
    pub credentials_mode: CredentialsMode,
    /// <https://fetch.spec.whatwg.org/#concept-request-use-url-credentials-flag>
    pub use_url_credentials: bool,
    /// <https://fetch.spec.whatwg.org/#concept-request-cache-mode>
    pub cache_mode: CacheMode,
    /// <https://fetch.spec.whatwg.org/#concept-request-redirect-mode>
    pub redirect_mode: RedirectMode,
    /// <https://fetch.spec.whatwg.org/#concept-request-integrity-metadata>
    pub integrity_metadata: String,
    // Use the last method on url_list to act as spec current url field, and
    // first method to act as spec url field
    /// <https://fetch.spec.whatwg.org/#concept-request-url-list>
    pub url_list: Vec<ServoUrl>,
    /// <https://fetch.spec.whatwg.org/#concept-request-redirect-count>
    pub redirect_count: u32,
    /// <https://fetch.spec.whatwg.org/#concept-request-response-tainting>
    pub response_tainting: ResponseTainting,
}

impl Request {
    pub fn new(url: ServoUrl, origin: Option<Origin>, pipeline_id: Option<PipelineId>) -> Request {
        Request {
            method: Method::GET,
            local_urls_only: false,
            sandboxed_storage_area_urls: false,
            headers: HeaderMap::new(),
            unsafe_request: false,
            body: None,
            window: Window::Client,
            keep_alive: false,
            service_workers_mode: ServiceWorkersMode::All,
            initiator: Initiator::None,
            destination: Destination::None,
            origin: origin.unwrap_or(Origin::Client),
            referrer: Referrer::Client,
            referrer_policy: None,
            pipeline_id: pipeline_id,
            synchronous: false,
            mode: RequestMode::NoCors,
            use_cors_preflight: false,
            credentials_mode: CredentialsMode::Omit,
            use_url_credentials: false,
            cache_mode: CacheMode::Default,
            redirect_mode: RedirectMode::Follow,
            integrity_metadata: String::new(),
            url_list: vec![url],
            redirect_count: 0,
            response_tainting: ResponseTainting::Basic,
        }
    }

    pub fn from_init(init: RequestInit) -> Request {
        let mut req = Request::new(
            init.url.clone(),
            Some(Origin::Origin(init.origin)),
            init.pipeline_id,
        );
        req.method = init.method;
        req.headers = init.headers;
        req.unsafe_request = init.unsafe_request;
        req.body = init.body;
        req.service_workers_mode = init.service_workers_mode;
        req.destination = init.destination;
        req.synchronous = init.synchronous;
        req.mode = init.mode;
        req.use_cors_preflight = init.use_cors_preflight;
        req.credentials_mode = init.credentials_mode;
        req.use_url_credentials = init.use_url_credentials;
        req.cache_mode = init.cache_mode;
        req.referrer = if let Some(url) = init.referrer_url {
            Referrer::ReferrerUrl(url)
        } else {
            Referrer::NoReferrer
        };
        req.referrer_policy = init.referrer_policy;
        req.redirect_mode = init.redirect_mode;
        let mut url_list = init.url_list;
        if url_list.is_empty() {
            url_list.push(init.url);
        }
        req.redirect_count = url_list.len() as u32 - 1;
        req.url_list = url_list;
        req.integrity_metadata = init.integrity_metadata;
        req
    }

    /// <https://fetch.spec.whatwg.org/#concept-request-url>
    pub fn url(&self) -> ServoUrl {
        self.url_list.first().unwrap().clone()
    }

    /// <https://fetch.spec.whatwg.org/#concept-request-current-url>
    pub fn current_url(&self) -> ServoUrl {
        self.url_list.last().unwrap().clone()
    }

    /// <https://fetch.spec.whatwg.org/#concept-request-current-url>
    pub fn current_url_mut(&mut self) -> &mut ServoUrl {
        self.url_list.last_mut().unwrap()
    }

    /// <https://fetch.spec.whatwg.org/#navigation-request>
    pub fn is_navigation_request(&self) -> bool {
        self.destination == Destination::Document
    }

    /// <https://fetch.spec.whatwg.org/#subresource-request>
    pub fn is_subresource_request(&self) -> bool {
        match self.destination {
            Destination::Audio |
            Destination::Font |
            Destination::Image |
            Destination::Manifest |
            Destination::Script |
            Destination::Style |
            Destination::Track |
            Destination::Video |
            Destination::Xslt |
            Destination::None => true,
            _ => false,
        }
    }
}

impl Referrer {
    pub fn to_url(&self) -> Option<&ServoUrl> {
        match *self {
            Referrer::NoReferrer | Referrer::Client => None,
            Referrer::ReferrerUrl(ref url) => Some(url),
        }
    }
}
<|endoftext|>


<commit_before>#[macro_use]
extern crate glium;
extern crate image;

use glium::{glutin, Surface};
use glium::index::PrimitiveType;
use std::path::Path;

fn main() {
    // building the display, ie. the main object
    let events_loop = glutin::EventsLoop::new();
    let window = glutin::WindowBuilder::new().with_visibility(false);
    let context = glutin::ContextBuilder::new();
    let display = glium::Display::new(window, context, &events_loop).unwrap();

    // building the vertex buffer, which contains all the vertices that we will draw
    let vertex_buffer = {
        #[derive(Copy, Clone)]
        struct Vertex {
            position: [f32; 2],
            color: [f32; 3],
        }

        implement_vertex!(Vertex, position, color);

        glium::VertexBuffer::new(&display,
            &[
                Vertex { position: [-0.5, -0.5], color: [0.0, 1.0, 0.0] },
                Vertex { position: [ 0.0,  0.5], color: [0.0, 0.0, 1.0] },
                Vertex { position: [ 0.5, -0.5], color: [1.0, 0.0, 0.0] },
            ]
        ).unwrap()
    };

    // building the index buffer
    let index_buffer = glium::IndexBuffer::new(&display, PrimitiveType::TrianglesList,
                                               &[0u16, 1, 2]).unwrap();

    // compiling shaders and linking them together
    let program = program!(&display,
        140 => {
            vertex: "
                #version 140

                uniform mat4 matrix;

                in vec2 position;
                in vec3 color;

                out vec3 vColor;

                void main() {
                    gl_Position = vec4(position, 0.0, 1.0) * matrix;
                    vColor = color;
                }
            ",

            fragment: "
                #version 140
                in vec3 vColor;
                out vec4 f_color;

                void main() {
                    f_color = vec4(vColor, 1.0);
                }
            "
        },

        110 => {
            vertex: "
                #version 110

                uniform mat4 matrix;

                attribute vec2 position;
                attribute vec3 color;

                varying vec3 vColor;

                void main() {
                    gl_Position = vec4(position, 0.0, 1.0) * matrix;
                    vColor = color;
                }
            ",

            fragment: "
                #version 110
                varying vec3 vColor;

                void main() {
                    gl_FragColor = vec4(vColor, 1.0);
                }
            ",
        },
    ).unwrap();

    // drawing once

    // building the uniforms
    let uniforms = uniform! {
        matrix: [
            [1.0, 0.0, 0.0, 0.0],
            [0.0, 1.0, 0.0, 0.0],
            [0.0, 0.0, 1.0, 0.0],
            [0.0, 0.0, 0.0, 1.0f32]
        ]
    };

    // drawing a frame
    let mut target = display.draw();
    target.clear_color(0.0, 0.0, 0.0, 0.0);
    target.draw(&vertex_buffer, &index_buffer, &program, &uniforms, &Default::default()).unwrap();
    target.finish().unwrap();

    // reading the front buffer into an image
    let image: glium::texture::RawImage2d<u8> = display.read_front_buffer();
    let image = image::ImageBuffer::from_raw(image.width, image.height, image.data.into_owned()).unwrap();
    let image = image::DynamicImage::ImageRgba8(image).flipv();
    image.save("glium-example-screenshot.png").unwrap();
}
<commit_msg>Remove unused Path import<commit_after>#[macro_use]
extern crate glium;
extern crate image;

use glium::{glutin, Surface};
use glium::index::PrimitiveType;

fn main() {
    // building the display, ie. the main object
    let events_loop = glutin::EventsLoop::new();
    let window = glutin::WindowBuilder::new().with_visibility(false);
    let context = glutin::ContextBuilder::new();
    let display = glium::Display::new(window, context, &events_loop).unwrap();

    // building the vertex buffer, which contains all the vertices that we will draw
    let vertex_buffer = {
        #[derive(Copy, Clone)]
        struct Vertex {
            position: [f32; 2],
            color: [f32; 3],
        }

        implement_vertex!(Vertex, position, color);

        glium::VertexBuffer::new(&display,
            &[
                Vertex { position: [-0.5, -0.5], color: [0.0, 1.0, 0.0] },
                Vertex { position: [ 0.0,  0.5], color: [0.0, 0.0, 1.0] },
                Vertex { position: [ 0.5, -0.5], color: [1.0, 0.0, 0.0] },
            ]
        ).unwrap()
    };

    // building the index buffer
    let index_buffer = glium::IndexBuffer::new(&display, PrimitiveType::TrianglesList,
                                               &[0u16, 1, 2]).unwrap();

    // compiling shaders and linking them together
    let program = program!(&display,
        140 => {
            vertex: "
                #version 140

                uniform mat4 matrix;

                in vec2 position;
                in vec3 color;

                out vec3 vColor;

                void main() {
                    gl_Position = vec4(position, 0.0, 1.0) * matrix;
                    vColor = color;
                }
            ",

            fragment: "
                #version 140
                in vec3 vColor;
                out vec4 f_color;

                void main() {
                    f_color = vec4(vColor, 1.0);
                }
            "
        },

        110 => {
            vertex: "
                #version 110

                uniform mat4 matrix;

                attribute vec2 position;
                attribute vec3 color;

                varying vec3 vColor;

                void main() {
                    gl_Position = vec4(position, 0.0, 1.0) * matrix;
                    vColor = color;
                }
            ",

            fragment: "
                #version 110
                varying vec3 vColor;

                void main() {
                    gl_FragColor = vec4(vColor, 1.0);
                }
            ",
        },
    ).unwrap();

    // drawing once

    // building the uniforms
    let uniforms = uniform! {
        matrix: [
            [1.0, 0.0, 0.0, 0.0],
            [0.0, 1.0, 0.0, 0.0],
            [0.0, 0.0, 1.0, 0.0],
            [0.0, 0.0, 0.0, 1.0f32]
        ]
    };

    // drawing a frame
    let mut target = display.draw();
    target.clear_color(0.0, 0.0, 0.0, 0.0);
    target.draw(&vertex_buffer, &index_buffer, &program, &uniforms, &Default::default()).unwrap();
    target.finish().unwrap();

    // reading the front buffer into an image
    let image: glium::texture::RawImage2d<u8> = display.read_front_buffer();
    let image = image::ImageBuffer::from_raw(image.width, image.height, image.data.into_owned()).unwrap();
    let image = image::DynamicImage::ImageRgba8(image).flipv();
    image.save("glium-example-screenshot.png").unwrap();
}
<|endoftext|>


<commit_before>// Copyright 2015 Ilkka Rauta
//
// 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,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use std::error::Error;
use std::fmt::{self,Display,Formatter};
use std::num::ParseIntError;

#[derive(Copy,Clone,Debug)]
pub enum PropertyMappingError {
    UnrecognizedValue(GetProperty, u32),
    UnrecognizedProperty(u32),
    StatError(GetProperty),
    BufferError(GetProperty)
}

impl Error for PropertyMappingError {
    fn description(&self) -> &str {
        match *self {
            PropertyMappingError::UnrecognizedValue(_, _) => "Unrecognized property value",
            PropertyMappingError::UnrecognizedProperty(_) => "Unrecognized property",
            PropertyMappingError::StatError(_) => "Error interpreting statistical property",
            PropertyMappingError::BufferError(_) => "Error interpreting buffer property"
        }
    }
}

impl Display for PropertyMappingError {
    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
        write!(f, "{:?}", self)
    }
}

pub type PropertyMappingResult<T> = Result<T, PropertyMappingError>;

pub trait FromProperty {
    fn from_property(property_name: GetProperty, property: ffi::Struct_dtv_property) -> PropertyMappingResult<Self>;
}

impl FromProperty for u32 {
    fn from_property(property_name: GetProperty, property: ffi::Struct_dtv_property) -> PropertyMappingResult<Self> {
        let mut property = property;
        let value: u32 = unsafe { *(property.u.data()) };
        Ok(value)
    }
}

impl FromProperty for i32 {
    fn from_property(property_name: GetProperty, property: ffi::Struct_dtv_property) -> PropertyMappingResult<Self> {
        let mut property = property;
        let uvalue: u32 = unsafe { *(property.u.data()) };
        Ok(uvalue as i32)
    }
}

#[derive(Clone,Debug)]
pub enum PropertyValueError {
    ParseIntError(ParseIntError),
    UnrecognizedValue,
    UnrecognizedProperty
}

impl Error for PropertyValueError {
    fn description(&self) -> &str {
        match *self {
            PropertyValueError::UnrecognizedProperty => "Unrecognized property",
            PropertyValueError::UnrecognizedValue => "Unrecognized property value",
            PropertyValueError::ParseIntError(ref error) => Error::description(error)
        }
    }
}

impl Display for PropertyValueError {
    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
        write!(f, "{:?}", self)
    }
}

impl From<ParseIntError> for PropertyValueError {
    fn from(err: ParseIntError) -> PropertyValueError {
        PropertyValueError::ParseIntError(err)
    }
}

pub type PropertyValueResult<T> = Result<T, PropertyValueError>;

pub trait IntoPropertyValue {
    fn into_property_value(value_str: &str) -> PropertyValueResult<Self>;
}

impl IntoPropertyValue for u32 {
    fn into_property_value(value_str: &str) -> PropertyValueResult<Self> {
        u32::from_str_radix(value_str, 10).map_err(PropertyValueError::ParseIntError)
    }
}

impl IntoPropertyValue for i32 {
    fn into_property_value(value_str: &str) -> PropertyValueResult<Self> {
        i32::from_str_radix(value_str, 10).map_err(PropertyValueError::ParseIntError)
    }
}

fn ffi_property_data(property: ffi::Struct_dtv_property) -> u32 {
    unsafe {
        let mut property = property;
        *property.u.data()
    }
}

fn make_ffi_property(cmd: u32, value: u32) -> ffi::Struct_dtv_property {
    let mut p = ffi::Struct_dtv_property { cmd: cmd, ..Default::default() };
    unsafe {
        *p.u.data() = value;
    }
    p
}

#[derive(Copy,Clone,Debug,PartialEq)]
pub enum Lna {
    LnaOff,
    LnaOn,
    LnaAuto,
}

impl Into<u32> for Lna {
    fn into(self) -> u32 {
        match self {
            // On and off variants as defined by Linux DVB documentation
            Lna::LnaOff => 0,
            Lna::LnaOn => 1,
            Lna::LnaAuto => ffi::LNA_AUTO
        }
    }
}

impl FromProperty for Lna {
    fn from_property(property_name: GetProperty, property: ffi::Struct_dtv_property) -> PropertyMappingResult<Self> {
        match ffi_property_data(property) {
            0 => Ok(Lna::LnaOff),
            1 => Ok(Lna::LnaOn),
            ffi::LNA_AUTO => Ok(Lna::LnaAuto),
            value => Err(PropertyMappingError::UnrecognizedValue(property_name, value))
        }
    }
}

impl IntoPropertyValue for Lna {
    fn into_property_value(value_str: &str) -> PropertyValueResult<Self> {
        match value_str {
            "LnaOff" => Ok(Lna::LnaOff),
            "LnaOn" => Ok(Lna::LnaOn),
            "LnaAuto" => Ok(Lna::LnaAuto),
            _ => Err(PropertyValueError::UnrecognizedValue)
        }
    }
}

#[derive(Copy,Clone,Debug,PartialEq)]
pub enum StatValue {
    ScaleNotAvailable,
    Counter(u64),
    Decibel(i64),
    Relative(u64),
}

const STAT_COUNT: usize = 4;

#[derive(Copy,Clone,Debug,PartialEq)]
pub struct Stat {
    len: u8,
    stats: [StatValue; STAT_COUNT]
}

impl Stat {
    pub fn stats(&self) -> &[StatValue] {
        &self.stats[0..self.len as usize]
    }
}

impl FromProperty for Stat {
    fn from_property(property_name: GetProperty, property: ffi::Struct_dtv_property) -> PropertyMappingResult<Self> {
        let (len, ffi_stats) = unsafe {
            let mut property = property;
            ((*property.u.st()).len, (*property.u.st()).stat)
        };
        if len as usize > STAT_COUNT {
            return Err(PropertyMappingError::StatError(property_name));
        }
        let mut stats = [StatValue::ScaleNotAvailable; STAT_COUNT];
        for i in 0..len as usize {
            let mut ffi_stat = ffi_stats[i];
            let uvalue: u64 = unsafe { *ffi_stat.uvalue() };
            let svalue: i64 = unsafe { *ffi_stat.svalue() };
            let scale = ffi_stat.scale as u32;
            stats[i] = match scale {
                ffi::FE_SCALE_NOT_AVAILABLE => StatValue::ScaleNotAvailable,
                ffi::FE_SCALE_COUNTER => StatValue::Counter(uvalue),
                ffi::FE_SCALE_DECIBEL => StatValue::Decibel(svalue),
                ffi::FE_SCALE_RELATIVE => StatValue::Relative(uvalue),
                _ => return Err(PropertyMappingError::StatError(property_name))
            };
        }
        Ok(Stat { len: len, stats: stats })
    }
}

const BUFFER_SIZE: usize = 32;

#[derive(Copy,Clone,Debug,PartialEq)]
pub struct SupportedDeliverySystems {
    len: u32,
    delsys: [DeliverySystem; BUFFER_SIZE]
}

impl SupportedDeliverySystems {
    pub fn delivery_systems(&self) -> &[DeliverySystem] {
        &self.delsys[0..self.len as usize]
    }
}

impl FromProperty for SupportedDeliverySystems {
    fn from_property(property_name: GetProperty, property: ffi::Struct_dtv_property) -> PropertyMappingResult<Self> {
        let (len, buffer) = unsafe {
            let mut property = property;
            ((*property.u.buffer()).len, (*property.u.buffer()).data)
        };
        if len as usize > BUFFER_SIZE {
            return Err(PropertyMappingError::BufferError(property_name));
        }
        let mut delsys = [DeliverySystem::SysUndefined; BUFFER_SIZE];
        for i in 0..len as usize {
            let mut tmp: ffi::Struct_dtv_property = Default::default();
            unsafe { *tmp.u.data() = buffer[i] as u32; }
            delsys[i] = try!(FromProperty::from_property(property_name, tmp));
        }
        Ok(SupportedDeliverySystems { len: len, delsys: delsys })
    }
}

#[derive(Copy,Clone,Debug,PartialEq)]
pub struct ApiVersion {
    pub major: u8,
    pub minor: u8
}

impl FromProperty for ApiVersion {
    fn from_property(property_name: GetProperty, property: ffi::Struct_dtv_property) -> PropertyMappingResult<Self> {
        let data = ffi_property_data(property);
        let major = (data >> 8) & 0xff;
        let minor = data & 0xff;
        Ok(ApiVersion { major: major as u8, minor: minor as u8 })
    }
}

#[test]
fn ffi_property_generation() {
    let mut property = make_ffi_property(123, 456);
    assert_eq!(property.cmd, 123);
    let data = unsafe { *property.u.data() };
    assert_eq!(data, 456);
}

#[test]
fn str_to_property() {
    let property = make_set_property_value("DtvModulation", "Qam128").unwrap();
    assert_eq!(property, SetPropertyValue::DtvModulation(Modulation::Qam128));
}
<commit_msg>Allow unused variables in appropriate places.<commit_after>// Copyright 2015 Ilkka Rauta
//
// 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,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use std::error::Error;
use std::fmt::{self,Display,Formatter};
use std::num::ParseIntError;

#[derive(Copy,Clone,Debug)]
pub enum PropertyMappingError {
    UnrecognizedValue(GetProperty, u32),
    UnrecognizedProperty(u32),
    StatError(GetProperty),
    BufferError(GetProperty)
}

impl Error for PropertyMappingError {
    fn description(&self) -> &str {
        match *self {
            PropertyMappingError::UnrecognizedValue(_, _) => "Unrecognized property value",
            PropertyMappingError::UnrecognizedProperty(_) => "Unrecognized property",
            PropertyMappingError::StatError(_) => "Error interpreting statistical property",
            PropertyMappingError::BufferError(_) => "Error interpreting buffer property"
        }
    }
}

impl Display for PropertyMappingError {
    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
        write!(f, "{:?}", self)
    }
}

pub type PropertyMappingResult<T> = Result<T, PropertyMappingError>;

pub trait FromProperty {
    fn from_property(property_name: GetProperty, property: ffi::Struct_dtv_property) -> PropertyMappingResult<Self>;
}

impl FromProperty for u32 {
    #[allow(unused_variables)]
    fn from_property(property_name: GetProperty, property: ffi::Struct_dtv_property) -> PropertyMappingResult<Self> {
        let mut property = property;
        let value: u32 = unsafe { *(property.u.data()) };
        Ok(value)
    }
}

impl FromProperty for i32 {
    #[allow(unused_variables)]
    fn from_property(property_name: GetProperty, property: ffi::Struct_dtv_property) -> PropertyMappingResult<Self> {
        let mut property = property;
        let uvalue: u32 = unsafe { *(property.u.data()) };
        Ok(uvalue as i32)
    }
}

#[derive(Clone,Debug)]
pub enum PropertyValueError {
    ParseIntError(ParseIntError),
    UnrecognizedValue,
    UnrecognizedProperty
}

impl Error for PropertyValueError {
    fn description(&self) -> &str {
        match *self {
            PropertyValueError::UnrecognizedProperty => "Unrecognized property",
            PropertyValueError::UnrecognizedValue => "Unrecognized property value",
            PropertyValueError::ParseIntError(ref error) => Error::description(error)
        }
    }
}

impl Display for PropertyValueError {
    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
        write!(f, "{:?}", self)
    }
}

impl From<ParseIntError> for PropertyValueError {
    fn from(err: ParseIntError) -> PropertyValueError {
        PropertyValueError::ParseIntError(err)
    }
}

pub type PropertyValueResult<T> = Result<T, PropertyValueError>;

pub trait IntoPropertyValue {
    fn into_property_value(value_str: &str) -> PropertyValueResult<Self>;
}

impl IntoPropertyValue for u32 {
    fn into_property_value(value_str: &str) -> PropertyValueResult<Self> {
        u32::from_str_radix(value_str, 10).map_err(PropertyValueError::ParseIntError)
    }
}

impl IntoPropertyValue for i32 {
    fn into_property_value(value_str: &str) -> PropertyValueResult<Self> {
        i32::from_str_radix(value_str, 10).map_err(PropertyValueError::ParseIntError)
    }
}

fn ffi_property_data(property: ffi::Struct_dtv_property) -> u32 {
    unsafe {
        let mut property = property;
        *property.u.data()
    }
}

fn make_ffi_property(cmd: u32, value: u32) -> ffi::Struct_dtv_property {
    let mut p = ffi::Struct_dtv_property { cmd: cmd, ..Default::default() };
    unsafe {
        *p.u.data() = value;
    }
    p
}

#[derive(Copy,Clone,Debug,PartialEq)]
pub enum Lna {
    LnaOff,
    LnaOn,
    LnaAuto,
}

impl Into<u32> for Lna {
    fn into(self) -> u32 {
        match self {
            // On and off variants as defined by Linux DVB documentation
            Lna::LnaOff => 0,
            Lna::LnaOn => 1,
            Lna::LnaAuto => ffi::LNA_AUTO
        }
    }
}

impl FromProperty for Lna {
    fn from_property(property_name: GetProperty, property: ffi::Struct_dtv_property) -> PropertyMappingResult<Self> {
        match ffi_property_data(property) {
            0 => Ok(Lna::LnaOff),
            1 => Ok(Lna::LnaOn),
            ffi::LNA_AUTO => Ok(Lna::LnaAuto),
            value => Err(PropertyMappingError::UnrecognizedValue(property_name, value))
        }
    }
}

impl IntoPropertyValue for Lna {
    fn into_property_value(value_str: &str) -> PropertyValueResult<Self> {
        match value_str {
            "LnaOff" => Ok(Lna::LnaOff),
            "LnaOn" => Ok(Lna::LnaOn),
            "LnaAuto" => Ok(Lna::LnaAuto),
            _ => Err(PropertyValueError::UnrecognizedValue)
        }
    }
}

#[derive(Copy,Clone,Debug,PartialEq)]
pub enum StatValue {
    ScaleNotAvailable,
    Counter(u64),
    Decibel(i64),
    Relative(u64),
}

const STAT_COUNT: usize = 4;

#[derive(Copy,Clone,Debug,PartialEq)]
pub struct Stat {
    len: u8,
    stats: [StatValue; STAT_COUNT]
}

impl Stat {
    pub fn stats(&self) -> &[StatValue] {
        &self.stats[0..self.len as usize]
    }
}

impl FromProperty for Stat {
    fn from_property(property_name: GetProperty, property: ffi::Struct_dtv_property) -> PropertyMappingResult<Self> {
        let (len, ffi_stats) = unsafe {
            let mut property = property;
            ((*property.u.st()).len, (*property.u.st()).stat)
        };
        if len as usize > STAT_COUNT {
            return Err(PropertyMappingError::StatError(property_name));
        }
        let mut stats = [StatValue::ScaleNotAvailable; STAT_COUNT];
        for i in 0..len as usize {
            let mut ffi_stat = ffi_stats[i];
            let uvalue: u64 = unsafe { *ffi_stat.uvalue() };
            let svalue: i64 = unsafe { *ffi_stat.svalue() };
            let scale = ffi_stat.scale as u32;
            stats[i] = match scale {
                ffi::FE_SCALE_NOT_AVAILABLE => StatValue::ScaleNotAvailable,
                ffi::FE_SCALE_COUNTER => StatValue::Counter(uvalue),
                ffi::FE_SCALE_DECIBEL => StatValue::Decibel(svalue),
                ffi::FE_SCALE_RELATIVE => StatValue::Relative(uvalue),
                _ => return Err(PropertyMappingError::StatError(property_name))
            };
        }
        Ok(Stat { len: len, stats: stats })
    }
}

const BUFFER_SIZE: usize = 32;

#[derive(Copy,Clone,Debug,PartialEq)]
pub struct SupportedDeliverySystems {
    len: u32,
    delsys: [DeliverySystem; BUFFER_SIZE]
}

impl SupportedDeliverySystems {
    pub fn delivery_systems(&self) -> &[DeliverySystem] {
        &self.delsys[0..self.len as usize]
    }
}

impl FromProperty for SupportedDeliverySystems {
    fn from_property(property_name: GetProperty, property: ffi::Struct_dtv_property) -> PropertyMappingResult<Self> {
        let (len, buffer) = unsafe {
            let mut property = property;
            ((*property.u.buffer()).len, (*property.u.buffer()).data)
        };
        if len as usize > BUFFER_SIZE {
            return Err(PropertyMappingError::BufferError(property_name));
        }
        let mut delsys = [DeliverySystem::SysUndefined; BUFFER_SIZE];
        for i in 0..len as usize {
            let mut tmp: ffi::Struct_dtv_property = Default::default();
            unsafe { *tmp.u.data() = buffer[i] as u32; }
            delsys[i] = try!(FromProperty::from_property(property_name, tmp));
        }
        Ok(SupportedDeliverySystems { len: len, delsys: delsys })
    }
}

#[derive(Copy,Clone,Debug,PartialEq)]
pub struct ApiVersion {
    pub major: u8,
    pub minor: u8
}

impl FromProperty for ApiVersion {
    #[allow(unused_variables)]
    fn from_property(property_name: GetProperty, property: ffi::Struct_dtv_property) -> PropertyMappingResult<Self> {
        let data = ffi_property_data(property);
        let major = (data >> 8) & 0xff;
        let minor = data & 0xff;
        Ok(ApiVersion { major: major as u8, minor: minor as u8 })
    }
}

#[test]
fn ffi_property_generation() {
    let mut property = make_ffi_property(123, 456);
    assert_eq!(property.cmd, 123);
    let data = unsafe { *property.u.data() };
    assert_eq!(data, 456);
}

#[test]
fn str_to_property() {
    let property = make_set_property_value("DtvModulation", "Qam128").unwrap();
    assert_eq!(property, SetPropertyValue::DtvModulation(Modulation::Qam128));
}
<|endoftext|>


<commit_before>use nix::unistd::*;
use nix::unistd::ForkResult::*;
use nix::sys::signal::*;
use nix::sys::wait::*;
use libc::_exit;

#[test]
fn test_wait_signal() {
    #[allow(unused_variables)]
    let m = ::FORK_MTX.lock().expect("Mutex got poisoned by another test");

    // Safe: The child only calls `pause` and/or `_exit`, which are async-signal-safe.
    match fork() {
      Ok(Child) => pause().unwrap_or_else(|_| unsafe { _exit(123) }),
      Ok(Parent { child }) => {
          kill(child, Some(SIGKILL)).ok().expect("Error: Kill Failed");
          assert_eq!(waitpid(child, None), Ok(WaitStatus::Signaled(child, SIGKILL, false)));
      },
      // panic, fork should never fail unless there is a serious problem with the OS
      Err(_) => panic!("Error: Fork Failed")
    }
}

#[test]
fn test_wait_exit() {
    #[allow(unused_variables)]
    let m = ::FORK_MTX.lock().expect("Mutex got poisoned by another test");

    // Safe: Child only calls `_exit`, which is async-signal-safe.
    match fork() {
      Ok(Child) => unsafe { _exit(12); },
      Ok(Parent { child }) => {
          assert_eq!(waitpid(child, None), Ok(WaitStatus::Exited(child, 12)));
      },
      // panic, fork should never fail unless there is a serious problem with the OS
      Err(_) => panic!("Error: Fork Failed")
    }
}

#[cfg(any(target_os = "linux", target_os = "android"))]
// FIXME: qemu-user doesn't implement ptrace on most arches
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
mod ptrace {
    use nix::sys::ptrace::*;
    use nix::sys::ptrace::ptrace::*;
    use nix::sys::signal::*;
    use nix::sys::wait::*;
    use nix::unistd::*;
    use nix::unistd::ForkResult::*;
    use std::{ptr, process};

    fn ptrace_child() -> ! {
        let _ = ptrace(PTRACE_TRACEME, Pid::from_raw(0), ptr::null_mut(), ptr::null_mut());
        // As recommended by ptrace(2), raise SIGTRAP to pause the child
        // until the parent is ready to continue
        let _ = raise(SIGTRAP);
        process::exit(0)
    }

    fn ptrace_parent(child: Pid) {
        // Wait for the raised SIGTRAP
        assert_eq!(waitpid(child, None), Ok(WaitStatus::Stopped(child, SIGTRAP)));
        // We want to test a syscall stop and a PTRACE_EVENT stop
        assert!(ptrace_setoptions(child, PTRACE_O_TRACESYSGOOD | PTRACE_O_TRACEEXIT).is_ok());

        // First, stop on the next system call, which will be exit()
        assert!(ptrace(PTRACE_SYSCALL, child, ptr::null_mut(), ptr::null_mut()).is_ok());
        assert_eq!(waitpid(child, None), Ok(WaitStatus::PtraceSyscall(child)));
        // Then get the ptrace event for the process exiting
        assert!(ptrace(PTRACE_CONT, child, ptr::null_mut(), ptr::null_mut()).is_ok());
        assert_eq!(waitpid(child, None), Ok(WaitStatus::PtraceEvent(child, SIGTRAP, PTRACE_EVENT_EXIT)));
        // Finally get the normal wait() result, now that the process has exited
        assert!(ptrace(PTRACE_CONT, child, ptr::null_mut(), ptr::null_mut()).is_ok());
        assert_eq!(waitpid(child, None), Ok(WaitStatus::Exited(child, 0)));
    }

    #[test]
    fn test_wait_ptrace() {
        #[allow(unused_variables)]
        let m = ::FORK_MTX.lock().expect("Mutex got poisoned by another test");

        match fork() {
            Ok(Child) => ptrace_child(),
            Ok(Parent { child }) => ptrace_parent(child),
            Err(_) => panic!("Error: Fork Failed")
        }
    }
}
<commit_msg>Replace remaining process::exit with libc::_exit<commit_after>use nix::unistd::*;
use nix::unistd::ForkResult::*;
use nix::sys::signal::*;
use nix::sys::wait::*;
use libc::_exit;

#[test]
fn test_wait_signal() {
    #[allow(unused_variables)]
    let m = ::FORK_MTX.lock().expect("Mutex got poisoned by another test");

    // Safe: The child only calls `pause` and/or `_exit`, which are async-signal-safe.
    match fork() {
      Ok(Child) => pause().unwrap_or_else(|_| unsafe { _exit(123) }),
      Ok(Parent { child }) => {
          kill(child, Some(SIGKILL)).ok().expect("Error: Kill Failed");
          assert_eq!(waitpid(child, None), Ok(WaitStatus::Signaled(child, SIGKILL, false)));
      },
      // panic, fork should never fail unless there is a serious problem with the OS
      Err(_) => panic!("Error: Fork Failed")
    }
}

#[test]
fn test_wait_exit() {
    #[allow(unused_variables)]
    let m = ::FORK_MTX.lock().expect("Mutex got poisoned by another test");

    // Safe: Child only calls `_exit`, which is async-signal-safe.
    match fork() {
      Ok(Child) => unsafe { _exit(12); },
      Ok(Parent { child }) => {
          assert_eq!(waitpid(child, None), Ok(WaitStatus::Exited(child, 12)));
      },
      // panic, fork should never fail unless there is a serious problem with the OS
      Err(_) => panic!("Error: Fork Failed")
    }
}

#[cfg(any(target_os = "linux", target_os = "android"))]
// FIXME: qemu-user doesn't implement ptrace on most arches
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
mod ptrace {
    use nix::sys::ptrace::*;
    use nix::sys::ptrace::ptrace::*;
    use nix::sys::signal::*;
    use nix::sys::wait::*;
    use nix::unistd::*;
    use nix::unistd::ForkResult::*;
    use std::{ptr, process};
    use libc::_exit;

    fn ptrace_child() -> ! {
        let _ = ptrace(PTRACE_TRACEME, Pid::from_raw(0), ptr::null_mut(), ptr::null_mut());
        // As recommended by ptrace(2), raise SIGTRAP to pause the child
        // until the parent is ready to continue
        let _ = raise(SIGTRAP);
        unsafe { _exit(0) }
    }

    fn ptrace_parent(child: Pid) {
        // Wait for the raised SIGTRAP
        assert_eq!(waitpid(child, None), Ok(WaitStatus::Stopped(child, SIGTRAP)));
        // We want to test a syscall stop and a PTRACE_EVENT stop
        assert!(ptrace_setoptions(child, PTRACE_O_TRACESYSGOOD | PTRACE_O_TRACEEXIT).is_ok());

        // First, stop on the next system call, which will be exit()
        assert!(ptrace(PTRACE_SYSCALL, child, ptr::null_mut(), ptr::null_mut()).is_ok());
        assert_eq!(waitpid(child, None), Ok(WaitStatus::PtraceSyscall(child)));
        // Then get the ptrace event for the process exiting
        assert!(ptrace(PTRACE_CONT, child, ptr::null_mut(), ptr::null_mut()).is_ok());
        assert_eq!(waitpid(child, None), Ok(WaitStatus::PtraceEvent(child, SIGTRAP, PTRACE_EVENT_EXIT)));
        // Finally get the normal wait() result, now that the process has exited
        assert!(ptrace(PTRACE_CONT, child, ptr::null_mut(), ptr::null_mut()).is_ok());
        assert_eq!(waitpid(child, None), Ok(WaitStatus::Exited(child, 0)));
    }

    #[test]
    fn test_wait_ptrace() {
        #[allow(unused_variables)]
        let m = ::FORK_MTX.lock().expect("Mutex got poisoned by another test");

        match fork() {
            Ok(Child) => ptrace_child(),
            Ok(Parent { child }) => ptrace_parent(child),
            Err(_) => panic!("Error: Fork Failed")
        }
    }
}
<|endoftext|>


<commit_before>use std::ptr;
use std::fs;
use std::io::{Write, SeekFrom, Seek};
use std::os::unix::prelude::AsRawFd;
use mmap::{MemoryMap, MapOption};
use std::thread;

// from crates.io
extern crate mmap;
extern crate libc;

fn toggle(data: *mut u8, led_pin: u32) {
    unsafe {
        *(data.offset(0x40000000 + 0x30) as *mut u32) ^= 1 << led_pin;
    }
}

fn main() {
    let size: usize = 0x407FFFFF; // i want to access the memory from 0x40000000 to 0x407FFFFF

    let mut f = fs::OpenOptions::new().read(true)
                                      .write(true)
                                      //.create(true) ... i guess this should be disables!?
                                      .open("/dev/mem")
                                      .unwrap();

    // Allocate space in the file first
    //f.seek(SeekFrom::Start(size as u64)).unwrap();
    //f.write_all(&[0]).unwrap();
    //f.seek(SeekFrom::Start(0)).unwrap();

    let mmap_opts = &[
        // Then make the mapping *public* so it is written back to the file
        MapOption::MapNonStandardFlags(libc::consts::os::posix88::MAP_SHARED),
        MapOption::MapReadable,
        MapOption::MapWritable,
        MapOption::MapFd(f.as_raw_fd()),
    ];

    let mmap = MemoryMap::new(size, mmap_opts).unwrap();

    let data = mmap.data();

    if data.is_null() {
        panic!("Could not access data from memory mapped file")
    }
    else {
        println!("successful data access to memory mapped file");
    }

    //let src = "Hello!";
    //let src_data = src.as_bytes();

    //unsafe {
    //    ptr::copy(src_data.as_ptr(), data, src_data.len());
    //}

    while (true) {
        toggle(data, 3);
        thread::sleep_ms(200);
    }
}<commit_msg>updated code<commit_after>use std::ptr;
use std::fs;
use std::io::{Write, SeekFrom, Seek};
use std::os::unix::prelude::AsRawFd;
use mmap::{MemoryMap, MapOption};
use std::thread;

// from crates.io
extern crate mmap;
extern crate libc;

fn toggle(data: *mut u8, led_pin: u32) {
    unsafe {
        *(data.offset(/*0x40000000 +*/ 0x30) as *mut u32) ^= 1 << led_pin;
    }
}

fn main() {
    let size: usize = 0x7FFFFF; // i want to access the memory from 0x40000000 to 0x407FFFFF

    let mut f = fs::OpenOptions::new().read(true)
                                      .write(true)
                                      //.create(true) ... i guess this should be disables!?
                                      .open("/dev/mem")
                                      .unwrap();

    // Allocate space in the file first
    //f.seek(SeekFrom::Start(size as u64)).unwrap();
    //f.write_all(&[0]).unwrap();
    //f.seek(SeekFrom::Start(0)).unwrap();

    let mmap_opts = &[
        // Then make the mapping *public* so it is written back to the file
        MapOption::MapNonStandardFlags(libc::MAP_SHARED), //consts::os::posix88::MAP_SHARED),
        MapOption::MapNonStandardFlags(libc::consts::os::extra::O_SYNC),
        MapOption::MapReadable,
        MapOption::MapWritable,
        MapOption::MapOffset(0x40000000),
        MapOption::MapFd(f.as_raw_fd()),
    ];

    let mmap = MemoryMap::new(size, mmap_opts).unwrap();

    let data = mmap.data();

    if data.is_null() {
        panic!("Could not access data from memory mapped file")
    }
    else {
        println!("successful data access to memory mapped file");
    }

    //let src = "Hello!";
    //let src_data = src.as_bytes();

    //unsafe {
    //    ptr::copy(src_data.as_ptr(), data, src_data.len());
    //}

    while (true) {
        toggle(data, 3);
        thread::sleep_ms(200);
    }
}<|endoftext|>


<commit_before>use chrono::Utc;
use conduit_cookie::RequestSession;

use super::prelude::*;

use crate::middleware::log_request;
use crate::models::{ApiToken, User};
use crate::util::errors::{
    account_locked, forbidden, internal, AppError, AppResult, ChainError,
    InsecurelyGeneratedTokenRevoked,
};

#[derive(Debug)]
pub struct AuthenticatedUser {
    user: User,
    token_id: Option<i32>,
}

impl AuthenticatedUser {
    pub fn user_id(&self) -> i32 {
        self.user.id
    }

    pub fn api_token_id(&self) -> Option<i32> {
        self.token_id
    }

    pub fn user(self) -> User {
        self.user
    }
}

/// The Origin header (https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Origin)
/// is sent with CORS requests and POST requests, and indicates where the request comes from.
/// We don't want to accept authenticated requests that originated from other sites, so this
/// function returns an error if the Origin header doesn't match what we expect "this site" to
/// be: https://crates.io in production, or http://localhost:port/ in development.
fn verify_origin(req: &dyn RequestExt) -> AppResult<()> {
    let headers = req.headers();
    let allowed_origins = &req.app().config.allowed_origins;

    let bad_origin = headers
        .get_all(header::ORIGIN)
        .iter()
        .filter_map(|value| value.to_str().ok())
        .find(|value| !allowed_origins.iter().any(|it| it == value));

    if let Some(bad_origin) = bad_origin {
        let error_message = format!(
            "only same-origin requests can be authenticated. got {:?}",
            bad_origin
        );
        return Err(internal(&error_message))
            .chain_error(|| Box::new(forbidden()) as Box<dyn AppError>);
    }
    Ok(())
}

fn authenticate_user(req: &dyn RequestExt) -> AppResult<AuthenticatedUser> {
    let conn = req.db_conn()?;

    let session = req.session();
    let user_id_from_session = session.get("user_id").and_then(|s| s.parse::<i32>().ok());

    let (user_id, token_id) = if let Some(id) = user_id_from_session {
        (id, None)
    } else {
        // Otherwise, look for an `Authorization` header on the request
        let maybe_authorization: Option<String> = {
            req.headers()
                .get(header::AUTHORIZATION)
                .and_then(|h| h.to_str().ok())
                .map(|h| h.to_string())
        };
        if let Some(header_value) = maybe_authorization {
            let (user_id, token_id) = ApiToken::find_by_api_token(&conn, &header_value)
                .map(|token| (token.user_id, Some(token.id)))
                .map_err(|e| {
                    if e.is::<InsecurelyGeneratedTokenRevoked>() {
                        e
                    } else {
                        e.chain(internal("invalid token")).chain(forbidden())
                    }
                })?;

            (user_id, token_id)
        } else {
            // Unable to authenticate the user
            return Err(internal("no cookie session or auth header found")).chain_error(forbidden);
        }
    };

    let user = User::find(&conn, user_id)
        .chain_error(|| internal("user_id from cookie or token not found in database"))?;

    Ok(AuthenticatedUser { user, token_id })
}

impl<'a> UserAuthenticationExt for dyn RequestExt + 'a {
    /// Obtain `AuthenticatedUser` for the request or return an `Forbidden` error
    fn authenticate(&mut self) -> AppResult<AuthenticatedUser> {
        verify_origin(self)?;

        let authenticated_user = authenticate_user(self)?;

        if let Some(reason) = &authenticated_user.user.account_lock_reason {
            let still_locked = if let Some(until) = authenticated_user.user.account_lock_until {
                until > Utc::now().naive_utc()
            } else {
                true
            };
            if still_locked {
                return Err(account_locked(
                    &reason,
                    authenticated_user.user.account_lock_until,
                ));
            }
        }

        log_request::add_custom_metadata(self, "uid", authenticated_user.user_id());
        if let Some(id) = authenticated_user.api_token_id() {
            log_request::add_custom_metadata(self, "tokenid", id);
        }

        Ok(authenticated_user)
    }
}
<commit_msg>controllers::util: Simplify `ApiToken::find_by_api_token()` call<commit_after>use chrono::Utc;
use conduit_cookie::RequestSession;

use super::prelude::*;

use crate::middleware::log_request;
use crate::models::{ApiToken, User};
use crate::util::errors::{
    account_locked, forbidden, internal, AppError, AppResult, ChainError,
    InsecurelyGeneratedTokenRevoked,
};

#[derive(Debug)]
pub struct AuthenticatedUser {
    user: User,
    token_id: Option<i32>,
}

impl AuthenticatedUser {
    pub fn user_id(&self) -> i32 {
        self.user.id
    }

    pub fn api_token_id(&self) -> Option<i32> {
        self.token_id
    }

    pub fn user(self) -> User {
        self.user
    }
}

/// The Origin header (https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Origin)
/// is sent with CORS requests and POST requests, and indicates where the request comes from.
/// We don't want to accept authenticated requests that originated from other sites, so this
/// function returns an error if the Origin header doesn't match what we expect "this site" to
/// be: https://crates.io in production, or http://localhost:port/ in development.
fn verify_origin(req: &dyn RequestExt) -> AppResult<()> {
    let headers = req.headers();
    let allowed_origins = &req.app().config.allowed_origins;

    let bad_origin = headers
        .get_all(header::ORIGIN)
        .iter()
        .filter_map(|value| value.to_str().ok())
        .find(|value| !allowed_origins.iter().any(|it| it == value));

    if let Some(bad_origin) = bad_origin {
        let error_message = format!(
            "only same-origin requests can be authenticated. got {:?}",
            bad_origin
        );
        return Err(internal(&error_message))
            .chain_error(|| Box::new(forbidden()) as Box<dyn AppError>);
    }
    Ok(())
}

fn authenticate_user(req: &dyn RequestExt) -> AppResult<AuthenticatedUser> {
    let conn = req.db_conn()?;

    let session = req.session();
    let user_id_from_session = session.get("user_id").and_then(|s| s.parse::<i32>().ok());

    let (user_id, token_id) = if let Some(id) = user_id_from_session {
        (id, None)
    } else {
        // Otherwise, look for an `Authorization` header on the request
        let maybe_authorization: Option<String> = {
            req.headers()
                .get(header::AUTHORIZATION)
                .and_then(|h| h.to_str().ok())
                .map(|h| h.to_string())
        };
        if let Some(header_value) = maybe_authorization {
            let token = ApiToken::find_by_api_token(&conn, &header_value).map_err(|e| {
                if e.is::<InsecurelyGeneratedTokenRevoked>() {
                    e
                } else {
                    e.chain(internal("invalid token")).chain(forbidden())
                }
            })?;

            (token.user_id, Some(token.id))
        } else {
            // Unable to authenticate the user
            return Err(internal("no cookie session or auth header found")).chain_error(forbidden);
        }
    };

    let user = User::find(&conn, user_id)
        .chain_error(|| internal("user_id from cookie or token not found in database"))?;

    Ok(AuthenticatedUser { user, token_id })
}

impl<'a> UserAuthenticationExt for dyn RequestExt + 'a {
    /// Obtain `AuthenticatedUser` for the request or return an `Forbidden` error
    fn authenticate(&mut self) -> AppResult<AuthenticatedUser> {
        verify_origin(self)?;

        let authenticated_user = authenticate_user(self)?;

        if let Some(reason) = &authenticated_user.user.account_lock_reason {
            let still_locked = if let Some(until) = authenticated_user.user.account_lock_until {
                until > Utc::now().naive_utc()
            } else {
                true
            };
            if still_locked {
                return Err(account_locked(
                    &reason,
                    authenticated_user.user.account_lock_until,
                ));
            }
        }

        log_request::add_custom_metadata(self, "uid", authenticated_user.user_id());
        if let Some(id) = authenticated_user.api_token_id() {
            log_request::add_custom_metadata(self, "tokenid", id);
        }

        Ok(authenticated_user)
    }
}
<|endoftext|>