Skip to content

Commit

Permalink
Make SingleValueConstraint accept alternatives
Browse files Browse the repository at this point in the history
SingleValueConstraint can describe a set of valid values, not
necessarily just one.

This is not strictly correct -- the "|" token is used to create a UNION
constraint composed of multiple other constraints of different types, so
e.g. (1 | a | 6..10) is valid ASN.1, but not accepted by asn1ate.

When proper combined constraints are implemented, this should fall out
nicely and just work, but for now, support a common scenario with more
than one SingleValue.
  • Loading branch information
kimgr committed Jun 9, 2019
1 parent 989d094 commit 323b0c2
Show file tree
Hide file tree
Showing 4 changed files with 8 additions and 5 deletions.
3 changes: 2 additions & 1 deletion asn1ate/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,8 @@ def annotation(t):
# todo: consider the full subtype and general constraint syntax described in 45.*
lower_bound = (constraint_real_value | signed_number | referenced_value | MIN)
upper_bound = (constraint_real_value | signed_number | referenced_value | MAX)
single_value_constraint = Suppress('(') + value + Suppress(')')

single_value_constraint = Suppress('(') + Group(delimitedList(value, delim='|')) + Suppress(')')
value_range_constraint = Suppress('(') + lower_bound + Suppress('..') + upper_bound + Suppress(')')
# TODO: Include contained subtype constraint here if we ever implement it.
size_constraint = Optional(Suppress('(')) + Suppress(SIZE) + (single_value_constraint | value_range_constraint) + Optional(Suppress(')'))
Expand Down
4 changes: 2 additions & 2 deletions asn1ate/pyasn1gen.py
Original file line number Diff line number Diff line change
Expand Up @@ -364,14 +364,14 @@ def build_tag_expr(self, tag_def):
def build_constraint_expr(self, constraint):
def unpack_size_constraint(nested):
if isinstance(nested, SingleValueConstraint):
return self.translate_value(nested.value), self.translate_value(nested.value)
return self.translate_value(nested.values[0]), self.translate_value(nested.values[0])
elif isinstance(nested, ValueRangeConstraint):
return self.translate_value(nested.min_value), self.translate_value(nested.max_value)
else:
raise Exception('Unrecognized nested size constraint type: %s' % nested.__class__.__name__)

if isinstance(constraint, SingleValueConstraint):
return 'constraint.SingleValueConstraint(%s)' % (self.translate_value(constraint.value))
return 'constraint.SingleValueConstraint(%s)' % ', '.join(self.translate_value(v) for v in constraint.values)
elif isinstance(constraint, SizeConstraint):
min_value, max_value = unpack_size_constraint(constraint.nested)
return 'constraint.ValueSizeConstraint(%s, %s)' % (self.translate_value(min_value), self.translate_value(max_value))
Expand Down
4 changes: 2 additions & 2 deletions asn1ate/sema.py
Original file line number Diff line number Diff line change
Expand Up @@ -672,10 +672,10 @@ def __str__(self):

class SingleValueConstraint(SemaNode):
def __init__(self, elements):
self.value = _maybe_create_sema_node(elements[0])
self.values = [_maybe_create_sema_node(e) for e in elements[0]]

def __str__(self):
return '(%s)' % self.value
return '(%s)' % ' | '.join(map(str, self.values))

__repr__ = __str__

Expand Down
2 changes: 2 additions & 0 deletions testdata/single_value_constraint.asn
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,15 @@ BEGIN
ConstrainedInteger1 ::= INTEGER (50)
ConstrainedInteger2 ::= INTEGER (value)
ConstrainedInteger3 ::= INTEGER { one(10), two(20) } (10)
ConstrainedInteger4 ::= INTEGER (100 | 50 | 25)

ConstrainedBitString1 ::= BIT STRING { one(1), two(2) } (1)

realValue REAL ::= 3.14
ConstrainedReal1 ::= REAL (2.73)
ConstrainedReal2 ::= REAL (realValue)
ConstrainedReal3 ::= REAL (4E9)
ConstrainedReal4 ::= REAL (2.73 | 3.14 | 1.23)

Alias ::= OCTET STRING
ConstrainedAlias ::= Alias (SIZE(8))
Expand Down

0 comments on commit 323b0c2

Please sign in to comment.