Commit e9ae37d3 authored by Maxime Perrotin's avatar Maxime Perrotin
Browse files

Merge https://github.com/esa/opengeode into feature_buster

parents 2f4f49d5 591ff4cf
...@@ -124,6 +124,9 @@ The background pattern was downloaded from www.subtlepatterns.com ...@@ -124,6 +124,9 @@ The background pattern was downloaded from www.subtlepatterns.com
Changelog Changelog
========= =========
**3.3.7 (03/2021)**
- Support IA5String type
**3.3.7 (03/2021)** **3.3.7 (03/2021)**
- Fix handling of context parameters in type/instances - Fix handling of context parameters in type/instances
......
...@@ -465,6 +465,8 @@ LD_LIBRARY_PATH=./lib:.:$LD_LIBRARY_PATH opengeode-simulator ...@@ -465,6 +465,8 @@ LD_LIBRARY_PATH=./lib:.:$LD_LIBRARY_PATH opengeode-simulator
varbty = find_basic_type(var_type) varbty = find_basic_type(var_type)
if varbty.kind in ('SequenceOfType', 'OctetStringType'): if varbty.kind in ('SequenceOfType', 'OctetStringType'):
dstr = array_content(def_value, dstr, varbty) dstr = array_content(def_value, dstr, varbty)
elif varbty.kind == 'IA5StringType':
dstr = ia5string_raw(def_value)
assert not dst and not dlocal,\ assert not dst and not dlocal,\
'DCL: Expecting a ground expression' 'DCL: Expecting a ground expression'
initial_values.append(f'{var_name} => {dstr}') initial_values.append(f'{var_name} => {dstr}')
...@@ -1330,6 +1332,11 @@ def write_statement(param, newline): ...@@ -1330,6 +1332,11 @@ def write_statement(param, newline):
code.extend(st2) code.extend(st2)
local.extend(lcl1) local.extend(lcl1)
local.extend(lcl2) local.extend(lcl2)
elif type_kind == 'IA5StringType':
# IA5String are null-terminated to match the C representation
# ASN1SCC API offers the getStringSize function to read the actual size
code, string, local = expression(param, readonly=1)
code.append(f'Put ({string} (1 .. adaasn1rtl.GetStringSize ({string})));')
elif type_kind.endswith('StringType'): elif type_kind.endswith('StringType'):
if isinstance(param, ogAST.PrimStringLiteral): if isinstance(param, ogAST.PrimStringLiteral):
# Raw string # Raw string
...@@ -2162,8 +2169,15 @@ def _assign_expression(expr, **kwargs): ...@@ -2162,8 +2169,15 @@ def _assign_expression(expr, **kwargs):
# If left side is a string/seqOf and right side is a substring, we must # If left side is a string/seqOf and right side is a substring, we must
# assign the .Data and .Length parts properly # assign the .Data and .Length parts properly
basic_left = find_basic_type(expr.left.exprType) basic_left = find_basic_type(expr.left.exprType)
if basic_left.kind in ('SequenceOfType', 'OctetStringType'): if (basic_left.kind == 'IA5StringType'
rlen = u"{}'Length".format(right_str) and isinstance(expr.right, ogAST.PrimStringLiteral)):
# Assignment of a raw IA5String: do not use the result of expression
# as it represents the string as a sequence of numbers to fit
# OCTET STRINGs.
def_value = ia5string_raw(expr.right)
strings.append(f'{left_str} := {def_value};')
elif basic_left.kind in ('SequenceOfType', 'OctetStringType'):
rlen = f"{right_str}'Length"
if isinstance(expr.right, ogAST.PrimSubstring): if isinstance(expr.right, ogAST.PrimSubstring):
if not isinstance(expr.left, ogAST.PrimSubstring): if not isinstance(expr.left, ogAST.PrimSubstring):
...@@ -2204,11 +2218,10 @@ def _assign_expression(expr, **kwargs): ...@@ -2204,11 +2218,10 @@ def _assign_expression(expr, **kwargs):
rlen = None rlen = None
else: else:
# Right part is a variable # Right part is a variable
strings.append(u"{} := {};".format(left_str, right_str)) strings.append(f"{left_str} := {right_str};")
rlen = None rlen = None
if rlen and basic_left.Min != basic_left.Max: if rlen and basic_left.Min != basic_left.Max:
strings.append(u"{lvar}.Length := {rlen};" strings.append(f"{left_str}.Length := {rlen};")
.format(lvar=left_str, rlen=rlen))
elif basic_left.kind.startswith('Integer'): elif basic_left.kind.startswith('Integer'):
# print '\nASSIGN:', expr.inputString, # print '\nASSIGN:', expr.inputString,
# print "Left type = ",type_name(find_basic_type (expr.left.exprType)), # print "Left type = ",type_name(find_basic_type (expr.left.exprType)),
...@@ -2236,9 +2249,9 @@ def _assign_expression(expr, **kwargs): ...@@ -2236,9 +2249,9 @@ def _assign_expression(expr, **kwargs):
else: else:
res = right_str res = right_str
strings.append(f"{left_str} := {res};".format(left_str, res)) strings.append(f"{left_str} := {res};")
else: else:
strings.append(u"{} := {};".format(left_str, right_str)) strings.append(f"{left_str} := {right_str};")
code.extend(left_stmts) code.extend(left_stmts)
code.extend(right_stmts) code.extend(right_stmts)
code.extend(strings) code.extend(strings)
...@@ -2528,9 +2541,17 @@ def _string_literal(primary, **kwargs): ...@@ -2528,9 +2541,17 @@ def _string_literal(primary, **kwargs):
# as expected by the Ada type corresponding to Octet String # as expected by the Ada type corresponding to Octet String
unsigned_8 = [str(ord(val)) for val in primary.value[1:-1]] unsigned_8 = [str(ord(val)) for val in primary.value[1:-1]]
ada_string = u', '.join(unsigned_8) ada_string = ', '.join(unsigned_8)
return [], str(ada_string), [] return [], str(ada_string), []
def ia5string_raw(prim: ogAST.PrimStringLiteral):
''' IA5 Strings are of type String in Ada but this is not directly
compatible with variable-length strings as defined in ASN.1
Since the Ada type maps to a null-terminated C type, we have to make
a corresponding assignment, filling then non-used part of the container
with NULL character. To know the size, we can use adaasn1rtl.getStringSize
'''
return "('" + "', '".join(prim.value[1:-1]) + "', others => Standard.ASCII.NUL)"
@expression.register(ogAST.PrimConstant) @expression.register(ogAST.PrimConstant)
def _constant(primary, **kwargs): def _constant(primary, **kwargs):
...@@ -2542,7 +2563,7 @@ def _constant(primary, **kwargs): ...@@ -2542,7 +2563,7 @@ def _constant(primary, **kwargs):
def _mantissa_base_exp(primary, **kwargs): def _mantissa_base_exp(primary, **kwargs):
''' Generate code for a Real with Mantissa-base-Exponent representation ''' ''' Generate code for a Real with Mantissa-base-Exponent representation '''
# TODO # TODO
return [], u'', [] return [], '', []
@expression.register(ogAST.PrimConditional) @expression.register(ogAST.PrimConditional)
...@@ -2556,7 +2577,7 @@ def _conditional(cond, **kwargs): ...@@ -2556,7 +2577,7 @@ def _conditional(cond, **kwargs):
then_str = cond.value['then'].value.replace("'", '"') then_str = cond.value['then'].value.replace("'", '"')
else_str = cond.value['else'].value.replace("'", '"') else_str = cond.value['else'].value.replace("'", '"')
lens = [len(then_str), len(else_str)] lens = [len(then_str), len(else_str)]
tmp_type = 'String(1 .. {})'.format(max(lens) - 2) tmp_type = 'String (1 .. {})'.format(max(lens) - 2)
# Ada require fixed-length strings, adjust with spaces # Ada require fixed-length strings, adjust with spaces
if lens[0] < lens[1]: if lens[0] < lens[1]:
then_str = then_str[0:-1] + ' ' * (lens[1] - lens[0]) + '"' then_str = then_str[0:-1] + ' ' * (lens[1] - lens[0]) + '"'
...@@ -3124,7 +3145,7 @@ def _inner_procedure(proc, **kwargs): ...@@ -3124,7 +3145,7 @@ def _inner_procedure(proc, **kwargs):
inner_code, inner_local = generate(inner_proc) inner_code, inner_local = generate(inner_proc)
local_decl.extend(inner_local) local_decl.extend(inner_local)
code.extend(inner_code) code.extend(inner_code)
code.append(pi_header + u' is') code.append(f'{pi_header} is')
for var_name, (var_type, def_value) in proc.variables.items(): for var_name, (var_type, def_value) in proc.variables.items():
typename = type_name(var_type) typename = type_name(var_type)
if def_value: if def_value:
...@@ -3132,8 +3153,11 @@ def _inner_procedure(proc, **kwargs): ...@@ -3132,8 +3153,11 @@ def _inner_procedure(proc, **kwargs):
# require temporary variable to store computed result # require temporary variable to store computed result
dst, dstr, dlocal = expression(def_value, readonly=1) dst, dstr, dlocal = expression(def_value, readonly=1)
varbty = find_basic_type(var_type) varbty = find_basic_type(var_type)
print(f'{var_name}: {dstr} {varbty.kind}')
if varbty.kind in ('SequenceOfType', 'OctetStringType'): if varbty.kind in ('SequenceOfType', 'OctetStringType'):
dstr = array_content(def_value, dstr, varbty) dstr = array_content(def_value, dstr, varbty)
elif varbty.kind == 'IA5StringType':
dstr = ia5string_raw(def_value)
assert not dst and not dlocal, 'Ground expression error' assert not dst and not dlocal, 'Ground expression error'
code.append(u'{name} : {sort}{default};' code.append(u'{name} : {sort}{default};'
.format(name=var_name, .format(name=var_name,
......
...@@ -271,7 +271,8 @@ def is_string(ty) -> bool: ...@@ -271,7 +271,8 @@ def is_string(ty) -> bool:
return find_basic_type(ty).kind in ( return find_basic_type(ty).kind in (
'StandardStringType', 'StandardStringType',
'OctetStringType', 'OctetStringType',
'StringType' 'StringType',
'IA5StringType'
) )
...@@ -1170,8 +1171,10 @@ def check_type_compatibility(primary, type_ref, context): ...@@ -1170,8 +1171,10 @@ def check_type_compatibility(primary, type_ref, context):
# Octet strings # Octet strings
basic_type = find_basic_type(type_ref) basic_type = find_basic_type(type_ref)
if basic_type.kind == 'StandardStringType': if basic_type.kind == 'StandardStringType':
# raw string
return warnings return warnings
elif basic_type.kind.endswith('StringType'): elif basic_type.kind.endswith('StringType'):
# all strings including IA5String
try: try:
if int(minR) <= len( if int(minR) <= len(
primary.value[1:-1]) <= int(maxR): primary.value[1:-1]) <= int(maxR):
......
...@@ -141,7 +141,7 @@ except ImportError: ...@@ -141,7 +141,7 @@ except ImportError:
__all__ = ['opengeode', 'SDL_Scene', 'SDL_View', 'parse'] __all__ = ['opengeode', 'SDL_Scene', 'SDL_View', 'parse']
__version__ = '3.3.7' __version__ = '3.3.8'
if hasattr(sys, 'frozen'): if hasattr(sys, 'frozen'):
# Detect if we are running on Windows (py2exe-generated) # Detect if we are running on Windows (py2exe-generated)
......
...@@ -5,6 +5,11 @@ List ::= SEQUENCE(SIZE(5)) OF OCTET STRING(SIZE(1..6)) ...@@ -5,6 +5,11 @@ List ::= SEQUENCE(SIZE(5)) OF OCTET STRING(SIZE(1..6))
OutStr ::= OCTET STRING (SIZE(0..255)) OutStr ::= OCTET STRING (SIZE(0..255))
Octet ::= OCTET STRING (SIZE (1))
Short-String ::= SEQUENCE (SIZE (0..255)) OF Octet
Textstring ::= IA5String (SIZE (0..255))
END END
...@@ -5,3 +5,4 @@ foo ...@@ -5,3 +5,4 @@ foo
bar bar
baz baz
String literal (should be 'hello'):hello String literal (should be 'hello'):hello
hello world
...@@ -15,7 +15,7 @@ system og; ...@@ -15,7 +15,7 @@ system og;
connect c and r; connect c and r;
/* CIF PROCESS (253, 105), (150, 75) */ /* CIF PROCESS (253, 105), (150, 75) */
process og; process og;
/* CIF TEXT (0, 33), (356, 203) */ /* CIF TEXT (0, 33), (356, 264) */
-- Text area for declarations and comments -- Text area for declarations and comments
dcl a List := {'a', 'b', 'foo', 'bar', 'baz'}; dcl a List := {'a', 'b', 'foo', 'bar', 'baz'};
...@@ -28,6 +28,10 @@ system og; ...@@ -28,6 +28,10 @@ system og;
dcl strlit outStr := '68656c6c6f'H; dcl strlit outStr := '68656c6c6f'H;
dcl bitstrlit outStr := '01010110'B; dcl bitstrlit outStr := '01010110'B;
dcl helloStr Short_String := {'h', 'e', 'l', 'l', 'o'};
dcl ia5 TextString := 'hello';
/* CIF ENDTEXT */ /* CIF ENDTEXT */
/* CIF START (639, 63), (70, 35) */ /* CIF START (639, 63), (70, 35) */
START; START;
...@@ -52,7 +56,17 @@ endfor ...@@ -52,7 +56,17 @@ endfor
(sep is also a dcl-variable)'; (sep is also a dcl-variable)';
/* CIF PROCEDURECALL (509, 441), (330, 35) */ /* CIF PROCEDURECALL (509, 441), (330, 35) */
call writeln('String literal (should be "hello"):', strlit); call writeln('String literal (should be "hello"):', strlit);
/* CIF NEXTSTATE (639, 491), (70, 35) */ /* CIF task (608, 496), (130, 56) */
task for chr in helloStr:
call write(chr);
endfor;
/* CIF PROCEDURECALL (631, 572), (84, 35) */
call write(' ');
/* CIF task (625, 627), (97, 35) */
task ia5 := 'world';
/* CIF PROCEDURECALL (624, 682), (99, 35) */
call writeln(ia5);
/* CIF NEXTSTATE (639, 732), (70, 35) */
NEXTSTATE wait; NEXTSTATE wait;
/* CIF state (366, 217), (70, 35) */ /* CIF state (366, 217), (70, 35) */
state wait; state wait;
......
Supports Markdown
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