Commit 89e525cf authored by Maxime Perrotin's avatar Maxime Perrotin
Browse files

Add caching similar to dmt when calling asn1

parent 9946e2d5
......@@ -135,6 +135,9 @@ The background pattern was downloaded from www.subtlepatterns.com
Changelog
=========
2.0.13 (06/2018)
- Add taste-compatible cache mechanism when calling asn1scc
2.0.12 (06/2018)
- Fix resolution of ASN.1 constants - values were not use propertly when
a constant was referencing another constant (numerical operations only)
......
......@@ -4,7 +4,7 @@
"""
Python API for the ASN1Scc compiler
Copyright (c) 2013-2016 European Space Agency
Copyright (c) 2013-2018 European Space Agency
Designed and implemented by Maxime Perrotin
......@@ -81,20 +81,39 @@ def parse_asn1(*files, **options):
This function uses QProcess to launch the ASN.1 compiler because
the subprocess module from Python has issues on the Windows platform
'''
# use basic caching to avoid re-parsing when loading the model
project_cache = os.getenv ("PROJECT_CACHE")
if project_cache is not None and not os.path.isdir(project_cache):
raise TypeError (
"The configured cache folder \""
+ project_cache + "\" is not there!\n")
# make sure the same files are not parsed more than once if not modified
filehash = hashlib.md5()
file_list = list(*files)
file_list = sorted(list(*files))
try:
for each in file_list:
filehash.update(open(each).read())
# also hash the file path: it is used in the AST, so it is
# not enough to hash the content of the ASN.1 files, as two sets
# of input files may have the same hash
filehash.update(each)
except IOError as err:
raise TypeError (str(err))
new_hash = filehash.hexdigest()
fileset = "".join(file_list)
if fileset in AST.viewkeys() and AST[fileset]['hash'] == new_hash:
return AST[fileset]['ast']
else:
AST[fileset] = {'hash': new_hash}
# names of the files that will be generated by asn1scc and then parsed
out_py_name = new_hash + ".py"
out_html_name = new_hash + ".html"
if new_hash in AST.viewkeys():
return AST[new_hash]
elif project_cache is not None:
outdir = project_cache
elif project_cache is None:
outdir = tempfile.mkdtemp()
# to allow the import
sys.path.append(outdir)
ast_version = options.get('ast_version', ASN1.UniqueEnumeratedNames)
rename_policy = options.get('rename_policy', ASN1.NoRename)
......@@ -117,45 +136,46 @@ def parse_asn1(*files, **options):
binary = path_to_asn1scc
arg0 = ''
asn1scc_root = os.path.abspath(os.path.dirname(path_to_asn1scc))
# Create a temporary directory to store dataview.py and import it
tempdir = tempfile.mkdtemp()
sys.path.append(tempdir)
if os.name == 'nt':
# On windows, remove the drive letter, workaround to ASN1SCC bug
tempdir = tempdir[2:]
outdir = outdir[2:]
asn1scc_root = asn1scc_root[2:]
filename = str(uuid.uuid4()).replace('-', '_')
filepath = tempdir + os.sep + filename + '.py'
stg = asn1scc_root + os.sep + 'python.stg'
if pprint:
# Generate an html file with pretty-printed ASN.1 types
stg_qrc = QFile(':misc/pretty_print_asn1.stg')
stg_qrc.open(1)
content = stg_qrc.readAll()
stgfile = tempdir + os.sep + 'pretty_print_asn1.stg'
with open(stgfile, 'w') as tmpfile:
tmpfile.write(content.data())
out_html = tempdir + os.sep + 'dataview.html'
html = ['-customIcdUper', stgfile + '::' + out_html]
else:
html = []
args = [arg0, '-customStgAstVersion', str(ast_version.value),
'-customStg', stg + '::' + filepath,
'-renamePolicy', str(rename_policy.value)] + html + list(*files)
asn1scc = QProcess()
LOG.debug(os.getcwd())
LOG.debug(binary + ' ' + ' '.join(args))
asn1scc.start(binary, args)
_ = waitfor_qprocess(asn1scc, "ASN.1 Compiler")
ast = importlib.import_module(filename)
AST[fileset]['ast'] = ast
# The two possible files that can be generated with complete path:
py_filepath = outdir + os.sep + out_py_name
html_filepath = outdir + os.sep + out_html_name
# call the ASN.1 compiler only if there is no existing cached file
if project_cache is None or not os.path.exists(py_filepath):
stg = asn1scc_root + os.sep + 'python.stg'
if pprint:
# Generate an html file with pretty-printed ASN.1 types
stg_qrc = QFile(':misc/pretty_print_asn1.stg')
stg_qrc.open(1)
content = stg_qrc.readAll()
stgfile = outdir + os.sep + 'pretty_print_asn1.stg'
with open(stgfile, 'w') as tmpfile:
tmpfile.write(content.data())
html = ['-customIcdUper', stgfile + '::' + html_filepath]
else:
html = []
args = [arg0, '-customStgAstVersion', str(ast_version.value),
'-customStg', stg + '::' + py_filepath,
'-renamePolicy', str(rename_policy.value)] + html + file_list
asn1scc = QProcess()
LOG.debug(os.getcwd())
LOG.debug(binary + ' ' + ' '.join(args))
asn1scc.start(binary, args)
_ = waitfor_qprocess(asn1scc, "ASN.1 Compiler")
ast = importlib.import_module(new_hash)
AST[new_hash] = ast
if pprint:
# add the path to the optionally-gernated pretty-printed HTML file
ast.html = out_html
# add the path to the optionally-generated pretty-printed HTML file
ast.html = html_filepath
return ast
......
......@@ -141,7 +141,7 @@ except ImportError:
__all__ = ['opengeode', 'SDL_Scene', 'SDL_View', 'parse']
__version__ = '2.0.12'
__version__ = '2.0.13'
if hasattr(sys, 'frozen'):
# Detect if we are running on Windows (py2exe-generated)
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment