Add executable x-lint
This commit is contained in:
parent
d3c4fbc626
commit
43ce73e5e2
|
@ -2,9 +2,8 @@
|
||||||
extern crate clap;
|
extern crate clap;
|
||||||
extern crate json;
|
extern crate json;
|
||||||
|
|
||||||
mod cst;
|
|
||||||
|
|
||||||
use clap::Arg;
|
use clap::Arg;
|
||||||
|
use cst_to_llhd::cst::{DescriptionList, Tag};
|
||||||
use std::{fs::File, io::Read, result::Result};
|
use std::{fs::File, io::Read, result::Result};
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
@ -42,21 +41,11 @@ fn main_inner() -> Result<(), String> {
|
||||||
println!("");
|
println!("");
|
||||||
|
|
||||||
let json_tree = &json_top[sv_file_name]["tree"];
|
let json_tree = &json_top[sv_file_name]["tree"];
|
||||||
assert!(json_tree["tag"] == cst::Tag::DESCRIPTION_LIST);
|
assert!(json_tree["tag"] == Tag::DESCRIPTION_LIST);
|
||||||
|
|
||||||
let module_list = cst::DescriptionList::codegen(json_tree);
|
let module_list = DescriptionList::codegen(json_tree);
|
||||||
for module in module_list {
|
for module in module_list {
|
||||||
println!("{}", module.dump());
|
println!("{}", module.dump());
|
||||||
|
|
||||||
for entity in module.entities() {
|
|
||||||
println!(
|
|
||||||
r#"entity "{}" has {} input ports and {} output ports"#,
|
|
||||||
entity.name(),
|
|
||||||
entity.input_args().count(),
|
|
||||||
entity.output_args().count()
|
|
||||||
);
|
|
||||||
println!("");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
|
@ -0,0 +1,104 @@
|
||||||
|
#[macro_use]
|
||||||
|
extern crate clap;
|
||||||
|
extern crate json;
|
||||||
|
|
||||||
|
use clap::Arg;
|
||||||
|
use cst_to_llhd::cst::{DescriptionList, Tag};
|
||||||
|
use std::{
|
||||||
|
process::{Command, Stdio},
|
||||||
|
result::Result,
|
||||||
|
};
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
match main_inner() {
|
||||||
|
Ok(_) => (),
|
||||||
|
Err(e) => {
|
||||||
|
eprintln!("Error: {}", e);
|
||||||
|
std::process::exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main_inner() -> Result<(), std::io::Error> {
|
||||||
|
let matches = app_from_crate!()
|
||||||
|
.about("x-lint: a linter using both CST and LLHD.")
|
||||||
|
.arg(
|
||||||
|
Arg::with_name("input")
|
||||||
|
.help("the Verilog file for linting")
|
||||||
|
.required(true),
|
||||||
|
)
|
||||||
|
.get_matches();
|
||||||
|
|
||||||
|
let json_raw = {
|
||||||
|
let mut ret = String::new();
|
||||||
|
|
||||||
|
let input = matches.value_of("input").unwrap();
|
||||||
|
|
||||||
|
let cmd_verible = "verible-verilog-syntax";
|
||||||
|
let cmd_tr = "tr";
|
||||||
|
let cmd_sed = "sed";
|
||||||
|
|
||||||
|
let mut verible_output_child = Command::new("verible-verilog-syntax")
|
||||||
|
.args(&["--printtree", "--export_json", input])
|
||||||
|
.stdout(Stdio::piped())
|
||||||
|
.spawn()
|
||||||
|
.expect(cmd_not_found(cmd_verible).as_str());
|
||||||
|
|
||||||
|
if let Some(verible_output) = verible_output_child.stdout.take() {
|
||||||
|
let mut tr_output_child = Command::new("tr")
|
||||||
|
.args(&["-d", r#"' \t\n'"#])
|
||||||
|
.stdin(verible_output)
|
||||||
|
.stdout(Stdio::piped())
|
||||||
|
.spawn()
|
||||||
|
.expect(cmd_not_found(cmd_tr).as_str());
|
||||||
|
|
||||||
|
verible_output_child.wait()?;
|
||||||
|
|
||||||
|
if let Some(tr_output) = tr_output_child.stdout.take() {
|
||||||
|
let sed_output_child = Command::new("sed")
|
||||||
|
.args(&["-e", r#"s/,null//g"#, "-e", r#"s/null,//g"#])
|
||||||
|
.stdin(tr_output)
|
||||||
|
.stdout(Stdio::piped())
|
||||||
|
.spawn()
|
||||||
|
.expect(cmd_not_found(cmd_sed).as_str());
|
||||||
|
|
||||||
|
let sed_output = sed_output_child.wait_with_output()?;
|
||||||
|
|
||||||
|
tr_output_child.wait()?;
|
||||||
|
|
||||||
|
ret = String::from_utf8(sed_output.stdout).unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ret
|
||||||
|
};
|
||||||
|
|
||||||
|
let json_top = json::parse(json_raw.as_str()).unwrap();
|
||||||
|
assert!(json_top.len() == 1);
|
||||||
|
|
||||||
|
let sv_file_name = json_top.entries().next().unwrap().0;
|
||||||
|
println!(r#"codegen from CST to LLHD for "{}" ..."#, sv_file_name);
|
||||||
|
println!("");
|
||||||
|
|
||||||
|
let json_tree = &json_top[sv_file_name]["tree"];
|
||||||
|
assert!(json_tree["tag"] == Tag::DESCRIPTION_LIST);
|
||||||
|
|
||||||
|
let module_list = DescriptionList::codegen(json_tree);
|
||||||
|
for module in module_list {
|
||||||
|
for entity in module.entities() {
|
||||||
|
println!(
|
||||||
|
r#"entity "{}" has {} input ports and {} output ports"#,
|
||||||
|
entity.name(),
|
||||||
|
entity.input_args().count(),
|
||||||
|
entity.output_args().count()
|
||||||
|
);
|
||||||
|
println!("");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn cmd_not_found(cmd: &str) -> String {
|
||||||
|
format!(r#"command "{}" not found"#, cmd)
|
||||||
|
}
|
|
@ -14,7 +14,7 @@ EOF
|
||||||
)
|
)
|
||||||
|
|
||||||
if [[ -f $verilog ]] ; then
|
if [[ -f $verilog ]] ; then
|
||||||
verible-verilog-syntax --printtree --export_json $verilog | tr -d ' \t\n' | sed "s/,null//g" | sed "s/null,//g" | jq
|
verible-verilog-syntax --printtree --export_json $verilog | tr -d ' \t\n' | sed -e "s/,null//g" -e "s/null,//g" | jq
|
||||||
else
|
else
|
||||||
echo "$usage"
|
echo "$usage"
|
||||||
echo ""
|
echo ""
|
||||||
|
|
Loading…
Reference in New Issue