<commit_before>use super::helpers::edits::{get_random_edit, invert_edit};
use super::helpers::fixtures::{fixtures_dir, get_language, get_test_language};
use super::helpers::random::Rand;
use super::helpers::scope_sequence::ScopeSequence;
use crate::generate;
use crate::parse::perform_edit;
use crate::test::{parse_tests, print_diff, print_diff_key, strip_sexp_fields, TestEntry};
use crate::util;
use lazy_static::lazy_static;
use std::{env, fs, time, usize};
use tree_sitter::{allocations, LogType, Node, Parser, Tree};

const EDIT_COUNT: usize = 3;
const TRIAL_COUNT: usize = 10;

lazy_static! {
    static ref LOG_ENABLED: bool = env::var("TREE_SITTER_TEST_ENABLE_LOG").is_ok();
    static ref LOG_GRAPH_ENABLED: bool = env::var("TREE_SITTER_TEST_ENABLE_LOG_GRAPHS").is_ok();
    static ref LANGUAGE_FILTER: Option<String> = env::var("TREE_SITTER_TEST_LANGUAGE_FILTER").ok();
    static ref EXAMPLE_FILTER: Option<String> = env::var("TREE_SITTER_TEST_EXAMPLE_FILTER").ok();
    static ref TRIAL_FILTER: Option<usize> = env::var("TREE_SITTER_TEST_TRIAL_FILTER")
        .map(|s| usize::from_str_radix(&s, 10).unwrap())
        .ok();
    pub static ref SEED: usize = env::var("TREE_SITTER_TEST_SEED")
        .map(|s| {
            let seed = usize::from_str_radix(&s, 10).unwrap();
            eprintln!("\n\nRandom seed: {}\n", *SEED);
            seed
        })
        .unwrap_or(
            time::SystemTime::now()
                .duration_since(time::UNIX_EPOCH)
                .unwrap()
                .as_secs() as usize,
        );
}

#[test]
fn test_bash_corpus() {
    test_language_corpus("bash");
}

#[test]
fn test_c_corpus() {
    test_language_corpus("c");
}

#[test]
fn test_cpp_corpus() {
    test_language_corpus("cpp");
}

#[test]
fn test_embedded_template_corpus() {
    test_language_corpus("embedded-template");
}

#[test]
fn test_go_corpus() {
    test_language_corpus("go");
}

#[test]
fn test_html_corpus() {
    test_language_corpus("html");
}

#[test]
fn test_javascript_corpus() {
    test_language_corpus("javascript");
}

#[test]
fn test_json_corpus() {
    test_language_corpus("json");
}

#[test]
fn test_php_corpus() {
    test_language_corpus("php");
}

#[test]
fn test_python_corpus() {
    test_language_corpus("python");
}

#[test]
fn test_ruby_corpus() {
    test_language_corpus("ruby");
}

#[test]
fn test_rust_corpus() {
    test_language_corpus("rust");
}

fn test_language_corpus(language_name: &str) {
    if let Some(language_filter) = LANGUAGE_FILTER.as_ref() {
        if language_filter != language_name {
            return;
        }
    }

    let grammars_dir = fixtures_dir().join("grammars");
    let error_corpus_dir = fixtures_dir().join("error_corpus");

    let mut failure_count = 0;

    let language = get_language(language_name);
    let mut corpus_dir = grammars_dir.join(language_name).join("corpus");
    if !corpus_dir.is_dir() {
        corpus_dir = grammars_dir.join(language_name).join("test").join("corpus");
    }

    let error_corpus_file = error_corpus_dir.join(&format!("{}_errors.txt", language_name));
    let main_tests = parse_tests(&corpus_dir).unwrap();
    let error_tests = parse_tests(&error_corpus_file).unwrap_or(TestEntry::default());
    let mut tests = flatten_tests(main_tests);
    tests.extend(flatten_tests(error_tests));

    for (example_name, input, expected_output, has_fields) in tests {
        println!("  {} example - {}", language_name, example_name);

        let trial = 0;
        if TRIAL_FILTER.map_or(true, |t| t == trial) {
            let passed = allocations::record(|| {
                let mut log_session = None;
                let mut parser = get_parser(&mut log_session, "log.html");
                parser.set_language(language).unwrap();
                let tree = parser.parse(&input, None).unwrap();
                let mut actual_output = tree.root_node().to_sexp();
                if !has_fields {
                    actual_output = strip_sexp_fields(actual_output);
                }
                if actual_output == expected_output {
                    true
                } else {
                    println!(
                        "Incorrect initial parse for {} - {}",
                        language_name, example_name,
                    );
                    print_diff_key();
                    print_diff(&actual_output, &expected_output);
                    println!("");
                    false
                }
            });

            if !passed {
                failure_count += 1;
                continue;
            }
        }

        let mut parser = Parser::new();
        parser.set_language(language).unwrap();
        let tree = parser.parse(&input, None).unwrap();
        drop(parser);

        for trial in 1..=TRIAL_COUNT {
            if TRIAL_FILTER.map_or(true, |filter| filter == trial) {
                let mut rand = Rand::new(*SEED + trial);

                let passed = allocations::record(|| {
                    let mut log_session = None;
                    let mut parser = get_parser(&mut log_session, "log.html");
                    parser.set_language(language).unwrap();
                    let mut tree = tree.clone();
                    let mut input = input.clone();

                    if *LOG_GRAPH_ENABLED {
                        eprintln!("{}\n", String::from_utf8_lossy(&input));
                    }

                    // Perform a random series of edits and reparse.
                    let mut undo_stack = Vec::new();
                    for _ in 0..EDIT_COUNT {
                        let edit = get_random_edit(&mut rand, &input);
                        undo_stack.push(invert_edit(&input, &edit));
                        perform_edit(&mut tree, &mut input, &edit);
                    }
                    if *LOG_GRAPH_ENABLED {
                        eprintln!("{}\n", String::from_utf8_lossy(&input));
                    }

                    let mut tree2 = parser.parse(&input, Some(&tree)).unwrap();

                    // Check that the new tree is consistent.
                    check_consistent_sizes(&tree2, &input);
                    if let Err(message) = check_changed_ranges(&tree, &tree2, &input) {
                        println!(
                            "\nUnexpected scope change in trial {}\n{}\n\n",
                            trial, message
                        );
                        return false;
                    }

                    // Undo all of the edits and re-parse again.
                    while let Some(edit) = undo_stack.pop() {
                        perform_edit(&mut tree2, &mut input, &edit);
                    }
                    if *LOG_GRAPH_ENABLED {
                        eprintln!("{}\n", String::from_utf8_lossy(&input));
                    }

                    let tree3 = parser.parse(&input, Some(&tree2)).unwrap();

                    // Verify that the final tree matches the expectation from the corpus.
                    let mut actual_output = tree3.root_node().to_sexp();
                    if !has_fields {
                        actual_output = strip_sexp_fields(actual_output);
                    }

                    if actual_output != expected_output {
                        println!(
                            "Incorrect parse for {} - {} - trial {}",
                            language_name, example_name, trial
                        );
                        print_diff_key();
                        print_diff(&actual_output, &expected_output);
                        println!("");
                        return false;
                    }

                    // Check that the edited tree is consistent.
                    check_consistent_sizes(&tree3, &input);
                    if let Err(message) = check_changed_ranges(&tree2, &tree3, &input) {
                        eprintln!(
                            "Unexpected scope change in trial {}\n{}\n\n",
                            trial, message
                        );
                        return false;
                    }

                    true
                });

                if !passed {
                    failure_count += 1;
                    break;
                }
            }
        }
    }

    if failure_count > 0 {
        panic!("{} {} corpus tests failed", failure_count, language_name);
    }
}

#[test]
fn test_feature_corpus_files() {
    let test_grammars_dir = fixtures_dir().join("test_grammars");

    let mut failure_count = 0;
    for entry in fs::read_dir(&test_grammars_dir).unwrap() {
        let entry = entry.unwrap();
        if !entry.metadata().unwrap().is_dir() {
            continue;
        }
        let language_name = entry.file_name();
        let language_name = language_name.to_str().unwrap();

        if let Some(filter) = LANGUAGE_FILTER.as_ref() {
            if language_name != filter.as_str() {
                continue;
            }
        }

        let test_path = entry.path();
        let mut grammar_path = test_path.join("grammar.js");
        if !grammar_path.exists() {
            grammar_path = test_path.join("grammar.json");
        }
        let error_message_path = test_path.join("expected_error.txt");
        let grammar_json = generate::load_grammar_file(&grammar_path).unwrap();
        let generate_result = generate::generate_parser_for_grammar(&grammar_json);

        if error_message_path.exists() {
            if EXAMPLE_FILTER.is_some() {
                continue;
            }

            eprintln!("test language: {:?}", language_name);

            let expected_message = fs::read_to_string(&error_message_path)
                .unwrap()
                .replace("\r\n", "\n");
            if let Err(e) = generate_result {
                let actual_message = e.to_string().replace("\r\n", "\n");
                if expected_message != actual_message {
                    eprintln!(
                        "Unexpected error message.\n\nExpected:\n\n{}\nActual:\n\n{}\n",
                        expected_message, actual_message
                    );
                    failure_count += 1;
                }
            } else {
                eprintln!(
                    "Expected error message but got none for test grammar '{}'",
                    language_name
                );
                failure_count += 1;
            }
        } else {
            if let Err(e) = &generate_result {
                eprintln!(
                    "Unexpected error for test grammar '{}':\n{}",
                    language_name, e
                );
                failure_count += 1;
                continue;
            }

            let corpus_path = test_path.join("corpus.txt");
            let c_code = generate_result.unwrap().1;
            let language = get_test_language(language_name, &c_code, Some(&test_path));
            let test = parse_tests(&corpus_path).unwrap();
            let tests = flatten_tests(test);

            if !tests.is_empty() {
                eprintln!("test language: {:?}", language_name);
            }

            for (name, input, expected_output, has_fields) in tests {
                eprintln!("  example: {:?}", name);

                let passed = allocations::record(|| {
                    let mut log_session = None;
                    let mut parser = get_parser(&mut log_session, "log.html");
                    parser.set_language(language).unwrap();
                    let tree = parser.parse(&input, None).unwrap();
                    let mut actual_output = tree.root_node().to_sexp();
                    if !has_fields {
                        actual_output = strip_sexp_fields(actual_output);
                    }
                    if actual_output == expected_output {
                        true
                    } else {
                        print_diff_key();
                        print_diff(&actual_output, &expected_output);
                        println!("");
                        false
                    }
                });

                if !passed {
                    failure_count += 1;
                    continue;
                }
            }
        }
    }
    if failure_count > 0 {
        panic!("{} corpus tests failed", failure_count);
    }
}

fn check_consistent_sizes(tree: &Tree, input: &Vec<u8>) {
    fn check(node: Node, line_offsets: &Vec<usize>) {
        let start_byte = node.start_byte();
        let end_byte = node.end_byte();
        let start_point = node.start_position();
        let end_point = node.end_position();

        assert!(start_byte <= end_byte);
        assert!(start_point <= end_point);
        assert_eq!(
            start_byte,
            line_offsets[start_point.row] + start_point.column
        );
        assert_eq!(end_byte, line_offsets[end_point.row] + end_point.column);

        let mut last_child_end_byte = start_byte;
        let mut last_child_end_point = start_point;
        let mut some_child_has_changes = false;
        let mut actual_named_child_count = 0;
        for i in 0..node.child_count() {
            let child = node.child(i).unwrap();
            assert!(child.start_byte() >= last_child_end_byte);
            assert!(child.start_position() >= last_child_end_point);
            check(child, line_offsets);
            if child.has_changes() {
                some_child_has_changes = true;
            }
            if child.is_named() {
                actual_named_child_count += 1;
            }
            last_child_end_byte = child.end_byte();
            last_child_end_point = child.end_position();
        }

        assert_eq!(actual_named_child_count, node.named_child_count());

        if node.child_count() > 0 {
            assert!(end_byte >= last_child_end_byte);
            assert!(end_point >= last_child_end_point);
        }

        if some_child_has_changes {
            assert!(node.has_changes());
        }
    }

    let mut line_offsets = vec![0];
    for (i, c) in input.iter().enumerate() {
        if *c == '\n' as u8 {
            line_offsets.push(i + 1);
        }
    }

    check(tree.root_node(), &line_offsets);
}

fn check_changed_ranges(old_tree: &Tree, new_tree: &Tree, input: &Vec<u8>) -> Result<(), String> {
    let changed_ranges = old_tree.changed_ranges(new_tree).collect();
    let old_scope_sequence = ScopeSequence::new(old_tree);
    let new_scope_sequence = ScopeSequence::new(new_tree);
    old_scope_sequence.check_changes(&new_scope_sequence, &input, &changed_ranges)
}

fn get_parser(session: &mut Option<util::LogSession>, log_filename: &str) -> Parser {
    let mut parser = Parser::new();

    if *LOG_ENABLED {
        parser.set_logger(Some(Box::new(|log_type, msg| {
            if log_type == LogType::Lex {
                eprintln!("  {}", msg);
            } else {
                eprintln!("{}", msg);
            }
        })));
    } else if *LOG_GRAPH_ENABLED {
        *session = Some(util::log_graphs(&mut parser, log_filename).unwrap());
    }

    parser
}

fn flatten_tests(test: TestEntry) -> Vec<(String, Vec<u8>, String, bool)> {
    fn helper(
        test: TestEntry,
        is_root: bool,
        prefix: &str,
        result: &mut Vec<(String, Vec<u8>, String, bool)>,
    ) {
        match test {
            TestEntry::Example {
                mut name,
                input,
                output,
                has_fields,
            } => {
                if !prefix.is_empty() {
                    name.insert_str(0, " - ");
                    name.insert_str(0, prefix);
                }
                if let Some(filter) = EXAMPLE_FILTER.as_ref() {
                    if !name.contains(filter.as_str()) {
                        return;
                    }
                }
                result.push((name, input, output, has_fields));
            }
            TestEntry::Group {
                mut name, children, ..
            } => {
                if !is_root && !prefix.is_empty() {
                    name.insert_str(0, " - ");
                    name.insert_str(0, prefix);
                }
                for child in children {
                    helper(child, false, &name, result);
                }
            }
        }
    }
    let mut result = Vec::new();
    helper(test, true, "", &mut result);
    result
}
<commit_msg>Fix logging of seed in randomized test<commit_after>use super::helpers::edits::{get_random_edit, invert_edit};
use super::helpers::fixtures::{fixtures_dir, get_language, get_test_language};
use super::helpers::random::Rand;
use super::helpers::scope_sequence::ScopeSequence;
use crate::generate;
use crate::parse::perform_edit;
use crate::test::{parse_tests, print_diff, print_diff_key, strip_sexp_fields, TestEntry};
use crate::util;
use lazy_static::lazy_static;
use std::{env, fs, time, usize};
use tree_sitter::{allocations, LogType, Node, Parser, Tree};

const EDIT_COUNT: usize = 3;
const TRIAL_COUNT: usize = 10;

lazy_static! {
    static ref LOG_ENABLED: bool = env::var("TREE_SITTER_TEST_ENABLE_LOG").is_ok();
    static ref LOG_GRAPH_ENABLED: bool = env::var("TREE_SITTER_TEST_ENABLE_LOG_GRAPHS").is_ok();
    static ref LANGUAGE_FILTER: Option<String> = env::var("TREE_SITTER_TEST_LANGUAGE_FILTER").ok();
    static ref EXAMPLE_FILTER: Option<String> = env::var("TREE_SITTER_TEST_EXAMPLE_FILTER").ok();
    static ref TRIAL_FILTER: Option<usize> = env::var("TREE_SITTER_TEST_TRIAL_FILTER")
        .map(|s| usize::from_str_radix(&s, 10).unwrap())
        .ok();
    pub static ref SEED: usize = {
        let seed = env::var("TREE_SITTER_TEST_SEED")
            .map(|s| usize::from_str_radix(&s, 10).unwrap())
            .unwrap_or(
                time::SystemTime::now()
                    .duration_since(time::UNIX_EPOCH)
                    .unwrap()
                    .as_secs() as usize,
            );
        eprintln!("\n\nRandom seed: {}\n", seed);
        seed
    };
}

#[test]
fn test_bash_corpus() {
    test_language_corpus("bash");
}

#[test]
fn test_c_corpus() {
    test_language_corpus("c");
}

#[test]
fn test_cpp_corpus() {
    test_language_corpus("cpp");
}

#[test]
fn test_embedded_template_corpus() {
    test_language_corpus("embedded-template");
}

#[test]
fn test_go_corpus() {
    test_language_corpus("go");
}

#[test]
fn test_html_corpus() {
    test_language_corpus("html");
}

#[test]
fn test_javascript_corpus() {
    test_language_corpus("javascript");
}

#[test]
fn test_json_corpus() {
    test_language_corpus("json");
}

#[test]
fn test_php_corpus() {
    test_language_corpus("php");
}

#[test]
fn test_python_corpus() {
    test_language_corpus("python");
}

#[test]
fn test_ruby_corpus() {
    test_language_corpus("ruby");
}

#[test]
fn test_rust_corpus() {
    test_language_corpus("rust");
}

fn test_language_corpus(language_name: &str) {
    if let Some(language_filter) = LANGUAGE_FILTER.as_ref() {
        if language_filter != language_name {
            return;
        }
    }

    let grammars_dir = fixtures_dir().join("grammars");
    let error_corpus_dir = fixtures_dir().join("error_corpus");

    let mut failure_count = 0;

    let language = get_language(language_name);
    let mut corpus_dir = grammars_dir.join(language_name).join("corpus");
    if !corpus_dir.is_dir() {
        corpus_dir = grammars_dir.join(language_name).join("test").join("corpus");
    }

    let error_corpus_file = error_corpus_dir.join(&format!("{}_errors.txt", language_name));
    let main_tests = parse_tests(&corpus_dir).unwrap();
    let error_tests = parse_tests(&error_corpus_file).unwrap_or(TestEntry::default());
    let mut tests = flatten_tests(main_tests);
    tests.extend(flatten_tests(error_tests));

    for (example_name, input, expected_output, has_fields) in tests {
        println!("  {} example - {}", language_name, example_name);

        let trial = 0;
        if TRIAL_FILTER.map_or(true, |t| t == trial) {
            let passed = allocations::record(|| {
                let mut log_session = None;
                let mut parser = get_parser(&mut log_session, "log.html");
                parser.set_language(language).unwrap();
                let tree = parser.parse(&input, None).unwrap();
                let mut actual_output = tree.root_node().to_sexp();
                if !has_fields {
                    actual_output = strip_sexp_fields(actual_output);
                }
                if actual_output == expected_output {
                    true
                } else {
                    println!(
                        "Incorrect initial parse for {} - {}",
                        language_name, example_name,
                    );
                    print_diff_key();
                    print_diff(&actual_output, &expected_output);
                    println!("");
                    false
                }
            });

            if !passed {
                failure_count += 1;
                continue;
            }
        }

        let mut parser = Parser::new();
        parser.set_language(language).unwrap();
        let tree = parser.parse(&input, None).unwrap();
        drop(parser);

        for trial in 1..=TRIAL_COUNT {
            if TRIAL_FILTER.map_or(true, |filter| filter == trial) {
                let mut rand = Rand::new(*SEED + trial);

                let passed = allocations::record(|| {
                    let mut log_session = None;
                    let mut parser = get_parser(&mut log_session, "log.html");
                    parser.set_language(language).unwrap();
                    let mut tree = tree.clone();
                    let mut input = input.clone();

                    if *LOG_GRAPH_ENABLED {
                        eprintln!("{}\n", String::from_utf8_lossy(&input));
                    }

                    // Perform a random series of edits and reparse.
                    let mut undo_stack = Vec::new();
                    for _ in 0..EDIT_COUNT {
                        let edit = get_random_edit(&mut rand, &input);
                        undo_stack.push(invert_edit(&input, &edit));
                        perform_edit(&mut tree, &mut input, &edit);
                    }
                    if *LOG_GRAPH_ENABLED {
                        eprintln!("{}\n", String::from_utf8_lossy(&input));
                    }

                    let mut tree2 = parser.parse(&input, Some(&tree)).unwrap();

                    // Check that the new tree is consistent.
                    check_consistent_sizes(&tree2, &input);
                    if let Err(message) = check_changed_ranges(&tree, &tree2, &input) {
                        println!(
                            "\nUnexpected scope change in trial {}\n{}\n\n",
                            trial, message
                        );
                        return false;
                    }

                    // Undo all of the edits and re-parse again.
                    while let Some(edit) = undo_stack.pop() {
                        perform_edit(&mut tree2, &mut input, &edit);
                    }
                    if *LOG_GRAPH_ENABLED {
                        eprintln!("{}\n", String::from_utf8_lossy(&input));
                    }

                    let tree3 = parser.parse(&input, Some(&tree2)).unwrap();

                    // Verify that the final tree matches the expectation from the corpus.
                    let mut actual_output = tree3.root_node().to_sexp();
                    if !has_fields {
                        actual_output = strip_sexp_fields(actual_output);
                    }

                    if actual_output != expected_output {
                        println!(
                            "Incorrect parse for {} - {} - trial {}",
                            language_name, example_name, trial
                        );
                        print_diff_key();
                        print_diff(&actual_output, &expected_output);
                        println!("");
                        return false;
                    }

                    // Check that the edited tree is consistent.
                    check_consistent_sizes(&tree3, &input);
                    if let Err(message) = check_changed_ranges(&tree2, &tree3, &input) {
                        eprintln!(
                            "Unexpected scope change in trial {}\n{}\n\n",
                            trial, message
                        );
                        return false;
                    }

                    true
                });

                if !passed {
                    failure_count += 1;
                    break;
                }
            }
        }
    }

    if failure_count > 0 {
        panic!("{} {} corpus tests failed", failure_count, language_name);
    }
}

#[test]
fn test_feature_corpus_files() {
    let test_grammars_dir = fixtures_dir().join("test_grammars");

    let mut failure_count = 0;
    for entry in fs::read_dir(&test_grammars_dir).unwrap() {
        let entry = entry.unwrap();
        if !entry.metadata().unwrap().is_dir() {
            continue;
        }
        let language_name = entry.file_name();
        let language_name = language_name.to_str().unwrap();

        if let Some(filter) = LANGUAGE_FILTER.as_ref() {
            if language_name != filter.as_str() {
                continue;
            }
        }

        let test_path = entry.path();
        let mut grammar_path = test_path.join("grammar.js");
        if !grammar_path.exists() {
            grammar_path = test_path.join("grammar.json");
        }
        let error_message_path = test_path.join("expected_error.txt");
        let grammar_json = generate::load_grammar_file(&grammar_path).unwrap();
        let generate_result = generate::generate_parser_for_grammar(&grammar_json);

        if error_message_path.exists() {
            if EXAMPLE_FILTER.is_some() {
                continue;
            }

            eprintln!("test language: {:?}", language_name);

            let expected_message = fs::read_to_string(&error_message_path)
                .unwrap()
                .replace("\r\n", "\n");
            if let Err(e) = generate_result {
                let actual_message = e.to_string().replace("\r\n", "\n");
                if expected_message != actual_message {
                    eprintln!(
                        "Unexpected error message.\n\nExpected:\n\n{}\nActual:\n\n{}\n",
                        expected_message, actual_message
                    );
                    failure_count += 1;
                }
            } else {
                eprintln!(
                    "Expected error message but got none for test grammar '{}'",
                    language_name
                );
                failure_count += 1;
            }
        } else {
            if let Err(e) = &generate_result {
                eprintln!(
                    "Unexpected error for test grammar '{}':\n{}",
                    language_name, e
                );
                failure_count += 1;
                continue;
            }

            let corpus_path = test_path.join("corpus.txt");
            let c_code = generate_result.unwrap().1;
            let language = get_test_language(language_name, &c_code, Some(&test_path));
            let test = parse_tests(&corpus_path).unwrap();
            let tests = flatten_tests(test);

            if !tests.is_empty() {
                eprintln!("test language: {:?}", language_name);
            }

            for (name, input, expected_output, has_fields) in tests {
                eprintln!("  example: {:?}", name);

                let passed = allocations::record(|| {
                    let mut log_session = None;
                    let mut parser = get_parser(&mut log_session, "log.html");
                    parser.set_language(language).unwrap();
                    let tree = parser.parse(&input, None).unwrap();
                    let mut actual_output = tree.root_node().to_sexp();
                    if !has_fields {
                        actual_output = strip_sexp_fields(actual_output);
                    }
                    if actual_output == expected_output {
                        true
                    } else {
                        print_diff_key();
                        print_diff(&actual_output, &expected_output);
                        println!("");
                        false
                    }
                });

                if !passed {
                    failure_count += 1;
                    continue;
                }
            }
        }
    }
    if failure_count > 0 {
        panic!("{} corpus tests failed", failure_count);
    }
}

fn check_consistent_sizes(tree: &Tree, input: &Vec<u8>) {
    fn check(node: Node, line_offsets: &Vec<usize>) {
        let start_byte = node.start_byte();
        let end_byte = node.end_byte();
        let start_point = node.start_position();
        let end_point = node.end_position();

        assert!(start_byte <= end_byte);
        assert!(start_point <= end_point);
        assert_eq!(
            start_byte,
            line_offsets[start_point.row] + start_point.column
        );
        assert_eq!(end_byte, line_offsets[end_point.row] + end_point.column);

        let mut last_child_end_byte = start_byte;
        let mut last_child_end_point = start_point;
        let mut some_child_has_changes = false;
        let mut actual_named_child_count = 0;
        for i in 0..node.child_count() {
            let child = node.child(i).unwrap();
            assert!(child.start_byte() >= last_child_end_byte);
            assert!(child.start_position() >= last_child_end_point);
            check(child, line_offsets);
            if child.has_changes() {
                some_child_has_changes = true;
            }
            if child.is_named() {
                actual_named_child_count += 1;
            }
            last_child_end_byte = child.end_byte();
            last_child_end_point = child.end_position();
        }

        assert_eq!(actual_named_child_count, node.named_child_count());

        if node.child_count() > 0 {
            assert!(end_byte >= last_child_end_byte);
            assert!(end_point >= last_child_end_point);
        }

        if some_child_has_changes {
            assert!(node.has_changes());
        }
    }

    let mut line_offsets = vec![0];
    for (i, c) in input.iter().enumerate() {
        if *c == '\n' as u8 {
            line_offsets.push(i + 1);
        }
    }

    check(tree.root_node(), &line_offsets);
}

fn check_changed_ranges(old_tree: &Tree, new_tree: &Tree, input: &Vec<u8>) -> Result<(), String> {
    let changed_ranges = old_tree.changed_ranges(new_tree).collect();
    let old_scope_sequence = ScopeSequence::new(old_tree);
    let new_scope_sequence = ScopeSequence::new(new_tree);
    old_scope_sequence.check_changes(&new_scope_sequence, &input, &changed_ranges)
}

fn get_parser(session: &mut Option<util::LogSession>, log_filename: &str) -> Parser {
    let mut parser = Parser::new();

    if *LOG_ENABLED {
        parser.set_logger(Some(Box::new(|log_type, msg| {
            if log_type == LogType::Lex {
                eprintln!("  {}", msg);
            } else {
                eprintln!("{}", msg);
            }
        })));
    } else if *LOG_GRAPH_ENABLED {
        *session = Some(util::log_graphs(&mut parser, log_filename).unwrap());
    }

    parser
}

fn flatten_tests(test: TestEntry) -> Vec<(String, Vec<u8>, String, bool)> {
    fn helper(
        test: TestEntry,
        is_root: bool,
        prefix: &str,
        result: &mut Vec<(String, Vec<u8>, String, bool)>,
    ) {
        match test {
            TestEntry::Example {
                mut name,
                input,
                output,
                has_fields,
            } => {
                if !prefix.is_empty() {
                    name.insert_str(0, " - ");
                    name.insert_str(0, prefix);
                }
                if let Some(filter) = EXAMPLE_FILTER.as_ref() {
                    if !name.contains(filter.as_str()) {
                        return;
                    }
                }
                result.push((name, input, output, has_fields));
            }
            TestEntry::Group {
                mut name, children, ..
            } => {
                if !is_root && !prefix.is_empty() {
                    name.insert_str(0, " - ");
                    name.insert_str(0, prefix);
                }
                for child in children {
                    helper(child, false, &name, result);
                }
            }
        }
    }
    let mut result = Vec::new();
    helper(test, true, "", &mut result);
    result
}
<|endoftext|>


<commit_before>#![allow(dead_code)]

use rayon::ThreadPoolBuilder;
use std::env;

pub mod eq;
pub mod parse;

/// Read the `ABORT_AFTER_FAILURE` environment variable, and parse it.
pub fn abort_after() -> usize {
    match env::var("ABORT_AFTER_FAILURE") {
        Ok(s) => s.parse().expect("failed to parse ABORT_AFTER_FAILURE"),
        Err(_) => usize::max_value(),
    }
}

/// Configure Rayon threadpool.
pub fn rayon_init() {
    ThreadPoolBuilder::new()
        .stack_size(20 * 1024 * 1024)
        .build_global()
        .unwrap();
}
<commit_msg>Respect RUST_MIN_STACK initializing Rayon threadpool<commit_after>#![allow(dead_code)]

use rayon::ThreadPoolBuilder;
use std::env;

pub mod eq;
pub mod parse;

/// Read the `ABORT_AFTER_FAILURE` environment variable, and parse it.
pub fn abort_after() -> usize {
    match env::var("ABORT_AFTER_FAILURE") {
        Ok(s) => s.parse().expect("failed to parse ABORT_AFTER_FAILURE"),
        Err(_) => usize::max_value(),
    }
}

/// Configure Rayon threadpool.
pub fn rayon_init() {
    let stack_size = match env::var("RUST_MIN_STACK") {
        Ok(s) => s.parse().expect("failed to parse RUST_MIN_STACK"),
        Err(_) => 20 * 1024 * 1024,
    };
    ThreadPoolBuilder::new()
        .stack_size(stack_size)
        .build_global()
        .unwrap();
}
<|endoftext|>


<commit_before>#![feature(core)]
#![deny(warnings)]

use std::borrow::ToOwned;

extern crate glassful;

const TEST_PROG: &'static str = r#"
#![version="110"]

static foo: f32 = 3.0;

#[varying] static zed: vec2 = UNINIT;
#[uniform] static prev_frame: sampler2D = UNINIT;
#[uniform] static _p_scale: f32 = UNINIT;

fn complex_to_tex(p: vec2) -> vec2 {
    (0.5/_p_scale)*p + vec2(0.5, 0.5)
}

fn complex_mul(a: vec2, b: vec2) -> vec2 {
    vec2(a.x*b.x - a.y*b.y, a.x*b.y + a.y*b.x)
}

fn in_bounds(p: vec2) -> bool {
    macro_rules! check {
        ($i:ident) => ((p.$i >= -_p_scale) && (p.$i <= _p_scale))
    }

    check!(x) && check!(y)
}

#[uniform] static param: vec2 = UNINIT;

fn main() {
    let color: vec3;
    let oldpoint: vec2 = complex_mul(zed, zed) + 1.6*param;

    if in_bounds(oldpoint) {
        let oldcoord: vec2 = complex_to_tex(oldpoint);
        color = 1.8*texture2D(prev_frame, oldcoord).brg;
    } else {
        color = vec3(1.0, 0.0, 0.0);
    }

    gl_FragColor = vec4(color, 1.0);
}
"#;

#[test]
fn smoke_test() {
    // Just make sure we can translate without crashing.
    glassful::translate(TEST_PROG.to_owned());
}
<commit_msg>Remove unused feature(core) to get tests passing<commit_after>#![deny(warnings)]

use std::borrow::ToOwned;

extern crate glassful;

const TEST_PROG: &'static str = r#"
#![version="110"]

static foo: f32 = 3.0;

#[varying] static zed: vec2 = UNINIT;
#[uniform] static prev_frame: sampler2D = UNINIT;
#[uniform] static _p_scale: f32 = UNINIT;

fn complex_to_tex(p: vec2) -> vec2 {
    (0.5/_p_scale)*p + vec2(0.5, 0.5)
}

fn complex_mul(a: vec2, b: vec2) -> vec2 {
    vec2(a.x*b.x - a.y*b.y, a.x*b.y + a.y*b.x)
}

fn in_bounds(p: vec2) -> bool {
    macro_rules! check {
        ($i:ident) => ((p.$i >= -_p_scale) && (p.$i <= _p_scale))
    }

    check!(x) && check!(y)
}

#[uniform] static param: vec2 = UNINIT;

fn main() {
    let color: vec3;
    let oldpoint: vec2 = complex_mul(zed, zed) + 1.6*param;

    if in_bounds(oldpoint) {
        let oldcoord: vec2 = complex_to_tex(oldpoint);
        color = 1.8*texture2D(prev_frame, oldcoord).brg;
    } else {
        color = vec3(1.0, 0.0, 0.0);
    }

    gl_FragColor = vec4(color, 1.0);
}
"#;

#[test]
fn smoke_test() {
    // Just make sure we can translate without crashing.
    glassful::translate(TEST_PROG.to_owned());
}
<|endoftext|>


<commit_before>#[macro_use]
extern crate clap;

use clap::Shell;

include!("src/app.rs");

fn main() {
    let outdir = match std::env::var_os("OUT_DIR") {
        None => return,
        Some(outdir) => outdir,
    };

    let mut app = build_app();
    app.gen_completions("fd", Shell::Bash, &outdir);
    app.gen_completions("fd", Shell::Fish, &outdir);
    app.gen_completions("fd", Shell::Zsh, &outdir);
    app.gen_completions("fd", Shell::PowerShell, &outdir);
}
<commit_msg>Allow overriding of OUT_DIR in build.rs (#124)<commit_after>#[macro_use]
extern crate clap;

use clap::Shell;

include!("src/app.rs");

fn main() {
    let var = std::env::var_os("SHELL_COMPLETIONS_DIR").or(std::env::var_os("OUT_DIR"));
    let outdir = match var {
        None => return,
        Some(outdir) => outdir,
    };

    let mut app = build_app();
    app.gen_completions("fd", Shell::Bash, &outdir);
    app.gen_completions("fd", Shell::Fish, &outdir);
    app.gen_completions("fd", Shell::Zsh, &outdir);
    app.gen_completions("fd", Shell::PowerShell, &outdir);
}
<|endoftext|>


<commit_before>// The MIT License (MIT)
//
// Copyright (c) 2013 Jeremy Letang (letang.jeremy@gmail.com)
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
// the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

extern crate pkg_config;

use std::path::Path;
use std::env;

#[cfg(all(unix, not(target_os = "linux")))]
use unix_platform as platform;

fn main() {
    if env::var("PORTAUDIO_ONLY_STATIC").is_err() {
        // If pkg-config finds a library on the system, we are done
        if pkg_config::Config::new().atleast_version("19").find("portaudio-2.0").is_ok() {
            return;
        }
    }

    build();
}

fn build() {
    // retrieve cargo deps out dir
    let out_dir_str = env::var("OUT_DIR").unwrap();
    let out_dir = Path::new(&out_dir_str);

    let static_lib = out_dir.join("lib/libportaudio.a");
    if let Err(_) = ::std::fs::metadata(static_lib) {
        platform::download();
        platform::build(out_dir);
    }

    platform::print_libs(out_dir);
}

#[allow(dead_code)]
mod unix_platform {
    use std::process::Command;
    use std::path::Path;

    use std::env;

    pub const PORTAUDIO_URL: &'static str = "http://www.portaudio.com/archives/pa_stable_v19_20140130.tgz";
    pub const PORTAUDIO_TAR: &'static str = "pa_stable_v19_20140130.tgz";
    pub const PORTAUDIO_FOLDER: &'static str = "portaudio";

    pub fn download() {
        match Command::new("curl").arg(PORTAUDIO_URL).arg("-O").output() {
            Ok(_) => {},
            Err(e) => panic!("{}", e)
        }
    }

    pub fn build(out_dir: &Path) {
        // untar portaudio sources
        match Command::new("tar").arg("xvf").arg(PORTAUDIO_TAR).output() {
            Ok(_) => {},
            Err(e) => panic!("{}", e)
        }

        // change dir to the portaudio folder
        match env::set_current_dir(PORTAUDIO_FOLDER) {
            Ok(_) => {},
            Err(e) => panic!("{}", e)
        }

        // run portaudio autoconf
        Command::new("./configure")
            .args(&["--disable-shared", "--enable-static"]) // Only build static lib
            .args(&["--prefix", out_dir.to_str().unwrap()]) // Install on the outdir
            .arg("--with-pic") // Build position-independent code (required by Rust)
            .output()
            .unwrap();

        // then make
        match Command::new("make").output() {
            Ok(_) => {},
            Err(e) => panic!("{}", e)
        }

        // "install" on the outdir
        match Command::new("make").arg("install").output() {
            Ok(_) => {},
            Err(e) => panic!("{}", e)
        }

        // return to rust-portaudio root
        match env::set_current_dir("..") {
            Ok(_) => {},
            Err(e) => panic!("{}", e)
        }

        // cleaning portaudio sources
        match Command::new("rm").arg("-rf").args(&[PORTAUDIO_TAR, PORTAUDIO_FOLDER]).output() {
            Ok(_) => {},
            Err(e) => panic!("{}", e)
        }
    }

    pub fn print_libs(out_dir: &Path) {
        let out_str = out_dir.to_str().unwrap();
        println!("cargo:rustc-flags=-L native={}/lib -l static=portaudio", out_str);
    }
}

#[cfg(target_os = "linux")]
mod platform {
    use pkg_config;
    use std::process::Command;
    use super::unix_platform;
    use std::path::Path;

    pub fn download() {
        match Command::new("wget").arg(unix_platform::PORTAUDIO_URL).output() {
            Ok(_) => {},
            Err(e) => panic!("{}", e)
        }
    }

    pub fn build(out_dir: &Path) {
        unix_platform::build(out_dir);
    }

    pub fn print_libs(out_dir: &Path) {
        let portaudio_pc_file = out_dir.join("lib/pkgconfig/portaudio-2.0.pc");
        let portaudio_pc_file = portaudio_pc_file.to_str().unwrap();

        pkg_config::Config::new().statik(true).find(portaudio_pc_file).unwrap();
    }
}

#[cfg(windows)]
mod platform {
    use std::path::Path;

    pub fn download() {
        println!("Don't know how to build portaudio on Windows yet!");
    }

    pub fn build(_: &Path) {
        println!("Don't know how to build portaudio on Windows yet!");
    }

    pub fn print_libs(_: &Path) {
        println!("Don't know how to build portaudio on Windows yet!");
    }
}
<commit_msg>on Windows: printing message pointing to portaudio site<commit_after>// The MIT License (MIT)
//
// Copyright (c) 2013 Jeremy Letang (letang.jeremy@gmail.com)
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
// the Software, and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

extern crate pkg_config;

use std::path::Path;
use std::env;

#[cfg(all(unix, not(target_os = "linux")))]
use unix_platform as platform;

fn main() {
    if env::var("PORTAUDIO_ONLY_STATIC").is_err() {
        // If pkg-config finds a library on the system, we are done
        if pkg_config::Config::new().atleast_version("19").find("portaudio-2.0").is_ok() {
            return;
        }
    }

    build();
}

fn build() {
    // retrieve cargo deps out dir
    let out_dir_str = env::var("OUT_DIR").unwrap();
    let out_dir = Path::new(&out_dir_str);

    let static_lib = out_dir.join("lib/libportaudio.a");
    if let Err(_) = ::std::fs::metadata(static_lib) {
        platform::download();
        platform::build(out_dir);
    }

    platform::print_libs(out_dir);
}

#[allow(dead_code)]
mod unix_platform {
    use std::process::Command;
    use std::path::Path;

    use std::env;

    pub const PORTAUDIO_URL: &'static str = "http://www.portaudio.com/archives/pa_stable_v19_20140130.tgz";
    pub const PORTAUDIO_TAR: &'static str = "pa_stable_v19_20140130.tgz";
    pub const PORTAUDIO_FOLDER: &'static str = "portaudio";

    pub fn download() {
        match Command::new("curl").arg(PORTAUDIO_URL).arg("-O").output() {
            Ok(_) => {},
            Err(e) => panic!("{}", e)
        }
    }

    pub fn build(out_dir: &Path) {
        // untar portaudio sources
        match Command::new("tar").arg("xvf").arg(PORTAUDIO_TAR).output() {
            Ok(_) => {},
            Err(e) => panic!("{}", e)
        }

        // change dir to the portaudio folder
        match env::set_current_dir(PORTAUDIO_FOLDER) {
            Ok(_) => {},
            Err(e) => panic!("{}", e)
        }

        // run portaudio autoconf
        Command::new("./configure")
            .args(&["--disable-shared", "--enable-static"]) // Only build static lib
            .args(&["--prefix", out_dir.to_str().unwrap()]) // Install on the outdir
            .arg("--with-pic") // Build position-independent code (required by Rust)
            .output()
            .unwrap();

        // then make
        match Command::new("make").output() {
            Ok(_) => {},
            Err(e) => panic!("{}", e)
        }

        // "install" on the outdir
        match Command::new("make").arg("install").output() {
            Ok(_) => {},
            Err(e) => panic!("{}", e)
        }

        // return to rust-portaudio root
        match env::set_current_dir("..") {
            Ok(_) => {},
            Err(e) => panic!("{}", e)
        }

        // cleaning portaudio sources
        match Command::new("rm").arg("-rf").args(&[PORTAUDIO_TAR, PORTAUDIO_FOLDER]).output() {
            Ok(_) => {},
            Err(e) => panic!("{}", e)
        }
    }

    pub fn print_libs(out_dir: &Path) {
        let out_str = out_dir.to_str().unwrap();
        println!("cargo:rustc-flags=-L native={}/lib -l static=portaudio", out_str);
    }
}

#[cfg(target_os = "linux")]
mod platform {
    use pkg_config;
    use std::process::Command;
    use super::unix_platform;
    use std::path::Path;

    pub fn download() {
        match Command::new("wget").arg(unix_platform::PORTAUDIO_URL).output() {
            Ok(_) => {},
            Err(e) => panic!("{}", e)
        }
    }

    pub fn build(out_dir: &Path) {
        unix_platform::build(out_dir);
    }

    pub fn print_libs(out_dir: &Path) {
        let portaudio_pc_file = out_dir.join("lib/pkgconfig/portaudio-2.0.pc");
        let portaudio_pc_file = portaudio_pc_file.to_str().unwrap();

        pkg_config::Config::new().statik(true).find(portaudio_pc_file).unwrap();
    }
}

#[cfg(windows)]
mod platform {
    use std::path::Path;
    use std::io::{self, Write};

    const PORTAUDIO_DOWNLOAD_URL: &'static str = "http://www.portaudio.com";

    fn print_lib_url() {
        let msg = format!("Don't know how to build portaudio on Windows yet. Sources and build instructions available at: {}", PORTAUDIO_DOWNLOAD_URL);
        io::stderr().write(msg.as_bytes()).unwrap();
    }

    pub fn download() {
        print_lib_url();
    }

    pub fn build(_: &Path) {
        print_lib_url();
    }

    pub fn print_libs(_: &Path) {
        print_lib_url();
    }
}
<|endoftext|>


<commit_before>extern crate case;
extern crate hyper;
extern crate rustc_serialize;

use std::collections::HashMap;
use case::CaseExt;
use rustc_serialize::json::Json;
use hyper::Client;
use std::env;
use std::fs::File;
use std::io::{Result, Read, Write};
use std::path::Path;

/// generate an enum of Events
fn main() {

    let events = vec!["commit_comment",
                      "create",
                      "delete",
                      "deployment",
                      "deployment_status",
                      "fork",
                      "gollum",
                      "issue_comment",
                      "issues",
                      "member",
                      "membership",
                      "page_build",
                      "ping",
                      "public",
                      "pull_request",
                      "pull_request_review_comment",
                      "push",
                      "release",
                      "repository",
                      "status",
                      "team_add",
                      "watch"];

    if let Ok(_) = env::var("FETCH_PAYLOAD_DATA") {
        let _ = fetch_payload_data(&events);
    }
    let _ = generate(&events);
}

fn fetch_payload_data(events: &Vec<&str>) -> Result<()> {
    let data_dir = Path::new("data");
    let client = Client::new();
    for event in events {
        let src = format!("https://raw.githubusercontent.com/github/developer.github.\
                           com/master/lib/webhooks/{}.payload.json",
                          event);
        let mut res = client.get(&src)
                            .send()
                            .unwrap();
        let mut buf = String::new();
        try!(res.read_to_string(&mut buf));
        let outfile = data_dir.join(format!("{}.json", event));
        let mut f = try!(File::create(outfile));
        try!(f.write_all(buf.as_bytes()));
    }
    Ok(())
}

fn generate(events: &Vec<&str>) -> Result<()> {
    let out_dir = env::var("OUT_DIR").unwrap();
    let dest_path = Path::new(&out_dir).join("events.rs");
    let mut f = try!(File::create(&dest_path));
    let client = Client::new();

    // generate Event enum containing definitions each hook struct definition
    try!(f.write_all(b"#[derive(Debug, RustcDecodable)]
pub enum Event {
"));
    let mut defs = HashMap::new();
    for event in events {
        let src = format!("https://raw.githubusercontent.com/github/developer.github.\
                           com/master/lib/webhooks/{}.payload.json",
                          event);
        let mut res = client.get(&src)
                            .send()
                            .unwrap();
        let mut buf = String::new();
        try!(res.read_to_string(&mut buf));
        let parsed = Json::from_str(&buf).unwrap();
        let enum_name = container_name(event);
        try!(f.write_all(format!("  /// generated from {}
  {} ",
                                 src,
                                 enum_name)
                             .as_bytes()));
        try!(f.write_all(b"{
 "));

        match parsed {
            Json::Object(obj) => {
                for (k, v) in obj {
                    try!(f.write_all(format!("   {}: {},
 ",
                                             field_name(&k),
                                             value(&enum_name, &mut defs, &k, &v))
                                         .as_bytes()))
                }
            }
            _ => (),
        }
        try!(f.write_all(b"
  },"));
    }
    try!(f.write_all(b"}

"));

    try!(print_structs(&mut f, defs, &mut vec![], 0));
    Ok(())
}

fn print_structs(f: &mut File,
                 defs: HashMap<String, Json>,
                 generated: &mut Vec<String>,
                 depth: usize)
                 -> Result<()> {
    let mut aux = HashMap::new();
    for (struct_name, json) in defs.iter() {
        if generated.contains(&struct_name) {
            continue;
        }
        println!("struct {}", struct_name);
        try!(f.write_all(format!("
#[derive(Default, Debug, RustcDecodable)]
pub struct {} ",
                                 struct_name)
                             .as_bytes()));
        try!(f.write_all(b"{"));
        match json {
            &Json::Object(ref obj) => {
                for (k, v) in obj {
                    try!(f.write_all(format!("
  pub {}: {},",
                                             field_name(&k),
                                             value(&struct_name, &mut aux, &k, &v))
                                         .as_bytes()))
                }
            }
            _ => (),
        }

        try!(f.write_all(b"
}
"));
        generated.push(struct_name.clone());
    }
    if !aux.is_empty() {
        try!(print_structs(f, aux, generated, depth + 1));
    }
    Ok(())
}

fn value(container: &String, defs: &mut HashMap<String, Json>, k: &str, j: &Json) -> String {
    match j {
        &Json::I64(_) => "i64".to_owned(),
        &Json::U64(_) => "u64".to_owned(),
        &Json::F64(_) => "f64".to_owned(),
        &Json::String(_) => "String".to_owned(),
        &Json::Boolean(_) => "bool".to_owned(),
        &Json::Array(ref jv) => {
            if jv.is_empty() {
                "Vec<String>".to_owned() // this is just a guess!
            } else {
                format!("Vec<{}>", value(&container, defs, k, &jv[0]))
            }
        }
        obj @ &Json::Object(_) => {
            if "payload" == k {
                "HashMap<String, String>".to_owned()
            } else {
                let struct_name = match container_name(k) {
                    ref recursive if recursive == container => format!("{}Inner", recursive),
                    valid => valid,
                };
                defs.insert(struct_name.clone(), obj.clone());
                struct_name
            }
        }
        &Json::Null => "Option<String>".to_owned(),
    }
}

fn container_name(field: &str) -> String {
    if "self" == field {
        "SelfLink".to_owned()
    } else {
        field.to_camel()
    }
}

/// works around conflicts with reservied words
fn field_name(s: &str) -> String {
    let reserved = vec!["ref", "self", "type"];
    if reserved.contains(&s) {
        format!("_{}", s)
    } else {
        s.to_owned()
    }
}
<commit_msg>build stuff<commit_after>extern crate case;
extern crate hyper;
extern crate rustc_serialize;

use std::collections::HashMap;
use case::CaseExt;
use rustc_serialize::json::Json;
use hyper::Client;
use std::env;
use std::fs::File;
use std::io::{Result, Read, Write};
use std::path::Path;

/// generate an enum of Events
fn main() {

    let events = vec!["commit_comment",
                      "create",
                      "delete",
                      "deployment",
                      "deployment_status",
                      "fork",
                      "gollum",
                      "issue_comment",
                      "issues",
                      "member",
                      "membership",
                      "page_build",
                      "ping",
                      "public",
                      "pull_request",
                      "pull_request_review_comment",
                      "push",
                      "release",
                      "repository",
                      "status",
                      "team_add",
                      "watch"];

    if let Ok(_) = env::var("FETCH_PAYLOAD_DATA") {
        fetch_payload_data(&events).unwrap();
    }
    generate(&events).unwrap();
}

fn fetch_payload_data(events: &Vec<&str>) -> Result<()> {
    let data_dir = Path::new("data");
    let client = Client::new();
    for event in events {
        let src = format!("https://raw.githubusercontent.com/github/developer.github.\
                           com/master/lib/webhooks/{}.payload.json",
                          event);
        let mut res = client.get(&src)
                            .send()
                            .unwrap();
        let mut buf = String::new();
        try!(res.read_to_string(&mut buf));
        let outfile = data_dir.join(format!("{}.json", event));
        let mut f = try!(File::create(outfile));
        try!(f.write_all(buf.as_bytes()));
    }
    Ok(())
}

fn generate(events: &Vec<&str>) -> Result<()> {
    let out_dir = env::var("OUT_DIR").unwrap();
    let dest_path = Path::new(&out_dir).join("events.rs");
    let mut f = try!(File::create(&dest_path));

    try!(f.write_all(b"/// An enumeration of possible github events
#[derive(Debug, RustcDecodable)]
pub enum Event {
"));
    let mut defs = HashMap::new();
    for event in events {
        let mut data = try!(File::open(format!("data/{}.json", event)));
        let mut buf = String::new();
        try!(data.read_to_string(&mut buf));
        let parsed = Json::from_str(&buf).unwrap();
        let enum_name = container_name(event);
        try!(f.write_all(format!("  {} ", enum_name).as_bytes()));
        try!(f.write_all(b"{"));

        match parsed {
            Json::Object(obj) => {
                for (k, v) in obj {
                    try!(f.write_all(format!("
    {}: {},",
                                             field_name(&k),
                                             value(&enum_name, &mut defs, &k, &v))
                                         .as_bytes()))
                }
            }
            _ => (),
        }
        try!(f.write_all(b"
  },
"));
    }
    try!(f.write_all(b"}

"));

    try!(print_structs(&mut f, defs, &mut vec![], 0));
    Ok(())
}

fn print_structs(f: &mut File,
                 defs: HashMap<String, Json>,
                 generated: &mut Vec<String>,
                 depth: usize)
                 -> Result<()> {
    let mut aux = HashMap::new();
    for (struct_name, json) in defs.iter() {
        if generated.contains(&struct_name) {
            continue;
        }
        println!("struct {}", struct_name);
        try!(f.write_all(format!("
#[derive(Default, Debug, RustcDecodable)]
pub struct {} ",
                                 struct_name)
                             .as_bytes()));
        try!(f.write_all(b"{"));
        match json {
            &Json::Object(ref obj) => {
                for (k, v) in obj {
                    try!(f.write_all(format!("
  pub {}: {},",
                                             field_name(&k),
                                             value(&struct_name, &mut aux, &k, &v))
                                         .as_bytes()))
                }
            }
            _ => (),
        }

        try!(f.write_all(b"
}
"));
        generated.push(struct_name.clone());
    }
    if !aux.is_empty() {
        try!(print_structs(f, aux, generated, depth + 1));
    }
    Ok(())
}

fn value(container: &String, defs: &mut HashMap<String, Json>, k: &str, j: &Json) -> String {
    match j {
        &Json::I64(_) => "i64".to_owned(),
        &Json::U64(_) => "u64".to_owned(),
        &Json::F64(_) => "f64".to_owned(),
        &Json::String(_) => "String".to_owned(),
        &Json::Boolean(_) => "bool".to_owned(),
        &Json::Array(ref jv) => {
            if jv.is_empty() {
                "Vec<String>".to_owned() // this is just a guess!
            } else {
                format!("Vec<{}>", value(&container, defs, k, &jv[0]))
            }
        }
        obj @ &Json::Object(_) => {
            if "payload" == k {
                "HashMap<String, String>".to_owned()
            } else {
                let struct_name = match container_name(k) {
                    ref recursive if recursive == container => format!("{}Inner", recursive),
                    valid => valid,
                };
                defs.insert(struct_name.clone(), obj.clone());
                struct_name
            }
        }
        &Json::Null => "Option<String>".to_owned(),
    }
}

fn container_name(field: &str) -> String {
    if "self" == field {
        "SelfLink".to_owned()
    } else {
        field.to_camel()
    }
}

/// works around conflicts with reservied words
fn field_name(s: &str) -> String {
    let reserved = vec!["ref", "self", "type"];
    if reserved.contains(&s) {
        format!("_{}", s)
    } else {
        s.to_owned()
    }
}
<|endoftext|>


<commit_before>/*
 * Copyright 2016-2017 Nathan Fiedler
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
extern crate bindgen;
extern crate pkg_config;

use std::env;
use std::fs::File;
use std::io::prelude::*;
use std::path::{Path, PathBuf};

const MIN_VERSION: &'static str = "6.9";
const MAX_VERSION: &'static str = "6.10";

static HEADER: &'static str = "#include <wand/MagickWand.h>\n";

fn main() {
    // Assert that the appropriate version of MagickWand is installed,
    // since we are very dependent on the particulars of MagickWand.
    let library = pkg_config::Config::new()
        .atleast_version(MIN_VERSION)
        .arg(format!("--max-version={}", MAX_VERSION))
        .probe("MagickWand")
        .unwrap();

    // If the generated bindings are missing, generate them now.
    let out_dir = PathBuf::from(env::var("OUT_DIR").unwrap());
    let bindings_path_str = out_dir.join("bindings.rs");
    if !Path::new(&bindings_path_str).exists() {

        // Create the header file that rust-bindgen needs as input.
        let gen_h_path = out_dir.join("gen.h");
        let mut gen_h = File::create(&gen_h_path).expect("could not create file");
        gen_h.write_all(HEADER.as_bytes()).expect("could not write header file");

        // Geneate the bindings.
        let mut builder = bindgen::Builder::default()
            .no_unstable_rust()
            .emit_builtins()
            .ctypes_prefix("libc")
            .raw_line("extern crate libc;")
            .header(gen_h_path.to_str().unwrap());
        for include_path in library.include_paths {
            builder = builder.clang_arg(format!("-I{}", include_path.to_string_lossy()));
        }
        if cfg!(target_os = "freebsd") {
            // pkg_config does not seem to work properly on FreeBSD, so
            // hard-code the builder settings for the time being.
            builder = builder.clang_arg("-I/usr/local/include/ImageMagick-6");
            // Need to hack the linker flags as well.
            println!("cargo:rustc-link-lib=dylib=MagickWand-6");
            println!("cargo:rustc-link-search=native=/usr/local/lib");
        }
        let bindings = builder.generate().unwrap();
        let mut file = File::create(&bindings_path_str).expect("could not create bindings file");
        // Work around the include! issue in rustc (as described in the
        // rust-bindgen README file) by wrapping the generated code in a
        // `pub mod` declaration; see issue #359 in (old) rust-bindgen.
        file.write(b"pub mod bindings {\n").unwrap();
        file.write(bindings.to_string().as_bytes()).unwrap();
        file.write(b"\n}").unwrap();

        std::fs::remove_file(&gen_h_path).expect("could not remove header file");
    }
}
<commit_msg>Split the pkg-config version and flags checks<commit_after>/*
 * Copyright 2016-2017 Nathan Fiedler
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
extern crate bindgen;
extern crate pkg_config;

use std::env;
use std::fs::File;
use std::io::prelude::*;
use std::path::{Path, PathBuf};

const MIN_VERSION: &'static str = "6.9";
const MAX_VERSION: &'static str = "6.10";

static HEADER: &'static str = "#include <wand/MagickWand.h>\n";

fn main() {
    // Assert that the appropriate version of MagickWand is installed,
    // since we are very dependent on the particulars of MagickWand.
    pkg_config::Config::new()
        .atleast_version(MIN_VERSION)
        .arg(format!("--max-version={}", MAX_VERSION))
        .probe("MagickWand")
        .unwrap();
    // We have to split the version check and the cflags/libs check because you can't do both at
    // the same time on RHEL (apparently).
    let library = pkg_config::Config::new().probe("MagickWand").unwrap();

    // If the generated bindings are missing, generate them now.
    let out_dir = PathBuf::from(env::var("OUT_DIR").unwrap());
    let bindings_path_str = out_dir.join("bindings.rs");
    if !Path::new(&bindings_path_str).exists() {

        // Create the header file that rust-bindgen needs as input.
        let gen_h_path = out_dir.join("gen.h");
        let mut gen_h = File::create(&gen_h_path).expect("could not create file");
        gen_h.write_all(HEADER.as_bytes()).expect("could not write header file");

        // Geneate the bindings.
        let mut builder = bindgen::Builder::default()
            .no_unstable_rust()
            .emit_builtins()
            .ctypes_prefix("libc")
            .raw_line("extern crate libc;")
            .header(gen_h_path.to_str().unwrap());
        for include_path in library.include_paths {
            builder = builder.clang_arg(format!("-I{}", include_path.to_string_lossy()));
        }
        if cfg!(target_os = "freebsd") {
            // pkg_config does not seem to work properly on FreeBSD, so
            // hard-code the builder settings for the time being.
            builder = builder.clang_arg("-I/usr/local/include/ImageMagick-6");
            // Need to hack the linker flags as well.
            println!("cargo:rustc-link-lib=dylib=MagickWand-6");
            println!("cargo:rustc-link-search=native=/usr/local/lib");
        }
        let bindings = builder.generate().unwrap();
        let mut file = File::create(&bindings_path_str).expect("could not create bindings file");
        // Work around the include! issue in rustc (as described in the
        // rust-bindgen README file) by wrapping the generated code in a
        // `pub mod` declaration; see issue #359 in (old) rust-bindgen.
        file.write(b"pub mod bindings {\n").unwrap();
        file.write(bindings.to_string().as_bytes()).unwrap();
        file.write(b"\n}").unwrap();

        std::fs::remove_file(&gen_h_path).expect("could not remove header file");
    }
}
<|endoftext|>


<commit_before>#![feature(core)]

extern crate capnpc;

fn main() {

    // CAPNP_INCLUDE_DIR=$(shell dirname $(shell which capnp))/../include

    let prefix = {
        let output = ::std::process::Command::new("which").arg("capnp")
            .output().unwrap().stdout;
        let path = ::std::path::Path::new(::std::str::from_utf8(output.as_slice()).unwrap());
        let mut path1 = path.parent().unwrap().parent().unwrap().to_path_buf();
        path1.push("include/capnp");
        path1
    };

    ::capnpc::compile(&*prefix,
                      &[&*prefix.clone().join(::std::path::Path::new("rpc.capnp")),
                        &*prefix.join(::std::path::Path::new("rpc-twoparty.capnp"))]).unwrap();
}
<commit_msg>Don't depend on feature(core) in build.rs.<commit_after>extern crate capnpc;

fn main() {

    // CAPNP_INCLUDE_DIR=$(shell dirname $(shell which capnp))/../include

    let prefix = {
        let output = ::std::process::Command::new("which").arg("capnp")
            .output().unwrap().stdout;
        let path = ::std::path::Path::new(::std::str::from_utf8(&output).unwrap());
        let mut path1 = path.parent().unwrap().parent().unwrap().to_path_buf();
        path1.push("include/capnp");
        path1
    };

    ::capnpc::compile(&*prefix,
                      &[&*prefix.clone().join(::std::path::Path::new("rpc.capnp")),
                        &*prefix.join(::std::path::Path::new("rpc-twoparty.capnp"))]).unwrap();
}
<|endoftext|>


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

use dom::attr::AttrMethods;
use dom::bindings::codegen::BindingDeclarations::HTMLObjectElementBinding;
use dom::bindings::codegen::InheritTypes::HTMLObjectElementDerived;
use dom::bindings::codegen::InheritTypes::{ElementCast, HTMLElementCast};
use dom::bindings::js::{JSRef, Temporary};
use dom::bindings::error::ErrorResult;
use dom::document::Document;
use dom::element::{Element, HTMLObjectElementTypeId};
use dom::element::AttributeHandlers;
use dom::eventtarget::{EventTarget, NodeTargetTypeId};
use dom::htmlelement::HTMLElement;
use dom::htmlformelement::HTMLFormElement;
use dom::node::{Node, ElementNodeTypeId, NodeHelpers, window_from_node};
use dom::validitystate::ValidityState;
use dom::virtualmethods::VirtualMethods;
use dom::window::Window;
use servo_util::str::DOMString;

use servo_net::image_cache_task;
use servo_net::image_cache_task::ImageCacheTask;
use servo_util::url::parse_url;
use servo_util::namespace::Null;
use servo_util::url::is_image_data;
use url::Url;

#[deriving(Encodable)]
pub struct HTMLObjectElement {
    pub htmlelement: HTMLElement,
}

impl HTMLObjectElementDerived for EventTarget {
    fn is_htmlobjectelement(&self) -> bool {
        self.type_id == NodeTargetTypeId(ElementNodeTypeId(HTMLObjectElementTypeId))
    }
}

impl HTMLObjectElement {
    pub fn new_inherited(localName: DOMString, document: &JSRef<Document>) -> HTMLObjectElement {
        HTMLObjectElement {
            htmlelement: HTMLElement::new_inherited(HTMLObjectElementTypeId, localName, document),
        }
    }

    pub fn new(localName: DOMString, document: &JSRef<Document>) -> Temporary<HTMLObjectElement> {
        let element = HTMLObjectElement::new_inherited(localName, document);
        Node::reflect_node(box element, document, HTMLObjectElementBinding::Wrap)
    }
}

trait ProcessDataURL {
    fn process_data_url(&mut self, image_cache: ImageCacheTask, url: Option<Url>);
}

impl<'a> ProcessDataURL for JSRef<'a, HTMLObjectElement> {
    // Makes the local `data` member match the status of the `data` attribute and starts
    /// prefetching the image. This method must be called after `data` is changed.
    fn process_data_url(&mut self, image_cache: ImageCacheTask, url: Option<Url>) {
        let elem: &JSRef<Element> = ElementCast::from_ref(self);

        // TODO: support other values
        match (elem.get_attribute(Null, "type").map(|x| x.root().Value()),
               elem.get_attribute(Null, "data").map(|x| x.root().Value())) {
            (None, Some(uri)) => {
                if is_image_data(uri) {
                    let data_url = parse_url(uri, url);
                    // Issue #84
                    image_cache.send(image_cache_task::Prefetch(data_url));
                }
            }
            _ => { }
        }
    }
}

pub trait HTMLObjectElementMethods {
    fn Data(&self) -> DOMString;
    fn SetData(&mut self, _data: DOMString) -> ErrorResult;
    fn Type(&self) -> DOMString;
    fn SetType(&mut self, _type: DOMString) -> ErrorResult;
    fn Name(&self) -> DOMString;
    fn SetName(&mut self, _name: DOMString) -> ErrorResult;
    fn UseMap(&self) -> DOMString;
    fn SetUseMap(&mut self, _use_map: DOMString) -> ErrorResult;
    fn GetForm(&self) -> Option<Temporary<HTMLFormElement>>;
    fn Width(&self) -> DOMString;
    fn SetWidth(&mut self, _width: DOMString) -> ErrorResult;
    fn Height(&self) -> DOMString;
    fn SetHeight(&mut self, _height: DOMString) -> ErrorResult;
    fn GetContentDocument(&self) -> Option<Temporary<Document>>;
    fn GetContentWindow(&self) -> Option<Temporary<Window>>;
    fn WillValidate(&self) -> bool;
    fn Validity(&self) -> Temporary<ValidityState>;
    fn ValidationMessage(&self) -> DOMString;
    fn CheckValidity(&self) -> bool;
    fn SetCustomValidity(&mut self, _error: DOMString);
    fn Align(&self) -> DOMString;
    fn SetAlign(&mut self, _align: DOMString) -> ErrorResult;
    fn Archive(&self) -> DOMString;
    fn SetArchive(&mut self, _archive: DOMString) -> ErrorResult;
    fn Code(&self) -> DOMString;
    fn SetCode(&mut self, _code: DOMString) -> ErrorResult;
    fn Declare(&self) -> bool;
    fn SetDeclare(&mut self, _declare: bool) -> ErrorResult;
    fn Hspace(&self) -> u32;
    fn SetHspace(&mut self, _hspace: u32) -> ErrorResult;
    fn Standby(&self) -> DOMString;
    fn SetStandby(&mut self, _standby: DOMString) -> ErrorResult;
    fn Vspace(&self) -> u32;
    fn SetVspace(&mut self, _vspace: u32) -> ErrorResult;
    fn CodeBase(&self) -> DOMString;
    fn SetCodeBase(&mut self, _codebase: DOMString) -> ErrorResult;
    fn CodeType(&self) -> DOMString;
    fn SetCodeType(&mut self, _codetype: DOMString) -> ErrorResult;
    fn Border(&self) -> DOMString;
    fn SetBorder(&mut self, _border: DOMString) -> ErrorResult;
    fn GetSVGDocument(&self) -> Option<Temporary<Document>>;
}

impl<'a> HTMLObjectElementMethods for JSRef<'a, HTMLObjectElement> {
    fn Data(&self) -> DOMString {
        "".to_owned()
    }

    fn SetData(&mut self, _data: DOMString) -> ErrorResult {
        Ok(())
    }

    fn Type(&self) -> DOMString {
        "".to_owned()
    }

    fn SetType(&mut self, _type: DOMString) -> ErrorResult {
        Ok(())
    }

    fn Name(&self) -> DOMString {
        "".to_owned()
    }

    fn SetName(&mut self, _name: DOMString) -> ErrorResult {
        Ok(())
    }

    fn UseMap(&self) -> DOMString {
        "".to_owned()
    }

    fn SetUseMap(&mut self, _use_map: DOMString) -> ErrorResult {
        Ok(())
    }

    fn GetForm(&self) -> Option<Temporary<HTMLFormElement>> {
        None
    }

    fn Width(&self) -> DOMString {
        "".to_owned()
    }

    fn SetWidth(&mut self, _width: DOMString) -> ErrorResult {
        Ok(())
    }

    fn Height(&self) -> DOMString {
        "".to_owned()
    }

    fn SetHeight(&mut self, _height: DOMString) -> ErrorResult {
        Ok(())
    }

    fn GetContentDocument(&self) -> Option<Temporary<Document>> {
        None
    }

    fn GetContentWindow(&self) -> Option<Temporary<Window>> {
        None
    }

    fn WillValidate(&self) -> bool {
        false
    }

    fn Validity(&self) -> Temporary<ValidityState> {
        let window = window_from_node(self).root();
        ValidityState::new(&*window)
    }

    fn ValidationMessage(&self) -> DOMString {
        "".to_owned()
    }

    fn CheckValidity(&self) -> bool {
        false
    }

    fn SetCustomValidity(&mut self, _error: DOMString) {
    }

    fn Align(&self) -> DOMString {
        "".to_owned()
    }

    fn SetAlign(&mut self, _align: DOMString) -> ErrorResult {
        Ok(())
    }

    fn Archive(&self) -> DOMString {
        "".to_owned()
    }

    fn SetArchive(&mut self, _archive: DOMString) -> ErrorResult {
        Ok(())
    }

    fn Code(&self) -> DOMString {
        "".to_owned()
    }

    fn SetCode(&mut self, _code: DOMString) -> ErrorResult {
        Ok(())
    }

    fn Declare(&self) -> bool {
        false
    }

    fn SetDeclare(&mut self, _declare: bool) -> ErrorResult {
        Ok(())
    }

    fn Hspace(&self) -> u32 {
        0
    }

    fn SetHspace(&mut self, _hspace: u32) -> ErrorResult {
        Ok(())
    }

    fn Standby(&self) -> DOMString {
        "".to_owned()
    }

    fn SetStandby(&mut self, _standby: DOMString) -> ErrorResult {
        Ok(())
    }

    fn Vspace(&self) -> u32 {
        0
    }

    fn SetVspace(&mut self, _vspace: u32) -> ErrorResult {
        Ok(())
    }

    fn CodeBase(&self) -> DOMString {
        "".to_owned()
    }

    fn SetCodeBase(&mut self, _codebase: DOMString) -> ErrorResult {
        Ok(())
    }

    fn CodeType(&self) -> DOMString {
        "".to_owned()
    }

    fn SetCodeType(&mut self, _codetype: DOMString) -> ErrorResult {
        Ok(())
    }

    fn Border(&self) -> DOMString {
        "".to_owned()
    }

    fn SetBorder(&mut self, _border: DOMString) -> ErrorResult {
        Ok(())
    }

    fn GetSVGDocument(&self) -> Option<Temporary<Document>> {
        None
    }
}

impl<'a> VirtualMethods for JSRef<'a, HTMLObjectElement> {
    fn super_type<'a>(&'a mut self) -> Option<&'a mut VirtualMethods:> {
        let htmlelement: &mut JSRef<HTMLElement> = HTMLElementCast::from_mut_ref(self);
        Some(htmlelement as &mut VirtualMethods:)
    }

    fn after_set_attr(&mut self, name: DOMString, value: DOMString) {
        match self.super_type() {
            Some(ref mut s) => s.after_set_attr(name.clone(), value),
            _ => (),
        }

        if "data" == name {
            let window = window_from_node(self).root();
            let url = Some(window.deref().get_url());
            self.process_data_url(window.deref().image_cache_task.clone(), url);
        }
    }
}
<commit_msg>Remove needless '&mut self' from htmlobjectelement.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/. */

use dom::attr::AttrMethods;
use dom::bindings::codegen::BindingDeclarations::HTMLObjectElementBinding;
use dom::bindings::codegen::InheritTypes::HTMLObjectElementDerived;
use dom::bindings::codegen::InheritTypes::{ElementCast, HTMLElementCast};
use dom::bindings::js::{JSRef, Temporary};
use dom::bindings::error::ErrorResult;
use dom::document::Document;
use dom::element::{Element, HTMLObjectElementTypeId};
use dom::element::AttributeHandlers;
use dom::eventtarget::{EventTarget, NodeTargetTypeId};
use dom::htmlelement::HTMLElement;
use dom::htmlformelement::HTMLFormElement;
use dom::node::{Node, ElementNodeTypeId, NodeHelpers, window_from_node};
use dom::validitystate::ValidityState;
use dom::virtualmethods::VirtualMethods;
use dom::window::Window;
use servo_util::str::DOMString;

use servo_net::image_cache_task;
use servo_net::image_cache_task::ImageCacheTask;
use servo_util::url::parse_url;
use servo_util::namespace::Null;
use servo_util::url::is_image_data;
use url::Url;

#[deriving(Encodable)]
pub struct HTMLObjectElement {
    pub htmlelement: HTMLElement,
}

impl HTMLObjectElementDerived for EventTarget {
    fn is_htmlobjectelement(&self) -> bool {
        self.type_id == NodeTargetTypeId(ElementNodeTypeId(HTMLObjectElementTypeId))
    }
}

impl HTMLObjectElement {
    pub fn new_inherited(localName: DOMString, document: &JSRef<Document>) -> HTMLObjectElement {
        HTMLObjectElement {
            htmlelement: HTMLElement::new_inherited(HTMLObjectElementTypeId, localName, document),
        }
    }

    pub fn new(localName: DOMString, document: &JSRef<Document>) -> Temporary<HTMLObjectElement> {
        let element = HTMLObjectElement::new_inherited(localName, document);
        Node::reflect_node(box element, document, HTMLObjectElementBinding::Wrap)
    }
}

trait ProcessDataURL {
    fn process_data_url(&self, image_cache: ImageCacheTask, url: Option<Url>);
}

impl<'a> ProcessDataURL for JSRef<'a, HTMLObjectElement> {
    // Makes the local `data` member match the status of the `data` attribute and starts
    /// prefetching the image. This method must be called after `data` is changed.
    fn process_data_url(&self, image_cache: ImageCacheTask, url: Option<Url>) {
        let elem: &JSRef<Element> = ElementCast::from_ref(self);

        // TODO: support other values
        match (elem.get_attribute(Null, "type").map(|x| x.root().Value()),
               elem.get_attribute(Null, "data").map(|x| x.root().Value())) {
            (None, Some(uri)) => {
                if is_image_data(uri) {
                    let data_url = parse_url(uri, url);
                    // Issue #84
                    image_cache.send(image_cache_task::Prefetch(data_url));
                }
            }
            _ => { }
        }
    }
}

pub trait HTMLObjectElementMethods {
    fn Data(&self) -> DOMString;
    fn SetData(&self, _data: DOMString) -> ErrorResult;
    fn Type(&self) -> DOMString;
    fn SetType(&self, _type: DOMString) -> ErrorResult;
    fn Name(&self) -> DOMString;
    fn SetName(&self, _name: DOMString) -> ErrorResult;
    fn UseMap(&self) -> DOMString;
    fn SetUseMap(&self, _use_map: DOMString) -> ErrorResult;
    fn GetForm(&self) -> Option<Temporary<HTMLFormElement>>;
    fn Width(&self) -> DOMString;
    fn SetWidth(&self, _width: DOMString) -> ErrorResult;
    fn Height(&self) -> DOMString;
    fn SetHeight(&self, _height: DOMString) -> ErrorResult;
    fn GetContentDocument(&self) -> Option<Temporary<Document>>;
    fn GetContentWindow(&self) -> Option<Temporary<Window>>;
    fn WillValidate(&self) -> bool;
    fn Validity(&self) -> Temporary<ValidityState>;
    fn ValidationMessage(&self) -> DOMString;
    fn CheckValidity(&self) -> bool;
    fn SetCustomValidity(&self, _error: DOMString);
    fn Align(&self) -> DOMString;
    fn SetAlign(&self, _align: DOMString) -> ErrorResult;
    fn Archive(&self) -> DOMString;
    fn SetArchive(&self, _archive: DOMString) -> ErrorResult;
    fn Code(&self) -> DOMString;
    fn SetCode(&self, _code: DOMString) -> ErrorResult;
    fn Declare(&self) -> bool;
    fn SetDeclare(&self, _declare: bool) -> ErrorResult;
    fn Hspace(&self) -> u32;
    fn SetHspace(&self, _hspace: u32) -> ErrorResult;
    fn Standby(&self) -> DOMString;
    fn SetStandby(&self, _standby: DOMString) -> ErrorResult;
    fn Vspace(&self) -> u32;
    fn SetVspace(&self, _vspace: u32) -> ErrorResult;
    fn CodeBase(&self) -> DOMString;
    fn SetCodeBase(&self, _codebase: DOMString) -> ErrorResult;
    fn CodeType(&self) -> DOMString;
    fn SetCodeType(&self, _codetype: DOMString) -> ErrorResult;
    fn Border(&self) -> DOMString;
    fn SetBorder(&self, _border: DOMString) -> ErrorResult;
    fn GetSVGDocument(&self) -> Option<Temporary<Document>>;
}

impl<'a> HTMLObjectElementMethods for JSRef<'a, HTMLObjectElement> {
    fn Data(&self) -> DOMString {
        "".to_owned()
    }

    fn SetData(&self, _data: DOMString) -> ErrorResult {
        Ok(())
    }

    fn Type(&self) -> DOMString {
        "".to_owned()
    }

    fn SetType(&self, _type: DOMString) -> ErrorResult {
        Ok(())
    }

    fn Name(&self) -> DOMString {
        "".to_owned()
    }

    fn SetName(&self, _name: DOMString) -> ErrorResult {
        Ok(())
    }

    fn UseMap(&self) -> DOMString {
        "".to_owned()
    }

    fn SetUseMap(&self, _use_map: DOMString) -> ErrorResult {
        Ok(())
    }

    fn GetForm(&self) -> Option<Temporary<HTMLFormElement>> {
        None
    }

    fn Width(&self) -> DOMString {
        "".to_owned()
    }

    fn SetWidth(&self, _width: DOMString) -> ErrorResult {
        Ok(())
    }

    fn Height(&self) -> DOMString {
        "".to_owned()
    }

    fn SetHeight(&self, _height: DOMString) -> ErrorResult {
        Ok(())
    }

    fn GetContentDocument(&self) -> Option<Temporary<Document>> {
        None
    }

    fn GetContentWindow(&self) -> Option<Temporary<Window>> {
        None
    }

    fn WillValidate(&self) -> bool {
        false
    }

    fn Validity(&self) -> Temporary<ValidityState> {
        let window = window_from_node(self).root();
        ValidityState::new(&*window)
    }

    fn ValidationMessage(&self) -> DOMString {
        "".to_owned()
    }

    fn CheckValidity(&self) -> bool {
        false
    }

    fn SetCustomValidity(&self, _error: DOMString) {
    }

    fn Align(&self) -> DOMString {
        "".to_owned()
    }

    fn SetAlign(&self, _align: DOMString) -> ErrorResult {
        Ok(())
    }

    fn Archive(&self) -> DOMString {
        "".to_owned()
    }

    fn SetArchive(&self, _archive: DOMString) -> ErrorResult {
        Ok(())
    }

    fn Code(&self) -> DOMString {
        "".to_owned()
    }

    fn SetCode(&self, _code: DOMString) -> ErrorResult {
        Ok(())
    }

    fn Declare(&self) -> bool {
        false
    }

    fn SetDeclare(&self, _declare: bool) -> ErrorResult {
        Ok(())
    }

    fn Hspace(&self) -> u32 {
        0
    }

    fn SetHspace(&self, _hspace: u32) -> ErrorResult {
        Ok(())
    }

    fn Standby(&self) -> DOMString {
        "".to_owned()
    }

    fn SetStandby(&self, _standby: DOMString) -> ErrorResult {
        Ok(())
    }

    fn Vspace(&self) -> u32 {
        0
    }

    fn SetVspace(&self, _vspace: u32) -> ErrorResult {
        Ok(())
    }

    fn CodeBase(&self) -> DOMString {
        "".to_owned()
    }

    fn SetCodeBase(&self, _codebase: DOMString) -> ErrorResult {
        Ok(())
    }

    fn CodeType(&self) -> DOMString {
        "".to_owned()
    }

    fn SetCodeType(&self, _codetype: DOMString) -> ErrorResult {
        Ok(())
    }

    fn Border(&self) -> DOMString {
        "".to_owned()
    }

    fn SetBorder(&self, _border: DOMString) -> ErrorResult {
        Ok(())
    }

    fn GetSVGDocument(&self) -> Option<Temporary<Document>> {
        None
    }
}

impl<'a> VirtualMethods for JSRef<'a, HTMLObjectElement> {
    fn super_type<'a>(&'a mut self) -> Option<&'a mut VirtualMethods:> {
        let htmlelement: &mut JSRef<HTMLElement> = HTMLElementCast::from_mut_ref(self);
        Some(htmlelement as &mut VirtualMethods:)
    }

    fn after_set_attr(&mut self, name: DOMString, value: DOMString) {
        match self.super_type() {
            Some(ref mut s) => s.after_set_attr(name.clone(), value),
            _ => (),
        }

        if "data" == name {
            let window = window_from_node(self).root();
            let url = Some(window.deref().get_url());
            self.process_data_url(window.deref().image_cache_task.clone(), url);
        }
    }
}
<|endoftext|>


<commit_before>#[cfg(feature = "integration_tests")]
extern crate kafka;

#[cfg(feature = "integration_tests")]
mod integration {
    mod client;
    mod consumer_producer;

    pub const LOCAL_KAFKA_BOOTSTRAP_HOST: &'static str = "localhost:9092";
    pub const TEST_TOPIC_NAME: &'static str = "kafka-rust-test";
    pub const TEST_GROUP_NAME: &'static str = "kafka-rust-tester";
    pub const TEST_TOPIC_PARTITIONS: [i32; 2] = [0, 1];
    pub const KAFKA_CONSUMER_OFFSETS_TOPIC_NAME: &'static str = "__consumer_offsets";
}
<commit_msg>const &str no longer needs 'static<commit_after>#[cfg(feature = "integration_tests")]
extern crate kafka;

#[cfg(feature = "integration_tests")]
mod integration {
    mod client;
    mod consumer_producer;

    pub const LOCAL_KAFKA_BOOTSTRAP_HOST: &str = "localhost:9092";
    pub const TEST_TOPIC_NAME: &str = "kafka-rust-test";
    pub const TEST_GROUP_NAME: &str = "kafka-rust-tester";
    pub const TEST_TOPIC_PARTITIONS: [i32; 2] = [0, 1];
    pub const KAFKA_CONSUMER_OFFSETS_TOPIC_NAME: &str = "__consumer_offsets";
}
<|endoftext|>


<commit_before><commit_msg>Handle time changing on recv, too.<commit_after><|endoftext|>