pub mod advantest;
pub mod flow_api;
mod flow_manager;
mod model;
mod nodes;
mod processors;
pub mod teradyne;
mod validators;
pub mod config;
mod supported_testers;
pub mod test_ids;
use std::path::Path;
use std::path::PathBuf;
pub use flow_manager::FlowManager;
pub use model::Bin;
pub use model::BinType;
pub use model::FlowCondition;
pub use model::FlowID;
pub use model::GroupType;
pub use model::Limit;
pub use model::LimitSelector;
pub use model::LimitType;
pub use model::Model;
pub use model::ParamType;
pub use model::ParamValue;
pub use model::Pattern;
pub use model::PatternGroupType;
pub use model::PatternReferenceType;
pub use model::PatternType;
pub use model::Test;
pub use model::TestCollection;
pub use model::TestCollectionItem;
pub use model::Variable;
pub use model::VariableOperation;
pub use model::VariableType;
pub use nodes::PGM;
pub use supported_testers::SupportedTester;
pub use model::{TestTemplate, TestTemplateCollection, TestTemplateParameter};
use model::load_test_from_lib;
use crate::ast::AST;
use crate::ast::{Attrs, Node};
#[derive(Debug, PartialEq, EnumString, Clone, Serialize)]
pub enum ResourcesType {
#[strum(serialize = "All", serialize = "all", serialize = "ALL")]
All,
#[strum(
serialize = "Pattern",
serialize = "pattern",
serialize = "PATTERN",
serialize = "Patterns",
serialize = "patterns",
serialize = "PATTERNS"
)]
Patterns,
#[strum(
serialize = "Variable",
serialize = "variable",
serialize = "VARIABLE",
serialize = "Variables",
serialize = "variables",
serialize = "VARIABLES"
)]
Variables,
}
#[derive(Debug, Serialize, Clone, PartialEq)]
pub enum UniquenessOption {
None,
Signature,
Flowname,
String(String),
}
impl std::str::FromStr for UniquenessOption {
type Err = String;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s.to_lowercase().as_str() {
"none" => Ok(UniquenessOption::None),
"signature" => Ok(UniquenessOption::Signature),
"flowname" => Ok(UniquenessOption::Flowname),
_ => Ok(UniquenessOption::String(s.to_string())),
}
}
}
pub trait ProgramGenerator {
}
pub fn trace_error<T: Attrs>(node: &Node<T>, error: crate::Error) -> crate::Result<()> {
let help = {
let s = node.meta_string();
if s != "" {
s
} else {
if crate::PROG_GEN_CONFIG.debug_enabled() {
let n = node.replace_children(vec![]);
format!("Sorry, no flow source information was found, here is the flow node that failed if it helps:\n{}", n)
} else {
"Run again with the --debug switch to try and trace this back to a flow source file location".to_string()
}
}
};
bail!("{}\n{}", error, &help)
}
pub fn render_program(tester: SupportedTester, output_dir: &Path) -> crate::Result<(Vec<PathBuf>, Model)> {
match tester {
SupportedTester::V93KSMT7 => advantest::smt7::render(output_dir),
SupportedTester::V93KSMT8 => advantest::smt8::render(output_dir),
_ => Ok((vec![], Model::new(tester))),
}
}
pub fn test_invocation_options(tester: SupportedTester) -> crate::Result<Vec<String>> {
match tester {
SupportedTester::V93KSMT7 | SupportedTester::V93KSMT8 => {
let t = load_test_from_lib(
&tester,
"_internal",
"test_suite",
)?;
let mut options = vec![];
if let Some(params) = t.parameter_list {
for param in params.keys() {
options.push(param.to_owned());
}
}
if let Some(params) = t.aliases {
for param in params.keys() {
options.push(param.to_owned());
}
}
Ok(options)
}
_ => Ok(vec![]),
}
}
pub fn process_flow(flow: &AST<PGM>, model: Model, tester: SupportedTester, validate: bool) -> crate::Result<(Node<PGM>, Model)> {
log_debug!("Screening flow for tester {:?}", tester);
let mut ast = flow.process(&mut |n| {
processors::target_tester::run(n, tester)
})?;
if validate {
log_debug!("Validating flow for tester {:?}", tester);
validators::duplicate_ids::run(&ast)?;
validators::missing_ids::run(&ast)?;
validators::jobs::run(&ast)?;
validators::flags::run(&ast)?;
log_debug!("Flow validation completed successfully");
}
let mut m;
log_debug!("Extracting initial model from flow for tester {:?}", tester);
(ast, m) = processors::initial_model_extract::run(
&ast,
tester,
model,
)?;
log_debug!("Processing flow for tester {:?}", tester);
ast = processors::clean_resources::run(&ast)?;
ast = processors::nest_on_result_nodes::run(&ast)?;
ast = processors::relationship::run(&ast)?;
ast = processors::condition::run(&ast)?;
ast = processors::continue_implementer::run(&ast)?;
ast = processors::flag_optimizer::run(&ast, None)?;
ast = processors::adjacent_if_combiner::run(&ast)?;
match tester {
SupportedTester::V93KSMT7 => {
(ast, m) = advantest::smt7::processors::clean_names_and_add_sig::run(&ast, m)?;
}
SupportedTester::V93KSMT8 => {
ast = advantest::smt8::processors::create_flow_data::run(&ast)?;
}
_ => { }
}
Ok(processors::final_model_extract::run(&ast, m)?)
}