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

Proper range check when using OCTET STRINGs/SEQUENCE OF

parent ef5cbe44
This diff is collapsed.
...@@ -590,6 +590,7 @@ def check_type_compatibility(primary, type_ref, context): ...@@ -590,6 +590,7 @@ def check_type_compatibility(primary, type_ref, context):
''' '''
assert type_ref is not None assert type_ref is not None
if type_ref is UNKNOWN_TYPE: if type_ref is UNKNOWN_TYPE:
#print traceback.print_stack()
raise TypeError('Type reference is unknown') raise TypeError('Type reference is unknown')
basic_type = find_basic_type(type_ref) basic_type = find_basic_type(type_ref)
...@@ -650,7 +651,8 @@ def check_type_compatibility(primary, type_ref, context): ...@@ -650,7 +651,8 @@ def check_type_compatibility(primary, type_ref, context):
+ basic_type.Min + ')') + basic_type.Min + ')')
elif isinstance(primary, ogAST.PrimSequenceOf) \ elif isinstance(primary, ogAST.PrimSequenceOf) \
and basic_type.kind == 'SequenceOfType': and basic_type.kind == 'SequenceOfType':
if (len(primary.value) < int(basic_type.Min) or if type_ref.__name__ != 'Apnd' and \
(len(primary.value) < int(basic_type.Min) or
len(primary.value) > int(basic_type.Max)): len(primary.value) > int(basic_type.Max)):
raise TypeError(str(len(primary.value)) + raise TypeError(str(len(primary.value)) +
' elements in SEQUENCE OF, while constraint is [' + ' elements in SEQUENCE OF, while constraint is [' +
...@@ -782,11 +784,20 @@ def compare_types(type_a, type_b): ...@@ -782,11 +784,20 @@ def compare_types(type_a, type_b):
if type_a.kind == type_b.kind: if type_a.kind == type_b.kind:
if type_a.kind == 'SequenceOfType': if type_a.kind == 'SequenceOfType':
if type_a.Min == type_b.Min and type_a.Max == type_b.Max: if type_a.Min == type_a.Max:
if type_a.Min == type_b.Min == type_b.Max:
compare_types(type_a.type, type_b.type)
return
else:
raise TypeError('Incompatible sizes - size of {} can vary'
.format(type_name(type_b)))
elif(int(type_b.Min) >= int(type_a.Min)
and int(type_b.Max) <= int(type_a.Max)):
compare_types(type_a.type, type_b.type) compare_types(type_a.type, type_b.type)
return return
else: else:
raise TypeError('Incompatible arrays') compare_types(type_a.type, type_b.type)
raise Warning('Size constraints mismatch - risk of overflow')
# TODO: Check that OctetString types have compatible range # TODO: Check that OctetString types have compatible range
return return
elif is_string(type_a) and is_string(type_b): elif is_string(type_a) and is_string(type_b):
...@@ -862,20 +873,6 @@ def fix_expression_types(expr, context): ...@@ -862,20 +873,6 @@ def fix_expression_types(expr, context):
fix_enumerated_and_choice(expr, context) fix_enumerated_and_choice(expr, context)
expr.right, expr.left = expr.left, expr.right expr.right, expr.left = expr.left, expr.right
# for side in permutations(('left', 'right')):
# side_type = find_basic_type(getattr(expr, side[0]).exprType).kind
# if side_type == 'EnumeratedType':
# prim = ogAST.PrimEnumeratedValue(primary=getattr(expr, side[1]))
# elif side_type == 'ChoiceEnumeratedType':
# prim = ogAST.PrimChoiceDeterminant(primary=getattr(expr, side[1]))
# try:
# check_type_compatibility(prim, getattr(expr, side[0]).exprType,
# context)
# setattr(expr, side[1], prim)
# getattr(expr, side[1]).exprType = getattr(expr, side[0]).exprType
# except (UnboundLocalError, AttributeError, TypeError):
# pass
for side in (expr.right, expr.left): for side in (expr.right, expr.left):
if side.is_raw: if side.is_raw:
raw_expr = side raw_expr = side
...@@ -884,11 +881,11 @@ def fix_expression_types(expr, context): ...@@ -884,11 +881,11 @@ def fix_expression_types(expr, context):
ref_type = typed_expr.exprType ref_type = typed_expr.exprType
# If a side is a raw Sequence Of with unknown type, try to resolve it # If a side is a raw Sequence Of with unknown type, try to resolve it
for side in permutations(('left', 'right')): for side_a, side_b in permutations(('left', 'right')):
value = getattr(expr, side[0]) # get expr.left then expr.right value = getattr(expr, side_a) # get expr.left then expr.right
if not isinstance(value, ogAST.PrimSequenceOf): if not isinstance(value, ogAST.PrimSequenceOf):
continue continue
other = getattr(expr, side[1]) # other side other = getattr(expr, side_b) # other side
basic = find_basic_type(value.exprType) basic = find_basic_type(value.exprType)
if basic.kind == 'SequenceOfType' and basic.type == UNKNOWN_TYPE: if basic.kind == 'SequenceOfType' and basic.type == UNKNOWN_TYPE:
asn_type = find_basic_type(other.exprType) asn_type = find_basic_type(other.exprType)
...@@ -969,9 +966,14 @@ def fix_expression_types(expr, context): ...@@ -969,9 +966,14 @@ def fix_expression_types(expr, context):
if expr.right.is_raw != expr.left.is_raw: if expr.right.is_raw != expr.left.is_raw:
check_type_compatibility(raw_expr, ref_type, context) check_type_compatibility(raw_expr, ref_type, context)
if not raw_expr.exprType.kind.startswith(('Integer', 'Real')): if not raw_expr.exprType.kind.startswith(('Integer',
'Real',
'SequenceOf',
'String')):
# Raw int/real must keep their type because of the range # Raw int/real must keep their type because of the range
# that can be computed # that can be computed
# Also true for raw SEQOF and String - Min/Max must not change
# Substrings: CHECKME XXX
raw_expr.exprType = ref_type raw_expr.exprType = ref_type
else: else:
compare_types(expr.left.exprType, expr.right.exprType) compare_types(expr.left.exprType, expr.right.exprType)
...@@ -1061,6 +1063,8 @@ def binary_expression(root, context): ...@@ -1061,6 +1063,8 @@ def binary_expression(root, context):
fix_expression_types(expr, context) fix_expression_types(expr, context)
except (AttributeError, TypeError) as err: except (AttributeError, TypeError) as err:
errors.append(error(root, str(err))) errors.append(error(root, str(err)))
except Warning as warn:
warnings.append(warning(root, str(warn)))
return expr, errors, warnings return expr, errors, warnings
...@@ -1277,14 +1281,20 @@ def append_expression(root, context): ...@@ -1277,14 +1281,20 @@ def append_expression(root, context):
''' Append expression analysis ''' ''' Append expression analysis '''
expr, errors, warnings = binary_expression(root, context) expr, errors, warnings = binary_expression(root, context)
for bty in (find_basic_type(expr.left.exprType), left = find_basic_type(expr.left.exprType)
find_basic_type(expr.right.exprType)): right = find_basic_type(expr.right.exprType)
for bty in (left, right):
if bty.kind != 'SequenceOfType' and not is_string(bty): if bty.kind != 'SequenceOfType' and not is_string(bty):
msg = 'Append can only be applied to types SequenceOf or String' msg = 'Append can only be applied to types SequenceOf or String'
errors.append(error(root, msg)) errors.append(error(root, msg))
break break
else:
attrs = {'Min': str(int(right.Min) + int(left.Min)),
'Max': str(int(right.Max) + int(left.Max))}
expr.exprType = type('Apnd', (left,), attrs)
#expr.exprType = expr.left.exprType
expr.exprType = expr.left.exprType
return expr, errors, warnings return expr, errors, warnings
...@@ -1507,20 +1517,23 @@ def primary_substring(root, context): ...@@ -1507,20 +1517,23 @@ def primary_substring(root, context):
if receiver_bty.kind == 'SequenceOfType' or \ if receiver_bty.kind == 'SequenceOfType' or \
receiver_bty.kind.endswith('StringType'): receiver_bty.kind.endswith('StringType'):
node.exprType = receiver.exprType min0 = float(find_basic_type(params[0].exprType).Min)
# Check bounds min1 = float(find_basic_type(params[1].exprType).Min)
max0 = float(find_basic_type(params[0].exprType).Max)
max1 = float(find_basic_type(params[1].exprType).Max)
node.exprType = type('SubStr', (receiver_bty,),
{'Min':
str(int(min1) - int(max0) + 1),
'Max':
str(int(max1) - int(min0) + 1)})
basic = find_basic_type(node.exprType) basic = find_basic_type(node.exprType)
min0 = find_basic_type(params[0].exprType).Min
min1 = find_basic_type(params[1].exprType).Min
max0 = find_basic_type(params[0].exprType).Max
max1 = find_basic_type(params[1].exprType).Max
if int(min0) > int(min1) or int(max0) > int(max1): if int(min0) > int(min1) or int(max0) > int(max1):
msg = 'Substring bounds are invalid' msg = 'Substring bounds are invalid'
errors.append(error(root, msg)) errors.append(error(root, msg))
if int(min0) > int(basic.Max) \ if int(min0) > int(receiver_bty.Max) \
or int(max1) > int(basic.Max): or int(max1) > int(receiver_bty.Max):
msg = 'Substring bounds [{}..{}] outside range [{}..{}]'.format( msg = 'Substring bounds [{}..{}] outside range [{}..{}]'.format(
min0, max1, basic.Min, basic.Max) min0, max1, receiver_bty.Min, receiver_bty.Max)
errors.append(error(root, msg)) errors.append(error(root, msg))
else: else:
msg = 'Substring can only be applied to types SequenceOf or String' msg = 'Substring can only be applied to types SequenceOf or String'
...@@ -1660,7 +1673,7 @@ def primary(root, context): ...@@ -1660,7 +1673,7 @@ def primary(root, context):
'kind': 'SequenceOfType', 'kind': 'SequenceOfType',
'Min': str(len(root.children)), 'Min': str(len(root.children)),
'Max': str(len(root.children)), 'Max': str(len(root.children)),
'type': UNKNOWN_TYPE 'type': prim_elem.exprType #UNKNOWN_TYPE
}) })
elif root.type == lexer.BITSTR: elif root.type == lexer.BITSTR:
prim = ogAST.PrimBitStringLiteral() prim = ogAST.PrimBitStringLiteral()
...@@ -1717,7 +1730,8 @@ def variables(root, ta_ast, context): ...@@ -1717,7 +1730,8 @@ def variables(root, ta_ast, context):
expr.right.inputString + ', type= ' + expr.right.inputString + ', type= ' +
type_name(expr.right.exprType) + ') ' + str(err)) type_name(expr.right.exprType) + ') ' + str(err))
else: else:
def_value.exprType = asn1_sort if def_value.exprType == UNKNOWN_TYPE:
def_value.exprType = asn1_sort
if not def_value.is_raw and \ if not def_value.is_raw and \
not isinstance(def_value, ogAST.PrimConstant): not isinstance(def_value, ogAST.PrimConstant):
...@@ -3525,13 +3539,19 @@ def assign(root, context): ...@@ -3525,13 +3539,19 @@ def assign(root, context):
if basic.kind.startswith(('Integer', 'Real')): if basic.kind.startswith(('Integer', 'Real')):
check_range(basic, find_basic_type(expr.right.exprType)) check_range(basic, find_basic_type(expr.right.exprType))
except(AttributeError, TypeError) as err: except(AttributeError, TypeError) as err:
errors.append('Types are incompatible in assignment: left (' + errors.append('Type mismatch: left (' +
expr.left.inputString + ', type= ' + expr.left.inputString + ', type= ' +
type_name(expr.left.exprType) + '), right (' + type_name(expr.left.exprType) + '), right (' +
expr.right.inputString + ', type= ' + expr.right.inputString + ', type= ' +
(type_name(expr.right.exprType) (type_name(expr.right.exprType)
if expr.right.exprType else 'Unknown') + ') ' + str(err)) if expr.right.exprType else 'Unknown') + ') ' + str(err))
else: except Warning as warn:
warnings.append('Expression "{}": {}'
.format(expr.inputString, str(warn)))
if expr.right.exprType == UNKNOWN_TYPE or not \
isinstance(expr.right, (ogAST.ExprAppend,
ogAST.PrimSequenceOf,
ogAST.PrimStringLiteral)):
expr.right.exprType = expr.left.exprType expr.right.exprType = expr.left.exprType
return expr, errors, warnings return expr, errors, warnings
......
...@@ -8,11 +8,18 @@ edit: ...@@ -8,11 +8,18 @@ edit:
test-parse: test-parse:
$(OPENGEODE) og.pr system_structure.pr --check $(OPENGEODE) og.pr system_structure.pr --check
test-ada: og.ali test-ada: og.ali dataview-uniq.o | test_ada.o
$(GNATBIND) -n og.ali
$(GNATLINK) -o test_ada test_ada.o og.ali -lgnat
./test_ada
test-llvm: og.o dataview-uniq.o | test_llvm.o
$(CC) og.o dataview-uniq.o test_llvm.o -o test_llvm -lm
./test_llvm
test-llvm: og.o
coverage: coverage:
coverage run -p $(OPENGEODE) og.pr system_structure.pr --toAda coverage run -p $(OPENGEODE) og.pr system_structure.pr --toAda
.PHONY: all edit test-parse test-ada test-llvm coverage .PHONY: all edit test-parse test-ada test-llvm coverage
\ No newline at end of file
...@@ -49,38 +49,46 @@ defined in the ASN.1 model'; ...@@ -49,38 +49,46 @@ defined in the ASN.1 model';
two SEQUENCE OF'; two SEQUENCE OF';
/* CIF TASK (408, 484), (137, 50) */ /* CIF TASK (408, 484), (137, 50) */
TASK 'seq(1) := seq(2)'; TASK 'seq(1) := seq(2)';
/* CIF TASK (380, 549), (193, 50) */ /* CIF TASK (382, 549), (189, 50) */
TASK seq := seq(1,2) // seq(4,5) TASK seq := seq(0,1) // seq(3, 4)
/* CIF COMMENT (593, 549), (166, 50) */ /* CIF COMMENT (590, 549), (166, 50) */
COMMENT 'Remove 3rd element'; COMMENT 'Remove 3rd element';
/* CIF DECISION (425, 614), (104, 70) */ /* CIF TASK (407, 614), (140, 53) */
TASK for x in seq:
call writeln(x);
endfor;
/* CIF PROCEDURECALL (395, 682), (164, 35) */
CALL writeln('test=', test);
/* CIF DECISION (425, 732), (104, 70) */
DECISION test in seq DECISION test in seq
/* CIF COMMENT (549, 629), (170, 39) */ /* CIF COMMENT (549, 747), (170, 39) */
COMMENT 'Test the "in" operator COMMENT 'Test the "in" operator
Unicode test: Ï'; Unicode test: Ï';
/* CIF ANSWER (335, 704), (100, 35) */ /* CIF ANSWER (335, 822), (100, 35) */
(TRUE): (TRUE):
/* CIF PROCEDURECALL (308, 754), (154, 50) */ /* CIF PROCEDURECALL (308, 872), (154, 50) */
CALL writeln('All OK (1)'); CALL writeln('All OK (1)');
/* CIF ANSWER (498, 704), (100, 35) */ /* CIF ANSWER (498, 822), (100, 35) */
(FALSE): (FALSE):
/* CIF PROCEDURECALL (466, 754), (164, 50) */ /* CIF PROCEDURECALL (466, 872), (164, 50) */
CALL writeln('NOT OK (1)') CALL writeln('NOT OK (1)')
/* CIF COMMENT (650, 761), (117, 35) */ /* CIF COMMENT (650, 879), (117, 35) */
COMMENT 'Call UnicÔDË'; COMMENT 'Call UnicÔDË';
ENDDECISION; ENDDECISION;
/* CIF DECISION (427, 819), (100, 70) */ /* CIF DECISION (427, 937), (100, 70) */
DECISION 3 in seq; DECISION 3 in seq
/* CIF ANSWER (341, 909), (100, 35) */ /* CIF COMMENT (547, 954), (256, 35) */
COMMENT 'test==3 so it should also return true';
/* CIF ANSWER (341, 1027), (100, 35) */
(TRUE): (TRUE):
/* CIF PROCEDURECALL (309, 959), (164, 50) */ /* CIF PROCEDURECALL (309, 1077), (164, 50) */
CALL writeln('NOT OK (2)'); CALL writeln('ALL OK (2)');
/* CIF ANSWER (513, 909), (100, 35) */ /* CIF ANSWER (513, 1027), (100, 35) */
(FALSE): (FALSE):
/* CIF PROCEDURECALL (482, 959), (161, 50) */ /* CIF PROCEDURECALL (481, 1077), (164, 50) */
CALL writeln('All OK (2)'); CALL writeln('NOT OK (2)');
ENDDECISION; ENDDECISION;
/* CIF NEXTSTATE (427, 1024), (100, 50) */ /* CIF NEXTSTATE (427, 1142), (100, 50) */
NEXTSTATE Wait; NEXTSTATE Wait;
/* CIF STATE (1204, 151), (100, 50) */ /* CIF STATE (1204, 151), (100, 50) */
STATE Running; STATE Running;
...@@ -140,47 +148,47 @@ against current Length'; ...@@ -140,47 +148,47 @@ against current Length';
NEXTSTATE Running; NEXTSTATE Running;
ENDDECISION; ENDDECISION;
ENDSTATE; ENDSTATE;
/* CIF STATE (427, 1024), (100, 50) */ /* CIF STATE (427, 1142), (100, 50) */
STATE Wait; STATE Wait;
/* CIF INPUT (427, 1094), (100, 50) */ /* CIF INPUT (427, 1212), (100, 50) */
INPUT go(msg) INPUT go(msg)
/* CIF COMMENT (547, 1101), (120, 35) */ /* CIF COMMENT (547, 1219), (120, 35) */
COMMENT 'Ïñpût unicode'; COMMENT 'Ïñpût unicode';
/* CIF DECISION (420, 1159), (114, 70) */ /* CIF DECISION (420, 1277), (114, 70) */
DECISION msg = 'hello' DECISION msg = 'hello'
/* CIF COMMENT (554, 1169), (128, 50) */ /* CIF COMMENT (554, 1287), (128, 50) */
COMMENT 'Boolean test COMMENT 'Boolean test
on string value'; on string value';
/* CIF ANSWER (638, 1249), (100, 35) */ /* CIF ANSWER (638, 1367), (100, 35) */
(FALSE): (FALSE):
/* CIF OUTPUT (618, 1299), (139, 50) */ /* CIF OUTPUT (618, 1417), (139, 50) */
OUTPUT rezult(first_msg) OUTPUT rezult(first_msg)
/* CIF COMMENT (777, 1306), (85, 35) */ /* CIF COMMENT (777, 1424), (85, 35) */
COMMENT 'OûtpUT'; COMMENT 'OûtpUT';
/* CIF NEXTSTATE (638, 1364), (100, 50) */ /* CIF NEXTSTATE (638, 1482), (100, 50) */
NEXTSTATE Wait; NEXTSTATE Wait;
/* CIF ANSWER (367, 1249), (100, 35) */ /* CIF ANSWER (367, 1367), (100, 35) */
(TRUE): (TRUE):
/* CIF OUTPUT (344, 1299), (145, 50) */ /* CIF OUTPUT (344, 1417), (145, 50) */
OUTPUT rezult('Welcome') OUTPUT rezult('Welcome')
/* CIF COMMENT (509, 1299), (95, 50) */ /* CIF COMMENT (509, 1417), (95, 50) */
COMMENT 'Send raw COMMENT 'Send raw
string'; string';
/* CIF DECISION (368, 1364), (98, 50) */ /* CIF DECISION (368, 1482), (98, 50) */
DECISION 3 in {1,2,3}; DECISION 3 in {1,2,3};
/* CIF ANSWER (328, 1434), (88, 23) */ /* CIF ANSWER (328, 1552), (88, 23) */
(1 in {1,2}): (1 in {1,2}):
/* CIF ANSWER (418, 1434), (88, 23) */ /* CIF ANSWER (418, 1552), (88, 23) */
(0 in {1,2}): (0 in {1,2}):
ENDDECISION; ENDDECISION;
/* CIF DECISION (368, 1477), (98, 50) */ /* CIF DECISION (368, 1590), (98, 50) */
DECISION 4 in {1,2,3}; DECISION 4 in {1,2,3};
/* CIF ANSWER (337, 1547), (70, 23) */ /* CIF ANSWER (337, 1590), (70, 23) */
(true): (true):
/* CIF ANSWER (427, 1547), (70, 23) */ /* CIF ANSWER (427, 1590), (70, 23) */
(false): (false):
ENDDECISION; ENDDECISION;
/* CIF NEXTSTATE (367, 1590), (100, 50) */ /* CIF NEXTSTATE (367, 1628), (100, 50) */
NEXTSTATE Running; NEXTSTATE Running;
ENDDECISION; ENDDECISION;
ENDSTATE; ENDSTATE;
......
#include <stdio.h>
#include "dataview-uniq.h"
extern void adainit();
extern void og_go(asn1SccMy_OctStr *);
void og_RI_rezult (asn1SccMy_OctStr *val)
{
printf("[C] got something]\n");
}
int main() {
asn1SccMy_OctStr toto;
adainit();
og_go(&toto);
return 0;
}
#include <stdio.h>
#include "dataview-uniq.h"
extern void og_startup();
extern void og_go(asn1SccMy_OctStr *);
void og_RI_rezult (asn1SccMy_OctStr *val)
{
printf("[C] got something]\n");
}
int main() {
asn1SccMy_OctStr toto;
og_startup();
og_go(&toto);
return 0;
}
...@@ -8,11 +8,14 @@ edit: ...@@ -8,11 +8,14 @@ edit:
test-parse: test-parse:
$(OPENGEODE) orchestrator.pr system_structure.pr --check $(OPENGEODE) orchestrator.pr system_structure.pr --check
test-ada: orchestrator.ali test-ada: orchestrator.ali dataview-uniq.o | test_ada.o
$(GNATBIND) -n orchestrator.ali
$(GNATLINK) -o test_ada test_ada.o orchestrator.ali -lgnat
./test_ada
test-llvm: orchestrator.o test-llvm: orchestrator.o
coverage: coverage:
coverage run -p $(OPENGEODE) orchestrator.pr system_structure.pr --toAda coverage run -p $(OPENGEODE) orchestrator.pr system_structure.pr --toAda
.PHONY: all edit test-parse test-ada test-llvm coverage .PHONY: all edit test-parse test-ada test-llvm coverage
\ No newline at end of file
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
PROCESS orchestrator PROCESS orchestrator
/* CIF COMMENT (405, 192), (71, 35) */ /* CIF COMMENT (405, 192), (71, 35) */
COMMENT 'Hello'; COMMENT 'Hello';
/* CIF TEXT (0, 12), (289, 173) */ /* CIF TEXT (0, 12), (293, 200) */
-- GNC Orchestrator for the VEGA simulator -- GNC Orchestrator for the VEGA simulator
DCL gnc_output T_GNC_LV_SIM_INPUTS; DCL gnc_output T_GNC_LV_SIM_INPUTS;
...@@ -12,108 +12,111 @@ DCL gnc_input T_GNC_LV_SIM_CONTEXT; ...@@ -12,108 +12,111 @@ DCL gnc_input T_GNC_LV_SIM_CONTEXT;
DCL intr T_INTR; DCL intr T_INTR;
DCL plot_data T_Plot; DCL plot_data T_Plot;
dcl seq tastE_Peek_id_list := {1};
DCL major_cycle, sub_cycle T_UInt32; DCL major_cycle, sub_cycle T_UInt32;
/* CIF ENDTEXT */ /* CIF ENDTEXT */
/* CIF START (145, 208), (100, 50) */ /* CIF START (348, 208), (100, 45) */
START; START;
/* CIF PROCEDURECALL (100, 273), (189, 50) */ /* CIF TASK (311, 268), (172, 35) */
TASK seq := seq // {2} // {1};
/* CIF PROCEDURECALL (303, 318), (189, 50) */
CALL writeln CALL writeln
('[Orchestrator] Startup'); ('[Orchestrator] Startup');
/* CIF TASK (123, 338), (143, 50) */ /* CIF TASK (325, 383), (144, 50) */
TASK intr := obt_pulse4; TASK intr := obt_pulse4;
/* CIF OUTPUT (130, 403), (130, 35) */ /* CIF OUTPUT (333, 448), (130, 35) */
OUTPUT telemetry; OUTPUT telemetry;
/* CIF TASK (123, 453), (144, 50) */ /* CIF TASK (326, 498), (144, 50) */
TASK major_cycle := 1, TASK major_cycle := 1,
sub_cycle := 0; sub_cycle := 0;
/* CIF NEXTSTATE (137, 518), (116, 50) */ /* CIF NEXTSTATE (337, 563), (118, 50) */
NEXTSTATE Wait_for_GUI; NEXTSTATE Wait_for_GUI;
/* CIF STATE (856, 32), (100, 50) */ /* CIF STATE (1134, 32), (100, 50) */
STATE Running; STATE Running;
/* CIF INPUT (1111, 102), (136, 50) */ /* CIF INPUT (1388, 102), (136, 50) */
INPUT start_simulation INPUT start_simulation
(gnc_input) (gnc_input)
/* CIF COMMENT (1267, 102), (169, 50) */ /* CIF COMMENT (1546, 102), (169, 50) */
COMMENT 'Input from gui COMMENT 'Input from gui
stops the simulation'; stops the simulation';
/* CIF NEXTSTATE (1121, 167), (116, 50) */ /* CIF NEXTSTATE (1397, 167), (118, 50) */
NEXTSTATE Wait_for_GUI; NEXTSTATE Wait_for_GUI;
/* CIF INPUT (665, 102), (105, 50) */ /* CIF INPUT (943, 102), (105, 50) */
INPUT pulse INPUT pulse
/* CIF COMMENT (790, 102), (114, 50) */ /* CIF COMMENT (1068, 102), (114, 50) */
COMMENT 'Periodic call'; COMMENT 'Periodic call';
/* CIF PROCEDURECALL (529, 167), (377, 50) */ /* CIF PROCEDURECALL (798, 167), (393, 50) */
CALL S_SET_GNC_LV_SIM_CONTEXT_FOR_NEXT_MAJOR_CYCLE CALL S_SET_GNC_LV_SIM_CONTEXT_FOR_NEXT_MAJOR_CYCLE
(gnc_input) (gnc_input)
/* CIF COMMENT (923, 158), (173, 68) */ /* CIF COMMENT (1210, 158), (173, 72) */
COMMENT 'Set data computed COMMENT 'Set data computed
by the Simulink model by the Simulink model
(Simulator) in the GNC (Simulator) in the GNC
input vector'; input vector';
/* CIF PROCEDURECALL (667, 232), (100, 50) */ /* CIF PROCEDURECALL (945, 232), (100, 50) */
CALL Scheduler CALL Scheduler