Commit 83c4daf4 authored by Thanassis Tsiodras's avatar Thanassis Tsiodras
parents 47486aa1 d92c4275
[flake8]
ignore = E501,E225,C103
ignore = E501,E225,C103,E722,E252,W504
max-line-length = 160
......@@ -21,7 +21,7 @@ pylint:
mypy:
@echo Performing type analysis via mypy...
@mypy --disallow-untyped-defs --check-untyped-defs ${PY_SRC} || exit 1
@mypy --disallow-untyped-defs --check-untyped-defs --ignore-missing-imports ${PY_SRC} || exit 1
coverage:
@echo Performing coverage checks...
......
......@@ -3,7 +3,7 @@
TASTE Data Modelling Tools
==========================
These are the tools used by the European Space Agency's [TASTE toolchain](https://taste.tuxfamily.org/)
These are the tools used by the European Space Agency's [TASTE toolchain](https://taste.tools/)
to automate handling of the Data Modelling. They include more than two
dozen codegenerators that automatically create the 'glue'; the run-time translation
bridges that allow code generated by modelling tools (Simulink, SCADE, OpenGeode, etc)
......@@ -13,7 +13,7 @@ For the encoders and decoders of the messages
themselves, TASTE uses [ASN1SCC](https://github.com/ttsiodras/asn1scc) - an ASN.1
compiler specifically engineered for safety-critical environments.
For more details, visit the [TASTE site](https://taste.tuxfamily.org/).
For more details, visit the [TASTE site](https://taste.tools/).
Installation
------------
......
......@@ -9,7 +9,7 @@ dependencies:
- sudo rm -rf /var/cache/apt/archives && sudo ln -s ~/.apt-cache /var/cache/apt/archives && mkdir -p ~/.apt-cache/partial
# - sudo apt-get update
- sudo apt-get install libxslt-dev libxml2-dev python-psycopg2
- wget -O - -q https://github.com/ttsiodras/asn1scc/releases/download/3.3.9/asn1scc-bin-3.3.9.tar.bz2 | tar jxvf -
- wget -O - -q https://github.com/ttsiodras/asn1scc/releases/download/4.1b/asn1scc-bin-4.1b.tar.bz2 | tar jxvf -
- wget -O - -q https://github.com/ttsiodras/DataModellingTools/files/335591/antlr-2.7.7.tar.gz | tar zxvf - ; cd antlr-2.7.7/lib/python ; sudo pip2 install .
- sudo apt-get install mono-runtime libmono-system-data4.0-cil libmono-system-web4.0-cil libfsharp-core4.3-cil
......
......@@ -26,7 +26,7 @@ import copy
import DV_Types # pylint: disable=import-error
from ctypes import (
cdll, c_void_p, c_ubyte, c_double, c_uint,
c_longlong, c_bool, c_int, c_long
c_longlong, c_bool, c_int, c_long, c_char
)
# load the *getset.so in this folder
......@@ -252,18 +252,19 @@ An example for SetLength:
'double': c_double,
'flag': c_bool,
'int': c_int,
'long': c_long
'long': c_long,
'char': c_ubyte # char
}.get(resType, None)
if cTypesResultType is None:
raise AsnCoderError("Result type of %s not yet supported in the Python mapper - contact support." % resType)
bridgeFunc = getattr(JMP, bridgeFuncName)
bridgeFunc.restype = cTypesResultType
retVal = bridgeFunc(self._ptr, *self._params)
except:
except Exception as e:
oldAP = self._accessPath
if args.get("reset", True):
self.Reset()
raise AsnCoderError("The access path you used (%s) is not valid." % oldAP)
raise AsnCoderError("The access path you used (%s) is not valid. (%s)" % (oldAP, str(e)))
if args.get("reset", True):
self.Reset()
return retVal
......
......@@ -48,7 +48,7 @@ def OnStartup(unused_modelingLanguage: str, asnFiles: List[str], outputDir: str,
panic("ASN1SCC seems to be missing from your system (asn1.exe not found in PATH).\n") # pragma: no cover
os.system(
("mono " if sys.platform.startswith('linux') else "") +
"\"{}\" -wordSize 8 -typePrefix asn1Scc -Ada -uPER -o \"".format(asn1SccPath) +
"\"{}\" -typePrefix asn1Scc -Ada -uPER -o \"".format(asn1SccPath) +
outputDir + "\" \"" + "\" \"".join(asnFiles) + "\"")
os.system("rm -f \"" + outputDir + "\"/*.adb")
......
......@@ -47,7 +47,7 @@ def OnStartup(unused_modelingLanguage: str, asnFiles: List[str], outputDir: str,
panic("ASN1SCC seems to be missing from your system (asn1.exe not found in PATH).\n") # pragma: no cover
os.system(
("mono " if sys.platform.startswith('linux') else "") +
"\"{}\" -wordSize 8 -typePrefix asn1Scc -c -uPER -o \"".format(asn1SccPath) +
"\"{}\" -typePrefix asn1Scc -c -uPER -o \"".format(asn1SccPath) +
outputDir + "\" \"" + "\" \"".join(asnFiles) + "\"")
cmd = 'rm -f '
for i in ['real.c', 'asn1crt.c', 'acn.c']:
......
#
# (C) Semantix Information Technologies.
#
# Semantix Information Technologies is licensing the code of the
# Data Modelling Tools (DMT) in the following dual-license mode:
#
# Commercial Developer License:
# The DMT Commercial Developer License is the suggested version
# to use for the development of proprietary and/or commercial software.
# This version is for developers/companies who do not want to comply
# with the terms of the GNU Lesser General Public License version 2.1.
#
# GNU LGPL v. 2.1:
# This version of DMT is the one to use for the development of
# applications, when you are willing to comply with the terms of the
# GNU Lesser General Public License version 2.1.
#
# Note that in both cases, there are no charges (royalties) for the
# generated code.
# (C) Semantix Information Technologies,
# Neuropublic,
# European Space Agency
#
# The license of the Data Modelling Tools (DMT) is GPL with Runtime Exception
import re
import os
......@@ -28,7 +15,8 @@ from ..commonPy.utility import panic, inform
from ..commonPy.asnAST import (
AsnBool, AsnInt, AsnReal, AsnString, isSequenceVariable, AsnEnumerated,
AsnSequence, AsnSet, AsnChoice, AsnMetaMember, AsnSequenceOf, AsnSetOf,
AsnBasicNode, AsnNode, AsnSequenceOrSet, AsnSequenceOrSetOf)
AsnBasicNode, AsnNode, AsnSequenceOrSet, AsnSequenceOrSetOf,
AsnAsciiString)
from ..commonPy.asnParser import AST_Lookup, AST_Leaftypes
from ..commonPy.cleanupNodes import SetOfBadTypenames
......@@ -44,7 +32,7 @@ g_bHasStartupRunOnce = False
def Version() -> None:
print("Code generator: " +
"$Id: python_A_mapper.py 2400 2012-09-04 10:40:19Z ttsiodras $") # pragma: no cover
"$Id: python_A_mapper.py $") # pragma: no cover
def CleanNameAsPythonWants(name: str) -> str:
......@@ -52,7 +40,7 @@ def CleanNameAsPythonWants(name: str) -> str:
def OnStartup(unused_modelingLanguage: str, asnFile: str, outputDir: str, badTypes: SetOfBadTypenames) -> None:
os.system("bash -c '[ ! -f \"" + outputDir + "/" + asnFile + "\" ] && cp \"" + asnFile + "\" \"" + outputDir + "\"'")
os.system("cp -u \"" + asnFile + "\" \"" + outputDir + "\"")
this_path = os.path.dirname(__file__)
stubs = this_path + os.sep + 'Stubs.py'
os.system('cp "{}" "{}"'.format(stubs, outputDir))
......@@ -158,7 +146,7 @@ $(BDIR)/$(GRAMMAR)_getset.c: $(GRAMMAR).asn
$(BDIR)/asn1crt.c $(BDIR)/$(GRAMMAR).c $(BDIR)/real.c $(BDIR)/acn.c $(BDIR)/$(GRAMMAR).h $(BDIR)/asn1crt.h: $(GRAMMAR).asn
%(tab)sif [ ! -f "$(GRAMMAR).acn" ] ; then %(mono)s $(ASN1SCC) -ACND -o $(BDIR) $< ; fi
%(tab)s%(mono)s $(ASN1SCC) -ACN -c -uPER -equal -wordSize 8 -o $(BDIR) $< $(GRAMMAR).acn
%(tab)s%(mono)s $(ASN1SCC) -ACN -c -uPER -equal -o $(BDIR) $< $(GRAMMAR).acn
$(BDIR)/DV.py: $(GRAMMAR).asn
%(tab)sgrep 'REQUIRED_BYTES_FOR_.*ENCODING' $(BDIR)/$(GRAMMAR).h | awk '{print $$2 " = " $$3}' > $@
......@@ -182,6 +170,7 @@ clean:
g_outputGetSetC.write('\n/* Helper functions for NATIVE encodings */\n\n')
def WorkOnType(nodeTypeName: str) -> None:
inform("Python_A_mapper: Working on type '%s'...", nodeTypeName)
typ = CleanNameAsPythonWants(nodeTypeName)
g_outputGetSetH.write('void SetDataFor_%s(void *dest, void *src);\n' % typ)
g_outputGetSetH.write("byte* MovePtrBySizeOf_%s(byte *pData);\n" % typ)
......@@ -329,7 +318,6 @@ def CommonBaseImpl(comment: str,
g_outputGetSetC.write("}\n")
# def CommonBaseImplSequenceFixed(comment, ctype, path, params, accessPathInC, node, postfix = ""):
def CommonBaseImplSequenceFixed(comment: str,
ctype: str,
path: str,
......@@ -349,6 +337,31 @@ def CommonBaseImplSequenceFixed(comment: str,
g_outputGetSetC.write("}\n")
def CommonBaseImplIA5String(comment: str,
ctype: str,
path: str,
params: Params,
accessPathInC: str,
node: AsnAsciiString) -> None:
g_outputGetSetH.write("\n/* %s */\n%s %s_GetLength(%s);\n" % (comment, ctype, path, params.GetDecl()))
g_outputGetSetC.write("\n/* %s */\n%s %s_GetLength(%s)\n" % (comment, ctype, path, params.GetDecl()))
g_outputGetSetC.write("{\n")
if not isSequenceVariable(node):
g_outputGetSetC.write(" return " + str(node._range[-1]) + ";\n")
else:
g_outputGetSetC.write(" return strlen((*root)" + accessPathInC + ");\n")
g_outputGetSetC.write("}\n")
g_outputGetSetH.write("\n/* %s */\nvoid %s_SetLength(%s, %s value);\n" % (comment, path, params.GetDecl(), ctype))
g_outputGetSetC.write("\n/* %s */\nvoid %s_SetLength(%s, %s value)\n" % (comment, path, params.GetDecl(), ctype))
g_outputGetSetC.write("{\n")
if not isSequenceVariable(node):
g_outputGetSetC.write(" assert(value == " + str(node._range[-1]) + ");\n")
# g_outputGetSetC.write(" fprintf(stderr, \"WARNING: setting length of fixed-length string\\n\");\n")
else:
g_outputGetSetC.write(" (*root)" + accessPathInC + "[value] = 0;\n")
g_outputGetSetC.write("}\n")
def CreateGettersAndSetters(
path: str,
params: Params,
......@@ -367,6 +380,13 @@ def CreateGettersAndSetters(
CommonBaseImpl("INTEGER", "asn1SccSint", path, params, accessPathInC)
elif isinstance(node, AsnReal):
CommonBaseImpl("REAL", "double", path, params, accessPathInC)
elif isinstance(node, AsnAsciiString):
if not node._range:
panic("Python_A_mapper: IA5String (in %s) must have a SIZE constraint!\n" % node.Location()) # pragma: no cover
CommonBaseImplIA5String("IA5String", "long", path, params, accessPathInC, node)
params.AddParam('int', "iDx", leafTypeDict)
CommonBaseImpl("IA5String_bytes", "char", path + "_iDx", params, accessPathInC + ("[" + params._vars[-1] + "]"), "")
params.Pop()
elif isinstance(node, AsnString):
if not node._range:
panic("Python_A_mapper: string (in %s) must have a SIZE constraint!\n" % node.Location()) # pragma: no cover
......@@ -539,12 +559,13 @@ def CreateDeclarationForType(nodeTypename: str, names: AST_Lookup, leafTypeDict:
g_outputFile.write(" print(self.GSER() + '\\n')\n\n\n")
else: # pragma: no cover
panic("Unexpected ASN.1 type... Send this grammar to Semantix") # pragma: no cover
panic("Unexpected ASN.1 type... Send this grammar to ESA") # pragma: no cover
def CreateDeclarationsForAllTypes(names: AST_Lookup, leafTypeDict: AST_Leaftypes, badTypes: SetOfBadTypenames) -> None:
for nodeTypename in names:
if not names[nodeTypename]._isArtificial and nodeTypename not in badTypes:
# Do not ignore the so called "bad types". In python, IA5Strings are supported
if not names[nodeTypename]._isArtificial: # and nodeTypename not in badTypes:
CreateDeclarationForType(nodeTypename, names, leafTypeDict)
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4
......@@ -72,7 +72,7 @@ def OnStartup(unused_modelingLanguage: str, asnFiles: List[str], outputDir: str,
panic("ASN1SCC seems to be missing from your system (asn1.exe not found in PATH).\n") # pragma: no cover
os.system(
("mono " if sys.platform.startswith('linux') else "") +
"\"{}\" -wordSize 8 -typePrefix asn1Scc -c -uPER -o \"".format(asn1SccPath) +
"\"{}\" -typePrefix asn1Scc -c -uPER -o \"".format(asn1SccPath) +
outputDir + "\" \"" + "\" \"".join(asnFiles) + "\"")
os.system("rm -f \"" + outputDir + "\"/*.adb")
......
......@@ -362,7 +362,7 @@ taste.bit: $(SRCS)
{tab}cp "$@" ../TASTE.bit || exit 1
$(SYSTEMC_GENERATED): $(SYSTEMC_SRC)
{tab}for i in $^ ; do if [ "`basename "$$i" | sed 's,^.*\.,,'`" = "cpp" ] ; then /c/Program\ Files/SystemCrafter/SystemCrafter\ SC/bin/craft.exe /vhdl $$i || exit 1; fi ; done
{tab}for i in $^ ; do if [ "`basename "$$i" | sed 's,^.*\\.,,'`" = "cpp" ] ; then /c/Program\\ Files/SystemCrafter/SystemCrafter\\ SC/bin/craft.exe /vhdl $$i || exit 1; fi ; done
test:
{tab}cd .. ; ./TASTE.exe
......
......@@ -459,7 +459,7 @@ static void ErrorHandler(
ZESTSC1_STATUS Status,
const char *Msg)
{
printf("**** TASTE - Function %s returned an error\\n \\"%%s\\"\\n\\n", Function, Msg);
printf("**** TASTE - Function %s returned an error\\n \\"%s\\"\\n\\n", Function, Msg);
exit(1);
}
......
......@@ -166,7 +166,7 @@ of each SUBPROGRAM param.'''
for step in python2className.split('.')[1:]:
klass = getattr(klass, step)
o.__class__ = klass
except Exception as _:
except Exception:
pass
patchMe(sp)
......@@ -207,7 +207,7 @@ types). This used to cover Dumpable C/Ada Types and OG headers.'''
if asnFile is not None:
if not asn1SccPath:
panic("ASN1SCC seems not installed on your system (asn1.exe not found in PATH).\n") # pragma: no cover
os.system('mono "{}" -wordSize 8 -typePrefix asn1Scc -Ada -equal -o "{}" "{}"'
os.system('mono "{}" -typePrefix asn1Scc -Ada -equal -o "{}" "{}"'
.format(asn1SccPath, outputDir, '" "'.join([asnFile])))
......
......@@ -89,11 +89,14 @@ def calculateForNativeAndASN1SCC(absASN1SCCpath, autosrc, names, inputFiles):
# Spawn ASN1SCC.exe compiler - for MacOS define a new sh file calling mono Asn1f2.exe
if platform.system() == "Windows" or platform.system() == "Darwin":
mysystem("%s -wordSize 8 -c -uPER -o \"%s\" %s %s" % (absASN1SCCpath, autosrc, acn, '"' + '" "'.join(inputFiles) + '"'))
mysystem("%s -c -uPER -o \"%s\" %s %s" % (absASN1SCCpath, autosrc, acn, '"' + '" "'.join(inputFiles) + '"'))
for line in os.popen("%s -AdaUses %s" % (absASN1SCCpath, '" "'.join(inputASN1files))):
g_AdaPackageNameOfType[line.split(':')[0]] = line.split(':')[1].rstrip()
else:
mysystem("mono %s -wordSize 8 -c -uPER -o \"%s\" %s %s" % (absASN1SCCpath, autosrc, acn, '"' + '" "'.join(inputFiles) + '"'))
cmd = "mono %s -c -uPER -o \"%s\" %s %s" % (absASN1SCCpath, autosrc, acn, '"' + '" "'.join(inputFiles) + '"')
res = mysystem(cmd)
if res != 0:
panic("This command failed: %s\n" % cmd)
for line in os.popen('mono %s -AdaUses "%s"' % (absASN1SCCpath, '" "'.join(inputASN1files))):
g_AdaPackageNameOfType[line.split(':')[0]] = line.split(':')[1].rstrip()
......@@ -424,7 +427,7 @@ end Stream_Element_Buffer;
if bAADLv2:
o.write(' Deployment::ASN1_Module_Name => "%s";\n' % g_AdaPackageNameOfType[asnTypename].replace('_', '-'))
if os.getenv('UPD') is None:
o.write(' Source_Language => ASN1;\n')
o.write(' Source_Language => (ASN1);\n')
o.write(' -- Size of a buffer to cover all forms of message representation:\n')
le_size = 0 if asnTypename not in messageSizes else messageSizes[asnTypename][0]
o.write(' -- Real message size is %d; suggested aligned message buffer is...\n' % le_size)
......@@ -487,6 +490,22 @@ end Stream_Element_Buffer;
o.write(' Data_Model::Data_Representation => Struct;\n')
o.write('END ' + cleanName + '_Buffer.impl;\n\n')
# Generate a SYSTEM in the DataView, otherwise Ocarina cannot parse it
# standalone. This allows buildsupport to get the list of ASN.1 files
# and modules, which is otherwise not visible unless those for which
# at least one type is referenced in a provided interface.
o.write('SYSTEM Taste_DataView\n')
o.write('END Taste_DataView;\n\n')
o.write('SYSTEM IMPLEMENTATION Taste_DataView.others\n')
o.write('SUBCOMPONENTS\n')
for asnTypename in list(asnParser.g_names.keys()):
node = asnParser.g_names[asnTypename]
if node._isArtificial:
continue
cleanName = cleanNameAsAADLWants(asnTypename)
o.write(' %s : DATA %s;\n' % (cleanName, cleanName))
o.write('END Taste_DataView.others;\n')
listOfAsn1Files = {}
for asnTypename in list(asnParser.g_names.keys()):
listOfAsn1Files[asnParser.g_names[asnTypename]._asnFilename] = 1
......@@ -500,7 +519,7 @@ end Stream_Element_Buffer;
o.write('DATA ACN_' + fname + '\n')
o.write('PROPERTIES\n')
o.write(' Source_Text => ("' + possibleACN + '");\n')
o.write(' Source_Language => ACN;\n')
o.write(' Source_Language => (ACN);\n')
o.write('END ACN_' + fname + ';\n\n')
o.write('end DataView;\n')
......
#!/usr/bin/env python3
# vim: set expandtab ts=8 sts=4 shiftwidth=4
#
# (C) Semantix Information Technologies.
# (C) Semantix Information Technologies, Neuropublic, and European Space Agency
#
# Copyright 2014-2015 IB Krates <info@krates.ee>
# QGenc code generator integration
#
# Semantix Information Technologies is licensing the code of the
# Data Modelling Tools (DMT) in the following dual-license mode:
#
# Commercial Developer License:
# The DMT Commercial Developer License is the suggested version
# to use for the development of proprietary and/or commercial software.
# This version is for developers/companies who do not want to comply
# with the terms of the GNU Lesser General Public License version 2.1.
#
# GNU LGPL v. 2.1:
# This version of DMT is the one to use for the development of
# applications, when you are willing to comply with the terms of the
# GNU Lesser General Public License version 2.1.
#
# Note that in both cases, there are no charges (royalties) for the
# generated code.
#
# License is GPL with runtime exception
'''
Model Translator
......@@ -211,7 +195,8 @@ def main() -> None:
names = uniqueASNfiles[asnFile][0]
for nodeTypename in sorted(names):
# Check if this type must be skipped
if nodeTypename in badTypes:
if nodeTypename in badTypes and modelingLanguage.lower() != 'python':
# all languages but python discard IA5Strings
continue
node = names[nodeTypename]
inform("Processing %s (%s)...", nodeTypename, modelingLanguage)
......@@ -220,7 +205,7 @@ def main() -> None:
assert nodeTypename in leafTypeDict
leafType = leafTypeDict[nodeTypename]
if leafType in ['BOOLEAN', 'INTEGER', 'REAL', 'OCTET STRING']:
if leafType in ['BOOLEAN', 'INTEGER', 'REAL', 'OCTET STRING', 'AsciiString']:
processor = backend.OnBasic
elif leafType == 'SEQUENCE':
processor = backend.OnSequence
......
This diff is collapsed.
# (C) Semantix Information Technologies.
#
# Semantix Information Technologies is licensing the code of the
# Data Modelling Tools (DMT) in the following dual-license mode:
#
# Commercial Developer License:
# The DMT Commercial Developer License is the appropriate version
# to use for the development of proprietary and/or commercial software.
# This version is for developers/companies who do not want to share
# the source code they develop with others or otherwise comply with the
# terms of the GNU Lesser General Public License version 3.
#
# GNU LGPL v. 2.1:
# This version of DMT is the one to use for the development of
# non-commercial applications, when you are willing to comply
# with the terms of the GNU Lesser General Public License version 3.
#
# The features of the two licenses are summarized below:
#
# Commercial
# Developer LGPL
# License
#
# License cost License fee charged No license fee
#
# Must provide source
# code changes to DMT No, modifications can Yes, all source code
# be closed must be provided back
#
# Can create Yes, that is, No, applications are subject
# proprietary no source code needs to the LGPL and all source code
# applications to be disclosed must be made available
#
# Support Yes, 12 months of No, but available separately
# premium technical for purchase
# support
#
# Charge for Runtimes None None
# (C) Semantix Information Technologies,
# Neuropublic,
# European Space Agency
#
# The license of the Data Modelling Tools (DMT) is GPL with Runtime Exception
'''
Rules to gather the list of types that must be skipped
'''
......
coverage>=3.7.1
flake8>=2.6.0
mypy>=0.530
flake8==2.6.0
mypy==0.530
pyflakes>=1.2.3
pylint>=1.7.0
pytest>=2.6.3
......
......@@ -11,7 +11,7 @@ from setuptools import setup, find_packages
setup(
name='dmt',
version="2.1.10",
version="2.1.11",
packages=find_packages(),
author='Thanassis Tsiodras',
author_email='Thanassis.Tsiodras@esa.int',
......
......@@ -107,9 +107,34 @@ myVar MyInt ::= 4
ConfigString ::= IA5String (SIZE(1..20))
myStrVar ConfigString ::= "This is a test"
T-TypeThatMustNotBeMapped ::= SEQUENCE {
FixedLenConfigString ::= IA5String (SIZE (5))
myStrFixed FixedLenConfigString ::= "Hello"
T-TypeThatMustNotBeMappedExceptInPython ::= SEQUENCE {
config ConfigString,
param INTEGER (0..10)
param INTEGER (0..10),
fixstr FixedLenConfigString DEFAULT "Hello"
}
E ::= INTEGER (0..255|1299)(5)
TypeWithOptional ::= SEQUENCE {
a BOOLEAN OPTIONAL,
b INTEGER (0..255|1299),
c INTEGER (0..255),
d T-TypeThatMustNotBeMappedExceptInPython DEFAULT {config "Config", param 5, fixstr "World"}
}
push-it T-TypeThatMustNotBeMappedExceptInPython ::= {config "Config", param 5, fixstr "World"}
SubTypeWithOptional ::= TypeWithOptional (WITH COMPONENTS {a ABSENT, c (42), b (1299)})
SuperChoice ::= CHOICE {
first-choice BOOLEAN,
second-choice INTEGER (0..255),
third-choice TypeWithOptional
}
-- Choice items can be removed in subtypes
SuperRestrictedChoice ::= SuperChoice (WITH COMPONENTS {second-choice ABSENT})
END
This diff is collapsed.
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