blob: 8e53ae42ff43a90247e9c5638676a9acf6fdd87e [file] [log] [blame]
# takes: fei (either xml or text) and smv,
# and produces smv and fault modes files
import sys
import os.path
import logging
import _paths
import _utils
def get_expanded_fei_fname(fei_txt_fname):
"""Given the fei text file name, provides the file name of the
expanded fei """
base_in, _ext = os.path.splitext(fei_txt_fname)
return os.path.basename(base_in) + ".xml"
def get_extended_smv_fname(smv_fname):
full_base, ext = os.path.splitext(smv_fname)
base = os.path.basename(full_base)
prefix = "extended_"
return prefix + base + ext
def compile_fei(fei_xml_fname, out_xml_fname, lib_path=None):
from feic import feicm
feicm.main(fei_xml_fname, out_xml_fname,
lib_path or feicm.get_default_fault_lib_path())
def translate_fei_to_xml(fei_txt_fname, outdir, path):
"""returns the name of generated xml file. Raises RuntimeError
is an error occurs while parsing"""
from feic.translate import fei_translator
out_fei_xml = os.path.join(outdir, get_expanded_fei_fname(fei_txt_fname))
fei_translator.convert_fei_text_to_xml_format(
fei_txt_fname, out_fei_xml, path)
logging.info("Generated XML fei: " + out_fei_xml)
return out_fei_xml
def extend_model(smv_fname, fei_fname, outdir,
disable_checks=False, disable_cc=False,
anonymize=False):
import subprocess
if not os.path.exists(_paths.BIN_DIR) or not os.path.isdir(_paths.BIN_DIR):
raise RuntimeError("Could not find bin directory containing xsap")
cmd_pat = """set on_failure_script_quits
read_model -i "{smv_in}"
flatten_hierarchy
fe_load_doc -o "{error_fname}" {disable_checks} -p "{dtd_path}" -i "{xml_fei}"
fe_extend_module -m "{fms_fname}" {disable_cc} {anonymize} -o "{smv_out}"
quit
"""
smv_out = os.path.join(outdir,
get_extended_smv_fname(smv_fname))
fms_fname = os.path.join(outdir,
_utils.get_fms_fname(smv_out))
stdouterr_fname = os.path.join(outdir, "xsap_extend_model.out")
if os.path.exists(stdouterr_fname):
os.remove(stdouterr_fname)
error_fname = os.path.join(outdir, "errors.log")
if os.path.exists(error_fname):
os.remove(error_fname)
# generate command file
cmd_fname = os.path.join(outdir, "xsap_extend_model.cmd")
with open(cmd_fname, "w") as _cmd_file:
_cmd_file.write(cmd_pat.format(
smv_in=smv_fname,
error_fname=error_fname,
disable_checks="-c" if disable_checks else "",
dtd_path=_paths.SCHEMA_DIR,
xml_fei=fei_fname,
fms_fname=fms_fname,
disable_cc="-c" if disable_cc else "",
anonymize="-A" if anonymize else "",
smv_out=smv_out))
logging.info("Generated xsap commands script: " + cmd_fname)
logging.info("Invoking xsap to carry out smv extension of " + smv_fname)
exe_name = _utils.get_exec_fullname()
args = [exe_name, "-source", cmd_fname]
with open(stdouterr_fname, "w") as o_file:
o_file.write("\n" + "-" * 70)
o_file.write("\nInvoking:\n" + " ".join(args))
o_file.write("\n" + "-" * 70)
o_file.write("\nContent of %s is:\n" % cmd_fname)
o_file.write(open(cmd_fname).read())
res = subprocess.call(args, stdout=o_file, stderr=subprocess.STDOUT)
o_file.write("\n" + "-" * 70)
o_file.write("\nxsap returned %d\n" % res)
o_file.write("-" * 70 + '\n')
if res != 0:
logging.error("A fatal error occurred")
if os.path.exists(error_fname):
logging.error("This is content of %s:" % error_fname)
with open(error_fname) as _err:
for line in _err:
if line.strip():
print (" " + line.strip())
if os.path.exists(stdouterr_fname):
logging.error("(See also content of file %s)" % stdouterr_fname)
sys.exit(1)
else:
logging.info("Successfully created:")
logging.info(" - Extend smv file: '%s'" % smv_out)
logging.info(" - Fault modes xml file: '%s'" % fms_fname)
return smv_out, fms_fname
def handle_options():
"""returns (options, input_file):
values (as a map) and the name of the input file"""
import argparse
parser = argparse.ArgumentParser(description="Produces an extend smv file"
" out of given nominal smv file and fei")
parser.add_argument("smv_file",
metavar="SMV-FILE",
help="The input nominal smv file name")
parser.add_argument("fei_file",
metavar="FEI-FILE",
#dest="fei_file",
help="The input fei file name")
parser.add_argument('--xml-fei', '-x',
action='store_true',
default=False,
help='Process XML-format for input fei file')
parser.add_argument('--verbose', '-v',
action='store_true',
default=False,
help='Sets verbosity to high level')
parser.add_argument('--disable-checks', '-c',
action='store_true',
default=False,
help='Disable semantics checks when '
'extending model (for debugging)')
parser.add_argument(
"-p", "--path",
default=os.path.join(_paths.DATA_DIR, "fm_library"),
metavar="PATH",
help="Path to the extension library (default:%(default)s)")
parser.add_argument(
"-d", "--outdir",
default="out",
metavar="PATH",
help="Output directory, where all generated file should be "
"put into (default:%(default)s)")
parser.add_argument('--disable-cc', '-C',
action='store_true',
default=False,
help='Disable generation of common cause encoding '
'when extending model (for debugging)')
parser.add_argument('--anonymize', '-A',
action='store_true',
default=False,
help='Anonymize the generated extended model')
args = parser.parse_args()
for fn in (args.smv_file, args.fei_file):
if not os.path.isfile(fn):
parser.error("File not found: " + fn)
if os.path.exists(args.outdir) and not os.path.isdir(args.outdir):
parser.error("Not a directory: " + args.outdir)
return args
if "__main__" == __name__:
_paths.setup_path()
args = handle_options()
if not os.path.exists(args.outdir):
os.makedirs(args.outdir)
if args.verbose:
logging.getLogger().setLevel(logging.INFO)
# convert text format if user specified text format as input
try:
fei_in = (translate_fei_to_xml(args.fei_file, args.outdir, args.path)
if not args.xml_fei
else args.fei_file)
except RuntimeError as e:
logging.error(e)
sys.exit(1)
base_in, _ext = os.path.splitext(args.fei_file)
out_fei_fname = os.path.join(
args.outdir,
"expanded_" + os.path.basename(base_in) + ".xml")
if os.path.isfile(out_fei_fname):
logging.info("Removing previously generated expanded XML fei: " +
out_fei_fname)
os.remove(out_fei_fname)
logging.info("Generating expanded XML fei: " + out_fei_fname)
compile_fei(fei_in, out_fei_fname, args.path)
if not os.path.isfile(out_fei_fname):
logging.error("An error occurred while generating expanded XML fei: " +
out_fei_fname)
else:
logging.info("Generated expanded XML fei: " + out_fei_fname)
out_smv_fname, out_fms = extend_model(
args.smv_file, out_fei_fname,
args.outdir,
disable_checks=args.disable_checks,
disable_cc=args.disable_cc,
anonymize=args.anonymize,
)