GCC Code Coverage Report


Directory: src/
File: src/support/types.c
Date: 2024-11-22 17:07:10
Exec Total Coverage
Lines: 358 386 92.7%
Functions: 52 54 96.3%
Branches: 208 246 84.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 2645 int parse_bool(const char *str, bool *value) {
33
2/2
✓ Branch 0 taken 2640 times.
✓ Branch 1 taken 5 times.
2645 if (strcasecmp(str, "1")==0 ||
34
2/2
✓ Branch 0 taken 2081 times.
✓ Branch 1 taken 559 times.
2640 strcasecmp(str, "yes")==0 ||
35
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 2080 times.
2081 strcasecmp(str, "true")==0) {
36 565 *value = true;
37
2/2
✓ Branch 0 taken 2074 times.
✓ Branch 1 taken 6 times.
2080 } else if (strcasecmp(str, "0")==0 ||
38
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 2069 times.
2074 strcasecmp(str, "no")==0 ||
39
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 2 times.
5 strcasecmp(str, "false")==0) {
40 2078 *value = false;
41 } else {
42 2 return DLB_ERR_NOENT;
43 }
44 2643 return DLB_SUCCESS;
45 }
46
47 3 bool equivalent_bool(const char *str1, const char *str2) {
48 3 bool b1 = false;
49 3 bool b2 = true;
50 3 int err1 = parse_bool(str1, &b1);
51 3 int err2 = parse_bool(str2, &b2);
52
4/6
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✓ Branch 5 taken 2 times.
3 return err1 == DLB_SUCCESS && err2 == DLB_SUCCESS && b1 == b2;
53 }
54
55 16 int parse_negated_bool(const char *str, bool *value) {
56
2/2
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 2 times.
16 if (strcasecmp(str, "1")==0 ||
57
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 4 times.
14 strcasecmp(str, "yes")==0 ||
58
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 9 times.
10 strcasecmp(str, "true")==0) {
59 7 *value = false;
60
2/2
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 2 times.
9 } else if (strcasecmp(str, "0")==0 ||
61
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 2 times.
7 strcasecmp(str, "no")==0 ||
62
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 2 times.
5 strcasecmp(str, "false")==0) {
63 7 *value = true;
64 } else {
65 2 return DLB_ERR_NOENT;
66 }
67 14 return DLB_SUCCESS;
68 }
69
70 2 bool equivalent_negated_bool(const char *str1, const char *str2) {
71 2 bool b1 = false;
72 2 bool b2 = true;
73 2 int err1 = parse_negated_bool(str1, &b1);
74 2 int err2 = parse_negated_bool(str2, &b2);
75
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;
76 }
77
78 962 int parse_int(const char *str, int *value) {
79 char *endptr;
80 962 long val = strtol(str, &endptr, 0);
81
4/4
✓ Branch 0 taken 789 times.
✓ Branch 1 taken 173 times.
✓ Branch 2 taken 787 times.
✓ Branch 3 taken 2 times.
962 if ((val == 0 && endptr == str)
82
2/6
✓ Branch 0 taken 960 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 960 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
960 || ((val == LONG_MIN || val == LONG_MAX) && errno == ERANGE)) {
83 2 debug_warning("Error parsing integer. str: %s, strlen: %lu, val: %ld, "
84 "errno: %d, strptr: %p, endptr: %p", str, strlen(str), val,
85 errno, str, endptr);
86 2 return DLB_ERR_NOENT;
87 }
88 960 *value = (int)val;
89 960 return DLB_SUCCESS;
90 }
91
92 2 bool equivalent_int(const char *str1, const char *str2) {
93 2 int i1 = 0;
94 2 int i2 = 1;
95 2 int err1 = parse_int(str1, &i1);
96 2 int err2 = parse_int(str2, &i2);
97
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;
98 }
99
100
101 /* verbose_opts_t */
102 static const verbose_opts_t verbose_opts_values[] =
103 {VB_CLEAR, VB_ALL, VB_API, VB_MICROLB, VB_SHMEM, VB_MPI_API, VB_MPI_INT, VB_STATS,
104 VB_DROM, VB_ASYNC, VB_OMPT, VB_AFFINITY, VB_BARRIER, VB_TALP, VB_INSTR};
105 static const char* const verbose_opts_choices[] =
106 {"no", "all", "api", "microlb", "shmem", "mpi_api", "mpi_intercept", "stats", "drom",
107 "async", "ompt", "affinity", "barrier", "talp", "instrument"};
108 static const char verbose_opts_choices_str[] =
109 "no:all:api:microlb:shmem:mpi_api:mpi_intercept:stats:"LINE_BREAK
110 "drom:async:ompt:affinity:barrier:talp:instrument";
111 enum { verbose_opts_nelems = sizeof(verbose_opts_values) / sizeof(verbose_opts_values[0]) };
112
113 217 int parse_verbose_opts(const char *str, verbose_opts_t *value) {
114 /* particular case: '--verbose/--verbose=yes' enables all verbose options */
115
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 214 times.
217 if (strcmp(str, "yes") == 0) {
116 3 *value = VB_ALL;
117 3 return DLB_SUCCESS;
118 }
119
120 214 *value = VB_CLEAR;
121
122 /* tokenize multiple options separated by ':' */
123 214 char *end_token = NULL;
124 214 size_t len = strlen(str) + 1;
125 214 char *str_copy = malloc(sizeof(char)*len);
126 214 strcpy(str_copy, str);
127 214 char *token = strtok_r(str_copy, ":", &end_token);
128
2/2
✓ Branch 0 taken 225 times.
✓ Branch 1 taken 214 times.
439 while (token) {
129 int i;
130
2/2
✓ Branch 0 taken 451 times.
✓ Branch 1 taken 2 times.
453 for (i=0; i<verbose_opts_nelems; ++i) {
131
2/2
✓ Branch 0 taken 223 times.
✓ Branch 1 taken 228 times.
451 if (strcmp(token, verbose_opts_choices[i]) == 0) {
132 223 *value |= verbose_opts_values[i];
133 223 break;
134 }
135 }
136
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 223 times.
225 if (i == verbose_opts_nelems) {
137 2 warning("Unknown --verbose option: %s", token);
138 }
139 225 token = strtok_r(NULL, ":", &end_token);
140 }
141 214 free(str_copy);
142
143 214 return DLB_SUCCESS;
144 }
145
146 7 const char* verbose_opts_tostr(verbose_opts_t value) {
147 /* particular cases */
148
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 2 times.
7 if (value == VB_CLEAR) {
149 5 return "no";
150 }
151
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 if (value == VB_ALL) {
152 1 return "all";
153 }
154
155 static char str[sizeof(verbose_opts_choices_str)] = "";
156 1 char *p = str;
157 int i;
158
2/2
✓ Branch 0 taken 13 times.
✓ Branch 1 taken 1 times.
14 for (i=2; i<verbose_opts_nelems; ++i) {
159
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 11 times.
13 if (value & verbose_opts_values[i]) {
160
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 if (p!=str) {
161 1 *p = ':';
162 1 ++p;
163 1 *p = '\0';
164 }
165 2 p += sprintf(p, "%s", verbose_opts_choices[i]);
166 }
167 }
168 1 return str;
169 }
170
171 4 const char* get_verbose_opts_choices(void) {
172 4 return verbose_opts_choices_str;
173 }
174
175 3 bool equivalent_verbose_opts(const char *str1, const char *str2) {
176 verbose_opts_t value1, value2;
177 3 parse_verbose_opts(str1, &value1);
178 3 parse_verbose_opts(str2, &value2);
179 3 return value1 == value2;
180 }
181
182
183 /* verbose_fmt_t */
184 static const verbose_fmt_t verbose_fmt_values[] =
185 {VBF_NODE, VBF_MPINODE, VBF_MPIRANK, VBF_SPID, VBF_THREAD, VBF_TSTAMP};
186 static const char* const verbose_fmt_choices[] =
187 {"node", "mpinode", "mpirank", "spid", "thread", "timestamp"};
188 static const char verbose_fmt_choices_str[] =
189 "node:mpinode:mpirank:spid:thread:timestamp";
190 enum { verbose_fmt_nelems = sizeof(verbose_fmt_values) / sizeof(verbose_fmt_values[0]) };
191
192 167 int parse_verbose_fmt(const char *str, verbose_fmt_t *value) {
193 167 *value = VBF_CLEAR;
194
195 /* tokenize multiple options separated by ':' */
196 167 char *end_token = NULL;
197 167 size_t len = strlen(str) + 1;
198 167 char *str_copy = malloc(sizeof(char)*len);
199 167 strcpy(str_copy, str);
200 167 char *token = strtok_r(str_copy, ":", &end_token);
201
2/2
✓ Branch 0 taken 329 times.
✓ Branch 1 taken 167 times.
496 while (token) {
202 int i;
203
2/2
✓ Branch 0 taken 841 times.
✓ Branch 1 taken 3 times.
844 for (i=0; i<verbose_fmt_nelems; ++i) {
204
2/2
✓ Branch 0 taken 326 times.
✓ Branch 1 taken 515 times.
841 if (strcmp(token, verbose_fmt_choices[i]) == 0) {
205 326 *value |= verbose_fmt_values[i];
206 326 break;
207 }
208 }
209
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 326 times.
329 if (i == verbose_fmt_nelems) {
210 3 warning("Unknown --verbose-format option: %s", token);
211 }
212 329 token = strtok_r(NULL, ":", &end_token);
213 }
214 167 free(str_copy);
215
216 167 return DLB_SUCCESS;
217 }
218
219 8 const char* verbose_fmt_tostr(verbose_fmt_t value) {
220 static char str[sizeof(verbose_fmt_choices_str)] = "";
221 8 char *p = str;
222 int i;
223
2/2
✓ Branch 0 taken 48 times.
✓ Branch 1 taken 8 times.
56 for (i=0; i<verbose_fmt_nelems; ++i) {
224
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 36 times.
48 if (value & verbose_fmt_values[i]) {
225
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 7 times.
12 if (p!=str) {
226 5 *p = ':';
227 5 ++p;
228 5 *p = '\0';
229 }
230 12 p += sprintf(p, "%s", verbose_fmt_choices[i]);
231 }
232 }
233 8 return str;
234 }
235
236 4 const char* get_verbose_fmt_choices(void) {
237 4 return verbose_fmt_choices_str;
238 }
239
240 3 bool equivalent_verbose_fmt(const char *str1, const char *str2) {
241 verbose_fmt_t value1, value2;
242 3 parse_verbose_fmt(str1, &value1);
243 3 parse_verbose_fmt(str2, &value2);
244 3 return value1 == value2;
245 }
246
247
248 /* instrument_items_t */
249 static const instrument_items_t instrument_items_values[] =
250 {INST_NONE, INST_ALL, INST_MPI, INST_LEWI, INST_DROM, INST_TALP, INST_BARR, INST_OMPT, INST_CPUS, INST_CBCK};
251 static const char* const instrument_items_choices[] =
252 {"none", "all", "mpi", "lewi", "drom", "talp", "barrier", "ompt", "cpus", "callbacks"};
253 static const char instrument_items_choices_str[] =
254 "none:all:mpi:lewi:drom:talp:barrier:ompt:cpus:callbacks";
255 enum { instrument_items_nelems = sizeof(instrument_items_values) / sizeof(instrument_items_values[0]) };
256
257 168 int parse_instrument_items(const char *str, instrument_items_t *value) {
258 /* particular case: '--instrument/--instrument=yes' enables all instrument items */
259
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 166 times.
168 if (strcmp(str, "yes") == 0) {
260 2 *value = INST_ALL;
261 2 return DLB_SUCCESS;
262 }
263
264 /* particular case: '--no-instrument/--instrument=no' disables all instrument items */
265
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 166 times.
166 if (strcmp(str, "no") == 0) {
266 *value = INST_NONE;
267 return DLB_SUCCESS;
268 }
269
270 166 *value = INST_NONE;
271
272 /* tokenize multiple options separated by ':' */
273 166 char *end_token = NULL;
274 166 size_t len = strlen(str) + 1;
275 166 char *str_copy = malloc(sizeof(char)*len);
276 166 strcpy(str_copy, str);
277 166 char *token = strtok_r(str_copy, ":", &end_token);
278
2/2
✓ Branch 0 taken 176 times.
✓ Branch 1 taken 166 times.
342 while (token) {
279 int i;
280
2/2
✓ Branch 0 taken 429 times.
✓ Branch 1 taken 4 times.
433 for (i=0; i<instrument_items_nelems; ++i) {
281
2/2
✓ Branch 0 taken 172 times.
✓ Branch 1 taken 257 times.
429 if (strcmp(token, instrument_items_choices[i]) == 0) {
282 172 *value |= instrument_items_values[i];
283 172 break;
284 }
285 }
286
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 172 times.
176 if (i == instrument_items_nelems) {
287 4 warning("Unknown --instrument option: %s", token);
288 }
289 176 token = strtok_r(NULL, ":", &end_token);
290 }
291 166 free(str_copy);
292
293 166 return DLB_SUCCESS;
294 }
295
296 7 const char* instrument_items_tostr(instrument_items_t value) {
297 // particular cases
298
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 6 times.
7 if (value == INST_NONE) {
299 1 return "none";
300 }
301
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 1 times.
6 if (value == INST_ALL) {
302 5 return "all";
303 }
304
305 static char str[sizeof(instrument_items_choices_str)] = "";
306 1 char *p = str;
307 int i;
308
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 1 times.
9 for (i=2; i<instrument_items_nelems; ++i) {
309
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 6 times.
8 if (value & instrument_items_values[i]) {
310
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 if (p!=str) {
311 1 *p = ':';
312 1 ++p;
313 1 *p = '\0';
314 }
315 2 p += sprintf(p, "%s", instrument_items_choices[i]);
316 }
317 }
318 1 return str;
319 }
320
321 4 const char* get_instrument_items_choices(void) {
322 4 return instrument_items_choices_str;
323 }
324
325 3 bool equivalent_instrument_items(const char *str1, const char *str2) {
326 instrument_items_t value1, value2;
327 3 parse_instrument_items(str1, &value1);
328 3 parse_instrument_items(str2, &value2);
329 3 return value1 == value2;
330 }
331
332
333 /* debug_opts_t */
334 static const debug_opts_t debug_opts_values[] =
335 {DBG_RETURNSTOLEN, DBG_WERROR, DBG_LPOSTMORTEM, DBG_WARNMPI};
336 static const char* const debug_opts_choices[] =
337 {"return-stolen", "werror", "lend-post-mortem", "warn-mpi-version"};
338 static const char debug_opts_choices_str[] =
339 "return-stolen:werror:lend-post-mortem:warn-mpi-version";
340 enum { debug_opts_nelems = sizeof(debug_opts_values) / sizeof(debug_opts_values[0]) };
341
342 157 int parse_debug_opts(const char *str, debug_opts_t *value) {
343 157 *value = DBG_CLEAR;
344 int i;
345
2/2
✓ Branch 0 taken 628 times.
✓ Branch 1 taken 157 times.
785 for (i=0; i<debug_opts_nelems; ++i) {
346
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 625 times.
628 if (strstr(str, debug_opts_choices[i]) != NULL) {
347 3 *value |= debug_opts_values[i];
348 }
349 }
350 157 return DLB_SUCCESS;
351 }
352
353 1 const char* debug_opts_tostr(debug_opts_t value) {
354 static char str[sizeof(debug_opts_choices_str)] = "";
355 1 char *p = str;
356 int i;
357
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 1 times.
5 for (i=0; i<debug_opts_nelems; ++i) {
358
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if (value & debug_opts_values[i]) {
359 if (p!=str) {
360 *p = ':';
361 ++p;
362 *p = '\0';
363 }
364 p += sprintf(p, "%s", debug_opts_choices[i]);
365 }
366 }
367 1 return str;
368 }
369
370 1 const char* get_debug_opts_choices(void) {
371 1 return debug_opts_choices_str;
372 }
373
374 bool equivalent_debug_opts(const char *str1, const char *str2) {
375 debug_opts_t value1, value2;
376 parse_debug_opts(str1, &value1);
377 parse_debug_opts(str2, &value2);
378 return value1 == value2;
379 }
380
381
382 /* lewi_affinity_t */
383 static const lewi_affinity_t lewi_affinity_values[] =
384 {LEWI_AFFINITY_AUTO, LEWI_AFFINITY_NONE, LEWI_AFFINITY_MASK,
385 LEWI_AFFINITY_NEARBY_FIRST, LEWI_AFFINITY_NEARBY_ONLY, LEWI_AFFINITY_SPREAD_IFEMPTY};
386 static const char* const lewi_affinity_choices[] =
387 {"auto", "none", "mask", "nearby-first", "nearby-only", "spread-ifempty"};
388 static const char lewi_affinity_choices_str[] =
389 "auto, none, mask, nearby-first,"LINE_BREAK
390 "nearby-only, spread-ifempty";
391 enum { lewi_affinity_nelems = sizeof(lewi_affinity_values) / sizeof(lewi_affinity_values[0]) };
392
393 214 int parse_lewi_affinity(const char *str, lewi_affinity_t *value) {
394
395
2/2
✓ Branch 0 taken 262 times.
✓ Branch 1 taken 4 times.
266 for (int i = 0; i < lewi_affinity_nelems; ++i) {
396
2/2
✓ Branch 0 taken 210 times.
✓ Branch 1 taken 52 times.
262 if (strcasecmp(str, lewi_affinity_choices[i]) == 0) {
397 210 *value = lewi_affinity_values[i];
398 210 return DLB_SUCCESS;
399 }
400 }
401
402 /* Support deprecated values */
403
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2 times.
4 if (strcasecmp(str, "any") == 0) {
404 2 *value = LEWI_AFFINITY_MASK;
405 2 return DLB_SUCCESS;
406 }
407
408 2 return DLB_ERR_NOENT;
409 }
410
411 4 const char* lewi_affinity_tostr(lewi_affinity_t value) {
412 int i;
413
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 for (i=0; i<lewi_affinity_nelems; ++i) {
414
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 if (lewi_affinity_values[i] == value) {
415 4 return lewi_affinity_choices[i];
416 }
417 }
418 return "unknown";
419 }
420
421 4 const char* get_lewi_affinity_choices(void) {
422 4 return lewi_affinity_choices_str;
423 }
424
425 2 bool equivalent_lewi_affinity(const char *str1, const char *str2) {
426 2 lewi_affinity_t value1 = LEWI_AFFINITY_NONE;
427 2 lewi_affinity_t value2 = LEWI_AFFINITY_MASK;
428 2 int err1 = parse_lewi_affinity(str1, &value1);
429 2 int err2 = parse_lewi_affinity(str2, &value2);
430
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;
431 }
432
433
434 /* talp_summary_t */
435 static const talp_summary_t talp_summary_values[] =
436 {SUMMARY_NONE, SUMMARY_ALL, SUMMARY_POP_METRICS, SUMMARY_POP_RAW, SUMMARY_NODE,
437 SUMMARY_PROCESS};
438 static const char* const talp_summary_choices[] =
439 {"none", "all", "pop-metrics", "pop-raw", "node", "process"};
440 static const char talp_summary_choices_str[] =
441 "none:all:pop-metrics:process";
442 enum { talp_summary_nelems = sizeof(talp_summary_values) / sizeof(talp_summary_values[0]) };
443
444 167 int parse_talp_summary(const char *str, talp_summary_t *value) {
445 /* particular case: '--talp-summary/--talp-summary=yes' enables only POP metrics */
446
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 166 times.
167 if (strcmp(str, "yes") == 0) {
447 1 *value = SUMMARY_POP_METRICS;
448 1 return DLB_SUCCESS;
449 }
450
451 /* particular case: '--no-talp-summary/--talp-summary=no' disables all summaries */
452
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 166 times.
166 if (strcmp(str, "no") == 0) {
453 *value = SUMMARY_NONE;
454 return DLB_SUCCESS;
455 }
456
457 166 *value = SUMMARY_NONE;
458
459 /* tokenize multiple options separated by ':' */
460 166 char *end_token = NULL;
461 166 size_t len = strlen(str) + 1;
462 166 char *str_copy = malloc(sizeof(char)*len);
463 166 strcpy(str_copy, str);
464 166 char *token = strtok_r(str_copy, ":", &end_token);
465
2/2
✓ Branch 0 taken 168 times.
✓ Branch 1 taken 166 times.
334 while (token) {
466 int i;
467
2/2
✓ Branch 0 taken 524 times.
✓ Branch 1 taken 4 times.
528 for (i=0; i<talp_summary_nelems; ++i) {
468
2/2
✓ Branch 0 taken 164 times.
✓ Branch 1 taken 360 times.
524 if (strcmp(token, talp_summary_choices[i]) == 0) {
469 164 *value |= talp_summary_values[i];
470 164 break;
471 }
472
473 /* Support deprecated values */
474
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 360 times.
360 if (strcmp(token, "app") == 0) {
475 *value |= SUMMARY_POP_METRICS;
476 break;
477 }
478 }
479
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 164 times.
168 if (i == talp_summary_nelems) {
480 4 warning("Unknown --talp-summary option: %s", token);
481 }
482 168 token = strtok_r(NULL, ":", &end_token);
483 }
484 166 free(str_copy);
485
486 /* Deprecation warnings: */
487
488
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 163 times.
166 if (*value & SUMMARY_POP_RAW) {
489 3 warning("Deprecated: --talp-summary=pop-raw is deprecated. Use pop-metrics instead.");
490 }
491
492
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 164 times.
166 if (*value & SUMMARY_NODE) {
493 2 warning("Deprecated: --talp-summary=node is deprecated. Use process instead.");
494 }
495
496 166 return DLB_SUCCESS;
497 }
498
499 7 const char* talp_summary_tostr(talp_summary_t value) {
500 // particular cases
501
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 6 times.
7 if (value == SUMMARY_NONE) {
502 1 return "none";
503 }
504
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 5 times.
6 if (value == SUMMARY_ALL) {
505 1 return "all";
506 }
507
508 static char str[sizeof(talp_summary_choices_str)] = "";
509 5 char *p = str;
510 int i;
511
2/2
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 5 times.
25 for (i=2; i<talp_summary_nelems; ++i) {
512
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 15 times.
20 if (value & talp_summary_values[i]) {
513
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
5 if (p!=str) {
514 *p = ':';
515 ++p;
516 *p = '\0';
517 }
518 5 p += sprintf(p, "%s", talp_summary_choices[i]);
519 }
520 }
521 5 return str;
522 }
523
524 4 const char* get_talp_summary_choices(void) {
525 4 return talp_summary_choices_str;
526 }
527
528 3 bool equivalent_talp_summary(const char *str1, const char *str2) {
529 talp_summary_t value1, value2;
530 3 parse_talp_summary(str1, &value1);
531 3 parse_talp_summary(str2, &value2);
532 3 return value1 == value2;
533 }
534
535
536 /* talp_model_t */
537 static const talp_model_t talp_model_values[] = {TALP_MODEL_HYBRID_V1, TALP_MODEL_HYBRID_V2};
538 static const char* const talp_model_choices[] = {"hybrid-v1", "hybrid-v2"};
539 static const char talp_model_choices_str[] = "hybrid-v1, hybrid-v2";
540 enum { talp_model_nelems = sizeof(talp_model_values) / sizeof(talp_model_values[0]) };
541
542 163 int parse_talp_model(const char *str, talp_model_t *value) {
543 int i;
544
2/2
✓ Branch 0 taken 322 times.
✓ Branch 1 taken 1 times.
323 for (i=0; i<talp_model_nelems; ++i) {
545
2/2
✓ Branch 0 taken 162 times.
✓ Branch 1 taken 160 times.
322 if (strcasecmp(str, talp_model_choices[i]) == 0) {
546 162 *value = talp_model_values[i];
547 162 return DLB_SUCCESS;
548 }
549 }
550 1 return DLB_ERR_NOENT;
551 }
552
553 2 const char* talp_model_tostr(talp_model_t value) {
554 int i;
555
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 for (i=0; i<talp_model_nelems; ++i) {
556
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2 times.
4 if (talp_model_values[i] == value) {
557 2 return talp_model_choices[i];
558 }
559 }
560 return "unknown";
561 }
562
563 1 const char* get_talp_model_choices(void) {
564 1 return talp_model_choices_str;
565 }
566
567 2 bool equivalent_talp_model(const char *str1, const char *str2) {
568 2 talp_model_t value1 = TALP_MODEL_HYBRID_V1;
569 2 talp_model_t value2 = TALP_MODEL_HYBRID_V2;
570 2 int err1 = parse_talp_model(str1, &value1);
571 2 int err2 = parse_talp_model(str2, &value2);
572
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;
573 }
574
575
576 /* policy_t: most of this stuff is depcrecated, only policy_tostr is still used */
577 static const policy_t policy_values[] = {POLICY_NONE, POLICY_LEWI, POLICY_LEWI_ASYNC, POLICY_LEWI_MASK};
578 static const char* const policy_choices[] = {"no", "LeWI", "LeWI_async", "LeWI_mask"};
579 static const char policy_choices_str[] = "no, LeWI, LeWI_async, LeWI_mask";
580 enum { policy_nelems = sizeof(policy_values) / sizeof(policy_values[0]) };
581
582 9 int parse_policy(const char *str, policy_t *value) {
583 int i;
584
2/2
✓ Branch 0 taken 25 times.
✓ Branch 1 taken 2 times.
27 for (i=0; i<policy_nelems; ++i) {
585
2/2
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 18 times.
25 if (strcasecmp(str, policy_choices[i]) == 0) {
586 7 *value = policy_values[i];
587 7 return DLB_SUCCESS;
588 }
589 }
590 2 return DLB_ERR_NOENT;
591 }
592
593 50 const char* policy_tostr(policy_t value) {
594 int i;
595
2/2
✓ Branch 0 taken 134 times.
✓ Branch 1 taken 1 times.
135 for (i=0; i<policy_nelems; ++i) {
596
2/2
✓ Branch 0 taken 49 times.
✓ Branch 1 taken 85 times.
134 if (policy_values[i] == value) {
597 49 return policy_choices[i];
598 }
599 }
600 1 return "error";
601 }
602
603 const char* get_policy_choices(void) {
604 return policy_choices_str;
605 }
606
607 2 bool equivalent_policy(const char *str1, const char *str2) {
608 2 policy_t value1 = POLICY_NONE;
609 2 policy_t value2 = POLICY_LEWI;
610 2 int err1 = parse_policy(str1, &value1);
611 2 int err2 = parse_policy(str2, &value2);
612
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;
613 }
614
615 /* interaction_mode_t */
616 static const interaction_mode_t mode_values[] = {MODE_POLLING, MODE_ASYNC};
617 static const char* const mode_choices[] = {"polling", "async"};
618 static const char mode_choices_str[] = "polling, async";
619 enum { mode_nelems = sizeof(mode_values) / sizeof(mode_values[0]) };
620
621 164 int parse_mode(const char *str, interaction_mode_t *value) {
622 int i;
623
2/2
✓ Branch 0 taken 178 times.
✓ Branch 1 taken 2 times.
180 for (i=0; i<mode_nelems; ++i) {
624
2/2
✓ Branch 0 taken 162 times.
✓ Branch 1 taken 16 times.
178 if (strcasecmp(str, mode_choices[i]) == 0) {
625 162 *value = mode_values[i];
626 162 return DLB_SUCCESS;
627 }
628 }
629 2 return DLB_ERR_NOENT;
630 }
631
632 6 const char* mode_tostr(interaction_mode_t value) {
633 int i;
634
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 for (i=0; i<mode_nelems; ++i) {
635
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 if (mode_values[i] == value) {
636 6 return mode_choices[i];
637 }
638 }
639 return "unknown";
640 }
641
642 4 const char* get_mode_choices(void) {
643 4 return mode_choices_str;
644 }
645
646 2 bool equivalent_mode(const char *str1, const char *str2) {
647 2 interaction_mode_t value1 = MODE_POLLING;
648 2 interaction_mode_t value2 = MODE_ASYNC;
649 2 int err1 = parse_mode(str1, &value1);
650 2 int err2 = parse_mode(str2, &value2);
651
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;
652 }
653
654 /* mpi_set_t */
655 static const mpi_set_t mpiset_values[] = {MPISET_NONE, MPISET_ALL, MPISET_BARRIER, MPISET_COLLECTIVES};
656 static const char* const mpiset_choices[] = {"none", "all", "barrier", "collectives"};
657 static const char mpiset_choices_str[] = "none, all, barrier, collectives";
658 enum { mpiset_nelems = sizeof(mpiset_values) / sizeof(mpiset_values[0]) };
659
660 209 int parse_mpiset(const char *str, mpi_set_t *value) {
661 int i;
662
2/2
✓ Branch 0 taken 424 times.
✓ Branch 1 taken 1 times.
425 for (i=0; i<mpiset_nelems; ++i) {
663
2/2
✓ Branch 0 taken 208 times.
✓ Branch 1 taken 216 times.
424 if (strcasecmp(str, mpiset_choices[i]) == 0) {
664 208 *value = mpiset_values[i];
665 208 return DLB_SUCCESS;
666 }
667 }
668 1 return DLB_ERR_NOENT;
669 }
670
671 6 const char* mpiset_tostr(mpi_set_t value) {
672 int i;
673
1/2
✓ Branch 0 taken 13 times.
✗ Branch 1 not taken.
13 for (i=0; i<mpiset_nelems; ++i) {
674
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 7 times.
13 if (mpiset_values[i] == value) {
675 6 return mpiset_choices[i];
676 }
677 }
678 return "unknown";
679 }
680
681 4 const char* get_mpiset_choices(void) {
682 4 return mpiset_choices_str;
683 }
684
685 2 bool equivalent_mpiset(const char *str1, const char *str2) {
686 2 mpi_set_t value1 = MPISET_NONE;
687 2 mpi_set_t value2 = MPISET_ALL;
688 2 int err1 = parse_mpiset(str1, &value1);
689 2 int err2 = parse_mpiset(str2, &value2);
690
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;
691 }
692
693 /* omptool_opts_t */
694 static const omptool_opts_t omptool_opts_values[] =
695 {OMPTOOL_OPTS_NONE, OMPTOOL_OPTS_BORROW, OMPTOOL_OPTS_LEND};
696 static const char* const omptool_opts_choices[] = {"none", "borrow", "lend"};
697 static const char omptool_opts_choices_str[] = "none, {borrow:lend}";
698 enum { omptool_opts_nelems = sizeof(omptool_opts_values) / sizeof(omptool_opts_values[0]) };
699
700 210 int parse_omptool_opts(const char *str, omptool_opts_t *value) {
701
702 210 *value = OMPTOOL_OPTS_NONE;
703
704 /* tokenize multiple options separated by ':' */
705 210 char *end_token = NULL;
706 210 size_t len = strlen(str) + 1;
707 210 char *str_copy = malloc(sizeof(char)*len);
708 210 strcpy(str_copy, str);
709 210 char *token = strtok_r(str_copy, ":", &end_token);
710
2/2
✓ Branch 0 taken 214 times.
✓ Branch 1 taken 210 times.
424 while (token) {
711 int i;
712
2/2
✓ Branch 0 taken 435 times.
✓ Branch 1 taken 1 times.
436 for (i=0; i<omptool_opts_nelems; ++i) {
713
2/2
✓ Branch 0 taken 213 times.
✓ Branch 1 taken 222 times.
435 if (strcmp(token, omptool_opts_choices[i]) == 0) {
714 213 *value |= omptool_opts_values[i];
715 213 break;
716 }
717 }
718
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 213 times.
214 if (i == omptool_opts_nelems) {
719 1 warning("Unknown --lewi-ompt option: %s", token);
720 }
721 214 token = strtok_r(NULL, ":", &end_token);
722 }
723 210 free(str_copy);
724
725 210 return DLB_SUCCESS;
726 }
727
728 5 const char* omptool_opts_tostr(omptool_opts_t value) {
729 static char str[sizeof(omptool_opts_choices_str)] = "";
730 5 char *p = str;
731 int i;
732
2/2
✓ Branch 0 taken 15 times.
✓ Branch 1 taken 5 times.
20 for (i=0; i<omptool_opts_nelems; ++i) {
733
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 10 times.
15 if (value & omptool_opts_values[i]) {
734
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
5 if (p!=str) {
735 *p = ':';
736 ++p;
737 *p = '\0';
738 }
739 5 p += sprintf(p, "%s", omptool_opts_choices[i]);
740 }
741 }
742 5 return str;
743 }
744
745 4 const char* get_omptool_opts_choices(void) {
746 4 return omptool_opts_choices_str;
747 }
748
749 3 bool equivalent_omptool_opts(const char *str1, const char *str2) {
750 omptool_opts_t value1, value2;
751 3 parse_omptool_opts(str1, &value1);
752 3 parse_omptool_opts(str2, &value2);
753 3 return value1 == value2;
754 }
755
756 /* omptm_version_t */
757 static const omptm_version_t omptm_version_values[] = {OMPTM_NONE, OMPTM_OMP5,
758 OMPTM_FREE_AGENTS, OMPTM_ROLE_SHIFT};
759 static const char* const omptm_version_choices[] = {"none", "omp5", "free-agents", "role-shift"};
760 static const char omptm_version_choices_str[] = "none, omp5, free-agents, role-shift";
761 enum { omptm_version_nelems = sizeof(omptm_version_values) / sizeof(omptm_version_values[0]) };
762
763 161 int parse_omptm_version(const char *str, omptm_version_t *value) {
764 int i;
765
2/2
✓ Branch 0 taken 174 times.
✓ Branch 1 taken 1 times.
175 for (i=0; i<omptm_version_nelems; ++i) {
766
2/2
✓ Branch 0 taken 160 times.
✓ Branch 1 taken 14 times.
174 if (strcasecmp(str, omptm_version_choices[i]) == 0) {
767 160 *value = omptm_version_values[i];
768 160 return DLB_SUCCESS;
769 }
770 }
771 1 return DLB_ERR_NOENT;
772 }
773
774 4 const char* omptm_version_tostr(omptm_version_t value) {
775 int i;
776
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 for (i=0; i<omptm_version_nelems; ++i) {
777
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 if (omptm_version_values[i] == value) {
778 4 return omptm_version_choices[i];
779 }
780 }
781 return "unknown";
782 }
783
784 4 const char* get_omptm_version_choices(void) {
785 4 return omptm_version_choices_str;
786 }
787
788 2 bool equivalent_omptm_version_opts(const char *str1, const char *str2) {
789 2 omptm_version_t value1 = OMPTM_OMP5;
790 2 omptm_version_t value2 = OMPTM_FREE_AGENTS;
791 2 int err1 = parse_omptm_version(str1, &value1);
792 2 int err2 = parse_omptm_version(str2, &value2);
793
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;
794 }
795
796