GCC Code Coverage Report


Directory: src/
File: src/support/types.c
Date: 2026-09-15 07:37:49
Exec Total Coverage
Lines: 409 461 88.7%
Functions: 58 62 93.5%
Branches: 239 291 82.1%

Line Branch Exec Source
1 /*********************************************************************************/
2 /* Copyright 2009-2024 Barcelona Supercomputing Center */
3 /* */
4 /* This file is part of the DLB library. */
5 /* */
6 /* DLB is free software: you can redistribute it and/or modify */
7 /* it under the terms of the GNU Lesser General Public License as published by */
8 /* the Free Software Foundation, either version 3 of the License, or */
9 /* (at your option) any later version. */
10 /* */
11 /* DLB is distributed in the hope that it will be useful, */
12 /* but WITHOUT ANY WARRANTY; without even the implied warranty of */
13 /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
14 /* GNU Lesser General Public License for more details. */
15 /* */
16 /* You should have received a copy of the GNU Lesser General Public License */
17 /* along with DLB. If not, see <https://www.gnu.org/licenses/>. */
18 /*********************************************************************************/
19
20 #include "support/types.h"
21 #include "support/debug.h"
22 #include "apis/dlb_errors.h"
23
24 #include <limits.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include <stdio.h>
28 #include <errno.h>
29
30 #define LINE_BREAK "\n "
31
32 // option delimiter: flag options accept either : or , as delimiters
33 static const char *delim = ":,";
34
35 3999 int parse_bool(const char *str, bool *value) {
36
2/2
✓ Branch 0 taken 3986 times.
✓ Branch 1 taken 13 times.
3999 if (strcasecmp(str, "1")==0 ||
37
2/2
✓ Branch 0 taken 2975 times.
✓ Branch 1 taken 1011 times.
3986 strcasecmp(str, "yes")==0 ||
38
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 2974 times.
2975 strcasecmp(str, "true")==0) {
39 1025 *value = true;
40
2/2
✓ Branch 0 taken 2968 times.
✓ Branch 1 taken 6 times.
2974 } else if (strcasecmp(str, "0")==0 ||
41
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 2963 times.
2968 strcasecmp(str, "no")==0 ||
42
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 2 times.
5 strcasecmp(str, "false")==0) {
43 2972 *value = false;
44 } else {
45 2 return DLB_ERR_NOENT;
46 }
47 3997 return DLB_SUCCESS;
48 }
49
50 7 bool equivalent_bool(const char *str1, const char *str2) {
51 7 bool b1 = false;
52 7 bool b2 = true;
53 7 int err1 = parse_bool(str1, &b1);
54 7 int err2 = parse_bool(str2, &b2);
55
4/6
✓ Branch 0 taken 7 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 7 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 5 times.
✓ Branch 5 taken 2 times.
7 return err1 == DLB_SUCCESS && err2 == DLB_SUCCESS && b1 == b2;
56 }
57
58 13 int parse_negated_bool(const char *str, bool *value) {
59
2/2
✓ Branch 0 taken 11 times.
✓ Branch 1 taken 2 times.
13 if (strcasecmp(str, "1")==0 ||
60
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 2 times.
11 strcasecmp(str, "yes")==0 ||
61
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 8 times.
9 strcasecmp(str, "true")==0) {
62 5 *value = false;
63
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 2 times.
8 } else if (strcasecmp(str, "0")==0 ||
64
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 1 times.
6 strcasecmp(str, "no")==0 ||
65
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 2 times.
5 strcasecmp(str, "false")==0) {
66 6 *value = true;
67 } else {
68 2 return DLB_ERR_NOENT;
69 }
70 11 return DLB_SUCCESS;
71 }
72
73 2 bool equivalent_negated_bool(const char *str1, const char *str2) {
74 2 bool b1 = false;
75 2 bool b2 = true;
76 2 int err1 = parse_negated_bool(str1, &b1);
77 2 int err2 = parse_negated_bool(str2, &b2);
78
4/6
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✓ Branch 5 taken 1 times.
2 return err1 == DLB_SUCCESS && err2 == DLB_SUCCESS && b1 == b2;
79 }
80
81 2055 int parse_int(const char *str, int *value) {
82 char *endptr;
83 2055 long val = strtol(str, &endptr, 0);
84
4/4
✓ Branch 0 taken 1115 times.
✓ Branch 1 taken 940 times.
✓ Branch 2 taken 1113 times.
✓ Branch 3 taken 2 times.
2055 if ((val == 0 && endptr == str)
85
2/6
✓ Branch 0 taken 2053 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 2053 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
2053 || ((val == LONG_MIN || val == LONG_MAX) && errno == ERANGE)) {
86 2 debug_warning("Error parsing integer. str: %s, strlen: %lu, val: %ld, "
87 "errno: %d, strptr: %p, endptr: %p", str, strlen(str), val,
88 errno, str, endptr);
89 2 return DLB_ERR_NOENT;
90 }
91 2053 *value = (int)val;
92 2053 return DLB_SUCCESS;
93 }
94
95 2 bool equivalent_int(const char *str1, const char *str2) {
96 2 int i1 = 0;
97 2 int i2 = 1;
98 2 int err1 = parse_int(str1, &i1);
99 2 int err2 = parse_int(str2, &i2);
100
4/6
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✓ Branch 5 taken 1 times.
2 return err1 == DLB_SUCCESS && err2 == DLB_SUCCESS && i1 == i2;
101 }
102
103
104 /* verbose_opts_t */
105 static const verbose_opts_t verbose_opts_values[] =
106 {VB_CLEAR, VB_ALL, VB_API, VB_MICROLB, VB_SHMEM, VB_MPI_API, VB_MPI_INT, VB_STATS,
107 VB_DROM, VB_MNGO, VB_ASYNC, VB_OMPT, VB_AFFINITY, VB_BARRIER, VB_TALP, VB_INSTR};
108 static const char* const verbose_opts_choices[] =
109 {"no", "all", "api", "microlb", "shmem", "mpi_api", "mpi_intercept", "stats", "drom",
110 "mngo", "async", "ompt", "affinity", "barrier", "talp", "instrument"};
111 static const char verbose_opts_choices_str[] =
112 "no:all:api:microlb:shmem:mpi_api:mpi_intercept:stats:"LINE_BREAK
113 "drom:mngo:async:ompt:affinity:barrier:talp:instrument";
114 enum { verbose_opts_nelems = sizeof(verbose_opts_values) / sizeof(verbose_opts_values[0]) };
115
116 296 int parse_verbose_opts(const char *str, verbose_opts_t *value) {
117 /* particular case: '--verbose/--verbose=yes' enables all verbose options */
118
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 293 times.
296 if (strcmp(str, "yes") == 0) {
119 3 *value = VB_ALL;
120 3 return DLB_SUCCESS;
121 }
122
123 293 *value = VB_CLEAR;
124
125 /* tokenize multiple options separated by ':' */
126 293 char *end_token = NULL;
127 293 size_t len = strlen(str) + 1;
128 293 char *str_copy = malloc(sizeof(char)*len);
129 293 strcpy(str_copy, str);
130 293 char *token = strtok_r(str_copy, delim, &end_token);
131
2/2
✓ Branch 0 taken 316 times.
✓ Branch 1 taken 293 times.
609 while (token) {
132 int i;
133
2/2
✓ Branch 0 taken 762 times.
✓ Branch 1 taken 2 times.
764 for (i=0; i<verbose_opts_nelems; ++i) {
134
2/2
✓ Branch 0 taken 314 times.
✓ Branch 1 taken 448 times.
762 if (strcmp(token, verbose_opts_choices[i]) == 0) {
135 314 *value |= verbose_opts_values[i];
136 314 break;
137 }
138 }
139
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 314 times.
316 if (i == verbose_opts_nelems) {
140 2 warning("Unknown --verbose option: %s", token);
141 }
142 316 token = strtok_r(NULL, delim, &end_token);
143 }
144 293 free(str_copy);
145
146 293 return DLB_SUCCESS;
147 }
148
149 7 const char* verbose_opts_tostr(verbose_opts_t value) {
150 /* particular cases */
151
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 2 times.
7 if (value == VB_CLEAR) {
152 5 return "no";
153 }
154
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 if (value == VB_ALL) {
155 1 return "all";
156 }
157
158 static char str[sizeof(verbose_opts_choices_str)] = "";
159 1 char *p = str;
160 int i;
161
2/2
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 1 times.
15 for (i=2; i<verbose_opts_nelems; ++i) {
162
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 12 times.
14 if (value & verbose_opts_values[i]) {
163
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 if (p!=str) {
164 1 *p = ':';
165 1 ++p;
166 1 *p = '\0';
167 }
168 2 p += sprintf(p, "%s", verbose_opts_choices[i]);
169 }
170 }
171 1 return str;
172 }
173
174 4 const char* get_verbose_opts_choices(void) {
175 4 return verbose_opts_choices_str;
176 }
177
178 3 bool equivalent_verbose_opts(const char *str1, const char *str2) {
179 verbose_opts_t value1, value2;
180 3 parse_verbose_opts(str1, &value1);
181 3 parse_verbose_opts(str2, &value2);
182 3 return value1 == value2;
183 }
184
185
186 /* verbose_fmt_t */
187 static const verbose_fmt_t verbose_fmt_values[] =
188 {VBF_NODE, VBF_MPINODE, VBF_MPIRANK, VBF_SPID, VBF_THREAD, VBF_TSTAMP};
189 static const char* const verbose_fmt_choices[] =
190 {"node", "mpinode", "mpirank", "spid", "thread", "timestamp"};
191 static const char verbose_fmt_choices_str[] =
192 "node:mpinode:mpirank:spid:thread:timestamp";
193 enum { verbose_fmt_nelems = sizeof(verbose_fmt_values) / sizeof(verbose_fmt_values[0]) };
194
195 234 int parse_verbose_fmt(const char *str, verbose_fmt_t *value) {
196 234 *value = VBF_CLEAR;
197
198 /* tokenize multiple options separated by ':' */
199 234 char *end_token = NULL;
200 234 size_t len = strlen(str) + 1;
201 234 char *str_copy = malloc(sizeof(char)*len);
202 234 strcpy(str_copy, str);
203 234 char *token = strtok_r(str_copy, delim, &end_token);
204
2/2
✓ Branch 0 taken 462 times.
✓ Branch 1 taken 234 times.
696 while (token) {
205 int i;
206
2/2
✓ Branch 0 taken 1170 times.
✓ Branch 1 taken 2 times.
1172 for (i=0; i<verbose_fmt_nelems; ++i) {
207
2/2
✓ Branch 0 taken 460 times.
✓ Branch 1 taken 710 times.
1170 if (strcmp(token, verbose_fmt_choices[i]) == 0) {
208 460 *value |= verbose_fmt_values[i];
209 460 break;
210 }
211 }
212
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 460 times.
462 if (i == verbose_fmt_nelems) {
213 2 warning("Unknown --verbose-format option: %s", token);
214 }
215 462 token = strtok_r(NULL, delim, &end_token);
216 }
217 234 free(str_copy);
218
219 234 return DLB_SUCCESS;
220 }
221
222 8 const char* verbose_fmt_tostr(verbose_fmt_t value) {
223 static char str[sizeof(verbose_fmt_choices_str)] = "";
224 8 char *p = str;
225 int i;
226
2/2
✓ Branch 0 taken 48 times.
✓ Branch 1 taken 8 times.
56 for (i=0; i<verbose_fmt_nelems; ++i) {
227
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 36 times.
48 if (value & verbose_fmt_values[i]) {
228
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 7 times.
12 if (p!=str) {
229 5 *p = ':';
230 5 ++p;
231 5 *p = '\0';
232 }
233 12 p += sprintf(p, "%s", verbose_fmt_choices[i]);
234 }
235 }
236 8 return str;
237 }
238
239 4 const char* get_verbose_fmt_choices(void) {
240 4 return verbose_fmt_choices_str;
241 }
242
243 3 bool equivalent_verbose_fmt(const char *str1, const char *str2) {
244 verbose_fmt_t value1, value2;
245 3 parse_verbose_fmt(str1, &value1);
246 3 parse_verbose_fmt(str2, &value2);
247 3 return value1 == value2;
248 }
249
250
251 /* instrument_items_t */
252 static const instrument_items_t instrument_items_values[] =
253 {INST_NONE, INST_ALL, INST_MPI, INST_LEWI, INST_DROM, INST_TALP, INST_MNGO, INST_BARR, INST_OMPT, INST_CPUS, INST_CBCK};
254 static const char* const instrument_items_choices[] =
255 {"none", "all", "mpi", "lewi", "drom", "talp", "mngo", "barrier", "ompt", "cpus", "callbacks"};
256 static const char instrument_items_choices_str[] =
257 "none:all:mpi:lewi:drom:talp:mngo:barrier:ompt:cpus:callbacks";
258 enum { instrument_items_nelems = sizeof(instrument_items_values) / sizeof(instrument_items_values[0]) };
259
260 235 int parse_instrument_items(const char *str, instrument_items_t *value) {
261 /* particular case: '--instrument/--instrument=yes' enables all instrument items */
262
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 233 times.
235 if (strcmp(str, "yes") == 0) {
263 2 *value = INST_ALL;
264 2 return DLB_SUCCESS;
265 }
266
267 /* particular case: '--no-instrument/--instrument=no' disables all instrument items */
268
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 233 times.
233 if (strcmp(str, "no") == 0) {
269 *value = INST_NONE;
270 return DLB_SUCCESS;
271 }
272
273 233 *value = INST_NONE;
274
275 /* tokenize multiple options separated by ':' */
276 233 char *end_token = NULL;
277 233 size_t len = strlen(str) + 1;
278 233 char *str_copy = malloc(sizeof(char)*len);
279 233 strcpy(str_copy, str);
280 233 char *token = strtok_r(str_copy, delim, &end_token);
281
2/2
✓ Branch 0 taken 243 times.
✓ Branch 1 taken 233 times.
476 while (token) {
282 int i;
283
2/2
✓ Branch 0 taken 572 times.
✓ Branch 1 taken 4 times.
576 for (i=0; i<instrument_items_nelems; ++i) {
284
2/2
✓ Branch 0 taken 239 times.
✓ Branch 1 taken 333 times.
572 if (strcmp(token, instrument_items_choices[i]) == 0) {
285 239 *value |= instrument_items_values[i];
286 239 break;
287 }
288 }
289
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 239 times.
243 if (i == instrument_items_nelems) {
290 4 warning("Unknown --instrument option: %s", token);
291 }
292 243 token = strtok_r(NULL, delim, &end_token);
293 }
294 233 free(str_copy);
295
296 233 return DLB_SUCCESS;
297 }
298
299 7 const char* instrument_items_tostr(instrument_items_t value) {
300 // particular cases
301
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 6 times.
7 if (value == INST_NONE) {
302 1 return "none";
303 }
304
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 1 times.
6 if (value == INST_ALL) {
305 5 return "all";
306 }
307
308 static char str[sizeof(instrument_items_choices_str)] = "";
309 1 char *p = str;
310 int i;
311
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 1 times.
10 for (i=2; i<instrument_items_nelems; ++i) {
312
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 7 times.
9 if (value & instrument_items_values[i]) {
313
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 if (p!=str) {
314 1 *p = ':';
315 1 ++p;
316 1 *p = '\0';
317 }
318 2 p += sprintf(p, "%s", instrument_items_choices[i]);
319 }
320 }
321 1 return str;
322 }
323
324 4 const char* get_instrument_items_choices(void) {
325 4 return instrument_items_choices_str;
326 }
327
328 3 bool equivalent_instrument_items(const char *str1, const char *str2) {
329 instrument_items_t value1, value2;
330 3 parse_instrument_items(str1, &value1);
331 3 parse_instrument_items(str2, &value2);
332 3 return value1 == value2;
333 }
334
335
336 /* debug_opts_t */
337 static const debug_opts_t debug_opts_values[] =
338 {DBG_WALL, DBG_WERROR, DBG_WARNMPI, DBG_RETURNSTOLEN, DBG_LPOSTMORTEM};
339 static const char* const debug_opts_choices[] =
340 {"wall", "werror", "warn-mpi-version", "return-stolen", "lend-post-mortem"};
341 static const char debug_opts_choices_str[] =
342 "wall:werror:warn-mpi-version:return-stolen:lend-post-mortem";
343 enum { debug_opts_nelems = sizeof(debug_opts_values) / sizeof(debug_opts_values[0]) };
344
345 224 int parse_debug_opts(const char *str, debug_opts_t *value) {
346 224 *value = DBG_CLEAR;
347 int i;
348
2/2
✓ Branch 0 taken 1120 times.
✓ Branch 1 taken 224 times.
1344 for (i=0; i<debug_opts_nelems; ++i) {
349
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 1117 times.
1120 if (strstr(str, debug_opts_choices[i]) != NULL) {
350 3 *value |= debug_opts_values[i];
351 }
352 }
353 224 return DLB_SUCCESS;
354 }
355
356 1 const char* debug_opts_tostr(debug_opts_t value) {
357 static char str[sizeof(debug_opts_choices_str)] = "";
358 1 char *p = str;
359 int i;
360
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 1 times.
6 for (i=0; i<debug_opts_nelems; ++i) {
361
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
5 if (value & debug_opts_values[i]) {
362 if (p!=str) {
363 *p = ':';
364 ++p;
365 *p = '\0';
366 }
367 p += sprintf(p, "%s", debug_opts_choices[i]);
368 }
369 }
370 1 return str;
371 }
372
373 1 const char* get_debug_opts_choices(void) {
374 1 return debug_opts_choices_str;
375 }
376
377 bool equivalent_debug_opts(const char *str1, const char *str2) {
378 debug_opts_t value1, value2;
379 parse_debug_opts(str1, &value1);
380 parse_debug_opts(str2, &value2);
381 return value1 == value2;
382 }
383
384
385 /* lewi_affinity_t */
386 static const lewi_affinity_t lewi_affinity_values[] =
387 {LEWI_AFFINITY_AUTO, LEWI_AFFINITY_NONE, LEWI_AFFINITY_MASK,
388 LEWI_AFFINITY_NEARBY_FIRST, LEWI_AFFINITY_NEARBY_ONLY, LEWI_AFFINITY_SPREAD_IFEMPTY};
389 static const char* const lewi_affinity_choices[] =
390 {"auto", "none", "mask", "nearby-first", "nearby-only", "spread-ifempty"};
391 static const char lewi_affinity_choices_str[] =
392 "auto, none, mask, nearby-first,"LINE_BREAK
393 "nearby-only, spread-ifempty";
394 enum { lewi_affinity_nelems = sizeof(lewi_affinity_values) / sizeof(lewi_affinity_values[0]) };
395
396 298 int parse_lewi_affinity(const char *str, lewi_affinity_t *value) {
397
398
2/2
✓ Branch 0 taken 376 times.
✓ Branch 1 taken 4 times.
380 for (int i = 0; i < lewi_affinity_nelems; ++i) {
399
2/2
✓ Branch 0 taken 294 times.
✓ Branch 1 taken 82 times.
376 if (strcasecmp(str, lewi_affinity_choices[i]) == 0) {
400 294 *value = lewi_affinity_values[i];
401 294 return DLB_SUCCESS;
402 }
403 }
404
405 /* Support deprecated values */
406
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2 times.
4 if (strcasecmp(str, "any") == 0) {
407 2 *value = LEWI_AFFINITY_MASK;
408 2 return DLB_SUCCESS;
409 }
410
411 2 return DLB_ERR_NOENT;
412 }
413
414 34 const char* lewi_affinity_tostr(lewi_affinity_t value) {
415 int i;
416
1/2
✓ Branch 0 taken 64 times.
✗ Branch 1 not taken.
64 for (i=0; i<lewi_affinity_nelems; ++i) {
417
2/2
✓ Branch 0 taken 34 times.
✓ Branch 1 taken 30 times.
64 if (lewi_affinity_values[i] == value) {
418 34 return lewi_affinity_choices[i];
419 }
420 }
421 return "unknown";
422 }
423
424 4 const char* get_lewi_affinity_choices(void) {
425 4 return lewi_affinity_choices_str;
426 }
427
428 2 bool equivalent_lewi_affinity(const char *str1, const char *str2) {
429 2 lewi_affinity_t value1 = LEWI_AFFINITY_NONE;
430 2 lewi_affinity_t value2 = LEWI_AFFINITY_MASK;
431 2 int err1 = parse_lewi_affinity(str1, &value1);
432 2 int err2 = parse_lewi_affinity(str2, &value2);
433
4/6
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✓ Branch 5 taken 1 times.
2 return err1 == DLB_SUCCESS && err2 == DLB_SUCCESS && value1 == value2;
434 }
435
436
437 /* talp_summary_t */
438 static const talp_summary_t talp_summary_values[] =
439 {SUMMARY_NONE, SUMMARY_ALL, SUMMARY_POP_METRICS, SUMMARY_POP_RAW, SUMMARY_NODE,
440 SUMMARY_PROCESS};
441 static const char* const talp_summary_choices[] =
442 {"none", "all", "pop-metrics", "pop-raw", "node", "process"};
443 static const char talp_summary_choices_str[] =
444 "none:all:pop-metrics:process";
445 enum { talp_summary_nelems = sizeof(talp_summary_values) / sizeof(talp_summary_values[0]) };
446
447 234 int parse_talp_summary(const char *str, talp_summary_t *value) {
448 /* particular case: '--talp-summary/--talp-summary=yes' enables only POP metrics */
449
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 233 times.
234 if (strcmp(str, "yes") == 0) {
450 1 *value = SUMMARY_POP_METRICS;
451 1 return DLB_SUCCESS;
452 }
453
454 /* particular case: '--no-talp-summary/--talp-summary=no' disables all summaries */
455
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 233 times.
233 if (strcmp(str, "no") == 0) {
456 *value = SUMMARY_NONE;
457 return DLB_SUCCESS;
458 }
459
460 233 *value = SUMMARY_NONE;
461
462 /* tokenize multiple options separated by ':' */
463 233 char *end_token = NULL;
464 233 size_t len = strlen(str) + 1;
465 233 char *str_copy = malloc(sizeof(char)*len);
466 233 strcpy(str_copy, str);
467 233 char *token = strtok_r(str_copy, delim, &end_token);
468
2/2
✓ Branch 0 taken 235 times.
✓ Branch 1 taken 233 times.
468 while (token) {
469 int i;
470
2/2
✓ Branch 0 taken 725 times.
✓ Branch 1 taken 4 times.
729 for (i=0; i<talp_summary_nelems; ++i) {
471
2/2
✓ Branch 0 taken 231 times.
✓ Branch 1 taken 494 times.
725 if (strcmp(token, talp_summary_choices[i]) == 0) {
472 231 *value |= talp_summary_values[i];
473 231 break;
474 }
475
476 /* Support deprecated values */
477
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 494 times.
494 if (strcmp(token, "app") == 0) {
478 *value |= SUMMARY_POP_METRICS;
479 break;
480 }
481 }
482
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 231 times.
235 if (i == talp_summary_nelems) {
483 4 warning("Unknown --talp-summary option: %s", token);
484 }
485 235 token = strtok_r(NULL, delim, &end_token);
486 }
487 233 free(str_copy);
488
489 /* Deprecation warnings: */
490
491
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 230 times.
233 if (*value & SUMMARY_POP_RAW) {
492 3 warning("Deprecated: --talp-summary=pop-raw is deprecated. Use pop-metrics instead.");
493 }
494
495
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 231 times.
233 if (*value & SUMMARY_NODE) {
496 2 warning("Deprecated: --talp-summary=node is deprecated. Use process instead.");
497 }
498
499 233 return DLB_SUCCESS;
500 }
501
502 7 const char* talp_summary_tostr(talp_summary_t value) {
503 // particular cases
504
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 6 times.
7 if (value == SUMMARY_NONE) {
505 1 return "none";
506 }
507
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 5 times.
6 if (value == SUMMARY_ALL) {
508 1 return "all";
509 }
510
511 static char str[sizeof(talp_summary_choices_str)] = "";
512 5 char *p = str;
513 int i;
514
2/2
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 5 times.
25 for (i=2; i<talp_summary_nelems; ++i) {
515
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 15 times.
20 if (value & talp_summary_values[i]) {
516
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
5 if (p!=str) {
517 *p = ':';
518 ++p;
519 *p = '\0';
520 }
521 5 p += sprintf(p, "%s", talp_summary_choices[i]);
522 }
523 }
524 5 return str;
525 }
526
527 4 const char* get_talp_summary_choices(void) {
528 4 return talp_summary_choices_str;
529 }
530
531 3 bool equivalent_talp_summary(const char *str1, const char *str2) {
532 talp_summary_t value1, value2;
533 3 parse_talp_summary(str1, &value1);
534 3 parse_talp_summary(str2, &value2);
535 3 return value1 == value2;
536 }
537
538 /* mngo_mode_t */
539 static const mngo_mode_t mngo_mode_values[] =
540 {MNGO_HELPER_THREAD, MNGO_REGIONS};
541 static const char* const mngo_mode_choices[] =
542 {"helper-thread", "regions"};
543 static const char mngo_mode_choices_str[] =
544 "helper-thread, regions";
545 enum { mngo_mode_nelems = sizeof(mngo_mode_values) / sizeof(mngo_mode_values[0]) };
546 225 int parse_mngo_mode(const char *str, mngo_mode_t *option) {
547
548 int i;
549
2/2
✓ Branch 0 taken 449 times.
✓ Branch 1 taken 1 times.
450 for (i = 0; i < mngo_mode_nelems; i++) {
550
2/2
✓ Branch 0 taken 224 times.
✓ Branch 1 taken 225 times.
449 if (strcmp(str, mngo_mode_choices[i]) == 0) {
551 224 *option = mngo_mode_values[i];
552 224 return DLB_SUCCESS;
553 }
554 }
555
556 1 return DLB_ERR_NOENT;
557 }
558
559 4 const char* mngo_mode_tostr(mngo_mode_t value) {
560
1/3
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
4 switch (value) {
561 case MNGO_HELPER_THREAD:
562 return "helper-thread";
563 4 case MNGO_REGIONS:
564 4 return "regions";
565 default:
566 return "helper-thread";
567 }
568 }
569
570 4 const char* get_mngo_mode_choices(void) {
571 4 return mngo_mode_choices_str;
572 }
573
574 bool equivalent_mngo_mode(const char *str1, const char *str2) {
575 mngo_mode_t value1, value2;
576 if (parse_mngo_mode(str1, &value1) != DLB_SUCCESS) {
577 return false;
578 }
579 if (parse_mngo_mode(str2, &value2) != DLB_SUCCESS) {
580 return false;
581 }
582 return value1 == value2;
583 }
584
585 /* talp_model_t */
586 static const talp_model_t talp_model_values[] = {TALP_MODEL_HYBRID_V1, TALP_MODEL_HYBRID_V2};
587 static const char* const talp_model_choices[] = {"hybrid-v1", "hybrid-v2"};
588 static const char talp_model_choices_str[] = "hybrid-v1, hybrid-v2";
589 enum { talp_model_nelems = sizeof(talp_model_values) / sizeof(talp_model_values[0]) };
590
591 230 int parse_talp_model(const char *str, talp_model_t *value) {
592 int i;
593
2/2
✓ Branch 0 taken 456 times.
✓ Branch 1 taken 1 times.
457 for (i=0; i<talp_model_nelems; ++i) {
594
2/2
✓ Branch 0 taken 229 times.
✓ Branch 1 taken 227 times.
456 if (strcasecmp(str, talp_model_choices[i]) == 0) {
595 229 *value = talp_model_values[i];
596 229 return DLB_SUCCESS;
597 }
598 }
599 1 return DLB_ERR_NOENT;
600 }
601
602 2 const char* talp_model_tostr(talp_model_t value) {
603 int i;
604
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 for (i=0; i<talp_model_nelems; ++i) {
605
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2 times.
4 if (talp_model_values[i] == value) {
606 2 return talp_model_choices[i];
607 }
608 }
609 return "unknown";
610 }
611
612 1 const char* get_talp_model_choices(void) {
613 1 return talp_model_choices_str;
614 }
615
616 2 bool equivalent_talp_model(const char *str1, const char *str2) {
617 2 talp_model_t value1 = TALP_MODEL_HYBRID_V1;
618 2 talp_model_t value2 = TALP_MODEL_HYBRID_V2;
619 2 int err1 = parse_talp_model(str1, &value1);
620 2 int err2 = parse_talp_model(str2, &value2);
621
4/6
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✓ Branch 5 taken 1 times.
2 return err1 == DLB_SUCCESS && err2 == DLB_SUCCESS && value1 == value2;
622 }
623
624
625 /* talp_component_t */
626 static const talp_component_t talp_component_values[] = {
627 TALP_COMPONENT_NONE, TALP_COMPONENT_DEFAULT, TALP_COMPONENT_MPI, TALP_COMPONENT_OPENMP,
628 TALP_COMPONENT_GPU, TALP_COMPONENT_HWC };
629 static const char* const talp_component_choices[] = {"none", "default", "mpi", "openmp", "gpu", "hwc"};
630 static const char talp_component_choices_str[] = "none:default:mpi:openmp:gpu:hwc";
631 enum { talp_component_nelems = sizeof(talp_component_values) / sizeof(talp_component_values[0]) };
632
633 222 int parse_talp_component(const char *str, talp_component_t *value) {
634 /* particular case: '--talp/--talp=yes' is equivalent to --talp=default */
635
2/2
✓ Branch 0 taken 25 times.
✓ Branch 1 taken 197 times.
222 if (strcmp(str, "yes") == 0) {
636 25 *value = TALP_COMPONENT_DEFAULT;
637 25 return DLB_SUCCESS;
638 }
639
640 /* particular case: '--no-talp/--talp=no' is equivalent to --talp=none */
641
2/2
✓ Branch 0 taken 196 times.
✓ Branch 1 taken 1 times.
197 if (strcmp(str, "no") == 0
642
2/2
✓ Branch 0 taken 190 times.
✓ Branch 1 taken 6 times.
196 || strcmp(str, talp_component_choices[0]) == 0) {
643 191 *value = TALP_COMPONENT_NONE;
644 191 return DLB_SUCCESS;
645 }
646
647 6 *value = TALP_COMPONENT_NONE;
648
649 /* tokenize multiple options separated by ':' */
650 6 char *end_token = NULL;
651 6 size_t len = strlen(str) + 1;
652 6 char *str_copy = malloc(sizeof(char)*len);
653 6 strcpy(str_copy, str);
654 6 char *token = strtok_r(str_copy, delim, &end_token);
655
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 6 times.
14 while (token) {
656 int i;
657
1/2
✓ Branch 0 taken 19 times.
✗ Branch 1 not taken.
19 for (i=1; i<talp_component_nelems; ++i) {
658
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 14 times.
19 if (strcmp(token, talp_component_choices[i]) == 0) {
659 5 *value |= talp_component_values[i];
660 5 break;
661 }
662
663 /* Support "easy-to-confuse" values */
664
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14 times.
14 if (strcmp(token, "cuda") == 0) {
665 *value |= TALP_COMPONENT_GPU;
666 break;
667 }
668
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14 times.
14 if (strcmp(token, "omp") == 0) {
669 *value |= TALP_COMPONENT_OPENMP;
670 break;
671 }
672
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 11 times.
14 if (strcmp(token, "papi") == 0) {
673 3 *value |= TALP_COMPONENT_HWC;
674 3 break;
675 }
676 }
677
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
8 if (i == talp_component_nelems) {
678 warning("Unknown --talp option: %s", token);
679 }
680 8 token = strtok_r(NULL, delim, &end_token);
681 }
682 6 free(str_copy);
683
684 6 return DLB_SUCCESS;
685 }
686
687 5 const char* talp_component_tostr(talp_component_t value) {
688 // particular cases
689
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 1 times.
5 if (value == TALP_COMPONENT_NONE) {
690 4 return "none";
691 }
692
693 static char str[sizeof(talp_component_choices_str)] = "";
694 1 char *p = str;
695 int i;
696
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 1 times.
6 for (i=1; i<talp_component_nelems; ++i) {
697
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 4 times.
5 if (value & talp_component_values[i]) {
698
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (p!=str) {
699 *p = ':';
700 ++p;
701 *p = '\0';
702 }
703 1 p += sprintf(p, "%s", talp_component_choices[i]);
704 }
705 }
706 1 return str;
707 }
708
709 4 const char* get_talp_component_choices(void) {
710 4 return talp_component_choices_str;
711 }
712
713 bool equivalent_talp_component(const char *str1, const char *str2) {
714 talp_component_t value1 = TALP_COMPONENT_MPI;
715 talp_component_t value2 = TALP_COMPONENT_OPENMP;
716 int err1 = parse_talp_component(str1, &value1);
717 int err2 = parse_talp_component(str2, &value2);
718 return err1 == DLB_SUCCESS && err2 == DLB_SUCCESS && value1 == value2;
719 }
720
721
722 /* policy_t: most of this stuff is depcrecated, only policy_tostr is still used */
723 static const policy_t policy_values[] = {POLICY_NONE, POLICY_LEWI, POLICY_LEWI_ASYNC, POLICY_LEWI_MASK};
724 static const char* const policy_choices[] = {"no", "LeWI", "LeWI_async", "LeWI_mask"};
725 static const char policy_choices_str[] = "no, LeWI, LeWI_async, LeWI_mask";
726 enum { policy_nelems = sizeof(policy_values) / sizeof(policy_values[0]) };
727
728 9 int parse_policy(const char *str, policy_t *value) {
729 int i;
730
2/2
✓ Branch 0 taken 25 times.
✓ Branch 1 taken 2 times.
27 for (i=0; i<policy_nelems; ++i) {
731
2/2
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 18 times.
25 if (strcasecmp(str, policy_choices[i]) == 0) {
732 7 *value = policy_values[i];
733 7 return DLB_SUCCESS;
734 }
735 }
736 2 return DLB_ERR_NOENT;
737 }
738
739 67 const char* policy_tostr(policy_t value) {
740 int i;
741
2/2
✓ Branch 0 taken 199 times.
✓ Branch 1 taken 1 times.
200 for (i=0; i<policy_nelems; ++i) {
742
2/2
✓ Branch 0 taken 66 times.
✓ Branch 1 taken 133 times.
199 if (policy_values[i] == value) {
743 66 return policy_choices[i];
744 }
745 }
746 1 return "error";
747 }
748
749 const char* get_policy_choices(void) {
750 return policy_choices_str;
751 }
752
753 2 bool equivalent_policy(const char *str1, const char *str2) {
754 2 policy_t value1 = POLICY_NONE;
755 2 policy_t value2 = POLICY_LEWI;
756 2 int err1 = parse_policy(str1, &value1);
757 2 int err2 = parse_policy(str2, &value2);
758
4/6
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✓ Branch 5 taken 1 times.
2 return err1 == DLB_SUCCESS && err2 == DLB_SUCCESS && value1 == value2;
759 }
760
761 /* interaction_mode_t */
762 static const interaction_mode_t mode_values[] = {MODE_POLLING, MODE_ASYNC};
763 static const char* const mode_choices[] = {"polling", "async"};
764 static const char mode_choices_str[] = "polling, async";
765 enum { mode_nelems = sizeof(mode_values) / sizeof(mode_values[0]) };
766
767 231 int parse_mode(const char *str, interaction_mode_t *value) {
768 int i;
769
2/2
✓ Branch 0 taken 259 times.
✓ Branch 1 taken 2 times.
261 for (i=0; i<mode_nelems; ++i) {
770
2/2
✓ Branch 0 taken 229 times.
✓ Branch 1 taken 30 times.
259 if (strcasecmp(str, mode_choices[i]) == 0) {
771 229 *value = mode_values[i];
772 229 return DLB_SUCCESS;
773 }
774 }
775 2 return DLB_ERR_NOENT;
776 }
777
778 8 const char* mode_tostr(interaction_mode_t value) {
779 int i;
780
1/2
✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
10 for (i=0; i<mode_nelems; ++i) {
781
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 2 times.
10 if (mode_values[i] == value) {
782 8 return mode_choices[i];
783 }
784 }
785 return "unknown";
786 }
787
788 4 const char* get_mode_choices(void) {
789 4 return mode_choices_str;
790 }
791
792 2 bool equivalent_mode(const char *str1, const char *str2) {
793 2 interaction_mode_t value1 = MODE_POLLING;
794 2 interaction_mode_t value2 = MODE_ASYNC;
795 2 int err1 = parse_mode(str1, &value1);
796 2 int err2 = parse_mode(str2, &value2);
797
4/6
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✓ Branch 5 taken 1 times.
2 return err1 == DLB_SUCCESS && err2 == DLB_SUCCESS && value1 == value2;
798 }
799
800 /* mpi_set_t */
801 static const mpi_set_t mpiset_values[] = {MPISET_NONE, MPISET_ALL, MPISET_BARRIER, MPISET_COLLECTIVES};
802 static const char* const mpiset_choices[] = {"none", "all", "barrier", "collectives"};
803 static const char mpiset_choices_str[] = "none, all, barrier, collectives";
804 enum { mpiset_nelems = sizeof(mpiset_values) / sizeof(mpiset_values[0]) };
805
806 293 int parse_mpiset(const char *str, mpi_set_t *value) {
807 int i;
808
2/2
✓ Branch 0 taken 592 times.
✓ Branch 1 taken 1 times.
593 for (i=0; i<mpiset_nelems; ++i) {
809
2/2
✓ Branch 0 taken 292 times.
✓ Branch 1 taken 300 times.
592 if (strcasecmp(str, mpiset_choices[i]) == 0) {
810 292 *value = mpiset_values[i];
811 292 return DLB_SUCCESS;
812 }
813 }
814 1 return DLB_ERR_NOENT;
815 }
816
817 6 const char* mpiset_tostr(mpi_set_t value) {
818 int i;
819
1/2
✓ Branch 0 taken 13 times.
✗ Branch 1 not taken.
13 for (i=0; i<mpiset_nelems; ++i) {
820
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 7 times.
13 if (mpiset_values[i] == value) {
821 6 return mpiset_choices[i];
822 }
823 }
824 return "unknown";
825 }
826
827 4 const char* get_mpiset_choices(void) {
828 4 return mpiset_choices_str;
829 }
830
831 2 bool equivalent_mpiset(const char *str1, const char *str2) {
832 2 mpi_set_t value1 = MPISET_NONE;
833 2 mpi_set_t value2 = MPISET_ALL;
834 2 int err1 = parse_mpiset(str1, &value1);
835 2 int err2 = parse_mpiset(str2, &value2);
836
4/6
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✓ Branch 5 taken 1 times.
2 return err1 == DLB_SUCCESS && err2 == DLB_SUCCESS && value1 == value2;
837 }
838
839 /* omptool_opts_t */
840 static const omptool_opts_t omptool_opts_values[] =
841 {OMPTOOL_OPTS_NONE, OMPTOOL_OPTS_BORROW, OMPTOOL_OPTS_LEND};
842 static const char* const omptool_opts_choices[] = {"none", "borrow", "lend"};
843 static const char omptool_opts_choices_str[] = "none, {borrow:lend}";
844 enum { omptool_opts_nelems = sizeof(omptool_opts_values) / sizeof(omptool_opts_values[0]) };
845
846 294 int parse_omptool_opts(const char *str, omptool_opts_t *value) {
847
848 294 *value = OMPTOOL_OPTS_NONE;
849
850 /* tokenize multiple options separated by ':' */
851 294 char *end_token = NULL;
852 294 size_t len = strlen(str) + 1;
853 294 char *str_copy = malloc(sizeof(char)*len);
854 294 strcpy(str_copy, str);
855 294 char *token = strtok_r(str_copy, delim, &end_token);
856
2/2
✓ Branch 0 taken 298 times.
✓ Branch 1 taken 294 times.
592 while (token) {
857 int i;
858
2/2
✓ Branch 0 taken 603 times.
✓ Branch 1 taken 1 times.
604 for (i=0; i<omptool_opts_nelems; ++i) {
859
2/2
✓ Branch 0 taken 297 times.
✓ Branch 1 taken 306 times.
603 if (strcmp(token, omptool_opts_choices[i]) == 0) {
860 297 *value |= omptool_opts_values[i];
861 297 break;
862 }
863 }
864
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 297 times.
298 if (i == omptool_opts_nelems) {
865 1 warning("Unknown --lewi-ompt option: %s", token);
866 }
867 298 token = strtok_r(NULL, delim, &end_token);
868 }
869 294 free(str_copy);
870
871 294 return DLB_SUCCESS;
872 }
873
874 5 const char* omptool_opts_tostr(omptool_opts_t value) {
875 static char str[sizeof(omptool_opts_choices_str)] = "";
876 5 char *p = str;
877 int i;
878
2/2
✓ Branch 0 taken 15 times.
✓ Branch 1 taken 5 times.
20 for (i=0; i<omptool_opts_nelems; ++i) {
879
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 10 times.
15 if (value & omptool_opts_values[i]) {
880
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
5 if (p!=str) {
881 *p = ':';
882 ++p;
883 *p = '\0';
884 }
885 5 p += sprintf(p, "%s", omptool_opts_choices[i]);
886 }
887 }
888 5 return str;
889 }
890
891 4 const char* get_omptool_opts_choices(void) {
892 4 return omptool_opts_choices_str;
893 }
894
895 3 bool equivalent_omptool_opts(const char *str1, const char *str2) {
896 omptool_opts_t value1, value2;
897 3 parse_omptool_opts(str1, &value1);
898 3 parse_omptool_opts(str2, &value2);
899 3 return value1 == value2;
900 }
901
902 /* omptm_version_t */
903 static const omptm_version_t omptm_version_values[] = {OMPTM_NONE, OMPTM_OMP5,
904 OMPTM_FREE_AGENTS, OMPTM_ROLE_SHIFT};
905 static const char* const omptm_version_choices[] = {"none", "omp5", "free-agents", "role-shift"};
906 static const char omptm_version_choices_str[] = "none, omp5, free-agents, role-shift";
907 enum { omptm_version_nelems = sizeof(omptm_version_values) / sizeof(omptm_version_values[0]) };
908
909 228 int parse_omptm_version(const char *str, omptm_version_t *value) {
910 int i;
911
2/2
✓ Branch 0 taken 459 times.
✓ Branch 1 taken 1 times.
460 for (i=0; i<omptm_version_nelems; ++i) {
912
2/2
✓ Branch 0 taken 227 times.
✓ Branch 1 taken 232 times.
459 if (strcasecmp(str, omptm_version_choices[i]) == 0) {
913 227 *value = omptm_version_values[i];
914 227 return DLB_SUCCESS;
915 }
916 }
917 1 return DLB_ERR_NOENT;
918 }
919
920 4 const char* omptm_version_tostr(omptm_version_t value) {
921 int i;
922
1/2
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
8 for (i=0; i<omptm_version_nelems; ++i) {
923
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 4 times.
8 if (omptm_version_values[i] == value) {
924 4 return omptm_version_choices[i];
925 }
926 }
927 return "unknown";
928 }
929
930 4 const char* get_omptm_version_choices(void) {
931 4 return omptm_version_choices_str;
932 }
933
934 2 bool equivalent_omptm_version_opts(const char *str1, const char *str2) {
935 2 omptm_version_t value1 = OMPTM_OMP5;
936 2 omptm_version_t value2 = OMPTM_FREE_AGENTS;
937 2 int err1 = parse_omptm_version(str1, &value1);
938 2 int err2 = parse_omptm_version(str2, &value2);
939
4/6
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✓ Branch 5 taken 1 times.
2 return err1 == DLB_SUCCESS && err2 == DLB_SUCCESS && value1 == value2;
940 }
941
942