Linux GNU 11.4.0 Code Coverage Report


Directory: ./
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 30.1% 157 / 0 / 522
Functions: 52.8% 19 / 0 / 36
Branches: 24.2% 48 / 0 / 198

OMCompiler/SimulationRuntime/c/util/read_write.c
Line Branch Exec Source
1 /*
2 * This file belongs to the OpenModelica Run-Time System
3 *
4 * Copyright (c) 1998-2026, Open Source Modelica Consortium (OSMC), c/o Linköpings
5 * universitet, Department of Computer and Information Science, SE-58183 Linköping, Sweden. All rights
6 * reserved.
7 *
8 * THIS PROGRAM IS PROVIDED UNDER THE TERMS OF THE BSD NEW LICENSE OR THE
9 * AGPL VERSION 3 LICENSE OR THE OSMC PUBLIC LICENSE (OSMC-PL) VERSION 1.8. ANY
10 * USE, REPRODUCTION OR DISTRIBUTION OF THIS PROGRAM CONSTITUTES RECIPIENT'S
11 * ACCEPTANCE OF THE BSD NEW LICENSE OR THE OSMC PUBLIC LICENSE OR THE AGPL
12 * VERSION 3, ACCORDING TO RECIPIENTS CHOICE.
13 *
14 * The OpenModelica software and the OSMC (Open Source Modelica Consortium) Public License
15 * (OSMC-PL) are obtained from OSMC, either from the above address, from the URLs:
16 * http://www.openmodelica.org or https://github.com/OpenModelica/ or
17 * http://www.ida.liu.se/projects/OpenModelica, and in the OpenModelica distribution. GNU
18 * AGPL version 3 is obtained from: https://www.gnu.org/licenses/licenses.html#GPL. The BSD NEW
19 * License is obtained from: http://www.opensource.org/licenses/BSD-3-Clause.
20 *
21 * This program is distributed WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, EXCEPT AS EXPRESSLY
23 * SET FORTH IN THE BY RECIPIENT SELECTED SUBSIDIARY LICENSE CONDITIONS OF
24 * OSMC-PL.
25 *
26 */
27
28 #if defined(__cplusplus)
29 extern "C"
30 {
31 #endif
32
33 #include "read_write.h"
34 #include "omc_strdup.h"
35 /* The MetaModelica build also converts type_descriptions to MMC values. */
36 #if defined(OMC_METAMODELICA_RUNTIME)
37 #include "../meta/meta_modelica.h"
38 #else
39 #include "omc_string.h"
40 #endif
41 #include "real_array.h"
42 #include "integer_array.h"
43 #include "boolean_array.h"
44 #include "string_array.h"
45 #include <string.h>
46
47 24 int getMyBool(const type_description *desc)
48 {
49
1/2
✓ Branch 0 taken 24 times.
✗ Branch 1 not taken.
24 switch (desc->type) {
50 24 case TYPE_DESC_BOOL:
51 /*fprintf(stderr,"returning %d\n",desc->data.boolean ? 1:0);*/
52 24 return desc->data.boolean ? 1:0;
53 default:
54 /*fprintf(stderr, "UNKNOWN: Values.Value!\n");*/
55 break;
56 }
57 return 0;
58 }
59 #if 1 /* only used for debug */
60 ✗ void puttype(const type_description *desc)
61 {
62 ✗ fprintf(stderr, "TYPE[%d] -> ", desc->type);
63 ✗ switch (desc->type) {
64 ✗ case TYPE_DESC_REAL:
65 ✗ fprintf(stderr, "REAL: %g\n", desc->data.real);
66 break;
67 ✗ case TYPE_DESC_INT:
68 ✗ fprintf(stderr, "INT: " OMC_INT_FORMAT "\n", desc->data.integer);
69 break;
70 ✗ case TYPE_DESC_BOOL:
71 ✗ fprintf(stderr, "BOOL: %c\n", desc->data.boolean ? 't' : 'f');
72 break;
73 ✗ case TYPE_DESC_STRING:
74 ✗ fprintf(stderr, "STR: '%s'\n", desc->data.string);
75 break;
76 ✗ case TYPE_DESC_TUPLE: {
77 size_t e;
78 ✗ fprintf(stderr, "TUPLE (%u):\n", (unsigned) desc->data.tuple.elements);
79 ✗ for(e = 0; e < desc->data.tuple.elements; ++e) {
80 ✗ fprintf(stderr, "\t");
81 ✗ puttype(desc->data.tuple.element + e);
82 }
83 }
84 break;
85 ✗ case TYPE_DESC_REAL_ARRAY: {
86 int d;
87 ✗ fprintf(stderr, "REAL ARRAY [%d] (", desc->data.r_array.ndims);
88 ✗ for(d = 0; d < desc->data.r_array.ndims; ++d) {
89 ✗ fprintf(stderr, "%d, ", (int) desc->data.r_array.dim_size[d]);
90 }
91 ✗ fprintf(stderr, ")\n");
92 ✗ if(desc->data.r_array.ndims == 1) {
93 int e;
94 ✗ fprintf(stderr, "\t[");
95 ✗ for(e = 0; e < desc->data.r_array.dim_size[0]; ++e) {
96 ✗ fprintf(stderr, "%g, ",
97 ✗ ((modelica_real *) desc->data.r_array.data)[e]);
98 }
99 ✗ fprintf(stderr, "]\n");
100 }
101 }
102 break;
103 ✗ case TYPE_DESC_INT_ARRAY: {
104 int d;
105 ✗ fprintf(stderr, "INT ARRAY [%d] (", desc->data.int_array.ndims);
106 ✗ for(d = 0; d < desc->data.int_array.ndims; ++d) {
107 ✗ fprintf(stderr, "%d, ", (int) desc->data.int_array.dim_size[d]);
108 }
109 ✗ fprintf(stderr, ")\n");
110 ✗ if(desc->data.int_array.ndims == 1) {
111 int e;
112 ✗ fprintf(stderr, "\t[");
113 ✗ for(e = 0; e < desc->data.int_array.dim_size[0]; ++e) {
114 ✗ fprintf(stderr, OMC_INT_FORMAT ", ", ((modelica_integer *) desc->data.int_array.data)[e]);
115 }
116 ✗ fprintf(stderr, "]\n");
117 }
118 }
119 break;
120 ✗ case TYPE_DESC_BOOL_ARRAY: {
121 int d;
122 ✗ fprintf(stderr, "BOOL ARRAY [%d] (", desc->data.bool_array.ndims);
123 ✗ for(d = 0; d < desc->data.bool_array.ndims; ++d) {
124 ✗ fprintf(stderr, "%d, ", (int) desc->data.bool_array.dim_size[d]);
125 }
126 ✗ fprintf(stderr, ")\n");
127 ✗ if(desc->data.bool_array.ndims == 1) {
128 int e;
129 ✗ fprintf(stderr, "\t[");
130 ✗ for(e = 0; e < desc->data.bool_array.dim_size[0]; ++e) {
131 ✗ fprintf(stderr, "%c, ",
132 ✗ ((modelica_boolean *) desc->data.bool_array.data)[e] ? 'T':'F');
133 }
134 ✗ fprintf(stderr, "]\n");
135 }
136 }
137 break;
138 ✗ case TYPE_DESC_STRING_ARRAY: {
139 int d;
140 ✗ fprintf(stderr, "STRING ARRAY [%d] (", desc->data.str_array.ndims);
141 ✗ for(d = 0; d < desc->data.str_array.ndims; ++d) {
142 ✗ fprintf(stderr, "%d, ", (int) desc->data.str_array.dim_size[d]);
143 }
144 ✗ fprintf(stderr, ")\n");
145 ✗ if(desc->data.str_array.ndims == 1) {
146 int e;
147 ✗ fprintf(stderr, "\t[");
148 ✗ for(e = 0; e < desc->data.str_array.dim_size[0]; ++e) {
149 ✗ fprintf(stderr, "%s, ", desc->data.str_array.data[e]);
150 }
151 ✗ fprintf(stderr, "]\n");
152 }
153 }
154 break;
155 ✗ case TYPE_DESC_COMPLEX:
156 ✗ fprintf(stderr, "COMPLEX\n");
157 break;
158 ✗ case TYPE_DESC_NONE:
159 ✗ fprintf(stderr, "NONE\n");
160 break;
161 ✗ case TYPE_DESC_RECORD: {
162 size_t i;
163 ✗ fprintf(stderr, "RECORD: %s ", desc->data.record.record_name?desc->data.record.record_name:"[no name]");
164 ✗ if(!desc->data.record.elements) {
165 ✗ fprintf(stderr, "has no members!?\n");
166 } else {
167 ✗ fprintf(stderr, "has the following members:\n");
168 }
169 ✗ for(i = 0; i < desc->data.record.elements; i++) {
170 ✗ fprintf(stderr, "NAME: %s\n", desc->data.record.name[i]);
171 ✗ puttype(&(desc->data.record.element[i]));
172 }
173 }
174 break;
175 ✗ case TYPE_DESC_MMC:
176 #if defined(OMC_METAMODELICA_RUNTIME)
177 ✗ fprintf(stderr, "%s\n", anyString(desc->data.mmc));
178 #else
179 ✗ fprintf(stderr, "<metatype>\n");
180 #endif
181 break;
182 ✗ default:
183 ✗ fprintf(stderr, "UNKNOWN: Values.Value!\n");
184 break;
185 }
186 ✗ fflush(stderr);
187 ✗ }
188 #endif
189
190 ✗ static void in_report(const char *str)
191 {
192 ✗ fprintf(stderr, "input failed: %s\n", str); fflush(stderr);
193 ✗ }
194
195 static type_description *add_tuple_item(type_description *desc);
196
197 862 void init_type_description(type_description *desc)
198 {
199 862 desc->type = TYPE_DESC_NONE;
200 862 desc->retval = 0;
201 862 memset(&(desc->data), 0, sizeof(desc->data));
202 862 }
203
204 488 void free_type_description(type_description *desc)
205 {
206
6/8
✓ Branch 0 taken 41 times.
✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 3 times.
✓ Branch 5 taken 27 times.
✓ Branch 6 taken 22 times.
✓ Branch 7 taken 388 times.
488 switch (desc->type) {
207 case TYPE_DESC_NONE:
208 break;
209 case TYPE_DESC_REAL:
210 case TYPE_DESC_INT:
211 case TYPE_DESC_BOOL:
212 break;
213 41 case TYPE_DESC_STRING:
214
2/2
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 13 times.
41 if(desc->retval) {
215 28 free((void*) desc->data.string);
216 }
217 break;
218 7 case TYPE_DESC_REAL_ARRAY:
219
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 4 times.
7 if(desc->retval) {
220 3 free(desc->data.r_array.dim_size);
221 3 free(desc->data.r_array.data);
222 }
223 break;
224 ✗ case TYPE_DESC_INT_ARRAY:
225 ✗ if(desc->retval) {
226 ✗ free(desc->data.int_array.dim_size);
227 ✗ free(desc->data.int_array.data);
228 }
229 break;
230 ✗ case TYPE_DESC_BOOL_ARRAY:
231 ✗ if(desc->retval) {
232 ✗ free(desc->data.bool_array.dim_size);
233 ✗ free(desc->data.bool_array.data);
234 }
235 break;
236 3 case TYPE_DESC_STRING_ARRAY:
237
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 1 time.
3 if(desc->retval) {
238 size_t i, n = str_array_nr_of_elements(desc->data.str_array);
239
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 2 times.
7 for(i = 0; i < n; ++i) {
240 5 free((void*) desc->data.str_array.data[i]);
241 }
242 2 free(desc->data.str_array.dim_size);
243 2 free(desc->data.str_array.data);
244 }
245 break;
246 27 case TYPE_DESC_TUPLE: {
247 size_t i;
248 27 type_description *e = desc->data.tuple.element;
249
2/2
✓ Branch 0 taken 120 times.
✓ Branch 1 taken 27 times.
147 for(i = 0; i < desc->data.tuple.elements; ++i, ++e) {
250 120 free_type_description(e);
251 }
252
1/2
✓ Branch 0 taken 27 times.
✗ Branch 1 not taken.
27 if(desc->data.tuple.elements > 0) {
253 27 free(desc->data.tuple.element);
254 }
255 }
256 break;
257 case TYPE_DESC_FUNCTION:
258 case TYPE_DESC_MMC:
259 case TYPE_DESC_COMPLEX:
260 case TYPE_DESC_NORETCALL:
261 break;
262 22 case TYPE_DESC_RECORD: {
263 size_t i;
264 22 type_description *e = desc->data.record.element;
265 /* char **n = desc->data.record.name; */
266
2/2
✓ Branch 0 taken 47 times.
✓ Branch 1 taken 22 times.
69 for(i = 0; i < desc->data.record.elements; i++, e++) {
267 47 free(desc->data.record.name[i]);
268 47 free_type_description(e);
269 }
270
2/2
✓ Branch 0 taken 21 times.
✓ Branch 1 taken 1 time.
22 if(desc->data.record.elements > 0) {
271 21 free(desc->data.record.element);
272 21 free(desc->data.record.name);
273 }
274 }
275 break;
276 }
277 488 }
278
279 29 int read_modelica_real(type_description **descptr, modelica_real *data)
280 {
281 29 type_description *desc = (*descptr)++;
282
1/3
✓ Branch 0 taken 29 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
29 switch (desc->type) {
283 29 case TYPE_DESC_REAL:
284 29 *data = desc->data.real;
285 29 return 0;
286 ✗ case TYPE_DESC_INT:
287 ✗ *data = (modelica_real)desc->data.integer;
288 ✗ return 0;
289 default:
290 break;
291 }
292 ✗ in_report("rs type");
293 ✗ fprintf(stderr, "Expected real scalar, got:"); puttype(desc); fflush(stderr);
294 ✗ return -1;
295 }
296
297 67 int read_modelica_integer(type_description **descptr, modelica_integer *data)
298 {
299 67 type_description *desc = (*descptr)++;
300
1/2
✓ Branch 0 taken 67 times.
✗ Branch 1 not taken.
67 switch (desc->type) {
301 67 case TYPE_DESC_INT:
302 67 *data = desc->data.integer;
303 67 return 0;
304 default:
305 break;
306 }
307
308 ✗ in_report("is type");
309 ✗ fprintf(stderr, "Expected integer scalar, got:"); puttype(desc); fflush(stderr);
310 ✗ return -1;
311 }
312
313 7 int read_modelica_boolean(type_description **descptr, modelica_boolean *data)
314 {
315 7 type_description *desc = (*descptr)++;
316
1/2
✓ Branch 0 taken 7 times.
✗ Branch 1 not taken.
7 switch (desc->type) {
317 7 case TYPE_DESC_BOOL:
318 7 *data = desc->data.boolean;
319 7 return 0;
320 default:
321 break;
322 }
323
324 ✗ in_report("bs type");
325 ✗ fprintf(stderr, "Expected boolean scalar, got:"); puttype(desc); fflush(stderr);
326 ✗ return -1;
327 }
328
329 1 int read_real_array(type_description **descptr, real_array *arr)
330 {
331 1 type_description *desc = (*descptr)++;
332
1/3
✓ Branch 0 taken 1 time.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
1 switch (desc->type) {
333 1 case TYPE_DESC_REAL_ARRAY:
334 1 *arr = desc->data.r_array;
335 1 return 0;
336 ✗ case TYPE_DESC_INT_ARRAY:
337 ✗ cast_integer_array_to_real(&(desc->data.int_array), arr);
338 ✗ return 0;
339 default:
340 break;
341 }
342
343 ✗ in_report("ra type");
344 ✗ fprintf(stderr, "Expected real array, got:"); puttype(desc); fflush(stderr);
345 ✗ return -1;
346 }
347
348 ✗ int read_integer_array(type_description **descptr, integer_array *arr)
349 {
350 ✗ type_description *desc = (*descptr)++;
351 ✗ switch (desc->type) {
352 ✗ case TYPE_DESC_INT_ARRAY:
353 ✗ *arr = desc->data.int_array;
354 ✗ return 0;
355 ✗ case TYPE_DESC_REAL_ARRAY:
356 /* Empty arrays automaticly get to be real arrays */
357 ✗ if(desc->data.r_array.dim_size[desc->data.r_array.ndims - 1] == 0) {
358 int dims = desc->data.r_array.ndims;
359 _index_t *dim_size = desc->data.r_array.dim_size;
360 ✗ desc->type = TYPE_DESC_INT_ARRAY;
361 desc->data.int_array.ndims = dims;
362 desc->data.int_array.dim_size = dim_size;
363 ✗ alloc_integer_array_data(&(desc->data.int_array));
364 ✗ *arr = desc->data.int_array;
365 ✗ return 0;
366 }
367 break;
368 default:
369 break;
370 }
371
372 ✗ in_report("ia type");
373 ✗ fprintf(stderr, "Expected integer array, got:"); puttype(desc); fflush(stderr);
374 ✗ return -1;
375 }
376
377 ✗ int read_boolean_array(type_description **descptr, boolean_array *arr)
378 {
379 ✗ type_description *desc = (*descptr)++;
380 ✗ switch (desc->type) {
381 ✗ case TYPE_DESC_BOOL_ARRAY:
382 ✗ *arr = desc->data.bool_array;
383 ✗ return 0;
384 ✗ case TYPE_DESC_REAL_ARRAY:
385 /* Empty arrays automaticly get to be real arrays */
386 ✗ if(desc->data.r_array.dim_size[desc->data.r_array.ndims - 1] == 0) {
387 int dims = desc->data.r_array.ndims;
388 _index_t *dim_size = desc->data.r_array.dim_size;
389 ✗ desc->type = TYPE_DESC_BOOL_ARRAY;
390 desc->data.bool_array.ndims = dims;
391 desc->data.bool_array.dim_size = dim_size;
392 ✗ alloc_boolean_array_data(&(desc->data.bool_array));
393 ✗ *arr = desc->data.bool_array;
394 ✗ return 0;
395 }
396 break;
397 default:
398 break;
399 }
400
401 ✗ in_report("ba type");
402 ✗ fprintf(stderr, "Expected boolean array, got:"); puttype(desc); fflush(stderr);
403 ✗ return -1;
404 }
405
406 ✗ static void alloc_desc_string_array(string_array *arr, int ndims, const _index_t *dim_size)
407 {
408 int i;
409 ✗ arr->ndims = ndims;
410 ✗ arr->dim_size = size_alloc(ndims);
411 ✗ for(i = 0; i < ndims; ++i) {
412 ✗ arr->dim_size[i] = dim_size[i];
413 }
414 ✗ arr->flexible = 0;
415 ✗ arr->owns_data = 1;
416 ✗ alloc_string_array_data(arr);
417 ✗ }
418
419 ✗ int read_string_array(type_description **descptr, string_array *arr)
420 {
421 ✗ type_description *desc = (*descptr)++;
422 ✗ switch (desc->type) {
423 ✗ case TYPE_DESC_STRING_ARRAY: {
424 size_t i, n;
425 modelica_string *dst;
426 ✗ alloc_desc_string_array(arr, desc->data.str_array.ndims, desc->data.str_array.dim_size);
427 ✗ n = base_array_nr_of_elements(*arr);
428 ✗ dst = (modelica_string*) arr->data;
429 ✗ for(i = 0; i < n; ++i) {
430 ✗ dst[i] = omc_string_new(desc->data.str_array.data[i]);
431 }
432 return 0;
433 }
434 ✗ case TYPE_DESC_REAL_ARRAY:
435 /* Empty arrays automaticly get to be real arrays */
436 ✗ if(desc->data.r_array.dim_size[desc->data.r_array.ndims - 1] == 0) {
437 ✗ alloc_desc_string_array(arr, desc->data.r_array.ndims, desc->data.r_array.dim_size);
438 ✗ return 0;
439 }
440 break;
441 default:
442 break;
443 }
444
445 ✗ in_report("sa type");
446 ✗ fprintf(stderr, "Expected string array, got:"); puttype(desc); fflush(stderr);
447 ✗ return -1;
448 }
449
450 28 void write_modelica_real(type_description *desc, const modelica_real *data)
451 {
452
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 18 times.
28 if(desc->type != TYPE_DESC_NONE) {
453 10 desc = add_tuple_item(desc);
454 }
455 28 desc->type = TYPE_DESC_REAL;
456 28 desc->data.real = *data;
457 28 }
458
459 39 void write_modelica_integer(type_description *desc, const modelica_integer *data)
460 {
461
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 30 times.
39 if(desc->type != TYPE_DESC_NONE) {
462 9 desc = add_tuple_item(desc);
463 }
464 39 desc->type = TYPE_DESC_INT;
465 39 desc->data.integer = *data;
466 39 }
467
468 24 void write_modelica_boolean(type_description *desc, const modelica_boolean *data)
469 {
470
2/2
✓ Branch 0 taken 21 times.
✓ Branch 1 taken 3 times.
24 if(desc->type != TYPE_DESC_NONE) {
471 21 desc = add_tuple_item(desc);
472 }
473 24 desc->type = TYPE_DESC_BOOL;
474 24 desc->data.boolean = *data;
475 24 }
476
477 4 void write_noretcall(type_description *desc)
478 {
479 4 desc->type = TYPE_DESC_NORETCALL;
480 4 }
481
482 ✗ void write_real_array(type_description *desc, const real_array *arr)
483 {
484 ✗ if(desc->type != TYPE_DESC_NONE) {
485 ✗ desc = add_tuple_item(desc);
486 }
487 ✗ desc->type = TYPE_DESC_REAL_ARRAY;
488 ✗ if(desc->retval) {
489 /* Can't use memory pool for these */
490 size_t nr_elements;
491 ✗ desc->data.r_array.ndims = arr->ndims;
492 ✗ desc->data.r_array.dim_size = (_index_t*)malloc(sizeof(*(arr->dim_size)) * arr->ndims);
493 ✗ memcpy(desc->data.r_array.dim_size, arr->dim_size, sizeof(*(arr->dim_size)) * arr->ndims);
494 ✗ nr_elements = base_array_nr_of_elements(*arr);
495 ✗ desc->data.r_array.data = malloc(sizeof(modelica_real) * nr_elements);
496 ✗ memcpy(desc->data.r_array.data, arr->data,
497 sizeof(modelica_real) * nr_elements);
498 } else {
499 ✗ copy_real_array(*arr, &(desc->data.r_array));
500 }
501 ✗ }
502
503 ✗ void write_integer_array(type_description *desc, const integer_array *arr)
504 {
505 ✗ if(desc->type != TYPE_DESC_NONE) {
506 ✗ desc = add_tuple_item(desc);
507 }
508 ✗ desc->type = TYPE_DESC_INT_ARRAY;
509 ✗ if(desc->retval) {
510 /* Can't use memory pool for these */
511 size_t nr_elements;
512 ✗ desc->data.int_array.ndims = arr->ndims;
513 ✗ desc->data.int_array.dim_size = (_index_t*)malloc(sizeof(*(arr->dim_size)) * arr->ndims);
514 ✗ memcpy(desc->data.int_array.dim_size, arr->dim_size, sizeof(*(arr->dim_size)) * arr->ndims);
515 ✗ nr_elements = base_array_nr_of_elements(*arr);
516 ✗ desc->data.int_array.data = malloc(sizeof(modelica_integer) * nr_elements);
517 ✗ memcpy(desc->data.int_array.data, arr->data,
518 sizeof(modelica_integer) * nr_elements);
519 } else {
520 ✗ clone_integer_array_spec(arr, &(desc->data.int_array));
521 ✗ integer_array_copy_data(*arr, desc->data.int_array);
522 }
523 ✗ }
524
525 ✗ void write_boolean_array(type_description *desc, const boolean_array *arr)
526 {
527 ✗ if(desc->type != TYPE_DESC_NONE) {
528 ✗ desc = add_tuple_item(desc);
529 }
530 ✗ desc->type = TYPE_DESC_BOOL_ARRAY;
531 ✗ if(desc->retval) {
532 /* Can't use memory pool for these */
533 size_t nr_elements;
534 ✗ desc->data.bool_array.ndims = arr->ndims;
535 ✗ desc->data.bool_array.dim_size = (_index_t*)malloc(sizeof(*(arr->dim_size)) * arr->ndims);
536 ✗ memcpy(desc->data.bool_array.dim_size, arr->dim_size, sizeof(*(arr->dim_size)) * arr->ndims);
537 ✗ nr_elements = base_array_nr_of_elements(*arr);
538 ✗ desc->data.bool_array.data = malloc(sizeof(modelica_boolean) * nr_elements);
539 ✗ memcpy(desc->data.bool_array.data, arr->data,
540 sizeof(modelica_boolean) * nr_elements);
541 } else {
542 ✗ copy_boolean_array(*arr, &(desc->data.bool_array));
543 }
544 ✗ }
545
546 ✗ void write_string_array(type_description *desc, const string_array *arr)
547 {
548 ✗ if(desc->type != TYPE_DESC_NONE) {
549 ✗ desc = add_tuple_item(desc);
550 }
551 ✗ desc->type = TYPE_DESC_STRING_ARRAY;
552 {
553 size_t i, nr_elements;
554 const char **dst;
555 const modelica_string *src;
556 ✗ desc->data.str_array.ndims = arr->ndims;
557 ✗ desc->data.str_array.dim_size = (_index_t*)malloc(sizeof(*(arr->dim_size)) * arr->ndims);
558 ✗ memcpy(desc->data.str_array.dim_size, arr->dim_size, sizeof(*(arr->dim_size)) * arr->ndims);
559 ✗ nr_elements = base_array_nr_of_elements(*arr);
560 ✗ desc->data.str_array.data = (const char**) malloc(sizeof(const char*) * nr_elements);
561 dst = desc->data.str_array.data;
562 ✗ src = (const modelica_string*) arr->data;
563 /* As write_modelica_string: the caller reads this after the callee's
564 frame, and its releases, are gone. */
565 ✗ for(i = 0; i < nr_elements; ++i) {
566 ✗ dst[i] = omc_strdup(omc_string_data(src[i]));
567 }
568 }
569 ✗ }
570
571 12 int read_modelica_string(type_description **descptr, modelica_string *str)
572 {
573 12 type_description *desc = (*descptr)++;
574
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
12 switch (desc->type) {
575 12 case TYPE_DESC_STRING:
576 12 *str = omc_string_new(desc->data.string);
577 12 return 0;
578 default:
579 break;
580 }
581
582 ✗ in_report("ms type");
583 ✗ return -1;
584 }
585
586 27 void write_modelica_string(type_description *desc, modelica_string *str)
587 {
588
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 23 times.
27 if(desc->type != TYPE_DESC_NONE) {
589 4 desc = add_tuple_item(desc);
590 }
591 27 desc->type = TYPE_DESC_STRING;
592
1/2
✓ Branch 0 taken 27 times.
✗ Branch 1 not taken.
27 if(desc->retval) {
593 /* The caller reads this after the callee's frame, and its releases, are
594 gone; free_type_description gives it back. */
595 27 desc->data.string = omc_strdup(omc_string_data(*str));
596 } else {
597 ✗ *str = omc_string_new(desc->data.string);
598 }
599 27 }
600
601 ✗ int read_modelica_complex(type_description **descptr, modelica_complex *data)
602 {
603 ✗ type_description *desc = (*descptr)++;
604 ✗ switch (desc->type) {
605 ✗ case TYPE_DESC_COMPLEX:
606 ✗ *data = desc->data.om_complex;
607 ✗ return 0;
608 default:
609 break;
610 }
611
612 ✗ in_report("mc type");
613 ✗ return -1;
614 }
615
616 ✗ void write_modelica_complex(type_description *desc, const modelica_complex *data)
617 {
618 ✗ if(desc->type != TYPE_DESC_NONE) {
619 ✗ desc = add_tuple_item(desc);
620 }
621 ✗ desc->type = TYPE_DESC_COMPLEX;
622 ✗ desc->data.om_complex = *data;
623 ✗ }
624
625 /* function pointer functions - added by stefan */
626
627 ✗ int read_modelica_fnptr(type_description **descptr, modelica_fnptr *fn)
628 {
629 ✗ type_description *desc = (*descptr)++;
630 ✗ switch(desc->type) {
631 ✗ case TYPE_DESC_FUNCTION:
632 ✗ *fn = desc->data.function;
633 ✗ return 0;
634 default:
635 break;
636 }
637
638 ✗ in_report("mc type");
639 ✗ return -1;
640 }
641
642 ✗ void write_modelica_fnptr(type_description *desc, const modelica_fnptr *fn)
643 {
644 ✗ if(desc->type != TYPE_DESC_NONE) {
645 ✗ desc = add_tuple_item(desc);
646 }
647 ✗ desc->type = TYPE_DESC_FUNCTION;
648 ✗ desc->data.function = *fn;
649 ✗ }
650
651 #if defined(OMC_METAMODELICA_RUNTIME)
652 /* Converting a type_description to a MetaModelica value: only the compiler
653 does this, and only its build links the boxing primitives. */
654 40 int read_modelica_metatype(type_description **descptr, modelica_metatype *ut)
655 {
656 40 type_description *desc = (*descptr)++;
657
1/6
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 40 times.
✗ Branch 5 not taken.
40 switch(desc->type) {
658 ✗ case TYPE_DESC_INT:
659 ✗ *ut = mmc_mk_icon(desc->data.integer);
660 ✗ return 0;
661 ✗ case TYPE_DESC_REAL:
662 ✗ *ut = mmc_mk_rcon(desc->data.real);
663 ✗ return 0;
664 ✗ case TYPE_DESC_STRING:
665 ✗ *ut = mmc_mk_scon(desc->data.string);
666 ✗ return 0;
667 ✗ case TYPE_DESC_BOOL:
668 ✗ *ut = mmc_mk_icon((desc->data.boolean == 0) ? 0 : 1);
669 ✗ return 0;
670 40 case TYPE_DESC_MMC:
671 40 *ut = desc->data.mmc;
672 40 return 0;
673 default:
674 break;
675 }
676
677 ✗ in_report("MMC type");
678 ✗ return -1;
679 }
680 #endif /* OMC_METAMODELICA_RUNTIME */
681
682 45 void write_modelica_metatype(type_description *desc, const modelica_metatype *ut)
683 {
684
2/2
✓ Branch 0 taken 17 times.
✓ Branch 1 taken 28 times.
45 if(desc->type != TYPE_DESC_NONE) {
685 17 desc = add_tuple_item(desc);
686 }
687 45 desc->type = TYPE_DESC_MMC;
688 45 desc->data.mmc = *ut;
689 45 }
690
691 5 static int read_modelica_record_helper(type_description **descptr, va_list *arg)
692 {
693 5 type_description *desc = (*descptr)++;
694 5 type_description *elem = NULL;
695 size_t e;
696
1/2
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
5 switch (desc->type) {
697 5 case TYPE_DESC_RECORD:
698 5 elem = desc->data.record.element;
699
2/2
✓ Branch 0 taken 15 times.
✓ Branch 1 taken 5 times.
20 for(e = 0; e < desc->data.record.elements; ++e) {
700
3/16
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✓ Branch 2 taken 5 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 5 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 5 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
15 switch (elem->type) {
701 case TYPE_DESC_NONE:
702 return -1;
703 ✗ case TYPE_DESC_REAL:
704 ✗ read_modelica_real(&elem, va_arg(*arg, modelica_real *));
705 ✗ break;
706 ✗ case TYPE_DESC_REAL_ARRAY:
707 ✗ read_real_array(&elem, va_arg(*arg, real_array *));
708 ✗ break;
709 5 case TYPE_DESC_INT:
710 5 read_modelica_integer(&elem, va_arg(*arg, modelica_integer *));
711 5 break;
712 ✗ case TYPE_DESC_INT_ARRAY:
713 ✗ read_integer_array(&elem, va_arg(*arg, integer_array *));
714 ✗ break;
715 5 case TYPE_DESC_BOOL:
716 5 read_modelica_boolean(&elem, va_arg(*arg, modelica_boolean *));
717 5 break;
718 ✗ case TYPE_DESC_BOOL_ARRAY:
719 ✗ read_boolean_array(&elem, va_arg(*arg, boolean_array *));
720 ✗ break;
721 5 case TYPE_DESC_STRING:
722 5 read_modelica_string(&elem, va_arg(*arg, modelica_string *));
723 5 break;
724 ✗ case TYPE_DESC_STRING_ARRAY:
725 ✗ read_string_array(&elem, va_arg(*arg, string_array *));
726 ✗ break;
727 ✗ case TYPE_DESC_TUPLE:
728 ✗ in_report("tuple in record is unsupported.");
729 ✗ return -1;
730 ✗ case TYPE_DESC_COMPLEX:
731 ✗ read_modelica_complex(&elem, va_arg(*arg, modelica_complex *));
732 ✗ break;
733 ✗ case TYPE_DESC_MMC:
734 #if defined(OMC_METAMODELICA_RUNTIME)
735 ✗ read_modelica_metatype(&elem, va_arg(*arg, void **));
736 #endif
737 ✗ break;
738 ✗ case TYPE_DESC_RECORD:
739 ✗ read_modelica_record_helper(&elem, arg);
740 ✗ break;
741 ✗ case TYPE_DESC_FUNCTION:
742 ✗ in_report("function pointer in record is unsupported.");
743 ✗ return -1;
744 ✗ case TYPE_DESC_NORETCALL:
745 ✗ in_report("noretcall in record is invalid.");
746 ✗ return -1;
747 }
748 }
749 return 0;
750 default:
751 break;
752 }
753
754 ✗ in_report("mr type");
755 ✗ return -1;
756 }
757
758 5 int read_modelica_record(type_description **descptr, ...)
759 {
760 va_list arg;
761 int res;
762 5 va_start(arg, descptr);
763 5 res = read_modelica_record_helper(descptr,&arg);
764 5 va_end(arg);
765 5 return res;
766 }
767
768 27 type_description *add_modelica_record_member(type_description *desc,
769 const char *name, size_t nlen)
770 {
771 type_description *elem;
772
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 27 times.
27 assert(desc->type == TYPE_DESC_RECORD);
773 27 desc->data.record.name = (char**)realloc(desc->data.record.name, sizeof(char *)
774 27 * (desc->data.record.elements + 1));
775 27 desc->data.record.element = (struct type_desc_s*)realloc(desc->data.record.element,
776 sizeof(struct type_desc_s)
777 27 * (desc->data.record.elements + 1));
778 27 elem = desc->data.record.element + desc->data.record.elements;
779 27 desc->data.record.name[desc->data.record.elements] = (char*)malloc(nlen + 1);
780 27 memcpy(desc->data.record.name[desc->data.record.elements], name, nlen + 1);
781 27 ++desc->data.record.elements;
782 27 init_type_description(elem);
783 27 return elem;
784 }
785
786 /* Help write_modelica_record work recursively. sjoelund */
787 ✗ static void write_modelica_record_helper(type_description *desc, const void* rec_desc_void, va_list* arg)
788 {
789 enum type_desc_e type;
790 ✗ const struct record_description rec_desc = *((const struct record_description*) rec_desc_void);
791 ✗ if(desc->type != TYPE_DESC_NONE) {
792 ✗ desc = add_tuple_item(desc);
793 }
794 ✗ desc->type = TYPE_DESC_RECORD;
795 ✗ desc->data.record.record_name = rec_desc.path;
796 ✗ desc->data.record.elements = 0;
797 ✗ desc->data.record.name = NULL;
798 ✗ desc->data.record.element = NULL;
799 /* atleast small enums gets casted to ints */
800 ✗ while((type = (enum type_desc_e) va_arg(*arg, int)) != TYPE_DESC_NONE) {
801 type_description *elem;
802 const char *name;
803 size_t nlen;
804 ✗ name = rec_desc.fieldNames[desc->data.record.elements];
805 ✗ nlen = strlen(name);
806
807 ✗ elem = add_modelica_record_member(desc, name, nlen);
808 ✗ elem->retval = desc->retval;
809
810 ✗ switch (type) {
811 case TYPE_DESC_NONE:
812 break;
813 ✗ case TYPE_DESC_REAL:
814 ✗ write_modelica_real(elem, va_arg(*arg, modelica_real *));
815 ✗ break;
816 ✗ case TYPE_DESC_REAL_ARRAY:
817 ✗ write_real_array(elem, va_arg(*arg, real_array *));
818 ✗ break;
819 ✗ case TYPE_DESC_INT:
820 ✗ write_modelica_integer(elem, va_arg(*arg, modelica_integer *));
821 ✗ break;
822 ✗ case TYPE_DESC_INT_ARRAY:
823 ✗ write_integer_array(elem, va_arg(*arg, integer_array *));
824 ✗ break;
825 ✗ case TYPE_DESC_BOOL:
826 ✗ write_modelica_boolean(elem, va_arg(*arg, modelica_boolean *));
827 ✗ break;
828 ✗ case TYPE_DESC_BOOL_ARRAY:
829 ✗ write_boolean_array(elem, va_arg(*arg, boolean_array *));
830 ✗ break;
831 ✗ case TYPE_DESC_STRING:
832 ✗ write_modelica_string(elem, va_arg(*arg, modelica_string *));
833 ✗ break;
834 ✗ case TYPE_DESC_STRING_ARRAY:
835 ✗ write_string_array(elem, va_arg(*arg, string_array *));
836 ✗ break;
837 ✗ case TYPE_DESC_COMPLEX:
838 ✗ write_modelica_complex(elem, va_arg(*arg, modelica_complex *));
839 ✗ break;
840 ✗ case TYPE_DESC_MMC:
841 ✗ write_modelica_metatype(elem, va_arg(*arg, void **));
842 ✗ break;
843 ✗ case TYPE_DESC_TUPLE:
844 ✗ in_report("tuple in record is unsupported.");
845 ✗ assert(0);
846 return;
847 ✗ case TYPE_DESC_RECORD: {
848 ✗ struct record_description* new_desc = va_arg(*arg, struct record_description*);
849 ✗ write_modelica_record_helper(elem, new_desc, arg);
850 }
851 ✗ break;
852 ✗ case TYPE_DESC_FUNCTION:
853 ✗ in_report("function pointer in record is unsupported.");
854 ✗ assert(0);
855 return;
856 ✗ case TYPE_DESC_NORETCALL:
857 ✗ in_report("noretcall in record is invalid.");
858 ✗ assert(0);
859 return;
860 }
861 }
862 }
863
864 ✗ void write_modelica_record(type_description *desc, void* rec_desc_void, ...)
865 {
866 va_list arg;
867 ✗ va_start(arg, rec_desc_void);
868 ✗ write_modelica_record_helper(desc, rec_desc_void, &arg);
869 ✗ va_end(arg);
870 ✗ }
871
872 ✗ type_description *add_tuple_member(type_description *desc)
873 {
874 type_description *ret = NULL;
875 ✗ assert(desc->type == TYPE_DESC_TUPLE);
876 ✗ desc->data.tuple.element = (struct type_desc_s*)realloc(desc->data.tuple.element,
877 ✗ (desc->data.tuple.elements + 1)
878 * sizeof(struct type_desc_s));
879 ✗ ret = desc->data.tuple.element + desc->data.tuple.elements;
880 ✗ ++(desc->data.tuple.elements);
881 ✗ init_type_description(ret);
882 ✗ return ret;
883 }
884
885 61 static type_description *add_tuple_item(type_description *desc)
886 {
887 type_description *ret = NULL;
888
889
2/2
✓ Branch 0 taken 44 times.
✓ Branch 1 taken 17 times.
61 if(desc->type == TYPE_DESC_TUPLE) {
890 44 desc->data.tuple.element = (struct type_desc_s*)realloc(desc->data.tuple.element,
891 44 (desc->data.tuple.elements + 1)
892 * sizeof(struct type_desc_s));
893 44 ret = desc->data.tuple.element + desc->data.tuple.elements;
894 44 ++(desc->data.tuple.elements);
895 } else {
896 struct type_desc_s tmp;
897 memcpy(&tmp, desc, sizeof(tmp));
898 17 desc->type = TYPE_DESC_TUPLE;
899 17 desc->retval = tmp.retval;
900 17 desc->data.tuple.elements = 2;
901 17 desc->data.tuple.element = (struct type_desc_s*)malloc(2 * sizeof(struct type_desc_s));
902 memcpy(desc->data.tuple.element, &tmp, sizeof(tmp));
903 17 ret = desc->data.tuple.element + 1;
904 }
905
906 61 init_type_description(ret);
907 61 ret->retval = desc->retval;
908 61 return ret;
909 }
910
911 #if defined(__cplusplus)
912 }
913 #endif
914