Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
TASTE
dmt
Commits
b8b94ff1
Commit
b8b94ff1
authored
Apr 08, 2019
by
Thanassis Tsiodras
Browse files
Merge mandatory changes from master.
parent
7c86ba8d
Changes
5
Hide whitespace changes
Inline
Side-by-side
dmt/A_mappers/python_A_mapper.py
View file @
b8b94ff1
...
...
@@ -247,7 +247,7 @@ def OnShutdown(unused_badTypes: SetOfBadTypenames) -> None:
pass
class
Params
(
object
)
:
class
Params
:
cTypes
=
{
"BOOLEAN"
:
"flag"
,
"INTEGER"
:
"asn1SccSint"
,
...
...
@@ -302,8 +302,8 @@ def CommonBaseImpl(comment: str,
path
:
str
,
params
:
Params
,
accessPathInC
:
str
,
postfix
:
str
=
""
,
returnPointer
:
bool
=
False
)
->
None
:
postfix
:
str
=
""
,
returnPointer
:
bool
=
False
)
->
None
:
takeAddr
=
'&'
if
returnPointer
else
''
g_outputGetSetH
.
write
(
"
\n
/* %s */
\n
%s %s_Get%s(%s);
\n
"
%
(
comment
,
ctype
,
path
,
postfix
,
params
.
GetDecl
()))
g_outputGetSetC
.
write
(
"
\n
/* %s */
\n
%s %s_Get%s(%s)
\n
"
%
(
comment
,
ctype
,
path
,
postfix
,
params
.
GetDecl
()))
...
...
@@ -324,7 +324,7 @@ def CommonBaseImplSequenceFixed(comment: str,
params
:
Params
,
_
:
str
,
node
:
Union
[
AsnSequenceOf
,
AsnSetOf
,
AsnString
],
postfix
:
str
=
""
)
->
None
:
postfix
:
str
=
""
)
->
None
:
g_outputGetSetH
.
write
(
"
\n
/* %s */
\n
%s %s_Get%s(%s);
\n
"
%
(
comment
,
ctype
,
path
,
postfix
,
params
.
GetDecl
()))
g_outputGetSetC
.
write
(
"
\n
/* %s */
\n
%s %s_Get%s(%s)
\n
"
%
(
comment
,
ctype
,
path
,
postfix
,
params
.
GetDecl
()))
g_outputGetSetC
.
write
(
"{
\n
"
)
...
...
@@ -408,6 +408,13 @@ def CreateGettersAndSetters(
for
child
in
node
.
_members
:
childNode
=
child
[
1
]
childVarname
=
CleanNameAsPythonWants
(
child
[
0
])
if
child
[
3
]:
# OPTIONAL field in a sequence
CreateGettersAndSetters
(
path
+
"_exist_"
+
childVarname
,
params
,
accessPathInC
+
union
+
".exist."
+
childVarname
,
AsnInt
(),
# exist field is an int
names
,
# ignored
leafTypeDict
)
# ignored
if
isinstance
(
childNode
,
AsnMetaMember
):
baseTypeOfChild
=
names
[
childNode
.
_containedType
].
_leafType
baseTypeOfChild
=
leafTypeDict
.
get
(
baseTypeOfChild
,
baseTypeOfChild
)
...
...
@@ -442,30 +449,30 @@ def DumpTypeDumper(
codeIndent
+
'lines.append("%s"+str(%s.Get()!=0).upper())'
%
(
outputIndent
,
variableName
))
if
variableName
.
startswith
(
"path[i]"
):
lines
.
append
(
codeIndent
+
'
self
.Reset(state)'
)
lines
.
append
(
codeIndent
+
'
path
.Reset(state)'
)
elif
isinstance
(
node
,
AsnInt
):
lines
.
append
(
codeIndent
+
'lines.append("%s"+str(%s.Get()))'
%
(
outputIndent
,
variableName
))
if
variableName
.
startswith
(
"path[i]"
):
lines
.
append
(
codeIndent
+
'
self
.Reset(state)'
)
lines
.
append
(
codeIndent
+
'
path
.Reset(state)'
)
elif
isinstance
(
node
,
AsnReal
):
lines
.
append
(
codeIndent
+
'lines.append("%s"+str(%s.Get()))'
%
(
outputIndent
,
variableName
))
if
variableName
.
startswith
(
"path[i]"
):
lines
.
append
(
codeIndent
+
'
self
.Reset(state)'
)
lines
.
append
(
codeIndent
+
'
path
.Reset(state)'
)
elif
isinstance
(
node
,
AsnString
):
lines
.
append
(
codeIndent
+
'lines.append("%s
\\\"
"+str(%s.GetPyString()) + "
\\\"
")'
%
(
outputIndent
,
variableName
))
if
variableName
.
startswith
(
"path[i]"
):
lines
.
append
(
codeIndent
+
'
self
.Reset(state)'
)
lines
.
append
(
codeIndent
+
'
path
.Reset(state)'
)
elif
isinstance
(
node
,
AsnEnumerated
):
mapping
=
str
({
val
:
name
for
name
,
val
in
node
.
_members
})
lines
.
append
(
codeIndent
+
'lines.append("%s"+%s[str(%s.Get())])'
%
(
outputIndent
,
mapping
,
variableName
))
if
variableName
.
startswith
(
"path[i]"
):
lines
.
append
(
codeIndent
+
'
self
.Reset(state)'
)
lines
.
append
(
codeIndent
+
'
path
.Reset(state)'
)
elif
isinstance
(
node
,
(
AsnChoice
,
AsnSet
,
AsnSequence
)):
if
not
isinstance
(
node
,
AsnChoice
):
lines
.
append
(
codeIndent
+
'lines.append("{")'
)
...
...
@@ -475,10 +482,14 @@ def DumpTypeDumper(
extraIndent
=
" "
for
idx
,
child
in
enumerate
(
node
.
_members
):
if
isinstance
(
node
,
AsnChoice
):
if
variableName
.
startswith
(
"path[i]"
):
lines
.
append
(
codeIndent
+
'path.Reset(state)'
)
# pragma: nocover
lines
.
append
(
codeIndent
+
'if %s.kind.Get() == DV.%s:'
%
(
variableName
,
CleanNameAsPythonWants
(
child
[
2
])))
if
variableName
.
startswith
(
"path[i]"
):
lines
.
append
(
codeIndent
+
' path.Reset(state)'
)
# pragma: nocover
sep
=
": "
elif
idx
>
0
:
# Separate fields with comas:
...
...
@@ -497,13 +508,15 @@ def DumpTypeDumper(
variableName
+
"."
+
CleanNameAsPythonWants
(
child
[
0
]),
childNode
,
names
)
if
not
isinstance
(
node
,
AsnChoice
):
lines
.
append
(
codeIndent
+
'lines.append("}")'
)
if
variableName
.
startswith
(
"path[i]"
):
lines
.
append
(
codeIndent
+
'path.Reset(state)'
)
elif
isinstance
(
node
,
(
AsnSetOf
,
AsnSequenceOf
)):
lines
.
append
(
codeIndent
+
'lines.append("{")'
)
containedNode
=
node
.
_containedType
if
isinstance
(
containedNode
,
str
):
containedNode
=
names
[
containedNode
]
lines
.
append
(
codeIndent
+
'def emitElem(path, i):'
)
lines
.
append
(
codeIndent
+
' state =
self
.GetState()'
)
lines
.
append
(
codeIndent
+
' state =
path
.GetState()'
)
lines
.
append
(
codeIndent
+
' if i > 0:'
)
lines
.
append
(
codeIndent
+
' lines.append(",")'
)
DumpTypeDumper
(
codeIndent
+
" "
,
...
...
@@ -562,7 +575,7 @@ def CreateDeclarationForType(nodeTypename: str, names: AST_Lookup, leafTypeDict:
panic
(
"Unexpected ASN.1 type... Send this grammar to ESA"
)
# pragma: no cover
def
CreateDeclarationsForAllTypes
(
names
:
AST_Lookup
,
leafTypeDict
:
AST_Leaftypes
,
badTypes
:
SetOfBadTypenames
)
->
None
:
def
CreateDeclarationsForAllTypes
(
names
:
AST_Lookup
,
leafTypeDict
:
AST_Leaftypes
,
unused_
badTypes
:
SetOfBadTypenames
)
->
None
:
for
nodeTypename
in
names
:
# Do not ignore the so called "bad types". In python, IA5Strings are supported
if
not
names
[
nodeTypename
].
_isArtificial
:
# and nodeTypename not in badTypes:
...
...
dmt/B_mappers/pyside_B_mapper.py
View file @
b8b94ff1
...
...
@@ -175,7 +175,9 @@ editor = None
global
g_firstElem
g_firstElem
=
True
buttons
=
[]
# type: List[List[str]]
# buttons = [] # type: List[List[str]]
buttons
=
([[
"plotButton"
,
"Plot"
],
[
"meterButton"
,
"Meter"
],
[
"unusedButton"
,
"Unused"
]])
# RI = TC (Telecommand), PI = TM (Telemetry)
if
modelingLanguage
.
lower
()
==
'gui_ri'
:
g_BackendFile
.
write
(
'''
...
...
@@ -223,7 +225,8 @@ def setSharedLib(dll=None):
buttons
=
([[
"sendButton"
,
"Send TC"
],
[
"loadButton"
,
"Load TC"
],
[
"saveButton"
,
"Save TC"
]])
classType
=
"asn1Editor"
elif
modelingLanguage
.
lower
()
==
'gui_pi'
:
else
:
assert
modelingLanguage
.
lower
()
==
'gui_pi'
g_BackendFile
.
write
(
'''
tmId = -1
...
...
@@ -364,7 +367,7 @@ def checkConstraints(asnVal):
def encode_ACN(asnVal):
\'\'\'
Enco
r
e the native Asn1Scc structure in ACN
\'\'\'
\'\'\'
Enco
d
e the native Asn1Scc structure in ACN
\'\'\'
# Check the ASN.1 constraints:
if not checkConstraints(asnVal):
...
...
@@ -546,7 +549,10 @@ def WriteCodeForGUIControls(prefixes: List[str], # pylint: disable=invalid-sequ
param
:
Param
,
leafTypeDict
:
AST_Leaftypes
,
names
:
AST_Lookup
,
nodeTypename
:
str
=
''
)
->
None
:
nodeTypename
:
str
=
''
,
isOptional
:
bool
=
False
,
alwaysPresent
:
bool
=
False
,
alwaysAbsent
:
bool
=
False
)
->
None
:
global
g_firstElem
global
g_onceOnly
global
g_asnId
...
...
@@ -574,43 +580,44 @@ def WriteCodeForGUIControls(prefixes: List[str], # pylint: disable=invalid-sequ
if
len
(
parentControl
)
>=
i
:
pyStr
+=
"[{index}]"
.
format
(
index
=
parentControl
[
i
-
1
])
for
item
in
prefixes
[
i
][
len
(
prefixes
[
i
-
1
]):].
split
(
'.'
):
if
len
(
item
)
>
0
:
if
item
:
pyStr
+=
'''["{prefixKey}"]'''
.
format
(
prefixKey
=
item
)
if
isinstance
(
node
,
(
AsnInt
,
AsnReal
,
AsnOctetString
)):
if
isinstance
(
node
,
AsnInt
):
if
g_onceOnly
:
g_PyDataModel
.
write
(
'''{'nodeTypename': '%s', 'type': '%s', 'id': '%s', 'minR': %d, 'maxR': %d}'''
%
(
nodeTypename
,
node
.
_name
,
txtPrefix
,
'''{'nodeTypename': '%s', 'type': '%s', 'id': '%s',
'isOptional': %s, 'alwaysPresent': %s, 'alwaysAbsent': %s,
'minR': %d, 'maxR': %d}'''
%
(
nodeTypename
,
node
.
_name
,
txtPrefix
,
isOptional
,
alwaysPresent
,
alwaysAbsent
,
node
.
_range
[
0
],
node
.
_range
[
1
]))
elif
isinstance
(
node
,
AsnReal
):
if
g_onceOnly
:
g_PyDataModel
.
write
(
'''{'nodeTypename': '%s', 'type': '%s', 'id': '%s', 'minR': %f, 'maxR': %f}'''
%
(
nodeTypename
,
node
.
_name
,
txtPrefix
,
'''{'nodeTypename': '%s', 'type': '%s', 'id': '%s',
'isOptional': %s, 'alwaysPresent': %s, 'alwaysAbsent': %s,
'minR': %
20.20
f, 'maxR': %
20.20
f}'''
%
(
nodeTypename
,
node
.
_name
,
txtPrefix
,
isOptional
,
alwaysPresent
,
alwaysAbsent
,
node
.
_range
[
0
],
node
.
_range
[
1
]))
elif
isinstance
(
node
,
AsnOctetString
):
if
g_onceOnly
:
g_PyDataModel
.
write
(
'''{'nodeTypename': '%s', 'type': 'STRING', 'id': '%s', 'minSize': %d, 'maxSize': %d}'''
%
(
nodeTypename
,
txtPrefix
,
node
.
_range
[
0
],
node
.
_range
[
1
]))
'''{'nodeTypename': '%s', 'type': 'STRING', 'id': '%s', 'isOptional': %s, 'alwaysPresent': %s, 'alwaysAbsent': %s, 'minSize': %d, 'maxSize': %d}'''
%
(
nodeTypename
,
txtPrefix
,
isOptional
,
alwaysPresent
,
alwaysAbsent
,
node
.
_range
[
0
],
node
.
_range
[
1
]))
elif
isinstance
(
node
,
AsnBool
):
if
g_onceOnly
:
g_PyDataModel
.
write
(
'''{'nodeTypename': '%s', 'type': '%s', 'id': '%s', 'default': 'False'}'''
%
(
nodeTypename
,
node
.
_name
,
txtPrefix
))
'''{'nodeTypename': '%s', 'type': '%s', 'id': '%s',
'isOptional': %s, 'alwaysPresent': %s, 'alwaysAbsent': %s,
'default': 'False'}'''
%
(
nodeTypename
,
node
.
_name
,
txtPrefix
,
isOptional
,
alwaysPresent
,
alwaysAbsent
))
elif
isinstance
(
node
,
AsnEnumerated
):
if
g_onceOnly
:
global
g_needsComa
g_needsComa
=
False
g_PyDataModel
.
write
(
'''{'nodeTypename': '%s', 'type': '%s', 'id': '%s', 'values':['''
%
(
nodeTypename
,
node
.
_name
,
txtPrefix
))
'''{'nodeTypename': '%s', 'type': '%s', 'id': '%s',
'isOptional': %s, 'alwaysPresent': %s, 'alwaysAbsent': %s,
'values':['''
%
(
nodeTypename
,
node
.
_name
,
txtPrefix
,
isOptional
,
alwaysPresent
,
alwaysAbsent
))
values
=
[]
valuesmap
=
[]
for
enum_value
in
node
.
_members
:
...
...
@@ -623,11 +630,11 @@ def WriteCodeForGUIControls(prefixes: List[str], # pylint: disable=invalid-sequ
elif
isinstance
(
node
,
(
AsnSequence
,
AsnChoice
,
AsnSet
)):
if
g_onceOnly
:
g_PyDataModel
.
write
(
'''{'nodeTypename': '%s', 'type': '%s', 'id': '%s', '''
%
(
nodeTypename
,
node
.
_name
,
txtPrefix
))
'''{'nodeTypename': '%s', 'type': '%s', 'id': '%s',
'isOptional': %s, 'alwaysPresent': %s, 'alwaysAbsent': %s,
'''
%
(
nodeTypename
,
node
.
_name
,
txtPrefix
,
isOptional
,
alwaysPresent
,
alwaysAbsent
))
if
isinstance
(
node
,
AsnChoice
):
g_PyDataModel
.
write
(
'''"choices":['''
)
elif
isinstance
(
node
,
AsnSequence
)
or
isinstance
(
node
,
AsnSet
):
elif
isinstance
(
node
,
(
AsnSequence
,
AsnSet
)
)
:
g_PyDataModel
.
write
(
'''"children":['''
)
# Recurse on children
if
node
.
_members
:
...
...
@@ -639,15 +646,25 @@ def WriteCodeForGUIControls(prefixes: List[str], # pylint: disable=invalid-sequ
for
child
in
node
.
_members
:
# child[0] is the name of the field
# child[2] is the string "field_PRESENT" used for choice indexes
# child[3] is the field optionality status
# child[4] is the "alwaysPresent" status (when child[3] is True)
# child[5] is the "alwaysAbsent" status (when child[3] is True)
CleanChild
=
CleanName
(
child
[
0
])
childType
=
child
[
1
]
isOptional
=
child
[
3
]
alwaysPresent
=
child
[
4
]
alwaysAbsent
=
child
[
5
]
# print(CleanChild + " optional: "+ str(isOptional) + " always Present: " + str(alwaysPresent) + " always absent: " + str(alwaysAbsent))
if
isinstance
(
childType
,
AsnMetaMember
):
childType
=
names
[
childType
.
_containedType
]
seqPrefix
=
prefixes
[
-
1
]
prefixes
[
-
1
]
=
prefixes
[
-
1
]
+
"."
+
CleanChild
WriteCodeForGUIControls
(
prefixes
,
parentControl
,
childType
,
subProgram
,
subProgramImplementation
,
param
,
leafTypeDict
,
names
)
param
,
leafTypeDict
,
names
,
isOptional
=
isOptional
,
alwaysPresent
=
alwaysPresent
,
alwaysAbsent
=
alwaysAbsent
)
prefixes
[
-
1
]
=
seqPrefix
if
g_onceOnly
:
if
isinstance
(
node
,
AsnChoice
):
...
...
@@ -664,8 +681,8 @@ def WriteCodeForGUIControls(prefixes: List[str], # pylint: disable=invalid-sequ
elif
isinstance
(
node
,
(
AsnSequenceOf
,
AsnSetOf
)):
if
g_onceOnly
:
g_PyDataModel
.
write
(
"{'nodeTypename': '%s', 'type': 'SEQOF', 'id': '%s', 'minSize': %d, 'maxSize': %d, 'seqoftype':"
%
(
nodeTypename
,
txtPrefix
,
node
.
_range
[
0
],
node
.
_range
[
1
]))
"{'nodeTypename': '%s', 'type': 'SEQOF', 'id': '%s',
'isOptional': %s, 'alwaysPresent': %s, 'alwaysAbsent': %s,
'minSize': %d, 'maxSize': %d, 'seqoftype':"
%
(
nodeTypename
,
txtPrefix
,
isOptional
,
alwaysPresent
,
alwaysAbsent
,
node
.
_range
[
0
],
node
.
_range
[
1
]))
containedNode
=
node
.
_containedType
if
isinstance
(
containedNode
,
str
):
containedNode
=
names
[
containedNode
]
...
...
dmt/commonPy/asnAST.py
View file @
b8b94ff1
...
...
@@ -62,18 +62,40 @@
# | | | |
# | +----------------+ |
# +-----------------------------+ ^ |
# | AsnEnumerated | | +------------------------+
# |-----------------------------| | | AsnSequenceOf/AsnSetOf |
# | _members list:(name, value) | | |------------------------|
# +-----------------------------+ | | _containedType |
# +-----------------------------+ | value: string, |
# | AsnSequence/AsnSet | | AsnBasicNode, |
# |-----------------------------| | AsnEnumerated |
# | _members list:(name, value) | +------------------------+
# | value: AsnBasicNode, |
# | AsnEnumerated, |
# | AsnMetaMember |
# +-----------------------------+
# | AsnEnumerated | | +------------------------+
# |-----------------------------| | | AsnSequenceOf/AsnSetOf |
# | _members list:(name, value) | | |------------------------|
# +-----------------------------+ | | _containedType |
# +------------------------------------+ | value: string, |
# | AsnSequence/AsnSet/AsnChoice | | AsnBasicNode, |
# |------------------------------------| | AsnEnumerated |
# | _members list:(name, value, ... | +------------------------+
# | value: AsnBasicNode, |
# | AsnEnumerated, |
# | AsnMetaMember |
# | en: the EnumID from ASN1SCC |
# | op: the OPTIONAL-ity status |
# | alwaysPresent: bool [1] |
# | alwaysAbsent: bool [1] |
# +------------------------------------+
#
# [1] The alwaysAbsent/Present are additions made in Oct/2018 to accomodate
# the complex interactions between OPTIONAL and WITH COMPONENTS.
# Maxime described it to me as follows:
#
# "The use case is two-fold - for SEQUENCE :
#
# MySeq ::= MyOtherSeq (WITH COMPONENTS {..., b ABSENT })
#
# ...and for CHOICE:
#
# AllPossibleTC ::= CHOICE {
# tc-6-1 ..,
# tc-5-4 , .....}
# TC-Subset ::= AllPossibleTC (WITH COMPONENTS {tc-6-1 ABSENT})
#
# So alwaysPresent is NOT the negative of alwaysPresent:
# a field can be optional, OR always present, OR always absent
from
typing
import
List
,
Union
,
Dict
,
Any
# NOQA pylint: disable=unused-import
...
...
@@ -84,7 +106,7 @@ AsnSequenceOrSet = Union['AsnSequence', 'AsnSet']
AsnSequenceOrSetOf
=
Union
[
'AsnSequenceOf'
,
'AsnSetOf'
]
class
AsnNode
(
object
)
:
class
AsnNode
:
def
__init__
(
self
,
asnFilename
:
str
)
->
None
:
self
.
_leafType
=
"unknown"
...
...
@@ -95,7 +117,7 @@ class AsnNode(object):
def
Location
(
self
)
->
str
:
return
"file %s, line %d"
%
(
self
.
_asnFilename
,
int
(
self
.
_lineno
))
# pragma: no cover
def
IdenticalPerSMP2
(
self
,
other
:
'AsnNode'
,
mynames
:
Lookup
,
othernames
:
Lookup
)
->
bool
:
# pylint: disable=no-self-use
def
IdenticalPerSMP2
(
self
,
unused_
other
:
'AsnNode'
,
unused_
mynames
:
Lookup
,
unused_
othernames
:
Lookup
)
->
bool
:
# pylint: disable=no-self-use
utility
.
panic
(
"internal error: Must be defined in derived class..."
)
def
AsASN1
(
self
,
_
:
Lookup
)
->
str
:
# pylint: disable=no-self-use
...
...
@@ -145,7 +167,7 @@ Members:
self
.
_leafType
=
"BOOLEAN"
self
.
_lineno
=
args
.
get
(
'lineno'
,
None
)
self
.
_bDefaultValue
=
args
.
get
(
'bDefaultValue'
,
None
)
for
i
in
args
.
keys
()
:
for
i
in
args
:
assert
i
in
AsnBool
.
validOptions
def
__repr__
(
self
)
->
str
:
...
...
@@ -154,7 +176,7 @@ Members:
result
+=
", default value "
+
self
.
_bDefaultValue
# pragma: no cover
return
result
def
IdenticalPerSMP2
(
self
,
other
:
AsnNode
,
mynames
:
Lookup
,
othernames
:
Lookup
)
->
bool
:
# pylint: disable=no-self-use
def
IdenticalPerSMP2
(
self
,
other
:
AsnNode
,
unused_
mynames
:
Lookup
,
unused_
othernames
:
Lookup
)
->
bool
:
# pylint: disable=no-self-use
return
isinstance
(
other
,
AsnBool
)
def
AsASN1
(
self
,
_
:
Lookup
)
->
str
:
...
...
@@ -178,7 +200,7 @@ Members:
self
.
_lineno
=
args
.
get
(
'lineno'
,
None
)
self
.
_range
=
args
.
get
(
'range'
,
[])
self
.
_iDefaultValue
=
args
.
get
(
'iDefaultValue'
,
None
)
for
i
in
args
.
keys
()
:
for
i
in
args
:
assert
i
in
AsnInt
.
validOptions
def
__repr__
(
self
)
->
str
:
...
...
@@ -189,7 +211,7 @@ Members:
result
+=
" with default value of %s"
%
self
.
_iDefaultValue
# pragma: no cover
return
result
def
IdenticalPerSMP2
(
self
,
other
:
AsnNode
,
mynames
:
Lookup
,
othernames
:
Lookup
)
->
bool
:
# pylint: disable=no-self-use
def
IdenticalPerSMP2
(
self
,
other
:
AsnNode
,
unused_
mynames
:
Lookup
,
unused_
othernames
:
Lookup
)
->
bool
:
# pylint: disable=no-self-use
return
isinstance
(
other
,
AsnInt
)
and
CommonIdenticalRangePerSMP2
(
self
.
_range
,
other
.
_range
)
def
AsASN1
(
self
,
_
:
Lookup
)
->
str
:
...
...
@@ -224,7 +246,7 @@ Members:
self
.
_baseRange
=
args
.
get
(
'base'
,
None
)
self
.
_exponentRange
=
args
.
get
(
'exponent'
,
None
)
self
.
_dbDefaultValue
=
args
.
get
(
'defaultValue'
,
None
)
for
i
in
args
.
keys
()
:
for
i
in
args
:
assert
i
in
AsnReal
.
validOptions
def
__repr__
(
self
)
->
str
:
...
...
@@ -246,7 +268,7 @@ Members:
result
+=
" within [%s,%s]"
%
(
self
.
_range
[
0
],
self
.
_range
[
1
])
return
result
def
IdenticalPerSMP2
(
self
,
other
:
AsnNode
,
mynames
:
Lookup
,
othernames
:
Lookup
)
->
bool
:
# pylint: disable=no-self-use
def
IdenticalPerSMP2
(
self
,
other
:
AsnNode
,
unused_
mynames
:
Lookup
,
unused_
othernames
:
Lookup
)
->
bool
:
# pylint: disable=no-self-use
return
isinstance
(
other
,
AsnReal
)
and
CommonIdenticalRangePerSMP2
(
self
.
_range
,
other
.
_range
)
def
AsASN1
(
self
,
_
:
Lookup
)
->
str
:
...
...
@@ -274,7 +296,7 @@ Members:
# nameless string types can't be used, so a unique pseudo-type name
# is created from the fieldname + "_type"
self
.
_pseudoname
=
None
# type: Union[None, str]
for
i
in
args
.
keys
()
:
for
i
in
args
:
assert
i
in
AsnString
.
validOptions
def
__repr__
(
self
)
->
str
:
...
...
@@ -284,7 +306,7 @@ Members:
result
+=
str
(
self
.
_range
)
return
result
def
IdenticalPerSMP2
(
self
,
other
:
AsnNode
,
mynames
:
Lookup
,
othernames
:
Lookup
)
->
bool
:
# pylint: disable=no-self-use
def
IdenticalPerSMP2
(
self
,
other
:
AsnNode
,
unused_
mynames
:
Lookup
,
unused_
othernames
:
Lookup
)
->
bool
:
# pylint: disable=no-self-use
return
isinstance
(
other
,
AsnString
)
and
CommonIdenticalRangePerSMP2
(
self
.
_range
,
other
.
_range
)
def
AsASN1
(
self
,
_
:
Lookup
)
->
str
:
...
...
@@ -387,7 +409,7 @@ Members:
# nameless string types can't be used, so a unique pseudo-type name
# is created from the fieldname + "_type"
self
.
_pseudoname
=
None
# type: Union[None, str]
for
i
in
args
.
keys
()
:
for
i
in
args
:
assert
i
in
AsnEnumerated
.
validOptions
existing
=
{}
# type: Dict[str, int]
for
elem
in
self
.
_members
:
...
...
@@ -407,7 +429,7 @@ Members:
result
+=
str
(
member
)
return
result
def
IdenticalPerSMP2
(
self
,
other
:
AsnNode
,
mynames
:
Lookup
,
othernames
:
Lookup
)
->
bool
:
# pylint: disable=no-self-use
def
IdenticalPerSMP2
(
self
,
other
:
AsnNode
,
unused_
mynames
:
Lookup
,
unused_
othernames
:
Lookup
)
->
bool
:
# pylint: disable=no-self-use
return
isinstance
(
other
,
AsnEnumerated
)
and
sorted
(
self
.
_members
)
==
sorted
(
other
.
_members
)
def
AsASN1
(
self
,
_
:
Lookup
)
->
str
:
...
...
@@ -461,8 +483,12 @@ This class stores the semantic content of an ASN.1 SEQUENCE.
Members:
_name : the name of the type
_members : a tuple of all child elements. Each tuple contains
two elements: the name of the variable and the
type itself (as an AsnInt, AsnReal, ... or an AsnMetaMember).
many elements: the name of the variable, the type itself
(as an AsnInt, AsnReal, ... or an AsnMetaMember),
an optionality boolean (true mean OPTIONAL),
and two more booleans to indicate alwaysAbsent
and alwaysPresent semantics. See comment at the
top diagram for more info.
'''
validOptions
=
[
'members'
,
'lineno'
,
'asnFilename'
]
...
...
@@ -472,7 +498,7 @@ Members:
self
.
_leafType
=
"SEQUENCE"
self
.
_members
=
args
.
get
(
'members'
,
[])
self
.
_lineno
=
args
.
get
(
'lineno'
,
None
)
for
i
in
args
.
keys
()
:
for
i
in
args
:
assert
i
in
AsnSequence
.
validOptions
existing
=
{}
# type: Dict[str, int]
for
elem
in
self
.
_members
:
...
...
@@ -499,7 +525,7 @@ Members:
isinstance
(
other
,
(
AsnSet
,
AsnSequence
,
AsnChoice
))
and
\
CommonIdenticalCheck
(
self
,
other
,
mynames
,
othernames
)
def
AsASN1
(
self
,
typeDict
:
Lookup
=
None
)
->
str
:
def
AsASN1
(
self
,
typeDict
:
Lookup
=
None
)
->
str
:
if
typeDict
is
None
:
typeDict
=
{}
return
CommonAsASN1
(
'SEQUENCE'
,
self
,
typeDict
)
...
...
@@ -513,7 +539,7 @@ class AsnSet(AsnComplexNode):
self
.
_leafType
=
"SET"
self
.
_members
=
args
.
get
(
'members'
,
[])
self
.
_lineno
=
args
.
get
(
'lineno'
,
None
)
for
i
in
args
.
keys
()
:
for
i
in
args
:
assert
i
in
AsnSequence
.
validOptions
existing
=
{}
# type: Dict[str, int]
for
elem
in
self
.
_members
:
...
...
@@ -540,7 +566,7 @@ class AsnSet(AsnComplexNode):
isinstance
(
other
,
(
AsnSet
,
AsnSequence
,
AsnChoice
))
and
\
CommonIdenticalCheck
(
self
,
other
,
mynames
,
othernames
)
def
AsASN1
(
self
,
typeDict
:
Lookup
=
None
)
->
str
:
def
AsASN1
(
self
,
typeDict
:
Lookup
=
None
)
->
str
:
if
typeDict
is
None
:
typeDict
=
{}
return
CommonAsASN1
(
'SET'
,
self
,
typeDict
)
...
...
@@ -563,7 +589,7 @@ Members:
self
.
_leafType
=
"CHOICE"
self
.
_members
=
args
.
get
(
'members'
,
[])
self
.
_lineno
=
args
.
get
(
'lineno'
,
None
)
for
i
in
args
.
keys
()
:
for
i
in
args
:
assert
i
in
AsnChoice
.
validOptions
existing
=
{}
# type: Dict[str, int]
for
elem
in
self
.
_members
:
...
...
@@ -586,7 +612,7 @@ Members:
def
IdenticalPerSMP2
(
self
,
other
:
AsnNode
,
mynames
:
Lookup
,
othernames
:
Lookup
)
->
bool
:
return
isinstance
(
other
,
AsnChoice
)
and
CommonIdenticalCheck
(
self
,
other
,
mynames
,
othernames
)
def
AsASN1
(
self
,
typeDict
:
Lookup
=
None
)
->
str
:
def
AsASN1
(
self
,
typeDict
:
Lookup
=
None
)
->
str
:
if
typeDict
is
None
:
typeDict
=
{}
return
CommonAsASN1
(
'CHOICE'
,
self
,
typeDict
)
...
...
@@ -642,7 +668,7 @@ Members:
self
.
_lineno
=
args
.
get
(
'lineno'
,
None
)
self
.
_name
=
"unnamed"
# default in case of SEQUENCE_OF SEQUENCE_OF
self
.
_leafType
=
"SEQUENCEOF"
for
i
in
args
.
keys
()
:
for
i
in
args
:
assert
i
in
AsnSequenceOf
.
validOptions
def
__repr__
(
self
)
->
str
:
...
...
@@ -660,7 +686,7 @@ Members:
isinstance
(
other
,
(
AsnSequenceOf
,
AsnSetOf
))
and
\
CommonIdenticalArrayCheck
(
self
,
other
,
mynames
,
othernames
)
def
AsASN1
(
self
,
typeDict
:
Lookup
=
None
)
->
str
:
def
AsASN1
(
self
,
typeDict
:
Lookup
=
None
)
->
str
:
if
typeDict
is
None
:
typeDict
=
{}
return
CommonAsASN1array
(
'SEQUENCE'
,
self
,
typeDict
)
...
...
@@ -675,7 +701,7 @@ class AsnSetOf(AsnComplexNode):
self
.
_lineno
=
args
.
get
(
'lineno'
,
None
)
self
.
_name
=
"unnamed"
# default in case of SEQUENCE_OF SEQUENCE_OF
self
.
_leafType
=
"SETOF"
for
i
in
args
.
keys
()
:
for
i
in
args
:
assert
i
in
AsnSequenceOf
.
validOptions
def
__repr__
(
self
)
->
str
:
...
...
@@ -693,7 +719,7 @@ class AsnSetOf(AsnComplexNode):
isinstance
(
other
,
(
AsnSequenceOf
,
AsnSetOf
))
and
\
CommonIdenticalArrayCheck
(
self
,
other
,
mynames
,
othernames
)
def
AsASN1
(
self
,
typeDict
:
Lookup
=
None
)
->
str
:
def
AsASN1
(
self
,
typeDict
:
Lookup
=
None
)
->
str
:
if
typeDict
is
None
:
typeDict
=
{}
return
CommonAsASN1array
(
'SET'
,
self
,
typeDict
)
...
...
@@ -715,7 +741,7 @@ Members:
self
.
_lineno
=
args
.
get
(
'lineno'
,
None
)
self
.
_Min
=
args
.
get
(
'Min'
,
None
)
self
.
_Max
=
args
.
get
(
'Max'
,
None
)
for
i
in
args
.
keys
()
:
for
i
in
args
:
assert
i
in
AsnMetaMember
.
validOptions
def
__repr__
(
self
)
->
str
:
...
...
@@ -747,7 +773,7 @@ e.g.:
self
.
_lineno
=
args
.
get
(
'lineno'
,
None
)
self
.
_Min
=
args
.
get
(
'Min'
,
None
)
self
.
_Max
=
args
.
get
(
'Max'
,
None
)
for
i
in
args
.
keys
()
:
for
i
in
args
:
assert
i
in
AsnMetaType
.
validOptions
def
__repr__
(
self
)
->
str
:
...
...
dmt/commonPy/asnParser.py
View file @
b8b94ff1
...
...
@@ -45,12 +45,15 @@ ASN.1 Parser
This module parses ASN.1 grammars and creates an abstract syntax tree (AST)
inside configMT.inputCodeAST, for use with the code generators.
'''
# pylint: disable=too-many-lines
import
os
import
sys
import
copy
import
tempfile
import
re
import
distutils
.spawn
as
spawn
from
distutils
import
spawn
import
hashlib
import
xml.sax
# type: ignore
...
...
@@ -236,7 +239,7 @@ def VerifyAndFixAST() -> Dict[str, str]:
if
lastEquivalents
==
equivalents
and
lastKnownTypes
==
knownTypes
and
lastUnknownTypes
==
unknownTypes
:
break
if
len
(
unknownTypes
)
!=
0
:
if
unknownTypes
:
utility
.
panic
(
'AsnParser: Types remain unknown after symbol fixup:
\n
%s
\n
'
%
list
(
unknownTypes
.
keys
()))
# Remove all AsnMetaTypes from the ast
...
...
@@ -384,7 +387,7 @@ def CheckForInvalidKeywords(node_or_str: Union[str, AsnNode]) -> None:
def
ParseAsnFileList
(
listOfFilenames
:
List
[
str
])
->
None
:
# pylint: disable=invalid-sequence-index
# Add basic ASN.1 caching to avoid calling the ASN.1 compiler over and over
projectCache
=
os
.
getenv
(
"PROJECT_CACHE"
)
projectCache
=
os
.
getenv
(
"PROJECT_CACHE"
)
if
projectCache
is
not
None
and
not
os
.
path
.
isdir
(
projectCache
):
utility
.
panic
(
"The configured cache folder:
\n\n\t
"
+
projectCache
+
"
\n\n
...is not there!
\n
"
)
...
...
@@ -401,7 +404,7 @@ def ParseAsnFileList(listOfFilenames: List[str]) -> None: # pylint: disable=inv
filehash
.
update
(
each
.
encode
(
'utf-8'
))
newHash
=
filehash
.
hexdigest
()
# set the name of the XML files containing the dumped ASTs
xmlAST
=
projectCache
+
os
.
sep
+
newHash
+
"_ast_v4.xml"
xmlAST
=
projectCache
+
os
.
sep
+
newHash
+
"_ast_v4.xml"
xmlAST2
=
projectCache
+
os
.
sep
+
newHash
+
"_ast_v1.xml"
if
not
os
.
path
.
exists
(
xmlAST
)
or
not
os
.
path
.
exists
(
xmlAST2
):
someFilesHaveChanged
=
True
...
...
@@ -499,7 +502,7 @@ class Element:
class
InputFormatXMLHandler
(
xml
.
sax
.
ContentHandler
):
# type: ignore
def
__init__
(
self
,
debug
:
bool
=
False
)
->
None
:
def
__init__
(
self
,
debug
:
bool
=
False
)
->
None
:
xml
.
sax
.
ContentHandler
.
__init__
(
self
)
# type: ignore
self
.
_debug
=
False
if
debug
:
...
...
@@ -695,7 +698,7 @@ def CommonSetSeqOf(newModule: Module, lineNo: int, xmlSequenceOfNode: Element, c
if
xmlType
is
None
:
utility
.
panic
(
"CommonSetSeqOf: No child under SequenceOfType (%s, %s)"
%
# pragma: no cover
(
newModule
.
_asnFilename
,
lineNo
))
# pragma: no cover
if
len
(
xmlType
.
_children
)
==
0
:
if
len
(
xmlType
.
_children
)
==
0
:
# pylint: disable=len-as-condition
utility
.
panic
(
"CommonSetSeqOf: No children for Type (%s, %s)"
%
# pragma: no cover
(
newModule
.
_asnFilename
,
lineNo
))
# pragma: no cover
if
xmlType
.
_children
[
0
].
_name
==
"ReferenceType"
:
...
...
@@ -735,11 +738,15 @@ def CommonSeqSetChoice(
for
x
in
xmlSequenceNode
.
_children
:
if
x
.
_name
==
childTypeName
:
opti
=
GetAttr
(
x
,
"Optional"
)
bAlwaysPresent
=
GetAttr
(
x
,
"bAlwaysPresent"
)
bAlwaysAbsent
=
GetAttr
(
x
,
"bAlwaysAbsent"
)
if
opti
and
opti
==
"True"
: