<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::{run, os};
use std::io::buffered::BufferedReader;
use std::path::posix::Path;
use std::option::Option;
use std::io::{stdin, stdio, process, IoError, io_error, File, Truncate, Write};
use std::run::Process;
use std::io::process::ProcessExit;
use std::run::ProcessOptions;
use extra::getopts;

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

fn is_dead(exit_port : &Option<Port<ProcessExit>>) -> bool {
    let mut dead = false;
    match *exit_port {
        Some(ref p) => {
            match p.try_recv() {
                Some (exitstatus) => {
                    if (exitstatus.success()) {
                        dead = true;
                    }
                },
                _ => {}
            }
        },
        _ => {},
    };
    dead
}

trait Command {
    fn run(&mut self) -> Option<Process>;
}

struct CmdProcess {
    command     : ~str,
    args        : ~[~str],
    stdin       : Option<i32>,
    stdout      : Option<i32>,
    exit_status : Option<process::ProcessExit>,
}
impl CmdProcess {
    fn new(command: &str,
           args: ~[~str],
           stdin : Option<i32>,
           stdout : Option<i32>)
        -> Option<CmdProcess>
    {
        if (cmd_exists(command)) {
            Some(CmdProcess {
                command     : command.to_owned(),
                args        : args.to_owned(),
                stdin       : stdin,
                stdout      : stdout,
                exit_status : None,
            })
        }
        else { None }
    }
}
impl Command for CmdProcess {
    fn run(&mut self) -> Option<Process> {
        let command = self.command.to_owned();
        let args = self.args.to_owned();
        let options = ProcessOptions {
            env    : None,
            dir    : None,
            in_fd  : self.stdin,
            out_fd : self.stdout,
            err_fd : None,
        };
        Process::new(command, args, options)
    }
}

struct BackgroundProcess {
    command      : ~str,
    args         : ~[~str],
    exit_status  : Option<ProcessExit>,
    exit_port    : Option<Port<ProcessExit>>,
    kill_chan    : Option<Chan<int>>,
}
impl BackgroundProcess {
    fn new(command: &str, args: ~[~str]) -> Option<BackgroundProcess> {
        if (cmd_exists(command)) {
            Some(BackgroundProcess {
                command: command.to_owned(),
                args: args.to_owned(),
                exit_status: None,
                exit_port: None,
                kill_chan: None,
            })
        }
        else { None }
    }
    fn run(&mut self) {
        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) => {
                    let signal = killport.recv();
                    let mut error = None;
                    match signal {
                        9 => {
                            io_error::cond.trap(|e: IoError| {
                                error = Some(e);
                                }).inside(|| {
                                    process.force_destroy()
                                })
                        }
                        15 => {
                            io_error::cond.trap(|e: IoError| {
                                error = Some(e);
                                }).inside(|| {
                                    process.force_destroy()
                                })
                        }
                        _ => {}
                    }
                    chan.try_send_deferred(process.finish());
                }
                None => {
                }
            }
        });
        self.exit_port = Some(port);
        self.kill_chan = Some(killchan);
    }
}

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

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);
            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() {
            if is_dead(&cmd.exit_port) {
                dead.push(i);
            }
            i += 1;
        }
        for &p in dead.iter() {
            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.try_send_deferred(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) {
        if cmd_line.contains_char('>') {
            self.parse_r_redirect(cmd_line);
        }
        else if cmd_line.contains_char('<') {
            self.parse_l_redirect(cmd_line);
        }
        else {
            let argv: ~[~str] =
                cmd_line.split(' ').filter_map(|x| if x != ""
                    {
                        Some(x.to_owned())
                    }
                    else {
                        None
                    }).to_owned_vec();
            if argv.len() > 0 {
                self.parse_process(argv);
            }
        }
    }

    fn parse_process(&mut self, mut argv : ~[~str]) {
        let program: ~str = argv.remove(0);
        if argv.len() > 0 {
            let last = argv.last().to_owned();
            if last == ~"&" {
                argv.pop();
                self.make_bg_process(program, argv);
            }
            else {
                self.make_fg_process(program, argv);
            }
        }
        else {
            self.make_fg_process(program, argv);
        }
    }

    fn parse_r_redirect(&mut self, cmd_line : &str) {
        let pair : ~[&str] = cmd_line.rsplit('>').collect();
        let file = pair[0].trim();
        let command = pair[1].trim();
        let mut argv: ~[~str] =
            command.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);
            match CmdProcess::new(program, argv, None, None) {
                Some(mut cmdprocess) => {
                    match cmdprocess.run() {
                        Some(mut process) => {
                            self.write_output_to_file(
                                process.finish_with_output(),
                                file);
                        }
                        None => {
                            println!("Failed spawning a process for {:s}.", command)
                        }
                    }
                }
                None => {
                    println!("{:s} is not a command.", command)
                }
            }
        }
    }

    fn write_output_to_file(&mut self,
                            output : std::run::ProcessOutput,
                            filename : &str) {
        if output.status.success() {
            match File::open_mode(&Path::new(filename),
                                  std::io::Truncate,
                                  std::io::Write)
            {
                Some(mut file) => {
                    file.write(output.output);
                }
                None =>{
                    println!("Opening {:s} failed!", filename);
                }
            }
        }
        else {
            println!("{:?}", output.error);
        }
    }

    fn parse_l_redirect(&mut self, cmd_line : &str) {
        let pair : ~[&str] = cmd_line.rsplit('<').collect();
        let filename = pair[0].trim();
        let command = pair[1].trim();
        let mut argv: ~[~str] =
            command.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);
            match CmdProcess::new(program, argv, None, Some(1)) {
                Some(mut cmdprocess) => {
                    match cmdprocess.run() {
                        Some(mut process) => {
                            match File::open_mode(&Path::new(filename),
                                                  std::io::Append,
                                                  std::io::ReadWrite)
                            {
                                Some(file) => {
                                    let proc_input = process.input();
                                    let mut file_buffer = BufferedReader::new(file);
                                    proc_input.write(file_buffer.read_to_end());
                                }
                                None => {}
                            }
                        }
                        None => {
                            println!("Failed spawning a process for {:s}.", command)
                        }
                    }
                }
                None => {
                    println!("{:s} is not a command.", command)
                }
            }
        }
    }

    fn make_fg_process(&mut self, program : ~str, argv : ~[~str]) {
        match CmdProcess::new(program, argv, Some(0), Some(1)) {
            Some(mut cmdprocess) => {
                cmdprocess.run();
            }
            None              => { }
        }
    }

    fn make_bg_process(&mut self, program : ~str, argv : ~[~str]) {
        match BackgroundProcess::new(program, argv) {
            Some(mut process) => {
                process.run();
                self.processes.push(~process);
            }
            None          => { }
        }
    }
}

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>Partially working pipes<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::{run, os};
use std::io::buffered::BufferedReader;
use std::path::posix::Path;
use std::option::Option;
use std::io::{stdin, stdio, process, IoError, io_error, File, Truncate, Write};
use std::run::Process;
use std::io::process::ProcessExit;
use std::run::ProcessOptions;
use extra::getopts;

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

fn is_dead(exit_port : &Option<Port<ProcessExit>>) -> bool {
    let mut dead = false;
    match *exit_port {
        Some(ref p) => {
            match p.try_recv() {
                Some (exitstatus) => {
                    if (exitstatus.success()) {
                        dead = true;
                    }
                },
                _ => {}
            }
        },
        _ => {},
    };
    dead
}

trait Command {
    fn run(&mut self) -> Option<Process>;
}

struct CmdProcess {
    command     : ~str,
    args        : ~[~str],
    stdin       : Option<i32>,
    stdout      : Option<i32>,
    exit_status : Option<process::ProcessExit>,
}
impl CmdProcess {
    fn new(command: &str,
           args: ~[~str],
           stdin : Option<i32>,
           stdout : Option<i32>)
        -> Option<CmdProcess>
    {
        if (cmd_exists(command)) {
            Some(CmdProcess {
                command     : command.to_owned(),
                args        : args.to_owned(),
                stdin       : stdin,
                stdout      : stdout,
                exit_status : None,
            })
        }
        else { None }
    }
}
impl Command for CmdProcess {
    fn run(&mut self) -> Option<Process> {
        let command = self.command.to_owned();
        let args = self.args.to_owned();
        let options = ProcessOptions {
            env    : None,
            dir    : None,
            in_fd  : self.stdin,
            out_fd : self.stdout,
            err_fd : None,
        };
        Process::new(command, args, options)
    }
}

struct BackgroundProcess {
    command      : ~str,
    args         : ~[~str],
    exit_status  : Option<ProcessExit>,
    exit_port    : Option<Port<ProcessExit>>,
    kill_chan    : Option<Chan<int>>,
}
impl BackgroundProcess {
    fn new(command: &str, args: ~[~str]) -> Option<BackgroundProcess> {
        if (cmd_exists(command)) {
            Some(BackgroundProcess {
                command: command.to_owned(),
                args: args.to_owned(),
                exit_status: None,
                exit_port: None,
                kill_chan: None,
            })
        }
        else { None }
    }
    fn run(&mut self) {
        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) => {
                    let signal = killport.recv();
                    let mut error = None;
                    match signal {
                        9 => {
                            io_error::cond.trap(|e: IoError| {
                                error = Some(e);
                                }).inside(|| {
                                    process.force_destroy()
                                })
                        }
                        15 => {
                            io_error::cond.trap(|e: IoError| {
                                error = Some(e);
                                }).inside(|| {
                                    process.force_destroy()
                                })
                        }
                        _ => {}
                    }
                    chan.try_send_deferred(process.finish());
                }
                None => {
                }
            }
        });
        self.exit_port = Some(port);
        self.kill_chan = Some(killchan);
    }
}

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

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);
            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() {
            if is_dead(&cmd.exit_port) {
                dead.push(i);
            }
            i += 1;
        }
        for &p in dead.iter() {
            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.try_send_deferred(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] = self.split_words(cmd_line);
        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) {
        if cmd_line.contains_char('>') {
            self.parse_r_redirect(cmd_line);
        }
        else if cmd_line.contains_char('<') {
            self.parse_l_redirect(cmd_line);
        }
        else if cmd_line.contains_char('|') {
            self.parse_pipeline(cmd_line);
        }
        else {
            let argv: ~[~str] = self.split_words(cmd_line);
            if argv.len() > 0 {
                self.parse_process(argv);
            }
        }
    }

    fn parse_process(&mut self, mut argv : ~[~str]) {
        let program: ~str = argv.remove(0);
        if argv.len() > 0 {
            let last = argv.last().to_owned();
            if last == ~"&" {
                argv.pop();
                self.make_bg_process(program, argv);
            }
            else {
                self.make_fg_process(program, argv);
            }
        }
        else {
            self.make_fg_process(program, argv);
        }
    }

    fn parse_pipeline(&mut self, cmd_line : &str) -> Option<~run::Process> {
        let pair : ~[&str] = cmd_line.rsplitn('|', 1).collect();
        let one = pair[0].trim();
        println!("one: {:?}", one);
        if pair.len() > 1 {
            let mut argv: ~[~str] = self.split_words(one);
            if argv.len() > 0 {
                let two = self.parse_pipeline(pair[1].trim());
                let program: ~str = argv.remove(0);
                println!("{:?} -> {:?}", pair[1].trim(), one);
                self.pipe_input(program, argv, two)
            }
            else {
                None
            }
        }
        else {
            self.make_process(one)
        }
    }

    fn pipe_input(&mut self, program : &str, argv : ~[~str], two : Option<~run::Process>)
            -> Option<~run::Process> {
        println("Piping input");
        match CmdProcess::new(program, argv, None, Some(1)) {
            Some(mut cmdprocess) => {
                match cmdprocess.run() {
                    Some(mut process) => {
                        match two {
                            Some(mut p2) => {
                                println("We have a p2");
                                let output = p2.finish_with_output();
                                if output.status.success() {
                                    process.input().write(output.output);
                                    process.close_input();
                                    process.finish();
                                }
                                Some(~process)
                            }
                            None => {
                                println("We have NO p2");
                                Some(~process)
                            }
                        }
                    }
                    None => {
                        println!("Failed spawning a process for {:s}.", program) ;
                        None
                    }
                }
            }
            None => {
                println!("{:s} is not a command.", program);
                None
            }
        }
    }

    // For pipeline - first item. Returns Maybe Process.
    fn make_process(&mut self, cmd_line : &str) -> Option<~run::Process>{
        println!("Making first process for {:s}", cmd_line);
        let mut argv: ~[~str] = self.split_words(cmd_line);
        if argv.len() > 0 {
            let program: ~str = argv.remove(0);
            match CmdProcess::new(program, argv, None, None) {
                Some(mut cmdprocess) => {
                    match cmdprocess.run() {
                        Some(process) => {
                            Some(~process)
                        }
                        None => {
                            println!("Failed spawning a process for {:s}.", program);
                            None
                        }
                    }
                }
                None => {
                    println!("{:s} is not a command.", program) ;
                    None
                }
            }
        }
        else {None}
    }

    fn split_words(&mut self, word : &str) -> ~[~str] {
        word.split(' ').filter_map(
            |x| if x != "" { Some(x.to_owned()) }
                else { None }
            ).to_owned_vec()
    }

    fn parse_r_redirect(&mut self, cmd_line : &str) {
        let pair : ~[&str] = cmd_line.rsplit('>').collect();
        let file = pair[0].trim();
        let command = pair[1].trim();
        let mut argv: ~[~str] = self.split_words(command);
        if argv.len() > 0 {
            let program: ~str = argv.remove(0);
            match CmdProcess::new(program, argv, None, None) {
                Some(mut cmdprocess) => {
                    match cmdprocess.run() {
                        Some(mut process) => {
                            self.write_output_to_file(
                                process.finish_with_output(),
                                file);
                        }
                        None => {
                            println!("Failed spawning a process for {:s}.", command)
                        }
                    }
                }
                None => {
                    println!("{:s} is not a command.", command)
                }
            }
        }
    }

    fn write_output_to_file(&mut self,
                            output : std::run::ProcessOutput,
                            filename : &str) {
        if output.status.success() {
            match File::open_mode(&Path::new(filename),
                                  std::io::Truncate,
                                  std::io::Write)
            {
                Some(mut file) => {
                    file.write(output.output);
                }
                None =>{
                    println!("Opening {:s} failed!", filename);
                }
            }
        }
        else {
            println!("{:?}", output.error);
        }
    }

    fn parse_l_redirect(&mut self, cmd_line : &str) {
        let pair : ~[&str] = cmd_line.rsplit('<').collect();
        let filename = pair[0].trim();
        let command = pair[1].trim();
        let mut argv: ~[~str] = self.split_words(command);
        if argv.len() > 0 {
            let program: ~str = argv.remove(0);
            match CmdProcess::new(program, argv, None, Some(1)) {
                Some(mut cmdprocess) => {
                    match cmdprocess.run() {
                        Some(mut process) => {
                            match File::open_mode(&Path::new(filename),
                                                  std::io::Append,
                                                  std::io::ReadWrite)
                            {
                                Some(file) => {
                                    let proc_input = process.input();
                                    let mut file_buffer = BufferedReader::new(file);
                                    proc_input.write(file_buffer.read_to_end());
                                }
                                None => {}
                            }
                        }
                        None => {
                            println!("Failed spawning a process for {:s}.", command)
                        }
                    }
                }
                None => {
                    println!("{:s} is not a command.", command)
                }
            }
        }
    }

    fn make_fg_process(&mut self, program : ~str, argv : ~[~str]) {
        match CmdProcess::new(program, argv, Some(0), Some(1)) {
            Some(mut cmdprocess) => {
                cmdprocess.run();
            }
            None => { }
        }
    }

    fn make_bg_process(&mut self, program : ~str, argv : ~[~str]) {
        match BackgroundProcess::new(program, argv) {
            Some(mut process) => {
                process.run();
                self.processes.push(~process);
            }
            None          => { }
        }
    }
}

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>//
// 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::{run, os};
use std::io::buffered::BufferedReader;
use std::path::posix::Path;
use std::option::Option;
use std::io::{stdin, stdio, process, IoError, io_error, File, Truncate, Write};
use std::run::Process;
use std::io::process::ProcessExit;
use std::run::ProcessOptions;
use extra::getopts;

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

fn is_dead(exit_port : &Option<Port<ProcessExit>>) -> bool {
    let mut dead = false;
    match *exit_port {
        Some(ref p) => {
            match p.try_recv() {
                Some (exitstatus) => {
                    if (exitstatus.success()) {
                        dead = true;
                    }
                },
                _ => {}
            }
        },
        _ => {},
    };
    dead
}

trait Command {
    fn run(&mut self) -> Option<Process>;
}

struct CmdProcess {
    command     : ~str,
    args        : ~[~str],
    stdin       : Option<i32>,
    stdout      : Option<i32>,
    exit_status : Option<process::ProcessExit>,
}
impl CmdProcess {
    fn new(command: &str,
           args: ~[~str],
           stdin : Option<i32>,
           stdout : Option<i32>)
        -> Option<CmdProcess>
    {
        if (cmd_exists(command)) {
            Some(CmdProcess {
                command     : command.to_owned(),
                args        : args.to_owned(),
                stdin       : stdin,
                stdout      : stdout,
                exit_status : None,
            })
        }
        else { None }
    }
}
impl Command for CmdProcess {
    fn run(&mut self) -> Option<Process> {
        let command = self.command.to_owned();
        let args = self.args.to_owned();
        let options = ProcessOptions {
            env    : None,
            dir    : None,
            in_fd  : self.stdin,
            out_fd : self.stdout,
            err_fd : None,
        };
        Process::new(command, args, options)
    }
}

struct BackgroundProcess {
    command      : ~str,
    args         : ~[~str],
    exit_status  : Option<ProcessExit>,
    exit_port    : Option<Port<ProcessExit>>,
    kill_chan    : Option<Chan<int>>,
}
impl BackgroundProcess {
    fn new(command: &str, args: ~[~str]) -> Option<BackgroundProcess> {
        if (cmd_exists(command)) {
            Some(BackgroundProcess {
                command: command.to_owned(),
                args: args.to_owned(),
                exit_status: None,
                exit_port: None,
                kill_chan: None,
            })
        }
        else { None }
    }
    fn run(&mut self) {
        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) => {
                    let signal = killport.recv();
                    let mut error = None;
                    match signal {
                        9 => {
                            io_error::cond.trap(|e: IoError| {
                                error = Some(e);
                                }).inside(|| {
                                    process.force_destroy()
                                })
                        }
                        15 => {
                            io_error::cond.trap(|e: IoError| {
                                error = Some(e);
                                }).inside(|| {
                                    process.force_destroy()
                                })
                        }
                        _ => {}
                    }
                    chan.try_send_deferred(process.finish());
                }
                None => {
                }
            }
        });
        self.exit_port = Some(port);
        self.kill_chan = Some(killchan);
    }
}

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

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);
            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() {
            if is_dead(&cmd.exit_port) {
                dead.push(i);
            }
            i += 1;
        }
        for &p in dead.iter() {
            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.try_send_deferred(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] = self.split_words(cmd_line);
        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) {
        if cmd_line.contains_char('>') {
            self.parse_r_redirect(cmd_line);
        }
        else if cmd_line.contains_char('<') {
            self.parse_l_redirect(cmd_line);
        }
        else if cmd_line.contains_char('|') {
            self.parse_pipeline(cmd_line);
        }
        else {
            let argv: ~[~str] = self.split_words(cmd_line);
            if argv.len() > 0 {
                self.parse_process(argv);
            }
        }
    }

    fn parse_process(&mut self, mut argv : ~[~str]) -> Option<Process>{
        let program: ~str = argv.remove(0);
        if argv.len() > 0 {
            let last = argv.last().to_owned();
            if last == ~"&" {
                argv.pop();
                self.make_bg_process(program, argv);
                None
            }
            else {
                self.make_process(program, argv, Some(0), Some(1))
            }
        }
        else {
            self.make_process(program, argv, Some(0), Some(1))
        }
    }

    fn parse_pipeline(&mut self, cmd_line : &str) -> Option<~run::Process> {
        let pair : ~[&str] = cmd_line.rsplitn('|', 1).collect();
        let one = pair[0].trim();
        if pair.len() > 1 {
            let mut argv: ~[~str] = self.split_words(one);
            if argv.len() > 0 {
                let two = self.parse_pipeline(pair[1].trim());
                let program: ~str = argv.remove(0);
                if cmd_line.contains_char('|') {
                    self.pipe_input(program, argv, two)
                }
                else {
                    self.pipe_input(program, argv, two)
                }
            }
            else {
                None
            }
        }
        else {
            self.make_first_process(one)
        }
    }

    fn pipe_input(&mut self, program : &str, argv : ~[~str], two : Option<~run::Process>)
            -> Option<~run::Process> {
        match CmdProcess::new(program, argv, None, Some(1)) {
            Some(mut cmdprocess) => {
                match cmdprocess.run() {
                    Some(mut process) => {
                        match two {
                            Some(mut p2) => {
                                let output = p2.finish_with_output();
                                if output.status.success() {
                                    process.input().write(output.output);
                                    process.close_input();
                                    process.finish();
                                }
                                Some(~process)
                            }
                            None => {
                                Some(~process)
                            }
                        }
                    }
                    None => {
                        println!("Failed spawning a process for {:s}.", program) ;
                        None
                    }
                }
            }
            None => {
                println!("{:s} is not a command.", program);
                None
            }
        }
    }

    // For pipeline - first item. Returns Maybe Process.
    fn make_first_process(&mut self, cmd_line : &str) -> Option<~run::Process>{
        let mut argv: ~[~str] = self.split_words(cmd_line);
        if argv.len() > 0 {
            let program: ~str = argv.remove(0);
            match self.make_process(program, argv, None, None) {
                Some(process) => {
                    Some(~process)
                }
                None => {
                    println!("Failed spawning a process for {:s}.", program);
                    None
                }
            }
        }
        else {None}
    }

    fn split_words(&mut self, word : &str) -> ~[~str] {
        word.split(' ').filter_map(
            |x| if x != "" { Some(x.to_owned()) }
                else { None }
            ).to_owned_vec()
    }

    fn parse_r_redirect(&mut self, cmd_line : &str) {
        let pair : ~[&str] = cmd_line.rsplit('>').collect();
        let file = pair[0].trim();
        let command = pair[1].trim();
        let mut argv: ~[~str] = self.split_words(command);
        if argv.len() > 0 {
            let program: ~str = argv.remove(0);
            match self.make_process(program, argv, None, None) {
                Some(mut process) => {
                    self.write_output_to_file(
                        process.finish_with_output(),
                        file);
                }
                None => {
                    println!("Failed spawning a process for {:s}.", command)
                }
            }
        }
    }

    fn write_output_to_file(&mut self,
                            output : std::run::ProcessOutput,
                            filename : &str) {
        if output.status.success() {
            match File::open_mode(&Path::new(filename),
                                  std::io::Truncate,
                                  std::io::Write)
            {
                Some(mut file) => {
                    file.write(output.output);
                }
                None =>{
                    println!("Opening {:s} failed!", filename);
                }
            }
        }
        else {
            println!("{:?}", output.error);
        }
    }

    fn parse_l_redirect(&mut self, cmd_line : &str) {
        let pair : ~[&str] = cmd_line.rsplit('<').collect();
        let filename = pair[0].trim();
        let command = pair[1].trim();
        let mut argv: ~[~str] = self.split_words(command);
        if argv.len() > 0 {
            let program: ~str = argv.remove(0);
            match self.make_process(program, argv, None, Some(1)) {
                Some(mut process) => {
                    match File::open_mode(&Path::new(filename),
                                            std::io::Append,
                                            std::io::ReadWrite)
                    {
                        Some(file) => {
                            let proc_input = process.input();
                            let mut file_buffer = BufferedReader::new(file);
                            proc_input.write(file_buffer.read_to_end());
                        }
                        None => {}
                    }
                }
                None => {
                    println!("Failed spawning a process for {:s}.", command)
                }
            }
        }
    }

    fn make_process(&mut self,
                    program : &str,
                    argv : ~[~str],
                    stdin: Option<i32>,
                    stdout: Option<i32>) -> Option<run::Process> {
        match CmdProcess::new(program, argv, stdin, stdout) {
            Some(mut cmdprocess) => {
                cmdprocess.run()
            }
            None => { None }
        }
    }

    fn make_bg_process(&mut self, program : &str, argv : ~[~str]) {
        match BackgroundProcess::new(program, argv) {
            Some(mut process) => {
                process.run();
                self.processes.push(~process);
            }
            None          => { }
        }
    }
}

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>refactor program, args -> Cmd<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::{run, os};
use std::io::buffered::BufferedReader;
use std::path::posix::Path;
use std::option::Option;
use std::io::{stdin, stdio, IoError, io_error, File, Truncate, Write};
use std::run::Process;
use std::io::process::ProcessExit;
use std::run::ProcessOptions;
use extra::getopts;

struct Cmd {
    program : ~str,
    argv : ~[~str],
}

impl Cmd {
    fn new(cmd_name: &str) -> Option<Cmd> {
        let mut argv: ~[~str] = split_words(cmd_name);
        if argv.len() > 0 {
            let program: ~str = argv.remove(0);
            let argv : ~[~str] = argv;
            Some(Cmd {
                program : program,
                argv : argv,
            })
        }
        else {
            None
        }
    }
}

trait Command {
    fn run(&mut self) -> Option<Process>;
}

struct CmdProcess {
    command     : ~str,
    args        : ~[~str],
    stdin       : Option<i32>,
    stdout      : Option<i32>,
}
impl CmdProcess {
    fn new(cmd : Cmd,
           stdin : Option<i32>,
           stdout : Option<i32>)
        -> Option<CmdProcess>
    {
        if (cmd_exists(&cmd)) {
            Some(CmdProcess {
                command     : cmd.program.to_owned(),
                args        : cmd.argv.to_owned(),
                stdin       : stdin,
                stdout      : stdout,
            })
        }
        else { None }
    }

    fn set_stdin(&mut self, stdin : Option<i32>) {
        self.stdin = stdin;
    }

    fn set_stdout(&mut self, stdout : Option<i32>) {
        self.stdout = stdout;
    }
}
impl Command for CmdProcess {
    fn run(&mut self) -> Option<Process> {
        let command = self.command.to_owned();
        let args = self.args.to_owned();
        let options = ProcessOptions {
            env    : None,
            dir    : None,
            in_fd  : self.stdin,
            out_fd : self.stdout,
            err_fd : None,
        };
        Process::new(command, args, options)
    }
}

struct BackgroundProcess {
    command      : ~str,
    args         : ~[~str],
    exit_port    : Option<Port<ProcessExit>>,
    kill_chan    : Option<Chan<int>>,
}
impl BackgroundProcess {
    fn new(cmd : Cmd) -> Option<BackgroundProcess> {
        if (cmd_exists(&cmd)) {
            Some(BackgroundProcess {
                command: cmd.program.to_owned(),
                args: cmd.argv.to_owned(),
                exit_port: None,
                kill_chan: None,
            })
        }
        else { None }
    }
    fn run(&mut self) {
        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) => {
                let signal = killport.recv();
                let mut error = None;
                match signal {
                9 => {
                    io_error::cond.trap(|e: IoError| {
                        error = Some(e);
                        }).inside(|| {
                            process.force_destroy()
                        })
                }
                15 => {
                    io_error::cond.trap(|e: IoError| {
                        error = Some(e);
                        }).inside(|| {
                            process.force_destroy()
                        })
                }
                _ => {
                }}
                chan.try_send_deferred(process.finish());
            }
            None => {
            }}
        });
        self.exit_port = Some(port);
        self.kill_chan = Some(killchan);
    }
}

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

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);
            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() {
            if is_dead(&cmd.exit_port) {
                dead.push(i);
            }
            i += 1;
        }
        for &p in dead.iter() {
            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.try_send_deferred(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] = split_words(cmd_line);
        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) {
        if cmd_line.contains_char('>') {
            parse_r_redirect(cmd_line);
        }
        else if cmd_line.contains_char('<') {
            parse_l_redirect(cmd_line);
        }
        else if cmd_line.contains_char('|') {
            self.parse_pipeline(cmd_line);
        }
        else {
            self.parse_process(cmd_line);
        }
    }

    fn parse_process(&mut self, cmd_line : &str) -> Option<Process>{
        match Cmd::new(cmd_line) {
        Some(cmd) => {
            if (cmd.argv.len() > 0 && cmd.argv.last() == &~"&") {
                let mut argv = cmd.argv.to_owned();
                argv.pop();
                self.make_bg_process(Cmd{
                    program:cmd.program,
                    argv:argv});
                None
            }
            else {
                make_process(cmd, Some(0), Some(1))
            }
        }
        None => {
            None
        }}
    }

    fn parse_pipeline(&mut self, cmd_line : &str) -> Option<~run::Process> {
        let pair : ~[&str] = cmd_line.rsplitn('|', 1).collect();
        if pair.len() > 1 {
            match Cmd::new(pair[0].trim()) {
            Some(cmd) => {
                let two = self.parse_pipeline(pair[1].trim());
                self.pipe_input(cmd, two)
            }
            None => {
                None
            }}
        }
        else {
            self.make_first_process(pair[0].trim())
        }
    }

    fn pipe_input(&mut self,
                  cmd : Cmd,
                  two : Option<~run::Process>) -> Option<~run::Process> {
        match make_process(cmd, None, Some(1)) {
        Some(mut process) => {
            match two {
            Some(mut p2) => {
                let output = p2.finish_with_output();
                if output.status.success() {
                    process.input().write(output.output);
                    process.close_input();
                    process.finish();
                }
                Some(~process)
            }
            None => {
                Some(~process)
            }}
        }
        None => {
            None
        }}
    }

    // For pipeline - first item. Returns Maybe Process.
    fn make_first_process(&mut self, cmd_line : &str) -> Option<~run::Process>{
        match Cmd::new(cmd_line) {
        Some(cmd) => {
            match make_process(cmd, None, None) {
            Some(process) => {
                Some(~process)
            }
            None => {
                None
            }}
        }
        None => {
            None
        }}
    }

    fn make_bg_process(&mut self, cmd : Cmd) {
        match BackgroundProcess::new(cmd) {
        Some(mut process) => {
            process.run();
            self.processes.push(~process);
        }
        None          => {
        }}
    }
}

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 cmd_exists(command : &Cmd) -> bool {
    let ret = run::process_output("which", [command.program.to_owned()]);
    return ret.expect("exit code error.").status.success();
}

fn is_dead(exit_port : &Option<Port<ProcessExit>>) -> bool {
    let mut dead = false;
    match *exit_port {
    Some(ref p) => {
        match p.try_recv() {
        Some (exitstatus) => {
            dead = exitstatus.success();
        },
        None => {
        }}
    }
    _ => {
    }}
    dead
}

fn split_words(word : &str) -> ~[~str] {
    word.split(' ').filter_map(
        |x| if x != "" { Some(x.to_owned()) } else { None }
        ).to_owned_vec()
}

fn make_process(cmd : Cmd,
                stdin: Option<i32>,
                stdout: Option<i32>) -> Option<run::Process> {
    match CmdProcess::new(cmd, stdin, stdout) {
    Some(mut cmdprocess) => {
        cmdprocess.run()
    }
    None => {
        None
    }}
}

fn parse_l_redirect(cmd_line : &str) {
    let pair : ~[&str] = cmd_line.rsplit('<').collect();
    let filename = pair[0].trim();
    match Cmd::new(pair[1].trim()) {
    Some(cmd) => {
        match make_process(cmd, None, Some(1)) {
        Some(mut process) => {
            match File::open_mode(&Path::new(filename),
                                    std::io::Append,
                                    std::io::ReadWrite) {
            Some(file) => {
                let proc_input = process.input();
                let mut file_buffer = BufferedReader::new(file);
                proc_input.write(file_buffer.read_to_end());
            }
            None => {
            }}
        }
        None => {
        }}
    }
    None => {
    }}
}

fn write_output_to_file(output : std::run::ProcessOutput,
                        filename : &str) {
    if output.status.success() {
        match File::open_mode(&Path::new(filename),
                                std::io::Truncate,
                                std::io::Write)
        {
            Some(mut file) => {
                file.write(output.output);
            }
            None =>{
                println!("Opening {:s} failed!", filename);
            }
        }
    }
    else {
        println!("{:?}", output.error);
    }
}

fn parse_r_redirect(cmd_line : &str) {
    let pair : ~[&str] = cmd_line.rsplit('>').collect();
    let file = pair[0].trim();
    //let command = pair[1].trim();
    match Cmd::new(pair[1].trim()) {
    Some(cmd) => {
    //let mut argv: ~[~str] = split_words(command);
        match make_process(cmd, None, None) {
        Some(mut process) => {
            write_output_to_file(
                process.finish_with_output(),
                file);
        }
        None => {
        }}
    }
    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>extern mod std;
use json = std::json;
use Json = std::json::Json;
use List = std::json::List;
use Number = std::json::Number;
struct Point {
	x: float,
	y: float
}

fn getSquareDistance(p1: Point, p2: Point) -> float {
	let dx : float = p1.x - p2.x;
	let dy : float = p1.y - p2.y;
	return dx * dx + dy * dy;
}

fn getSquareSegmentDistance(p: Point, p1: Point, p2: Point) -> float {
	let mut dxy = Point { x: p2.x - p1.x, y: p2.y-p1.x};
	let mut xy : Point = Point { x: p1.x, y: p1.y};
	 if dxy.x != 0.0 && dxy.y != 0.0 {
		let t : float =((p.x - p1.x) * dxy.x + (p.y - p1.y) * dxy.y) / (dxy.y * dxy.y + dxy.y * dxy.y);
		if t>1.0 {
			 xy = p2;
		}else if t>0.0 {
			 xy = Point { x: dxy.x * t + p1.x,y: dxy.y * t + p1.y};
		}else{
			 xy  = Point { x: p1.x,y:  p1.y};
		}
	}
	dxy = Point {x: (p.x - xy.x), y: (p.y - xy.y)};
	return dxy.x * dxy.x + dxy.x * dxy.y;
}
fn simplifyRadialDistance(points:~[Point], sqTolerance:float) -> ~[Point]{
	let mut i : uint = 1u;
	let len : uint = points.len();
	let mut prevPoint : Point = points[0u];
	let mut newPoints : ~[Point] = ~[prevPoint];
	let mut point : Point = points[i];
	loop {
		if (getSquareDistance(point, prevPoint) > sqTolerance) {
			newPoints.push(point);
			prevPoint = point;
		}
		i+=1;
		if (i < len) {
			point = points[i];
		}else{
			break;
		}
	}
	if (prevPoint.x != point.x && prevPoint.y != point.y) {
		newPoints.push(point);
	}
	return newPoints;
}
fn simplifyDouglasPeucker(points : ~[Point], sqTolerance : float) -> ~[Point]{
	let len : uint = points.len();
	let mut markers : ~[uint] = ~[];
	let mut first : uint = 0u;
	let mut last : uint = len - 1u;
	let mut firstStack : ~[uint] = ~[];
	let mut lastStack : ~[uint] = ~[];
	let mut newPoints : ~[Point] = ~[];
	markers[first] = 1u;
	markers[last] = 1u;
	loop {
		let mut maxSqDist : float = 0.0f;
		let mut i : uint = first + 1u;
		let mut index : uint = 0;
		while (i < last) {
			let sqDist :float  = getSquareSegmentDistance(
				points[i],
				points[first],
				points[last]
			);
			if (sqDist > maxSqDist) {
				index = i;
				maxSqDist = sqDist;
			}
			i += 1;
		}
		if (maxSqDist > sqTolerance) {
			markers[index] = 1u;
			firstStack.push(first);
			lastStack.push(index);
			firstStack.push(index);
			lastStack.push(last);
		}
		if(firstStack.len()>0u && lastStack.len()>0u){
			first = firstStack.pop();
			last = lastStack.pop();
		}else{
			break;
		};
	};
	markers.eachi(|j,marker|{
		if(*marker==1u){
			newPoints.push(points[j]);
		};
		true
	});
	return newPoints;
}
fn dealList(l:~[Json])->~[Point]{
	l.map(|b|{
		match *b{
			List([Number(x),Number(y)])=>Point{x:x,y:y},
			_=>Point{x:0.0,y:0.0}
		}
	})
}

fn dealJson (j:Json)->~[Point]{
	match j{
		List(l)=> dealList(l),
	_=>~[Point{x:0.0,y:0.0}]
	}
}

fn main() {
	let reader = io::stdin();
	match json::from_reader(reader){
		Ok(points)=> io::println(fmt!("from %?",dealJson(points))),
		Err(e)=>io::println(fmt!("%?",e))
	}
}
<commit_msg>workign<commit_after>extern mod std;
use json = std::json;
use Json = std::json::Json;
use List = std::json::List;
use Number = std::json::Number;
struct Point {
	x: float,
	y: float
}

fn getSquareDistance(p1: Point, p2: Point) -> float {
	let dx : float = p1.x - p2.x;
	let dy : float = p1.y - p2.y;
	return dx * dx + dy * dy;
}

fn getSquareSegmentDistance(p: Point, p1: Point, p2: Point) -> float {
	let mut dxy = Point { x: p2.x - p1.x, y: p2.y-p1.x};
	let mut xy : Point = Point { x: p1.x, y: p1.y};
	 if dxy.x != 0.0 && dxy.y != 0.0 {
		let t : float =((p.x - p1.x) * dxy.x + (p.y - p1.y) * dxy.y) / (dxy.y * dxy.y + dxy.y * dxy.y);
		if t>1.0 {
			 xy = p2;
		}else if t>0.0 {
			 xy = Point { x: dxy.x * t + p1.x,y: dxy.y * t + p1.y};
		}else{
			 xy  = Point { x: p1.x,y:  p1.y};
		}
	}
	dxy = Point {x: (p.x - xy.x), y: (p.y - xy.y)};
	return dxy.x * dxy.x + dxy.x * dxy.y;
}
fn simplifyRadialDistance(points:~[Point], sqTolerance:float) -> ~[Point]{
	let mut i : uint = 1u;
	let len : uint = points.len();
	let mut prevPoint : Point = points[0u];
	let mut newPoints : ~[Point] = ~[prevPoint];
	let mut point : Point = points[i];
	loop {
		if (getSquareDistance(point, prevPoint) > sqTolerance) {
			newPoints.push(point);
			prevPoint = point;
		}
		i+=1;
		if (i < len) {
			point = points[i];
		}else{
			break;
		}
	}
	if (prevPoint.x != point.x && prevPoint.y != point.y) {
		newPoints.push(point);
	}
	return newPoints;
}
fn simplifyDouglasPeucker(points : ~[Point], sqTolerance : float, hq:bool) -> ~[Point]{
	let pts:~[Point]=match hq {
		true=>points,
		_=>simplifyRadialDistance(points,sqTolerance)
	};
	let len : uint = vec::len(pts);
	io::println(fmt!("len:%?",len));
	let mut markers : ~[uint] = ~[0u, ..0x1000000];
	let mut first : uint = 0u;
	let mut last : uint = len - 1u;
	let mut firstStack : ~[uint] = ~[];
	let mut lastStack : ~[uint] = ~[];
	let mut newPoints : ~[Point] = ~[];
	markers[first] = 1u;
	markers[last] = 1u;
	loop {
		let mut maxSqDist : float = 0.0f;
		let mut i : uint = first + 1u;
		let mut index : uint = 0;
		while (i < last) {
			let sqDist :float  = getSquareSegmentDistance(
				pts[i],
				pts[first],
				pts[last]
			);
			if (sqDist > maxSqDist) {
				index = i;
				maxSqDist = sqDist;
			}
			i += 1;
		}
		if (maxSqDist > sqTolerance) {
			markers[index] = 1u;
			firstStack.push(first);
			lastStack.push(index);
			firstStack.push(index);
			lastStack.push(last);
		}
		if(firstStack.len()>0u && lastStack.len()>0u){
			first = firstStack.pop();
			last = lastStack.pop();
		}else{
			break;
		};
	};
	markers.eachi(|j,marker|{
		if(*marker==1u){
			newPoints.push(pts[j]);
		};
		true
	});
	return newPoints;
}
fn dealList(l:~[Json])->~[Point]{
	l.map(|b|{
		match *b{
			List([Number(x),Number(y)])=>Point{x:x,y:y},
			_=>Point{x:0.0,y:0.0}
		}
	})
}

fn dealJson (j:Json)->~[Point]{
	match j{
		List(l)=> dealList(l),
	_=>~[Point{x:0.0,y:0.0}]
	}
}

fn main() {
	let reader = io::stdin();
	match json::from_reader(reader){
		Ok(points)=> io::println(fmt!("from %?",vec::len(simplifyDouglasPeucker(dealJson(points),0.8f,false)))),
		Err(e)=>io::println(fmt!("%?",e))
	}
}
<|endoftext|>


<commit_before>//! Generates Rust code from IR.

use crate::ir::cc::RsIr;
use crate::ir::rs;
use std::io;

pub fn perform_codegen(
    db: &impl RsIr,
    mdl: &rs::Module,
    out: &mut impl io::Write,
) -> io::Result<()> {
    for (_, st) in mdl.structs(db) {
        st.gen(db, out)?;
    }
    Ok(())
}

trait Codegen {
    fn gen(&self, db: &impl RsIr, f: &mut impl io::Write) -> io::Result<()>;
}

impl Codegen for rs::Struct {
    fn gen(&self, db: &impl RsIr, f: &mut impl io::Write) -> io::Result<()> {
        writeln!(f, "#[repr(C, align({}))]", self.align)?;
        writeln!(f, "struct {} {{", self.name)?;
        for field in &self.fields {
            write!(f, "    {}: ", field.name)?;
            field.ty.gen(db, f)?;
            writeln!(f, ",")?;
        }
        writeln!(f, "}}")?;
        Ok(())
    }
}

impl Codegen for rs::Ty {
    fn gen(&self, _db: &impl RsIr, f: &mut impl io::Write) -> io::Result<()> {
        use rs::Ty::*;
        let name = match self {
            Error => "<error>",
            U8 => "u8",
            I8 => "i8",
            U16 => "u16",
            I16 => "i16",
            U32 => "u32",
            I32 => "i32",
            U64 => "u64",
            I64 => "i64",
            USize => "usize",
            ISize => "isize",
            F32 => "f32",
            F64 => "f64",
            Bool => "bool",
            Struct(_id) => unimplemented!(),
        };
        write!(f, "{}", name)
    }
}

#[cfg(test)]
mod tests {
    use crate::Session;

    #[test]
    fn pod() {
        let mut sess = Session::new();
        cpp_to_rs!(sess, {
            struct Pod {
                int a, b;
                char e;
                double c, d;
            };

            namespace rust_export {
              using ::Pod;
            }
        } => r#"
            #[repr(C, align(8))]
            struct Pod {
                a: i32,
                b: i32,
                e: i8,
                c: f64,
                d: f64,
            }
        "#);
    }
}
<commit_msg>Support codegenning struct names<commit_after>//! Generates Rust code from IR.

use crate::ir::cc::RsIr;
use crate::ir::rs;
use std::io;

pub fn perform_codegen(
    db: &impl RsIr,
    mdl: &rs::Module,
    out: &mut impl io::Write,
) -> io::Result<()> {
    for (_, st) in mdl.structs(db) {
        st.gen(db, out)?;
    }
    Ok(())
}

trait Codegen {
    fn gen(&self, db: &impl RsIr, f: &mut impl io::Write) -> io::Result<()>;
}

impl Codegen for rs::Struct {
    fn gen(&self, db: &impl RsIr, f: &mut impl io::Write) -> io::Result<()> {
        writeln!(f, "#[repr(C, align({}))]", self.align)?;
        writeln!(f, "struct {} {{", self.name)?;
        for field in &self.fields {
            write!(f, "    {}: ", field.name)?;
            field.ty.gen(db, f)?;
            writeln!(f, ",")?;
        }
        writeln!(f, "}}")?;
        Ok(())
    }
}

impl Codegen for rs::Ty {
    fn gen(&self, db: &impl RsIr, f: &mut impl io::Write) -> io::Result<()> {
        use rs::Ty::*;
        let name = match self {
            Error => "<error>",
            U8 => "u8",
            I8 => "i8",
            U16 => "u16",
            I16 => "i16",
            U32 => "u32",
            I32 => "i32",
            U64 => "u64",
            I64 => "i64",
            USize => "usize",
            ISize => "isize",
            F32 => "f32",
            F64 => "f64",
            Bool => "bool",
            Struct(id) => return write!(f, "{}", id.lookup(db).name),
        };
        write!(f, "{}", name)
    }
}

#[cfg(test)]
mod tests {
    use crate::Session;

    #[test]
    fn pod() {
        let mut sess = Session::new();
        cpp_to_rs!(sess, {
            struct Pod {
                int a, b;
                char e;
                double c, d;
            };

            namespace rust_export {
              using ::Pod;
            }
        } => r#"
            #[repr(C, align(8))]
            struct Pod {
                a: i32,
                b: i32,
                e: i8,
                c: f64,
                d: f64,
            }
        "#);
    }

    #[test]
    fn nested_struct() {
        let mut sess = Session::new();
        cpp_to_rs!(sess, {
            // TODO codegen a struct for Foo
            struct Foo {
                int a, b;
            };
            struct Bar {
                char c, d;
                Foo foo;
            };
            namespace rust_export {
                using ::Bar;
            }
        } => r#"
            #[repr(C, align(4))]
            struct Bar {
                c: i8,
                d: i8,
                foo: Foo,
            }
        "#);
    }
}
<|endoftext|>


<commit_before>use constants::*;
use std::fs;
use std::fs::File;
use std::io::Write;
use std::path::Path;

pub fn initialize() {
    println!("Initialize ...");

    let dir_name    = ".kic";
    let path_to_dir = Path::new(dir_name);
    if path_to_dir.exists() && path_to_dir.is_dir() {
        println!("  OK: \"{}\" directory has already exist.", dir_name);
    } else {
        match fs::create_dir(path_to_dir) {
            Ok(_)    => println!("  OK: Created \"{}\" directory.", dir_name),
            Err(why) => panic!("{:?}", why),
        }
    }

    let config_file    = "config.yml";
    let path_to_config = path_to_dir.clone().join(config_file);
    if path_to_config.exists() && path_to_config.is_file() {
        println!("  OK: \"{}\" file has already exist.", config_file);
    } else {
        match File::create(path_to_config) {
            Ok(mut fp) => {
                println!("  OK: Created \"{}\" file.", config_file);
                write_default_config(&mut fp);
            },
            Err(why) => panic!("{:?}", why),
        }
    }
}

fn write_default_config(fp: &mut File) {
    let contents = DEFAULT_CONFIG.to_string() +
"ignore:
  - Cargo.lock
  - Cargo.toml
  - README.md
  - src/
  - target/
";
    match fp.write(contents.as_bytes()) {
        Ok(_)    => {},
        Err(why) => panic!("{:?}", why),
    }
}

pub fn set_params() {
    println!("set parameters");
}

pub fn sweep() {
    println!("sweep");
}

pub fn burn() {
    println!("burn");
}

pub fn register_with_cron() {
    println!("register");
}

pub fn unregister_cron() {
    println!("unregister");
}

pub fn destroy() {
    println!("destroy");
}
<commit_msg>Create walk_dir() and Set default "ignore"<commit_after>use constants::*;
use std::ffi::OsString;
use std::fs;
use std::fs::File;
use std::io::Write;
use std::path::Path;

pub fn initialize() {
    println!("Initialize ...");

    let dir_name    = ".kic";
    let path_to_dir = Path::new(dir_name);
    if path_to_dir.exists() && path_to_dir.is_dir() {
        println!("  OK: \"{}\" directory has already exist.", dir_name);
    } else {
        match fs::create_dir(path_to_dir) {
            Ok(_)    => println!("  OK: Created \"{}\" directory.", dir_name),
            Err(why) => panic!("{:?}", why),
        }
    }

    let config_file    = "config.yml";
    let path_to_config = path_to_dir.clone().join(config_file);
    if path_to_config.exists() && path_to_config.is_file() {
        println!("  OK: \"{}\" file has already exist.", config_file);
    } else {
        match File::create(path_to_config) {
            Ok(mut fp) => {
                println!("  OK: Created \"{}\" file.", config_file);
                write_default_config(&mut fp);
            },
            Err(why) => panic!("{:?}", why),
        }
    }
}

fn write_default_config(fp: &mut File) {
    let mut files = walk_dir(".").iter()
        .map(|f| f.clone().into_string())
        .filter(|f| f.is_ok())
        .map(|f| f.unwrap())
        .collect::<Vec<String>>();
    files.sort();
    let ignore_config = files.iter()
        .map(|f| "  - ".to_string() + f + "\n")
        .fold("ignore:\n".to_string(), |config, elem| config + &elem);
    let contents = DEFAULT_CONFIG.to_string() + &ignore_config;
    match fp.write(contents.as_bytes()) {
        Ok(_)    => {},
        Err(why) => panic!("{:?}", why),
    }
}

// You will be enable to use std::fs::walk_dir instead of this function in rust 1.6.0 or later
fn walk_dir<P: AsRef<Path>>(p: P) -> Vec<OsString> {
    let dirs = match fs::read_dir(p) {
        Ok(ds)   => ds,
        Err(why) => panic!("{:?}", why),
    };
    let dirs = dirs.filter(|d| d.is_ok())
        .flat_map(|d| {
            let p = d.unwrap().path();
            if p.is_file() {
                vec![p.into_os_string()]
            } else {
                walk_dir(&p)
            }
        })
        .collect::<Vec<OsString>>();
    dirs
}

pub fn set_params() {
    println!("set parameters");
}

pub fn sweep() {
    println!("sweep");
}

pub fn burn() {
    println!("burn");
}

pub fn register_with_cron() {
    println!("register");
}

pub fn unregister_cron() {
    println!("unregister");
}

pub fn destroy() {
    println!("destroy");
}
<|endoftext|>


<commit_before>/* automatically generated by rust-bindgen */

use glut::bindgen::{glutCreateWindow, glutDestroyWindow, glutDisplayFunc, glutGet, glutGetWindow};
use glut::bindgen::{glutInit, glutInitDisplayMode, glutPostRedisplay, glutReshapeFunc};
use glut::bindgen::{glutReshapeWindow, glutSetWindow, glutSwapBuffers, glutTimerFunc};
use libc::*;
use dvec::DVec;
use ptr::{null, to_unsafe_ptr};
use str::to_bytes;
use task::local_data::{local_data_get, local_data_set};
use cast::reinterpret_cast;
use vec::raw::to_ptr;

/* FIXME: global variable glutStrokeRoman */

/* FIXME: global variable glutStrokeMonoRoman */

/* FIXME: global variable glutBitmap9By15 */

/* FIXME: global variable glutBitmap8By13 */

/* FIXME: global variable glutBitmapTimesRoman10 */

/* FIXME: global variable glutBitmapTimesRoman24 */

/* FIXME: global variable glutBitmapHelvetica10 */

/* FIXME: global variable glutBitmapHelvetica12 */

/* FIXME: global variable glutBitmapHelvetica18 */

pub type GLenum = i32;
pub type GLint = i32;
pub type GLfloat = f32;
pub type GLdouble = f64;

pub enum Window = c_int;

pub const DOUBLE: c_uint = 2 as c_uint;

const WINDOW_WIDTH: GLenum = 102;
const WINDOW_HEIGHT: GLenum = 103;

pub enum State {
    WindowWidth,
    WindowHeight
}

pub fn destroy<T>(_value: ~[T]) {
    // let it drop
}

pub fn init() {
    unsafe {
        let argc = 0 as c_int;
        let command = to_bytes(~"glut");
        let argv: (*u8, *u8) = (to_ptr(command), null());
        let argv_p = reinterpret_cast(&to_unsafe_ptr(&argv));

        glutInit(to_unsafe_ptr(&argc), argv_p);

        destroy(command);
    }
}

pub fn create_window(name: ~str) -> Window {
    unsafe {
        let bytes = to_bytes(name);
        return Window(glutCreateWindow(to_ptr(bytes) as *c_char));
    }
}

pub fn destroy_window(window: Window) {
    unsafe {
        glutDestroyWindow(*window);
    }
}

pub fn reshape_window(window: Window, width: c_int, height: c_int) {
    unsafe {
        let current_window = glutGetWindow();
        glutSetWindow(*window);
        glutReshapeWindow(width, height);
        glutSetWindow(current_window);
    }
}

pub fn display_callback_tls_key(_callback: @@fn()) {
    // Empty.
}

pub extern fn display_callback() {
    unsafe {
        let callback = local_data_get(display_callback_tls_key).get();
        (*callback)();
    }
}

pub fn display_func(callback: @fn()) {
    unsafe {
        local_data_set(display_callback_tls_key, @callback);
        glutDisplayFunc(display_callback);
    }
}

pub fn timer_callback_tls_key(_callback: @DVec<@fn()>) {
    // Empty.
}

pub extern fn timer_callback(index: int) {
    unsafe {
        let callbacks = local_data_get(timer_callback_tls_key).get();
        ((*callbacks)[index as uint])();
    }
}

pub fn timer_func(msecs: u32, callback: @fn()) {
    unsafe {
        let callbacks;
        match local_data_get(timer_callback_tls_key) {
            None => {
                callbacks = @DVec();
                local_data_set(timer_callback_tls_key, copy callbacks);
            }
            Some(existing_callbacks) => {
                callbacks = existing_callbacks;
            }
        }

        callbacks.push(callback);
        let index = (callbacks.len() - 1) as c_int;
        glutTimerFunc(msecs, timer_callback, index);
    }
}

pub fn reshape_callback_tls_key(_callback: @@fn(x: c_int, y: c_int)) {
    // Empty.
}

pub extern fn reshape_callback(++width: c_int, ++height: c_int) {
    unsafe {
        let callback = local_data_get(reshape_callback_tls_key).get();
        (*callback)(width, height);
    }
}

pub fn reshape_func(_window: Window, callback: @fn(x: c_int, y: c_int)) {
    unsafe {
        local_data_set(reshape_callback_tls_key, @callback);
        glutReshapeFunc(reshape_callback);
    }
}

#[cfg(target_os="macos")]
pub fn check_loop() {
    unsafe {
        ext::glutCheckLoop();
    }
}

#[cfg(target_os="linux")]
pub fn check_loop() {
    unsafe {
        ext::glutMainLoopEvent();
    }
}

pub fn init_display_mode(mode: c_uint) {
    unsafe {
        glutInitDisplayMode(mode);
    }
}

pub fn swap_buffers() {
    unsafe {
        glutSwapBuffers();
    }
}

pub fn post_redisplay() {
    unsafe {
        glutPostRedisplay();
    }
}

pub fn get(state: State) -> c_int {
    unsafe {
        let glut_state;
        match state {
            WindowWidth => glut_state = WINDOW_WIDTH,
            WindowHeight => glut_state = WINDOW_HEIGHT
        }
        glutGet(glut_state)
    }
}

#[cfg(target_os="macos")]
#[nolink]
#[link_args="-framework GLUT"]
pub extern mod dummy {
}

#[cfg(target_os="linux")]
#[link_name="glut"]
pub extern mod dummy {
}

#[cfg(target_os="macos")]
#[nolink]
pub extern mod ext {
    // Mac GLUT extension.
    fn glutCheckLoop();
}

#[cfg(target_os="linux")]
#[nolink]
pub extern mod ext {
    // freeglut extension.
    fn glutMainLoopEvent();
}

#[nolink]
pub extern mod bindgen {

pub fn glutInit(++argcp: *c_int, ++argv: **c_char);

pub fn glutInitDisplayMode(++mode: c_uint);

pub fn glutInitDisplayString(++string: *c_char);

pub fn glutInitWindowPosition(++x: c_int, ++y: c_int);

pub fn glutInitWindowSize(++width: c_int, ++height: c_int);

pub fn glutMainLoop();

pub fn glutCreateWindow(++title: *c_char) -> c_int;

pub fn glutCreateSubWindow(++win: c_int, ++x: c_int, ++y: c_int, ++width: c_int, ++height: c_int) -> c_int;

pub fn glutDestroyWindow(++win: c_int);

pub fn glutPostRedisplay();

pub fn glutPostWindowRedisplay(++win: c_int);

pub fn glutSwapBuffers();

pub fn glutGetWindow() -> c_int;

pub fn glutSetWindow(++win: c_int);

pub fn glutSetWindowTitle(++title: *c_char);

pub fn glutSetIconTitle(++title: *c_char);

pub fn glutPositionWindow(++x: c_int, ++y: c_int);

pub fn glutReshapeWindow(++width: c_int, ++height: c_int);

pub fn glutPopWindow();

pub fn glutPushWindow();

pub fn glutIconifyWindow();

pub fn glutShowWindow();

pub fn glutHideWindow();

pub fn glutFullScreen();

pub fn glutSetCursor(++cursor: c_int);

pub fn glutWarpPointer(++x: c_int, ++y: c_int);

pub fn glutEstablishOverlay();

pub fn glutRemoveOverlay();

pub fn glutUseLayer(++layer: GLenum);

pub fn glutPostOverlayRedisplay();

pub fn glutPostWindowOverlayRedisplay(++win: c_int);

pub fn glutShowOverlay();

pub fn glutHideOverlay();

pub fn glutCreateMenu(++arg1: *u8) -> c_int;

pub fn glutDestroyMenu(++menu: c_int);

pub fn glutGetMenu() -> c_int;

pub fn glutSetMenu(++menu: c_int);

pub fn glutAddMenuEntry(++label: *c_char, ++value: c_int);

pub fn glutAddSubMenu(++label: *c_char, ++submenu: c_int);

pub fn glutChangeToMenuEntry(++item: c_int, ++label: *c_char, ++value: c_int);

pub fn glutChangeToSubMenu(++item: c_int, ++label: *c_char, ++submenu: c_int);

pub fn glutRemoveMenuItem(++item: c_int);

pub fn glutAttachMenu(++button: c_int);

pub fn glutDetachMenu(++button: c_int);

pub fn glutDisplayFunc(++func: *u8);

pub fn glutReshapeFunc(++func: *u8);

pub fn glutKeyboardFunc(++func: *u8);

pub fn glutMouseFunc(++func: *u8);

pub fn glutMotionFunc(++func: *u8);

pub fn glutPassiveMotionFunc(++func: *u8);

pub fn glutEntryFunc(++func: *u8);

pub fn glutVisibilityFunc(++func: *u8);

pub fn glutIdleFunc(++func: *u8);

pub fn glutTimerFunc(++millis: c_uint, ++func: *u8, ++value: c_int);

pub fn glutMenuStateFunc(++func: *u8);

pub fn glutSpecialFunc(++func: *u8);

pub fn glutSpaceballMotionFunc(++func: *u8);

pub fn glutSpaceballRotateFunc(++func: *u8);

pub fn glutSpaceballButtonFunc(++func: *u8);

pub fn glutButtonBoxFunc(++func: *u8);

pub fn glutDialsFunc(++func: *u8);

pub fn glutTabletMotionFunc(++func: *u8);

pub fn glutTabletButtonFunc(++func: *u8);

pub fn glutMenuStatusFunc(++func: *u8);

pub fn glutOverlayDisplayFunc(++func: *u8);

pub fn glutWindowStatusFunc(++func: *u8);

pub fn glutKeyboardUpFunc(++func: *u8);

pub fn glutSpecialUpFunc(++func: *u8);

pub fn glutJoystickFunc(++func: *u8, ++pollInterval: c_int);

pub fn glutSetColor(++arg1: c_int, ++red: GLfloat, ++green: GLfloat, ++blue: GLfloat);

pub fn glutGetColor(++ndx: c_int, ++component: c_int) -> GLfloat;

pub fn glutCopyColormap(++win: c_int);

pub fn glutGet(++_type: GLenum) -> c_int;

pub fn glutDeviceGet(++_type: GLenum) -> c_int;

pub fn glutExtensionSupported(++name: *c_char) -> c_int;

pub fn glutGetModifiers() -> c_int;

pub fn glutLayerGet(++_type: GLenum) -> c_int;

pub fn glutGetProcAddress(++procName: *c_char) -> *c_void;

pub fn glutBitmapCharacter(++font: *c_void, ++character: c_int);

pub fn glutBitmapWidth(++font: *c_void, ++character: c_int) -> c_int;

pub fn glutStrokeCharacter(++font: *c_void, ++character: c_int);

pub fn glutStrokeWidth(++font: *c_void, ++character: c_int) -> c_int;

pub fn glutBitmapLength(++font: *c_void, ++string: *c_uchar) -> c_int;

pub fn glutStrokeLength(++font: *c_void, ++string: *c_uchar) -> c_int;

pub fn glutWireSphere(++radius: GLdouble, ++slices: GLint, ++stacks: GLint);

pub fn glutSolidSphere(++radius: GLdouble, ++slices: GLint, ++stacks: GLint);

pub fn glutWireCone(++base: GLdouble, ++height: GLdouble, ++slices: GLint, ++stacks: GLint);

pub fn glutSolidCone(++base: GLdouble, ++height: GLdouble, ++slices: GLint, ++stacks: GLint);

pub fn glutWireCube(++size: GLdouble);

pub fn glutSolidCube(++size: GLdouble);

pub fn glutWireTorus(++innerRadius: GLdouble, ++outerRadius: GLdouble, ++sides: GLint, ++rings: GLint);

pub fn glutSolidTorus(++innerRadius: GLdouble, ++outerRadius: GLdouble, ++sides: GLint, ++rings: GLint);

pub fn glutWireDodecahedron();

pub fn glutSolidDodecahedron();

pub fn glutWireTeapot(++size: GLdouble);

pub fn glutSolidTeapot(++size: GLdouble);

pub fn glutWireOctahedron();

pub fn glutSolidOctahedron();

pub fn glutWireTetrahedron();

pub fn glutSolidTetrahedron();

pub fn glutWireIcosahedron();

pub fn glutSolidIcosahedron();

pub fn glutVideoResizeGet(++param: GLenum) -> c_int;

pub fn glutSetupVideoResizing();

pub fn glutStopVideoResizing();

pub fn glutVideoResize(++x: c_int, ++y: c_int, ++width: c_int, ++height: c_int);

pub fn glutVideoPan(++x: c_int, ++y: c_int, ++width: c_int, ++height: c_int);

pub fn glutReportErrors();

pub fn glutIgnoreKeyRepeat(++ignore: c_int);

pub fn glutSetKeyRepeat(++repeatMode: c_int);

pub fn glutForceJoystickFunc();

pub fn glutGameModeString(++string: *c_char);

pub fn glutEnterGameMode() -> c_int;

pub fn glutLeaveGameMode();

pub fn glutGameModeGet(++mode: GLenum) -> c_int;

}
<commit_msg>Language changes.<commit_after>/* automatically generated by rust-bindgen */

use glut::bindgen::{glutCreateWindow, glutDestroyWindow, glutDisplayFunc, glutGet, glutGetWindow};
use glut::bindgen::{glutInit, glutInitDisplayMode, glutPostRedisplay, glutReshapeFunc};
use glut::bindgen::{glutReshapeWindow, glutSetWindow, glutSwapBuffers, glutTimerFunc};
use core::libc::*;
use core::dvec::DVec;
use core::ptr::{null, to_unsafe_ptr};
use core::str::to_bytes;
use core::task::local_data::{local_data_get, local_data_set};
use core::cast::reinterpret_cast;
use core::vec::raw::to_ptr;

/* FIXME: global variable glutStrokeRoman */

/* FIXME: global variable glutStrokeMonoRoman */

/* FIXME: global variable glutBitmap9By15 */

/* FIXME: global variable glutBitmap8By13 */

/* FIXME: global variable glutBitmapTimesRoman10 */

/* FIXME: global variable glutBitmapTimesRoman24 */

/* FIXME: global variable glutBitmapHelvetica10 */

/* FIXME: global variable glutBitmapHelvetica12 */

/* FIXME: global variable glutBitmapHelvetica18 */

pub type GLenum = i32;
pub type GLint = i32;
pub type GLfloat = f32;
pub type GLdouble = f64;

pub enum Window = c_int;

pub const DOUBLE: c_uint = 2 as c_uint;

const WINDOW_WIDTH: GLenum = 102;
const WINDOW_HEIGHT: GLenum = 103;

pub enum State {
    WindowWidth,
    WindowHeight
}

pub fn destroy<T>(_value: ~[T]) {
    // let it drop
}

pub fn init() {
    unsafe {
        let argc = 0 as c_int;
        let command = to_bytes(~"glut");
        let argv: (*u8, *u8) = (to_ptr(command), null());
        let argv_p = reinterpret_cast(&to_unsafe_ptr(&argv));

        glutInit(to_unsafe_ptr(&argc), argv_p);

        destroy(command);
    }
}

pub fn create_window(name: ~str) -> Window {
    unsafe {
        let bytes = to_bytes(name);
        return Window(glutCreateWindow(to_ptr(bytes) as *c_char));
    }
}

pub fn destroy_window(window: Window) {
    unsafe {
        glutDestroyWindow(*window);
    }
}

pub fn reshape_window(window: Window, width: c_int, height: c_int) {
    unsafe {
        let current_window = glutGetWindow();
        glutSetWindow(*window);
        glutReshapeWindow(width, height);
        glutSetWindow(current_window);
    }
}

pub fn display_callback_tls_key(_callback: @@fn()) {
    // Empty.
}

pub extern fn display_callback() {
    unsafe {
        let callback = local_data_get(display_callback_tls_key).get();
        (*callback)();
    }
}

pub fn display_func(callback: @fn()) {
    unsafe {
        local_data_set(display_callback_tls_key, @callback);
        glutDisplayFunc(display_callback);
    }
}

pub fn timer_callback_tls_key(_callback: @DVec<@fn()>) {
    // Empty.
}

pub extern fn timer_callback(index: int) {
    unsafe {
        let callbacks = local_data_get(timer_callback_tls_key).get();
        ((*callbacks)[index as uint])();
    }
}

pub fn timer_func(msecs: u32, callback: @fn()) {
    unsafe {
        let callbacks;
        match local_data_get(timer_callback_tls_key) {
            None => {
                callbacks = @DVec();
                local_data_set(timer_callback_tls_key, copy callbacks);
            }
            Some(existing_callbacks) => {
                callbacks = existing_callbacks;
            }
        }

        callbacks.push(callback);
        let index = (callbacks.len() - 1) as c_int;
        glutTimerFunc(msecs, timer_callback, index);
    }
}

pub fn reshape_callback_tls_key(_callback: @@fn(x: c_int, y: c_int)) {
    // Empty.
}

pub extern fn reshape_callback(++width: c_int, ++height: c_int) {
    unsafe {
        let callback = local_data_get(reshape_callback_tls_key).get();
        (*callback)(width, height);
    }
}

pub fn reshape_func(_window: Window, callback: @fn(x: c_int, y: c_int)) {
    unsafe {
        local_data_set(reshape_callback_tls_key, @callback);
        glutReshapeFunc(reshape_callback);
    }
}

#[cfg(target_os="macos")]
pub fn check_loop() {
    unsafe {
        ext::glutCheckLoop();
    }
}

#[cfg(target_os="linux")]
pub fn check_loop() {
    unsafe {
        ext::glutMainLoopEvent();
    }
}

pub fn init_display_mode(mode: c_uint) {
    unsafe {
        glutInitDisplayMode(mode);
    }
}

pub fn swap_buffers() {
    unsafe {
        glutSwapBuffers();
    }
}

pub fn post_redisplay() {
    unsafe {
        glutPostRedisplay();
    }
}

pub fn get(state: State) -> c_int {
    unsafe {
        let glut_state;
        match state {
            WindowWidth => glut_state = WINDOW_WIDTH,
            WindowHeight => glut_state = WINDOW_HEIGHT
        }
        glutGet(glut_state)
    }
}

#[cfg(target_os="macos")]
#[nolink]
#[link_args="-framework GLUT"]
pub extern mod dummy {
}

#[cfg(target_os="linux")]
#[link_name="glut"]
pub extern mod dummy {
}

#[cfg(target_os="macos")]
#[nolink]
pub extern mod ext {
    // Mac GLUT extension.
    fn glutCheckLoop();
}

#[cfg(target_os="linux")]
#[nolink]
pub extern mod ext {
    // freeglut extension.
    fn glutMainLoopEvent();
}

#[nolink]
pub extern mod bindgen {

pub fn glutInit(++argcp: *c_int, ++argv: **c_char);

pub fn glutInitDisplayMode(++mode: c_uint);

pub fn glutInitDisplayString(++string: *c_char);

pub fn glutInitWindowPosition(++x: c_int, ++y: c_int);

pub fn glutInitWindowSize(++width: c_int, ++height: c_int);

pub fn glutMainLoop();

pub fn glutCreateWindow(++title: *c_char) -> c_int;

pub fn glutCreateSubWindow(++win: c_int, ++x: c_int, ++y: c_int, ++width: c_int, ++height: c_int) -> c_int;

pub fn glutDestroyWindow(++win: c_int);

pub fn glutPostRedisplay();

pub fn glutPostWindowRedisplay(++win: c_int);

pub fn glutSwapBuffers();

pub fn glutGetWindow() -> c_int;

pub fn glutSetWindow(++win: c_int);

pub fn glutSetWindowTitle(++title: *c_char);

pub fn glutSetIconTitle(++title: *c_char);

pub fn glutPositionWindow(++x: c_int, ++y: c_int);

pub fn glutReshapeWindow(++width: c_int, ++height: c_int);

pub fn glutPopWindow();

pub fn glutPushWindow();

pub fn glutIconifyWindow();

pub fn glutShowWindow();

pub fn glutHideWindow();

pub fn glutFullScreen();

pub fn glutSetCursor(++cursor: c_int);

pub fn glutWarpPointer(++x: c_int, ++y: c_int);

pub fn glutEstablishOverlay();

pub fn glutRemoveOverlay();

pub fn glutUseLayer(++layer: GLenum);

pub fn glutPostOverlayRedisplay();

pub fn glutPostWindowOverlayRedisplay(++win: c_int);

pub fn glutShowOverlay();

pub fn glutHideOverlay();

pub fn glutCreateMenu(++arg1: *u8) -> c_int;

pub fn glutDestroyMenu(++menu: c_int);

pub fn glutGetMenu() -> c_int;

pub fn glutSetMenu(++menu: c_int);

pub fn glutAddMenuEntry(++label: *c_char, ++value: c_int);

pub fn glutAddSubMenu(++label: *c_char, ++submenu: c_int);

pub fn glutChangeToMenuEntry(++item: c_int, ++label: *c_char, ++value: c_int);

pub fn glutChangeToSubMenu(++item: c_int, ++label: *c_char, ++submenu: c_int);

pub fn glutRemoveMenuItem(++item: c_int);

pub fn glutAttachMenu(++button: c_int);

pub fn glutDetachMenu(++button: c_int);

pub fn glutDisplayFunc(++func: *u8);

pub fn glutReshapeFunc(++func: *u8);

pub fn glutKeyboardFunc(++func: *u8);

pub fn glutMouseFunc(++func: *u8);

pub fn glutMotionFunc(++func: *u8);

pub fn glutPassiveMotionFunc(++func: *u8);

pub fn glutEntryFunc(++func: *u8);

pub fn glutVisibilityFunc(++func: *u8);

pub fn glutIdleFunc(++func: *u8);

pub fn glutTimerFunc(++millis: c_uint, ++func: *u8, ++value: c_int);

pub fn glutMenuStateFunc(++func: *u8);

pub fn glutSpecialFunc(++func: *u8);

pub fn glutSpaceballMotionFunc(++func: *u8);

pub fn glutSpaceballRotateFunc(++func: *u8);

pub fn glutSpaceballButtonFunc(++func: *u8);

pub fn glutButtonBoxFunc(++func: *u8);

pub fn glutDialsFunc(++func: *u8);

pub fn glutTabletMotionFunc(++func: *u8);

pub fn glutTabletButtonFunc(++func: *u8);

pub fn glutMenuStatusFunc(++func: *u8);

pub fn glutOverlayDisplayFunc(++func: *u8);

pub fn glutWindowStatusFunc(++func: *u8);

pub fn glutKeyboardUpFunc(++func: *u8);

pub fn glutSpecialUpFunc(++func: *u8);

pub fn glutJoystickFunc(++func: *u8, ++pollInterval: c_int);

pub fn glutSetColor(++arg1: c_int, ++red: GLfloat, ++green: GLfloat, ++blue: GLfloat);

pub fn glutGetColor(++ndx: c_int, ++component: c_int) -> GLfloat;

pub fn glutCopyColormap(++win: c_int);

pub fn glutGet(++_type: GLenum) -> c_int;

pub fn glutDeviceGet(++_type: GLenum) -> c_int;

pub fn glutExtensionSupported(++name: *c_char) -> c_int;

pub fn glutGetModifiers() -> c_int;

pub fn glutLayerGet(++_type: GLenum) -> c_int;

pub fn glutGetProcAddress(++procName: *c_char) -> *c_void;

pub fn glutBitmapCharacter(++font: *c_void, ++character: c_int);

pub fn glutBitmapWidth(++font: *c_void, ++character: c_int) -> c_int;

pub fn glutStrokeCharacter(++font: *c_void, ++character: c_int);

pub fn glutStrokeWidth(++font: *c_void, ++character: c_int) -> c_int;

pub fn glutBitmapLength(++font: *c_void, ++string: *c_uchar) -> c_int;

pub fn glutStrokeLength(++font: *c_void, ++string: *c_uchar) -> c_int;

pub fn glutWireSphere(++radius: GLdouble, ++slices: GLint, ++stacks: GLint);

pub fn glutSolidSphere(++radius: GLdouble, ++slices: GLint, ++stacks: GLint);

pub fn glutWireCone(++base: GLdouble, ++height: GLdouble, ++slices: GLint, ++stacks: GLint);

pub fn glutSolidCone(++base: GLdouble, ++height: GLdouble, ++slices: GLint, ++stacks: GLint);

pub fn glutWireCube(++size: GLdouble);

pub fn glutSolidCube(++size: GLdouble);

pub fn glutWireTorus(++innerRadius: GLdouble, ++outerRadius: GLdouble, ++sides: GLint, ++rings: GLint);

pub fn glutSolidTorus(++innerRadius: GLdouble, ++outerRadius: GLdouble, ++sides: GLint, ++rings: GLint);

pub fn glutWireDodecahedron();

pub fn glutSolidDodecahedron();

pub fn glutWireTeapot(++size: GLdouble);

pub fn glutSolidTeapot(++size: GLdouble);

pub fn glutWireOctahedron();

pub fn glutSolidOctahedron();

pub fn glutWireTetrahedron();

pub fn glutSolidTetrahedron();

pub fn glutWireIcosahedron();

pub fn glutSolidIcosahedron();

pub fn glutVideoResizeGet(++param: GLenum) -> c_int;

pub fn glutSetupVideoResizing();

pub fn glutStopVideoResizing();

pub fn glutVideoResize(++x: c_int, ++y: c_int, ++width: c_int, ++height: c_int);

pub fn glutVideoPan(++x: c_int, ++y: c_int, ++width: c_int, ++height: c_int);

pub fn glutReportErrors();

pub fn glutIgnoreKeyRepeat(++ignore: c_int);

pub fn glutSetKeyRepeat(++repeatMode: c_int);

pub fn glutForceJoystickFunc();

pub fn glutGameModeString(++string: *c_char);

pub fn glutEnterGameMode() -> c_int;

pub fn glutLeaveGameMode();

pub fn glutGameModeGet(++mode: GLenum) -> c_int;

}
<|endoftext|>