<commit_before>extern crate clap;
extern crate quick_xml;

use clap::{Arg, App};

use std::fs::File;
use std::io::Write;
use std::io::BufReader;

use std::str;

use quick_xml::reader::Reader;
use quick_xml::events::Event;

fn main(){

    //Clap
    let matches = App::new("parse_ft_gfx_xml")
                        .version("0.1")
                        .about("Retrieve tags from factorytalk gfx-xml file!")
                        .author("Michael Groncki")
                        .arg(Arg::with_name("INPUT")
                            .help("Sets the input file to use")
                            .required(true)
                            .index(1))
                        .get_matches();

    //Input file
    let file_name_in = matches.value_of("INPUT").unwrap();
    println!(); println!("Using input file: {}", file_name_in); println!();
    let input = File::open(file_name_in).unwrap();

    //Output file
    let file_name_out = format!("{}{}{}", "tagnames_", file_name_in, ".txt");
    let mut output = File::create(file_name_out).unwrap();

    //let input = File::open("MachineParameter_TabControl1.xml").unwrap();

    let buffered = BufReader::new(input);

    let mut reader = Reader::from_reader(buffered);
    reader.trim_text(true);

    let mut buf = Vec::new();

    let mut tag_names:Vec<String> = Vec::new(); //save all tags found during search here

    // The `Reader` does not implement `Iterator` because it outputs borrowed data (`Cow`s)
    loop {
        match reader.read_event(&mut buf) {
            // Ok(Event::Start(ref e)) => {

            //     match e.name() {
            //         b"group" => {
            //             let my_result = e.attributes().map(|a| a.unwrap()).collect::<Vec<_>>();

            //             for attrib in e.attributes() {

            //                 let my_attrib:quick_xml::events::attributes::Attribute = attrib.unwrap();

            //                 let my_key = str::from_utf8(my_attrib.key).unwrap();
            //                 let my_value = str::from_utf8(my_attrib.value).unwrap();

            //                 if my_key == "isReferenceObject" {
            //                     if my_value == "true" {
            //                         // println!("The group is reference object!");
            //                     }
            //                 }
            //             }

            //             for rs in &my_result {
            //                 if str::from_utf8(rs.key).unwrap() == "isReferenceObject" {
            //                     // println!("{:?}", str::from_utf8(rs.key).unwrap());
            //                 }
            //             }
            //         }

            //         _ => (),
            //     }
            // },
            Ok(Event::Empty(ref e)) => {

                match e.name() {
                    b"connection" => {
                        let my_result = e.attributes().map(|a| a.unwrap()).collect::<Vec<_>>();
                        // println!("attributes values: {:?} - {:?}", str::from_utf8(my_result[1].key).unwrap(), str::from_utf8(my_result[1].value).unwrap());
                        tag_names.push(String::from(str::from_utf8(my_result[1].value).unwrap()));
                    },

                    b"parameter" => {
                        let my_result = e.attributes().map(|a| a.unwrap()).collect::<Vec<_>>();
                        if str::from_utf8(my_result[2].value).unwrap().contains("{") {
                            // println!("attributes values: {:?} - {:?}", str::from_utf8(my_result[2].key).unwrap(), str::from_utf8(my_result[2].value).unwrap());
                            tag_names.push(String::from(str::from_utf8(my_result[2].value).unwrap()));
                        }
                    },

                    _ => (),
                }
            },
            Ok(Event::Eof) => break, // exits the loop when reaching end of file
            Err(e) => panic!("Error at position {}: {:?}", reader.buffer_position(), e),
            _ => (), // There are several other `Event`s we do not consider here
        }

        // if we don't keep a borrow elsewhere, we can clear the buffer to keep memory usage low
        buf.clear();
    }

    println!("--- Tagnames ---");

    let mut tag_name_placeholder:Vec<String> = Vec::new(); //save tags which contains a placeholder here
    let mut final_tag_names:Vec<String> = Vec::new(); //the final tags

    for tag in tag_names {
        //Remove curly braces
        let v: Vec<&str> = tag.split(|c| c == '{' || c == '}').collect();

        if tag.contains("#") {
            tag_name_placeholder.push(String::from(v[1]));
        }

        if tag.contains("[PLC") {
            for placeholder in &tag_name_placeholder {
                final_tag_names.push(placeholder.replace("#1", &String::from(v[1])));
            }
            &tag_name_placeholder.clear();
        }

    }

    //print tag names to screen
    for name in final_tag_names {
        println!("{:?}", name);
        write!(output, "{}\n", name).unwrap();
    }

    println!("--- Done ---");
}<commit_msg>clean-up<commit_after>extern crate clap;
extern crate quick_xml;

use clap::{Arg, App};

use std::fs::File;
use std::io::Write;
use std::io::BufReader;

use std::str;

use quick_xml::reader::Reader;
use quick_xml::events::Event;

fn main(){

    //Clap
    let matches = App::new("parse_ft_gfx_xml")
                        .version("0.1")
                        .about("Retrieve tags from factorytalk gfx-xml file!")
                        .author("Michael Groncki")
                        .arg(Arg::with_name("INPUT")
                            .help("Sets the input file to use")
                            .required(true)
                            .index(1))
                        .get_matches();

    //Input file
    let file_name_in = matches.value_of("INPUT").unwrap();
    println!(); println!("Using input file: {}", file_name_in); println!();
    let input = File::open(file_name_in).unwrap();

    //Output file
    let file_name_out = format!("{}{}{}", "tagnames_", file_name_in, ".txt");
    let mut output = File::create(file_name_out).unwrap();

    //Create xml reader
    let buffered = BufReader::new(input);
    let mut reader = Reader::from_reader(buffered);
    reader.trim_text(true);

    let mut buf = Vec::new();

    let mut tag_names:Vec<String> = Vec::new(); //save all tags found during search here

    // The `Reader` does not implement `Iterator` because it outputs borrowed data (`Cow`s)
    loop {
        match reader.read_event(&mut buf) {
            // Ok(Event::Start(ref e)) => {

            //     match e.name() {
            //         b"group" => {
            //             let my_result = e.attributes().map(|a| a.unwrap()).collect::<Vec<_>>();

            //             for attrib in e.attributes() {

            //                 let my_attrib:quick_xml::events::attributes::Attribute = attrib.unwrap();

            //                 let my_key = str::from_utf8(my_attrib.key).unwrap();
            //                 let my_value = str::from_utf8(my_attrib.value).unwrap();

            //                 if my_key == "isReferenceObject" {
            //                     if my_value == "true" {
            //                         // println!("The group is reference object!");
            //                     }
            //                 }
            //             }

            //             for rs in &my_result {
            //                 if str::from_utf8(rs.key).unwrap() == "isReferenceObject" {
            //                     // println!("{:?}", str::from_utf8(rs.key).unwrap());
            //                 }
            //             }
            //         }

            //         _ => (),
            //     }
            // },
            Ok(Event::Empty(ref e)) => {

                match e.name() {
                    b"connection" => {
                        let my_result = e.attributes().map(|a| a.unwrap()).collect::<Vec<_>>();
                        // println!("attributes values: {:?} - {:?}", str::from_utf8(my_result[1].key).unwrap(), str::from_utf8(my_result[1].value).unwrap());
                        tag_names.push(String::from(str::from_utf8(my_result[1].value).unwrap()));
                    },

                    b"parameter" => {
                        let my_result = e.attributes().map(|a| a.unwrap()).collect::<Vec<_>>();
                        if str::from_utf8(my_result[2].value).unwrap().contains("{") {
                            // println!("attributes values: {:?} - {:?}", str::from_utf8(my_result[2].key).unwrap(), str::from_utf8(my_result[2].value).unwrap());
                            tag_names.push(String::from(str::from_utf8(my_result[2].value).unwrap()));
                        }
                    },

                    _ => (),
                }
            },
            Ok(Event::Eof) => break, // exits the loop when reaching end of file
            Err(e) => panic!("Error at position {}: {:?}", reader.buffer_position(), e),
            _ => (), // There are several other `Event`s we do not consider here
        }

        // if we don't keep a borrow elsewhere, we can clear the buffer to keep memory usage low
        buf.clear();
    }

    println!("--- Tagnames ---");

    let mut tag_name_placeholder:Vec<String> = Vec::new(); //save tags which contains a placeholder here
    let mut final_tag_names:Vec<String> = Vec::new(); //the final tags

    for tag in tag_names {
        //Remove curly braces
        let v: Vec<&str> = tag.split(|c| c == '{' || c == '}').collect();

        if tag.contains("#") {
            tag_name_placeholder.push(String::from(v[1]));
        }

        if tag.contains("[PLC") {
            for placeholder in &tag_name_placeholder {
                final_tag_names.push(placeholder.replace("#1", &String::from(v[1])));
            }
            &tag_name_placeholder.clear();
        }

    }

    //print tag names to screen
    for name in final_tag_names {
        println!("{:?}", name);
        write!(output, "{}\n", name).unwrap();
    }

    println!("--- Done ---");
}<|endoftext|>


<commit_before>use std::io::prelude::*;
use std::fs::File;
use std::process::{Command, Stdio};

extern crate clap;
use clap::{Arg, ArgGroup, App};

extern crate isbfc;
use isbfc::Token;
use isbfc::Token::*;
use isbfc::parse;
use isbfc::optimize;

struct CompileState {
    output: String,
    loopnum: i32,
    ifnum: i32,
    outbuffsize: i32,
}

fn main() {
    let matches = App::new("isbfc")
        .version("0.0.1")
        .author("Ian D. Scott <ian@iandouglasscott.com>")
        .about("Brainfuck compiler")
        .arg(Arg::with_name("output_asm")
            .short("S")
            .help("Assemble but do not link"))
        .arg(Arg::with_name("dump_ir")
            .long("dumpir")
            .help("Dump intermediate representation; for debugging"))
        .group(ArgGroup::with_name("actions").args(&["output_asm", "dump_ir"]))
        .arg(Arg::with_name("debugging_symbols")
            .short("g")
            .help("Generate debugging information"))
        .arg(Arg::with_name("out_name")
            .short("o")
            .help("Output file name")
            .takes_value(true)
            .empty_values(false)
            .value_name("file"))
        .arg(Arg::with_name("tape_size")
            .long("tape-size")
            .help("Size of tape; defaults to 8192")
            .takes_value(true)
            .empty_values(false)
            .value_name("bytes"))
        .arg(Arg::with_name("FILENAME")
            .help("Source file to compile")
            .required(true)
            .index(1))
        .get_matches();

    let mut tape_size = 8192;
    if let Some(tape_size_str) = matches.value_of("tape_size") {
        tape_size = tape_size_str.parse::<i32>().unwrap();
    }

    let path = matches.value_of("FILENAME").unwrap();
    let name = path.rsplitn(2, '.').last().unwrap();
    let mut file = File::open(&path).unwrap();
    let mut code = String::new();
    file.read_to_string(&mut code).unwrap();

    let tokens = parse(&code);
    let tokens = optimize(tokens);

    if matches.is_present("dump_ir") {
        let output = dump_ir(tokens);
        if let Some(out_name) = matches.value_of("out_name") {
            let mut irfile = File::create(out_name).unwrap();
            irfile.write_all(&output.into_bytes()).unwrap();
        } else {
            print!("{}", output);
        }
    } else if matches.is_present("output_asm") {
        let output = compile(tokens, tape_size);
        let def_name = format!("{}.s", name);
        let out_name = matches.value_of("out_name").unwrap_or(&def_name);
        let mut asmfile = File::create(out_name).unwrap();
        asmfile.write_all(&output.into_bytes()).unwrap();
    } else {
        let output = compile(tokens, tape_size);
        let out_name = matches.value_of("out_name").unwrap_or(name);
        let debug = matches.is_present("debugging_symbols");
        asm_and_link(&output, &name, &out_name, debug);
    }
}

fn compile_iter(state: &mut CompileState, tokens: Vec<Token>) {
    let mut outbuffpos = 0;
    for token in tokens {
        match token {
            Add(offset, value) => {
                let dest = if offset == 0 {
                    "%r12".to_string()
                } else {
                    format!("{}(%rbx)", (offset * 8))
                };
                if value == 1 && dest == "%r12" {
                    state.output.push_str("    inc %r12\n");
                } else if value >= 1 {
                    state.output.push_str(&format!("    addq ${}, {}\n", value, dest));
                } else if value == -1 && dest == "%r12" {
                    state.output.push_str("    dec %r12\n");
                } else if value <= -1 {
                    state.output.push_str(&format!("    subq ${}, {}\n", -value, dest));
                }
            }
            MulCopy(src_idx, dest_idx, mul) => {
                let mut src = if src_idx == 0 {
                    "%r12".to_string()
                } else {
                    format!("{}(%rbx)", (src_idx * 8))
                };
                let dest = if dest_idx == 0 {
                    "%r12".to_string()
                } else {
                    format!("{}(%rbx)", (dest_idx * 8))
                };

                if mul != -1 && mul != 1 {
                    state.output.push_str(&format!(concat!("    movq {}, %rax\n",
                                                           "    movq ${}, %rdx\n",
                                                           "    mulq %rdx\n"),
                                                   src,
                                                   mul.abs()));
                    src = "%rax".to_string();
                } else if src != "%r12" && dest != "%r12" {
                    // x86 cannot move memory to memory
                    state.output.push_str(&format!("    movq {}, %rax\n", src));
                    src = "%rax".to_string();
                }

                if mul > 0 {
                    state.output.push_str(&format!("    addq {}, {}\n", src, dest));
                } else {
                    state.output.push_str(&format!("    subq {}, {}\n", src, dest));
                }
            }
            Set(offset, value) => {
                if offset == 0 && value == 0 {
                    state.output.push_str("    xor %r12, %r12\n");
                } else if offset == 0 {
                    state.output.push_str(&format!("    movq ${}, %r12\n", value));
                } else {
                    state.output.push_str(&format!("    movq ${}, {}(%rbx)\n", value, offset * 8));
                }
            }
            Move(offset) => {
                if offset != 0 {
                    state.output.push_str("    movq %r12, (%rbx)\n");
                    if offset > 0 {
                        state.output.push_str(&format!("    addq ${}, %rbx\n", offset * 8));
                    } else {
                        state.output.push_str(&format!("    subq ${}, %rbx\n", -offset * 8));
                    }
                    state.output.push_str("    movq (%rbx), %r12\n");
                }
            }
            Loop(content) => {
                state.loopnum += 1;
                let curloop = state.loopnum;
                state.output.push_str(&format!(concat!("    jmp endloop{}\n", "    loop{}:\n"),
                                               curloop,
                                               curloop));

                compile_iter(state, content);

                state.output.push_str(&format!(concat!("    endloop{}:\n",
                                                       "    test %r12, %r12\n",
                                                       "    jnz loop{}\n"),
                                               curloop,
                                               curloop))
            }
            If(offset, content) => {
                state.ifnum += 1;
                let curif = state.ifnum;
                if offset == 0 {
                    state.output.push_str("    test %r12, %r12\n");
                } else {
                    state.output.push_str(&format!("    cmpq $0, {}(%rbx)\n", offset * 8));
                }
                state.output.push_str(&format!("    jz endif{}\n", curif));

                compile_iter(state, content);

                state.output.push_str(&format!("    endif{}:\n", curif))
            }
            Scan(offset) => {
                // Slighly more optimal than normal loop and move
                state.loopnum += 1;
                state.output.push_str(&format!(concat!("    movq %r12, (%rbx)\n",
                                                       "    jmp endloop{}\n",
                                                       "    loop{}:\n"),
                                               state.loopnum,
                                               state.loopnum));
                if offset > 0 {
                    state.output.push_str(&format!("    addq ${}, %rbx\n", offset * 8));
                } else {
                    state.output.push_str(&format!("    subq ${}, %rbx\n", -offset * 8));
                }
                state.output.push_str(&format!(concat!("    endloop{}:\n",
                                                       "    cmp $0, (%rbx)\n",
                                                       "    jnz loop{}\n",
                                                       "    movq (%rbx), %r12\n"),
                                               state.loopnum,
                                               state.loopnum));
            }
            Input => {
                state.output.push_str(concat!("\n    xor %rax, %rax\n",
                                              "    xor %rdi, %rdi\n",
                                              "    movq %rbx, %rsi\n",
                                              "    movq $1, %rdx\n",
                                              "    syscall\n",
                                              "    movq (%rbx), %r12\n\n"))
            }
            LoadOut(offset, add) => {
                let outaddr = format!("(strbuff+{})", outbuffpos);
                if offset == 0 {
                    state.output.push_str(&format!("    movq %r12, {}\n", outaddr));
                } else {
                    state.output.push_str(&format!("    movq {}(%rbx), %rax\n", offset * 8));
                    state.output.push_str(&format!("    movq %rax, {}\n", outaddr));
                }
                if add > 0 {
                    state.output.push_str(&format!("    addb ${}, {}\n", add, outaddr));
                } else if add < 0 {
                    state.output.push_str(&format!("    subb ${}, {}\n", -add, outaddr));
                }
                outbuffpos += 1;
            }
            LoadOutSet(value) => {
                let outaddr = format!("(strbuff+{})", outbuffpos);
                state.output.push_str(&format!("    movq ${}, {}\n", value, outaddr));
                outbuffpos += 1;
            }
            Output => {
                state.output.push_str(&format!(concat!("    movq $1, %rax\n",
                                                       "    movq $1, %rdi\n",
                                                       "    movq $strbuff, %rsi\n",
                                                       "    movq ${}, %rdx\n",
                                                       "    syscall\n\n"),
                                               outbuffpos));

                if state.outbuffsize < outbuffpos + 8 {
                    state.outbuffsize = outbuffpos + 8;
                }
                outbuffpos = 0;
            }
        }
    }
}

fn compile(tokens: Vec<Token>, tape_size: i32) -> String {
    println!("Compiling...");

    let mut state = CompileState {
        output: String::new(),
        loopnum: 0,
        ifnum: 0,
        outbuffsize: 0,
    };

    compile_iter(&mut state, tokens);

    // Exit syscall
    state.output.push_str(concat!("\n    movq $60, %rax\n",
                                  "    movq $0, %rdi\n",
                                  "    syscall\n"));

    format!(concat!(".section .bss\n",
                    "    .lcomm strbuff, {outbuffsize}\n",
                    "    .lcomm mem, {}\n",
                    "    .set startidx, mem + {}\n",
                    ".section .text\n",
                    ".global _start\n",
                    "_start:\n",
                    "    xor %r12, %r12\n",
                    "    movq $startidx, %rbx\n\n{}"),
            tape_size,
            tape_size / 2,
            state.output,
            outbuffsize = state.outbuffsize)
}

fn asm_and_link(code: &str, name: &str, out_name: &str, debug: bool) {
    println!("Assembling...");

    let mut command = Command::new("as");
    if debug {
        command.arg("-g");
    }
    let mut child = command
        .arg("-") // Standard input
        .arg("-o")
        .arg(format!("{}.o", name))
        .stdin(Stdio::piped())
        .spawn().unwrap();

    child.stdin.take().unwrap().write_all(code.as_bytes()).unwrap();

    let status = child.wait().unwrap();
    if status.code() == Some(0) {
        println!("Linking...");
        Command::new("ld")
            .arg(format!("{}.o", name))
            .arg("-o")
            .arg(out_name)
            .spawn()
            .unwrap();
    }
}

fn dump_ir(tokens: Vec<Token>) -> String {
    format!("{:#?}\n", tokens)
}
<commit_msg>Inline dump_ir function, since it is so simple now<commit_after>use std::io::prelude::*;
use std::fs::File;
use std::process::{Command, Stdio};

extern crate clap;
use clap::{Arg, ArgGroup, App};

extern crate isbfc;
use isbfc::Token;
use isbfc::Token::*;
use isbfc::parse;
use isbfc::optimize;

struct CompileState {
    output: String,
    loopnum: i32,
    ifnum: i32,
    outbuffsize: i32,
}

fn main() {
    let matches = App::new("isbfc")
        .version("0.0.1")
        .author("Ian D. Scott <ian@iandouglasscott.com>")
        .about("Brainfuck compiler")
        .arg(Arg::with_name("output_asm")
            .short("S")
            .help("Assemble but do not link"))
        .arg(Arg::with_name("dump_ir")
            .long("dumpir")
            .help("Dump intermediate representation; for debugging"))
        .group(ArgGroup::with_name("actions").args(&["output_asm", "dump_ir"]))
        .arg(Arg::with_name("debugging_symbols")
            .short("g")
            .help("Generate debugging information"))
        .arg(Arg::with_name("out_name")
            .short("o")
            .help("Output file name")
            .takes_value(true)
            .empty_values(false)
            .value_name("file"))
        .arg(Arg::with_name("tape_size")
            .long("tape-size")
            .help("Size of tape; defaults to 8192")
            .takes_value(true)
            .empty_values(false)
            .value_name("bytes"))
        .arg(Arg::with_name("FILENAME")
            .help("Source file to compile")
            .required(true)
            .index(1))
        .get_matches();

    let mut tape_size = 8192;
    if let Some(tape_size_str) = matches.value_of("tape_size") {
        tape_size = tape_size_str.parse::<i32>().unwrap();
    }

    let path = matches.value_of("FILENAME").unwrap();
    let name = path.rsplitn(2, '.').last().unwrap();
    let mut file = File::open(&path).unwrap();
    let mut code = String::new();
    file.read_to_string(&mut code).unwrap();

    let tokens = parse(&code);
    let tokens = optimize(tokens);

    if matches.is_present("dump_ir") {
        let output = format!("{:#?}\n", tokens);
        if let Some(out_name) = matches.value_of("out_name") {
            let mut irfile = File::create(out_name).unwrap();
            irfile.write_all(&output.into_bytes()).unwrap();
        } else {
            print!("{}", output);
        }
    } else if matches.is_present("output_asm") {
        let output = compile(tokens, tape_size);
        let def_name = format!("{}.s", name);
        let out_name = matches.value_of("out_name").unwrap_or(&def_name);
        let mut asmfile = File::create(out_name).unwrap();
        asmfile.write_all(&output.into_bytes()).unwrap();
    } else {
        let output = compile(tokens, tape_size);
        let out_name = matches.value_of("out_name").unwrap_or(name);
        let debug = matches.is_present("debugging_symbols");
        asm_and_link(&output, &name, &out_name, debug);
    }
}

fn compile_iter(state: &mut CompileState, tokens: Vec<Token>) {
    let mut outbuffpos = 0;
    for token in tokens {
        match token {
            Add(offset, value) => {
                let dest = if offset == 0 {
                    "%r12".to_string()
                } else {
                    format!("{}(%rbx)", (offset * 8))
                };
                if value == 1 && dest == "%r12" {
                    state.output.push_str("    inc %r12\n");
                } else if value >= 1 {
                    state.output.push_str(&format!("    addq ${}, {}\n", value, dest));
                } else if value == -1 && dest == "%r12" {
                    state.output.push_str("    dec %r12\n");
                } else if value <= -1 {
                    state.output.push_str(&format!("    subq ${}, {}\n", -value, dest));
                }
            }
            MulCopy(src_idx, dest_idx, mul) => {
                let mut src = if src_idx == 0 {
                    "%r12".to_string()
                } else {
                    format!("{}(%rbx)", (src_idx * 8))
                };
                let dest = if dest_idx == 0 {
                    "%r12".to_string()
                } else {
                    format!("{}(%rbx)", (dest_idx * 8))
                };

                if mul != -1 && mul != 1 {
                    state.output.push_str(&format!(concat!("    movq {}, %rax\n",
                                                           "    movq ${}, %rdx\n",
                                                           "    mulq %rdx\n"),
                                                   src,
                                                   mul.abs()));
                    src = "%rax".to_string();
                } else if src != "%r12" && dest != "%r12" {
                    // x86 cannot move memory to memory
                    state.output.push_str(&format!("    movq {}, %rax\n", src));
                    src = "%rax".to_string();
                }

                if mul > 0 {
                    state.output.push_str(&format!("    addq {}, {}\n", src, dest));
                } else {
                    state.output.push_str(&format!("    subq {}, {}\n", src, dest));
                }
            }
            Set(offset, value) => {
                if offset == 0 && value == 0 {
                    state.output.push_str("    xor %r12, %r12\n");
                } else if offset == 0 {
                    state.output.push_str(&format!("    movq ${}, %r12\n", value));
                } else {
                    state.output.push_str(&format!("    movq ${}, {}(%rbx)\n", value, offset * 8));
                }
            }
            Move(offset) => {
                if offset != 0 {
                    state.output.push_str("    movq %r12, (%rbx)\n");
                    if offset > 0 {
                        state.output.push_str(&format!("    addq ${}, %rbx\n", offset * 8));
                    } else {
                        state.output.push_str(&format!("    subq ${}, %rbx\n", -offset * 8));
                    }
                    state.output.push_str("    movq (%rbx), %r12\n");
                }
            }
            Loop(content) => {
                state.loopnum += 1;
                let curloop = state.loopnum;
                state.output.push_str(&format!(concat!("    jmp endloop{}\n", "    loop{}:\n"),
                                               curloop,
                                               curloop));

                compile_iter(state, content);

                state.output.push_str(&format!(concat!("    endloop{}:\n",
                                                       "    test %r12, %r12\n",
                                                       "    jnz loop{}\n"),
                                               curloop,
                                               curloop))
            }
            If(offset, content) => {
                state.ifnum += 1;
                let curif = state.ifnum;
                if offset == 0 {
                    state.output.push_str("    test %r12, %r12\n");
                } else {
                    state.output.push_str(&format!("    cmpq $0, {}(%rbx)\n", offset * 8));
                }
                state.output.push_str(&format!("    jz endif{}\n", curif));

                compile_iter(state, content);

                state.output.push_str(&format!("    endif{}:\n", curif))
            }
            Scan(offset) => {
                // Slighly more optimal than normal loop and move
                state.loopnum += 1;
                state.output.push_str(&format!(concat!("    movq %r12, (%rbx)\n",
                                                       "    jmp endloop{}\n",
                                                       "    loop{}:\n"),
                                               state.loopnum,
                                               state.loopnum));
                if offset > 0 {
                    state.output.push_str(&format!("    addq ${}, %rbx\n", offset * 8));
                } else {
                    state.output.push_str(&format!("    subq ${}, %rbx\n", -offset * 8));
                }
                state.output.push_str(&format!(concat!("    endloop{}:\n",
                                                       "    cmp $0, (%rbx)\n",
                                                       "    jnz loop{}\n",
                                                       "    movq (%rbx), %r12\n"),
                                               state.loopnum,
                                               state.loopnum));
            }
            Input => {
                state.output.push_str(concat!("\n    xor %rax, %rax\n",
                                              "    xor %rdi, %rdi\n",
                                              "    movq %rbx, %rsi\n",
                                              "    movq $1, %rdx\n",
                                              "    syscall\n",
                                              "    movq (%rbx), %r12\n\n"))
            }
            LoadOut(offset, add) => {
                let outaddr = format!("(strbuff+{})", outbuffpos);
                if offset == 0 {
                    state.output.push_str(&format!("    movq %r12, {}\n", outaddr));
                } else {
                    state.output.push_str(&format!("    movq {}(%rbx), %rax\n", offset * 8));
                    state.output.push_str(&format!("    movq %rax, {}\n", outaddr));
                }
                if add > 0 {
                    state.output.push_str(&format!("    addb ${}, {}\n", add, outaddr));
                } else if add < 0 {
                    state.output.push_str(&format!("    subb ${}, {}\n", -add, outaddr));
                }
                outbuffpos += 1;
            }
            LoadOutSet(value) => {
                let outaddr = format!("(strbuff+{})", outbuffpos);
                state.output.push_str(&format!("    movq ${}, {}\n", value, outaddr));
                outbuffpos += 1;
            }
            Output => {
                state.output.push_str(&format!(concat!("    movq $1, %rax\n",
                                                       "    movq $1, %rdi\n",
                                                       "    movq $strbuff, %rsi\n",
                                                       "    movq ${}, %rdx\n",
                                                       "    syscall\n\n"),
                                               outbuffpos));

                if state.outbuffsize < outbuffpos + 8 {
                    state.outbuffsize = outbuffpos + 8;
                }
                outbuffpos = 0;
            }
        }
    }
}

fn compile(tokens: Vec<Token>, tape_size: i32) -> String {
    println!("Compiling...");

    let mut state = CompileState {
        output: String::new(),
        loopnum: 0,
        ifnum: 0,
        outbuffsize: 0,
    };

    compile_iter(&mut state, tokens);

    // Exit syscall
    state.output.push_str(concat!("\n    movq $60, %rax\n",
                                  "    movq $0, %rdi\n",
                                  "    syscall\n"));

    format!(concat!(".section .bss\n",
                    "    .lcomm strbuff, {outbuffsize}\n",
                    "    .lcomm mem, {}\n",
                    "    .set startidx, mem + {}\n",
                    ".section .text\n",
                    ".global _start\n",
                    "_start:\n",
                    "    xor %r12, %r12\n",
                    "    movq $startidx, %rbx\n\n{}"),
            tape_size,
            tape_size / 2,
            state.output,
            outbuffsize = state.outbuffsize)
}

fn asm_and_link(code: &str, name: &str, out_name: &str, debug: bool) {
    println!("Assembling...");

    let mut command = Command::new("as");
    if debug {
        command.arg("-g");
    }
    let mut child = command
        .arg("-") // Standard input
        .arg("-o")
        .arg(format!("{}.o", name))
        .stdin(Stdio::piped())
        .spawn().unwrap();

    child.stdin.take().unwrap().write_all(code.as_bytes()).unwrap();

    let status = child.wait().unwrap();
    if status.code() == Some(0) {
        println!("Linking...");
        Command::new("ld")
            .arg(format!("{}.o", name))
            .arg("-o")
            .arg(out_name)
            .spawn()
            .unwrap();
    }
}
<|endoftext|>


<commit_before>extern crate rand;

#[macro_use]
extern crate lazy_static;

use rand::{XorShiftRng, Rng, thread_rng, SeedableRng};
use std::fmt;
use std::fmt::{Formatter, Debug};

use std::sync::Mutex;

trait Specimen: Sized {
    fn score(&self) -> f32;
    fn reevaluate(&mut self);
    fn mutate(generation: &mut[Self], rng: &mut XorShiftRng);
    fn breed(parents: &[Self], rng: &mut XorShiftRng) -> Self;
    fn filter_strongest(species: &mut Vec<Self>);

    fn initial() -> Vec<Self>;
}

fn genetic<S: Specimen>(threshold: f32, max_iters: usize, nparents: usize, nchildren: usize) -> S {
    let mut species: Vec<S> = S::initial();
    let mut best = (0f32, 0);
    for _ in 0..max_iters {
        species = next_gen(species, nparents, nchildren);

        for (i, specimen) in species.iter().enumerate() {
            let score = specimen.score();
            if best.0 <= score {
                best = (score, i)
            }
        }

        if best.0 >= threshold {
            println!("found!");
            break;
        }
    }

    species.swap_remove(best.1)
}

#[inline(never)]
fn next_gen<S: Specimen>(mut species: Vec<S>, nparents: usize, nchildren: usize) -> Vec<S> {
    let mut rng = RNG.lock().unwrap();

    // 1. filter strongest
    S::filter_strongest(&mut species);

    // 2. bear children
    let mut children = vec![];
    let mut family = vec![];
    for _ in 0..nchildren {
        make_family(&mut species, nparents, &mut family, &mut rng);
        let child = S::breed(&family, &mut rng);
        children.push(child);
        species.extend(family.drain(..));
    }

    // 3. mutate
    S::mutate(&mut children, &mut rng);
    for child in children.iter_mut() {
        child.reevaluate();
    }

    if KILL_PARENTS {
        children
    } else {
        species.extend(children);
        species
    }
}

fn make_family<S: Specimen>(species: &mut Vec<S>, nparents: usize, family: &mut Vec<S>, rng: &mut XorShiftRng) {
    assert!(family.is_empty());
    for _ in 0..nparents {
        let next = rng.gen_range(0, species.len());
        let s = species.swap_remove(next);
        family.push(s);
    }
}

//---------------------------------------------------

// BEST FOR SIZE=8
//const KILL_PARENTS: bool = true;
//const SIZE: usize = 8;
//const MUTATION_PROBABILITY: f32 = 1.0f32;
//const POPULATION: usize = 3;
//const MAX_ITERS: usize = 1000;
//const NPARENTS: usize = 2;
//const NCHILDREN: usize = 100;

// BEST FOR SIZE=12
//const KILL_PARENTS: bool = true;
//const SIZE: usize = 12;
//const MUTATION_PROBABILITY: f32 = 1.0f32;
//const POPULATION: usize = 3;
//const MAX_ITERS: usize = 1000;
//const NPARENTS: usize = 2;
//const NCHILDREN: usize = 100;

// BEST FOR SIZE=15
//const KILL_PARENTS: bool = true;
//const SIZE: usize = 15;
//const MUTATION_PROBABILITY: f32 = 1.0f32;
//const POPULATION: usize = 4;
//const MAX_ITERS: usize = 1000;
//const NPARENTS: usize = 2;
//const NCHILDREN: usize = 280;

// BEST FOR SIZE=30
//const KILL_PARENTS: bool = true;
//const SIZE: usize = 30;
//const MUTATION_PROBABILITY: f32 = 1.0f32;
//const POPULATION: usize = 4;
//const MAX_ITERS: usize = 5000;
//const NPARENTS: usize = 2;
//const NCHILDREN: usize = 480;

// BEST FOR SIZE=400
//const KILL_PARENTS: bool = true;
//const SIZE: usize = 400;
//const MUTATION_PROBABILITY: f32 = 1.0f32;
//const POPULATION: usize = 5;
//const MAX_ITERS: usize = 5000;
//const NPARENTS: usize = 2;
//const NCHILDREN: usize = 640;

//// BEST FOR SIZE=1000
//const KILL_PARENTS: bool = true;
//const SIZE: usize = 1000;
//const MUTATION_PROBABILITY: f32 = 1.0f32;
//const POPULATION: usize = 20;
//const MAX_ITERS: usize = 5000;
//const NPARENTS: usize = 2;
//const NCHILDREN: usize = 4000;

const KILL_PARENTS: bool = true;
const SIZE: usize = 1000;
const MUTATION_PROBABILITY: f32 = 1.0f32;
const POPULATION: usize = 20;
const MAX_ITERS: usize = 5000;
const NPARENTS: usize = 2;
const NCHILDREN: usize = 4000;

lazy_static! {
    static ref RNG: Mutex<XorShiftRng> = Mutex::new(XorShiftRng::new_unseeded());
}

struct Board {
    score: f32,
    queens: Vec<usize>,
}

impl Board {
    fn new(queens: Vec<usize>) -> Board {
        Board { score: 0f32, queens: queens }
    }

    #[inline(never)]
    fn do_mutate(&mut self, rng: &mut XorShiftRng) {
        let x = rng.gen_range(0, SIZE);

        let mut y = rng.gen_range(0, SIZE-1);
        if y >= self.queens[x] {
            y += 1;
        }
        self.queens[x] = y;
    }
}

impl Specimen for Board {
    #[inline(never)]
    fn reevaluate(&mut self) {
        let mut occurences = vec![0; 2*SIZE-1];
        let mut nonconflicting = Vec::with_capacity(SIZE);

        // columns
        for x in 0..SIZE {
            occurences[self.queens[x]] += 1;
        }
        for x in 0..SIZE {
            if occurences[self.queens[x]] == 1 {
                nonconflicting.push(x);
            }
        }

        // forward diagonals
        for y in 0..SIZE {
            occurences[y] = 0;
        }
        for x in 0..SIZE {
            let d = SIZE-1 + x - self.queens[x];
            occurences[d] += 1;
        }
        let mut i = 0;
        while i < nonconflicting.len() {
            let x = nonconflicting[i];
            let d = SIZE-1 + x - self.queens[x];
            if occurences[d] == 1 {
                i += 1;
            } else {
                nonconflicting.swap_remove(i);
            }
        }

        // backward diagonals
        for y in 0..2*SIZE-1 {
            occurences[y] = 0;
        }
        for x in 0..SIZE {
            let d = x + self.queens[x];
            occurences[d] += 1;
        }
        i = 0;
        while i < nonconflicting.len() {
            let x = nonconflicting[i];
            let d = x + self.queens[x];
            if occurences[d] == 1 {
                i += 1;
            } else {
                nonconflicting.swap_remove(i);
            }
        }

        self.score = nonconflicting.len() as f32 + 0.000001;
    }

    fn score(&self) -> f32 {
        self.score
    }

    #[inline(never)]
    fn mutate(new_gen: &mut [Self], rng: &mut XorShiftRng) {
        for board in new_gen.iter_mut() {
            if rng.next_f32() < MUTATION_PROBABILITY {
                board.do_mutate(rng);
            }
        }
    }

    #[inline(never)]
    fn breed(parents: &[Self], rng: &mut XorShiftRng) -> Self {
        let mut child = Board::new(Vec::with_capacity(SIZE));

        for x in 0..SIZE {
            let parent = rng.gen_range(0, parents.len());
            child.queens.push(parents[parent].queens[x]);
        }

        child
    }

    #[inline(never)]
    fn filter_strongest(species: &mut Vec<Self>) {
        if species.len() <= POPULATION {
            return;
        }

        species.sort_by(|s, t| t.score.partial_cmp(&s.score).unwrap());
        species.truncate(POPULATION);
    }

    #[inline(never)]
    fn initial() -> Vec<Self> {
        let mut boards = Vec::with_capacity(POPULATION);

        let mut rng = RNG.lock().unwrap();
        for _ in 0..POPULATION {
            let mut board = Board::new(Vec::with_capacity(SIZE));

            for _ in 0..SIZE {
                let y = rng.gen_range(0, SIZE);
                board.queens.push(y);
            }

            board.reevaluate();
            boards.push(board);
        }
        boards
    }
}

impl Debug for Board {
    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
        write!(f, "score={}, queens=[{:?}]", self.score, self.queens)
    }
}

fn genetic_queens() {
    {
        let mut rng = RNG.lock().unwrap();
        let mut trng = thread_rng();
        rng.reseed([trng.next_u32(), trng.next_u32(), trng.next_u32(), trng.next_u32()]);
    }

    let best = genetic::<Board>(SIZE as f32, MAX_ITERS, NPARENTS, NCHILDREN);
    println!("best: {:?}", &best);
}

fn main() {
    for _ in 0..10 {
        genetic_queens()
    }
}

<commit_msg>switch to permutations-based board representation. this narrows the search area even more, allowing fast solving for N=1000<commit_after>extern crate rand;

#[macro_use]
extern crate lazy_static;

use rand::{XorShiftRng, Rng, thread_rng, SeedableRng};
use std::fmt;
use std::fmt::{Formatter, Debug};
use std::sync::Mutex;

trait Specimen: Sized {
    fn score(&self) -> f32;
    fn reevaluate(&mut self);
    fn mutate(generation: &mut[Self], rng: &mut XorShiftRng);
    fn breed(parents: &[Self], rng: &mut XorShiftRng) -> Self;
    fn filter_strongest(species: &mut Vec<Self>);

    fn initial() -> Vec<Self>;
}

fn genetic<S: Specimen>(threshold: f32, max_iters: usize, nparents: usize, nchildren: usize) -> S {
    let mut species: Vec<S> = S::initial();
    let mut best = (0f32, 0);
    for _ in 0..max_iters {
        species = next_gen(species, nparents, nchildren);

        for (i, specimen) in species.iter().enumerate() {
            let score = specimen.score();
            if best.0 <= score {
                best = (score, i)
            }
        }

        if best.0 >= threshold {
            println!("found!");
            break;
        }
    }

    species.swap_remove(best.1)
}

#[inline(never)]
fn next_gen<S: Specimen>(mut species: Vec<S>, nparents: usize, nchildren: usize) -> Vec<S> {
    let mut rng = RNG.lock().unwrap();

    // 1. filter strongest
    S::filter_strongest(&mut species);

    // 2. bear children
    let mut children = vec![];
    let mut family = vec![];
    for _ in 0..nchildren {
        make_family(&mut species, nparents, &mut family, &mut rng);
        let child = S::breed(&family, &mut rng);
        children.push(child);
        species.extend(family.drain(..));
    }

    // 3. mutate
    S::mutate(&mut children, &mut rng);
    for child in children.iter_mut() {
        child.reevaluate();
    }

    if KILL_PARENTS {
        children
    } else {
        species.extend(children);
        species
    }
}

fn make_family<S: Specimen>(species: &mut Vec<S>, nparents: usize, family: &mut Vec<S>, rng: &mut XorShiftRng) {
    assert!(family.is_empty());
    for _ in 0..nparents {
        let next = rng.gen_range(0, species.len());
        let s = species.swap_remove(next);
        family.push(s);
    }
}

//---------------------------------------------------

// BEST FOR SIZE=1000
const KILL_PARENTS: bool = true;
const SIZE: usize = 1000;
const MUTATION_PROBABILITY: f32 = 1.0f32;
const POPULATION: usize = 4;
const MAX_ITERS: usize = 5000;
const NPARENTS: usize = 2;
const NCHILDREN: usize = 100;

//
//const KILL_PARENTS: bool = true;
//const SIZE: usize = 10000;
//const MUTATION_PROBABILITY: f32 = 1.0f32;
//const POPULATION: usize = 20;
//const MAX_ITERS: usize = 5000;
//const NPARENTS: usize = 2;
//const NCHILDREN: usize = 1000;

lazy_static! {
    static ref RNG: Mutex<XorShiftRng> = Mutex::new(XorShiftRng::new_unseeded());
}

struct Board {
    score: f32,
    queens: Vec<usize>,
}

impl Board {
    fn new(queens: Vec<usize>) -> Board {
        Board { score: 0f32, queens: queens }
    }

    #[inline(never)]
    fn do_mutate(&mut self, rng: &mut XorShiftRng) {
        let i = rng.gen_range(0, SIZE);
        let mut j = rng.gen_range(0, SIZE-1);

        if j >= i {
            j += 1;
        }

        let t = self.queens[i];
        self.queens[i] = self.queens[j];
        self.queens[j] = t;
    }

    // The algorithm is described in "Genetic Algorithm Solution of the TSP Avoiding Special Crossover and Mutation"
    // http://user.ceng.metu.edu.tr/~ucoluk/research/publications/tspnew.pdf
    #[inline(never)]
    fn breed_pmx(parents: &[Self], rng: &mut XorShiftRng) -> Self {
        // A very important assert! Without it, the program runs twice slower! o_O
        assert!(parents.len() == NPARENTS);

        let mut child = Board::new(parents[0].queens.clone());

        let mut inverse = vec![0; SIZE];
        for i in 0..SIZE {
            let y = child.queens[i];
            inverse[y] = i;
        }

        for x in 0..SIZE {
            let parent = rng.gen_range(0, parents.len());
            if parent != 0 {
                let mother_y = child.queens[x];
                let father_y = parents[parent].queens[x];
                let father_x = inverse[father_y];
                child.queens[father_x] = mother_y;
                child.queens[x] = father_y;
                inverse[mother_y] = father_x;
                if NPARENTS > 2 { // Optimization: this is not required when NPARENTS==2
                    inverse[father_y] = x;
                }
            }
        }

//        assert!(Self::permutation_valid(&child.queens), "father={:?}, mother={:?}, child={:?}", &parents[0], &parents[1], &child.queens);

        child
    }

//    fn permutation_valid(p: &[usize]) -> bool {
//        let mut used = vec![0; p.len()];
//        for &i in p.iter() {
//            used[i] = 1;
//        }
//        for &u in used.iter() {
//            if u != 1 {
//                return false;
//            }
//        }
//
//        true
//    }
}

impl Specimen for Board {
    #[inline(never)]
    fn reevaluate(&mut self) {
        let mut occurences = vec![0; 2*SIZE-1];
        let mut nonconflicting = Vec::with_capacity(SIZE);

        for x in 0..SIZE {
            let d = SIZE-1 + x - self.queens[x];
            occurences[d] += 1;
        }
        for x in 0..SIZE {
            let d = SIZE-1 + x - self.queens[x];
            if occurences[d] == 1 {
                nonconflicting.push(x);
            }
        }

        // backward diagonals
        for y in 0..2*SIZE-1 {
            occurences[y] = 0;
        }
        for x in 0..SIZE {
            let d = x + self.queens[x];
            occurences[d] += 1;
        }

        let mut s = 0;
        for x in nonconflicting {
            let d = x + self.queens[x];
            if occurences[d] == 1 {
                s += 1;
            }
        }

        self.score = s as f32 + 0.000001;
    }

    fn score(&self) -> f32 {
        self.score
    }

    #[inline(never)]
    fn mutate(new_gen: &mut [Self], rng: &mut XorShiftRng) {
        for board in new_gen.iter_mut() {
            if rng.next_f32() < MUTATION_PROBABILITY {
                board.do_mutate(rng);
            }
        }
    }

    #[inline(never)]
    fn breed(parents: &[Self], rng: &mut XorShiftRng) -> Self {
        Self::breed_pmx(parents, rng)
    }

    #[inline(never)]
    fn filter_strongest(species: &mut Vec<Self>) {
        if species.len() <= POPULATION {
            return;
        }

        species.sort_by(|s, t| t.score.partial_cmp(&s.score).unwrap());
        species.truncate(POPULATION);
    }

    #[inline(never)]
    fn initial() -> Vec<Self> {
        let mut boards = Vec::with_capacity(POPULATION);

        let mut ys = Vec::with_capacity(SIZE);

        let mut rng = RNG.lock().unwrap();
        for _ in 0..POPULATION {
            let mut board = Board::new(Vec::with_capacity(SIZE));

            for y in 0..SIZE {
                ys.push(y);
            }

            for _ in 0..SIZE {
                let z = rng.gen_range(0, ys.len());
                let y = ys.swap_remove(z);
                board.queens.push(y);
            }

            board.reevaluate();
            boards.push(board);
        }
        boards
    }
}

impl Debug for Board {
    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
        write!(f, "score={}, queens=[{:?}]", self.score, self.queens)
    }
}

fn genetic_queens() {
    {
        let mut rng = RNG.lock().unwrap();
        let mut trng = thread_rng();
        rng.reseed([trng.next_u32(), trng.next_u32(), trng.next_u32(), trng.next_u32()]);
    }

    let best = genetic::<Board>(SIZE as f32, MAX_ITERS, NPARENTS, NCHILDREN);
    println!("best: {:?}", &best);
}

fn main() {
    for _ in 0..10 {
        genetic_queens()
    }
}

<|endoftext|>


<commit_before><commit_msg>Put hq renders in a sub-folder<commit_after><|endoftext|>


<commit_before>extern crate ratel;
extern crate iron;

use std::io::Read;
use iron::prelude::*;
use iron::status;
use ratel::error::ParseError;

fn compile(source: String, minify: bool) -> Result<String, ParseError> {
    let mut ast = match ratel::parser::parse(source) {
        Ok(ast)    => ast,
        Err(error) => return Err(error),
    };

    let settings = ratel::transformer::Settings::target_es5();
    ratel::transformer::transform(&mut ast, settings);

    Ok(ratel::codegen::generate_code(&ast, minify))
}

fn main() {
    fn handler(req: &mut Request) -> IronResult<Response> {
        let mut source = String::new();

        match req.body.read_to_string(&mut source) {
            Ok(_)  => {},
            Err(_) => return Ok(Response::with((status::BadRequest, ":("))),
        }

        Ok(match compile(source, false) {
            Ok(source) => Response::with((status::Ok, source)),
            Err(error) => Response::with((status::UnprocessableEntity, format!("{:?}", error))),
        })
    }

    let _server = Iron::new(handler).http("0.0.0.0:3000").unwrap();
    println!("On 3000");
}
<commit_msg>Allow for the port to be set by env variable<commit_after>extern crate ratel;
extern crate iron;

use std::io::Read;
use iron::prelude::*;
use iron::status;
use ratel::error::ParseError;

const DEFAULT_PORT: u16 = 3000;

fn compile(source: String, minify: bool) -> Result<String, ParseError> {
    let mut ast = match ratel::parser::parse(source) {
        Ok(ast)    => ast,
        Err(error) => return Err(error),
    };

    let settings = ratel::transformer::Settings::target_es5();
    ratel::transformer::transform(&mut ast, settings);

    Ok(ratel::codegen::generate_code(&ast, minify))
}

fn main() {
    fn handler(req: &mut Request) -> IronResult<Response> {
        let mut source = String::new();

        match req.body.read_to_string(&mut source) {
            Ok(_)  => {},
            Err(_) => return Ok(Response::with((status::BadRequest, ":("))),
        }

        Ok(match compile(source, false) {
            Ok(source) => Response::with((status::Ok, source)),
            Err(error) => Response::with((status::UnprocessableEntity, format!("{:?}", error))),
        })
    }

    let port = option_env!("PORT").map(|port| port.parse().expect("Invalid port"))
                                  .unwrap_or(DEFAULT_PORT);

    let address = format!("0.0.0.0:{}", port);

    let _server = Iron::new(handler).http(address.as_str()).expect("Cannot start the server");

    println!("Listening on port {}", port);
}
<|endoftext|>


<commit_before>/// Run the static site generator.
#[macro_use]
extern crate clap;
extern crate glob;
extern crate pandoc;  // TODO: extract to `lib.rs`.
extern crate lightning;

mod cli;

// Standard library
use std::fs::OpenOptions;
use std::io::prelude::*;
use std::path::Path;

// Third party
use clap::{Arg, App};
use glob::glob;
use pandoc::{Pandoc, PandocOption, InputFormat, OutputFormat, OutputKind};

// First party
use cli::{cli, Command};
use lightning::syntax_highlighting::syntax_highlight;

/// Define a `Result`-returning function to run the app.
///
/// (This is a standard Rust pattern to support the use of `try~`/`?`.)
fn run() -> Result<(), String> {
    let extra_args: Vec<Arg> = vec![];
    let subcommands: Vec<App> = vec![];
    let args = cli(&extra_args, &subcommands)?;

    // TODO: actually use those matches.
    match args.sub_command {
        Command::Generate => {}
        Command::New => {}
        Command::Unspecified => {
            return Err(format!("Failed to parse command line."))
        }
    }

    // In the vein of "MVP": let's start by just loading all the files. We'll
    // extract this all into standalone functions as necessary later.

    // TODO: load this from the configuration file.
    let directory = Path::new("tests/data");

    // TODO: instead of unwrapping the directory and the glob result, we'll
    //   actually check both.
    let dir_str = format!("{}/**/*.md", directory.to_str().unwrap());
    let markdown_files = glob(&dir_str).unwrap();

    // TODO: we'll repeat this process on *all* of them instead of just one.
    //   Eventually we'll do that iteration with `rayon::par_iter::for_each()`.
    for file in markdown_files {
        // TODO: extract this into a nice function to call in a for loop/foreach.
        // Need to make item live long enough after unwrapping.
        let file = file.unwrap();
        let file = file.to_str().unwrap();

        let mut pandoc = Pandoc::new();
        pandoc.set_input_format(InputFormat::Markdown)
              .set_output_format(OutputFormat::Html5)
              .add_options(&[PandocOption::Smart, PandocOption::NoHighlight])
              .add_input(file)
              .set_output(OutputKind::Pipe);

        // TODO: don't panic, return a Result. That can then be a `?`.
        let output = match pandoc.execute_with_output() {
            Ok(output) => output,
            Err(err) => panic!("Failed pandoc-ing {}:\n{:?}", file, err),
        };

        let highlighted = syntax_highlight(output);

        // TODO: extract this as part of the writing it out process.
        let ff_path = Path::new(file);
        let dest = Path::new("./tests/output")
                        .join(ff_path.file_name().unwrap())
                        .with_extension("html");

        let mut fd = match OpenOptions::new()
                                       .write(true)
                                       .create(true)
                                       .open(dest.clone()) {
            Ok(fd) => fd,
            Err(why) => {
                return Err(format!("Could not open {} for write: {}", dest.to_string_lossy(), why))
            }
        };

        let result = write!(fd, "{}", highlighted);
        if let Err(reason) = result {
            return Err(format!("{:?}", reason.kind()));
        }
    }

    Ok(())
}

fn main() {
    if let Err(reason) = run() {
        // if this fails, we literally can't do a thing except panic.
        write!(std::io::stderr(), "failure: {}", reason).unwrap();
        std::process::exit(1);
    }
}
<commit_msg>Eliminate `unwrap()` in favor of returning `Result`.<commit_after>/// Run the static site generator.
#[macro_use]
extern crate clap;
extern crate glob;
extern crate pandoc;  // TODO: extract to `lib.rs`.
extern crate lightning;

mod cli;

// Standard library
use std::fs::OpenOptions;
use std::io::prelude::*;
use std::path::Path;

// Third party
use clap::{Arg, App};
use glob::glob;
use pandoc::{Pandoc, PandocOption, InputFormat, OutputFormat, OutputKind};

// First party
use cli::{cli, Command};
use lightning::syntax_highlighting::syntax_highlight;

fn main() {
    if let Err(reason) = run() {
        // if this fails, we literally can't do a thing except panic.
        write!(std::io::stderr(), "failure: {}", reason).unwrap();
        std::process::exit(1);
    }
}

/// Define a `Result`-returning function to run the app.
///
/// (This is a standard Rust pattern to support the use of `try~`/`?`.)
fn run() -> Result<(), String> {
    let extra_args: Vec<Arg> = vec![];
    let subcommands: Vec<App> = vec![];
    let args = cli(&extra_args, &subcommands)?;

    // TODO: actually use those matches.
    match args.sub_command {
        Command::Generate => {}
        Command::New => {}
        Command::Unspecified => {
            return Err(format!("Failed to parse command line."))
        }
    }

    // In the vein of "MVP": let's start by just loading all the files. We'll
    // extract this all into standalone functions as necessary later.

    // TODO: load this from the configuration file.
    let directory = Path::new("tests/data");
    let dir_str = format!(
        "{}/**/*.md",
        directory.to_str().ok_or(String::from("bad directory"))?
    );

    let markdown_files = glob(&dir_str).map_err(|err| format!("{:?}", err))?;

    // TODO: Iterate with `rayon::par_iter::for_each()`.
    for path_result in markdown_files {
        // TODO: extract this into a nice function to call in a for loop/foreach.
        let path = path_result.map_err(|e| format!("{:?}", e))?;
        let file_name = path.to_str()
                            .ok_or(format!("Could not convert path {:?} to str", path))?;

        let mut pandoc = Pandoc::new();
        pandoc.set_input_format(InputFormat::Markdown)
              .set_output_format(OutputFormat::Html5)
              .add_options(&[PandocOption::Smart, PandocOption::NoHighlight])
              .add_input(file_name)
              .set_output(OutputKind::Pipe);

        let converted = pandoc.execute_with_output()
                              .map_err(|err| format!("pandoc failure: {}:\n{:?}", file_name, err))?;

        let highlighted = syntax_highlight(converted);

        // TODO: extract this as part of the writing it out process.
        let ff_path = Path::new(file_name);
        let dest = Path::new("./tests/output")
                        .join(ff_path.file_name().ok_or(format!("invalid file: {}", file_name))?)
                        .with_extension("html");

        let mut fd = OpenOptions::new()
                                 .write(true)
                                 .create(true)
                                 .open(dest.clone())
                                 .map_err(|reason| {
                                     format!(
                                         "Could not open {} for write: {}",
                                         dest.to_string_lossy(),
                                         reason
                                     )
                                 })?;

        let result = write!(fd, "{}", highlighted);
        if let Err(reason) = result {
            return Err(format!("{:?}", reason.kind()));
        }
    }

    Ok(())
}
<|endoftext|>


<commit_before>#[macro_use(crate_version, crate_authors)]
extern crate clap;
extern crate vmm;

use clap::{App, Arg};
use vmm::boot_kernel;
use vmm::machine::MachineCfg;

fn main() {
    let matches = App::new("firecracker")
        .version(crate_version!())
        .author(crate_authors!())
        .about("Launch a microvm.")
        .arg(Arg::with_name("kernel_path")
            .short("k")
            .long("kernel-path")
            .help("The kernel's file path (vmlinux.bin)")
            .required(true)
            .takes_value(true))
        .arg(Arg::with_name("kernel_cmdline")
            .long("kernel-cmdline")
            .help("The kernel's command line")
            .takes_value(true))
        .get_matches();

    let mut cfg = MachineCfg::new();
    cfg.populate(matches).expect("parsing arguments failed");

    boot_kernel(&cfg).expect("cannot boot kernel");
}
<commit_msg>root: fix style by running cargo fmt<commit_after>#[macro_use(crate_version, crate_authors)]
extern crate clap;
extern crate vmm;

use clap::{App, Arg};
use vmm::boot_kernel;
use vmm::machine::MachineCfg;

fn main() {
    let matches = App::new("firecracker")
        .version(crate_version!())
        .author(crate_authors!())
        .about("Launch a microvm.")
        .arg(
            Arg::with_name("kernel_path")
                .short("k")
                .long("kernel-path")
                .help("The kernel's file path (vmlinux.bin)")
                .required(true)
                .takes_value(true),
        )
        .arg(
            Arg::with_name("kernel_cmdline")
                .long("kernel-cmdline")
                .help("The kernel's command line")
                .takes_value(true),
        )
        .get_matches();

    let mut cfg = MachineCfg::new();
    cfg.populate(matches).expect("parsing arguments failed");

    boot_kernel(&cfg).expect("cannot boot kernel");
}
<|endoftext|>


<commit_before>extern crate clap;
extern crate quick_xml;

use clap::{Arg, App};

use std::path::Path;

use std::fs;
use std::fs::File;
use std::io::Write;
use std::io::BufReader;

use std::str;

use quick_xml::reader::Reader;
use quick_xml::events::Event;

fn read_file_names(path: &Path) -> Vec<String> {

    let mut names:Vec<String> = Vec::new();

    match fs::read_dir(path.clone()) {
        Err(why) => println!("! {:?}", why.kind()),
        Ok(paths) => {
            names = paths.filter_map(|entry| {
                    entry.ok().and_then(|e| {
                        e.path()
                             .file_name()
                             .and_then(|n| n.to_str().map(|s| String::from(s)))
                    })
                })
                .collect::<Vec<String>>(); //Transforms the iterator into a collection
        }
    };

    names
}

fn main(){

    //Clap
    let matches = App::new("extract tags from gfx-xml")
                        .version("0.1")
                        .about("Extract tags from factorytalk gfx-xml file!")
                        .author("Michael Groncki")
                        .arg(Arg::with_name("INPUT")
                            .help("Sets the input dir to use")
                            .required(true)
                            .index(1))
                        .get_matches();

    let path = Path::new(matches.value_of("INPUT").unwrap());
    println!("{}", path.to_str().unwrap());

    println!("{:?}", read_file_names(path));

    for entry in read_file_names(path) {

        let file_name_in = format!("{}\\{}", String::from(path.to_str().unwrap()), entry);
        println!(); println!("Using input file: {}", file_name_in); println!();
        let input = File::open(file_name_in.clone()).unwrap();

        //Output file
        let file_name_out = format!("{}{}{}{}", String::from(path.to_str().unwrap()), "\\tagnames_", entry, ".txt");
        println!(); println!("Using output file: {}", file_name_out); println!();
        let mut output = File::create(file_name_out).unwrap();

        //Create xml reader
        let buffered = BufReader::new(input);
        let mut reader = Reader::from_reader(buffered);
        reader.trim_text(true);

        let mut buf = Vec::new();

        let mut tag_names:Vec<String> = Vec::new(); //save all tags found during search here

        // The `Reader` does not implement `Iterator` because it outputs borrowed data (`Cow`s)
        loop {
            match reader.read_event(&mut buf) {
                // Ok(Event::Start(ref e)) => {

                //     match e.name() {
                //         b"group" => {
                //             let my_result = e.attributes().map(|a| a.unwrap()).collect::<Vec<_>>();

                //             for attrib in e.attributes() {

                //                 let my_attrib:quick_xml::events::attributes::Attribute = attrib.unwrap();

                //                 let my_key = str::from_utf8(my_attrib.key).unwrap();
                //                 let my_value = str::from_utf8(my_attrib.value).unwrap();

                //                 if my_key == "isReferenceObject" {
                //                     if my_value == "true" {
                //                         // println!("The group is reference object!");
                //                     }
                //                 }
                //             }

                //             for rs in &my_result {
                //                 if str::from_utf8(rs.key).unwrap() == "isReferenceObject" {
                //                     // println!("{:?}", str::from_utf8(rs.key).unwrap());
                //                 }
                //             }
                //         }

                //         _ => (),
                //     }
                // },
                Ok(Event::Empty(ref e)) => {

                    match e.name() {
                        b"connection" => {
                            let my_result = e.attributes().map(|a| a.unwrap()).collect::<Vec<_>>();
                            // println!("attributes values: {:?} - {:?}", str::from_utf8(my_result[1].key).unwrap(), str::from_utf8(my_result[1].value).unwrap());
                            tag_names.push(String::from(str::from_utf8(my_result[1].value).unwrap()));
                        },

                        b"parameter" => {
                            let my_result = e.attributes().map(|a| a.unwrap()).collect::<Vec<_>>();
                            if str::from_utf8(my_result[2].value).unwrap().contains("{") {
                                // println!("attributes values: {:?} - {:?}", str::from_utf8(my_result[2].key).unwrap(), str::from_utf8(my_result[2].value).unwrap());
                                tag_names.push(String::from(str::from_utf8(my_result[2].value).unwrap()));
                            }
                        },

                        _ => (),
                    }
                },
                Ok(Event::Eof) => break, // exits the loop when reaching end of file
                Err(e) => panic!("Error at position {}: {:?}", reader.buffer_position(), e),
                _ => (), // There are several other `Event`s we do not consider here
            }

            // if we don't keep a borrow elsewhere, we can clear the buffer to keep memory usage low
            buf.clear();
        }

        println!("--- Tagnames ---");

        let mut tag_name_placeholder:Vec<String> = Vec::new(); //save tags which contains a placeholder here
        let mut final_tag_names:Vec<String> = Vec::new(); //the final tags

        for tag in tag_names {
            //Remove curly braces
            let v: Vec<&str> = tag.split(|c| c == '{' || c == '}').collect();

            if tag.contains("#") {
                tag_name_placeholder.push(String::from(v[1]));
            }

            if tag.contains("[PLC") {
                for placeholder in &tag_name_placeholder {
                    final_tag_names.push(placeholder.replace("#1", &String::from(v[1])));
                }
                &tag_name_placeholder.clear();
            }

        }

        //print tag names to screen
        for name in final_tag_names {
            println!("{:?}", name);
            write!(output, "{}\r\n", name).unwrap();
        }

        println!("--- Done ---");

    }
}
<commit_msg>modified read dir function<commit_after>extern crate clap;
extern crate quick_xml;

use clap::{Arg, App};

use std::ffi::OsStr;

use std::path::Path;

use std::fs;
use std::fs::File;
use std::io::Write;
use std::io::BufReader;

use std::str;

use quick_xml::reader::Reader;
use quick_xml::events::Event;

fn read_file_names(path: &Path) -> Vec<String> {
    let mut names:Vec<String> = Vec::new();

    let entries = fs::read_dir(path).unwrap();

    for entry in entries {

        let my_entry = entry.unwrap();

        //Determine the file extention
        let fullpath = my_entry.path().into_os_string().into_string().unwrap();
        let file_path = std::path::Path::new(&fullpath);
        let content_type = match file_path.extension().and_then(OsStr::to_str) {
                Some("xml") => "text/xml",
                _ => "",
        };

        //Save fullpath if the file extention is "xml"
        if content_type == "text/xml" {
            names.push(my_entry.path().into_os_string().into_string().unwrap());
        }
    }

    //Return filenames
    names
}

fn main(){

    //Clap
    let matches = App::new("extract tags from gfx-xml")
                        .version("0.1")
                        .about("Extract tags from factorytalk gfx-xml file!")
                        .author("Michael Groncki")
                        .arg(Arg::with_name("INPUT")
                            .help("Sets the input dir to use")
                            .required(true)
                            .index(1))
                        .get_matches();

    let path = Path::new(matches.value_of("INPUT").unwrap());

    for entry in read_file_names(path) {

        let file_name_in = format!("{}", entry);
        println!(); println!("Using input file: {}", file_name_in); println!();
        let input = File::open(file_name_in.clone()).unwrap();

        //Output file
        let file_name_out = format!("{}{}", entry, ".txt");
        println!(); println!("Using output file: {}", file_name_out); println!();
        let mut output = File::create(file_name_out).unwrap();

        //Create xml reader
        let buffered = BufReader::new(input);
        let mut reader = Reader::from_reader(buffered);
        reader.trim_text(true);

        let mut buf = Vec::new();

        let mut tag_names:Vec<String> = Vec::new(); //save all tags found during search here

        // The `Reader` does not implement `Iterator` because it outputs borrowed data (`Cow`s)
        loop {
            match reader.read_event(&mut buf) {
                // Ok(Event::Start(ref e)) => {

                //     match e.name() {
                //         b"group" => {
                //             let my_result = e.attributes().map(|a| a.unwrap()).collect::<Vec<_>>();

                //             for attrib in e.attributes() {

                //                 let my_attrib:quick_xml::events::attributes::Attribute = attrib.unwrap();

                //                 let my_key = str::from_utf8(my_attrib.key).unwrap();
                //                 let my_value = str::from_utf8(my_attrib.value).unwrap();

                //                 if my_key == "isReferenceObject" {
                //                     if my_value == "true" {
                //                         // println!("The group is reference object!");
                //                     }
                //                 }
                //             }

                //             for rs in &my_result {
                //                 if str::from_utf8(rs.key).unwrap() == "isReferenceObject" {
                //                     // println!("{:?}", str::from_utf8(rs.key).unwrap());
                //                 }
                //             }
                //         }

                //         _ => (),
                //     }
                // },
                Ok(Event::Empty(ref e)) => {

                    match e.name() {
                        b"connection" => {
                            let my_result = e.attributes().map(|a| a.unwrap()).collect::<Vec<_>>();
                            // println!("attributes values: {:?} - {:?}", str::from_utf8(my_result[1].key).unwrap(), str::from_utf8(my_result[1].value).unwrap());
                            tag_names.push(String::from(str::from_utf8(my_result[1].value).unwrap()));
                        },

                        b"parameter" => {
                            let my_result = e.attributes().map(|a| a.unwrap()).collect::<Vec<_>>();
                            if str::from_utf8(my_result[2].value).unwrap().contains("{") {
                                // println!("attributes values: {:?} - {:?}", str::from_utf8(my_result[2].key).unwrap(), str::from_utf8(my_result[2].value).unwrap());
                                tag_names.push(String::from(str::from_utf8(my_result[2].value).unwrap()));
                            }
                        },

                        _ => (),
                    }
                },
                Ok(Event::Eof) => break, // exits the loop when reaching end of file
                Err(e) => panic!("Error at position {}: {:?}", reader.buffer_position(), e),
                _ => (), // There are several other `Event`s we do not consider here
            }

            // if we don't keep a borrow elsewhere, we can clear the buffer to keep memory usage low
            buf.clear();
        }

        println!("--- Tagnames ---");

        let mut tag_name_placeholder:Vec<String> = Vec::new(); //save tags which contains a placeholder here
        let mut final_tag_names:Vec<String> = Vec::new(); //the final tags

        for tag in tag_names {
            //Remove curly braces
            let v: Vec<&str> = tag.split(|c| c == '{' || c == '}').collect();

            if tag.contains("#") {
                tag_name_placeholder.push(String::from(v[1]));
            }

            if tag.contains("[PLC") {
                for placeholder in &tag_name_placeholder {
                    final_tag_names.push(placeholder.replace("#1", &String::from(v[1])));
                }
                &tag_name_placeholder.clear();
            }

        }

        //print tag names to screen
        for name in final_tag_names {
            println!("{:?}", name);
            write!(output, "{}\r\n", name).unwrap();
        }

        println!("--- Done ---");

    }
}
<|endoftext|>


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

#![feature(result_expect)]

extern crate melvin;

use std::path;
use std::io::Result;
use std::io::Error;
use std::io::ErrorKind::Other;

use melvin::parser;
use melvin::parser::LvmTextMap;
use melvin::parser::TextMapOps;
use melvin::lvmetad;
use melvin::pvlabel;
use melvin::pvlabel::PvHeader;
use melvin::dm;

fn get_first_vg_meta() -> Result<(String, LvmTextMap)> {
    let dirs = vec![path::Path::new("/dev")];

    for path in try!(pvlabel::scan_for_pvs(&dirs)) {
        let pvheader = try!(PvHeader::find_in_dev(&path));
        let map = try!(pvheader.read_metadata());

        for (key, value) in map {
            match value {
                parser::Entry::TextMap(x) => return Ok((key, *x)),
                _ => {}
            }
        }
    }

    Err(Error::new(Other, "dude"))
}

fn get_conf() -> Result<LvmTextMap> {
    use std::fs;
    use std::io::Read;

    let mut f = try!(fs::File::open("/etc/lvm/lvm.conf"));

    let mut buf = Vec::new();
    try!(f.read_to_end(&mut buf));

    parser::buf_to_textmap(&buf)
}

fn main() {
    let (name, map) = get_first_vg_meta().unwrap();
    let vg = parser::vg_from_textmap(&name, &map).expect("didn't get vg!");
    // println!("heyo {} {}", vg.extents(), vg.extent_size);
    // println!("output {:?}", vg);

    // {
    //     let dm = dm::DM::new(&vg).unwrap();
    //     match dm.list_devices() {
    //         Ok(x) => println!("{:?}", x),
    //         Err(x) => println!("error {}", x),
    //     }
    // }

    // let mut vgs = lvmetad::vgs_from_lvmetad().expect("could not get vgs from lvmetad");
    // let mut vg = vgs.pop().expect("no vgs in vgs");

    // vg.new_linear_lv("grover125", 100);
    // vg.new_linear_lv("grover126", 200);

    // for (lvname, lv) in &vg.lvs {
    //     println!("lv2 {:?}", lv);
    // }

    // let tm = get_conf().expect("could not read lvm.conf");
    // let locking_type = tm.textmap_from_textmap("global")
    //     .and_then(|g| g.i64_from_textmap("locking_type")).unwrap();

    // println!("locking_type = {}", locking_type);

    // let vgtm = vg.into();
    // let s = parser::textmap_to_buf(&vgtm);
}
<commit_msg>update main.rs<commit_after>// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

#![feature(result_expect)]

extern crate melvin;

use std::path;
use std::io::Result;
use std::io::Error;
use std::io::ErrorKind::Other;
use std::str::FromStr;

use melvin::parser;
use melvin::parser::LvmTextMap;
use melvin::parser::TextMapOps;
use melvin::lvmetad;
use melvin::pvlabel;
use melvin::pvlabel::PvHeader;
use melvin::pv::Device;
use melvin::dm;

fn print_pvheaders() -> Result<()> {
    let dirs = vec![path::Path::new("/dev")];

    for path in try!(pvlabel::scan_for_pvs(&dirs)) {
        let pvheader = try!(PvHeader::find_in_dev(&path));
        println!("pvheader {:#?}", pvheader);
    }

    Ok(())
}

fn get_first_vg_meta() -> Result<(String, LvmTextMap)> {
    let dirs = vec![path::Path::new("/dev")];

    for path in try!(pvlabel::scan_for_pvs(&dirs)) {
        let pvheader = try!(PvHeader::find_in_dev(&path));
        println!("pvheader {:#?}", pvheader);
        let map = try!(pvheader.read_metadata());

        for (key, value) in map {
            match value {
                parser::Entry::TextMap(x) => return Ok((key, *x)),
                _ => {}
            }
        }
    }

    Err(Error::new(Other, "dude"))
}

fn get_conf() -> Result<LvmTextMap> {
    use std::fs;
    use std::io::Read;

    let mut f = try!(fs::File::open("/etc/lvm/lvm.conf"));

    let mut buf = Vec::new();
    try!(f.read_to_end(&mut buf));

    parser::buf_to_textmap(&buf)
}

fn main() {
    println!("{:?}", PvHeader::initialize(&Device::from_str("/dev/vdc1").unwrap()));
    print_pvheaders();
    // let (name, map) = get_first_vg_meta().unwrap();
    // let vg = parser::vg_from_textmap(&name, &map).expect("didn't get vg!");
    // println!("heyo {} {}", vg.extents(), vg.extent_size);
    // println!("output {:?}", vg);

    // {
    //     let dm = dm::DM::new(&vg).unwrap();
    //     match dm.list_devices() {
    //         Ok(x) => println!("{:?}", x),
    //         Err(x) => println!("error {}", x),
    //     }
    // }

    // let mut vgs = lvmetad::vgs_from_lvmetad().expect("could not get vgs from lvmetad");
    // let mut vg = vgs.pop().expect("no vgs in vgs");

    // vg.new_linear_lv("grover125", 100);
    // vg.new_linear_lv("grover126", 200);

    // for (lvname, lv) in &vg.lvs {
    //     println!("lv2 {:?}", lv);
    // }

    // let tm = get_conf().expect("could not read lvm.conf");
    // let locking_type = tm.textmap_from_textmap("global")
    //     .and_then(|g| g.i64_from_textmap("locking_type")).unwrap();

    // println!("locking_type = {}", locking_type);

    // let vgtm = vg.into();
    // let s = parser::textmap_to_buf(&vgtm);
}
<|endoftext|>


<commit_before>// MSPC == 'multiple sender, single receiver'
use std::sync::mpsc::{Sender, Receiver};
use std::sync::mpsc;
use std::thread;

type Payload = i32;
type Message = (Payload, Sender<Payload>);

fn main() {
    // Actor Mailbox
    let (outbox, inbox): (Sender<Message>, Receiver<Message>) = mpsc::channel();

    // Create a new thread
    let handle = thread::Builder::new()
        .name("actor".into())
        .spawn(move || {
            // Forever...
            loop {
                // See if we have messages!
                match inbox.recv() {
                    // If we're given a 'special' -1 value, exit.
                    Ok((num, _)) if num == -1 => {
                        println!("[Actor] Exiting!");
                        break;
                    }
                    // Otherwise, print and respond to the message!
                    Ok((num, sender)) => {
                        println!("[Actor] Got: {:?}", num);
                        sender.send(num + 1).unwrap();
                    }
                    // Exit on error
                    Err(e) => {
                        println!("[Actor] Error: {:?}", e);
                        break;
                    },
                }
            }

        })
        .unwrap();

    // Communication channel with actor
    let (sender, receiver): (Sender<Payload>, Receiver<Payload>) = mpsc::channel();
    outbox.send((0, sender.clone())).unwrap();
    let num = receiver.recv().unwrap();
    println!("[Main] Got: {:?}", num);

    // Send another number!
    outbox.send((num + 1, sender.clone())).unwrap();
    let num = receiver.recv().unwrap();
    println!("[Main] Got: {:?}", num);

    // Send exit code
    outbox.send((-1, sender.clone())).unwrap();

    // Wait for thread to exit
    let res = handle.join().unwrap();
    println!("[Main] Res: {:?}", res);
}
<commit_msg>message tuple --> struct<commit_after>// MSPC == 'multiple sender, single receiver'
use std::sync::mpsc::{Sender, Receiver};
use std::sync::mpsc;
use std::thread;

type Payload = i32;

struct Message {
    payload: i32,
    sender: Sender<i32>,
}

fn main() {
    // Actor Mailbox
    let (outbox, inbox): (Sender<Message>, Receiver<Message>) = mpsc::channel();

    // Create a new thread
    let handle = thread::Builder::new()
        .name("actor".into())
        .spawn(move || {
            // Forever...
            loop {
                // See if we have messages!
                match inbox.recv() {
                    // If we're given a 'special' -1 value, exit.
                    Ok(Message{payload: num, sender: _}) if num == -1 => {
                        println!("[Actor] Exiting!");
                        break;
                    },
                    // Otherwise, print and respond to the message!
                    Ok(Message{payload: num, sender: sender}) => {
                        println!("[Actor] Got: {:?}", num);
                        sender.send(num + 1).unwrap();
                    },
                    // Exit on error
                    Err(e) => {
                        println!("[Actor] Error: {:?}", e);
                        break;
                    },
                }
            }

        })
        .unwrap();

    // Communication channel with actor
    let (sender, receiver): (Sender<Payload>, Receiver<Payload>) = mpsc::channel();
    outbox.send(Message{payload: 0, sender: sender.clone()}).unwrap();
    let num = receiver.recv().unwrap();
    println!("[Main] Got: {:?}", num);

    // Send another number!
    outbox.send(Message{payload: num + 1, sender: sender.clone()}).unwrap();
    let num = receiver.recv().unwrap();
    println!("[Main] Got: {:?}", num);

    // Send exit code
    outbox.send(Message{payload: -1, sender: sender.clone()}).unwrap();

    // Wait for thread to exit
    let res = handle.join().unwrap();
    println!("[Main] Res: {:?}", res);
}
<|endoftext|>


<commit_before>fn main() {
    let test = "(abc)";
    let token = tokenize(test.to_string());
    println!("{}",token)
}

fn tokenize(chars: String) -> Vec<String> {
    let with_sapace = chars.replace("(", "( ");
    chars.as_slice().split(' ').collect()
}
<commit_msg>Still no compile.<commit_after>fn main() {
    let test = "(abc)".to_string();
    let token = tokenize(&test);

}

fn tokenize<'s>(chars: &'s String) -> Vec<&'s str> {
    let with_space: &'s String = chars.replace("(", "( ");
    let vected: Vec<&'s str>  = with_space.as_slice().split(' ').collect();
    return vected
}
<|endoftext|>


<commit_before>// error-pattern:yummy
#![feature(box_syntax)]
#![feature(rustc_private)]
#![allow(unknown_lints, missing_docs_in_private_items)]

const CARGO_CLIPPY_HELP: &str = r#"Checks a package to catch common mistakes and improve your Rust code.

Usage:
    cargo clippy [options] [--] [<opts>...]

Common options:
    -h, --help               Print this message
    -V, --version            Print version info and exit

Other options are the same as `cargo check`.

To allow or deny a lint from the command line you can use `cargo clippy --`
with:

    -W --warn OPT       Set lint warnings
    -A --allow OPT      Set lint allowed
    -D --deny OPT       Set lint denied
    -F --forbid OPT     Set lint forbidden

The feature `cargo-clippy` is automatically defined for convenience. You can use
it to allow or deny lints from the code, eg.:

    #[cfg_attr(feature = "cargo-clippy", allow(needless_lifetimes))]
"#;

#[allow(print_stdout)]
fn show_help() {
    println!("{}", CARGO_CLIPPY_HELP);
}

#[allow(print_stdout)]
fn show_version() {
    println!("{}", env!("CARGO_PKG_VERSION"));
}

pub fn main() {
    // Check for version and help flags even when invoked as 'cargo-clippy'
    if std::env::args().any(|a| a == "--help" || a == "-h") {
        show_help();
        return;
    }
    if std::env::args().any(|a| a == "--version" || a == "-V") {
        show_version();
        return;
    }

    if let Err(code) = process(std::env::args().skip(2)) {
        std::process::exit(code);
    }
}

fn process<I>(mut old_args: I) -> Result<(), i32>
where
    I: Iterator<Item = String>,
{
    let mut args = vec!["check".to_owned()];

    let mut found_dashes = false;
    for arg in old_args.by_ref() {
        found_dashes |= arg == "--";
        if found_dashes {
            break;
        }
        args.push(arg);
    }

    let clippy_args: String = old_args.map(|arg| format!("{}__CLIPPY_HACKERY__", arg)).collect();

    let mut path = std::env::current_exe()
        .expect("current executable path invalid")
        .with_file_name("clippy-driver");
    if cfg!(windows) {
        path.set_extension("exe");
    }

    let target_dir = std::env::var_os("CLIPPY_DOGFOOD")
        .map(|_| {
            std::env::var_os("CARGO_MANIFEST_DIR").map_or_else(
                || {
                    let mut fallback = std::ffi::OsString::new();
                    fallback.push("clippy_dogfood");
                    fallback
                },
                |d| {
                    std::path::PathBuf::from(d)
                        .join("target")
                        .join("dogfood")
                        .into_os_string()
                },
            )
        })
        .map(|p| ("CARGO_TARGET_DIR", p));

    let exit_status = std::process::Command::new("cargo")
        .args(&args)
        .env("RUSTC_WRAPPER", path)
        .env("CLIPPY_ARGS", clippy_args)
        .envs(target_dir)
        .spawn()
        .expect("could not run cargo")
        .wait()
        .expect("failed to wait for cargo?");

    if exit_status.success() {
        Ok(())
    } else {
        Err(exit_status.code().unwrap_or(-1))
    }
}
<commit_msg>Fix clippy warning<commit_after>// error-pattern:yummy
#![feature(box_syntax)]
#![feature(rustc_private)]
#![allow(unknown_lints, missing_docs_in_private_items)]

const CARGO_CLIPPY_HELP: &str = r#"Checks a package to catch common mistakes and improve your Rust code.

Usage:
    cargo clippy [options] [--] [<opts>...]

Common options:
    -h, --help               Print this message
    -V, --version            Print version info and exit

Other options are the same as `cargo check`.

To allow or deny a lint from the command line you can use `cargo clippy --`
with:

    -W --warn OPT       Set lint warnings
    -A --allow OPT      Set lint allowed
    -D --deny OPT       Set lint denied
    -F --forbid OPT     Set lint forbidden

The feature `cargo-clippy` is automatically defined for convenience. You can use
it to allow or deny lints from the code, eg.:

    #[cfg_attr(feature = "cargo-clippy", allow(needless_lifetimes))]
"#;

#[allow(print_stdout)]
fn show_help() {
    println!("{}", CARGO_CLIPPY_HELP);
}

#[allow(print_stdout)]
fn show_version() {
    println!(env!("CARGO_PKG_VERSION"));
}

pub fn main() {
    // Check for version and help flags even when invoked as 'cargo-clippy'
    if std::env::args().any(|a| a == "--help" || a == "-h") {
        show_help();
        return;
    }
    if std::env::args().any(|a| a == "--version" || a == "-V") {
        show_version();
        return;
    }

    if let Err(code) = process(std::env::args().skip(2)) {
        std::process::exit(code);
    }
}

fn process<I>(mut old_args: I) -> Result<(), i32>
where
    I: Iterator<Item = String>,
{
    let mut args = vec!["check".to_owned()];

    let mut found_dashes = false;
    for arg in old_args.by_ref() {
        found_dashes |= arg == "--";
        if found_dashes {
            break;
        }
        args.push(arg);
    }

    let clippy_args: String = old_args.map(|arg| format!("{}__CLIPPY_HACKERY__", arg)).collect();

    let mut path = std::env::current_exe()
        .expect("current executable path invalid")
        .with_file_name("clippy-driver");
    if cfg!(windows) {
        path.set_extension("exe");
    }

    let target_dir = std::env::var_os("CLIPPY_DOGFOOD")
        .map(|_| {
            std::env::var_os("CARGO_MANIFEST_DIR").map_or_else(
                || {
                    let mut fallback = std::ffi::OsString::new();
                    fallback.push("clippy_dogfood");
                    fallback
                },
                |d| {
                    std::path::PathBuf::from(d)
                        .join("target")
                        .join("dogfood")
                        .into_os_string()
                },
            )
        })
        .map(|p| ("CARGO_TARGET_DIR", p));

    let exit_status = std::process::Command::new("cargo")
        .args(&args)
        .env("RUSTC_WRAPPER", path)
        .env("CLIPPY_ARGS", clippy_args)
        .envs(target_dir)
        .spawn()
        .expect("could not run cargo")
        .wait()
        .expect("failed to wait for cargo?");

    if exit_status.success() {
        Ok(())
    } else {
        Err(exit_status.code().unwrap_or(-1))
    }
}
<|endoftext|>