GCC Code Coverage Report


Directory: src/
File: src/support/types.c
Date: 2026-04-21 15:16:03
Exec Total Coverage
Lines: 397 439 90.4%
Functions: 55 58 94.8%
Branches: 234 280 83.6%

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 3512 int parse_bool(const char *str, bool *value) {
36
2/2
✓ Branch 0 taken 3499 times.
✓ Branch 1 taken 13 times.
3512 if (strcasecmp(str, "1")==0 ||
37
2/2
✓ Branch 0 taken 2580 times.
✓ Branch 1 taken 919 times.
3499 strcasecmp(str, "yes")==0 ||
38
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 2579 times.
2580 strcasecmp(str, "true")==0) {
39 933 *value = true;
40
2/2
✓ Branch 0 taken 2573 times.
✓ Branch 1 taken 6 times.
2579 } else if (strcasecmp(str, "0")==0 ||
41
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 2568 times.
2573 strcasecmp(str, "no")==0 ||
42
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 2 times.
5 strcasecmp(str, "false")==0) {
43 2577 *value = false;
44 } else {
45 2 return DLB_ERR_NOENT;
46 }
47 3510 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 1293 int parse_int(const char *str, int *value) {
82 char *endptr;
83 1293 long val = strtol(str, &endptr, 0);
84
4/4
✓ Branch 0 taken 1035 times.
✓ Branch 1 taken 258 times.
✓ Branch 2 taken 1033 times.
✓ Branch 3 taken 2 times.
1293 if ((val == 0 && endptr == str)
85
2/6
✓ Branch 0 taken 1291 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1291 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
1291 || ((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 1291 *value = (int)val;
92 1291 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_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 "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:async:ompt:affinity:barrier:talp:instrument";
114 enum { verbose_opts_nelems = sizeof(verbose_opts_values) / sizeof(verbose_opts_values[0]) };
115
116 275 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 272 times.
275 if (strcmp(str, "yes") == 0) {
119 3 *value = VB_ALL;
120 3 return DLB_SUCCESS;
121 }
122
123 272 *value = VB_CLEAR;
124
125 /* tokenize multiple options separated by ':' */
126 272 char *end_token = NULL;
127 272 size_t len = strlen(str) + 1;
128 272 char *str_copy = malloc(sizeof(char)*len);
129 272 strcpy(str_copy, str);
130 272 char *token = strtok_r(str_copy, delim, &end_token);
131
2/2
✓ Branch 0 taken 287 times.
✓ Branch 1 taken 272 times.
559 while (token) {
132 int i;
133
2/2
✓ Branch 0 taken 569 times.
✓ Branch 1 taken 2 times.
571 for (i=0; i<verbose_opts_nelems; ++i) {
134
2/2
✓ Branch 0 taken 285 times.
✓ Branch 1 taken 284 times.
569 if (strcmp(token, verbose_opts_choices[i]) == 0) {
135 285 *value |= verbose_opts_values[i];
136 285 break;
137 }
138 }
139
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 285 times.
287 if (i == verbose_opts_nelems) {
140 2 warning("Unknown --verbose option: %s", token);
141 }
142 287 token = strtok_r(NULL, delim, &end_token);
143 }
144 272 free(str_copy);
145
146 272 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 13 times.
✓ Branch 1 taken 1 times.
14 for (i=2; i<verbose_opts_nelems; ++i) {
162
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 11 times.
13 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 218 int parse_verbose_fmt(const char *str, verbose_fmt_t *value) {
196 218 *value = VBF_CLEAR;
197
198 /* tokenize multiple options separated by ':' */
199 218 char *end_token = NULL;
200 218 size_t len = strlen(str) + 1;
201 218 char *str_copy = malloc(sizeof(char)*len);
202 218 strcpy(str_copy, str);
203 218 char *token = strtok_r(str_copy, delim, &end_token);
204
2/2
✓ Branch 0 taken 430 times.
✓ Branch 1 taken 218 times.
648 while (token) {
205 int i;
206
2/2
✓ Branch 0 taken 1090 times.
✓ Branch 1 taken 2 times.
1092 for (i=0; i<verbose_fmt_nelems; ++i) {
207
2/2
✓ Branch 0 taken 428 times.
✓ Branch 1 taken 662 times.
1090 if (strcmp(token, verbose_fmt_choices[i]) == 0) {
208 428 *value |= verbose_fmt_values[i];
209 428 break;
210 }
211 }
212
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 428 times.
430 if (i == verbose_fmt_nelems) {
213 2 warning("Unknown --verbose-format option: %s", token);
214 }
215 430 token = strtok_r(NULL, delim, &end_token);
216 }
217 218 free(str_copy);
218
219 218 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_BARR, INST_OMPT, INST_CPUS, INST_CBCK};
254 static const char* const instrument_items_choices[] =
255 {"none", "all", "mpi", "lewi", "drom", "talp", "barrier", "ompt", "cpus", "callbacks"};
256 static const char instrument_items_choices_str[] =
257 "none:all:mpi:lewi:drom:talp:barrier:ompt:cpus:callbacks";
258 enum { instrument_items_nelems = sizeof(instrument_items_values) / sizeof(instrument_items_values[0]) };
259
260 219 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 217 times.
219 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 217 times.
217 if (strcmp(str, "no") == 0) {
269 *value = INST_NONE;
270 return DLB_SUCCESS;
271 }
272
273 217 *value = INST_NONE;
274
275 /* tokenize multiple options separated by ':' */
276 217 char *end_token = NULL;
277 217 size_t len = strlen(str) + 1;
278 217 char *str_copy = malloc(sizeof(char)*len);
279 217 strcpy(str_copy, str);
280 217 char *token = strtok_r(str_copy, delim, &end_token);
281
2/2
✓ Branch 0 taken 227 times.
✓ Branch 1 taken 217 times.
444 while (token) {
282 int i;
283
2/2
✓ Branch 0 taken 531 times.
✓ Branch 1 taken 4 times.
535 for (i=0; i<instrument_items_nelems; ++i) {
284
2/2
✓ Branch 0 taken 223 times.
✓ Branch 1 taken 308 times.
531 if (strcmp(token, instrument_items_choices[i]) == 0) {
285 223 *value |= instrument_items_values[i];
286 223 break;
287 }
288 }
289
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 223 times.
227 if (i == instrument_items_nelems) {
290 4 warning("Unknown --instrument option: %s", token);
291 }
292 227 token = strtok_r(NULL, delim, &end_token);
293 }
294 217 free(str_copy);
295
296 217 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 8 times.
✓ Branch 1 taken 1 times.
9 for (i=2; i<instrument_items_nelems; ++i) {
312
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 6 times.
8 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 208 int parse_debug_opts(const char *str, debug_opts_t *value) {
346 208 *value = DBG_CLEAR;
347 int i;
348
2/2
✓ Branch 0 taken 1040 times.
✓ Branch 1 taken 208 times.
1248 for (i=0; i<debug_opts_nelems; ++i) {
349
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 1037 times.
1040 if (strstr(str, debug_opts_choices[i]) != NULL) {
350 3 *value |= debug_opts_values[i];
351 }
352 }
353 208 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 278 int parse_lewi_affinity(const char *str, lewi_affinity_t *value) {
397
398
2/2
✓ Branch 0 taken 356 times.
✓ Branch 1 taken 4 times.
360 for (int i = 0; i < lewi_affinity_nelems; ++i) {
399
2/2
✓ Branch 0 taken 274 times.
✓ Branch 1 taken 82 times.
356 if (strcasecmp(str, lewi_affinity_choices[i]) == 0) {
400 274 *value = lewi_affinity_values[i];
401 274 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 218 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 217 times.
218 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 217 times.
217 if (strcmp(str, "no") == 0) {
456 *value = SUMMARY_NONE;
457 return DLB_SUCCESS;
458 }
459
460 217 *value = SUMMARY_NONE;
461
462 /* tokenize multiple options separated by ':' */
463 217 char *end_token = NULL;
464 217 size_t len = strlen(str) + 1;
465 217 char *str_copy = malloc(sizeof(char)*len);
466 217 strcpy(str_copy, str);
467 217 char *token = strtok_r(str_copy, delim, &end_token);
468
2/2
✓ Branch 0 taken 219 times.
✓ Branch 1 taken 217 times.
436 while (token) {
469 int i;
470
2/2
✓ Branch 0 taken 677 times.
✓ Branch 1 taken 4 times.
681 for (i=0; i<talp_summary_nelems; ++i) {
471
2/2
✓ Branch 0 taken 215 times.
✓ Branch 1 taken 462 times.
677 if (strcmp(token, talp_summary_choices[i]) == 0) {
472 215 *value |= talp_summary_values[i];
473 215 break;
474 }
475
476 /* Support deprecated values */
477
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 462 times.
462 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 215 times.
219 if (i == talp_summary_nelems) {
483 4 warning("Unknown --talp-summary option: %s", token);
484 }
485 219 token = strtok_r(NULL, delim, &end_token);
486 }
487 217 free(str_copy);
488
489 /* Deprecation warnings: */
490
491
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 214 times.
217 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 215 times.
217 if (*value & SUMMARY_NODE) {
496 2 warning("Deprecated: --talp-summary=node is deprecated. Use process instead.");
497 }
498
499 217 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
539 /* talp_model_t */
540 static const talp_model_t talp_model_values[] = {TALP_MODEL_HYBRID_V1, TALP_MODEL_HYBRID_V2};
541 static const char* const talp_model_choices[] = {"hybrid-v1", "hybrid-v2"};
542 static const char talp_model_choices_str[] = "hybrid-v1, hybrid-v2";
543 enum { talp_model_nelems = sizeof(talp_model_values) / sizeof(talp_model_values[0]) };
544
545 214 int parse_talp_model(const char *str, talp_model_t *value) {
546 int i;
547
2/2
✓ Branch 0 taken 424 times.
✓ Branch 1 taken 1 times.
425 for (i=0; i<talp_model_nelems; ++i) {
548
2/2
✓ Branch 0 taken 213 times.
✓ Branch 1 taken 211 times.
424 if (strcasecmp(str, talp_model_choices[i]) == 0) {
549 213 *value = talp_model_values[i];
550 213 return DLB_SUCCESS;
551 }
552 }
553 1 return DLB_ERR_NOENT;
554 }
555
556 2 const char* talp_model_tostr(talp_model_t value) {
557 int i;
558
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 for (i=0; i<talp_model_nelems; ++i) {
559
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2 times.
4 if (talp_model_values[i] == value) {
560 2 return talp_model_choices[i];
561 }
562 }
563 return "unknown";
564 }
565
566 1 const char* get_talp_model_choices(void) {
567 1 return talp_model_choices_str;
568 }
569
570 2 bool equivalent_talp_model(const char *str1, const char *str2) {
571 2 talp_model_t value1 = TALP_MODEL_HYBRID_V1;
572 2 talp_model_t value2 = TALP_MODEL_HYBRID_V2;
573 2 int err1 = parse_talp_model(str1, &value1);
574 2 int err2 = parse_talp_model(str2, &value2);
575
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;
576 }
577
578
579 /* talp_component_t */
580 static const talp_component_t talp_component_values[] = {
581 TALP_COMPONENT_NONE, TALP_COMPONENT_DEFAULT, TALP_COMPONENT_MPI, TALP_COMPONENT_OPENMP,
582 TALP_COMPONENT_GPU, TALP_COMPONENT_HWC };
583 static const char* const talp_component_choices[] = {"none", "default", "mpi", "openmp", "gpu", "hwc"};
584 static const char talp_component_choices_str[] = "none:default:mpi:openmp:gpu:hwc";
585 enum { talp_component_nelems = sizeof(talp_component_values) / sizeof(talp_component_values[0]) };
586
587 206 int parse_talp_component(const char *str, talp_component_t *value) {
588 /* particular case: '--talp/--talp=yes' is equivalent to --talp=default */
589
2/2
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 186 times.
206 if (strcmp(str, "yes") == 0) {
590 20 *value = TALP_COMPONENT_DEFAULT;
591 20 return DLB_SUCCESS;
592 }
593
594 /* particular case: '--no-talp/--talp=no' is equivalent to --talp=none */
595
2/2
✓ Branch 0 taken 185 times.
✓ Branch 1 taken 1 times.
186 if (strcmp(str, "no") == 0
596
2/2
✓ Branch 0 taken 179 times.
✓ Branch 1 taken 6 times.
185 || strcmp(str, talp_component_choices[0]) == 0) {
597 180 *value = TALP_COMPONENT_NONE;
598 180 return DLB_SUCCESS;
599 }
600
601 6 *value = TALP_COMPONENT_NONE;
602
603 /* tokenize multiple options separated by ':' */
604 6 char *end_token = NULL;
605 6 size_t len = strlen(str) + 1;
606 6 char *str_copy = malloc(sizeof(char)*len);
607 6 strcpy(str_copy, str);
608 6 char *token = strtok_r(str_copy, delim, &end_token);
609
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 6 times.
14 while (token) {
610 int i;
611
1/2
✓ Branch 0 taken 19 times.
✗ Branch 1 not taken.
19 for (i=1; i<talp_component_nelems; ++i) {
612
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 14 times.
19 if (strcmp(token, talp_component_choices[i]) == 0) {
613 5 *value |= talp_component_values[i];
614 5 break;
615 }
616
617 /* Support "easy-to-confuse" values */
618
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14 times.
14 if (strcmp(token, "cuda") == 0) {
619 *value |= TALP_COMPONENT_GPU;
620 break;
621 }
622
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14 times.
14 if (strcmp(token, "omp") == 0) {
623 *value |= TALP_COMPONENT_OPENMP;
624 break;
625 }
626
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 11 times.
14 if (strcmp(token, "papi") == 0) {
627 3 *value |= TALP_COMPONENT_HWC;
628 3 break;
629 }
630 }
631
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
8 if (i == talp_component_nelems) {
632 warning("Unknown --talp option: %s", token);
633 }
634 8 token = strtok_r(NULL, delim, &end_token);
635 }
636 6 free(str_copy);
637
638 6 return DLB_SUCCESS;
639 }
640
641 5 const char* talp_component_tostr(talp_component_t value) {
642 // particular cases
643
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 1 times.
5 if (value == TALP_COMPONENT_NONE) {
644 4 return "none";
645 }
646
647 static char str[sizeof(talp_component_choices_str)] = "";
648 1 char *p = str;
649 int i;
650
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 1 times.
6 for (i=1; i<talp_component_nelems; ++i) {
651
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 4 times.
5 if (value & talp_component_values[i]) {
652
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (p!=str) {
653 *p = ':';
654 ++p;
655 *p = '\0';
656 }
657 1 p += sprintf(p, "%s", talp_component_choices[i]);
658 }
659 }
660 1 return str;
661 }
662
663 4 const char* get_talp_component_choices(void) {
664 4 return talp_component_choices_str;
665 }
666
667 bool equivalent_talp_component(const char *str1, const char *str2) {
668 talp_component_t value1 = TALP_COMPONENT_MPI;
669 talp_component_t value2 = TALP_COMPONENT_OPENMP;
670 int err1 = parse_talp_component(str1, &value1);
671 int err2 = parse_talp_component(str2, &value2);
672 return err1 == DLB_SUCCESS && err2 == DLB_SUCCESS && value1 == value2;
673 }
674
675
676 /* policy_t: most of this stuff is depcrecated, only policy_tostr is still used */
677 static const policy_t policy_values[] = {POLICY_NONE, POLICY_LEWI, POLICY_LEWI_ASYNC, POLICY_LEWI_MASK};
678 static const char* const policy_choices[] = {"no", "LeWI", "LeWI_async", "LeWI_mask"};
679 static const char policy_choices_str[] = "no, LeWI, LeWI_async, LeWI_mask";
680 enum { policy_nelems = sizeof(policy_values) / sizeof(policy_values[0]) };
681
682 9 int parse_policy(const char *str, policy_t *value) {
683 int i;
684
2/2
✓ Branch 0 taken 25 times.
✓ Branch 1 taken 2 times.
27 for (i=0; i<policy_nelems; ++i) {
685
2/2
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 18 times.
25 if (strcasecmp(str, policy_choices[i]) == 0) {
686 7 *value = policy_values[i];
687 7 return DLB_SUCCESS;
688 }
689 }
690 2 return DLB_ERR_NOENT;
691 }
692
693 63 const char* policy_tostr(policy_t value) {
694 int i;
695
2/2
✓ Branch 0 taken 183 times.
✓ Branch 1 taken 1 times.
184 for (i=0; i<policy_nelems; ++i) {
696
2/2
✓ Branch 0 taken 62 times.
✓ Branch 1 taken 121 times.
183 if (policy_values[i] == value) {
697 62 return policy_choices[i];
698 }
699 }
700 1 return "error";
701 }
702
703 const char* get_policy_choices(void) {
704 return policy_choices_str;
705 }
706
707 2 bool equivalent_policy(const char *str1, const char *str2) {
708 2 policy_t value1 = POLICY_NONE;
709 2 policy_t value2 = POLICY_LEWI;
710 2 int err1 = parse_policy(str1, &value1);
711 2 int err2 = parse_policy(str2, &value2);
712
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;
713 }
714
715 /* interaction_mode_t */
716 static const interaction_mode_t mode_values[] = {MODE_POLLING, MODE_ASYNC};
717 static const char* const mode_choices[] = {"polling", "async"};
718 static const char mode_choices_str[] = "polling, async";
719 enum { mode_nelems = sizeof(mode_values) / sizeof(mode_values[0]) };
720
721 215 int parse_mode(const char *str, interaction_mode_t *value) {
722 int i;
723
2/2
✓ Branch 0 taken 243 times.
✓ Branch 1 taken 2 times.
245 for (i=0; i<mode_nelems; ++i) {
724
2/2
✓ Branch 0 taken 213 times.
✓ Branch 1 taken 30 times.
243 if (strcasecmp(str, mode_choices[i]) == 0) {
725 213 *value = mode_values[i];
726 213 return DLB_SUCCESS;
727 }
728 }
729 2 return DLB_ERR_NOENT;
730 }
731
732 8 const char* mode_tostr(interaction_mode_t value) {
733 int i;
734
1/2
✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
10 for (i=0; i<mode_nelems; ++i) {
735
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 2 times.
10 if (mode_values[i] == value) {
736 8 return mode_choices[i];
737 }
738 }
739 return "unknown";
740 }
741
742 4 const char* get_mode_choices(void) {
743 4 return mode_choices_str;
744 }
745
746 2 bool equivalent_mode(const char *str1, const char *str2) {
747 2 interaction_mode_t value1 = MODE_POLLING;
748 2 interaction_mode_t value2 = MODE_ASYNC;
749 2 int err1 = parse_mode(str1, &value1);
750 2 int err2 = parse_mode(str2, &value2);
751
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;
752 }
753
754 /* mpi_set_t */
755 static const mpi_set_t mpiset_values[] = {MPISET_NONE, MPISET_ALL, MPISET_BARRIER, MPISET_COLLECTIVES};
756 static const char* const mpiset_choices[] = {"none", "all", "barrier", "collectives"};
757 static const char mpiset_choices_str[] = "none, all, barrier, collectives";
758 enum { mpiset_nelems = sizeof(mpiset_values) / sizeof(mpiset_values[0]) };
759
760 273 int parse_mpiset(const char *str, mpi_set_t *value) {
761 int i;
762
2/2
✓ Branch 0 taken 552 times.
✓ Branch 1 taken 1 times.
553 for (i=0; i<mpiset_nelems; ++i) {
763
2/2
✓ Branch 0 taken 272 times.
✓ Branch 1 taken 280 times.
552 if (strcasecmp(str, mpiset_choices[i]) == 0) {
764 272 *value = mpiset_values[i];
765 272 return DLB_SUCCESS;
766 }
767 }
768 1 return DLB_ERR_NOENT;
769 }
770
771 6 const char* mpiset_tostr(mpi_set_t value) {
772 int i;
773
1/2
✓ Branch 0 taken 13 times.
✗ Branch 1 not taken.
13 for (i=0; i<mpiset_nelems; ++i) {
774
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 7 times.
13 if (mpiset_values[i] == value) {
775 6 return mpiset_choices[i];
776 }
777 }
778 return "unknown";
779 }
780
781 4 const char* get_mpiset_choices(void) {
782 4 return mpiset_choices_str;
783 }
784
785 2 bool equivalent_mpiset(const char *str1, const char *str2) {
786 2 mpi_set_t value1 = MPISET_NONE;
787 2 mpi_set_t value2 = MPISET_ALL;
788 2 int err1 = parse_mpiset(str1, &value1);
789 2 int err2 = parse_mpiset(str2, &value2);
790
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;
791 }
792
793 /* omptool_opts_t */
794 static const omptool_opts_t omptool_opts_values[] =
795 {OMPTOOL_OPTS_NONE, OMPTOOL_OPTS_BORROW, OMPTOOL_OPTS_LEND};
796 static const char* const omptool_opts_choices[] = {"none", "borrow", "lend"};
797 static const char omptool_opts_choices_str[] = "none, {borrow:lend}";
798 enum { omptool_opts_nelems = sizeof(omptool_opts_values) / sizeof(omptool_opts_values[0]) };
799
800 274 int parse_omptool_opts(const char *str, omptool_opts_t *value) {
801
802 274 *value = OMPTOOL_OPTS_NONE;
803
804 /* tokenize multiple options separated by ':' */
805 274 char *end_token = NULL;
806 274 size_t len = strlen(str) + 1;
807 274 char *str_copy = malloc(sizeof(char)*len);
808 274 strcpy(str_copy, str);
809 274 char *token = strtok_r(str_copy, delim, &end_token);
810
2/2
✓ Branch 0 taken 278 times.
✓ Branch 1 taken 274 times.
552 while (token) {
811 int i;
812
2/2
✓ Branch 0 taken 563 times.
✓ Branch 1 taken 1 times.
564 for (i=0; i<omptool_opts_nelems; ++i) {
813
2/2
✓ Branch 0 taken 277 times.
✓ Branch 1 taken 286 times.
563 if (strcmp(token, omptool_opts_choices[i]) == 0) {
814 277 *value |= omptool_opts_values[i];
815 277 break;
816 }
817 }
818
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 277 times.
278 if (i == omptool_opts_nelems) {
819 1 warning("Unknown --lewi-ompt option: %s", token);
820 }
821 278 token = strtok_r(NULL, delim, &end_token);
822 }
823 274 free(str_copy);
824
825 274 return DLB_SUCCESS;
826 }
827
828 5 const char* omptool_opts_tostr(omptool_opts_t value) {
829 static char str[sizeof(omptool_opts_choices_str)] = "";
830 5 char *p = str;
831 int i;
832
2/2
✓ Branch 0 taken 15 times.
✓ Branch 1 taken 5 times.
20 for (i=0; i<omptool_opts_nelems; ++i) {
833
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 10 times.
15 if (value & omptool_opts_values[i]) {
834
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
5 if (p!=str) {
835 *p = ':';
836 ++p;
837 *p = '\0';
838 }
839 5 p += sprintf(p, "%s", omptool_opts_choices[i]);
840 }
841 }
842 5 return str;
843 }
844
845 4 const char* get_omptool_opts_choices(void) {
846 4 return omptool_opts_choices_str;
847 }
848
849 3 bool equivalent_omptool_opts(const char *str1, const char *str2) {
850 omptool_opts_t value1, value2;
851 3 parse_omptool_opts(str1, &value1);
852 3 parse_omptool_opts(str2, &value2);
853 3 return value1 == value2;
854 }
855
856 /* omptm_version_t */
857 static const omptm_version_t omptm_version_values[] = {OMPTM_NONE, OMPTM_OMP5,
858 OMPTM_FREE_AGENTS, OMPTM_ROLE_SHIFT};
859 static const char* const omptm_version_choices[] = {"none", "omp5", "free-agents", "role-shift"};
860 static const char omptm_version_choices_str[] = "none, omp5, free-agents, role-shift";
861 enum { omptm_version_nelems = sizeof(omptm_version_values) / sizeof(omptm_version_values[0]) };
862
863 212 int parse_omptm_version(const char *str, omptm_version_t *value) {
864 int i;
865
2/2
✓ Branch 0 taken 427 times.
✓ Branch 1 taken 1 times.
428 for (i=0; i<omptm_version_nelems; ++i) {
866
2/2
✓ Branch 0 taken 211 times.
✓ Branch 1 taken 216 times.
427 if (strcasecmp(str, omptm_version_choices[i]) == 0) {
867 211 *value = omptm_version_values[i];
868 211 return DLB_SUCCESS;
869 }
870 }
871 1 return DLB_ERR_NOENT;
872 }
873
874 4 const char* omptm_version_tostr(omptm_version_t value) {
875 int i;
876
1/2
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
8 for (i=0; i<omptm_version_nelems; ++i) {
877
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 4 times.
8 if (omptm_version_values[i] == value) {
878 4 return omptm_version_choices[i];
879 }
880 }
881 return "unknown";
882 }
883
884 4 const char* get_omptm_version_choices(void) {
885 4 return omptm_version_choices_str;
886 }
887
888 2 bool equivalent_omptm_version_opts(const char *str1, const char *str2) {
889 2 omptm_version_t value1 = OMPTM_OMP5;
890 2 omptm_version_t value2 = OMPTM_FREE_AGENTS;
891 2 int err1 = parse_omptm_version(str1, &value1);
892 2 int err2 = parse_omptm_version(str2, &value2);
893
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;
894 }
895
896