Skip to content

Commit

Permalink
Fix sym.dump to export the value_table into the {ENUMS} field of the (#…
Browse files Browse the repository at this point in the history
…481)

.sym file.
Refactor to remove the use of global variables "enum_dict" and "enums"

Add a test which checks that enums in the original .sym file and enums
which appear as values on a signal are exported to the .sym file.
  • Loading branch information
Seneda authored May 12, 2020
1 parent ef4d76e commit 0caf5fe
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 15 deletions.
30 changes: 18 additions & 12 deletions src/canmatrix/formats/sym.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,6 @@
import canmatrix.utils

logger = logging.getLogger(__name__)
enum_dict = {} # type: typing.Dict[str, str]
enums = "{ENUMS}\n"


def default_float_factory(value): # type: (typing.Any) -> decimal.Decimal
Expand Down Expand Up @@ -101,8 +99,6 @@ def format_float(f): # type: (typing.Any) -> str


def create_signal(db, signal): # type: (canmatrix.CanMatrix, canmatrix.Signal) -> str
global enums
global enum_dict
output = ""
if sys.version_info > (3, 0):
quote_name = not signal.name.isidentifier()
Expand Down Expand Up @@ -159,12 +155,7 @@ def create_signal(db, signal): # type: (canmatrix.CanMatrix, canmatrix.Signal)
val_tab_name = signal.name

output += "/e:%s " % val_tab_name
if val_tab_name not in enum_dict:
enum_dict[val_tab_name] = "enum " + val_tab_name + "(" + ', '.join(
'%s="%s"' %
(key, val) for (
key, val) in sorted(
signal.values.items())) + ")"


default = signal.initial_value # type: ignore
min_ok = signal.min is None or default >= signal.min
Expand All @@ -182,17 +173,31 @@ def create_signal(db, signal): # type: (canmatrix.CanMatrix, canmatrix.Signal)
output += "\n"
return output

def create_enum_from_signal_values(signal):
enum_dict = {}
if len(signal.values) > 0:
val_tab_name = signal.enumeration
if val_tab_name is None:
val_tab_name = signal.name

if val_tab_name not in enum_dict:
enum_dict[val_tab_name] = "enum " + val_tab_name + "(" + ', '.join(
'%s="%s"' %
(key, val) for (
key, val) in sorted(
signal.values.items())) + ")"
return enum_dict

def dump(db, f, **options): # type: (canmatrix.CanMatrix, typing.IO, **typing.Any) -> None
"""
export canmatrix-object as .sym file (compatible to PEAK-Systems)
"""
global enum_dict
global enums
sym_encoding = options.get('symExportEncoding', 'iso-8859-1')
ignore_encoding_errors = options.get("ignoreExportEncodingErrors", "")

enum_dict = {}
for enum_name, enum_values in db.value_tables.items():
enum_dict[enum_name] = "enum {}({})".format(enum_name, ', '.join('{}="{}"'.format(*items) for items in sorted(enum_values.items())))
enums = "{ENUMS}\n"

header = """\
Expand Down Expand Up @@ -308,6 +313,7 @@ def send_receive(for_frame):
output += "CycleTime=" + str(frame.effective_cycle_time) + "\n"
for signal in frame.signals:
output += create_signal(db, signal)
enum_dict.update(create_enum_from_signal_values(signal))
output += "\n"
enums += '\n'.join(sorted(enum_dict.values()))
# write output file
Expand Down
42 changes: 39 additions & 3 deletions src/canmatrix/tests/test_sym.py
Original file line number Diff line number Diff line change
Expand Up @@ -212,13 +212,49 @@ def test_enums_read(enum_str, enum_dict, enum_label):
{{ENUMS}}
{}
'''.format(enum_str).encode('utf-8'),
)
)

matrix = canmatrix.formats.sym.load(f)
assert matrix.load_errors == [], "Failed to load canmatrix, when testing enum case : '{}'".format(enum_label)
assert matrix.value_tables == enum_dict, "Enum not parsed correctly : '{}'".format(enum_label)
f_out = io.BytesIO()
canmatrix.formats.sym.dump(matrix, f_out)


def test_enums_export():
f = io.BytesIO('''\
FormatVersion=5.0 // Do not edit this line!
Title="An Example Title"
{ENUMS}
enum Animal(0="Dog",1="Cat",2="Fox")
{SENDRECEIVE}
[Frame1]
ID=000h
DLC=8
Var=Signal1 unsigned 0,16
'''.encode('utf-8'),
)

matrix = canmatrix.formats.sym.load(f)
assert matrix.load_errors == [], "Failed to load canmatrix"

# Add an enum to Signal1
matrix.frame_by_name("Frame1").signal_by_name("Signal1").enumeration = "Plants"
matrix.frame_by_name("Frame1").signal_by_name("Signal1").values = {0: "Grass", 1: "Flower", 2: "Tree"}

# Export and reimport
f_out = io.BytesIO()
canmatrix.formats.sym.dump(matrix, f_out)
f_in = io.BytesIO(f_out.getvalue())
new_matrix = canmatrix.formats.sym.load(f_in)

# Check that Enums from Enums table exported and reimported correctly
assert new_matrix.value_tables["Animal"] == {0: "Dog", 1: "Cat", 2: "Fox"}

# Check that Enums from a Signal.Values property exported and reimported correctly
assert new_matrix.value_tables["Plants"] == {0: "Grass", 1: "Flower", 2: "Tree"}



def test_types_read():
Expand Down

0 comments on commit 0caf5fe

Please sign in to comment.