From 47730239f5a7b4187f6b2042148c00e9e7b38870 Mon Sep 17 00:00:00 2001 From: Nathan Froyd Date: Mon, 31 Jul 2017 14:03:43 -0400 Subject: [PATCH] move stylo_test build script guts from Python to Rust stylo_test's build script is split between Python and Rust. style's build script already has to perform complicated dances to determine an appropriate binary to execute, depending on the platform. To avoid copying and pasting that code, it seems reasonable to simply port the Python code into Rust, thus making the relationship between generated files and the cargo dependency output clearer. The new Rust is somewhat more verbose, but not terribly so. --- Cargo.lock | 1 + tests/unit/stylo/Cargo.toml | 3 ++ tests/unit/stylo/build.rs | 63 +++++++++++++++++++++++++----- tests/unit/stylo/check_bindings.py | 35 ----------------- 4 files changed, 57 insertions(+), 45 deletions(-) delete mode 100755 tests/unit/stylo/check_bindings.py diff --git a/Cargo.lock b/Cargo.lock index 57a4a104ec2..f61bc940910 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3101,6 +3101,7 @@ dependencies = [ "geckoservo 0.0.1", "libc 0.2.23 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", + "regex 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "selectors 0.19.0", "size_of_test 0.0.1", "style 0.0.1", diff --git a/tests/unit/stylo/Cargo.toml b/tests/unit/stylo/Cargo.toml index 21eab2958a1..bae75a35ee1 100644 --- a/tests/unit/stylo/Cargo.toml +++ b/tests/unit/stylo/Cargo.toml @@ -26,3 +26,6 @@ selectors = {path = "../../../components/selectors", features = ["gecko_like_typ size_of_test = {path = "../../../components/size_of_test"} style_traits = {path = "../../../components/style_traits"} style = {path = "../../../components/style", features = ["gecko"]} + +[build-dependencies] +regex = "0.2" diff --git a/tests/unit/stylo/build.rs b/tests/unit/stylo/build.rs index 111da70f57e..340d63741a7 100644 --- a/tests/unit/stylo/build.rs +++ b/tests/unit/stylo/build.rs @@ -2,24 +2,67 @@ * 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/. */ +extern crate regex; + +use regex::Regex; use std::env; -use std::fs; -use std::io::Write; -use std::path; -use std::process::Command; +use std::fs::File; +use std::io::{BufRead, BufReader, Write}; +use std::path::Path; fn main() { + let root_path = Path::new("../../../"); + let bindings_file = root_path.join("components/style/gecko/generated/bindings.rs"); + let glue_file = root_path.join("ports/geckolib/glue.rs"); + println!("cargo:rerun-if-changed=build.rs"); - println!("cargo:rerun-if-changed=check_bindings.py"); - println!("cargo:rerun-if-changed=../../../ports/geckolib/glue.rs"); - println!("cargo:rerun-if-changed=../../../components/style/gecko_bindings/bindings.rs"); - assert!(Command::new("python").arg("./check_bindings.py") - .spawn().unwrap().wait().unwrap().success()); + println!("cargo:rerun-if-changed={}", glue_file.display()); + println!("cargo:rerun-if-changed={}", bindings_file.display()); + + let env_out_dir = env::var("OUT_DIR").unwrap(); + let out_dir = Path::new(&env_out_dir); + + { + let output = out_dir.join("check_bindings.rs"); + let r = BufReader::new(File::open(bindings_file).unwrap()); + let mut w = File::create(output).unwrap(); + + w.write_all(b"fn assert_types() {\n").unwrap(); + + let matcher = Regex::new(r"fn\s*Servo_([a-zA-Z0-9_]+)\s*\(").unwrap(); + + for line in r.lines() { + let s = line.unwrap(); + for cap in matcher.captures_iter(&s) { + // GetStyleVariables is a Servo_* function, but temporarily defined + // on the Gecko side. + if &cap[1] != "GetStyleVariables" { + w.write_all(format!(" [ Servo_{0}, bindings::Servo_{0} ];\n", &cap[1]).as_bytes()).unwrap(); + } + } + } + + w.write_all(b"}\n").unwrap(); + } + + { + let output = out_dir.join("glue.rs"); + let r = BufReader::new(File::open(glue_file).unwrap()); + let mut w = File::create(output).unwrap(); + + w.write_all(b"pub use style::gecko::arc_types::*;\n").unwrap(); + + for line in r.lines() { + let s = line.unwrap().replace("pub extern \"C\" fn", "pub unsafe extern \"C\" fn"); + w.write_all(s.as_bytes()).unwrap(); + w.write_all(b"\n").unwrap(); + } + } // https://github.com/rust-lang/cargo/issues/3544 let style_out_dir = env::var_os("DEP_FOR SOME REASON THE LINKS KEY IS REQUIRED \ TO PASS DATA AROUND BETWEEN BUILD SCRIPTS_OUT_DIR").unwrap(); - fs::File::create(path::PathBuf::from(env::var_os("OUT_DIR").unwrap()).join("bindings.rs")) + File::create(out_dir.join("bindings.rs")) .unwrap() .write_all(format!("include!(concat!({:?}, \"/gecko/structs_debug.rs\"));", style_out_dir).as_bytes()) diff --git a/tests/unit/stylo/check_bindings.py b/tests/unit/stylo/check_bindings.py deleted file mode 100755 index b337aa7665a..00000000000 --- a/tests/unit/stylo/check_bindings.py +++ /dev/null @@ -1,35 +0,0 @@ -#!/usr/bin/env python - -# 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/. - -import os -import re - -ROOT_PATH = os.path.join("..", "..", "..") -INPUT_FILE = os.path.join(ROOT_PATH, "components", "style", "gecko", "generated", "bindings.rs") -OUTPUT_FILE = os.path.join(os.environ["OUT_DIR"], "check_bindings.rs") -GLUE_FILE = os.path.join(ROOT_PATH, "ports", "geckolib", "glue.rs") -GLUE_OUTPUT_FILE = os.path.join(os.environ["OUT_DIR"], "glue.rs") - -TEMPLATE = """\ - [ Servo_{name}, bindings::Servo_{name} ]; -""" - -with open(INPUT_FILE, "r") as bindings, open(OUTPUT_FILE, "w+") as tests: - tests.write("fn assert_types() {\n") - - pattern = re.compile("fn\s*Servo_([a-zA-Z0-9_]+)\s*\(") - - for line in bindings: - match = pattern.search(line) - if match: - tests.write(TEMPLATE.format(name=match.group(1))) - - tests.write("}\n") - -with open(GLUE_FILE, "r") as glue, open(GLUE_OUTPUT_FILE, "w+") as glue_output: - glue_output.write("pub use style::gecko::arc_types::*;") - for line in glue: - glue_output.write(line.replace("pub extern \"C\" fn", "pub unsafe extern \"C\" fn"))