Commit 58a65ea5 authored by Maxime Perrotin's avatar Maxime Perrotin
Browse files

Asn1Scc API

parent bb893258
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
Python API for the ASN1Scc compiler
Copyright (c) 2013 European Space Agency
Designed and implemented by Maxime Perrotin
Based on the ASN.1 Space Certified Compiler from Neuropublic
Contact: maxime.perrotin@esa.int
"""
import subprocess
import tempfile
import uuid
import os
import sys
import importlib
import logging
import PySide.QtCore as Qt
import icons
LOG = logging.getLogger(__name__)
# global needed to store the imported module and list of modules ever loaded
AST = {}
try:
from enum import Enum
except ImportError:
raise ImportError('Enum module not found. use sudo pip install enum34')
__all__ = ['ASN1', 'parse_asn1']
__version__ = '0.1'
class ASN1(Enum):
''' Flags used to control the compiler options '''
NoParameterizedTypes = 1
NoInnerTypes = 2
NoConstraintReference = 3
UniqueEnumeratedNames = 4
AstOnly = 5
def parse_asn1(*files, **options):
''' Call the ASN.1 parser on a number of files, and return the module
containing the AST '''
global AST
ast_version = options.get('ast_version', ASN1.UniqueEnumeratedNames)
flags = options.get('flags' , [ASN1.AstOnly])
assert isinstance(ast_version, ASN1)
assert isinstance(flags, list)
tempdir = tempfile.mkdtemp()
filename = str(uuid.uuid4()).replace('-', '_')
filepath = tempdir + os.sep + filename + '.py'
# dump python.stg in the temp directory
stg = Qt.QFile(':misc/python.stg')
stg_data = stg.readData(stg.size())
tmp_stg = tempdir + os.sep + 'python.stg'
with open(tmp_stg, 'w') as fd:
fd.write(stg_data)
args = ['asn1.exe',
'-customStgAstVerion', str(ast_version.value),
'-customStg', tmp_stg + ':' + filepath] + list(*files)
LOG.debug('Calling: ' + ' '.join(args))
ret = subprocess.check_call(args)
sys.path.append(tempdir)
if ret == 0:
if filename in AST.viewkeys():
# Re-import module if it was already loaded
ast = AST[filename]
reload(ast)
else:
ast = importlib.import_module(filename)
AST[filename] = ast
return ast
else:
raise TypeError('Error calling ASN.1 compiler')
if __name__ == '__main__':
try:
ast = parse_asn1('dataview-uniq.asn',
ast_version=ASN1.NoParameterizedTypes,
flags=[ASN1.AstOnly])
print ast.types.keys()
sys.exit(0)
except TypeError as err:
print(str(err))
sys.exit(1)
group python;
//delimiters "$", "$"
RootXml(arrsFiles) ::= <<
#!/usr/bin/env python
# ASN.1 Data model
asn1Files = []
asn1Modules = []
exportedTypes = {}
exportedVariables = {}
importedModules = {}
types = {}
$arrsFiles;separator="\n"$
>>
FileXml(sFileName, arrsModules) ::= <<
asn1Files.append("$sFileName$")
$arrsModules;separator="\n"$
>>
ModuleXml(sName, arrsImportedModules, arrsExpTypes, arrsExpVars, arrsTases) ::=<<
asn1Modules.append("$sName$")
exportedTypes["$sName$"] = [$arrsExpTypes:{x|"$x$"};separator=", "$]
exportedVariables["$sName$"] = [$arrsExpVars:{x|"$x$"};separator=", "$]
importedModules["$sName$"] = [$arrsImportedModules:{x|$x$};separator=", "$]
$arrsTases;separator="\n"$
>>
ImportedMod(sName, arrsTypes, arrsVars) ::= <<
{"$sName$":{"ImportedTypes": [$arrsTypes:{t|"$t$"};separator=","$], "ImportedVariables": [$arrsVars:{t|"$t$"};separator=","$]}}
>>
TasXml(sName, nLine, nPos, sType) ::= <<
types["$sName$"] = type("$sName$", (object,), {
"Line": $nLine$, "CharPositionInLine": $nPos$, "type": type("$sName$_type", (object,), {
$sType$
})
})
>>
TypeGeneric(nLine, nPos, sSubType) ::= <<
"Line": $nLine$, "CharPositionInLine": $nPos$, $sSubType$
>>
MinMaxType(sName, sMin, sMax) ::= <<
"kind": "$sName$", "Min": "$sMin$", "Max": "$sMax$"
>>
MinMaxType2(sName, sMin, sMax) ::= <<
"kind": "$sName$", "Min": "$sMin$", "Max": "$sMax$"
>>
BooleanType () ::= <<"kind": "BooleanType">>
NullType () ::= <<"kind": "NullType">>
EnumItem (sName, nVal, nLine, nPos, sCID) ::= <<
"$sName$": type("$sCID$", (object,), {
"IntValue": $nVal$, "Line": $nLine$, "CharPositionInLine": $nPos$, "EnumID": "$sCID$"
})
>>
EnumType(arrsItems) ::= <<
"kind": "EnumeratedType", "Extensible": "False", "ValuesAutoCalculated": "False", "EnumValues": {
$arrsItems;separator=",\n"$
}
>>
ChoiceChild(sName, nLine, nPos, sChildContent, sNamePresent ) ::= <<
"$sName$": type("$sNamePresent$", (object,), {
"Line": $nLine$, "CharPositionInLine": $nPos$, "EnumID": "$sNamePresent$", "type": type("$sNamePresent$_type", (object,), {
$sChildContent$
})
})
>>
ChoiceType(arrsChildren) ::= <<
"kind": "ChoiceType", "Children": {
$arrsChildren;separator=",\n"$
}
>>
SequenceChild(sName, bOptional, sDefVal, nLine, nPos, sChildContent ) ::= <<
"$sName$": type("$sName$", (object,), {
"Optional": "$bOptional$"$if(sDefVal)$, "DefaultValue": "$sDefVal$"$endif$, "Line": $nLine$, "CharPositionInLine": $nPos$, "type": type("$sName$_type", (object,), {
$sChildContent$
})
})
>>
SequenceType(arrsChildren) ::= <<
"kind": "SequenceType", "Children": {
$arrsChildren;separator=",\n"$
}
>>
SequenceOfType(sMin, sMax, sChild) ::= <<
"kind": "SequenceOfType", "Min": "$sMin$", "Max": "$sMax$", "type": type("SeqOf_type", (object,), {
$sChild$
})
>>
RefTypeMinMax(sMin, sMax, sName, sModName) ::= <<
"kind": "ReferenceType", "ReferencedTypeName": "$sName$", "Min": "$sMin$", "Max": "$sMax$"$if(sModName)$, "ReferencedModName": "$sModName$"$endif$
>>
RefType(sName, sModName) ::= <<
"kind": "ReferenceType", "ReferencedTypeName": "$sName$"$if(sModName)$, "ReferencedModName": "$sModName$"$endif$
>>
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