Linux GNU 11.4.0 Code Coverage Report


Directory: ./
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 11.9% 50 / 0 / 421
Functions: 18.2% 10 / 0 / 55
Branches: 4.9% 13 / 0 / 264

OMCompiler/SimulationRuntime/c/util/boolean_array.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
29 #include "boolean_array.h"
30 #include "../gc/omc_gc.h"
31 #include "omc_error.h"
32 #include "generic_array.h"
33
34
35 #include <stdio.h>
36 #include <stdlib.h>
37 #include <assert.h>
38 #include <stdarg.h>
39
40
41 821 modelica_boolean boolean_get(const boolean_array a, size_t i)
42 {
43 821 return ((modelica_boolean *) a.data)[i];
44 }
45
46 ✗ modelica_boolean boolean_get_2D(const boolean_array a, size_t i, size_t j)
47 {
48 ✗ return boolean_get(a, getIndex_2D(a.dim_size,i,j));
49 }
50
51 ✗ modelica_boolean boolean_get_3D(const boolean_array a, size_t i, size_t j, size_t k)
52 {
53 ✗ return boolean_get(a, getIndex_3D(a.dim_size,i,j,k));
54 }
55
56 ✗ modelica_boolean boolean_get_4D(const boolean_array a, size_t i, size_t j, size_t k, size_t l)
57 {
58 ✗ return boolean_get(a, getIndex_4D(a.dim_size,i,j,k,l));
59 }
60
61 ✗ modelica_boolean boolean_get_5D(const boolean_array a, size_t i, size_t j, size_t k, size_t l, size_t m)
62 {
63 ✗ return boolean_get(a, getIndex_5D(a.dim_size,i,j,k,l,m));
64 }
65
66
67 static inline modelica_boolean *boolean_ptrget(const boolean_array *a, size_t i)
68 {
69 ✗ return ((modelica_boolean *) a->data) + i;
70 }
71
72 static inline void boolean_set(boolean_array *a, size_t i, modelica_boolean r)
73 {
74 5761 ((modelica_boolean *) a->data)[i] = r;
75 }
76
77 /** function: boolean_array_create
78 **
79 ** sets all fields in a boolean_array, i.e. data, ndims and dim_size.
80 **/
81
82 91864 void boolean_array_create(boolean_array *dest, modelica_boolean *data,
83 int ndims, ...)
84 {
85 va_list ap;
86 91864 va_start(ap, ndims);
87 91864 base_array_create(dest, data, ndims, ap);
88 91864 va_end(ap);
89 91864 }
90
91 15042 void simple_alloc_1d_boolean_array(boolean_array* dest, int n)
92 {
93 15042 simple_alloc_1d_base_array(dest, n, boolean_alloc(n));
94 15042 }
95
96 ✗ void simple_alloc_2d_boolean_array(boolean_array* dest, int r, int c)
97 {
98 ✗ simple_alloc_2d_base_array(dest, r, c, boolean_alloc(r * c));
99 ✗ }
100
101 2038 void alloc_boolean_array(boolean_array *dest, int ndims, ...)
102 {
103 size_t elements = 0;
104 va_list ap;
105 2038 va_start(ap, ndims);
106 2038 elements = alloc_base_array(dest, ndims, ap);
107 2038 va_end(ap);
108 2038 dest->data = boolean_alloc(elements);
109 2038 }
110
111 513 void alloc_boolean_array_data(boolean_array* a)
112 {
113 513 a->data = boolean_alloc(base_array_nr_of_elements(*a));
114 513 }
115
116 513 void and_boolean_array(const boolean_array *source1, const boolean_array *source2, boolean_array *dest)
117 {
118 size_t i, nr_of_elements;
119
120
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 513 times.
513 assert(base_array_ok(source1));
121
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 513 times.
513 assert(base_array_ok(source2));
122
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 513 times.
513 assert(base_array_shape_eq(source1, source2));
123
124 513 clone_base_array_spec(source1, dest);
125 // assert(base_array_ok(dest));
126 // assert(base_array_shape_eq(source1, dest));
127 513 alloc_boolean_array_data(dest);
128
129
130 513 nr_of_elements = base_array_nr_of_elements(*source1);
131
132
2/2
✓ Branch 0 taken 513 times.
✓ Branch 1 taken 513 times.
1026 for(i = 0; i < nr_of_elements; ++i) {
133
4/4
✓ Branch 1 taken 308 times.
✓ Branch 2 taken 205 times.
✓ Branch 4 taken 55 times.
✓ Branch 5 taken 253 times.
513 boolean_set(dest, i, boolean_get(*source1, i) && boolean_get(*source2, i));
134 }
135 513 }
136
137 ✗ void or_boolean_array(const boolean_array *source1, const boolean_array *source2, boolean_array *dest)
138 {
139 size_t i, nr_of_elements;
140
141 ✗ assert(base_array_ok(source1));
142 ✗ assert(base_array_ok(source2));
143 ✗ assert(base_array_shape_eq(source1, source2));
144
145 ✗ clone_base_array_spec(source1, dest);
146 // assert(base_array_ok(dest));
147 // assert(base_array_shape_eq(source1, dest));
148 ✗ alloc_boolean_array_data(dest);
149
150
151 ✗ nr_of_elements = base_array_nr_of_elements(*source1);
152
153 ✗ for(i = 0; i < nr_of_elements; ++i) {
154 ✗ boolean_set(dest, i, boolean_get(*source1, i) || boolean_get(*source2, i));
155 }
156 ✗ }
157
158 ✗ void not_boolean_array(const boolean_array source, boolean_array *dest)
159 {
160 size_t i, nr_of_elements;
161
162 ✗ assert(base_array_ok(&source));
163
164 ✗ clone_base_array_spec(&source, dest);
165 ✗ alloc_boolean_array_data(dest);
166
167
168 ✗ nr_of_elements = base_array_nr_of_elements(source);
169
170 ✗ for(i = 0; i < nr_of_elements; ++i) {
171 ✗ boolean_set(dest, i, !boolean_get(source, i));
172 }
173 ✗ }
174
175 ✗ void copy_boolean_array_data_mem(const boolean_array source, modelica_boolean *dest)
176 {
177 size_t i, nr_of_elements;
178
179 ✗ assert(base_array_ok(&source));
180
181 ✗ nr_of_elements = base_array_nr_of_elements(source);
182
183 ✗ for(i = 0; i < nr_of_elements; ++i) {
184 ✗ dest[i] = boolean_get(source, i);
185 }
186 ✗ }
187
188 ✗ void copy_boolean_array(const boolean_array source, boolean_array *dest)
189 {
190 ✗ boolean_array_alloc_copy(source,*dest);
191 ✗ }
192
193 /*
194 a[1:3] := b;
195 */
196
197 static inline modelica_boolean *calc_boolean_index_spec(int ndims, const _index_t* idx_vec,
198 const boolean_array *arr,
199 const index_spec_t *spec)
200 {
201 return boolean_ptrget(arr, calc_base_index_spec(ndims, idx_vec, arr, spec));
202 }
203
204 /* Uses zero based indexing */
205 ✗ modelica_boolean *calc_boolean_index(int ndims, const _index_t *idx_vec,
206 const boolean_array *arr)
207 {
208 ✗ return boolean_ptrget(arr, calc_base_index(ndims, idx_vec, arr));
209 }
210
211 /* One based index*/
212 ✗ modelica_boolean *calc_boolean_index_va(const boolean_array *source, int ndims,
213 va_list ap)
214 {
215 ✗ return boolean_ptrget(source, calc_base_index_va(source, ndims, ap));
216 }
217
218 ✗ void print_boolean_matrix(const boolean_array *source)
219 {
220 _index_t i,j;
221 modelica_boolean value;
222
223 ✗ if(source->ndims == 2) {
224 ✗ printf("%d X %d matrix:\n", (int) source->dim_size[0], (int) source->dim_size[1]);
225 ✗ for(i = 0; i < source->dim_size[0]; ++i) {
226 ✗ for(j = 0; j < source->dim_size[1]; ++j) {
227 ✗ value = boolean_get(*source, (i * source->dim_size[1]) + j);
228 ✗ printf("%c\t", value ? 'T' : 'F');
229 }
230 printf("\n");
231 }
232 } else {
233 printf("array with %d dimensions\n", source->ndims);
234 }
235 ✗ }
236
237 ✗ void print_boolean_array(const boolean_array *source)
238 {
239 _index_t i,j;
240 modelica_boolean *data;
241 ✗ assert(base_array_ok(source));
242
243 ✗ data = (modelica_boolean *) source->data;
244 ✗ if(source->ndims == 1) {
245 ✗ for(i = 1; i < source->dim_size[0]; ++i) {
246 ✗ printf("%c, ", (*data) ? 'T' : 'F');
247 ✗ ++data;
248 }
249 ✗ if(0 < source->dim_size[0]) {
250 ✗ printf("%c", (*data) ? 'T' : 'F');
251 }
252 ✗ } else if(source->ndims > 1) {
253 size_t k, n;
254 ✗ n = base_array_nr_of_elements(*source) /
255 ✗ (source->dim_size[0] * source->dim_size[1]);
256 ✗ for(k = 0; k < n; ++k) {
257 ✗ for(i = 0; i < source->dim_size[1]; ++i) {
258 ✗ for(j = 0; j < source->dim_size[0]; ++j) {
259 ✗ printf("%c, ",(*data) ? 'T' : 'F');
260 ✗ ++data;
261 }
262 ✗ if(0 < source->dim_size[0]) {
263 ✗ printf("%c",(*data) ? 'T' : 'F');
264 }
265 printf("\n");
266 }
267 ✗ if((k + 1) < n) {
268 printf("\n =================\n");
269 }
270 }
271 }
272 ✗ }
273
274 ✗ char print_boolean(modelica_boolean value)
275 {
276 ✗ return value ? 'T' : 'F';
277 }
278
279 2727 void put_boolean_element(modelica_boolean value, int i1, boolean_array *dest)
280 {
281 /* Assert that dest has correct dimension */
282 /* Assert that i1 is a valid index */
283 2727 boolean_set(dest, i1, value);
284 2727 }
285
286 6 void put_boolean_matrix_element(modelica_boolean value, int r, int c,
287 boolean_array* dest)
288 {
289 /* Assert that dest hast correct dimension */
290 /* Assert that r and c are valid indices */
291 6 boolean_set(dest, (r * dest->dim_size[1]) + c, value);
292 /* printf("Index %d\n",r*dest->dim_size[1]+c); */
293 6 }
294
295 /* Zero based index */
296 ✗ void simple_indexed_assign_boolean_array1(const boolean_array* source,
297 int i1,
298 boolean_array* dest)
299 {
300 /* Assert that source has the correct dimension */
301 /* Assert that dest has the correct dimension */
302 ✗ boolean_set(dest, i1, boolean_get(*source, i1));
303 ✗ }
304
305 ✗ void simple_indexed_assign_boolean_array2(const boolean_array* source,
306 int i1, int i2,
307 boolean_array* dest)
308 {
309 size_t index;
310 /* Assert that source has correct dimension */
311 /* Assert that dest has correct dimension */
312 ✗ index = (i1 * source->dim_size[1]) + i2;
313 ✗ boolean_set(dest, index, boolean_get(*source, index));
314 ✗ }
315
316 ✗ void indexed_assign_boolean_array(const boolean_array source, boolean_array* dest,
317 const index_spec_t* dest_spec)
318 {
319 _index_t *idx_vec1, *idx_size;
320 _index_t j, n;
321 ✗ indexed_assign_base_array_size_alloc(&source, dest, dest_spec, &idx_vec1, &idx_size);
322
323 ✗ n = base_array_nr_of_elements(source);
324 ✗ for (j = 0; j < n; j++) {
325 ✗ boolean_set(dest,
326 calc_base_index_spec(dest->ndims, idx_vec1, dest, dest_spec),
327 boolean_get(source, j));
328 ✗ next_index(dest_spec->ndims, idx_vec1, idx_size);
329 }
330
331 ✗ omc_rc_release_inline(idx_vec1);
332 ✗ omc_rc_release_inline(idx_size);
333 ✗ }
334
335 /*
336 * function: index_boolean_array
337 *
338 * Returns an subscript of the source array in the destination array.
339 * Assumes that both source array and destination array is properly
340 * allocated.
341 *
342 * a := b[1:3];
343 *
344 */
345
346 ✗ void index_boolean_array(const boolean_array* source,
347 const index_spec_t* source_spec,
348 boolean_array* dest)
349 {
350 _index_t* idx_vec1;
351 _index_t* idx_vec2;
352 _index_t* idx_size;
353 int j;
354 int i;
355
356 ✗ assert(base_array_ok(source));
357 ✗ assert(base_array_ok(dest));
358 ✗ assert(index_spec_ok(source_spec));
359 ✗ assert(index_spec_fit_base_array(source_spec,source));
360 ✗ for(i = 0, j = 0; i < source->ndims; ++i) {
361 ✗ if((source_spec->index_type[i] == 'W')
362 ✗ ||
363 (source_spec->index_type[i] == 'A')) {
364 ✗ ++j;
365 }
366 }
367 ✗ assert(j == dest->ndims);
368 ✗ if (base_array_nr_of_elements(*dest) == 0) {
369 return;
370 }
371
372 ✗ idx_vec1 = size_alloc(source->ndims); /*indices in the source array*/
373 ✗ idx_vec2 = size_alloc(dest->ndims); /* indices in the destination array*/
374 ✗ idx_size = size_alloc(source_spec->ndims);
375
376 ✗ for(i = 0; i < source->ndims; ++i) {
377 ✗ idx_vec1[i] = 0;
378 }
379 ✗ for(i = 0; i < source_spec->ndims; ++i) {
380 ✗ if(source_spec->index_type[i] != 'W') {
381 ✗ idx_size[i] = imax(source_spec->dim_size[i],1);
382 } else {
383 ✗ idx_size[i] = source->dim_size[i];
384 }
385 }
386
387 do {
388 ✗ for(i = 0, j = 0; i < source->ndims; ++i) {
389 ✗ if((source_spec->index_type[i] == 'W')
390 ✗ ||
391 (source_spec->index_type[i] == 'A')) {
392 ✗ idx_vec2[j] = idx_vec1[i];
393 ✗ j++;
394 }
395 }
396
397 ✗ boolean_set(dest, calc_base_index(dest->ndims, idx_vec2, dest),
398 boolean_get(*source,
399 calc_base_index_spec(source->ndims, idx_vec1,
400 source, source_spec)));
401
402 ✗ } while(0 == next_index(source->ndims, idx_vec1, idx_size));
403 ✗ omc_rc_release_inline(idx_vec1);
404 ✗ omc_rc_release_inline(idx_vec2);
405 ✗ omc_rc_release_inline(idx_size);
406 }
407
408 /*
409 * function: index_alloc_boolean_array
410 *
411 * Returns an subscript of the source array in the destination array
412 * in the same manner as index_boolean_array, except that the destination
413 * array is allocated.
414 *
415 *
416 * a := b[1:3];
417 */
418
419 ✗ void index_alloc_boolean_array(const boolean_array* source,
420 const index_spec_t* source_spec,
421 boolean_array* dest)
422 {
423 ✗ index_alloc_base_array_size(source, source_spec, dest);
424 ✗ alloc_boolean_array_data(dest);
425 ✗ index_boolean_array(source, source_spec, dest);
426 ✗ }
427
428 /* Returns dest := source[i1,:,:...]*/
429 ✗ void simple_index_alloc_boolean_array1(const boolean_array* source, int i1,
430 boolean_array* dest)
431 {
432 int i;
433 ✗ assert(base_array_ok(source));
434
435 ✗ dest->ndims = source->ndims - 1;
436 ✗ dest->dim_size = size_alloc(dest->ndims);
437 ✗ dest->owns_data = 1;
438
439 ✗ for(i = 0; i < dest->ndims; ++i) {
440 ✗ dest->dim_size[i] = source->dim_size[i+1];
441 }
442 ✗ alloc_boolean_array_data(dest);
443
444 ✗ simple_index_boolean_array1(source, i1, dest);
445 ✗ }
446
447 ✗ void simple_index_boolean_array1(const boolean_array* source, int i1,
448 boolean_array* dest)
449 {
450 size_t i;
451 ✗ size_t nr_of_elements = base_array_nr_of_elements(*dest);
452 ✗ size_t off = nr_of_elements * i1;
453
454 ✗ assert(dest->ndims == (source->ndims - 1));
455
456 ✗ for(i = 0 ; i < nr_of_elements ; i++) {
457 ✗ boolean_set(dest, i, boolean_get(*source, off + i));
458 }
459 ✗ }
460
461 ✗ void simple_index_boolean_array2(const boolean_array* source,
462 int i1, int i2,
463 boolean_array* dest)
464 {
465 size_t i;
466 ✗ size_t nr_of_elements = base_array_nr_of_elements(*dest);
467 ✗ size_t off = nr_of_elements * ((source->dim_size[1] * i1) + i2);
468
469 ✗ for(i = 0 ; i < nr_of_elements ; i++) {
470 ✗ boolean_set(dest, i, boolean_get(*source, off + i));
471 }
472 ✗ }
473
474 ✗ void array_boolean_array(boolean_array* dest,int n,boolean_array first,...)
475 {
476 int i,j,c;
477 va_list ap;
478
479 ✗ boolean_array *elts=(boolean_array*)malloc(sizeof(boolean_array) * n);
480 ✗ assert(elts);
481 /* collect all array ptrs to simplify traversal.*/
482 ✗ va_start(ap,first);
483 ✗ elts[0] = first;
484 ✗ for(i = 1; i < n; ++i) {
485 ✗ elts[i] = va_arg(ap, boolean_array);
486 }
487 ✗ va_end(ap);
488
489 ✗ check_base_array_dim_sizes(elts,n);
490
491 ✗ for(i = 0, c = 0; i < n; ++i) {
492 ✗ int m = base_array_nr_of_elements(elts[i]);
493 ✗ for(j = 0; j < m; ++j) {
494 ✗ boolean_set(dest, c, boolean_get(elts[i], j));
495 ✗ c++;
496 }
497 }
498 ✗ free(elts);
499 ✗ }
500
501 ✗ void array_alloc_boolean_array(boolean_array* dest, int n,
502 boolean_array first,...)
503 {
504 int i,j,c;
505 va_list ap;
506
507 ✗ boolean_array *elts = (boolean_array*)malloc(sizeof(boolean_array) * n);
508 ✗ assert(elts);
509 /* collect all array ptrs to simplify traversal.*/
510 ✗ va_start(ap,first);
511 ✗ elts[0] = first;
512 ✗ for(i = 1; i < n; ++i) {
513 ✗ elts[i] = va_arg(ap, boolean_array);
514 }
515 ✗ va_end(ap);
516
517 ✗ check_base_array_dim_sizes(elts,n);
518
519 ✗ if(first.ndims == 1) {
520 ✗ alloc_boolean_array(dest, 2, n, first.dim_size[0]);
521 ✗ } else if(first.ndims == 2) {
522 ✗ alloc_boolean_array(dest, 3, n, first.dim_size[0], first.dim_size[1]);
523 ✗ } else if(first.ndims == 3) {
524 ✗ alloc_boolean_array(dest, 4, n, first.dim_size[0],first.dim_size[1], first.dim_size[2]);
525 ✗ } else if(first.ndims == 4) {
526 ✗ alloc_boolean_array(dest, 5, n, first.dim_size[0], first.dim_size[1], first.dim_size[2], first.dim_size[3]);
527 } else {
528 ✗ assert(0 && "Dimension size > 4 not impl. yet");
529 }
530
531 ✗ for(i = 0, c = 0; i < n; ++i) {
532 ✗ int m = base_array_nr_of_elements(elts[i]);
533 ✗ for(j = 0; j < m; ++j) {
534 ✗ boolean_set(dest, c, boolean_get(elts[i], j));
535 ✗ c++;
536 }
537 }
538 ✗ free(elts);
539 ✗ }
540
541 /* array_alloc_scalar_boolean_array
542 *
543 * Creates(incl allocation) an array from scalar elements.
544 */
545
546 1312 void array_alloc_scalar_boolean_array(boolean_array* dest, int n, ...)
547 {
548 int i;
549 va_list ap;
550 1312 simple_alloc_1d_boolean_array(dest,n);
551 1312 va_start(ap,n);
552
2/2
✓ Branch 0 taken 2727 times.
✓ Branch 1 taken 1312 times.
4039 for(i = 0; i < n; ++i) {
553 2727 put_boolean_element((modelica_boolean) va_arg(ap, int),i,dest);
554 }
555 1312 va_end(ap);
556 1312 }
557
558
559 /* function: cat_boolean_array
560 *
561 * Concatenates n boolean arrays along the k:th dimension.
562 * k is one based
563 */
564 ✗ void cat_boolean_array(int k, boolean_array* dest, int n,
565 const boolean_array* first,...)
566 {
567 va_list ap;
568 int i, j, r, c;
569 int n_sub = 1, n_super = 1;
570 int new_k_dim_size = 0;
571 ✗ const boolean_array **elts = (const boolean_array**)malloc(sizeof(boolean_array *) * n);
572
573 ✗ assert(elts);
574 /* collect all array ptrs to simplify traversal.*/
575 ✗ va_start(ap, first);
576 ✗ elts[0] = first;
577
578 ✗ for(i = 1; i < n; i++) {
579 ✗ elts[i] = va_arg(ap,const boolean_array*);
580 }
581 ✗ va_end(ap);
582
583 /* check dim sizes of all inputs and dest */
584 ✗ assert(elts[0]->ndims >= k);
585 ✗ for(i = 0; i < n; i++) {
586 ✗ assert(dest->ndims == elts[i]->ndims);
587 ✗ for(j = 0; j < (k - 1); j++) {
588 ✗ assert(dest->dim_size[j] == elts[i]->dim_size[j]);
589 }
590 ✗ new_k_dim_size += elts[i]->dim_size[k-1];
591 ✗ for(j = k; j < elts[0]->ndims; j++) {
592 ✗ assert(dest->dim_size[j] == elts[i]->dim_size[j]);
593 }
594 }
595 ✗ assert(dest->dim_size[k-1] == new_k_dim_size);
596
597 /* calculate size of sub and super structure in 1-dim data representation */
598 ✗ for(i = 0; i < (k - 1); i++) {
599 ✗ n_super *= elts[0]->dim_size[i];
600 }
601 ✗ for(i = k; i < elts[0]->ndims; i++) {
602 ✗ n_sub *= elts[0]->dim_size[i];
603 }
604
605 /* concatenation along k-th dimension */
606 j = 0;
607 ✗ for(i = 0; i < n_super; i++) {
608 ✗ for(c = 0; c < n; c++) {
609 ✗ int n_sub_k = n_sub * elts[c]->dim_size[k-1];
610 ✗ for(r = 0; r < n_sub_k; r++) {
611 ✗ boolean_set(dest, j,
612 ✗ boolean_get(*elts[c], r + (i * n_sub_k)));
613 ✗ j++;
614 }
615 }
616 }
617 ✗ free(elts);
618 ✗ }
619
620 /* function: cat_alloc_boolean_array
621 *
622 * Concatenates n boolean arrays along the k:th dimension.
623 * allocates space in dest array
624 * k is one based
625 */
626 ✗ void cat_alloc_boolean_array(int k, boolean_array* dest, int n,
627 const boolean_array* first,...)
628 {
629 va_list ap;
630 int i, j, r, c;
631 int n_sub = 1, n_super = 1;
632 int new_k_dim_size = 0;
633 ✗ const boolean_array **elts = (const boolean_array**)malloc(sizeof(boolean_array *) * n);
634
635 ✗ assert(elts);
636 /* collect all array ptrs to simplify traversal.*/
637 ✗ va_start(ap, first);
638 ✗ elts[0] = first;
639
640 ✗ for(i = 1; i < n; i++) {
641 ✗ elts[i] = va_arg(ap,const boolean_array*);
642 }
643 ✗ va_end(ap);
644
645 /* check dim sizes of all inputs */
646 ✗ assert(elts[0]->ndims >= k);
647 ✗ new_k_dim_size = elts[0]->dim_size[k-1];
648 ✗ for(i = 1; i < n; i++) {
649 ✗ assert(elts[0]->ndims == elts[i]->ndims);
650 ✗ for(j = 0; j < (k - 1); j++) {
651 ✗ assert(elts[0]->dim_size[j] == elts[i]->dim_size[j]);
652 }
653 ✗ new_k_dim_size += elts[i]->dim_size[k-1];
654 ✗ for(j = k; j < elts[0]->ndims; j++) {
655 ✗ assert(elts[0]->dim_size[j] == elts[i]->dim_size[j]);
656 }
657 }
658
659 /* calculate size of sub and super structure in 1-dim data representation */
660 ✗ for(i = 0; i < (k - 1); i++) {
661 ✗ n_super *= elts[0]->dim_size[i];
662 }
663 ✗ for(i = k; i < elts[0]->ndims; i++) {
664 ✗ n_sub *= elts[0]->dim_size[i];
665 }
666 /* allocate dest structure */
667 ✗ dest->data = boolean_alloc( n_super * new_k_dim_size * n_sub);
668 ✗ dest->ndims = elts[0]->ndims;
669 ✗ dest->dim_size = size_alloc(dest->ndims);
670 ✗ dest->owns_data = 1;
671 ✗ for(j = 0; j < dest->ndims; j++) {
672 ✗ dest->dim_size[j] = elts[0]->dim_size[j];
673 }
674 ✗ dest->dim_size[k-1] = new_k_dim_size;
675 /* concatenation along k-th dimension */
676 j = 0;
677 ✗ for(i = 0; i < n_super; i++) {
678 ✗ for(c = 0; c < n; c++) {
679 ✗ int n_sub_k = n_sub * elts[c]->dim_size[k-1];
680 ✗ for(r = 0; r < n_sub_k; r++) {
681 ✗ boolean_set(dest, j,
682 ✗ boolean_get(*elts[c], r + (i * n_sub_k)));
683 ✗ j++;
684 }
685 }
686 }
687 ✗ free(elts);
688 ✗ }
689
690 /* function: promote_alloc_boolean_array
691 *
692 * Implementation of promote(A,n) same as promote_boolean_array except
693 * that the destination array is allocated.
694 */
695 ✗ void promote_alloc_boolean_array(const boolean_array* a, int n,
696 boolean_array* dest)
697 {
698 ✗ dest->flexible = a->flexible;
699 ✗ promote_boolean_array(a, n, dest);
700 ✗ }
701
702 /* function: promote_boolean_array.
703 *
704 * Implementation of promote(a,n)
705 * Adds n onesized array dimensions to the array a to "the right of array dimensions".
706 * For instance
707 * promote_exp( {1,2},1) => {{1},{2}}
708 * promote_exp( {1,2},2) => { {{1}},{{2}} }
709 */
710 ✗ void promote_boolean_array(const boolean_array* a, int n,boolean_array* dest)
711 {
712 int i;
713
714 ✗ dest->dim_size = size_alloc(n+a->ndims);
715 ✗ dest->data = a->data;
716 ✗ dest->owns_data = a->owns_data;
717 ✗ if (dest->owns_data) {
718 omc_rc_retain_inline(dest->data);
719 }
720 /* Assert a->ndims>=n */
721 ✗ for(i = 0; i < a->ndims; ++i) {
722 ✗ dest->dim_size[i] = a->dim_size[i];
723 }
724 ✗ for(i = a->ndims; i < (n+a->ndims); ++i) {
725 ✗ dest->dim_size[i] = 1;
726 }
727
728 ✗ dest->ndims=n+a->ndims;
729 ✗ }
730
731 /* function: promote_scalar_boolean_array
732 *
733 * promotes a scalar value to an n dimensional array.
734 */
735
736 ✗ void promote_scalar_boolean_array(modelica_boolean s,int n,
737 boolean_array* dest)
738 {
739 int i;
740
741 /* Assert that dest is of correct dimension */
742
743 /* Alloc size */
744 ✗ dest->dim_size = size_alloc(n);
745 ✗ dest->owns_data = 1;
746
747 /* Alloc data */
748 ✗ dest->data = boolean_alloc(1);
749
750 ✗ dest->ndims = n;
751 boolean_set(dest, 0, s);
752
753 ✗ for(i = 0; i < n; ++i) {
754 ✗ dest->dim_size[i] = 1;
755 }
756 ✗ }
757
758 ✗ void size_boolean_array(const boolean_array* a, integer_array* dest)
759 {
760 /* This should be an integer array dest instead */
761 int i;
762
763 ✗ assert(dest->ndims == 1);
764 ✗ assert(dest->dim_size[0] == a->ndims);
765
766 ✗ for(i = 0 ; i < a->ndims ; i++) {
767 ✗ ((modelica_integer *) dest->data)[i] = a->dim_size[i];
768 }
769 ✗ }
770
771 ✗ modelica_boolean scalar_boolean_array(const boolean_array* a)
772 {
773 ✗ assert(base_array_ok(a));
774 ✗ assert(base_array_one_element_ok(a));
775
776 ✗ return boolean_get(*a, 0);
777 }
778
779 ✗ void vector_boolean_array(const boolean_array* a, boolean_array* dest)
780 {
781 size_t i, nr_of_elements;
782
783 /* Assert that a has at most one dimension with dim_size>1*/
784
785 ✗ nr_of_elements = base_array_nr_of_elements(*a);
786 ✗ for(i = 0; i < nr_of_elements; ++i) {
787 ✗ boolean_set(dest, i, boolean_get(*a, i));
788 }
789 ✗ }
790
791 ✗ void vector_boolean_scalar(modelica_boolean a,boolean_array* dest)
792 {
793 /* Assert that dest is a 1-vector */
794 boolean_set(dest, 0, a);
795 ✗ }
796
797 ✗ void matrix_boolean_array(const boolean_array* a, boolean_array* dest)
798 {
799 size_t i, cnt;
800 /* Assert that size(A,i)=1 for 2 <i<=ndims(A)*/
801 ✗ dest->dim_size[0] = a->dim_size[0];
802 ✗ dest->dim_size[1] = (a->ndims < 2)? 1 : a->dim_size[1];
803
804 ✗ cnt = dest->dim_size[0] * dest->dim_size[1];
805
806 ✗ for(i = 0; i < cnt; ++i) {
807 ✗ boolean_set(dest, i, boolean_get(*a, i));
808 }
809 ✗ }
810
811 ✗ void matrix_boolean_scalar(modelica_boolean a, boolean_array* dest)
812 {
813 ✗ dest->ndims = 2;
814 ✗ dest->dim_size[0] = 1;
815 ✗ dest->dim_size[1] = 1;
816 boolean_set(dest, 0, a);
817 ✗ }
818
819 /* function: transpose_alloc_boolean_array
820 *
821 * Implementation of transpose(A) for matrix A. Same as transpose_boolean_array
822 * except that destionation array is allocated.
823 */
824
825 ✗ void transpose_alloc_boolean_array(const boolean_array* a, boolean_array* dest)
826 {
827 clone_boolean_array_spec(a,dest); /* allocation*/
828
829 /* transpose only valid for matrices.*/
830
831 ✗ assert(a->ndims == 2);
832 ✗ dest->dim_size[0]=a->dim_size[1];
833 ✗ dest->dim_size[1]=a->dim_size[0];
834 ✗ dest->ndims = 2;
835
836 ✗ alloc_boolean_array_data(dest);
837 ✗ transpose_boolean_array(a,dest);
838 ✗ }
839
840 /* function: transpose_boolean_array
841 *
842 * Implementation of transpose(A) for matrix A.
843 */
844 ✗ void transpose_boolean_array(const boolean_array* a, boolean_array* dest)
845 {
846 size_t i;
847 size_t j;
848 /* size_t k;*/
849 size_t n,m;
850
851 ✗ if(a->ndims == 1) {
852 ✗ boolean_array_copy_data(*a, *dest);
853 ✗ return;
854 }
855
856 ✗ assert(a->ndims==2 && dest->ndims==2);
857
858 ✗ n = a->dim_size[0];
859 ✗ m = a->dim_size[1];
860
861 ✗ assert(dest->dim_size[0] == m && dest->dim_size[1] == n);
862
863 ✗ for(i = 0; i < n; ++i) {
864 ✗ for(j = 0; j < m; ++j) {
865 ✗ boolean_set(dest, (j*n)+i, boolean_get(*a, (i*m)+j));
866 }
867 }
868 }
869
870 ✗ void fill_boolean_array(boolean_array* dest,modelica_boolean s)
871 {
872 size_t nr_of_elements;
873 size_t i;
874
875 ✗ nr_of_elements = base_array_nr_of_elements(*dest);
876 ✗ for(i = 0; i < nr_of_elements; ++i) {
877 boolean_set(dest, i, s);
878 }
879 ✗ }
880
881 ✗ void convert_alloc_boolean_array_to_f77(const boolean_array* a,
882 boolean_array* dest)
883 {
884 int i;
885 ✗ clone_reverse_base_array_spec(a, dest);
886 ✗ alloc_boolean_array_data(dest);
887 ✗ transpose_boolean_array(a, dest);
888 ✗ for(i = 0; i < dest->ndims; ++i) {
889 ✗ dest->dim_size[i] = a->dim_size[i];
890 }
891 ✗ }
892
893 ✗ void convert_alloc_boolean_array_from_f77(const boolean_array* a,
894 boolean_array* dest)
895 {
896 int i;
897 ✗ clone_reverse_base_array_spec(a,dest);
898 ✗ alloc_boolean_array_data(dest);
899 ✗ for(i = 0; i < dest->ndims; ++i) {
900 ✗ int tmp = dest->dim_size[i];
901 ✗ dest->dim_size[i] = a->dim_size[i];
902 ✗ a->dim_size[i] = tmp;
903 }
904 ✗ transpose_boolean_array(a, dest);
905 ✗ }
906
907 /* Fills an array with a value. */
908 503 void fill_alloc_boolean_array(boolean_array* dest, modelica_boolean value, int ndims, ...)
909 {
910 size_t i;
911 size_t elements = 0;
912 va_list ap;
913 503 va_start(ap, ndims);
914 503 elements = alloc_base_array(dest, ndims, ap);
915 503 va_end(ap);
916 503 dest->data = boolean_alloc(elements);
917
918
2/2
✓ Branch 0 taken 2515 times.
✓ Branch 1 taken 503 times.
3018 for(i = 0; i < elements; ++i) {
919 boolean_set(dest, i, value);
920 }
921 503 }
922
923 ✗ modelica_boolean min_boolean_array(const boolean_array a)
924 {
925 size_t nr_of_elements;
926
927 ✗ omc_assert_macro(base_array_ok(&a));
928 ✗ nr_of_elements = base_array_nr_of_elements(a);
929
930 size_t i;
931 ✗ for (i = 0; i < nr_of_elements; ++i) {
932 ✗ if (!boolean_get(a, i)) return 0;
933 }
934
935 return 1;
936 }
937
938 ✗ modelica_boolean max_boolean_array(const boolean_array a)
939 {
940 size_t nr_of_elements;
941
942 ✗ omc_assert_macro(base_array_ok(&a));
943 ✗ nr_of_elements = base_array_nr_of_elements(a);
944
945 size_t i;
946 ✗ for (i = 0; i < nr_of_elements; ++i) {
947 ✗ if (boolean_get(a, i)) return 1;
948 }
949
950 return 0;
951 }
952
953 ✗ static int boolean_element_to_string(char *buffer, size_t bufsize, const void *data, _index_t i)
954 {
955 ✗ return snprintf(buffer, bufsize, "%s", ((const modelica_boolean *)data)[i] ? "true" : "false");
956 }
957
958 /**
959 * @brief Write boolean vector into null-terminated string.
960 *
961 * @param source Boolean vector to write to `buffer`.
962 * @param isScalar Treat vector as scalar.
963 * @param buffer Buffer to write into.
964 * @param bufsize Length of `buffer`.
965 */
966 ✗ void boolean_vector_to_string(const boolean_array *source, modelica_boolean isScalar, char *buffer, size_t bufsize)
967 {
968 ✗ base_vector_to_string(source, isScalar, boolean_element_to_string, buffer, bufsize);
969 ✗ }
970
971 /**
972 * @brief Resize a start attribute array to n elements, repeating its values.
973 *
974 * The start attribute of an array variable can hold a single broadcast value
975 * or the values of an inner dimension only. Writing the start values of the
976 * whole array needs one element per array element. If the array has more than
977 * n elements, the first n are kept. Nothing is reallocated if the array
978 * already has n elements.
979 */
980 ✗ void boolean_array_ensure_size(boolean_array *a, int n)
981 {
982 ✗ int m = (int) base_array_nr_of_elements(*a);
983 boolean_array tmp;
984 int i;
985 ✗ if (m == n) {
986 ✗ return;
987 }
988 ✗ simple_alloc_1d_boolean_array(&tmp, n);
989 ✗ for (i = 0; i < n; ++i) {
990 ✗ ((modelica_boolean*) tmp.data)[i] = m > 0 ? ((modelica_boolean*) a->data)[i % m] : 0;
991 }
992 ✗ omc_array_release(a);
993 ✗ *a = tmp;
994 }
995