lalrpop binary / feature dual support

This commit is contained in:
Jeong YunWon
2022-08-18 19:09:22 +09:00
parent fe3f67f836
commit 719b0edf46
3 changed files with 158 additions and 17 deletions

View File

@@ -11,6 +11,8 @@ edition = "2021"
[build-dependencies]
tiny-keccak = { version = "2", features = ["sha3"] }
phf_codegen = "0.10"
lalrpop = { version = "0.19.8", optional = true }
anyhow = "1.0.45"
[dependencies]
rustpython-ast = { path = "../ast" }

View File

@@ -1,21 +1,19 @@
use std::fmt::Write as _;
use std::fs::File;
use std::io::{self, BufRead, BufReader, BufWriter, Write};
use std::io::{BufRead, BufReader, BufWriter, Write};
use std::path::PathBuf;
use std::process::{Command, ExitCode};
use tiny_keccak::{Hasher, Sha3};
fn main() -> ExitCode {
fn main() -> anyhow::Result<()> {
const SOURCE: &str = "python.lalrpop";
const TARGET: &str = "python.rs";
println!("cargo:rerun-if-changed={SOURCE}");
if let Err(exit_code) = try_lalrpop(SOURCE, TARGET) {
return exit_code;
}
try_lalrpop(SOURCE, TARGET)?;
gen_phf();
ExitCode::SUCCESS
Ok(())
}
fn requires_lalrpop(source: &str, target: &str) -> bool {
@@ -67,28 +65,44 @@ fn requires_lalrpop(source: &str, target: &str) -> bool {
!eq
}
fn try_lalrpop(source: &str, target: &str) -> Result<(), ExitCode> {
fn try_lalrpop(source: &str, target: &str) -> anyhow::Result<()> {
if !requires_lalrpop(source, target) {
return Ok(());
}
match Command::new("lalrpop").arg(source).status() {
#[cfg(feature = "lalrpop")]
lalrpop_dependency();
#[cfg(not(feature = "lalrpop"))]
lalrpop_command(source)?;
Ok(())
}
#[cfg(not(feature = "lalrpop"))]
fn lalrpop_command(source: &str) -> anyhow::Result<()> {
match std::process::Command::new("lalrpop").arg(source).status() {
Ok(stat) if stat.success() => Ok(()),
Ok(stat) => {
eprintln!("failed to execute lalrpop; exited with {stat}");
let exit_code = stat.code().map(|v| (v % 256) as u8).unwrap_or(1);
Err(ExitCode::from(exit_code))
Err(anyhow::anyhow!("lalrpop error status: {}", exit_code))
}
Err(e) if e.kind() == io::ErrorKind::NotFound => {
eprintln!(
"the lalrpop executable is not installed and parser/{source} has been changed"
);
eprintln!("please install lalrpop with `cargo install lalrpop`");
Err(ExitCode::FAILURE)
Err(e) if e.kind() == std::io::ErrorKind::NotFound => {
eprintln!("please install lalrpop with `cargo install lalrpop` or\n`cargo build --manifest-path=parser/Cargo.toml --features=lalrpop`");
Err(anyhow::anyhow!(
"the lalrpop executable is not installed and parser/{} has been changed",
source
))
}
Err(e) => panic!("io error {e:#}"),
Err(e) => Err(anyhow::Error::new(e)),
}
}
#[cfg(feature = "lalrpop")]
fn lalrpop_dependency() {
lalrpop::process_root().unwrap()
}
fn sha_equal(expected_sha3_str: &str, actual_sha3: &[u8; 32]) -> bool {
if expected_sha3_str.len() != 64 {
panic!("lalrpop version? hash bug is fixed in 0.19.8");