Linux GNU 11.4.0 Code Coverage Report


Directory: ./
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 61.8% 55 / 0 / 89
Functions: 66.7% 8 / 1 / 13
Branches: 57.1% 16 / 0 / 28

OMCompiler/SimulationRuntime/c/util/generic_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 #include <string.h>
29 #include <stdint.h>
30
31 #include "generic_array.h"
32 #include "omc_error.h"
33
34 static void* generic_ptrget(const base_array_t *a, size_t sze, size_t i) {
35 11060 return ((char*)a->data) + (i*sze);
36 }
37
38 static int generic_array_ndims_eq(const base_array_t* src, const base_array_t* dst) {
39
1/2
✓ Branch 0 taken 8856494 times.
✗ Branch 1 not taken.
8856494 if(src->ndims != dst->ndims) {
40 ✗ fprintf(stderr, "src->ndims != dst->ndims, %d != %d\n", src->ndims, dst->ndims);
41 return 0;
42 }
43 return 1;
44 }
45
46 #define omc_FORMAT "src->dim_size[%d] != dst->dim_size[%d], %" PRINT_MMC_SINT_T " != %" PRINT_MMC_SINT_T "\n"
47
48 ✗ static int generic_array_dimsizes_eq(const base_array_t* src, const base_array_t* dst, int print_error)
49 {
50 int i;
51
2/4
✓ Branch 0 taken 9069533 times.
✓ Branch 1 taken 8853472 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
17923005 for(i = 0; i < src->ndims; ++i) {
52
2/4
✓ Branch 0 taken 9066511 times.
✓ Branch 1 taken 3022 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
9069533 if(src->dim_size[i] != dst->dim_size[i]) {
53 ✗ if (print_error) {
54 ✗ fprintf(stderr, omc_FORMAT,
55 i, i, src->dim_size[i], dst->dim_size[i]);
56 }
57 ✗ return 0;
58 }
59 }
60
61 return 1;
62 }
63
64
65 8856494 static size_t check_copy_sanity(const base_array_t* src, base_array_t* dst, size_t sze) {
66 size_t i;
67 // TODO wrap me in debug. No need to do this in release.
68
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 8856494 times.
8856494 omc_assert_macro(base_array_ok(src));
69 ✗ omc_assert_macro(generic_array_ndims_eq(src, dst));
70
71 8856494 size_t nr_of_elements = base_array_nr_of_elements(*src);
72
73 // Check if shape is equal.
74 int shape_eq = generic_array_dimsizes_eq(src, dst, 0 /*do not print error yet*/);
75
76 if(shape_eq) {
77 return nr_of_elements;
78 }
79
80 // Shape not equal and destination is flexible array.
81 // Adjust the dim sizes and realloc the destination
82
1/2
✓ Branch 0 taken 3022 times.
✗ Branch 1 not taken.
3022 if(dst->flexible) {
83
2/2
✓ Branch 0 taken 3022 times.
✓ Branch 1 taken 3022 times.
6044 for(i = 0; i < dst->ndims; ++i) {
84 3022 dst->dim_size[i] = src->dim_size[i];
85 }
86 // let GC collect the old data.
87 3022 dst->data = generic_alloc(nr_of_elements, sze);
88
89 3022 return nr_of_elements;
90 }
91
92 // Shape not equal and destination is not flexible array.
93 ✗ generic_array_dimsizes_eq(src, dst, 1 /*print error*/); // Just to print more info.
94 ✗ raiseStreamPrint(NULL, "Failed to copy array. Dimension sizes are not equal and destination array is not flexible.");
95 ✗ return 0;
96 }
97
98 3022 void generic_array_create_flexible(base_array_t* dst, int ndims)
99 {
100 3022 dst->ndims = ndims;
101 3022 dst->dim_size = size_alloc(ndims);
102 3022 dst->owns_data = 1;
103
104 3022 dst->flexible = 1;
105
106 size_t i;
107
2/2
✓ Branch 0 taken 3022 times.
✓ Branch 1 taken 3022 times.
6044 for(i = 0; i < ndims; ++i) {
108 3022 dst->dim_size[i] = -1;
109 }
110 3022 }
111
112 7045 void generic_array_create(threadData_t* td, base_array_t* dst, constructor_func ctr_func, int ndims, size_t sze, ...)
113 {
114 size_t i, nr_of_elements;
115
116 va_list ap;
117 7045 va_start(ap, sze);
118 7045 nr_of_elements = alloc_base_array(dst, ndims, ap);
119 7045 va_end(ap);
120 7045 dst->data = generic_alloc(nr_of_elements, sze);
121
122 // If we get here then the dst array has known dims
123 // Which means it is not flexible.
124 7045 dst->flexible = 0;
125
126 // Initialize each element of the complex array
127 char* d_data = (char*)(dst->data);
128
2/2
✓ Branch 0 taken 28168 times.
✓ Branch 1 taken 7045 times.
35213 for(i = 0; i < nr_of_elements; ++i) {
129 28168 ctr_func(td, d_data + (i*sze));
130 }
131 7045 }
132
133 ✗ void simple_array_create(threadData_t* td, base_array_t* dst, int ndims, size_t sze, ...)
134 {
135 size_t i, nr_of_elements;
136
137 va_list ap;
138 ✗ va_start(ap, sze);
139 ✗ nr_of_elements = alloc_base_array(dst, ndims, ap);
140 ✗ va_end(ap);
141 ✗ dst->data = generic_alloc(nr_of_elements, sze);
142
143 // If we get here then the dst array has known dims
144 // Which means it is not flexible.
145 ✗ dst->flexible = 0;
146
147 // Init to 0. IDK if this is what Modelica expects
148 // I guess it is better than garbage values.
149 ✗ memset(dst->data, 0, nr_of_elements*sze);
150 ✗ }
151
152
153 ✗ void generic_array_alloc_copy(const base_array_t src_cp, base_array_t* dst, copy_func cp_func, size_t sze)
154 {
155 const base_array_t* src = &src_cp;
156
157 ✗ clone_base_array_spec(src, dst);
158
159 // If we get here then it means the dst array had a default value (i.e., binding to src array)
160 // Which means even if it was unknown size, it is not flexible anymore and is
161 // same shape as the src array.
162 ✗ dst->flexible = 0;
163
164 ✗ size_t nr_of_elements = base_array_nr_of_elements(*dst);
165 ✗ dst->data = generic_alloc(nr_of_elements, sze);
166
167 size_t i;
168 char* d_data = (char*)(dst->data);
169 ✗ char* s_data = (char*)(src->data);
170 ✗ for(i = 0; i < nr_of_elements; ++i) {
171 ✗ cp_func(s_data + (i*sze), d_data + (i*sze));
172 }
173 ✗ }
174
175 25243621 void simple_array_alloc_copy(const base_array_t src_cp, base_array_t* dst, size_t sze)
176 {
177 const base_array_t* src = &src_cp;
178
179 25243621 clone_base_array_spec(src, dst);
180
181 // If we get here then it means the dst array had a default value (i.e., binding to src array)
182 // Which means even if it was unknown size, it is not flexible anymore and is
183 // same shape as the src array.
184 25243621 dst->flexible = 0;
185
186 25243621 size_t nr_of_elements = base_array_nr_of_elements(*dst);
187 25243621 dst->data = generic_alloc(nr_of_elements, sze);
188
189 25243621 memcpy(dst->data, src->data, sze*nr_of_elements);
190 25243621 }
191
192
193 2015 void generic_array_copy_data(const base_array_t src_cp, base_array_t* dst, copy_func cp_func, size_t sze)
194 {
195 const base_array_t* src = &src_cp;
196
197 2015 size_t nr_of_elements = check_copy_sanity(src, dst, sze);
198
199 size_t i;
200 2015 char* d_data = (char*)(dst->data);
201 2015 char* s_data = (char*)(src->data);
202
2/2
✓ Branch 0 taken 5036 times.
✓ Branch 1 taken 2015 times.
7051 for(i = 0; i < nr_of_elements; ++i) {
203 5036 cp_func(s_data + (i*sze), d_data + (i*sze));
204 }
205 2015 }
206
207 1039 void simple_array_copy_to(const base_array_t src, void* dst, size_t n, size_t sze)
208 {
209
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1039 times.
1039 if (base_array_nr_of_elements(src) != n) {
210 ✗ raiseStreamPrint(NULL, "Failed to copy array. Dimension sizes are not equal.");
211 ✗ return;
212 }
213 1039 memmove(dst, src.data, n*sze);
214 }
215
216 8854479 void simple_array_copy_data(const base_array_t src_cp, base_array_t* dst, size_t sze)
217 {
218 const base_array_t* src = &src_cp;
219
220 8854479 size_t nr_of_elements = check_copy_sanity(src, dst, sze);
221 8854479 memcpy(dst->data, src->data, sze*nr_of_elements);
222 8854479 }
223
224
225
226 11060 void* generic_array_get(const base_array_t* src, size_t sze, ...) {
227 va_list ap;
228 11060 va_start(ap,sze);
229 // TODO assert va_list is as long as ndims. Otherwise we have slicing
230 11060 void* trgt = generic_ptrget(src, calc_base_index_va(src, src->ndims, ap), sze);
231 11060 va_end(ap);
232 11060 return trgt;
233 }
234
235 ✗ void generic_array_set(base_array_t* dst, void* val, copy_func cp_func, size_t sze, ...) {
236 va_list ap;
237 ✗ va_start(ap,sze);
238 // TODO assert va_list is as long as ndims. Otherwise we have slicing
239 ✗ void* trgt = generic_ptrget(dst, calc_base_index_va(dst, dst->ndims, ap), sze);
240 ✗ cp_func(val,trgt);
241 ✗ va_end(ap);
242 ✗ }
243
244
245