Commits (5)
......@@ -6,7 +6,7 @@ This directory contains the code for the ASN.1 Value editor:
** WARNING **
This version is different than the one present in the old Subversion repos
It contains a setup.py and is meant to be installed using the Python way:
$ sudo make install
This command will update the Qt resource file and call: python setup.py install --record
......@@ -32,3 +32,5 @@ Author: Maxime Perrotin
LICENSE: LGPL - see LICENSE file
CHANGELOG:
1.0.7 - fixed bug in value notation parser
......@@ -16,7 +16,7 @@
__author__ = "Maxime Perrotin"
__license__ = "LGPLv3"
__version__ = "1.0.6"
__version__ = "1.0.7"
__url__ = "http://taste.tuxfamily.org"
import sys
......@@ -39,12 +39,14 @@ ASN1TYPE = Qt.UserRole
class myTextEdit(QTextEdit):
''' Customized text editor that contains a context menu for loading data from a file '''
''' Customized text editor that contains a context menu for loading
data from a file '''
def __init__(self, parent=None):
super(myTextEdit, self).__init__(parent)
def contextMenuEvent(self, event):
''' When the context menu is open, add the Load from file action and open the menu '''
''' When the context menu is open, add the Load from file action
and open the menu '''
myMenu = self.createStandardContextMenu()
myAction = 'Load data from file'
myMenu.addAction(myAction)
......@@ -416,10 +418,10 @@ class asn1Editor(QTreeView):
elif asnType == 'ENUMERATED':
child.setText(value['Enum'])
elif asnType in ('SEQUENCE', 'SET'):
self.updateModel(root.child(i), value) # update recursively
self.updateModel(root.child(i), value) # update recursively
elif asnType == 'CHOICE':
child.setText(str(value['Choice']))
self.updateModel(root.child(i), value) # update recursively
self.updateModel(root.child(i), value) # update recursively
elif asnType == 'SEQOF':
child.setText(str(len(value)))
self.updateModel(root.child(i), value, len(value))
......
......@@ -368,6 +368,8 @@ class sdlHandler(QObject):
# Build up the list of states, including state compositions
context = self.proc
# get the list of state aggregations
aggregates = opengeode.Helper.state_aggregations(context)
get_statenames = lambda c: [CleanName(s) for s in c.mapping.viewkeys()
if not s.endswith(u'START')]
......@@ -385,8 +387,22 @@ class sdlHandler(QObject):
states = {'id': 'Current SDL state', 'type': 'ENUMERATED',
'values': list(statenames)}
self.tree_items['_states'] = self.asn1_editor.setAsn1Model(states, row)
if aggregates:
statenames.append('(not in state)')
# Add state variables for parelle states in aggregations
for agg, substates in aggregates.viewitems():
for each in substates:
row += 1
states = {'id': 'Substate {}.{}'.format(CleanName(agg),
each.statename),
'type': 'ENUMERATED',
'values': list(statenames)}
self.tree_items['substate_{}'.format(each.statename)] = \
self.asn1_editor.setAsn1Model(states, row)
# Add the SDL variables to the ASN.1 editor
row = 1
row += 1
for var, (sort, _) in self.proc.variables.viewitems():
item = asn1sccToasn1ValueEditorTypes(self.proc.dataview, var, sort)
self.tree_items[var] = self.asn1_editor.setAsn1Model(item, row)
......@@ -509,7 +525,7 @@ class sdlHandler(QObject):
''' Called when the undo button is pressed '''
self.undo_stack.undo()
self.check_state()
self.current_hash = self.on_event()
self.current_hash = self.on_event(check_ppty=False)
self.msc_undo.emit()
def redo(self):
......@@ -574,7 +590,7 @@ class sdlHandler(QObject):
undo_cmd = SendTC(self, old_state)
self.undo_stack.push(undo_cmd)
def on_event(self, tc_name=None, param=None):
def on_event(self, tc_name=None, param=None, check_ppty=True):
''' Read the values of internal variables in the dll, update the gui
accordingly (in the "global state" panel), and depending on the
current SDL state, enable/disable the buttons for sending TCs.
......@@ -629,6 +645,9 @@ class sdlHandler(QObject):
# Log all TC sent
self.log_area.addItem('Sent {}({})'.format(tc_name,
param or ''))
if check_ppty:
# When doing undo, dont check propertis again
self.check_properties(new_hash)
self.check_properties(new_hash)
return new_hash
......@@ -743,6 +762,7 @@ class sdlHandler(QObject):
print 'Exhaustive simulation (Breadth first)'
next_level = []
self.sim_param['state'] = 'exhaustive'
total_err = 0
def exhaust_interface(name, asn1_ty):
''' Send all combinations of an input signal and return
......@@ -778,10 +798,11 @@ class sdlHandler(QObject):
typename = sort.ReferencedTypeName.replace('-', '_')
ty = self.proc.dataview[sort.ReferencedTypeName]
next_states, error_count = exhaust_interface(name, ty)
total_err += error_count
next_level.extend(next_states)
print 'length of next level: ', len(next_level)
print 'Number of stop conditions reached:', error_count
print 'Number of stop conditions reached:', total_err
def random_simulation(self):
''' Random simulator - read the config from the checker_table and
......
......@@ -10,7 +10,6 @@
Parse a string containing an ASN.1 value expressed in GSER
(also called ASN.1 Value Notation) and return a Python structure that
is compatible with the widget of the ASN.1 Value Editor
Copyright (c) 2012-2015 European Space Agency
2) toASN1ValueNotation(val)
Does the reverse (from Qt widget to ASN.1 Value Notation/GSER)
......@@ -119,14 +118,12 @@ value = (BitStringLiteral
namedValue = identifier + value
# ASN.1 CHOICE
choiceValue << (identifier + ':' + value).setResultsName('CHOICE')
choiceValue << (identifier + ':' + value)#.setResultsName('CHOICE')
# ASN.1 SEQUENCE
#NAMED_VALUE_LIST << nestedExpr('{','}', delimitedList(namedValue, delim=',')).setResultsName('SEQUENCE', True)
NAMED_VALUE_LIST << LBRACKET + delimitedList(namedValue) + RBRACKET
# ASN.1 SEQUENCE OF
#VALUE_LIST << nestedExpr('{', '}', delimitedList(value, delim=',')).setResultsName('SEQOF', True)
VALUE_LIST << LBRACKET + Optional(delimitedList(value)) + RBRACKET
# Parse actions allow to modify the AST to be compliant with the ASN.1 Editor input
......@@ -134,8 +131,23 @@ NAMED_VALUE_LIST.setParseAction(lambda s, l, t: reduce(lambda a, b: a.update(b)
# below: works only with Python 2.7+
#NAMED_VALUE_LIST.setParseAction(lambda s, l, t: {c:a[c] for a in t for c in a.iterkeys()})
VALUE_LIST.setParseAction(lambda s, l, t: [t.asList()])
choiceValue.setParseAction(lambda s, l, t: {'Choice': t[0].replace('-', '_'), t[0].replace('-', '_'): t[2]})
valuereference.setParseAction(lambda s, l, t: {'Enum': t[0].replace('-', '_')})
def parseChoiceValue(s, l, t):
''' Parsing CHOICE '''
choice = t[0].replace('-', '_')
return {'Choice': choice, choice: t[2]}
choiceValue.setParseAction(parseChoiceValue)
def parseValueReference(s, l, t):
''' Parsing ENUMERATED Id '''
value = t[0].replace('-', '_')
return {'Enum': value}
valuereference.setParseAction(parseValueReference)
#choiceValue.setParseAction(lambda s, l, t: {'Choice': t[0].replace('-', '_'), t[0].replace('-', '_'): t[2]})
#valuereference.setParseAction(lambda s, l, t: {'Enum': t[0].replace('-', '_')})
namedValue.setParseAction(lambda s, l, t: {t[0].replace('-', '_'): t[1]})
FloatingPointLiteral.setParseAction(lambda s, l, t: float(t[0]))
INT.setParseAction(lambda s, l, t: int(t[0]))
......