Commit b3055210 authored by Maxime Perrotin's avatar Maxime Perrotin

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):
'''
assert type_ref is not None
if type_ref is UNKNOWN_TYPE:
#print traceback.print_stack()
raise TypeError('Type reference is unknown')
basic_type = find_basic_type(type_ref)
......@@ -650,7 +651,8 @@ def check_type_compatibility(primary, type_ref, context):
+ basic_type.Min + ')')
elif isinstance(primary, ogAST.PrimSequenceOf) \
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)):
raise TypeError(str(len(primary.value)) +
' elements in SEQUENCE OF, while constraint is [' +
......@@ -782,11 +784,20 @@ def compare_types(type_a, type_b):
if type_a.kind == type_b.kind:
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)
return
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
return
elif is_string(type_a) and is_string(type_b):
......@@ -862,20 +873,6 @@ def fix_expression_types(expr, context):
fix_enumerated_and_choice(expr, context)
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):
if side.is_raw:
raw_expr = side
......@@ -884,11 +881,11 @@ def fix_expression_types(expr, context):
ref_type = typed_expr.exprType
# If a side is a raw Sequence Of with unknown type, try to resolve it
for side in permutations(('left', 'right')):
value = getattr(expr, side[0]) # get expr.left then expr.right
for side_a, side_b in permutations(('left', 'right')):
value = getattr(expr, side_a) # get expr.left then expr.right
if not isinstance(value, ogAST.PrimSequenceOf):
continue
other = getattr(expr, side[1]) # other side
other = getattr(expr, side_b) # other side
basic = find_basic_type(value.exprType)
if basic.kind == 'SequenceOfType' and basic.type == UNKNOWN_TYPE:
asn_type = find_basic_type(other.exprType)
......@@ -969,9 +966,14 @@ def fix_expression_types(expr, context):
if expr.right.is_raw != expr.left.is_raw:
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
# that can be computed
# Also true for raw SEQOF and String - Min/Max must not change
# Substrings: CHECKME XXX
raw_expr.exprType = ref_type
else:
compare_types(expr.left.exprType, expr.right.exprType)
......@@ -1061,6 +1063,8 @@ def binary_expression(root, context):
fix_expression_types(expr, context)
except (AttributeError, TypeError) as err:
errors.append(error(root, str(err)))
except Warning as warn:
warnings.append(warning(root, str(warn)))
return expr, errors, warnings
......@@ -1277,14 +1281,20 @@ def append_expression(root, context):
''' Append expression analysis '''
expr, errors, warnings = binary_expression(root, context)
for bty in (find_basic_type(expr.left.exprType),
find_basic_type(expr.right.exprType)):
left = find_basic_type(expr.left.exprType)
right = find_basic_type(expr.right.exprType)
for bty in (left, right):
if bty.kind != 'SequenceOfType' and not is_string(bty):
msg = 'Append can only be applied to types SequenceOf or String'
errors.append(error(root, msg))
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
......@@ -1507,20 +1517,23 @@ def primary_substring(root, context):
if receiver_bty.kind == 'SequenceOfType' or \
receiver_bty.kind.endswith('StringType'):
node.exprType = receiver.exprType
# Check bounds
min0 = float(find_basic_type(params[0].exprType).Min)
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)
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):
msg = 'Substring bounds are invalid'
errors.append(error(root, msg))
if int(min0) > int(basic.Max) \
or int(max1) > int(basic.Max):
if int(min0) > int(receiver_bty.Max) \
or int(max1) > int(receiver_bty.Max):
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))
else:
msg = 'Substring can only be applied to types SequenceOf or String'
......@@ -1660,7 +1673,7 @@ def primary(root, context):
'kind': 'SequenceOfType',
'Min': str(len(root.children)),
'Max': str(len(root.children)),
'type': UNKNOWN_TYPE
'type': prim_elem.exprType #UNKNOWN_TYPE
})
elif root.type == lexer.BITSTR:
prim = ogAST.PrimBitStringLiteral()
......@@ -1717,7 +1730,8 @@ def variables(root, ta_ast, context):
expr.right.inputString + ', type= ' +
type_name(expr.right.exprType) + ') ' + str(err))
else:
def_value.exprType = asn1_sort
if def_value.exprType == UNKNOWN_TYPE:
def_value.exprType = asn1_sort
if not def_value.is_raw and \
not isinstance(def_value, ogAST.PrimConstant):
......@@ -3525,13 +3539,19 @@ def assign(root, context):
if basic.kind.startswith(('Integer', 'Real')):
check_range(basic, find_basic_type(expr.right.exprType))
except(AttributeError, TypeError) as err:
errors.append('Types are incompatible in assignment: left (' +
errors.append('Type mismatch: left (' +
expr.left.inputString + ', type= ' +
type_name(expr.left.exprType) + '), right (' +
expr.right.inputString + ', type= ' +
(type_name(expr.right.exprType)
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
return expr, errors, warnings
......
......@@ -8,11 +8,18 @@ edit:
test-parse:
$(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 run -p $(OPENGEODE) og.pr system_structure.pr --toAda
.PHONY: all edit test-parse test-ada test-llvm coverage
\ No newline at end of file
.PHONY: all edit test-parse test-ada test-llvm coverage
......@@ -49,38 +49,46 @@ defined in the ASN.1 model';
two SEQUENCE OF';
/* CIF TASK (408, 484), (137, 50) */
TASK 'seq(1) := seq(2)';
/* CIF TASK (380, 549), (193, 50) */
TASK seq := seq(1,2) // seq(4,5)
/* CIF COMMENT (593, 549), (166, 50) */
/* CIF TASK (382, 549), (189, 50) */
TASK seq := seq(0,1) // seq(3, 4)
/* CIF COMMENT (590, 549), (166, 50) */
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
/* CIF COMMENT (549, 629), (170, 39) */
/* CIF COMMENT (549, 747), (170, 39) */
COMMENT 'Test the "in" operator
Unicode test: Ï';
/* CIF ANSWER (335, 704), (100, 35) */
/* CIF ANSWER (335, 822), (100, 35) */
(TRUE):
/* CIF PROCEDURECALL (308, 754), (154, 50) */
/* CIF PROCEDURECALL (308, 872), (154, 50) */
CALL writeln('All OK (1)');
/* CIF ANSWER (498, 704), (100, 35) */
/* CIF ANSWER (498, 822), (100, 35) */
(FALSE):
/* CIF PROCEDURECALL (466, 754), (164, 50) */
/* CIF PROCEDURECALL (466, 872), (164, 50) */
CALL writeln('NOT OK (1)')
/* CIF COMMENT (650, 761), (117, 35) */
/* CIF COMMENT (650, 879), (117, 35) */
COMMENT 'Call UnicÔDË';
ENDDECISION;
/* CIF DECISION (427, 819), (100, 70) */
DECISION 3 in seq;
/* CIF ANSWER (341, 909), (100, 35) */
/* CIF DECISION (427, 937), (100, 70) */
DECISION 3 in seq
/* CIF COMMENT (547, 954), (256, 35) */
COMMENT 'test==3 so it should also return true';
/* CIF ANSWER (341, 1027), (100, 35) */
(TRUE):
/* CIF PROCEDURECALL (309, 959), (164, 50) */
CALL writeln('NOT OK (2)');
/* CIF ANSWER (513, 909), (100, 35) */
/* CIF PROCEDURECALL (309, 1077), (164, 50) */
CALL writeln('ALL OK (2)');
/* CIF ANSWER (513, 1027), (100, 35) */
(FALSE):
/* CIF PROCEDURECALL (482, 959), (161, 50) */
CALL writeln('All OK (2)');
/* CIF PROCEDURECALL (481, 1077), (164, 50) */
CALL writeln('NOT OK (2)');
ENDDECISION;
/* CIF NEXTSTATE (427, 1024), (100, 50) */
/* CIF NEXTSTATE (427, 1142), (100, 50) */
NEXTSTATE Wait;
/* CIF STATE (1204, 151), (100, 50) */
STATE Running;
......@@ -140,47 +148,47 @@ against current Length';
NEXTSTATE Running;
ENDDECISION;
ENDSTATE;
/* CIF STATE (427, 1024), (100, 50) */
/* CIF STATE (427, 1142), (100, 50) */
STATE Wait;
/* CIF INPUT (427, 1094), (100, 50) */
/* CIF INPUT (427, 1212), (100, 50) */
INPUT go(msg)
/* CIF COMMENT (547, 1101), (120, 35) */
/* CIF COMMENT (547, 1219), (120, 35) */
COMMENT 'Ïñpût unicode';
/* CIF DECISION (420, 1159), (114, 70) */
/* CIF DECISION (420, 1277), (114, 70) */
DECISION msg = 'hello'
/* CIF COMMENT (554, 1169), (128, 50) */
/* CIF COMMENT (554, 1287), (128, 50) */
COMMENT 'Boolean test
on string value';
/* CIF ANSWER (638, 1249), (100, 35) */
/* CIF ANSWER (638, 1367), (100, 35) */
(FALSE):
/* CIF OUTPUT (618, 1299), (139, 50) */
/* CIF OUTPUT (618, 1417), (139, 50) */
OUTPUT rezult(first_msg)
/* CIF COMMENT (777, 1306), (85, 35) */
/* CIF COMMENT (777, 1424), (85, 35) */
COMMENT 'OûtpUT';
/* CIF NEXTSTATE (638, 1364), (100, 50) */
/* CIF NEXTSTATE (638, 1482), (100, 50) */
NEXTSTATE Wait;
/* CIF ANSWER (367, 1249), (100, 35) */
/* CIF ANSWER (367, 1367), (100, 35) */
(TRUE):
/* CIF OUTPUT (344, 1299), (145, 50) */
/* CIF OUTPUT (344, 1417), (145, 50) */
OUTPUT rezult('Welcome')
/* CIF COMMENT (509, 1299), (95, 50) */
/* CIF COMMENT (509, 1417), (95, 50) */
COMMENT 'Send raw
string';
/* CIF DECISION (368, 1364), (98, 50) */
/* CIF DECISION (368, 1482), (98, 50) */
DECISION 3 in {1,2,3};
/* CIF ANSWER (328, 1434), (88, 23) */
/* CIF ANSWER (328, 1552), (88, 23) */
(1 in {1,2}):
/* CIF ANSWER (418, 1434), (88, 23) */
/* CIF ANSWER (418, 1552), (88, 23) */
(0 in {1,2}):
ENDDECISION;
/* CIF DECISION (368, 1477), (98, 50) */
/* CIF DECISION (368, 1590), (98, 50) */
DECISION 4 in {1,2,3};
/* CIF ANSWER (337, 1547), (70, 23) */
/* CIF ANSWER (337, 1590), (70, 23) */
(true):
/* CIF ANSWER (427, 1547), (70, 23) */
/* CIF ANSWER (427, 1590), (70, 23) */
(false):
ENDDECISION;
/* CIF NEXTSTATE (367, 1590), (100, 50) */
/* CIF NEXTSTATE (367, 1628), (100, 50) */
NEXTSTATE Running;
ENDDECISION;
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:
test-parse:
$(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
coverage:
coverage run -p $(OPENGEODE) orchestrator.pr system_structure.pr --toAda
.PHONY: all edit test-parse test-ada test-llvm coverage
\ No newline at end of file
.PHONY: all edit test-parse test-ada test-llvm coverage
......@@ -2,7 +2,7 @@
PROCESS orchestrator
/* CIF COMMENT (405, 192), (71, 35) */
COMMENT 'Hello';
/* CIF TEXT (0, 12), (289, 173) */
/* CIF TEXT (0, 12), (293, 200) */
-- GNC Orchestrator for the VEGA simulator
DCL gnc_output T_GNC_LV_SIM_INPUTS;
......@@ -12,108 +12,111 @@ DCL gnc_input T_GNC_LV_SIM_CONTEXT;
DCL intr T_INTR;
DCL plot_data T_Plot;
dcl seq tastE_Peek_id_list := {1};
DCL major_cycle, sub_cycle T_UInt32;
/* CIF ENDTEXT */
/* CIF START (145, 208), (100, 50) */
/* CIF START (348, 208), (100, 45) */
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
('[Orchestrator] Startup');
/* CIF TASK (123, 338), (143, 50) */
/* CIF TASK (325, 383), (144, 50) */
TASK intr := obt_pulse4;
/* CIF OUTPUT (130, 403), (130, 35) */
/* CIF OUTPUT (333, 448), (130, 35) */
OUTPUT telemetry;
/* CIF TASK (123, 453), (144, 50) */
/* CIF TASK (326, 498), (144, 50) */
TASK major_cycle := 1,
sub_cycle := 0;
/* CIF NEXTSTATE (137, 518), (116, 50) */
/* CIF NEXTSTATE (337, 563), (118, 50) */
NEXTSTATE Wait_for_GUI;
/* CIF STATE (856, 32), (100, 50) */
/* CIF STATE (1134, 32), (100, 50) */
STATE Running;
/* CIF INPUT (1111, 102), (136, 50) */
/* CIF INPUT (1388, 102), (136, 50) */
INPUT start_simulation
(gnc_input)
/* CIF COMMENT (1267, 102), (169, 50) */
/* CIF COMMENT (1546, 102), (169, 50) */
COMMENT 'Input from gui
stops the simulation';
/* CIF NEXTSTATE (1121, 167), (116, 50) */
/* CIF NEXTSTATE (1397, 167), (118, 50) */
NEXTSTATE Wait_for_GUI;
/* CIF INPUT (665, 102), (105, 50) */
/* CIF INPUT (943, 102), (105, 50) */
INPUT pulse
/* CIF COMMENT (790, 102), (114, 50) */
/* CIF COMMENT (1068, 102), (114, 50) */
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
(gnc_input)
/* CIF COMMENT (923, 158), (173, 68) */
/* CIF COMMENT (1210, 158), (173, 72) */
COMMENT 'Set data computed
by the Simulink model
(Simulator) in the GNC
input vector';
/* CIF PROCEDURECALL (667, 232), (100, 50) */
/* CIF PROCEDURECALL (945, 232), (100, 50) */
CALL Scheduler
(intr)
/* CIF COMMENT (788, 232), (170, 50) */
/* CIF COMMENT (1066, 232), (170, 50) */
COMMENT 'Call the GNC function';
/* CIF PROCEDURECALL (534, 297), (366, 50) */
/* CIF PROCEDURECALL (805, 297), (380, 50) */
CALL S_GET_GNC_LV_SIM_INPUTS_FOR_NEXT_MAJOR_CYCLE
(gnc_output)
/* CIF COMMENT (921, 297), (175, 50) */
/* CIF COMMENT (1207, 297), (175, 50) */
COMMENT 'Read output data
from the GNC function';
/* CIF PROCEDURECALL (627, 362), (181, 50) */
/* CIF PROCEDURECALL (903, 362), (183, 50) */
CALL VESAT_Simulation_Step
(gnc_output, gnc_input)
/* CIF COMMENT (828, 362), (182, 50) */
/* CIF COMMENT (1108, 362), (182, 50) */
COMMENT 'Call the Simulink model';
/* CIF DECISION (624, 427), (187, 115) */
/* CIF DECISION (902, 427), (187, 115) */
DECISION major_cycle mod 50 = 0
and
sub_cycle = 0
/* CIF COMMENT (831, 459), (250, 50) */
/* CIF COMMENT (1109, 459), (250, 50) */
COMMENT 'Plot only every 50 major cycles
(otherwise performance is too low)';
/* CIF ANSWER (608, 562), (100, 35) */
/* CIF ANSWER (886, 562), (100, 35) */
(true):
/* CIF TASK (520, 612), (276, 68) */
/* CIF TASK (798, 612), (276, 72) */
TASK plot_data!major_cycle := major_cycle,
plot_data!subcycle := sub_cycle mod 7,
plot_data!gnc_inputs := gnc_input,
plot_data!gnc_outputs := gnc_output;
/* CIF OUTPUT (578, 695), (159, 50) */
/* CIF OUTPUT (856, 699), (159, 50) */
OUTPUT plot(plot_data);
/* CIF ANSWER (803, 562), (100, 35) */
/* CIF ANSWER (1081, 562), (100, 35) */
(false):
ENDDECISION;
/* CIF DECISION (658, 760), (118, 70) */
/* CIF DECISION (936, 764), (118, 70) */
DECISION sub_cycle = 7
/* CIF COMMENT (797, 770), (199, 50) */
/* CIF COMMENT (1075, 774), (199, 50) */
COMMENT 'Compute next major cycle';
/* CIF ANSWER (519, 850), (100, 35) */
/* CIF ANSWER (797, 854), (100, 35) */
(true):
/* CIF TASK (427, 900), (283, 53) */
/* CIF TASK (705, 904), (283, 53) */
TASK sub_cycle := 0,
major_cycle := (major_cycle + 1) mod 100;
/* CIF PROCEDURECALL (449, 968), (240, 50) */
/* CIF PROCEDURECALL (722, 972), (249, 50) */
CALL S_JUMP_TO_NEXT_MAJOR_CYCLE;
/* CIF ANSWER (799, 850), (100, 35) */
/* CIF ANSWER (1077, 854), (100, 35) */
(false):
/* CIF TASK (720, 900), (257, 50) */
/* CIF TASK (998, 904), (257, 50) */
TASK sub_cycle := (sub_cycle + 1) mod 100;
ENDDECISION;
/* CIF NEXTSTATE (668, 1033), (100, 50) */
/* CIF NEXTSTATE (946, 1037), (100, 50) */
NEXTSTATE Running;
ENDSTATE;
/* CIF STATE (336, 53), (116, 50) */
/* CIF STATE (538, 53), (118, 50) */
STATE Wait_for_GUI;
/* CIF INPUT (326, 123), (136, 50) */
/* CIF INPUT (530, 123), (136, 50) */
INPUT start_simulation
(gnc_input);
/* CIF PROCEDURECALL (299, 188), (190, 50) */
/* CIF PROCEDURECALL (502, 188), (193, 50) */
CALL writeln
('[Orchestrator] Running');
/* CIF NEXTSTATE (344, 253), (100, 50) */
/* CIF NEXTSTATE (549, 253), (100, 50) */
NEXTSTATE Running;
ENDSTATE;
ENDPROCESS orchestrator;
\ No newline at end of file
#include <math.h>
#include <stdio.h>
#include "dataview-uniq.h"
extern void adainit();
void orchestrator_RI_telemetry(void *_){}
void orchestrator_RI_S_SET_GNC_LV_SIM_CONTEXT_FOR_NEXT_MAJOR_CYCLE(void *_){}
void orchestrator_RI_Scheduler(void *_){}
void orchestrator_RI_VESAT_Simulation_Step(void *_){}
void orchestrator_RI_plot(void *_) {}
void orchestrator_RI_S_JUMP_TO_NEXT_MAJOR_CYCLE() {}
void orchestrator_RI_S_GET_GNC_LV_SIM_INPUTS_FOR_NEXT_MAJOR_CYCLE(void *_){}
int main()
{
printf("[C Code] Running test\n");
adainit();
return 0;
}
Markdown is supported
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