qgenc_B_mapper.py 28.1 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#
# (C) Semantix Information Technologies.
#
# Copyright 2014-2015 IB Krates <info@krates.ee>
#       QGenc code generator integration
#
# Semantix Information Technologies is licensing the code of the
# Data Modelling Tools (DMT) in the following dual-license mode:
#
# Commercial Developer License:
#       The DMT Commercial Developer License is the suggested version
# to use for the development of proprietary and/or commercial software.
# This version is for developers/companies who do not want to comply
# with the terms of the GNU Lesser General Public License version 2.1.
#
# GNU LGPL v. 2.1:
#       This version of DMT is the one to use for the development of
# applications, when you are willing to comply with the terms of the
# GNU Lesser General Public License version 2.1.
#
# Note that in both cases, there are no charges (royalties) for the
# generated code.
#
'''
This is the code generator for the QGenC code mappers.
This backend is called by aadl2glueC, when a QGenC subprogram
is identified in the input concurrency view.

This code generator supports both UPER/ACN and Native encodings,
and also supports UPER/ACN using both ASN1SCC and Nokalva.

Matlab/QGenC is a member of the synchronous "club" (SCADE, etc) ;
The subsystem developer (or rather, the APLC developer) is
building a model in QGenC, and the generated code is offered
in the form of a "function" that does all the work.
To that end, we create "glue" functions for input and output
parameters, which have C callable interfaces. The necessary
stubs (to allow calling from the VM side) are also generated.
'''

41
from typing import List
42
from ..commonPy.utility import panicWithCallStack
43
44
from ..commonPy.asnAST import (
    sourceSequenceLimit, isSequenceVariable, AsnInt, AsnReal, AsnEnumerated,
45
46
    AsnBool, AsnSequenceOrSet, AsnSequenceOrSetOf, AsnChoice, AsnOctetString,
    AsnNode)
47
from ..commonPy.asnParser import AST_Lookup, AST_Leaftypes
48
from ..commonPy.aadlAST import AadlPort, AadlParameter, ApLevelContainer, Param
49
from ..commonPy.recursiveMapper import RecursiveMapper
50
51
52
53
54
55
from .synchronousTool import SynchronousToolGlueGenerator

isAsynchronous = False
qgencBackend = None


56
def IsElementMappedToPrimitive(node: AsnSequenceOrSetOf, names: AST_Lookup) -> bool:
57
58
59
60
61
62
    contained = node._containedType
    while isinstance(contained, str):
        contained = names[contained]
    return isinstance(contained, AsnInt) or isinstance(contained, AsnReal) or isinstance(contained, AsnBool) or isinstance(contained, AsnEnumerated)


Thanassis Tsiodras's avatar
Thanassis Tsiodras committed
63
# pylint: disable=no-self-use
64
class FromQGenCToASN1SCC(RecursiveMapper):
65
    def MapInteger(self, srcQGenC: str, destVar: str, _: AsnInt, __: AST_Leaftypes, ___: AST_Lookup) -> List[str]:  # pylint: disable=invalid-sequence-index
66
67
        return ["%s = (asn1SccSint) %s;\n" % (destVar, srcQGenC)]

68
    def MapReal(self, srcQGenC: str, destVar: str, _: AsnReal, __: AST_Leaftypes, ___: AST_Lookup) -> List[str]:  # pylint: disable=invalid-sequence-index
69
70
        return ["%s = (double) %s;\n" % (destVar, srcQGenC)]

71
    def MapBoolean(self, srcQGenC: str, destVar: str, _: AsnBool, __: AST_Leaftypes, ___: AST_Lookup) -> List[str]:  # pylint: disable=invalid-sequence-index
72
73
        return ["%s = (asn1SccUint) %s;\n" % (destVar, srcQGenC)]

74
    def MapOctetString(self, srcQGenC: str, destVar: str, node: AsnOctetString, _: AST_Leaftypes, __: AST_Lookup) -> List[str]:  # pylint: disable=invalid-sequence-index
Thanassis Tsiodras's avatar
Thanassis Tsiodras committed
75
        lines = []  # type: List[str]
76
        if not node._range:
77
78
79
80
81
82
            panicWithCallStack("OCTET STRING (in %s) must have a SIZE constraint inside ASN.1,\nor else we can't generate C code!" % node.Location())  # pragma: no cover
        for i in range(0, node._range[-1]):
            lines.append("%s.arr[%d] = %s.element_data[%d];\n" % (destVar, i, srcQGenC, i))
        if isSequenceVariable(node):
            lines.append("%s.nCount = %s.length;\n" % (destVar, srcQGenC))
        # No nCount anymore
83
84
        # else:
        #     lines.append("%s.nCount = %s;\n" % (destVar, node._range[-1]))
85
86
        return lines

87
    def MapEnumerated(self, srcQGenC: str, destVar: str, _: AsnEnumerated, __: AST_Leaftypes, ___: AST_Lookup) -> List[str]:  # pylint: disable=invalid-sequence-index
88
89
        return ["%s = %s;\n" % (destVar, srcQGenC)]

90
    def MapSequence(self, unused_srcQGenC: str, unused_destVar: str, node: AsnSequenceOrSet, leafTypeDict: AST_Leaftypes, names: AST_Lookup) -> List[str]:  # pylint: disable=invalid-sequence-index
Thanassis Tsiodras's avatar
Thanassis Tsiodras committed
91
        lines = []  # type: List[str]
92
93
94
95
96
97
98
99
100
101
        for child in node._members:
            lines.extend(
                self.Map(
                    "%s" % (self.CleanName(child[0])),
                    self.CleanName(child[0]),
                    child[1],
                    leafTypeDict,
                    names))
        return lines

102
    def MapSet(self, srcQGenC: str, destVar: str, node: AsnSequenceOrSet, leafTypeDict: AST_Leaftypes, names: AST_Lookup) -> List[str]:  # pylint: disable=invalid-sequence-index
103
104
        return self.MapSequence(srcQGenC, destVar, node, leafTypeDict, names)  # pragma: nocover

105
    def MapChoice(self, srcQGenC: str, destVar: str, node: AsnChoice, leafTypeDict: AST_Leaftypes, names: AST_Lookup) -> List[str]:  # pylint: disable=invalid-sequence-index
Thanassis Tsiodras's avatar
Thanassis Tsiodras committed
106
        lines = []  # type: List[str]
107
108
109
110
        childNo = 0
        for child in node._members:
            childNo += 1
            lines.append("%sif (%s.choiceIdx == %d) {\n" % (self.maybeElse(childNo), srcQGenC, childNo))
111
            lines.extend(
112
                ['    ' + x
113
114
115
116
117
118
                 for x in self.Map(
                     "%s.%s" % (srcQGenC, self.CleanName(child[0])),
                     destVar + ".u." + self.CleanName(child[0]),
                     child[1],
                     leafTypeDict,
                     names)])
119
120
121
122
            lines.append("    %s.kind = %s;\n" % (destVar, self.CleanName(child[2])))
            lines.append("}\n")
        return lines

123
    def MapSequenceOf(self, srcQGenC: str, destVar: str, node: AsnSequenceOrSetOf, leafTypeDict: AST_Leaftypes, names: AST_Lookup) -> List[str]:  # pylint: disable=invalid-sequence-index
124
        if not node._range:
125
126
            panicWithCallStack("need a SIZE constraint or else we can't generate C code (%s)!\n" % node.Location())  # pragma: no cover
        isMappedToPrimitive = IsElementMappedToPrimitive(node, names)
Thanassis Tsiodras's avatar
Thanassis Tsiodras committed
127
        lines = []  # type: List[str]
128
        for i in range(0, node._range[-1]):
129
            lines.extend(
130
                self.Map(("%s.element_data[%d]" % (srcQGenC, i)) if isMappedToPrimitive else ("%s.element_%02d" % (srcQGenC, i)),
131
132
133
134
135
136
137
                         destVar + ".arr[%d]" % i,
                         node._containedType,
                         leafTypeDict,
                         names))
        if isSequenceVariable(node):
            lines.append("%s.nCount = %s.length;\n" % (destVar, srcQGenC))
        # No nCount anymore
138
139
        # else:
        #     lines.append("%s.nCount = %s;\n" % (destVar, node._range[-1]))
140
141
        return lines

142
    def MapSetOf(self, srcQGenC: str, destVar: str, node: AsnSequenceOrSetOf, leafTypeDict: AST_Leaftypes, names: AST_Lookup) -> List[str]:  # pylint: disable=invalid-sequence-index
143
144
145
        return self.MapSequenceOf(srcQGenC, destVar, node, leafTypeDict, names)  # pragma: nocover


Thanassis Tsiodras's avatar
Thanassis Tsiodras committed
146
# pylint: disable=no-self-use
147
class FromASN1SCCtoQGenC(RecursiveMapper):
148
    def MapInteger(self, srcVar: str, dstQGenC: str, _: AsnInt, __: AST_Leaftypes, ___: AST_Lookup) -> List[str]:  # pylint: disable=invalid-sequence-index
149
150
        return ["%s = %s;\n" % (dstQGenC, srcVar)]

151
    def MapReal(self, srcVar: str, dstQGenC: str, _: AsnReal, __: AST_Leaftypes, ___: AST_Lookup) -> List[str]:  # pylint: disable=invalid-sequence-index
152
153
        return ["%s = %s;\n" % (dstQGenC, srcVar)]

154
    def MapBoolean(self, srcVar: str, dstQGenC: str, _: AsnBool, __: AST_Leaftypes, ___: AST_Lookup) -> List[str]:  # pylint: disable=invalid-sequence-index
155
156
        return ["%s = %s;\n" % (dstQGenC, srcVar)]

157
    def MapOctetString(self, srcVar: str, dstQGenC: str, node: AsnOctetString, _: AST_Leaftypes, __: AST_Lookup) -> List[str]:  # pylint: disable=invalid-sequence-index
158
        if not node._range:
159
160
            panicWithCallStack("OCTET STRING (in %s) must have a SIZE constraint inside ASN.1,\nor else we can't generate C code!" % node.Location())  # pragma: no cover

Thanassis Tsiodras's avatar
Thanassis Tsiodras committed
161
        lines = []  # type: List[str]
162
163
164
        limit = sourceSequenceLimit(node, srcVar)
        for i in range(0, node._range[-1]):
            lines.append("if (%s>=%d) %s.element_data[%d] = %s.arr[%d]; else %s.element_data[%d] = 0;\n" %
165
                         (limit, i + 1, dstQGenC, i, srcVar, i, dstQGenC, i))
166
        if len(node._range) > 1 and node._range[0] != node._range[1]:
167
168
169
            lines.append("%s.length = %s;\n" % (dstQGenC, limit))
        return lines

170
    def MapEnumerated(self, srcVar: str, dstQGenC: str, node: AsnEnumerated, __: AST_Leaftypes, ___: AST_Lookup) -> List[str]:  # pylint: disable=invalid-sequence-index
171
172
173
174
        if None in [x[1] for x in node._members]:
            panicWithCallStack("an ENUMERATED must have integer values! (%s)" % node.Location())  # pragma: no cover
        return ["%s = %s;\n" % (dstQGenC, srcVar)]

175
    def MapSequence(self, srcVar: str, dstQGenC: str, node: AsnSequenceOrSet, leafTypeDict: AST_Leaftypes, names: AST_Lookup) -> List[str]:  # pylint: disable=invalid-sequence-index
Thanassis Tsiodras's avatar
Thanassis Tsiodras committed
176
        lines = []  # type: List[str]
177
178
179
180
181
182
183
184
185
186
        for child in node._members:
            lines.extend(
                self.Map(
                    srcVar + "." + self.CleanName(child[0]),
                    "%s.%s" % (dstQGenC, self.CleanName(child[0])),
                    child[1],
                    leafTypeDict,
                    names))
        return lines

187
    def MapSet(self, srcVar: str, dstQGenC: str, node: AsnSequenceOrSet, leafTypeDict: AST_Leaftypes, names: AST_Lookup) -> List[str]:  # pylint: disable=invalid-sequence-index
188
189
        return self.MapSequence(srcVar, dstQGenC, node, leafTypeDict, names)  # pragma: nocover

190
    def MapChoice(self, srcVar: str, dstQGenC: str, node: AsnChoice, leafTypeDict: AST_Leaftypes, names: AST_Lookup) -> List[str]:  # pylint: disable=invalid-sequence-index
Thanassis Tsiodras's avatar
Thanassis Tsiodras committed
191
        lines = []  # type: List[str]
192
193
194
195
        childNo = 0
        for child in node._members:
            childNo += 1
            lines.append("%sif (%s.kind == %s) {\n" % (self.maybeElse(childNo), srcVar, self.CleanName(child[2])))
196
            lines.extend(
197
                ['    ' + x
198
199
200
201
202
203
                 for x in self.Map(
                     srcVar + ".u." + self.CleanName(child[0]),
                     "%s.%s" % (dstQGenC, self.CleanName(child[0])),
                     child[1],
                     leafTypeDict,
                     names)])
204
205
206
207
            lines.append("    %s.choiceIdx = %d;\n" % (dstQGenC, childNo))
            lines.append("}\n")
        return lines

208
    def MapSequenceOf(self, srcVar: str, dstQGenC: str, node: AsnSequenceOrSetOf, leafTypeDict: AST_Leaftypes, names: AST_Lookup) -> List[str]:  # pylint: disable=invalid-sequence-index
209
        if not node._range:
210
211
            panicWithCallStack("need a SIZE constraint or else we can't generate C code (%s)!\n" % node.Location())  # pragma: no cover
        isMappedToPrimitive = IsElementMappedToPrimitive(node, names)
Thanassis Tsiodras's avatar
Thanassis Tsiodras committed
212
        lines = []  # type: List[str]
213
214
215
        for i in range(0, node._range[-1]):
            lines.extend(self.Map(
                srcVar + ".arr[%d]" % i,
216
                ("%s.element_data[%d]" % (dstQGenC, i)) if isMappedToPrimitive else ("%s.element_%02d" % (dstQGenC, i)),
217
218
219
220
221
222
223
                node._containedType,
                leafTypeDict,
                names))
        if isSequenceVariable(node):
            lines.append("%s.length = %s.nCount;\n" % (dstQGenC, srcVar))
        return lines

224
    def MapSetOf(self, srcVar: str, dstQGenC: str, node: AsnSequenceOrSetOf, leafTypeDict: AST_Leaftypes, names: AST_Lookup) -> List[str]:  # pylint: disable=invalid-sequence-index
225
226
227
        return self.MapSequenceOf(srcVar, dstQGenC, node, leafTypeDict, names)  # pragma: nocover


Thanassis Tsiodras's avatar
Thanassis Tsiodras committed
228
# pylint: disable=no-self-use
229
class FromQGenCToOSS(RecursiveMapper):
230
    def MapInteger(self, srcQGenC: str, destVar: str, _: AsnInt, __: AST_Leaftypes, ___: AST_Lookup) -> List[str]:  # pylint: disable=invalid-sequence-index
231
232
        return ["%s = %s;\n" % (destVar, srcQGenC)]

233
    def MapReal(self, srcQGenC: str, destVar: str, _: AsnReal, __: AST_Leaftypes, ___: AST_Lookup) -> List[str]:  # pylint: disable=invalid-sequence-index
234
235
        return ["%s = %s;\n" % (destVar, srcQGenC)]

236
    def MapBoolean(self, srcQGenC: str, destVar: str, _: AsnBool, __: AST_Leaftypes, ___: AST_Lookup) -> List[str]:  # pylint: disable=invalid-sequence-index
237
238
        return ["%s = (char) %s;\n" % (destVar, srcQGenC)]

239
    def MapOctetString(self, srcQGenC: str, destVar: str, node: AsnOctetString, _: AST_Leaftypes, __: AST_Lookup) -> List[str]:  # pylint: disable=invalid-sequence-index
Thanassis Tsiodras's avatar
Thanassis Tsiodras committed
240
        lines = []  # type: List[str]
241
        if not node._range:
242
243
244
            panicWithCallStack("OCTET STRING (in %s) must have a SIZE constraint inside ASN.1,\nor else we can't generate C code!" % node.Location())  # pragma: no cover
        for i in range(0, node._range[-1]):
            lines.append("%s.value[%d] = %s.element_data[%d];\n" % (destVar, i, srcQGenC, i))
245
        if len(node._range) > 1 and node._range[0] != node._range[1]:
246
247
248
249
250
            lines.append("%s.length = %s.length;\n" % (destVar, srcQGenC))
        else:
            lines.append("%s.length = %s;\n" % (destVar, node._range[-1]))
        return lines

251
    def MapEnumerated(self, srcQGenC: str, destVar: str, _: AsnEnumerated, __: AST_Leaftypes, ___: AST_Lookup) -> List[str]:  # pylint: disable=invalid-sequence-index
252
253
        return ["%s = %s;\n" % (destVar, srcQGenC)]

254
    def MapSequence(self, srcQGenC: str, destVar: str, node: AsnSequenceOrSet, leafTypeDict: AST_Leaftypes, names: AST_Lookup) -> List[str]:  # pylint: disable=invalid-sequence-index
Thanassis Tsiodras's avatar
Thanassis Tsiodras committed
255
        lines = []  # type: List[str]
256
257
258
259
260
261
262
263
264
265
        for child in node._members:
            lines.extend(
                self.Map(
                    "%s.%s" % (srcQGenC, self.CleanName(child[0])),
                    destVar + "." + self.CleanName(child[0]),
                    child[1],
                    leafTypeDict,
                    names))
        return lines

266
    def MapSet(self, srcQGenC: str, destVar: str, node: AsnSequenceOrSet, leafTypeDict: AST_Leaftypes, names: AST_Lookup) -> List[str]:  # pylint: disable=invalid-sequence-index
267
268
        return self.MapSequence(srcQGenC, destVar, node, leafTypeDict, names)  # pragma: nocover

269
    def MapChoice(self, srcQGenC: str, destVar: str, node: AsnChoice, leafTypeDict: AST_Leaftypes, names: AST_Lookup) -> List[str]:  # pylint: disable=invalid-sequence-index
Thanassis Tsiodras's avatar
Thanassis Tsiodras committed
270
        lines = []  # type: List[str]
271
272
273
274
        childNo = 0
        for child in node._members:
            childNo += 1
            lines.append("%sif (%s.choiceIdx == %d) {\n" % (self.maybeElse(childNo), srcQGenC, childNo))
275
            lines.extend(
276
                ['    ' + x
277
278
279
280
281
282
                 for x in self.Map(
                     "%s.%s" % (srcQGenC, self.CleanName(child[0])),
                     destVar + ".u." + self.CleanName(child[0]),
                     child[1],
                     leafTypeDict,
                     names)])
283
284
285
286
            lines.append("    %s.choice = OSS_%s_chosen;\n" % (destVar, self.CleanName(child[0])))
            lines.append("}\n")
        return lines

287
    def MapSequenceOf(self, srcQGenC: str, destVar: str, node: AsnSequenceOrSetOf, leafTypeDict: AST_Leaftypes, names: AST_Lookup) -> List[str]:  # pylint: disable=invalid-sequence-index
288
        if not node._range:
289
290
            panicWithCallStack("(%s) needs a SIZE constraint or else we can't generate C code!\n" % node.Location())  # pragma: no cover
        isMappedToPrimitive = IsElementMappedToPrimitive(node, names)
Thanassis Tsiodras's avatar
Thanassis Tsiodras committed
291
        lines = []  # type: List[str]
292
        for i in range(0, node._range[-1]):
293
            lines.extend(
294
                self.Map(("%s.element_data[%d]" % (srcQGenC, i)) if isMappedToPrimitive else ("%s.element_%02d" % (srcQGenC, i)),
295
296
297
298
                         destVar + ".value[%d]" % i,
                         node._containedType,
                         leafTypeDict,
                         names))
299
        if len(node._range) > 1 and node._range[0] != node._range[1]:
300
301
302
303
304
            lines.append("%s.count = %s.length;\n" % (destVar, srcQGenC))
        else:
            lines.append("%s.count = %s;\n" % (destVar, node._range[-1]))
        return lines

305
    def MapSetOf(self, srcQGenC: str, destVar: str, node: AsnSequenceOrSetOf, leafTypeDict: AST_Leaftypes, names: AST_Lookup) -> List[str]:  # pylint: disable=invalid-sequence-index
306
307
308
        return self.MapSequenceOf(srcQGenC, destVar, node, leafTypeDict, names)  # pragma: nocover


Thanassis Tsiodras's avatar
Thanassis Tsiodras committed
309
# pylint: disable=no-self-use
310
class FromOSStoQGenC(RecursiveMapper):
311
    def MapInteger(self, srcVar: str, dstQGenC: str, _: AsnInt, __: AST_Leaftypes, ___: AST_Lookup) -> List[str]:  # pylint: disable=invalid-sequence-index
312
313
        return ["%s = %s;\n" % (dstQGenC, srcVar)]

314
    def MapReal(self, srcVar: str, dstQGenC: str, _: AsnReal, __: AST_Leaftypes, ___: AST_Lookup) -> List[str]:  # pylint: disable=invalid-sequence-index
315
316
        return ["%s = %s;\n" % (dstQGenC, srcVar)]

317
    def MapBoolean(self, srcVar: str, dstQGenC: str, _: AsnBool, __: AST_Leaftypes, ___: AST_Lookup) -> List[str]:  # pylint: disable=invalid-sequence-index
318
319
        return ["%s = %s;\n" % (dstQGenC, srcVar)]

320
    def MapOctetString(self, srcVar: str, dstQGenC: str, node: AsnOctetString, _: AST_Leaftypes, __: AST_Lookup) -> List[str]:  # pylint: disable=invalid-sequence-index
321
        if not node._range:
322
            panicWithCallStack("OCTET STRING (in %s) must have a SIZE constraint inside ASN.1,\nor else we can't generate C code!" % node.Location())  # pragma: no cover
Thanassis Tsiodras's avatar
Thanassis Tsiodras committed
323
        lines = []  # type: List[str]
324
325
        for i in range(0, node._range[-1]):
            lines.append("if (%s.length >= %d) %s.element_data[%d] = %s.value[%d]; else %s.element_data[%d] = 0;\n" %
326
                         (srcVar, i + 1, dstQGenC, i, srcVar, i, dstQGenC, i))
327
        if len(node._range) > 1 and node._range[0] != node._range[1]:
328
329
330
            lines.append("%s.length = %s.length;" % (dstQGenC, srcVar))
        return lines

331
    def MapEnumerated(self, srcVar: str, dstQGenC: str, node: AsnEnumerated, __: AST_Leaftypes, ___: AST_Lookup) -> List[str]:  # pylint: disable=invalid-sequence-index
332
333
334
335
        if None in [x[1] for x in node._members]:
            panicWithCallStack("an ENUMERATED must have integer values! (%s)" % node.Location())  # pragma: no cover
        return ["%s = %s;\n" % (dstQGenC, srcVar)]

336
    def MapSequence(self, srcVar: str, dstQGenC: str, node: AsnSequenceOrSet, leafTypeDict: AST_Leaftypes, names: AST_Lookup) -> List[str]:  # pylint: disable=invalid-sequence-index
Thanassis Tsiodras's avatar
Thanassis Tsiodras committed
337
        lines = []  # type: List[str]
338
339
340
341
342
343
344
345
346
347
        for child in node._members:
            lines.extend(
                self.Map(
                    srcVar + "." + self.CleanName(child[0]),
                    "%s.%s" % (dstQGenC, self.CleanName(child[0])),
                    child[1],
                    leafTypeDict,
                    names))
        return lines

348
    def MapSet(self, srcVar: str, dstQGenC: str, node: AsnSequenceOrSet, leafTypeDict: AST_Leaftypes, names: AST_Lookup) -> List[str]:  # pylint: disable=invalid-sequence-index
349
350
        return self.MapSequence(srcVar, dstQGenC, node, leafTypeDict, names)  # pragma: nocover

351
    def MapChoice(self, srcVar: str, dstQGenC: str, node: AsnChoice, leafTypeDict: AST_Leaftypes, names: AST_Lookup) -> List[str]:  # pylint: disable=invalid-sequence-index
Thanassis Tsiodras's avatar
Thanassis Tsiodras committed
352
        lines = []  # type: List[str]
353
354
355
356
        childNo = 0
        for child in node._members:
            childNo += 1
            lines.append("%sif (%s.choice == OSS_%s_chosen) {\n" % (self.maybeElse(childNo), srcVar, self.CleanName(child[0])))
357
            lines.extend(
358
                ['    ' + x
359
360
361
362
363
364
                 for x in self.Map(
                     srcVar + ".u." + self.CleanName(child[0]),
                     "%s.%s" % (dstQGenC, self.CleanName(child[0])),
                     child[1],
                     leafTypeDict,
                     names)])
365
366
367
368
            lines.append("    %s.choiceIdx = %d;\n" % (dstQGenC, childNo))
            lines.append("}\n")
        return lines

369
    def MapSequenceOf(self, srcVar: str, dstQGenC: str, node: AsnSequenceOrSetOf, leafTypeDict: AST_Leaftypes, names: AST_Lookup) -> List[str]:  # pylint: disable=invalid-sequence-index
370
        if not node._range:
371
372
            panicWithCallStack("(%s) needs a SIZE constraint or else we can't generate C code!\n" % node.Location())  # pragma: no cover
        isMappedToPrimitive = IsElementMappedToPrimitive(node, names)
Thanassis Tsiodras's avatar
Thanassis Tsiodras committed
373
        lines = []  # type: List[str]
374
375
376
        for i in range(0, node._range[-1]):
            lines.extend(self.Map(
                srcVar + ".value[%d]" % i,
377
                ("%s.element_data[%d]" % (dstQGenC, i)) if isMappedToPrimitive else ("%s.element_%02d" % (dstQGenC, i)),
378
379
380
                node._containedType,
                leafTypeDict,
                names))
381
        if len(node._range) > 1 and node._range[0] != node._range[1]:
382
383
384
            lines.append("%s.length = %s.count;\n" % (dstQGenC, srcVar))
        return lines

385
    def MapSetOf(self, srcVar: str, dstQGenC: str, node: AsnSequenceOrSetOf, leafTypeDict: AST_Leaftypes, names: AST_Lookup) -> List[str]:  # pylint: disable=invalid-sequence-index
386
387
388
389
        return self.MapSequenceOf(srcVar, dstQGenC, node, leafTypeDict, names)  # pragma: nocover


class QGenCGlueGenerator(SynchronousToolGlueGenerator):
Thanassis Tsiodras's avatar
Thanassis Tsiodras committed
390
    g_FVname = None  # type: str
391

392
    def Version(self) -> None:
393
394
        print("Code generator: " + "$Id: qgenc_B_mapper.py 2390 2014-11-27 12:39:17Z dtuulik $")  # pragma: no cover

395
    def FromToolToASN1SCC(self) -> RecursiveMapper:
396
397
        return FromQGenCToASN1SCC()

398
    def FromToolToOSS(self) -> RecursiveMapper:
399
400
        return FromQGenCToOSS()

401
    def FromASN1SCCtoTool(self) -> RecursiveMapper:
402
403
        return FromASN1SCCtoQGenC()

404
    def FromOSStoTool(self) -> RecursiveMapper:
405
406
        return FromOSStoQGenC()

407
    def HeadersOnStartup(self, unused_modelingLanguage: str, unused_asnFile: str, subProgram: ApLevelContainer, unused_subProgramImplementation: str, unused_outputDir: str, unused_maybeFVname: str) -> None:
408
409
410
411
412
413
414
415
416
417
418
        if self.useOSS:
            self.C_SourceFile.write(
                "#include \"%s.oss.h\" // OSS generated\n" % self.asn_name)
            self.C_SourceFile.write("extern OssGlobal *g_world;\n\n")
        self.C_SourceFile.write("#include \"%s.h\" // Space certified compiler generated\n" % self.asn_name)
        self.C_SourceFile.write("#include \"%s.h\"\n\n" % self.CleanNameAsToolWants(subProgram._id).lower())
        self.C_SourceFile.write("#include \"%s_types.h\"\n\n" % self.CleanNameAsToolWants(subProgram._id).lower())
        self.C_SourceFile.write("static comp_Input cInput;\n\n")
        self.C_SourceFile.write("static comp_Output cOutput;\n\n")
        self.g_FVname = subProgram._id

419
420
421
422
423
424
425
426
427
    def SourceVar(self,
                  unused_nodeTypename: str,
                  unused_encoding: str,
                  unused_node: AsnNode,
                  unused_subProgram: ApLevelContainer,
                  unused_subProgramImplementation: str,
                  param: Param,
                  unused_leafTypeDict: AST_Leaftypes,
                  unused_names: AST_Lookup) -> str:
428
        if isinstance(param._sourceElement, AadlPort):
429
            srcQGenC = "cOutput.%s" % param._id  # pragma: no cover
430
        elif isinstance(param._sourceElement, AadlParameter):
431
            srcQGenC = "cOutput.%s" % param._id
432
433
434
435
        else:  # pragma: no cover
            panicWithCallStack("%s not supported (yet?)\n" % str(param._sourceElement))  # pragma: no cover
        return srcQGenC

436
437
438
439
440
441
442
443
444
    def TargetVar(self,
                  unused_nodeTypename: str,
                  unused_encoding: str,
                  unused_node: AsnNode,
                  unused_subProgram: ApLevelContainer,
                  unused_subProgramImplementation: str,
                  param: Param,
                  unused_leafTypeDict: AST_Leaftypes,
                  unused_names: AST_Lookup) -> str:
445
        if isinstance(param._sourceElement, AadlPort):
446
            dstQGenC = "cInput.%s" % param._id  # pragma: no cover
447
        elif isinstance(param._sourceElement, AadlParameter):
448
            dstQGenC = "cInput.%s" % param._id
449
450
451
452
        else:  # pragma: no cover
            panicWithCallStack("%s not supported (yet?)\n" % str(param._sourceElement))  # pragma: no cover
        return dstQGenC

453
    def InitializeBlock(self, unused_modelingLanguage: str, unused_asnFile: str, unused_sp: ApLevelContainer, unused_subProgramImplementation: str, unused_maybeFVname: str) -> None:
454
455
456
457
458
459
        self.C_SourceFile.write("    static int initialized = 0;\n")
        self.C_SourceFile.write("    if (!initialized) {\n")
        self.C_SourceFile.write("        initialized = 1;\n")
        self.C_SourceFile.write("        %s_init();\n" % self.g_FVname)
        self.C_SourceFile.write("    }\n")

460
    def ExecuteBlock(self, unused_modelingLanguage: str, unused_asnFile: str, unused_sp: ApLevelContainer, unused_subProgramImplementation: str, unused_maybeFVname: str) -> None:
461
462
463
464
465
466
467
468
469
470
471
        self.C_SourceFile.write("#ifndef rtmGetStopRequested\n")
        self.C_SourceFile.write("    %s_comp(&cInput, &cOutput);\n" % self.g_FVname)
        self.C_SourceFile.write("#else\n")
        self.C_SourceFile.write("    if (!rtmGetStopRequested(%s_M)) {\n" % self.g_FVname)
        self.C_SourceFile.write("        %s_step(&cInput, &cOutput);\n" % self.g_FVname)
        self.C_SourceFile.write("        if (rtmGetStopRequested(%s_M)) { %s_terminate(); }\n" %
                                (self.g_FVname, self.g_FVname))
        self.C_SourceFile.write("    }\n")
        self.C_SourceFile.write("#endif\n")


472
def OnStartup(modelingLanguage: str, asnFile: str, subProgram: ApLevelContainer, subProgramImplementation: str, outputDir: str, maybeFVname: str, useOSS: bool) -> None:
473
474
475
476
477
    global qgencBackend
    qgencBackend = QGenCGlueGenerator()
    qgencBackend.OnStartup(modelingLanguage, asnFile, subProgram, subProgramImplementation, outputDir, maybeFVname, useOSS)


478
def OnBasic(nodeTypename: str, node: AsnNode, subProgram: ApLevelContainer, subProgramImplementation: str, param: Param, leafTypeDict: AST_Leaftypes, names: AST_Lookup) -> None:
479
480
481
    qgencBackend.OnBasic(nodeTypename, node, subProgram, subProgramImplementation, param, leafTypeDict, names)


482
def OnSequence(nodeTypename: str, node: AsnNode, subProgram: ApLevelContainer, subProgramImplementation: str, param: Param, leafTypeDict: AST_Leaftypes, names: AST_Lookup) -> None:
483
484
485
    qgencBackend.OnSequence(nodeTypename, node, subProgram, subProgramImplementation, param, leafTypeDict, names)


486
def OnSet(nodeTypename: str, node: AsnNode, subProgram: ApLevelContainer, subProgramImplementation: str, param: Param, leafTypeDict: AST_Leaftypes, names: AST_Lookup) -> None:
487
488
489
    qgencBackend.OnSet(nodeTypename, node, subProgram, subProgramImplementation, param, leafTypeDict, names)  # pragma: nocover


490
def OnEnumerated(nodeTypename: str, node: AsnNode, subProgram: ApLevelContainer, subProgramImplementation: str, param: Param, leafTypeDict: AST_Leaftypes, names: AST_Lookup) -> None:
491
492
493
    qgencBackend.OnEnumerated(nodeTypename, node, subProgram, subProgramImplementation, param, leafTypeDict, names)


494
def OnSequenceOf(nodeTypename: str, node: AsnNode, subProgram: ApLevelContainer, subProgramImplementation: str, param: Param, leafTypeDict: AST_Leaftypes, names: AST_Lookup) -> None:
495
496
497
    qgencBackend.OnSequenceOf(nodeTypename, node, subProgram, subProgramImplementation, param, leafTypeDict, names)


498
def OnSetOf(nodeTypename: str, node: AsnNode, subProgram: ApLevelContainer, subProgramImplementation: str, param: Param, leafTypeDict: AST_Leaftypes, names: AST_Lookup) -> None:
499
500
501
    qgencBackend.OnSetOf(nodeTypename, node, subProgram, subProgramImplementation, param, leafTypeDict, names)  # pragma: nocover


502
def OnChoice(nodeTypename: str, node: AsnNode, subProgram: ApLevelContainer, subProgramImplementation: str, param: Param, leafTypeDict: AST_Leaftypes, names: AST_Lookup) -> None:
503
504
505
    qgencBackend.OnChoice(nodeTypename, node, subProgram, subProgramImplementation, param, leafTypeDict, names)


506
def OnShutdown(modelingLanguage: str, asnFile: str, sp: ApLevelContainer, subProgramImplementation: str, maybeFVname: str) -> None:
507
    qgencBackend.OnShutdown(modelingLanguage, asnFile, sp, subProgramImplementation, maybeFVname)